diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/platform')
875 files changed, 17383 insertions, 15016 deletions
diff --git a/chromium/third_party/blink/renderer/platform/BUILD.gn b/chromium/third_party/blink/renderer/platform/BUILD.gn index bc9fe2cc200..05177001104 100644 --- a/chromium/third_party/blink/renderer/platform/BUILD.gn +++ b/chromium/third_party/blink/renderer/platform/BUILD.gn @@ -166,11 +166,6 @@ group("make_platform_generated") { import("//build/config/pch.gni") config("blink_platform_config") { - include_dirs = [ - #"$angle_path/include", - "$root_gen_dir/third_party/blink/renderer", - ] - configs = [ "//third_party/blink/renderer:config", "//third_party/blink/renderer:inside_blink", @@ -355,8 +350,8 @@ jumbo_component("platform") { "audio/audio_utilities.h", "audio/biquad.cc", "audio/biquad.h", - "audio/cone.cc", - "audio/cone.h", + "audio/cone_effect.cc", + "audio/cone_effect.h", "audio/cpu/arm/vector_math_neon.h", "audio/cpu/mips/vector_math_msa.h", "audio/cpu/x86/vector_math_avx.cc", @@ -495,10 +490,6 @@ jumbo_component("platform") { "content_decryption_module_result.h", "content_setting_callbacks.cc", "content_setting_callbacks.h", - "context_menu.cc", - "context_menu.h", - "context_menu_item.cc", - "context_menu_item.h", "cpu/mips/common_macros_msa.h", "cross_origin_attribute_value.h", "cross_thread_copier.cc", @@ -531,8 +522,6 @@ jumbo_component("platform") { "exported/web_blob_info.cc", "exported/web_cache.cc", "exported/web_canvas_capture_handler.cc", - "exported/web_clipboard_impl.cc", - "exported/web_clipboard_impl.h", "exported/web_coalesced_input_event.cc", "exported/web_content_decryption_module.cc", "exported/web_content_decryption_module_access.cc", @@ -570,11 +559,9 @@ jumbo_component("platform") { "exported/web_media_stream_track.cc", "exported/web_memory_coordinator.cc", "exported/web_mixed_content.cc", - "exported/web_mock_clipboard.cc", "exported/web_network_state_notifier.cc", "exported/web_prerender.cc", "exported/web_prerendering_support.cc", - "exported/web_presentation_receiver.cc", "exported/web_rtc_answer_options.cc", "exported/web_rtc_offer_options.cc", "exported/web_rtc_peer_connection_handler_client.cc", @@ -588,13 +575,6 @@ jumbo_component("platform") { "exported/web_rtc_stats_response.cc", "exported/web_rtc_void_request.cc", "exported/web_runtime_features.cc", - "exported/web_scrollbar_impl.cc", - "exported/web_scrollbar_impl.h", - "exported/web_scrollbar_theme_client_impl.cc", - "exported/web_scrollbar_theme_client_impl.h", - "exported/web_scrollbar_theme_geometry_native.cc", - "exported/web_scrollbar_theme_geometry_native.h", - "exported/web_scrollbar_theme_painter.cc", "exported/web_security_origin.cc", "exported/web_service_worker_installed_scripts_manager.cc", "exported/web_service_worker_request.cc", @@ -747,10 +727,13 @@ jumbo_component("platform") { "fonts/skia/skia_text_metrics.h", "fonts/small_caps_iterator.cc", "fonts/small_caps_iterator.h", + "fonts/string_truncator.cc", + "fonts/string_truncator.h", "fonts/symbols_iterator.cc", "fonts/symbols_iterator.h", "fonts/text_rendering_mode.cc", "fonts/text_rendering_mode.h", + "fonts/text_run_paint_info.h", "fonts/typesetting_features.cc", "fonts/typesetting_features.h", "fonts/unicode_range_set.cc", @@ -798,7 +781,6 @@ jumbo_component("platform") { "geometry/float_rounded_rect.h", "geometry/float_size.cc", "geometry/float_size.h", - "geometry/geometry_as_json.cc", "geometry/geometry_as_json.h", "geometry/int_point.cc", "geometry/int_point.h", @@ -817,10 +799,10 @@ jumbo_component("platform") { "geometry/layout_size.h", "geometry/region.cc", "geometry/region.h", - "geometry/transform_state.cc", - "geometry/transform_state.h", "graphics/accelerated_static_bitmap_image.cc", "graphics/accelerated_static_bitmap_image.h", + "graphics/begin_frame_provider.cc", + "graphics/begin_frame_provider.h", "graphics/bitmap_image.cc", "graphics/bitmap_image.h", "graphics/bitmap_image_metrics.cc", @@ -942,8 +924,6 @@ jumbo_component("platform") { "graphics/filters/source_graphic.h", "graphics/filters/spot_light_source.cc", "graphics/filters/spot_light_source.h", - "graphics/first_paint_invalidation_tracking.cc", - "graphics/first_paint_invalidation_tracking.h", "graphics/generated_image.cc", "graphics/generated_image.h", "graphics/gpu/drawing_buffer.cc", @@ -978,8 +958,6 @@ jumbo_component("platform") { "graphics/graphics_layer.cc", "graphics/graphics_layer.h", "graphics/graphics_layer_client.h", - "graphics/graphics_layer_debug_info.cc", - "graphics/graphics_layer_debug_info.h", "graphics/graphics_types.cc", "graphics/graphics_types.h", "graphics/graphics_types_3d.h", @@ -1012,9 +990,8 @@ jumbo_component("platform") { "graphics/logging_canvas.h", "graphics/mailbox_texture_holder.cc", "graphics/mailbox_texture_holder.h", + "graphics/offscreen_canvas_frame_dispatcher.cc", "graphics/offscreen_canvas_frame_dispatcher.h", - "graphics/offscreen_canvas_frame_dispatcher_impl.cc", - "graphics/offscreen_canvas_frame_dispatcher_impl.h", "graphics/offscreen_canvas_placeholder.cc", "graphics/offscreen_canvas_placeholder.h", "graphics/offscreen_canvas_resource_provider.cc", @@ -1061,13 +1038,12 @@ jumbo_component("platform") { "graphics/paint/geometry_mapper_clip_cache.h", "graphics/paint/geometry_mapper_transform_cache.cc", "graphics/paint/geometry_mapper_transform_cache.h", + "graphics/paint/hit_test_data.h", "graphics/paint/paint_artifact.cc", "graphics/paint/paint_artifact.h", "graphics/paint/paint_canvas.h", "graphics/paint/paint_chunk.cc", "graphics/paint/paint_chunk.h", - "graphics/paint/paint_chunk_properties.cc", - "graphics/paint/paint_chunk_properties.h", "graphics/paint/paint_chunk_subset.h", "graphics/paint/paint_chunker.cc", "graphics/paint/paint_chunker.h", @@ -1145,6 +1121,8 @@ jumbo_component("platform") { "graphics/surface_layer_bridge.h", "graphics/texture_holder.h", "graphics/touch_action.h", + "graphics/touch_action_rect.cc", + "graphics/touch_action_rect.h", "graphics/unaccelerated_static_bitmap_image.cc", "graphics/unaccelerated_static_bitmap_image.h", "graphics/video_frame_resource_provider.cc", @@ -1278,7 +1256,6 @@ jumbo_component("platform") { "peerconnection/rtc_stats_response_base.h", "peerconnection/rtc_void_request.h", "platform_chrome_client.h", - "platform_frame_view.h", "plugins/plugin_data.cc", "plugins/plugin_data.h", "plugins/plugin_list_builder.cc", @@ -1293,10 +1270,10 @@ jumbo_component("platform") { "prerender.cc", "prerender.h", "prerender_client.h", - "probe/PlatformTraceEventsAgent.cpp", - "probe/PlatformTraceEventsAgent.h", "probe/platform_probes.cc", "probe/platform_probes.h", + "probe/platform_trace_events_agent.cc", + "probe/platform_trace_events_agent.h", "resolution_units.h", "scoped_orientation_change_indicator.cc", "scoped_orientation_change_indicator.h", @@ -1320,12 +1297,13 @@ jumbo_component("platform") { "scroll/scrollable_area.h", "scroll/scrollbar.cc", "scroll/scrollbar.h", + "scroll/scrollbar_layer_delegate.cc", + "scroll/scrollbar_layer_delegate.h", "scroll/scrollbar_theme.cc", "scroll/scrollbar_theme.h", "scroll/scrollbar_theme_android.cc", "scroll/scrollbar_theme_aura.cc", "scroll/scrollbar_theme_aura.h", - "scroll/scrollbar_theme_client.h", "scroll/scrollbar_theme_mac.h", "scroll/scrollbar_theme_mac.mm", "scroll/scrollbar_theme_mock.cc", @@ -1357,6 +1335,8 @@ jumbo_component("platform") { "text/bidi_run_list.h", "text/bidi_text_run.cc", "text/bidi_text_run.h", + "text/capitalize.cc", + "text/capitalize.h", "text/character.cc", "text/character.h", "text/character_emoji.cc", @@ -1386,8 +1366,6 @@ jumbo_component("platform") { "text/quoted_printable.h", "text/segmented_string.cc", "text/segmented_string.h", - "text/string_truncator.cc", - "text/string_truncator.h", "text/suffix_tree.h", "text/text_boundaries.cc", "text/text_boundaries.h", @@ -1404,8 +1382,6 @@ jumbo_component("platform") { "text/text_run.cc", "text/text_run.h", "text/text_run_iterator.h", - "text/text_stream.cc", - "text/text_stream.h", "text/truncation.h", "text/unicode_bidi.h", "text/unicode_range.cc", @@ -1447,6 +1423,8 @@ jumbo_component("platform") { "transforms/skew_transform_operation.h", "transforms/transform_operations.cc", "transforms/transform_operations.h", + "transforms/transform_state.cc", + "transforms/transform_state.h", "transforms/transformation_matrix.cc", "transforms/transformation_matrix.h", "transforms/translate_transform_operation.cc", @@ -1547,15 +1525,15 @@ jumbo_component("platform") { ":platform_export", "//base/allocator:buildflags", "//components/viz/service", - "//device/base/synchronization", "//device/vr/public/mojom:mojom_blink", "//gin", "//mojo/public/cpp/base", "//mojo/public/cpp/bindings", "//mojo/public/cpp/bindings:wtf_support", "//services/service_manager/public/cpp", + "//skia:skcms", "//third_party:freetype_harfbuzz", - "//third_party/blink/public:offscreen_canvas_mojo_bindings_blink", + "//third_party/blink/public:embedded_frame_sink_mojo_bindings_blink", "//third_party/ced", "//third_party/icu", "//ui/gfx", @@ -1723,7 +1701,6 @@ jumbo_static_library("test_support") { ":platform", "//cc", "//cc:test_support", - "//cc/blink", "//components/viz/test:test_support", "//testing/gmock", "//testing/gtest:gtest", @@ -1798,6 +1775,7 @@ jumbo_source_set("blink_platform_unittests_sources") { "fonts/symbols_iterator_test.cc", "fonts/typesetting_features_test.cc", "fonts/unicode_range_set_test.cc", + "geometry/double_point_test.cc", "geometry/double_rect_test.cc", "geometry/float_box_test.cc", "geometry/float_box_test_helpers.cc", @@ -1811,7 +1789,6 @@ jumbo_source_set("blink_platform_unittests_sources") { "geometry/geometry_test_helpers.cc", "geometry/geometry_test_helpers.h", "geometry/int_rect_test.cc", - "geometry/layout_rect_outsets_test.cc", "geometry/layout_rect_test.cc", "geometry/layout_size_test.cc", "geometry/region_test.cc", @@ -1847,7 +1824,9 @@ jumbo_source_set("blink_platform_unittests_sources") { "graphics/paint/paint_record_builder_test.cc", "graphics/paint/property_tree_state_test.cc", "graphics/paint_invalidation_reason_test.cc", + "graphics/path_test.cc", "graphics/placeholder_image_test.cc", + "graphics/skia/skia_utils_test.cc", "graphics/static_bitmap_image_test.cc", "graphics/video_frame_submitter_test.cc", "histogram_test.cc", @@ -1889,10 +1868,12 @@ jumbo_source_set("blink_platform_unittests_sources") { "testing/tree_test_helpers.h", "text/bidi_resolver_test.cc", "text/bidi_test_harness.h", + "text/capitalize_test.cc", "text/character_test.cc", "text/date_time_format_test.cc", "text/hyphenation_test.cc", "text/icu_error_test.cc", + "text/line_ending_test.cc", "text/platform_locale_test.cc", "text/segmented_string_test.cc", "text/suffix_tree_test.cc", @@ -1954,9 +1935,6 @@ jumbo_source_set("blink_platform_unittests_sources") { "//base/test:test_support", "//cc", "//cc:test_support", - "//cc/blink", - "//device/base/synchronization", - "//mojo/common:test_common_custom_types_blink", "//mojo/edk", "//mojo/public/cpp/bindings/tests:for_blink_tests", "//mojo/public/cpp/test_support:test_utils", @@ -1985,8 +1963,6 @@ jumbo_source_set("blink_platform_unittests_sources") { ] defines = [ "INSIDE_BLINK" ] - - include_dirs = [ "$root_gen_dir/third_party/blink/renderer" ] } executable("image_decode_bench") { @@ -2246,7 +2222,7 @@ jumbo_source_set("unit_tests") { "graphics/image_decoding_store_test.cc", "graphics/image_frame_generator_test.cc", "graphics/image_layer_chromium_test.cc", - "graphics/offscreen_canvas_frame_dispatcher_impl_test.cc", + "graphics/offscreen_canvas_frame_dispatcher_test.cc", "graphics/test/fake_gles2_interface.h", "graphics/test/fake_scrollable_area.h", "graphics/test/fake_web_graphics_context_3d_provider.h", diff --git a/chromium/third_party/blink/renderer/platform/DEPS b/chromium/third_party/blink/renderer/platform/DEPS index 7b43092ccd2..2da4a9ced4f 100644 --- a/chromium/third_party/blink/renderer/platform/DEPS +++ b/chromium/third_party/blink/renderer/platform/DEPS @@ -8,12 +8,14 @@ include_rules = [ "+base/cpu.h", "+base/feature_list.h", "+base/files", + "+base/containers/flat_map.h", "+base/guid.h", "+base/json", "+base/location.h", "+base/logging.h", "+base/memory", "+base/observer_list.h", + "+base/memory/shared_memory.h", "+base/message_loop/message_loop.h", "+base/metrics/histogram.h", "+base/metrics/histogram_base.h", @@ -25,6 +27,7 @@ include_rules = [ "+base/rand_util.h", "+base/run_loop.h", "+base/sampling_heap_profiler/sampling_heap_profiler.h", + "+base/strings/pattern.h", "+base/strings/string_util.h", "+base/strings/stringprintf.h", "+base/synchronization/waitable_event.h", @@ -39,6 +42,7 @@ include_rules = [ "+base/values.h", "+base/lazy_instance.h", "+net/base/escape.h", + "+net/base/filename_util.h", "+net/http/http_util.h", "+net/http/http_request_headers.h", "+net/http/http_response_headers.h", diff --git a/chromium/third_party/blink/renderer/platform/OWNERS b/chromium/third_party/blink/renderer/platform/OWNERS index d52a1b2e054..7e45d470ca9 100644 --- a/chromium/third_party/blink/renderer/platform/OWNERS +++ b/chromium/third_party/blink/renderer/platform/OWNERS @@ -1,3 +1,4 @@ +bokan@chromium.org dgozman@chromium.org drott@chromium.org eae@chromium.org @@ -24,7 +25,7 @@ wangxianzhu@chromium.org # Any API or core owner can also approve changes to runtime-enabled features. # Please make sure to get a review from someone with expertise on the feature # you are changing. -per-file runtime_enabled_features.json5=file://third_party/WebKit/API_OWNERS +per-file runtime_enabled_features.json5=file://third_party/blink/API_OWNERS per-file runtime_enabled_features.json5=file://third_party/blink/renderer/core/OWNERS # COMPONENT: Platform diff --git a/chromium/third_party/blink/renderer/platform/animation/DEPS b/chromium/third_party/blink/renderer/platform/animation/DEPS index 8d825ff202e..26f742b2719 100644 --- a/chromium/third_party/blink/renderer/platform/animation/DEPS +++ b/chromium/third_party/blink/renderer/platform/animation/DEPS @@ -1,4 +1,20 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/animation", + + # Dependencies. "+cc", - "-cc/blink", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/layout_unit.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/transforms", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/animation/animation_translation_util.cc b/chromium/third_party/blink/renderer/platform/animation/animation_translation_util.cc index 7180abd59a8..76520157537 100644 --- a/chromium/third_party/blink/renderer/platform/animation/animation_translation_util.cc +++ b/chromium/third_party/blink/renderer/platform/animation/animation_translation_util.cc @@ -50,7 +50,7 @@ void ToCompositorTransformOperations( case TransformOperation::kScaleZ: case TransformOperation::kScale3D: case TransformOperation::kScale: { - auto transform = + auto* transform = static_cast<const ScaleTransformOperation*>(operation.get()); out_transform_operations->AppendScale(transform->X(), transform->Y(), transform->Z()); @@ -61,7 +61,7 @@ void ToCompositorTransformOperations( case TransformOperation::kTranslateZ: case TransformOperation::kTranslate3D: case TransformOperation::kTranslate: { - auto transform = + auto* transform = static_cast<const TranslateTransformOperation*>(operation.get()); DCHECK(transform->X().IsFixed() && transform->Y().IsFixed()); out_transform_operations->AppendTranslate( @@ -72,7 +72,7 @@ void ToCompositorTransformOperations( case TransformOperation::kRotateY: case TransformOperation::kRotate3D: case TransformOperation::kRotate: { - auto transform = + auto* transform = static_cast<const RotateTransformOperation*>(operation.get()); out_transform_operations->AppendRotate( transform->X(), transform->Y(), transform->Z(), transform->Angle()); @@ -81,14 +81,14 @@ void ToCompositorTransformOperations( case TransformOperation::kSkewX: case TransformOperation::kSkewY: case TransformOperation::kSkew: { - auto transform = + auto* transform = static_cast<const SkewTransformOperation*>(operation.get()); out_transform_operations->AppendSkew(transform->AngleX(), transform->AngleY()); break; } case TransformOperation::kMatrix: { - auto transform = + auto* transform = static_cast<const MatrixTransformOperation*>(operation.get()); TransformationMatrix m = transform->Matrix(); out_transform_operations->AppendMatrix( @@ -96,7 +96,7 @@ void ToCompositorTransformOperations( break; } case TransformOperation::kMatrix3D: { - auto transform = + auto* transform = static_cast<const Matrix3DTransformOperation*>(operation.get()); TransformationMatrix m = transform->Matrix(); out_transform_operations->AppendMatrix( @@ -104,7 +104,7 @@ void ToCompositorTransformOperations( break; } case TransformOperation::kPerspective: { - auto transform = + auto* transform = static_cast<const PerspectiveTransformOperation*>(operation.get()); out_transform_operations->AppendPerspective(transform->Perspective()); break; 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 fed54f402e9..d7c7c78b80d 100644 --- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h +++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation.h @@ -38,7 +38,7 @@ class PLATFORM_EXPORT CompositorAnimation : public cc::AnimationDelegate { explicit CompositorAnimation( scoped_refptr<cc::SingleKeyframeEffectAnimation>); - ~CompositorAnimation(); + ~CompositorAnimation() override; cc::SingleKeyframeEffectAnimation* CcAnimation() const; diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.cc b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.cc index 43badac34ea..63bb9f4db11 100644 --- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.cc +++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.cc @@ -39,23 +39,17 @@ void CompositorAnimationHost::TakeOverImplOnlyScrollOffsetAnimation( void CompositorAnimationHost::SetAnimationCounts( size_t total_animations_count, - size_t main_thread_compositable_animations_count, bool current_frame_had_raf, bool next_frame_has_pending_raf) { - animation_host_->SetAnimationCounts( - total_animations_count, main_thread_compositable_animations_count, - current_frame_had_raf, next_frame_has_pending_raf); + animation_host_->SetAnimationCounts(total_animations_count, + current_frame_had_raf, + next_frame_has_pending_raf); } size_t CompositorAnimationHost::GetMainThreadAnimationsCountForTesting() { return animation_host_->MainThreadAnimationsCount(); } -size_t -CompositorAnimationHost::GetMainThreadCompositableAnimationsCountForTesting() { - return animation_host_->MainThreadCompositableAnimationsCount(); -} - size_t CompositorAnimationHost::GetCompositedAnimationsCountForTesting() { return animation_host_->CompositedAnimationsCount(); } diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.h b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.h index ec80db3e8e4..ddef37628eb 100644 --- a/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.h +++ b/chromium/third_party/blink/renderer/platform/animation/compositor_animation_host.h @@ -32,11 +32,9 @@ class PLATFORM_EXPORT CompositorAnimationHost { const gfx::Vector2dF& adjustment); void TakeOverImplOnlyScrollOffsetAnimation(CompositorElementId); void SetAnimationCounts(size_t total_animations_count, - size_t main_thread_compositable_animations_count, bool current_frame_had_raf, bool next_frame_has_pending_raf); size_t GetMainThreadAnimationsCountForTesting(); - size_t GetMainThreadCompositableAnimationsCountForTesting(); size_t GetCompositedAnimationsCountForTesting(); bool CurrentFrameHadRAFForTesting(); bool NextFrameHasPendingRAFForTesting(); diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_filter_keyframe.h b/chromium/third_party/blink/renderer/platform/animation/compositor_filter_keyframe.h index f26806a9d77..fca7bbbdb84 100644 --- a/chromium/third_party/blink/renderer/platform/animation/compositor_filter_keyframe.h +++ b/chromium/third_party/blink/renderer/platform/animation/compositor_filter_keyframe.h @@ -22,7 +22,7 @@ class PLATFORM_EXPORT CompositorFilterKeyframe : public CompositorKeyframe { CompositorFilterKeyframe(double time, CompositorFilterOperations value, const TimingFunction&); - ~CompositorFilterKeyframe(); + ~CompositorFilterKeyframe() override; std::unique_ptr<cc::FilterKeyframe> CloneToCC() const; diff --git a/chromium/third_party/blink/renderer/platform/animation/compositor_transform_keyframe.h b/chromium/third_party/blink/renderer/platform/animation/compositor_transform_keyframe.h index c9eb01c7eac..26a6c29451d 100644 --- a/chromium/third_party/blink/renderer/platform/animation/compositor_transform_keyframe.h +++ b/chromium/third_party/blink/renderer/platform/animation/compositor_transform_keyframe.h @@ -21,7 +21,7 @@ class PLATFORM_EXPORT CompositorTransformKeyframe : public CompositorKeyframe { CompositorTransformKeyframe(double time, CompositorTransformOperations value, const TimingFunction&); - ~CompositorTransformKeyframe(); + ~CompositorTransformKeyframe() override; std::unique_ptr<cc::TransformKeyframe> CloneToCC() const; diff --git a/chromium/third_party/blink/renderer/platform/animation/timing_function.cc b/chromium/third_party/blink/renderer/platform/animation/timing_function.cc index 9ea3b3a1f13..51a362704e0 100644 --- a/chromium/third_party/blink/renderer/platform/animation/timing_function.cc +++ b/chromium/third_party/blink/renderer/platform/animation/timing_function.cc @@ -166,7 +166,7 @@ scoped_refptr<TimingFunction> CreateCompositorTimingFunctionFromCC( switch (timing_function->GetType()) { case cc::TimingFunction::Type::CUBIC_BEZIER: { - auto cubic_timing_function = + auto* cubic_timing_function = static_cast<const cc::CubicBezierTimingFunction*>(timing_function); if (cubic_timing_function->ease_type() != cc::CubicBezierTimingFunction::EaseType::CUSTOM) @@ -179,7 +179,7 @@ scoped_refptr<TimingFunction> CreateCompositorTimingFunctionFromCC( } case cc::TimingFunction::Type::STEPS: { - auto steps_timing_function = + auto* steps_timing_function = static_cast<const cc::StepsTimingFunction*>(timing_function); return StepsTimingFunction::Create( steps_timing_function->steps(), diff --git a/chromium/third_party/blink/renderer/platform/async_method_runner.h b/chromium/third_party/blink/renderer/platform/async_method_runner.h index f45f506c4d8..0313d396639 100644 --- a/chromium/third_party/blink/renderer/platform/async_method_runner.h +++ b/chromium/third_party/blink/renderer/platform/async_method_runner.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_ASYNC_METHOD_RUNNER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_ASYNC_METHOD_RUNNER_H_ +#include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" diff --git a/chromium/third_party/blink/renderer/platform/audio/DEPS b/chromium/third_party/blink/renderer/platform/audio/DEPS new file mode 100644 index 00000000000..8764ae657df --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/audio/DEPS @@ -0,0 +1,22 @@ +include_rules = [ + # Don't depend on platform. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/audio", + + # Dependencies. + "+third_party/blink/renderer/platform/cpu/mips/common_macros_msa.h", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/geometry/float_point_3d.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/waitable_event.h", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc b/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc index c72671f8713..24e122b12ac 100644 --- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc +++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.cc @@ -34,14 +34,12 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_audio_latency_hint.h" -#include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/platform/audio/audio_utilities.h" #include "third_party/blink/renderer/platform/audio/push_pull_fifo.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/web_task_runner.h" -#include "third_party/blink/renderer/platform/weborigin/security_origin.h" namespace blink { @@ -56,18 +54,14 @@ const size_t kFIFOSize = 96 * 128; scoped_refptr<AudioDestination> AudioDestination::Create( AudioIOCallback& callback, unsigned number_of_output_channels, - const WebAudioLatencyHint& latency_hint, - scoped_refptr<const SecurityOrigin> security_origin) { + const WebAudioLatencyHint& latency_hint) { return base::AdoptRef( - new AudioDestination(callback, number_of_output_channels, latency_hint, - std::move(security_origin))); + new AudioDestination(callback, number_of_output_channels, latency_hint)); } -AudioDestination::AudioDestination( - AudioIOCallback& callback, - unsigned number_of_output_channels, - const WebAudioLatencyHint& latency_hint, - scoped_refptr<const SecurityOrigin> security_origin) +AudioDestination::AudioDestination(AudioIOCallback& callback, + unsigned number_of_output_channels, + const WebAudioLatencyHint& latency_hint) : number_of_output_channels_(number_of_output_channels), is_playing_(false), fifo_( @@ -84,8 +78,7 @@ AudioDestination::AudioDestination( // renderer does not support it currently. Thus, we use zero for the number // of input channels. web_audio_device_ = Platform::Current()->CreateAudioDevice( - 0, number_of_output_channels, latency_hint, this, String(), - std::move(security_origin)); + 0, number_of_output_channels, latency_hint, this, String()); DCHECK(web_audio_device_); callback_buffer_size_ = web_audio_device_->FramesPerBuffer(); @@ -139,7 +132,7 @@ void AudioDestination::Render(const WebVector<float*>& destination_data, size_t frames_to_render = fifo_->Pull(output_bus_.get(), number_of_frames); - // Use the dual-thread rendering model if the AudioWorklet is activated. + // Use the dual-thread rendering model if the AudioWorklet is activated. if (worklet_task_runner_) { PostCrossThreadTask( *worklet_task_runner_, diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_destination.h b/chromium/third_party/blink/renderer/platform/audio/audio_destination.h index b73e61a184d..a42f2ee932b 100644 --- a/chromium/third_party/blink/renderer/platform/audio/audio_destination.h +++ b/chromium/third_party/blink/renderer/platform/audio/audio_destination.h @@ -31,6 +31,7 @@ #include <memory> #include "base/memory/scoped_refptr.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_audio_device.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/public/platform/web_vector.h" @@ -42,7 +43,6 @@ namespace blink { class PushPullFIFO; -class SecurityOrigin; class WebAudioLatencyHint; // The AudioDestination class is an audio sink interface between the media @@ -64,15 +64,13 @@ class PLATFORM_EXPORT AudioDestination public: AudioDestination(AudioIOCallback&, unsigned number_of_output_channels, - const WebAudioLatencyHint&, - scoped_refptr<const SecurityOrigin>); + const WebAudioLatencyHint&); ~AudioDestination() override; static scoped_refptr<AudioDestination> Create( AudioIOCallback&, unsigned number_of_output_channels, - const WebAudioLatencyHint&, - scoped_refptr<const SecurityOrigin>); + const WebAudioLatencyHint&); // The actual render function (WebAudioDevice::RenderCallback) isochronously // invoked by the media renderer. This is never called after Stop() is called. diff --git a/chromium/third_party/blink/renderer/platform/audio/cone.cc b/chromium/third_party/blink/renderer/platform/audio/cone_effect.cc index dc558870a71..c33d6649112 100644 --- a/chromium/third_party/blink/renderer/platform/audio/cone.cc +++ b/chromium/third_party/blink/renderer/platform/audio/cone_effect.cc @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/platform/audio/cone.h" +#include "third_party/blink/renderer/platform/audio/cone_effect.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" namespace blink { @@ -53,13 +53,13 @@ double ConeEffect::Gain(FloatPoint3D source_position, double abs_outer_angle = fabs(outer_angle_) / 2.0; double gain = 1.0; - if (abs_angle <= abs_inner_angle) + if (abs_angle <= abs_inner_angle) { // No attenuation gain = 1.0; - else if (abs_angle >= abs_outer_angle) + } else if (abs_angle >= abs_outer_angle) { // Max attenuation gain = outer_gain_; - else { + } else { // Between inner and outer cones // inner -> outer, x goes from 0 -> 1 double x = diff --git a/chromium/third_party/blink/renderer/platform/audio/cone.h b/chromium/third_party/blink/renderer/platform/audio/cone_effect.h index beaf5673790..c3c39cfc0ab 100644 --- a/chromium/third_party/blink/renderer/platform/audio/cone.h +++ b/chromium/third_party/blink/renderer/platform/audio/cone_effect.h @@ -26,8 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_EFFECT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_EFFECT_H_ #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -66,4 +66,4 @@ class PLATFORM_EXPORT ConeEffect { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_AUDIO_CONE_EFFECT_H_ diff --git a/chromium/third_party/blink/renderer/platform/audio/iir_filter.cc b/chromium/third_party/blink/renderer/platform/audio/iir_filter.cc index 1248ff48ef3..6ce33eb6cb9 100644 --- a/chromium/third_party/blink/renderer/platform/audio/iir_filter.cc +++ b/chromium/third_party/blink/renderer/platform/audio/iir_filter.cc @@ -151,7 +151,7 @@ void IIRFilter::GetFrequencyResponse(int n_frequencies, } } -double IIRFilter::TailTime(double sample_rate) { +double IIRFilter::TailTime(double sample_rate, bool is_filter_stable) { // The maximum tail time. This is somewhat arbitrary, but we're assuming that // no one is going to expect the IIRFilter to produce an output after this // much time after the inputs have stopped. @@ -162,6 +162,13 @@ double IIRFilter::TailTime(double sample_rate) { // that the impulse is less than 1 bit of a 16-bit PCM value. const float kMaxTailAmplitude = 1 / 32768.0; + // If filter is not stable, just return max tail. Since the filter is not + // stable, the impulse response won't converge to zero, so we don't need to + // find the impulse response to find the actual tail time. + if (!is_filter_stable) { + return kMaxTailTime; + } + // How to compute the tail time? We're going to filter an impulse // for |kMaxTailTime| seconds, in blocks of kRenderQuantumFrames at // a time. The maximum magnitude of this block is saved. After all diff --git a/chromium/third_party/blink/renderer/platform/audio/iir_filter.h b/chromium/third_party/blink/renderer/platform/audio/iir_filter.h index 152f8b1282e..00def1f35ea 100644 --- a/chromium/third_party/blink/renderer/platform/audio/iir_filter.h +++ b/chromium/third_party/blink/renderer/platform/audio/iir_filter.h @@ -30,7 +30,7 @@ class PLATFORM_EXPORT IIRFilter final { float* phase_response); // Compute the tail time of the IIR filter - double TailTime(double sample_rate); + double TailTime(double sample_rate, bool is_filter_stable); // Reset the internal state of the IIR filter to the initial state. void ResetState(); diff --git a/chromium/third_party/blink/renderer/platform/bindings/DEPS b/chromium/third_party/blink/renderer/platform/bindings/DEPS index 8e2d58bf4bf..f59246cf3c3 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/DEPS +++ b/chromium/third_party/blink/renderer/platform/bindings/DEPS @@ -1,3 +1,20 @@ include_rules = [ - "+gin/public" + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/bindings", + + # Dependencies. + "+gin/public", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/instance_counters.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/supplementable.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/bindings/TraceWrapperReference.md b/chromium/third_party/blink/renderer/platform/bindings/TraceWrapperReference.md index fa32b874f7f..23adab6a7ab 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/TraceWrapperReference.md +++ b/chromium/third_party/blink/renderer/platform/bindings/TraceWrapperReference.md @@ -17,7 +17,7 @@ participate in wrapper tracing. find other wrappers that this object should keep alive. 3. Use `TraceWrapperV8Reference<T>` to annotate references to V8 that this object should keep alive. -4. Declare a `virtual void TraceWrappers(const ScriptWrappableVisitor*) const` +4. Declare a `virtual void TraceWrappers(ScriptWrappableVisitor*) const` method to trace other wrappers. 5. Define the method and trace all fields that received a wrapper tracing type in (1) and (2) using `visitor->TraceWrappers(<field_>)` in the body. @@ -34,7 +34,7 @@ class SomeDOMObject : public ScriptWrappable { // (1) public: virtual void TraceWrappers( - const ScriptWrappableVisitor*) const; // (4) + ScriptWrappableVisitor*) const; // (4) private: TraceWrapperMember<OtherWrappable> other_wrappable_; // (2) @@ -44,7 +44,7 @@ class SomeDOMObject : public ScriptWrappable { // (1) }; void SomeDOMObject::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { // (5) + ScriptWrappableVisitor* visitor) const { // (5) visitor->TraceWrappers(other_wrappable_); // (5) visitor->TraceWrappers(v8object_); // (5) } @@ -112,7 +112,7 @@ class SomeDOMObject : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - virtual void TraceWrappers(const ScriptWrappableVisitor*) const; + virtual void TraceWrappers(ScriptWrappableVisitor*) const; private: Member<OtherWrappable> other_wrappable_; @@ -120,7 +120,7 @@ class SomeDOMObject : public ScriptWrappable { }; void SomeDOMObject::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { visitor->TraceWrappers(other_wrappable_); } ``` @@ -147,7 +147,7 @@ class SomeDOMObject : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); public: - virtual void TraceWrappers(const ScriptWrappableVisitor*) const; + virtual void TraceWrappers(ScriptWrappableVisitor*) const; private: TraceWrapperMember<OtherWrappable> other_wrappable_; @@ -155,7 +155,7 @@ class SomeDOMObject : public ScriptWrappable { }; void SomeDOMObject::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { visitor->TraceWrappers(other_wrappable_); } ``` @@ -176,14 +176,14 @@ class SomeDOMObject : public ScriptWrappable { public: // ... void AppendNewValue(OtherWrappable* newValue); - virtual void TraceWrappers(const ScriptWrappableVisitor*) const; + virtual void TraceWrappers(ScriptWrappableVisitor*) const; private: HeapVector<TraceWrapperMember<OtherWrappable>> other_wrappables_; }; void SomeDOMObject::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { for (auto other : other_wrappables_) visitor->TraceWrappers(other); } @@ -253,13 +253,13 @@ class ManualWrappable : public ScriptWrappable { SriptWrappableVisitor::WriteBarrier(other_wrappable_); } - virtual void TraceWrappers(const ScriptWrappableVisitor*) const; + virtual void TraceWrappers(ScriptWrappableVisitor*) const; private: Member<OtherWrappable>> other_wrappable_; }; void ManualWrappable::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { visitor->TraceWrappersWithManualWriteBarrier(other_wrappable_); } ``` diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc index 265dbb5e9f1..7add6d9ccad 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.cc @@ -19,7 +19,7 @@ CallbackFunctionBase::CallbackFunctionBase( } void CallbackFunctionBase::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { visitor->TraceWrappers(callback_function_); } diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h index 9d8103aa4ae..1bed7cd8e6c 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h +++ b/chromium/third_party/blink/renderer/platform/bindings/callback_function_base.h @@ -30,7 +30,7 @@ class PLATFORM_EXPORT CallbackFunctionBase virtual ~CallbackFunctionBase() = default; virtual void Trace(blink::Visitor* visitor) {} - void TraceWrappers(const ScriptWrappableVisitor*) const override; + void TraceWrappers(ScriptWrappableVisitor*) const override; const char* NameInHeapSnapshot() const override { return "CallbackFunctionBase"; } diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc index c6d306c3a62..9fd0d8fcba2 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.cc @@ -22,7 +22,7 @@ CallbackInterfaceBase::CallbackInterfaceBase( } void CallbackInterfaceBase::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { + ScriptWrappableVisitor* visitor) const { visitor->TraceWrappers(callback_object_); } diff --git a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h index 5276381bb47..b3a5d239ce5 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h +++ b/chromium/third_party/blink/renderer/platform/bindings/callback_interface_base.h @@ -37,7 +37,7 @@ class PLATFORM_EXPORT CallbackInterfaceBase virtual ~CallbackInterfaceBase() = default; virtual void Trace(blink::Visitor*) {} - void TraceWrappers(const ScriptWrappableVisitor*) const override; + void TraceWrappers(ScriptWrappableVisitor*) const override; const char* NameInHeapSnapshot() const override { return "CallbackInterfaceBase"; } @@ -49,6 +49,12 @@ class PLATFORM_EXPORT CallbackInterfaceBase return callback_relevant_script_state_.get(); } + // NodeIteratorBase counts the invocation of those which are callable and + // those which are not. + bool IsCallbackObjectCallableForNodeIteratorBase() const { + return IsCallbackObjectCallable(); + } + protected: CallbackInterfaceBase(v8::Local<v8::Object> callback_object, SingleOperationOrNot); @@ -75,6 +81,10 @@ class PLATFORM_EXPORT CallbackInterfaceBase scoped_refptr<ScriptState> incumbent_script_state_; friend class V8PersistentCallbackInterfaceBase; + // ToV8 needs to call |CallbackObject| member function. + friend v8::Local<v8::Value> ToV8(CallbackInterfaceBase* callback, + v8::Local<v8::Object> creation_context, + v8::Isolate*); }; // V8PersistentCallbackInterfaceBase retains the underlying v8::Object of a 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 33e30105185..c66d44d5e38 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 @@ -33,6 +33,7 @@ #include <memory> +#include "base/optional.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_map.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -40,7 +41,6 @@ #include "third_party/blink/renderer/platform/bindings/wrapper_type_info.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/stack_util.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "v8/include/v8.h" @@ -143,8 +143,12 @@ class DOMDataStore { return updated; } + void Trace(const ScriptWrappable* script_wrappable, Visitor* visitor) { + visitor->Trace(&wrapper_map_.value(), script_wrappable); + } + void TraceWrappers(const ScriptWrappable* script_wrappable, - const ScriptWrappableVisitor* visitor) { + ScriptWrappableVisitor* visitor) { visitor->TraceWrappers(&wrapper_map_.value(), script_wrappable); } @@ -192,7 +196,7 @@ class DOMDataStore { } bool is_main_world_; - WTF::Optional<DOMWrapperMap<ScriptWrappable>> wrapper_map_; + base::Optional<DOMWrapperMap<ScriptWrappable>> wrapper_map_; }; template <> diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc index 0351715bfdb..8f49afaeac3 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.cc @@ -115,8 +115,19 @@ void DOMWrapperWorld::AllWorldsInCurrentThread( worlds.push_back(world); } +void DOMWrapperWorld::Trace(const ScriptWrappable* script_wrappable, + Visitor* visitor) { + // Marking for worlds other than the main world. + DCHECK(ThreadState::Current()->GetIsolate()); + for (DOMWrapperWorld* world : GetWorldMap().Values()) { + DOMDataStore& data_store = world->DomDataStore(); + if (data_store.ContainsWrapper(script_wrappable)) + data_store.Trace(script_wrappable, visitor); + } +} + void DOMWrapperWorld::TraceWrappers(const ScriptWrappable* script_wrappable, - const ScriptWrappableVisitor* visitor) { + ScriptWrappableVisitor* visitor) { // Marking for worlds other than the main world. DCHECK(ThreadState::Current()->GetIsolate()); for (DOMWrapperWorld* world : GetWorldMap().Values()) { diff --git a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h index 5e5bc75d862..e6cef6de75d 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h +++ b/chromium/third_party/blink/renderer/platform/bindings/dom_wrapper_world.h @@ -96,8 +96,8 @@ class PLATFORM_EXPORT DOMWrapperWorld : public RefCounted<DOMWrapperWorld> { Vector<scoped_refptr<DOMWrapperWorld>>& worlds); // Traces wrappers corresponding to the ScriptWrappable in DOM data stores. - static void TraceWrappers(const ScriptWrappable*, - const ScriptWrappableVisitor*); + static void Trace(const ScriptWrappable*, Visitor*); + static void TraceWrappers(const ScriptWrappable*, ScriptWrappableVisitor*); static DOMWrapperWorld& World(v8::Local<v8::Context> context) { return ScriptState::From(context)->World(); diff --git a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h index ecc3c01c90d..c6d12b9b2f6 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h +++ b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats.h @@ -8,13 +8,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_RUNTIME_CALL_STATS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_RUNTIME_CALL_STATS_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats_count_everything_buildflags.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/time.h" #include "v8/include/v8.h" @@ -114,7 +114,7 @@ class PLATFORM_EXPORT RuntimeCallTimer { } #define RUNTIME_CALL_TIMER_SCOPE_WITH_RCS(runtime_call_stats, counterId) \ - Optional<RuntimeCallTimerScope> rcs_scope; \ + base::Optional<RuntimeCallTimerScope> rcs_scope; \ if (UNLIKELY(RuntimeEnabledFeatures::BlinkRuntimeCallStatsEnabled())) { \ rcs_scope.emplace(runtime_call_stats, counterId); \ } @@ -139,7 +139,7 @@ class PLATFORM_EXPORT RuntimeCallTimer { RUNTIME_CALL_TIMER_SCOPE_WITH_RCS(RuntimeCallStats::From(isolate), counterId) #define RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS(isolate, counterId) \ - Optional<RuntimeCallTimerScope> rcs_scope; \ + base::Optional<RuntimeCallTimerScope> rcs_scope; \ if (isolate) { \ RUNTIME_CALL_TIMER_SCOPE_WITH_OPTIONAL_RCS( \ rcs_scope, RuntimeCallStats::From(isolate), counterId) \ diff --git a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc index fe703d6424c..04287a513fe 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/runtime_call_stats_test.cc @@ -301,7 +301,7 @@ TEST_F(RuntimeCallStatsTest, TestScopeWithOptionalMacroWithCallStatsDisabled) { RuntimeCallCounter* counter = stats.GetCounter(test_counter_1_id); { - Optional<RuntimeCallTimerScope> scope; + base::Optional<RuntimeCallTimerScope> scope; RUNTIME_CALL_TIMER_SCOPE_WITH_OPTIONAL_RCS(scope, &stats, test_counter_1_id); AdvanceClock(25); @@ -317,7 +317,7 @@ TEST_F(RuntimeCallStatsTest, TestScopeWithOptionalMacroWithCallStatsEnabled) { RuntimeCallCounter* counter = stats.GetCounter(test_counter_1_id); { - Optional<RuntimeCallTimerScope> scope; + base::Optional<RuntimeCallTimerScope> scope; RUNTIME_CALL_TIMER_SCOPE_WITH_OPTIONAL_RCS(scope, &stats, test_counter_1_id); AdvanceClock(25); diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h b/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h index f778551eb20..656083c7377 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h +++ b/chromium/third_party/blink/renderer/platform/bindings/script_forbidden_scope.h @@ -5,10 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_FORBIDDEN_SCOPE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_FORBIDDEN_SCOPE_H_ +#include "base/auto_reset.h" #include "base/macros.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/stack_util.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" @@ -32,7 +32,7 @@ class PLATFORM_EXPORT ScriptForbiddenScope final { ~AllowUserAgentScript() { DCHECK(!IsScriptForbidden()); } private: - AutoReset<unsigned> saved_counter_; + base::AutoReset<unsigned> saved_counter_; }; static bool IsScriptForbidden() { diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_state.cc b/chromium/third_party/blink/renderer/platform/bindings/script_state.cc index e6fc3e248a2..9463657494f 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_state.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/script_state.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" +#include "third_party/blink/renderer/platform/instance_counters.h" namespace blink { @@ -44,6 +45,8 @@ ScriptState::ScriptState(v8::Local<v8::Context> context, ScriptState::~ScriptState() { DCHECK(!per_context_data_); DCHECK(context_.IsEmpty()); + InstanceCounters::DecrementCounter( + InstanceCounters::kDetachedScriptStateCounter); } void ScriptState::DetachGlobalObject() { @@ -53,6 +56,8 @@ void ScriptState::DetachGlobalObject() { void ScriptState::DisposePerContextData() { per_context_data_ = nullptr; + InstanceCounters::IncrementCounter( + InstanceCounters::kDetachedScriptStateCounter); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc index 950c3e88847..8b5de7a79c7 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.cc @@ -39,8 +39,12 @@ v8::Local<v8::Object> ScriptWrappable::AssociateWithWrapper( wrapper_type_info, wrapper); } -void ScriptWrappable::TraceWrappers( - const ScriptWrappableVisitor* visitor) const { +void ScriptWrappable::Trace(Visitor* visitor) { + visitor->Trace(main_world_wrapper_); + DOMWrapperWorld::Trace(this, visitor); +} + +void ScriptWrappable::TraceWrappers(ScriptWrappableVisitor* visitor) const { visitor->TraceWrappers(main_world_wrapper_); DOMWrapperWorld::TraceWrappers(this, visitor); } diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h index 7cc10a8be5e..cf57e9e7f64 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable.h @@ -57,10 +57,10 @@ class PLATFORM_EXPORT ScriptWrappable public: virtual ~ScriptWrappable() = default; - virtual void Trace(blink::Visitor*) {} + virtual void Trace(blink::Visitor*); // Traces wrapper objects corresponding to this ScriptWrappable in all worlds. - void TraceWrappers(const ScriptWrappableVisitor*) const override; + void TraceWrappers(ScriptWrappableVisitor*) const override; bool IsScriptWrappable() const override { return true; } diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc index d7ddc64762c..e0f83319b34 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h" +#include "base/auto_reset.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/bindings/active_script_wrappable_base.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_map.h" @@ -17,9 +18,8 @@ #include "third_party/blink/renderer/platform/heap/heap_compact.h" #include "third_party/blink/renderer/platform/heap/heap_page.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/supplementable.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -39,7 +39,7 @@ void ScriptWrappableMarkingVisitor::TracePrologue() { CHECK(marking_deque_.IsEmpty()); CHECK(verifier_deque_.IsEmpty()); tracing_in_progress_ = true; - ThreadState::Current()->SetWrapperTracingInProgress(true); + ThreadState::Current()->EnableWrapperTracingBarrier(); } void ScriptWrappableMarkingVisitor::EnterFinalPause() { @@ -62,7 +62,7 @@ void ScriptWrappableMarkingVisitor::TraceEpilogue() { should_cleanup_ = true; tracing_in_progress_ = false; - ThreadState::Current()->SetWrapperTracingInProgress(false); + ThreadState::Current()->DisableWrapperTracingBarrier(); ScheduleIdleLazyCleanup(); } @@ -70,7 +70,7 @@ void ScriptWrappableMarkingVisitor::AbortTracing() { CHECK(ThreadState::Current()); should_cleanup_ = true; tracing_in_progress_ = false; - ThreadState::Current()->SetWrapperTracingInProgress(false); + ThreadState::Current()->DisableWrapperTracingBarrier(); PerformCleanup(); } @@ -196,7 +196,7 @@ bool ScriptWrappableMarkingVisitor::AdvanceTracing( CHECK(ThreadState::Current()); CHECK(!ThreadState::Current()->IsWrapperTracingForbidden()); CHECK(tracing_in_progress_); - WTF::AutoReset<bool>(&advancing_tracing_, true); + base::AutoReset<bool>(&advancing_tracing_, true); while (actions.force_completion == v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION || WTF::CurrentTimeTicksInMilliseconds() < deadline_in_ms) { @@ -209,7 +209,7 @@ bool ScriptWrappableMarkingVisitor::AdvanceTracing( } void ScriptWrappableMarkingVisitor::MarkWrapperHeader( - HeapObjectHeader* header) const { + HeapObjectHeader* header) { DCHECK(!header->IsWrapperHeaderMarked()); // Verify that no compactable & movable objects are slated for // lazy unmarking. @@ -243,7 +243,7 @@ void ScriptWrappableMarkingVisitor::WriteBarrier( } void ScriptWrappableMarkingVisitor::Visit( - const TraceWrapperV8Reference<v8::Value>& traced_wrapper) const { + const TraceWrapperV8Reference<v8::Value>& traced_wrapper) { // The write barrier may try to mark a wrapper because cleanup is still // delayed. Bail out in this case. We also allow unconditional marking which // requires us to bail out here when tracing is not in progress. @@ -253,7 +253,8 @@ void ScriptWrappableMarkingVisitor::Visit( } void ScriptWrappableMarkingVisitor::Visit( - const TraceWrapperDescriptor& wrapper_descriptor) const { + void* object, + TraceWrapperDescriptor wrapper_descriptor) { HeapObjectHeader* header = HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload); if (header->IsWrapperHeaderMarked()) @@ -271,7 +272,7 @@ void ScriptWrappableMarkingVisitor::Visit( void ScriptWrappableMarkingVisitor::Visit( DOMWrapperMap<ScriptWrappable>* wrapper_map, - const ScriptWrappable* key) const { + const ScriptWrappable* key) { wrapper_map->MarkWrapper(const_cast<ScriptWrappable*>(key)); } diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h index f2b1f44d451..89384364fd8 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_marking_visitor.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_MARKING_VISITOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_MARKING_VISITOR_H_ +#include "base/gtest_prod_util.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h" #include "third_party/blink/renderer/platform/heap/heap_page.h" #include "third_party/blink/renderer/platform/heap/threading_traits.h" @@ -55,14 +56,14 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor // alive in the current GC cycle. template <typename T> static void WriteBarrier(const T* dst_object) { - if (!dst_object) + if (!ThreadState::IsAnyWrapperTracing() || !dst_object) return; const ThreadState* thread_state = ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); DCHECK(thread_state); // Bail out if tracing is not in progress. - if (!thread_state->WrapperTracingInProgress()) + if (!thread_state->IsWrapperTracing()) return; // If the wrapper is already marked we can bail out here. @@ -71,7 +72,8 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor return; CurrentVisitor(thread_state->GetIsolate()) - ->Visit(WrapperDescriptorFor(dst_object)); + ->Visit(const_cast<T*>(dst_object), + TraceWrapperDescriptorFor(dst_object)); } static void WriteBarrier(v8::Isolate*, @@ -97,12 +99,14 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor void EnterFinalPause() override; size_t NumberOfWrappersToTrace() override; - protected: - // ScriptWrappableVisitor interface. - void Visit(const TraceWrapperV8Reference<v8::Value>&) const override; - void Visit(const TraceWrapperDescriptor&) const override; + // Visitor interface. + void Visit(const TraceWrapperV8Reference<v8::Value>&) override; + void Visit(void*, TraceWrapperDescriptor) override; void Visit(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const override; + const ScriptWrappable* key) override; + + protected: + using Visitor::Visit; v8::Isolate* isolate() const { return isolate_; } @@ -145,7 +149,7 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor TraceWrappersCallback trace_wrappers_callback_; }; - void MarkWrapperHeader(HeapObjectHeader*) const; + void MarkWrapperHeader(HeapObjectHeader*); // Schedule an idle task to perform a lazy (incremental) clean up of // wrappers. @@ -157,10 +161,7 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor // Immediately cleans up all wrappers if necessary. void PerformCleanup(); - WTF::Deque<MarkingDequeItem>* MarkingDeque() const { return &marking_deque_; } - WTF::Vector<HeapObjectHeader*>* HeadersToUnmark() const { - return &headers_to_unmark_; - } + WTF::Deque<MarkingDequeItem>* MarkingDeque() { return &marking_deque_; } bool MarkingDequeContains(void* needle); @@ -187,7 +188,7 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor // - oilpan object cannot move // - oilpan gc will call invalidateDeadObjectsInMarkingDeque to delete all // obsolete objects - mutable WTF::Deque<MarkingDequeItem> marking_deque_; + WTF::Deque<MarkingDequeItem> marking_deque_; // Collection of objects we started tracing from. We assume it is safe to // hold on to the raw pointers because: @@ -198,14 +199,14 @@ class PLATFORM_EXPORT ScriptWrappableMarkingVisitor // These objects are used when TraceWrappablesVerifier feature is enabled to // verify that all objects reachable in the atomic pause were marked // incrementally. If not, there is one or multiple write barriers missing. - mutable WTF::Deque<MarkingDequeItem> verifier_deque_; + WTF::Deque<MarkingDequeItem> verifier_deque_; // Collection of headers we need to unmark after the tracing finished. We // assume it is safe to hold on to the headers because: // - oilpan objects cannot move // - objects this headers belong to are invalidated by the oilpan GC in // invalidateDeadObjectsInMarkingDeque. - mutable WTF::Vector<HeapObjectHeader*> headers_to_unmark_; + WTF::Vector<HeapObjectHeader*> headers_to_unmark_; v8::Isolate* isolate_; FRIEND_TEST_ALL_PREFIXES(ScriptWrappableMarkingVisitorTest, MixinTracing); diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.cc b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.cc index 93fd61983f6..af91f849cf2 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.cc @@ -12,17 +12,17 @@ namespace blink { void ScriptWrappableVisitor::TraceWrappers( DOMWrapperMap<ScriptWrappable>* wrapper_map, - const ScriptWrappable* key) const { + const ScriptWrappable* key) { Visit(wrapper_map, key); } void ScriptWrappableVisitor::DispatchTraceWrappers( - const TraceWrapperBase* wrapper_base) const { + TraceWrapperBase* wrapper_base) { wrapper_base->TraceWrappers(this); } void ScriptWrappableVisitor::DispatchTraceWrappersForSupplement( - const TraceWrapperBaseForSupplement* wrapper_base) const { + TraceWrapperBaseForSupplement* wrapper_base) { wrapper_base->TraceWrappers(this); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h index 28063c81d3e..63e83d2bbd1 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h @@ -8,6 +8,7 @@ #include "third_party/blink/renderer/platform/bindings/trace_wrapper_base.h" #include "third_party/blink/renderer/platform/heap/heap_page.h" #include "third_party/blink/renderer/platform/heap/threading_traits.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/deque.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -43,18 +44,9 @@ class TraceWrapperV8Reference; // - Call visitor.DispatchTraceWrappers(traceable). // DispatchTraceWrappers will invoke Visit() method for all // wrapper references in traceable. -class PLATFORM_EXPORT ScriptWrappableVisitor { +class PLATFORM_EXPORT ScriptWrappableVisitor : public Visitor { public: - template <typename T> - static NOINLINE void MissedWriteBarrier() { - NOTREACHED(); - } - - template <typename T> - static const char* NameCallback(const void* traceable) { - // Mixns never inherit from TraceWrapperBase. - return NameInHeapSnapshot(static_cast<const T*>(traceable)); - } + ScriptWrappableVisitor() : Visitor(ThreadState::Current()) {} // Trace all wrappers of |tracable|. // @@ -62,7 +54,7 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { // for some reason (e.g., unions using raw pointers), see // |TraceWrappersWithManualWriteBarrier()| below. template <typename T> - void TraceWrappers(const TraceWrapperMember<T>& traceable) const { + void TraceWrappers(const TraceWrapperMember<T>& traceable) { static_assert(sizeof(T), "T must be fully defined"); Visit(traceable.Get()); } @@ -70,14 +62,14 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { // Enable partial tracing of objects. This is used when tracing interior // objects without their own header. template <typename T> - void TraceWrappers(const T& traceable) const { + void TraceWrappers(const T& traceable) { static_assert(sizeof(T), "T must be fully defined"); traceable.TraceWrappers(this); } // Only called from automatically generated bindings code. template <typename T> - void TraceWrappersFromGeneratedCode(const T* traceable) const { + void TraceWrappersFromGeneratedCode(const T* traceable) { Visit(traceable); } @@ -87,65 +79,62 @@ class PLATFORM_EXPORT ScriptWrappableVisitor { // assignments to the field. Otherwise, the objects may be collected // prematurely. template <typename T> - void TraceWrappersWithManualWriteBarrier(const T* traceable) const { + void TraceWrappersWithManualWriteBarrier(const T* traceable) { Visit(traceable); } template <typename V8Type> - void TraceWrappers(const TraceWrapperV8Reference<V8Type>& v8reference) const { + void TraceWrappers(const TraceWrapperV8Reference<V8Type>& v8reference) { Visit(v8reference.template Cast<v8::Value>()); } // Trace wrappers in non-main worlds. void TraceWrappers(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const; + const ScriptWrappable* key); - virtual void DispatchTraceWrappers(const TraceWrapperBase*) const; + virtual void DispatchTraceWrappers(TraceWrapperBase*); template <typename T> - void DispatchTraceWrappers(const Supplement<T>* traceable) const { - const TraceWrapperBaseForSupplement* base = traceable; + void DispatchTraceWrappers(Supplement<T>* traceable) { + TraceWrapperBaseForSupplement* base = traceable; DispatchTraceWrappersForSupplement(base); } // Catch all handlers needed because of mixins except for Supplement<T>. void DispatchTraceWrappers(const void*) const { CHECK(false); } - protected: - // The visitor interface. Derived visitors should override this - // function to visit V8 references and ScriptWrappables. - virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) const = 0; - virtual void Visit(const TraceWrapperDescriptor&) const = 0; - virtual void Visit(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const = 0; + // Unused blink::Visitor overrides. Derived visitors should still override + // the cross-component visitation methods. See Visitor documentation. + void Visit(void* object, TraceDescriptor desc) final {} + void VisitWeak(void* object, + void** object_slot, + TraceDescriptor desc, + WeakCallback callback) final {} + void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) final {} + void VisitBackingStoreWeakly(void*, + void**, + TraceDescriptor, + WeakCallback, + void*) final {} + void VisitBackingStoreOnly(void*, void**) final {} + void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {} + void RegisterWeakCallback(void*, WeakCallback) final {} - template <typename T> - static TraceWrapperDescriptor WrapperDescriptorFor(const T* traceable) { - return TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable)); - } + protected: + using Visitor::Visit; private: - static const char* NameInHeapSnapshot(const TraceWrapperBase* traceable) { - return traceable->NameInHeapSnapshot(); - } - - static const char* NameInHeapSnapshot(...) { - // Default case for all non-TraceWrapperBase classes. - return "InternalNode"; - } - // Helper method to invoke the virtual Visit method with wrapper descriptor. template <typename T> - void Visit(const T* traceable) const { + void Visit(const T* traceable) { static_assert(sizeof(T), "T must be fully defined"); if (!traceable) return; - Visit(WrapperDescriptorFor(traceable)); + Visit(const_cast<T*>(traceable), TraceWrapperDescriptorFor(traceable)); } // Supplement-specific implementation of DispatchTraceWrappers. The suffix of // "ForSupplement" is necessary not to make this member function a candidate // of overload resolutions. - void DispatchTraceWrappersForSupplement( - const TraceWrapperBaseForSupplement*) const; + void DispatchTraceWrappersForSupplement(TraceWrapperBaseForSupplement*); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h index 4bd05ffecbd..65c6b99ef79 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h +++ b/chromium/third_party/blink/renderer/platform/bindings/script_wrappable_visitor_verifier.h @@ -5,7 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_VISITOR_VERIFIER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_VISITOR_VERIFIER_H_ +#include "base/logging.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h" +#include "third_party/blink/renderer/platform/heap/gc_info.h" namespace blink { @@ -13,27 +15,35 @@ namespace blink { // after marking is complete. The Visit method checks that the given wrapper // is also marked. class ScriptWrappableVisitorVerifier final : public ScriptWrappableVisitor { - protected: - void Visit(const TraceWrapperV8Reference<v8::Value>&) const final {} - void Visit(const TraceWrapperDescriptor& descriptor) const final { - if (!HeapObjectHeader::FromPayload(descriptor.base_object_payload) - ->IsWrapperHeaderMarked()) { - // If this branch is hit, it means that a white (not discovered by - // traceWrappers) object was assigned as a member to a black object - // (already processed by traceWrappers). Black object will not be - // processed anymore so White object will remain undetected and - // therefore its wrapper and all wrappers reachable from it would be - // collected. - - // This means there is a write barrier missing somewhere. Check the - // backtrace to see which types are causing this and review all the - // places where white object is set to a black object. - descriptor.missed_write_barrier_callback(); - NOTREACHED(); - } + public: + void Visit(const TraceWrapperV8Reference<v8::Value>&) final {} + + void Visit(void* object, TraceWrapperDescriptor descriptor) final { + HeapObjectHeader* header = + HeapObjectHeader::FromPayload(descriptor.base_object_payload); + const char* name = GCInfoTable::Get() + .GCInfoFromIndex(header->GcInfoIndex()) + ->name_(descriptor.base_object_payload); + // If this FATAL is hit, it means that a white (not discovered by + // TraceWrappers) object was assigned as a member to a black object (already + // processed by TraceWrappers). The black object will not be processed + // anymore so white object will remain undetected and therefore its wrapper + // and all wrappers reachable from it would be collected. + // + // This means there is a write barrier missing somewhere. Check the + // backtrace to see which types are causing this and review all the places + // where white object is set to a black object. + LOG_IF(FATAL, !header->IsWrapperHeaderMarked()) + << "Write barrier missed for " << name; } + void Visit(DOMWrapperMap<ScriptWrappable>*, - const ScriptWrappable* key) const final {} + const ScriptWrappable* key) final {} + + protected: + using Visitor::Visit; }; -} -#endif + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_SCRIPT_WRAPPABLE_VISITOR_VERIFIER_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 13ecc792188..e0a9e26a102 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/to_v8.h +++ b/chromium/third_party/blink/renderer/platform/bindings/to_v8.h @@ -10,13 +10,14 @@ #include <utility> +#include "base/optional.h" +#include "third_party/blink/renderer/platform/bindings/callback_interface_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" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "v8/include/v8.h" namespace blink { @@ -37,6 +38,20 @@ inline v8::Local<v8::Value> ToV8(ScriptWrappable* impl, return wrapper; } +// Callback interface + +inline v8::Local<v8::Value> ToV8(CallbackInterfaceBase* callback, + v8::Local<v8::Object> creation_context, + v8::Isolate* isolate) { + // |creation_context| is intentionally ignored. Callback interface objects + // are not wrappers nor clonable. ToV8 on a callback interface object must + // be used only when it's the same origin-domain in the same world. + DCHECK(!callback || (callback->CallbackRelevantScriptState()->GetContext() == + creation_context->CreationContext())); + return callback ? callback->CallbackObject().As<v8::Value>() + : v8::Null(isolate).As<v8::Value>(); +} + // Primitives inline v8::Local<v8::Value> ToV8(const String& value, diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h index 1b36e449cc2..e35a12dcb13 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h +++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_base.h @@ -20,7 +20,7 @@ class PLATFORM_EXPORT TraceWrapperBase { ~TraceWrapperBase() = default; virtual bool IsScriptWrappable() const { return false; } - virtual void TraceWrappers(const ScriptWrappableVisitor*) const = 0; + virtual void TraceWrappers(ScriptWrappableVisitor*) const = 0; // Human-readable name of this object. The DevTools heap snapshot uses // this method to show the object. diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_member.h b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_member.h index e3e21e414b2..2d4dd707a7e 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_member.h +++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_member.h @@ -77,7 +77,8 @@ void swap(HeapVector<TraceWrapperMember<T>>& a, HeapVector<Member<T>>& a_ = reinterpret_cast<HeapVector<Member<T>>&>(a); HeapVector<Member<T>>& b_ = reinterpret_cast<HeapVector<Member<T>>&>(b); a_.swap(b_); - if (ThreadState::Current()->WrapperTracingInProgress()) { + if (ThreadState::IsAnyWrapperTracing() && + ThreadState::Current()->IsWrapperTracing()) { // If incremental marking is enabled we need to emit the write barrier since // the swap was performed on HeapVector<Member<T>>. for (auto item : a) { @@ -106,7 +107,8 @@ void swap(HeapVector<TraceWrapperMember<T>>& a, HeapVector<Member<T>>& b) { // TraceWrapperMember and Member match in vector backings. HeapVector<Member<T>>& a_ = reinterpret_cast<HeapVector<Member<T>>&>(a); a_.swap(b); - if (ThreadState::Current()->WrapperTracingInProgress()) { + if (ThreadState::IsAnyWrapperTracing() && + ThreadState::Current()->IsWrapperTracing()) { // If incremental marking is enabled we need to emit the write barrier since // the swap was performed on HeapVector<Member<T>>. for (auto item : a) { diff --git a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h index 1f637e384cb..557870aded6 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h +++ b/chromium/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_string.h @@ -32,7 +32,7 @@ class PLATFORM_EXPORT TraceWrapperV8String final : public TraceWrapperBase { void Concat(v8::Isolate*, const String&); String Flatten(v8::Isolate*) const; - void TraceWrappers(const ScriptWrappableVisitor* visitor) const override { + void TraceWrappers(ScriptWrappableVisitor* visitor) const override { visitor->TraceWrappers(string_); } const char* NameInHeapSnapshot() const override { diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h index bedf60e7099..6be7ed51cb9 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h +++ b/chromium/third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h @@ -90,7 +90,7 @@ inline void V8DOMWrapper::SetNativeInfo( int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex}; void* values[] = {script_wrappable, const_cast<WrapperTypeInfo*>(wrapper_type_info)}; - wrapper->SetAlignedPointerInInternalFields(WTF_ARRAY_LENGTH(indices), indices, + wrapper->SetAlignedPointerInInternalFields(arraysize(indices), indices, values); auto* per_isolate_data = V8PerIsolateData::From(isolate); // We notify ScriptWrappableVisitor about the new wrapper association, @@ -106,7 +106,7 @@ inline void V8DOMWrapper::ClearNativeInfo(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) { int indices[] = {kV8DOMWrapperObjectIndex, kV8DOMWrapperTypeIndex}; void* values[] = {nullptr, nullptr}; - wrapper->SetAlignedPointerInInternalFields(WTF_ARRAY_LENGTH(indices), indices, + wrapper->SetAlignedPointerInInternalFields(arraysize(indices), indices, values); } diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc index 9d46e4800b8..87f2176ce89 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/v8_object_constructor.cc @@ -44,8 +44,12 @@ v8::MaybeLocal<v8::Object> V8ObjectConstructor::NewInstance( ConstructorMode constructor_mode(isolate); v8::MicrotasksScope microtasks_scope( isolate, v8::MicrotasksScope::kDoNotRunMicrotasks); - v8::MaybeLocal<v8::Object> result = - function->NewInstance(isolate->GetCurrentContext(), argc, argv); + // Construct without side effect only in ConstructorMode::kWrapExistingObject + // cases. This allows whitelisted methods to correctly set return values + // without invoking Blink's internal constructors. + v8::MaybeLocal<v8::Object> result = function->NewInstanceWithSideEffectType( + isolate->GetCurrentContext(), argc, argv, + v8::SideEffectType::kHasNoSideEffect); CHECK(!isolate->IsDead()); return result; } diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc b/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc index f137b259824..6116a9471e7 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc +++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.cc @@ -49,7 +49,8 @@ V8PerContextData::V8PerContextData(v8::Local<v8::Context> context) constructor_map_(isolate_), context_holder_(std::make_unique<gin::ContextHolder>(isolate_)), context_(isolate_, context), - activity_logger_(nullptr) { + activity_logger_(nullptr), + data_map_(new DataMap()) { context_holder_->SetContext(context); context_.Get().AnnotateStrongRetainer("blink::V8PerContextData::context_"); @@ -140,15 +141,15 @@ void V8PerContextData::AddCustomElementBinding( } void V8PerContextData::AddData(const char* key, Data* data) { - data_map_.Set(key, data); + data_map_->Set(key, data); } void V8PerContextData::ClearData(const char* key) { - data_map_.erase(key); + data_map_->erase(key); } V8PerContextData::Data* V8PerContextData::GetData(const char* key) { - return data_map_.at(key); + return data_map_->at(key); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.h b/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.h index 719ff9841d0..939b5f71fd1 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.h +++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_context_data.h @@ -160,8 +160,8 @@ class PLATFORM_EXPORT V8PerContextData final { // This is owned by a static hash map in V8DOMActivityLogger. V8DOMActivityLogger* activity_logger_; - using DataMap = PersistentHeapHashMap<const char*, Member<Data>>; - DataMap data_map_; + using DataMap = HeapHashMap<const char*, Member<Data>>; + Persistent<DataMap> data_map_; }; } // namespace blink 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 a05468a6fd0..108efb6d07e 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 @@ -71,7 +71,8 @@ V8PerIsolateData::V8PerIsolateData( use_counter_disabled_(false), is_handling_recursion_level_error_(false), is_reporting_exception_(false), - runtime_call_stats_(base::DefaultTickClock::GetInstance()) { + runtime_call_stats_(base::DefaultTickClock::GetInstance()), + handled_near_v8_heap_limit_(false) { // FIXME: Remove once all v8::Isolate::GetCurrent() calls are gone. GetIsolate()->Enter(); GetIsolate()->AddBeforeCallEnteredCallback(&BeforeCallEnteredCallback); @@ -95,7 +96,8 @@ V8PerIsolateData::V8PerIsolateData() use_counter_disabled_(false), is_handling_recursion_level_error_(false), is_reporting_exception_(false), - runtime_call_stats_(base::DefaultTickClock::GetInstance()) { + runtime_call_stats_(base::DefaultTickClock::GetInstance()), + handled_near_v8_heap_limit_(false) { CHECK(IsMainThread()); // SnapshotCreator enters the isolate, so we don't call Isolate::Enter() here. @@ -142,6 +144,12 @@ void V8PerIsolateData::WillBeDestroyed(v8::Isolate* isolate) { data->ClearEndOfScopeTasks(); data->active_script_wrappables_.Clear(); + + // Detach V8's garbage collector. + isolate->SetEmbedderHeapTracer(nullptr); + if (data->script_wrappable_visitor_->WrapperTracingInProgress()) + data->script_wrappable_visitor_->AbortTracing(); + data->script_wrappable_visitor_.reset(); } // destroy() clear things that should be cleared after ThreadState::detach() diff --git a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h index c150c179cee..5b22a053a3e 100644 --- a/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h +++ b/chromium/third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h @@ -28,6 +28,7 @@ #include <memory> +#include "base/single_thread_task_runner.h" #include "base/time/default_tick_clock.h" #include "gin/public/isolate_holder.h" #include "gin/public/v8_idle_task_runner.h" @@ -233,6 +234,9 @@ class PLATFORM_EXPORT V8PerIsolateData { ScriptWrappableMarkingVisitor* GetScriptWrappableMarkingVisitor() { return script_wrappable_visitor_.get(); } + int IsNearV8HeapLimitHandled() { return handled_near_v8_heap_limit_; } + + void HandledNearV8HeapLimit() { handled_near_v8_heap_limit_ = true; } private: V8PerIsolateData(scoped_refptr<base::SingleThreadTaskRunner>, @@ -304,6 +308,7 @@ class PLATFORM_EXPORT V8PerIsolateData { std::unique_ptr<ScriptWrappableMarkingVisitor> script_wrappable_visitor_; RuntimeCallStats runtime_call_stats_; + bool handled_near_v8_heap_limit_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/blob/DEPS b/chromium/third_party/blink/renderer/platform/blob/DEPS new file mode 100644 index 00000000000..24f75939c14 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/blob/DEPS @@ -0,0 +1,21 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/blob", + + # Dependencies. + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/file_metadata.h", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/text/line_ending.h", + "+third_party/blink/renderer/platform/uuid.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc index 70a61b5ac9f..b052941e0f6 100644 --- a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc +++ b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.cc @@ -188,7 +188,7 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset, ("Storage.Blob.RendererFileWriteFailed")); if (!file.IsValid()) { - std::move(callback).Run(WTF::nullopt); + std::move(callback).Run(base::nullopt); return; } @@ -197,7 +197,7 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset, bool seek_failed = seek_distance < 0; seek_histogram.Count(seek_failed); if (seek_failed) { - std::move(callback).Run(WTF::nullopt); + std::move(callback).Run(base::nullopt); return; } @@ -231,7 +231,7 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset, bool write_failed = actual_written < 0; write_histogram.Count(write_failed); if (write_failed) { - std::move(callback).Run(WTF::nullopt); + std::move(callback).Run(base::nullopt); return; } written += actual_written; @@ -241,12 +241,12 @@ void BlobBytesProvider::RequestAsFile(uint64_t source_offset, } if (!file.Flush()) { - std::move(callback).Run(WTF::nullopt); + std::move(callback).Run(base::nullopt); return; } base::File::Info info; if (!file.GetInfo(&info)) { - std::move(callback).Run(WTF::nullopt); + std::move(callback).Run(base::nullopt); return; } std::move(callback).Run(info.last_modified); diff --git a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.h b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.h index 9799b034291..a66f1f1780a 100644 --- a/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.h +++ b/chromium/third_party/blink/renderer/platform/blob/blob_bytes_provider.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BLOB_BLOB_BYTES_PROVIDER_H_ +#include "base/sequenced_task_runner.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h" #include "third_party/blink/renderer/platform/blob/blob_data.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 51cddb2949c..c591eb8edab 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 @@ -136,14 +136,14 @@ class RequestAsFile : public BlobBytesProviderTest, uint64_t file_offset) { base::FilePath path; base::CreateTemporaryFile(&path); - WTF::Optional<WTF::Time> received_modified; + base::Optional<WTF::Time> received_modified; test_provider_->RequestAsFile( source_offset, source_length, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), file_offset, base::BindOnce( - [](WTF::Optional<WTF::Time>* received_modified, - WTF::Optional<WTF::Time> modified) { + [](base::Optional<WTF::Time>* received_modified, + base::Optional<WTF::Time> modified) { *received_modified = modified; }, &received_modified)); @@ -218,7 +218,7 @@ TEST_P(RequestAsFile, OffsetInNonEmptyFile) { test_provider_->RequestAsFile( test.offset, test.size, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), - file_offset, base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { + file_offset, base::BindOnce([](base::Optional<WTF::Time> last_modified) { EXPECT_TRUE(last_modified); })); @@ -265,7 +265,7 @@ TEST_F(BlobBytesProviderTest, RequestAsFile_MultipleChunks) { provider->RequestAsFile( i, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), combined_bytes_.size() - i - 16, - base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<WTF::Time> last_modified) { EXPECT_TRUE(last_modified); })); expected_data.insert(0, combined_bytes_.data() + i, 16); @@ -289,7 +289,7 @@ TEST_F(BlobBytesProviderTest, RequestAsFile_InvaldFile) { provider->RequestAsFile( 0, 16, base::File(), 0, - base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<WTF::Time> last_modified) { EXPECT_FALSE(last_modified); })); } @@ -301,7 +301,7 @@ TEST_F(BlobBytesProviderTest, RequestAsFile_UnwritableFile) { base::CreateTemporaryFile(&path); provider->RequestAsFile( 0, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ), 0, - base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](base::Optional<WTF::Time> last_modified) { EXPECT_FALSE(last_modified); })); 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 2ba38d77230..ba69654a506 100644 --- a/chromium/third_party/blink/renderer/platform/blob/blob_data.cc +++ b/chromium/third_party/blink/renderer/platform/blob/blob_data.cc @@ -282,14 +282,14 @@ void BlobData::AppendDataInternal(base::span<const char> data, current_memory_population_ += data.size(); } else if (bytes_element->embedded_data) { current_memory_population_ -= bytes_element->embedded_data->size(); - bytes_element->embedded_data = WTF::nullopt; + bytes_element->embedded_data = base::nullopt; } } else { BytesProviderPtrInfo bytes_provider_info; last_bytes_provider_ = BlobBytesProvider::CreateAndBind(MakeRequest(&bytes_provider_info)); - auto bytes_element = DataElementBytes::New(data.size(), WTF::nullopt, + auto bytes_element = DataElementBytes::New(data.size(), base::nullopt, std::move(bytes_provider_info)); if (should_embed_bytes) { bytes_element->embedded_data = Vector<uint8_t>(); 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 af5cc3c8089..0d9df2bf3c8 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 @@ -51,7 +51,7 @@ struct ExpectedElement { static ExpectedElement LargeBytes(Vector<uint8_t> data) { uint64_t size = data.size(); return ExpectedElement{DataElement::NewBytes(DataElementBytes::New( - size, WTF::nullopt, nullptr)), + size, base::nullopt, nullptr)), String(), std::move(data)}; } @@ -89,7 +89,9 @@ class BlobDataHandleTest : public testing::Test { BlobDataHandle::SetBlobRegistryForTesting(blob_registry_ptr_.get()); } - ~BlobDataHandleTest() { BlobDataHandle::SetBlobRegistryForTesting(nullptr); } + ~BlobDataHandleTest() override { + BlobDataHandle::SetBlobRegistryForTesting(nullptr); + } void SetUp() override { small_test_data_.resize(1024); diff --git a/chromium/third_party/blink/renderer/platform/clipboard/DEPS b/chromium/third_party/blink/renderer/platform/clipboard/DEPS new file mode 100644 index 00000000000..715fce4a84b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/clipboard/DEPS @@ -0,0 +1,12 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/clipboard", + + # Dependencies. + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/weborigin/kurl.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.cc b/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.cc index fab14200560..058b9098c9f 100644 --- a/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.cc +++ b/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.cc @@ -30,7 +30,10 @@ #include "third_party/blink/renderer/platform/clipboard/clipboard_utilities.h" +#include "net/base/escape.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -62,4 +65,27 @@ String ConvertURIListToURL(const String& uri_list) { return String(); } +static String EscapeForHTML(const String& str) { + std::string output = + net::EscapeForHTML(StringUTF8Adaptor(str).AsStringPiece()); + return String(output.c_str()); +} + +// TODO(slangley): crbug.com/775830. Remove the implementation of +// URLToImageMarkup from clipboard_utils.h once we can delete +// MockClipboard. +String URLToImageMarkup(const KURL& url, const String& title) { + StringBuilder builder; + builder.Append("<img src=\""); + builder.Append(EscapeForHTML(url.GetString())); + builder.Append("\""); + if (!title.IsEmpty()) { + builder.Append(" alt=\""); + builder.Append(EscapeForHTML(title)); + builder.Append("\""); + } + builder.Append("/>"); + return builder.ToString(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.h b/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.h index fafd6dd44b8..514bc6f24bf 100644 --- a/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.h +++ b/chromium/third_party/blink/renderer/platform/clipboard/clipboard_utilities.h @@ -33,6 +33,7 @@ #include "build/build_config.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/forward.h" namespace blink { @@ -42,6 +43,7 @@ PLATFORM_EXPORT void ReplaceNewlinesWithWindowsStyleNewlines(String&); #endif PLATFORM_EXPORT void ReplaceNBSPWithSpace(String&); PLATFORM_EXPORT String ConvertURIListToURL(const String& uri_list); +PLATFORM_EXPORT String URLToImageMarkup(const KURL&, const String& title); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/context_menu.cc b/chromium/third_party/blink/renderer/platform/context_menu.cc deleted file mode 100644 index 689525b9284..00000000000 --- a/chromium/third_party/blink/renderer/platform/context_menu.cc +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2010 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 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/renderer/platform/context_menu.h" - -namespace blink { - -static const ContextMenuItem* FindItemWithAction( - unsigned action, - const Vector<ContextMenuItem>& items) { - for (size_t i = 0; i < items.size(); ++i) { - const ContextMenuItem& item = items[i]; - if (item.Action() == static_cast<ContextMenuAction>(action)) - return &item; - if (item.GetType() != kSubmenuType) - continue; - if (const ContextMenuItem* sub_menu_item = - FindItemWithAction(action, item.SubMenuItems())) - return sub_menu_item; - } - - return nullptr; -} - -const ContextMenuItem* ContextMenu::ItemWithAction(unsigned action) const { - return FindItemWithAction(action, items_); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/context_menu.h b/chromium/third_party/blink/renderer/platform/context_menu.h deleted file mode 100644 index a591bff7888..00000000000 --- a/chromium/third_party/blink/renderer/platform/context_menu.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, 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_CONTEXT_MENU_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_MENU_H_ - -#include "third_party/blink/renderer/platform/context_menu_item.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class PLATFORM_EXPORT ContextMenu { - WTF_MAKE_NONCOPYABLE(ContextMenu); - USING_FAST_MALLOC(ContextMenu); - - public: - ContextMenu() = default; - const ContextMenuItem* ItemWithAction(unsigned) const; - const Vector<ContextMenuItem>& Items() const { return items_; } - void AppendItem(const ContextMenuItem& item) { items_.push_back(item); } - void RemoveLastItem() { items_.pop_back(); } - - private: - Vector<ContextMenuItem> items_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_MENU_H_ diff --git a/chromium/third_party/blink/renderer/platform/context_menu_item.cc b/chromium/third_party/blink/renderer/platform/context_menu_item.cc deleted file mode 100644 index 9bc41ac2303..00000000000 --- a/chromium/third_party/blink/renderer/platform/context_menu_item.cc +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2010 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 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/renderer/platform/context_menu_item.h" - -#include "third_party/blink/renderer/platform/context_menu.h" - -namespace blink { - -ContextMenuItem::ContextMenuItem(ContextMenuItemType type, - ContextMenuAction action, - const String& title, - ContextMenu* sub_menu) - : type_(type), - action_(action), - title_(title), - enabled_(true), - checked_(false) { - if (sub_menu) - SetSubMenu(sub_menu); -} - -ContextMenuItem::ContextMenuItem(ContextMenuItemType type, - ContextMenuAction action, - const String& title, - bool enabled, - bool checked) - : type_(type), - action_(action), - title_(title), - enabled_(enabled), - checked_(checked) {} - -ContextMenuItem::ContextMenuItem(ContextMenuAction action, - const String& title, - bool enabled, - bool checked, - const Vector<ContextMenuItem>& sub_menu_items) - : type_(kSubmenuType), - action_(action), - title_(title), - enabled_(enabled), - checked_(checked), - sub_menu_items_(sub_menu_items) {} - -ContextMenuItem::~ContextMenuItem() = default; - -void ContextMenuItem::SetSubMenu(ContextMenu* sub_menu) { - if (sub_menu) { - type_ = kSubmenuType; - sub_menu_items_ = sub_menu->Items(); - } else { - type_ = kActionType; - sub_menu_items_.clear(); - } -} - -void ContextMenuItem::SetType(ContextMenuItemType type) { - type_ = type; -} - -ContextMenuItemType ContextMenuItem::GetType() const { - return type_; -} - -void ContextMenuItem::SetAction(ContextMenuAction action) { - action_ = action; -} - -ContextMenuAction ContextMenuItem::Action() const { - return action_; -} - -void ContextMenuItem::SetChecked(bool checked) { - checked_ = checked; -} - -bool ContextMenuItem::Checked() const { - return checked_; -} - -void ContextMenuItem::SetEnabled(bool enabled) { - enabled_ = enabled; -} - -bool ContextMenuItem::Enabled() const { - return enabled_; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/context_menu_item.h b/chromium/third_party/blink/renderer/platform/context_menu_item.h deleted file mode 100644 index 9765d45989f..00000000000 --- a/chromium/third_party/blink/renderer/platform/context_menu_item.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2010 Igalia S.L - * - * 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_CONTEXT_MENU_ITEM_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_MENU_ITEM_H_ - -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -class ContextMenu; - -enum ContextMenuAction { - kContextMenuItemBaseCustomTag = 5000, - kContextMenuItemCustomTagNoAction = 5998, - kContextMenuItemLastCustomTag = 5999 -}; - -enum ContextMenuItemType { - kActionType, - kCheckableActionType, - kSeparatorType, - kSubmenuType -}; - -class PLATFORM_EXPORT ContextMenuItem { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - - public: - ContextMenuItem(ContextMenuItemType, - ContextMenuAction, - const String& title, - ContextMenu* sub_menu = nullptr); - ContextMenuItem(ContextMenuItemType, - ContextMenuAction, - const String& title, - bool enabled, - bool checked); - - ~ContextMenuItem(); - - void SetType(ContextMenuItemType); - ContextMenuItemType GetType() const; - - void SetAction(ContextMenuAction); - ContextMenuAction Action() const; - - void SetChecked(bool = true); - bool Checked() const; - - void SetEnabled(bool = true); - bool Enabled() const; - - void SetSubMenu(ContextMenu*); - - ContextMenuItem(ContextMenuAction, - const String&, - bool enabled, - bool checked, - const Vector<ContextMenuItem>& sub_menu_items); - - void SetTitle(const String& title) { title_ = title; } - const String& Title() const { return title_; } - - const Vector<ContextMenuItem>& SubMenuItems() const { - return sub_menu_items_; - } - - private: - ContextMenuItemType type_; - ContextMenuAction action_; - String title_; - bool enabled_; - bool checked_; - Vector<ContextMenuItem> sub_menu_items_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_CONTEXT_MENU_ITEM_H_ diff --git a/chromium/third_party/blink/renderer/platform/drag_image.cc b/chromium/third_party/blink/renderer/platform/drag_image.cc index fb724c6a7b1..7354e4f82ec 100644 --- a/chromium/third_party/blink/renderer/platform/drag_image.cc +++ b/chromium/third_party/blink/renderer/platform/drag_image.cc @@ -36,6 +36,8 @@ #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" #include "third_party/blink/renderer/platform/fonts/font_metrics.h" +#include "third_party/blink/renderer/platform/fonts/string_truncator.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/int_point.h" @@ -47,7 +49,6 @@ #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/bidi_text_run.h" -#include "third_party/blink/renderer/platform/text/string_truncator.h" #include "third_party/blink/renderer/platform/text/text_run.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" diff --git a/chromium/third_party/blink/renderer/platform/event_dispatch_forbidden_scope.h b/chromium/third_party/blink/renderer/platform/event_dispatch_forbidden_scope.h index 7fb24f2ef23..385807ee887 100644 --- a/chromium/third_party/blink/renderer/platform/event_dispatch_forbidden_scope.h +++ b/chromium/third_party/blink/renderer/platform/event_dispatch_forbidden_scope.h @@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EVENT_DISPATCH_FORBIDDEN_SCOPE_H_ +#include "base/auto_reset.h" #include "base/macros.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" namespace blink { @@ -45,7 +45,7 @@ class EventDispatchForbiddenScope { ~AllowUserAgentEvents() { DCHECK(!count_); } - AutoReset<unsigned> change_; + base::AutoReset<unsigned> change_; }; private: diff --git a/chromium/third_party/blink/renderer/platform/exported/interface_registry.cc b/chromium/third_party/blink/renderer/platform/exported/interface_registry.cc index 002c2a68886..f3c23fb9866 100644 --- a/chromium/third_party/blink/renderer/platform/exported/interface_registry.cc +++ b/chromium/third_party/blink/renderer/platform/exported/interface_registry.cc @@ -4,6 +4,7 @@ #include "third_party/blink/public/platform/interface_registry.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" 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 b15478a499f..d7019cbeeff 100644 --- a/chromium/third_party/blink/renderer/platform/exported/platform.cc +++ b/chromium/third_party/blink/renderer/platform/exported/platform.cc @@ -37,9 +37,7 @@ #include "base/trace_event/memory_dump_manager.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/interface_provider.h" -#include "third_party/blink/public/common/origin_trials/trial_policy.h" #include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/modules/serviceworker/web_service_worker_cache_storage.h" #include "third_party/blink/public/platform/modules/webmidi/web_midi_accessor.h" #include "third_party/blink/public/platform/web_canvas_capture_handler.h" #include "third_party/blink/public/platform/web_gesture_curve.h" @@ -50,11 +48,9 @@ #include "third_party/blink/public/platform/web_prerendering_support.h" #include "third_party/blink/public/platform/web_rtc_certificate_generator.h" #include "third_party/blink/public/platform/web_rtc_peer_connection_handler.h" -#include "third_party/blink/public/platform/web_socket_handshake_throttle.h" #include "third_party/blink/public/platform/web_storage_namespace.h" #include "third_party/blink/public/platform/web_thread.h" -#include "third_party/blink/public/platform/web_trial_token_validator.h" -#include "third_party/blink/renderer/platform/exported/web_clipboard_impl.h" +#include "third_party/blink/public/platform/websocket_handshake_throttle.h" #include "third_party/blink/renderer/platform/font_family_names.h" #include "third_party/blink/renderer/platform/fonts/font_cache_memory_dump_provider.h" #include "third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h" @@ -205,11 +201,6 @@ std::unique_ptr<WebStorageNamespace> Platform::CreateSessionStorageNamespace( return nullptr; } -std::unique_ptr<WebServiceWorkerCacheStorage> Platform::CreateCacheStorage( - service_manager::InterfaceProvider* mojo_provider) { - return nullptr; -} - std::unique_ptr<WebThread> Platform::CreateThread( const WebThreadCreationParams& params) { return nullptr; @@ -223,7 +214,6 @@ std::unique_ptr<WebGraphicsContext3DProvider> Platform::CreateOffscreenGraphicsContext3DProvider( const Platform::ContextAttributes&, const WebURL& top_document_url, - WebGraphicsContext3DProvider* share_context, Platform::GraphicsInfo*) { return nullptr; }; @@ -279,14 +269,4 @@ Platform::CreateImageCaptureFrameGrabber() { return nullptr; } -std::unique_ptr<WebTrialTokenValidator> Platform::CreateTrialTokenValidator() { - return nullptr; -} - -// TODO(slangley): Remove this once we can get pepper to use mojo directly. -WebClipboard* Platform::Clipboard() { - DEFINE_STATIC_LOCAL(WebClipboardImpl, clipboard, ()); - return &clipboard; -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.cc b/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.cc index 30efc50e56b..b12a86bde76 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.cc @@ -38,7 +38,7 @@ std::unique_ptr<WebActiveGestureAnimation> WebActiveGestureAnimation::CreateWithTimeOffset( std::unique_ptr<WebGestureCurve> curve, WebGestureCurveTarget* target, - double start_time) { + base::TimeTicks start_time) { return base::WrapUnique( new WebActiveGestureAnimation(std::move(curve), target, start_time)); } @@ -48,13 +48,16 @@ WebActiveGestureAnimation::~WebActiveGestureAnimation() = default; WebActiveGestureAnimation::WebActiveGestureAnimation( std::unique_ptr<WebGestureCurve> curve, WebGestureCurveTarget* target, - double start_time) + base::TimeTicks start_time) : start_time_(start_time), curve_(std::move(curve)), target_(target) {} -bool WebActiveGestureAnimation::Animate(double time) { +bool WebActiveGestureAnimation::Animate(base::TimeTicks time) { // All WebGestureCurves assume zero-based time, so we subtract // the animation start time before passing to the curve. - return curve_->AdvanceAndApplyToTarget(time - start_time_, target_); + // TODO(dcheng): WebGestureCurve should be using base::TimeDelta to represent + // this. + return curve_->AdvanceAndApplyToTarget((time - start_time_).InSecondsF(), + target_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.h b/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.h index 00d963602b6..1b5f6b121c9 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.h +++ b/chromium/third_party/blink/renderer/platform/exported/web_active_gesture_animation.h @@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_ACTIVE_GESTURE_ANIMATION_H_ #include <memory> +#include "base/time/time.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" @@ -49,18 +50,18 @@ class PLATFORM_EXPORT WebActiveGestureAnimation { static std::unique_ptr<WebActiveGestureAnimation> CreateWithTimeOffset( std::unique_ptr<WebGestureCurve>, WebGestureCurveTarget*, - double start_time); + base::TimeTicks start_time); ~WebActiveGestureAnimation(); - bool Animate(double time); + bool Animate(base::TimeTicks); private: // Assumes a valid WebGestureCurveTarget that outlives the animation. WebActiveGestureAnimation(std::unique_ptr<WebGestureCurve>, WebGestureCurveTarget*, - double start_time); + base::TimeTicks start_time); - double start_time_; + base::TimeTicks start_time_; std::unique_ptr<WebGestureCurve> curve_; WebGestureCurveTarget* target_; }; diff --git a/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc b/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc deleted file mode 100644 index fadda48a8aa..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.cc +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/exported/web_clipboard_impl.h" - -#include "build/build_config.h" -#include "mojo/public/cpp/system/platform_handle.h" -#include "net/base/escape.h" -#include "services/service_manager/public/cpp/connector.h" -#include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_drag_data.h" -#include "third_party/blink/public/platform/web_image.h" -#include "third_party/blink/public/platform/web_size.h" -#include "third_party/blink/public/platform/web_string.h" -#include "third_party/blink/public/platform/web_url.h" -#include "third_party/blink/public/platform/web_vector.h" -#include "third_party/blink/renderer/platform/blob/blob_data.h" -#include "third_party/blink/renderer/platform/clipboard/clipboard_mime_types.h" -#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" - -namespace blink { - -namespace { - -struct DragData { - WTF::String text; - WTF::String html; - WTF::HashMap<WTF::String, WTF::String> custom_data; -}; - -// This plagiarizes the logic in DropDataBuilder::Build, but only extracts the -// data needed for the implementation of WriteDataObject. -// TODO(slangley): Use a mojo struct to send web_drag_data and allow receiving -// side to extract the data required. -DragData BuildDragData(const WebDragData& web_drag_data) { - DragData result; - - const WebVector<WebDragData::Item>& item_list = web_drag_data.Items(); - for (size_t i = 0; i < item_list.size(); ++i) { - const WebDragData::Item& item = item_list[i]; - if (item.storage_type == WebDragData::Item::kStorageTypeString) { - if (item.string_type == blink::kMimeTypeTextPlain) { - result.text = item.string_data; - } else if (item.string_type == blink::kMimeTypeTextHTML) { - result.html = item.string_data; - } else if (item.string_type != blink::kMimeTypeTextURIList && - item.string_type != blink::kMimeTypeDownloadURL) { - result.custom_data.insert(item.string_type, item.string_data); - } - } - } - - return result; -}; - -String EscapeForHTML(const String& str) { - std::string output = - net::EscapeForHTML(StringUTF8Adaptor(str).AsStringPiece()); - return String(output.c_str()); -} -// TODO(slangley): crbug.com/775830 Remove the implementation of -// URLToImageMarkup from clipboard_utils.h once we can delete -// MockWebClipboardImpl. -WTF::String URLToImageMarkup(const WebURL& url, const WTF::String& title) { - WTF::String markup("<img src=\""); - markup.append(EscapeForHTML(url.GetString())); - markup.append("\""); - if (!title.IsEmpty()) { - markup.append(" alt=\""); - markup.append(EscapeForHTML(title)); - markup.append("\""); - } - markup.append("/>"); - return markup; -} - -String EnsureNotNullWTFString(const WebString& string) { - String result = string; - if (result.IsNull()) { - return g_empty_string16_bit; - } - return result; -} - -} // namespace - -WebClipboardImpl::WebClipboardImpl() { - Platform::Current()->GetConnector()->BindInterface( - Platform::Current()->GetBrowserServiceName(), &clipboard_); -} - -WebClipboardImpl::~WebClipboardImpl() = default; - -uint64_t WebClipboardImpl::SequenceNumber(mojom::ClipboardBuffer buffer) { - uint64_t result = 0; - if (!IsValidBufferType(buffer)) - return 0; - - clipboard_->GetSequenceNumber(buffer, &result); - return result; -} - -bool WebClipboardImpl::IsFormatAvailable(mojom::ClipboardFormat format, - mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) - return false; - - bool result = false; - clipboard_->IsFormatAvailable(format, buffer, &result); - return result; -} - -WebVector<WebString> WebClipboardImpl::ReadAvailableTypes( - mojom::ClipboardBuffer buffer, - bool* contains_filenames) { - WTF::Vector<WTF::String> types; - if (IsValidBufferType(buffer)) { - clipboard_->ReadAvailableTypes(buffer, &types, contains_filenames); - } - return types; -} - -WebString WebClipboardImpl::ReadPlainText(mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) - return WebString(); - - WTF::String text; - clipboard_->ReadText(buffer, &text); - return text; -} - -WebString WebClipboardImpl::ReadHTML(mojom::ClipboardBuffer buffer, - WebURL* source_url, - unsigned* fragment_start, - unsigned* fragment_end) { - if (!IsValidBufferType(buffer)) - return WebString(); - - WTF::String html_stdstr; - KURL gurl; - clipboard_->ReadHtml(buffer, &html_stdstr, &gurl, - static_cast<uint32_t*>(fragment_start), - static_cast<uint32_t*>(fragment_end)); - *source_url = gurl; - return html_stdstr; -} - -WebString WebClipboardImpl::ReadRTF(mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) - return WebString(); - - WTF::String rtf; - clipboard_->ReadRtf(buffer, &rtf); - return rtf; -} - -WebBlobInfo WebClipboardImpl::ReadImage(mojom::ClipboardBuffer buffer) { - if (!IsValidBufferType(buffer)) - return WebBlobInfo(); - - scoped_refptr<BlobDataHandle> blob; - clipboard_->ReadImage(buffer, &blob); - if (!blob) - return WebBlobInfo(); - return blob; -} - -WebString WebClipboardImpl::ReadCustomData(mojom::ClipboardBuffer buffer, - const WebString& type) { - if (!IsValidBufferType(buffer)) - return WebString(); - - WTF::String data; - clipboard_->ReadCustomData(buffer, EnsureNotNullWTFString(type), &data); - return data; -} - -void WebClipboardImpl::WritePlainText(const WebString& plain_text) { - clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, plain_text); - clipboard_->CommitWrite(mojom::ClipboardBuffer::kStandard); -} - -void WebClipboardImpl::WriteHTML(const WebString& html_text, - const WebURL& source_url, - const WebString& plain_text, - bool write_smart_paste) { - clipboard_->WriteHtml(mojom::ClipboardBuffer::kStandard, html_text, - source_url); - clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, plain_text); - - if (write_smart_paste) - clipboard_->WriteSmartPasteMarker(mojom::ClipboardBuffer::kStandard); - clipboard_->CommitWrite(mojom::ClipboardBuffer::kStandard); -} - -void WebClipboardImpl::WriteImage(const WebImage& image, - const WebURL& url, - const WebString& title) { - DCHECK(!image.IsNull()); - if (!WriteImageToClipboard(mojom::ClipboardBuffer::kStandard, - image.GetSkBitmap())) - return; - - if (url.IsValid() && !url.IsEmpty()) { - clipboard_->WriteBookmark(mojom::ClipboardBuffer::kStandard, - url.GetString(), EnsureNotNullWTFString(title)); - - // When writing the image, we also write the image markup so that pasting - // into rich text editors, such as Gmail, reveals the image. We also don't - // want to call writeText(), since some applications (WordPad) don't pick - // the image if there is also a text format on the clipboard. - clipboard_->WriteHtml(mojom::ClipboardBuffer::kStandard, - URLToImageMarkup(url, title), KURL()); - } - clipboard_->CommitWrite(mojom::ClipboardBuffer::kStandard); -} - -void WebClipboardImpl::WriteDataObject(const WebDragData& data) { - const DragData& drag_data = BuildDragData(data); - // TODO(dcheng): Properly support text/uri-list here. - // Avoid calling the WriteFoo functions if there is no data associated with a - // type. This prevents stomping on clipboard contents that might have been - // written by extension functions such as chrome.bookmarkManagerPrivate.copy. - if (!drag_data.text.IsNull()) { - clipboard_->WriteText(mojom::ClipboardBuffer::kStandard, drag_data.text); - } - if (!drag_data.html.IsNull()) { - clipboard_->WriteHtml(mojom::ClipboardBuffer::kStandard, drag_data.html, - KURL()); - } - if (!drag_data.custom_data.IsEmpty()) { - clipboard_->WriteCustomData(mojom::ClipboardBuffer::kStandard, - std::move(drag_data.custom_data)); - } - clipboard_->CommitWrite(mojom::ClipboardBuffer::kStandard); -} - -bool WebClipboardImpl::IsValidBufferType(mojom::ClipboardBuffer buffer) { - switch (buffer) { - case mojom::ClipboardBuffer::kStandard: - return true; - case mojom::ClipboardBuffer::kSelection: -#if defined(USE_X11) - return true; -#else - // Chrome OS and non-X11 unix builds do not support - // the X selection clipboad. - // TODO: remove the need for this case, see http://crbug.com/361753 - return false; -#endif - } - return true; -} - -bool WebClipboardImpl::WriteImageToClipboard(mojom::ClipboardBuffer buffer, - const SkBitmap& bitmap) { - // Only 32-bit bitmaps are supported. - DCHECK_EQ(bitmap.colorType(), kN32_SkColorType); - - const WebSize size(bitmap.width(), bitmap.height()); - - void* pixels = bitmap.getPixels(); - // TODO(piman): this should not be NULL, but it is. crbug.com/369621 - if (!pixels) - return false; - - base::CheckedNumeric<uint32_t> checked_buf_size = 4; - checked_buf_size *= size.width; - checked_buf_size *= size.height; - if (!checked_buf_size.IsValid()) - return false; - - // Allocate a shared memory buffer to hold the bitmap bits. - uint32_t buf_size = checked_buf_size.ValueOrDie(); - auto shared_buffer = mojo::SharedBufferHandle::Create(buf_size); - auto mapping = shared_buffer->Map(buf_size); - memcpy(mapping.get(), pixels, buf_size); - - clipboard_->WriteImage(buffer, size, std::move(shared_buffer)); - return true; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.h b/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.h deleted file mode 100644 index 8bf6c2e96e3..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_clipboard_impl.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 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_EXPORTED_WEB_CLIPBOARD_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_CLIPBOARD_IMPL_H_ - -#include <stdint.h> - -#include <string> - -#include "third_party/blink/public/mojom/clipboard/clipboard.mojom-blink.h" -#include "third_party/blink/public/platform/web_clipboard.h" - -namespace blink { - -class WebClipboardImpl : public blink::WebClipboard { - public: - WebClipboardImpl(); - virtual ~WebClipboardImpl(); - - // WebClipboard methods: - uint64_t SequenceNumber(mojom::ClipboardBuffer) override; - bool IsFormatAvailable(mojom::ClipboardFormat, - mojom::ClipboardBuffer) override; - blink::WebVector<blink::WebString> ReadAvailableTypes( - mojom::ClipboardBuffer, - bool* contains_filenames) override; - blink::WebString ReadPlainText(mojom::ClipboardBuffer) override; - blink::WebString ReadHTML(mojom::ClipboardBuffer, - blink::WebURL* source_url, - unsigned* fragment_start, - unsigned* fragment_end) override; - blink::WebString ReadRTF(mojom::ClipboardBuffer) override; - blink::WebBlobInfo ReadImage(mojom::ClipboardBuffer) override; - blink::WebString ReadCustomData(mojom::ClipboardBuffer, - const blink::WebString& type) override; - void WritePlainText(const blink::WebString& plain_text) override; - void WriteHTML(const blink::WebString& html_text, - const blink::WebURL& source_url, - const blink::WebString& plain_text, - bool write_smart_paste) override; - void WriteImage(const blink::WebImage&, - const blink::WebURL& source_url, - const blink::WebString& title) override; - void WriteDataObject(const blink::WebDragData&) override; - - private: - bool IsValidBufferType(mojom::ClipboardBuffer); - bool WriteImageToClipboard(mojom::ClipboardBuffer, const SkBitmap&); - mojom::blink::ClipboardHostPtr clipboard_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_CLIPBOARD_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc b/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc index 75198b964aa..87ed9f774f8 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_coalesced_input_event.cc @@ -91,7 +91,7 @@ WebCoalescedInputEvent::WebCoalescedInputEvent( const WebInputEvent& event, const std::vector<const WebInputEvent*>& coalesced_events) { event_ = MakeWebScopedInputEvent(event); - for (const auto& coalesced_event : coalesced_events) + for (auto* const coalesced_event : coalesced_events) coalesced_events_.push_back(MakeWebScopedInputEvent(*coalesced_event)); } diff --git a/chromium/third_party/blink/renderer/platform/exported/web_cors.cc b/chromium/third_party/blink/renderer/platform/exported/web_cors.cc index bc00038c174..a1582c0b86d 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_cors.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_cors.cc @@ -218,15 +218,6 @@ bool IsOnAccessControlResponseHeaderWhitelist(const WebString& name) { allowed_cross_origin_response_headers.end(); } -WebString ListOfCORSEnabledURLSchemes() { - return SchemeRegistry::ListOfCORSEnabledURLSchemes(); -} - -bool ContainsOnlyCORSSafelistedOrForbiddenHeaders(const WebHTTPHeaderMap& map) { - return FetchUtils::ContainsOnlyCORSSafelistedOrForbiddenHeaders( - map.GetHTTPHeaderMap()); -} - // In the spec, https://fetch.spec.whatwg.org/#ref-for-concept-request-mode, // No-CORS mode is highly discouraged from using it for new features. Only // legacy usages for backward compatibility are allowed except for well-designed diff --git a/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc b/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc index dc94ef3502e..1421bc6d411 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_crypto_algorithm.cc @@ -343,7 +343,7 @@ WebCryptoAlgorithm WebCryptoAlgorithm::AdoptParamsAndCreate( const WebCryptoAlgorithmInfo* WebCryptoAlgorithm::LookupAlgorithmInfo( WebCryptoAlgorithmId id) { const unsigned id_int = id; - if (id_int >= WTF_ARRAY_LENGTH(kAlgorithmIdToInfo)) + if (id_int >= arraysize(kAlgorithmIdToInfo)) return nullptr; return &kAlgorithmIdToInfo[id]; } diff --git a/chromium/third_party/blink/renderer/platform/exported/web_font.cc b/chromium/third_party/blink/renderer/platform/exported/web_font.cc index 126e82ffdb5..cd9169f805a 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_font.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_font.cc @@ -12,6 +12,7 @@ #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_description.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.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_record_builder.h" @@ -79,7 +80,7 @@ float WebFont::XHeight() const { void WebFont::DrawText(WebCanvas* canvas, const WebTextRun& run, const WebFloatPoint& left_baseline, - WebColor color, + SkColor color, const WebRect& clip) const { FontCachePurgePreventer font_cache_purge_preventer; FloatRect text_clip_rect(clip); 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 2202619e50a..5db9aeda1c7 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 @@ -86,11 +86,13 @@ bool WebHTTPBody::ElementAt(size_t index, Element& result) const { case FormDataElement::kEncodedBlob: result.type = Element::kTypeBlob; result.blob_uuid = element.blob_uuid_; + result.blob_length = std::numeric_limits<uint64_t>::max(); if (element.optional_blob_data_handle_) { result.optional_blob_handle = element.optional_blob_data_handle_->CloneBlobPtr() .PassInterface() .PassHandle(); + result.blob_length = element.optional_blob_data_handle_->size(); } break; case FormDataElement::kDataPipe: @@ -135,6 +137,17 @@ void WebHTTPBody::AppendBlob(const WebString& uuid) { private_->AppendBlob(uuid, nullptr); } +void WebHTTPBody::AppendBlob(const WebString& uuid, + uint64_t length, + mojo::ScopedMessagePipeHandle blob_handle) { + EnsureMutable(); + mojom::blink::BlobPtrInfo blob_ptr_info(std::move(blob_handle), + mojom::blink::Blob::Version_); + private_->AppendBlob( + uuid, BlobDataHandle::Create(uuid, "" /* type is not necessary */, length, + std::move(blob_ptr_info))); +} + void WebHTTPBody::AppendDataPipe(mojo::ScopedMessagePipeHandle message_pipe) { EnsureMutable(); diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc index 7de9b8cd1b0..62855e89d10 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_media_constraints.cc @@ -72,6 +72,9 @@ void MaybeEmitNamedBoolean(StringBuilder& builder, } // namespace +const char kEchoCancellationTypeBrowser[] = "browser"; +const char kEchoCancellationTypeSystem[] = "system"; + class WebMediaConstraintsPrivate final : public ThreadSafeRefCounted<WebMediaConstraintsPrivate> { public: @@ -352,6 +355,7 @@ WebMediaTrackConstraintSet::WebMediaTrackConstraintSet() sample_rate("sampleRate"), sample_size("sampleSize"), echo_cancellation("echoCancellation"), + echo_cancellation_type("echoCancellationType"), latency("latency"), channel_count("channelCount"), device_id("deviceId"), @@ -415,6 +419,7 @@ std::vector<const BaseConstraint*> WebMediaTrackConstraintSet::AllConstraints() &sample_rate, &sample_size, &echo_cancellation, + &echo_cancellation_type, &latency, &channel_count, &device_id, @@ -469,7 +474,7 @@ std::vector<const BaseConstraint*> WebMediaTrackConstraintSet::AllConstraints() } bool WebMediaTrackConstraintSet::IsEmpty() const { - for (const auto& constraint : AllConstraints()) { + for (auto* const constraint : AllConstraints()) { if (!constraint->IsEmpty()) return false; } @@ -479,7 +484,7 @@ bool WebMediaTrackConstraintSet::IsEmpty() const { bool WebMediaTrackConstraintSet::HasMandatoryOutsideSet( const std::vector<std::string>& good_names, std::string& found_name) const { - for (const auto& constraint : AllConstraints()) { + for (auto* const constraint : AllConstraints()) { if (constraint->HasMandatory()) { if (std::find(good_names.begin(), good_names.end(), constraint->GetName()) == good_names.end()) { @@ -499,7 +504,7 @@ bool WebMediaTrackConstraintSet::HasMandatory() const { WebString WebMediaTrackConstraintSet::ToString() const { StringBuilder builder; bool first = true; - for (const auto& constraint : AllConstraints()) { + for (auto* const constraint : AllConstraints()) { if (!constraint->IsEmpty()) { if (!first) builder.Append(", "); diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc index 514f1de7bed..f0569624a29 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_source.cc @@ -127,6 +127,16 @@ bool WebMediaStreamSource::Remote() const { return private_.Get()->Remote(); } +void WebMediaStreamSource::SetGroupId(const blink::WebString& group_id) { + DCHECK(!private_.IsNull()); + private_->SetGroupId(group_id); +} + +WebString WebMediaStreamSource::GroupId() const { + DCHECK(!private_.IsNull()); + return private_->GroupId(); +} + void WebMediaStreamSource::SetReadyState(ReadyState state) { DCHECK(!private_.IsNull()); private_->SetReadyState(static_cast<MediaStreamSource::ReadyState>(state)); @@ -156,12 +166,15 @@ void WebMediaStreamSource::SetExtraData(ExtraData* extra_data) { base::WrapUnique(extra_data))); } -void WebMediaStreamSource::SetAudioProcessingProperties(bool echo_cancellation, - bool auto_gain_control, - bool noise_supression) { +void WebMediaStreamSource::SetAudioProcessingProperties( + EchoCancellationMode echo_cancellation_mode, + bool auto_gain_control, + bool noise_supression) { DCHECK(!private_.IsNull()); - private_->SetAudioProcessingProperties(echo_cancellation, auto_gain_control, - noise_supression); + private_->SetAudioProcessingProperties( + static_cast<MediaStreamSource::EchoCancellationMode>( + echo_cancellation_mode), + auto_gain_control, noise_supression); } WebMediaConstraints WebMediaStreamSource::Constraints() { diff --git a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc index db859bc16fd..8b78c45649f 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_media_stream_track.cc @@ -47,7 +47,7 @@ class TrackDataContainer : public MediaStreamComponent::TrackData { : extra_data_(std::move(extra_data)) {} WebMediaStreamTrack::TrackData* GetTrackData() { return extra_data_.get(); } - void GetSettings(WebMediaStreamTrack::Settings& settings) { + void GetSettings(WebMediaStreamTrack::Settings& settings) override { extra_data_->GetSettings(settings); } diff --git a/chromium/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc b/chromium/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc deleted file mode 100644 index 52d2c5dc75e..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_mock_clipboard.cc +++ /dev/null @@ -1,23 +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_mock_clipboard.h" - -#include "third_party/blink/renderer/platform/blob/blob_data.h" - -namespace blink { - -WebBlobInfo WebMockClipboard::CreateBlobFromData(base::span<const uint8_t> data, - const WebString& mime_type) { - auto blob_data = BlobData::Create(); - blob_data->SetContentType(mime_type); - blob_data->AppendBytes(data.data(), data.size()); - auto blob_data_handle = - BlobDataHandle::Create(std::move(blob_data), data.size()); - return WebBlobInfo( - blob_data_handle->Uuid(), mime_type, data.size(), - blob_data_handle->CloneBlobPtr().PassInterface().PassHandle()); -} - -} // 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 index 91ce74759cd..ca17946ee50 100644 --- 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 @@ -37,8 +37,8 @@ namespace blink { WebRTCSessionDescriptionRequest::WebRTCSessionDescriptionRequest( - RTCSessionDescriptionRequest* constraints) - : private_(constraints) {} + RTCSessionDescriptionRequest* request) + : private_(request) {} void WebRTCSessionDescriptionRequest::Assign( const WebRTCSessionDescriptionRequest& other) { @@ -56,7 +56,7 @@ void WebRTCSessionDescriptionRequest::RequestSucceeded( } void WebRTCSessionDescriptionRequest::RequestFailed( - const WebString& error) const { + const webrtc::RTCError& error) const { DCHECK(private_.Get()); private_->RequestFailed(error); } 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 index b771fa7239a..e796bd659b7 100644 --- 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 @@ -51,7 +51,7 @@ void WebRTCVoidRequest::RequestSucceeded() const { private_->RequestSucceeded(); } -void WebRTCVoidRequest::RequestFailed(WebRTCError error) const { +void WebRTCVoidRequest::RequestFailed(const webrtc::RTCError& error) const { if (private_.Get()) { private_->RequestFailed(error); } 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 d65f6e9d6fc..78bbbc5b4bc 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 @@ -140,6 +140,10 @@ void WebRuntimeFeatures::EnableGamepadExtensions(bool enable) { RuntimeEnabledFeatures::SetGamepadExtensionsEnabled(enable); } +void WebRuntimeFeatures::EnableGamepadVibration(bool enable) { + RuntimeEnabledFeatures::SetGamepadVibrationEnabled(enable); +} + void WebRuntimeFeatures::EnableGenericSensor(bool enable) { RuntimeEnabledFeatures::SetSensorEnabled(enable); } @@ -156,6 +160,14 @@ void WebRuntimeFeatures::EnableInputMultipleFieldsUI(bool enable) { RuntimeEnabledFeatures::SetInputMultipleFieldsUIEnabled(enable); } +void WebRuntimeFeatures::EnableIntersectionObserverGeometryMapper(bool enable) { + RuntimeEnabledFeatures::SetIntersectionObserverGeometryMapperEnabled(enable); +} + +void WebRuntimeFeatures::EnableLayeredAPI(bool enable) { + RuntimeEnabledFeatures::SetLayeredAPIEnabled(enable); +} + void WebRuntimeFeatures::EnableLazyFrameLoading(bool enable) { RuntimeEnabledFeatures::SetLazyFrameLoadingEnabled(enable); } @@ -196,10 +208,6 @@ void WebRuntimeFeatures::EnableNotifications(bool enable) { RuntimeEnabledFeatures::SetNotificationsEnabled(enable); } -void WebRuntimeFeatures::EnableNotificationsWithMojo(bool enable) { - RuntimeEnabledFeatures::SetNotificationsWithMojoEnabled(enable); -} - void WebRuntimeFeatures::EnableNavigatorContentUtils(bool enable) { RuntimeEnabledFeatures::SetNavigatorContentUtilsEnabled(enable); } @@ -292,12 +300,6 @@ void WebRuntimeFeatures::EnableTouchpadAndWheelScrollLatching(bool enable) { RuntimeEnabledFeatures::SetTouchpadAndWheelScrollLatchingEnabled(enable); } -void WebRuntimeFeatures::EnableTurnOff2DAndOpacityCompositorAnimations( - bool enable) { - RuntimeEnabledFeatures::SetTurnOff2DAndOpacityCompositorAnimationsEnabled( - enable); -} - void WebRuntimeFeatures::EnableWebGLDraftExtensions(bool enable) { RuntimeEnabledFeatures::SetWebGLDraftExtensionsEnabled(enable); } @@ -362,6 +364,10 @@ void WebRuntimeFeatures::EnableWebXRGamepadSupport(bool enable) { RuntimeEnabledFeatures::SetWebXRGamepadSupportEnabled(enable); } +void WebRuntimeFeatures::EnableWebXRHitTest(bool enable) { + RuntimeEnabledFeatures::SetWebXRHitTestEnabled(enable); +} + void WebRuntimeFeatures::EnablePresentationAPI(bool enable) { RuntimeEnabledFeatures::SetPresentationEnabled(enable); } @@ -382,18 +388,14 @@ void WebRuntimeFeatures::EnableExpensiveBackgroundTimerThrottling(bool enable) { RuntimeEnabledFeatures::SetExpensiveBackgroundTimerThrottlingEnabled(enable); } -void WebRuntimeFeatures::EnableRootLayerScrolling(bool enable) { - RuntimeEnabledFeatures::SetRootLayerScrollingEnabled(enable); -} - -void WebRuntimeFeatures::EnableScrollAnchoring(bool enable) { - RuntimeEnabledFeatures::SetScrollAnchoringEnabled(enable); -} - void WebRuntimeFeatures::EnableScrollAnchorSerialization(bool enable) { RuntimeEnabledFeatures::SetScrollAnchorSerializationEnabled(enable); } +void WebRuntimeFeatures::EnableSecMetadata(bool enable) { + RuntimeEnabledFeatures::SetSecMetadataEnabled(enable); +} + void WebRuntimeFeatures::EnableServiceWorkerScriptFullCodeCache(bool enable) { RuntimeEnabledFeatures::SetServiceWorkerScriptFullCodeCacheEnabled(enable); } @@ -502,14 +504,6 @@ void WebRuntimeFeatures::EnablePWAFullCodeCache(bool enable) { RuntimeEnabledFeatures::SetPWAFullCodeCacheEnabled(enable); } -void WebRuntimeFeatures::EnableCodeCacheAfterExecute(bool enable) { - RuntimeEnabledFeatures::SetCodeCacheAfterExecuteEnabled(enable); -} - -void WebRuntimeFeatures::EnableUnifiedTouchAdjustment(bool enable) { - RuntimeEnabledFeatures::SetUnifiedTouchAdjustmentEnabled(enable); -} - void WebRuntimeFeatures::EnableMojoBlobURLs(bool enable) { RuntimeEnabledFeatures::SetMojoBlobURLsEnabled(enable); } @@ -518,4 +512,16 @@ void WebRuntimeFeatures::EnableOffMainThreadWebSocket(bool enable) { RuntimeEnabledFeatures::SetOffMainThreadWebSocketEnabled(enable); } +void WebRuntimeFeatures::EnableExperimentalProductivityFeatures(bool enable) { + RuntimeEnabledFeatures::SetExperimentalProductivityFeaturesEnabled(enable); +} + +void WebRuntimeFeatures::EnableDisplayCutoutViewportFit(bool enable) { + RuntimeEnabledFeatures::SetDisplayCutoutViewportFitEnabled(enable); +} + +void WebRuntimeFeatures::EnableAutoplayIgnoresWebAudio(bool enable) { + RuntimeEnabledFeatures::SetAutoplayIgnoresWebAudioEnabled(enable); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc deleted file mode 100644 index 825beb9597d..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.cc +++ /dev/null @@ -1,124 +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/renderer/platform/exported/web_scrollbar_impl.h" - -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar.h" - -namespace blink { - -WebScrollbarImpl::WebScrollbarImpl(Scrollbar* scrollbar) - : scrollbar_(scrollbar) {} - -bool WebScrollbarImpl::IsOverlay() const { - return scrollbar_->IsOverlayScrollbar(); -} - -int WebScrollbarImpl::Value() const { - return scrollbar_->Value(); -} - -WebPoint WebScrollbarImpl::Location() const { - return scrollbar_->Location(); -} - -WebSize WebScrollbarImpl::Size() const { - return scrollbar_->Size(); -} - -bool WebScrollbarImpl::Enabled() const { - return scrollbar_->Enabled(); -} - -int WebScrollbarImpl::Maximum() const { - return scrollbar_->Maximum(); -} - -int WebScrollbarImpl::TotalSize() const { - return scrollbar_->TotalSize(); -} - -bool WebScrollbarImpl::IsScrollableAreaActive() const { - return scrollbar_->IsScrollableAreaActive(); -} - -bool WebScrollbarImpl::HasTickmarks() const { - Vector<IntRect> tickmarks; - scrollbar_->GetTickmarks(tickmarks); - - return !tickmarks.IsEmpty(); -} - -void WebScrollbarImpl::GetTickmarks(WebVector<WebRect>& web_tickmarks) const { - Vector<IntRect> tickmarks; - scrollbar_->GetTickmarks(tickmarks); - - WebVector<WebRect> result(tickmarks.size()); - for (size_t i = 0; i < tickmarks.size(); ++i) - result[i] = tickmarks[i]; - - web_tickmarks.Swap(result); -} - -WebScrollbar::ScrollbarControlSize WebScrollbarImpl::GetControlSize() const { - return static_cast<WebScrollbar::ScrollbarControlSize>( - scrollbar_->GetControlSize()); -} - -WebScrollbar::ScrollbarPart WebScrollbarImpl::PressedPart() const { - return static_cast<WebScrollbar::ScrollbarPart>(scrollbar_->PressedPart()); -} - -WebScrollbar::ScrollbarPart WebScrollbarImpl::HoveredPart() const { - return static_cast<WebScrollbar::ScrollbarPart>(scrollbar_->HoveredPart()); -} - -WebScrollbarOverlayColorTheme WebScrollbarImpl::ScrollbarOverlayColorTheme() - const { - return static_cast<WebScrollbarOverlayColorTheme>( - scrollbar_->GetScrollbarOverlayColorTheme()); -} - -WebScrollbar::Orientation WebScrollbarImpl::GetOrientation() const { - return static_cast<WebScrollbar::Orientation>(scrollbar_->Orientation()); -} - -bool WebScrollbarImpl::IsLeftSideVerticalScrollbar() const { - return scrollbar_->IsLeftSideVerticalScrollbar(); -} - -bool WebScrollbarImpl::IsCustomScrollbar() const { - return scrollbar_->IsCustomScrollbar(); -} - -float WebScrollbarImpl::ElasticOverscroll() const { - return scrollbar_->ElasticOverscroll(); -} - -void WebScrollbarImpl::SetElasticOverscroll(float elastic_overscroll) { - scrollbar_->SetElasticOverscroll(elastic_overscroll); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h deleted file mode 100644 index b6938a6168e..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_impl.h +++ /dev/null @@ -1,82 +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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_IMPL_H_ - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -#include <memory> - -namespace blink { - -class Scrollbar; -class PLATFORM_EXPORT WebScrollbarImpl final : public WebScrollbar { - USING_FAST_MALLOC(WebScrollbarImpl); - WTF_MAKE_NONCOPYABLE(WebScrollbarImpl); - - public: - static std::unique_ptr<WebScrollbarImpl> Create(Scrollbar* scrollbar) { - return base::WrapUnique(new WebScrollbarImpl(scrollbar)); - } - - // Implement WebScrollbar methods - bool IsOverlay() const override; - int Value() const override; - WebPoint Location() const override; - WebSize Size() const override; - bool Enabled() const override; - int Maximum() const override; - int TotalSize() const override; - bool IsScrollableAreaActive() const override; - bool HasTickmarks() const override; - void GetTickmarks(WebVector<WebRect>& tickmarks) const override; - ScrollbarControlSize GetControlSize() const override; - ScrollbarPart PressedPart() const override; - ScrollbarPart HoveredPart() const override; - WebScrollbarOverlayColorTheme ScrollbarOverlayColorTheme() const override; - bool IsCustomScrollbar() const override; - Orientation GetOrientation() const override; - bool IsLeftSideVerticalScrollbar() const override; - float ElasticOverscroll() const override; - void SetElasticOverscroll(float) override; - - private: - explicit WebScrollbarImpl(Scrollbar*); - - // Accessed by main and compositor threads, e.g., the compositor thread - // checks |orientation()|. - // - // TODO: minimize or avoid cross-thread use, if possible. - CrossThreadPersistent<Scrollbar> scrollbar_; -}; - -} // namespace blink - -#endif diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc deleted file mode 100644 index eb441771182..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.cc +++ /dev/null @@ -1,184 +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 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 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/renderer/platform/exported/web_scrollbar_theme_client_impl.h" - -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -WebScrollbarThemeClientImpl::WebScrollbarThemeClientImpl( - WebScrollbar& scrollbar) - : scrollbar_(scrollbar) { - ScrollbarTheme::DeprecatedStaticGetTheme().RegisterScrollbar(*this); -} - -WebScrollbarThemeClientImpl::~WebScrollbarThemeClientImpl() { - ScrollbarTheme::DeprecatedStaticGetTheme().UnregisterScrollbar(*this); -} - -int WebScrollbarThemeClientImpl::X() const { - return Location().X(); -} - -int WebScrollbarThemeClientImpl::Y() const { - return Location().Y(); -} - -int WebScrollbarThemeClientImpl::Width() const { - return Size().Width(); -} - -int WebScrollbarThemeClientImpl::Height() const { - return Size().Height(); -} - -IntSize WebScrollbarThemeClientImpl::Size() const { - return scrollbar_.Size(); -} - -IntPoint WebScrollbarThemeClientImpl::Location() const { - return scrollbar_.Location(); -} - -void WebScrollbarThemeClientImpl::SetFrameRect(const IntRect&) { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -IntRect WebScrollbarThemeClientImpl::FrameRect() const { - return IntRect(Location(), Size()); -} - -void WebScrollbarThemeClientImpl::Invalidate() { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -void WebScrollbarThemeClientImpl::InvalidateRect(const IntRect&) { - // Unused by Chromium scrollbar themes. - NOTREACHED(); -} - -ScrollbarOverlayColorTheme -WebScrollbarThemeClientImpl::GetScrollbarOverlayColorTheme() const { - return static_cast<ScrollbarOverlayColorTheme>( - scrollbar_.ScrollbarOverlayColorTheme()); -} - -void WebScrollbarThemeClientImpl::GetTickmarks( - Vector<IntRect>& tickmarks) const { - WebVector<WebRect> web_tickmarks; - scrollbar_.GetTickmarks(web_tickmarks); - tickmarks.resize(web_tickmarks.size()); - for (size_t i = 0; i < web_tickmarks.size(); ++i) - tickmarks[i] = web_tickmarks[i]; -} - -bool WebScrollbarThemeClientImpl::IsScrollableAreaActive() const { - return scrollbar_.IsScrollableAreaActive(); -} - -IntPoint WebScrollbarThemeClientImpl::ConvertFromRootFrame( - const IntPoint& point_in_root_frame) const { - // Unused by Chromium scrollbar themes. - NOTREACHED(); - return point_in_root_frame; -} - -bool WebScrollbarThemeClientImpl::IsCustomScrollbar() const { - return scrollbar_.IsCustomScrollbar(); -} - -ScrollbarOrientation WebScrollbarThemeClientImpl::Orientation() const { - return static_cast<ScrollbarOrientation>(scrollbar_.GetOrientation()); -} - -bool WebScrollbarThemeClientImpl::IsLeftSideVerticalScrollbar() const { - return scrollbar_.IsLeftSideVerticalScrollbar(); -} - -int WebScrollbarThemeClientImpl::Value() const { - return scrollbar_.Value(); -} - -float WebScrollbarThemeClientImpl::CurrentPos() const { - return Value(); -} - -int WebScrollbarThemeClientImpl::VisibleSize() const { - return TotalSize() - Maximum(); -} - -int WebScrollbarThemeClientImpl::TotalSize() const { - return scrollbar_.TotalSize(); -} - -int WebScrollbarThemeClientImpl::Maximum() const { - return scrollbar_.Maximum(); -} - -ScrollbarControlSize WebScrollbarThemeClientImpl::GetControlSize() const { - return static_cast<ScrollbarControlSize>(scrollbar_.GetControlSize()); -} - -ScrollbarPart WebScrollbarThemeClientImpl::PressedPart() const { - return static_cast<ScrollbarPart>(scrollbar_.PressedPart()); -} - -ScrollbarPart WebScrollbarThemeClientImpl::HoveredPart() const { - return static_cast<ScrollbarPart>(scrollbar_.HoveredPart()); -} - -void WebScrollbarThemeClientImpl::StyleChanged() { - NOTREACHED(); -} - -void WebScrollbarThemeClientImpl::SetScrollbarsHiddenIfOverlay(bool hidden) { - NOTREACHED(); -} - -bool WebScrollbarThemeClientImpl::Enabled() const { - return scrollbar_.Enabled(); -} - -void WebScrollbarThemeClientImpl::SetEnabled(bool) { - NOTREACHED(); -} - -bool WebScrollbarThemeClientImpl::IsOverlayScrollbar() const { - return scrollbar_.IsOverlay(); -} - -float WebScrollbarThemeClientImpl::ElasticOverscroll() const { - return scrollbar_.ElasticOverscroll(); -} - -void WebScrollbarThemeClientImpl::SetElasticOverscroll( - float elastic_overscroll) { - return scrollbar_.SetElasticOverscroll(elastic_overscroll); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h deleted file mode 100644 index 34a7d267f9f..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h +++ /dev/null @@ -1,89 +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 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 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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_ - -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -namespace blink { - -// Adapts a WebScrollbar to the ScrollbarThemeClient interface -class PLATFORM_EXPORT WebScrollbarThemeClientImpl - : public ScrollbarThemeClient { - DISALLOW_NEW(); - WTF_MAKE_NONCOPYABLE(WebScrollbarThemeClientImpl); - - public: - // Caller must retain ownership of this pointer and ensure that its lifetime - // exceeds this instance. - WebScrollbarThemeClientImpl(WebScrollbar&); - ~WebScrollbarThemeClientImpl() override; - - // Implement ScrollbarThemeClient interface - int X() const override; - int Y() const override; - int Width() const override; - int Height() const override; - IntSize Size() const override; - IntPoint Location() const override; - void SetFrameRect(const IntRect&) override; - IntRect FrameRect() const override; - void Invalidate() override; - void InvalidateRect(const IntRect&) override; - ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const override; - void GetTickmarks(Vector<IntRect>&) const override; - bool IsScrollableAreaActive() const override; - IntPoint ConvertFromRootFrame(const IntPoint&) const override; - bool IsCustomScrollbar() const override; - ScrollbarOrientation Orientation() const override; - bool IsLeftSideVerticalScrollbar() const override; - int Value() const override; - float CurrentPos() const override; - int VisibleSize() const override; - int TotalSize() const override; - int Maximum() const override; - ScrollbarControlSize GetControlSize() const override; - ScrollbarPart PressedPart() const override; - ScrollbarPart HoveredPart() const override; - void StyleChanged() override; - void SetScrollbarsHiddenIfOverlay(bool) override; - bool Enabled() const override; - void SetEnabled(bool) override; - bool IsOverlayScrollbar() const override; - float ElasticOverscroll() const override; - void SetElasticOverscroll(float) override; - - private: - WebScrollbar& scrollbar_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_CLIENT_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc deleted file mode 100644 index 89c9a73b01b..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.cc +++ /dev/null @@ -1,99 +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 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 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/renderer/platform/exported/web_scrollbar_theme_geometry_native.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "third_party/blink/public/platform/web_scrollbar.h" -#include "third_party/blink/renderer/platform/exported/web_scrollbar_theme_client_impl.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -std::unique_ptr<WebScrollbarThemeGeometryNative> -WebScrollbarThemeGeometryNative::Create(ScrollbarTheme& theme) { - return base::WrapUnique(new WebScrollbarThemeGeometryNative(theme)); -} - -WebScrollbarThemeGeometryNative::WebScrollbarThemeGeometryNative( - ScrollbarTheme& theme) - : theme_(theme) {} - -bool WebScrollbarThemeGeometryNative::HasButtons(WebScrollbar* scrollbar) { - return theme_.HasButtons(WebScrollbarThemeClientImpl(*scrollbar)); -} - -bool WebScrollbarThemeGeometryNative::HasThumb(WebScrollbar* scrollbar) { - return theme_.HasThumb(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::TrackRect(WebScrollbar* scrollbar) { - return theme_.TrackRect(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::ThumbRect(WebScrollbar* scrollbar) { - return theme_.ThumbRect(WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::BackButtonStartRect( - WebScrollbar* scrollbar) { - return theme_.BackButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kBackButtonStartPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::BackButtonEndRect( - WebScrollbar* scrollbar) { - return theme_.BackButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kBackButtonEndPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::ForwardButtonStartRect( - WebScrollbar* scrollbar) { - return theme_.ForwardButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kForwardButtonStartPart, false); -} - -WebRect WebScrollbarThemeGeometryNative::ForwardButtonEndRect( - WebScrollbar* scrollbar) { - return theme_.ForwardButtonRect(WebScrollbarThemeClientImpl(*scrollbar), - kForwardButtonEndPart, false); -} - -WebSize WebScrollbarThemeGeometryNative::NinePatchThumbCanvasSize( - WebScrollbar* scrollbar) { - DCHECK(theme_.UsesNinePatchThumbResource()); - return theme_.NinePatchThumbCanvasSize( - WebScrollbarThemeClientImpl(*scrollbar)); -} - -WebRect WebScrollbarThemeGeometryNative::NinePatchThumbAperture( - WebScrollbar* scrollbar) { - DCHECK(theme_.UsesNinePatchThumbResource()); - return theme_.NinePatchThumbAperture(WebScrollbarThemeClientImpl(*scrollbar)); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h deleted file mode 100644 index b7606dea6f4..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_geometry_native.h +++ /dev/null @@ -1,72 +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 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 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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_GEOMETRY_NATIVE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_EXPORTED_WEB_SCROLLBAR_THEME_GEOMETRY_NATIVE_H_ - -#include <memory> -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/public/platform/web_scrollbar_theme_geometry.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -namespace blink { - -class ScrollbarTheme; -class WebScrollbar; - -class PLATFORM_EXPORT WebScrollbarThemeGeometryNative - : public WebScrollbarThemeGeometry { - USING_FAST_MALLOC(WebScrollbarThemeGeometryNative); - WTF_MAKE_NONCOPYABLE(WebScrollbarThemeGeometryNative); - - public: - static std::unique_ptr<WebScrollbarThemeGeometryNative> Create( - ScrollbarTheme&); - - bool HasButtons(WebScrollbar*) override; - bool HasThumb(WebScrollbar*) override; - WebRect TrackRect(WebScrollbar*) override; - WebRect ThumbRect(WebScrollbar*) override; - WebRect BackButtonStartRect(WebScrollbar*) override; - WebRect BackButtonEndRect(WebScrollbar*) override; - WebRect ForwardButtonStartRect(WebScrollbar*) override; - WebRect ForwardButtonEndRect(WebScrollbar*) override; - WebSize NinePatchThumbCanvasSize(WebScrollbar*) override; - WebRect NinePatchThumbAperture(WebScrollbar*) override; - - private: - explicit WebScrollbarThemeGeometryNative(ScrollbarTheme&); - - // The theme is not owned by this class. It is assumed that the theme is a - // static pointer and its lifetime is essentially infinite. Only thread-safe - // functions on the theme can be called by this theme. - ScrollbarTheme& theme_; -}; - -} // namespace blink - -#endif diff --git a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc b/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc deleted file mode 100644 index 6d123b306d1..00000000000 --- a/chromium/third_party/blink/renderer/platform/exported/web_scrollbar_theme_painter.cc +++ /dev/null @@ -1,174 +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 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 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_scrollbar_theme_painter.h" - -#include "third_party/blink/public/platform/web_rect.h" -#include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" - -namespace blink { - -// WebScrollbarThemeMac uses GraphicsContextCanvas which doesn't quite support -// device clip rects not at the origin. This class translates the recording -// canvas to the origin and then adjusts it back during playback. -class ScopedScrollbarPainter { - public: - ScopedScrollbarPainter(WebScrollbarThemePainter* painter, - WebCanvas* canvas, - const WebRect& rect) - : int_rect_(IntRect(IntPoint(), IntSize(rect.width, rect.height))), - canvas_(canvas), - rect_(rect) { - builder_.Context().SetDeviceScaleFactor(painter->DeviceScaleFactor()); - } - GraphicsContext& Context() { return builder_.Context(); } - const IntRect& Rect() const { return int_rect_; } - - ~ScopedScrollbarPainter() { - canvas_->save(); - canvas_->translate(rect_.x, rect_.y); - canvas_->drawPicture(builder_.EndRecording()); - canvas_->restore(); - } - - protected: - IntRect int_rect_; - PaintRecordBuilder builder_; - WebCanvas* canvas_; - const WebRect& rect_; -}; - -void WebScrollbarThemePainter::Assign(const WebScrollbarThemePainter& painter) { - // This is a pointer to a static object, so no ownership transferral. - theme_ = painter.theme_; - scrollbar_ = painter.scrollbar_; - device_scale_factor_ = painter.device_scale_factor_; -} - -void WebScrollbarThemePainter::Reset() { - scrollbar_ = nullptr; -} - -void WebScrollbarThemePainter::PaintScrollbarBackground(WebCanvas* canvas, - const WebRect& rect) { - SkRect clip = SkRect::MakeXYWH(rect.x, rect.y, rect.width, rect.height); - canvas->clipRect(clip); - - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintScrollbarBackground(painter.Context(), *scrollbar_); -} - -void WebScrollbarThemePainter::PaintTrackBackground(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackBackground(painter.Context(), *scrollbar_, painter.Rect()); - if (!theme_->ShouldRepaintAllPartsOnInvalidation()) - scrollbar_->ClearTrackNeedsRepaint(); -} - -void WebScrollbarThemePainter::PaintBackTrackPart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackPiece(painter.Context(), *scrollbar_, painter.Rect(), - kBackTrackPart); -} - -void WebScrollbarThemePainter::PaintForwardTrackPart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTrackPiece(painter.Context(), *scrollbar_, painter.Rect(), - kForwardTrackPart); -} - -void WebScrollbarThemePainter::PaintBackButtonStart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kBackButtonStartPart); -} - -void WebScrollbarThemePainter::PaintBackButtonEnd(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kBackButtonEndPart); -} - -void WebScrollbarThemePainter::PaintForwardButtonStart(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kForwardButtonStartPart); -} - -void WebScrollbarThemePainter::PaintForwardButtonEnd(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintButton(painter.Context(), *scrollbar_, painter.Rect(), - kForwardButtonEndPart); -} - -void WebScrollbarThemePainter::PaintTickmarks(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintTickmarks(painter.Context(), *scrollbar_, painter.Rect()); -} - -void WebScrollbarThemePainter::PaintThumb(WebCanvas* canvas, - const WebRect& rect) { - ScopedScrollbarPainter painter(this, canvas, rect); - theme_->PaintThumb(painter.Context(), *scrollbar_, painter.Rect()); - if (!theme_->ShouldRepaintAllPartsOnInvalidation()) - scrollbar_->ClearThumbNeedsRepaint(); -} - -WebScrollbarThemePainter::WebScrollbarThemePainter(ScrollbarTheme& theme, - Scrollbar& scrollbar, - float device_scale_factor) - : theme_(&theme), - scrollbar_(&scrollbar), - device_scale_factor_(device_scale_factor) {} - -float WebScrollbarThemePainter::ThumbOpacity() const { - return theme_->ThumbOpacity(*scrollbar_); -} - -bool WebScrollbarThemePainter::TrackNeedsRepaint() const { - return scrollbar_->TrackNeedsRepaint(); -} - -bool WebScrollbarThemePainter::ThumbNeedsRepaint() const { - return scrollbar_->ThumbNeedsRepaint(); -} - -bool WebScrollbarThemePainter::UsesNinePatchThumbResource() const { - return theme_->UsesNinePatchThumbResource(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc b/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc index 4d9a026cacb..a55f8834fa6 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_service_worker_request.cc @@ -128,6 +128,11 @@ void WebServiceWorkerRequest::SetBlob(const WebString& uuid, BlobDataHandle::Create(uuid, String(), size, std::move(blob_info)); } +void WebServiceWorkerRequest::SetBlobDataHandle( + scoped_refptr<BlobDataHandle> blob_data_handle) { + private_->blob_data_handle = std::move(blob_data_handle); +} + scoped_refptr<BlobDataHandle> WebServiceWorkerRequest::GetBlobDataHandle() const { return private_->blob_data_handle; diff --git a/chromium/third_party/blink/renderer/platform/exported/web_speech_synthesizer_client_impl.h b/chromium/third_party/blink/renderer/platform/exported/web_speech_synthesizer_client_impl.h index e3ef80ee256..f298083085b 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_speech_synthesizer_client_impl.h +++ b/chromium/third_party/blink/renderer/platform/exported/web_speech_synthesizer_client_impl.h @@ -43,18 +43,18 @@ class WebSpeechSynthesizerClientImpl final public: WebSpeechSynthesizerClientImpl(PlatformSpeechSynthesizer*, PlatformSpeechSynthesizerClient*); - virtual ~WebSpeechSynthesizerClientImpl(); + ~WebSpeechSynthesizerClientImpl() override; - virtual void SetVoiceList(const WebVector<WebSpeechSynthesisVoice>& voices); - virtual void DidStartSpeaking(const WebSpeechSynthesisUtterance&); - virtual void DidFinishSpeaking(const WebSpeechSynthesisUtterance&); - virtual void DidPauseSpeaking(const WebSpeechSynthesisUtterance&); - virtual void DidResumeSpeaking(const WebSpeechSynthesisUtterance&); - virtual void SpeakingErrorOccurred(const WebSpeechSynthesisUtterance&); - virtual void WordBoundaryEventOccurred(const WebSpeechSynthesisUtterance&, - unsigned char_index); - virtual void SentenceBoundaryEventOccurred(const WebSpeechSynthesisUtterance&, - unsigned char_index); + void SetVoiceList(const WebVector<WebSpeechSynthesisVoice>& voices) override; + void DidStartSpeaking(const WebSpeechSynthesisUtterance&) override; + void DidFinishSpeaking(const WebSpeechSynthesisUtterance&) override; + void DidPauseSpeaking(const WebSpeechSynthesisUtterance&) override; + void DidResumeSpeaking(const WebSpeechSynthesisUtterance&) override; + void SpeakingErrorOccurred(const WebSpeechSynthesisUtterance&) override; + void WordBoundaryEventOccurred(const WebSpeechSynthesisUtterance&, + unsigned char_index) override; + void SentenceBoundaryEventOccurred(const WebSpeechSynthesisUtterance&, + unsigned char_index) override; void Trace(blink::Visitor*); diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc index 688e086648f..488a6e356fb 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_url_error.cc @@ -9,7 +9,7 @@ namespace blink { WebURLError::WebURLError(int reason, const WebURL& url) - : reason_(reason), extended_reason_(0), url_(url) { + : reason_(reason), url_(url) { DCHECK_NE(reason_, 0); } diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc index 43310e1b248..567469e81b2 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_url_load_timing.cc @@ -47,148 +47,132 @@ void WebURLLoadTiming::Assign(const WebURLLoadTiming& other) { private_ = other.private_; } -double WebURLLoadTiming::RequestTime() const { - return TimeTicksInSeconds(private_->RequestTime()); +base::TimeTicks WebURLLoadTiming::RequestTime() const { + return private_->RequestTime(); } -void WebURLLoadTiming::SetRequestTime(double time) { - DCHECK_GE(time, 0.0); - private_->SetRequestTime(TimeTicksFromSeconds(time)); +void WebURLLoadTiming::SetRequestTime(base::TimeTicks time) { + private_->SetRequestTime(time); } -double WebURLLoadTiming::ProxyStart() const { - return TimeTicksInSeconds(private_->ProxyStart()); +base::TimeTicks WebURLLoadTiming::ProxyStart() const { + return private_->ProxyStart(); } -void WebURLLoadTiming::SetProxyStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetProxyStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetProxyStart(base::TimeTicks start) { + private_->SetProxyStart(start); } -double WebURLLoadTiming::ProxyEnd() const { - return TimeTicksInSeconds(private_->ProxyEnd()); +base::TimeTicks WebURLLoadTiming::ProxyEnd() const { + return private_->ProxyEnd(); } -void WebURLLoadTiming::SetProxyEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetProxyEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetProxyEnd(base::TimeTicks end) { + private_->SetProxyEnd(end); } -double WebURLLoadTiming::DnsStart() const { - return TimeTicksInSeconds(private_->DnsStart()); +base::TimeTicks WebURLLoadTiming::DnsStart() const { + return private_->DnsStart(); } -void WebURLLoadTiming::SetDNSStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetDnsStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetDNSStart(base::TimeTicks start) { + private_->SetDnsStart(start); } -double WebURLLoadTiming::DnsEnd() const { - return TimeTicksInSeconds(private_->DnsEnd()); +base::TimeTicks WebURLLoadTiming::DnsEnd() const { + return private_->DnsEnd(); } -void WebURLLoadTiming::SetDNSEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetDnsEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetDNSEnd(base::TimeTicks end) { + private_->SetDnsEnd(end); } -double WebURLLoadTiming::ConnectStart() const { - return TimeTicksInSeconds(private_->ConnectStart()); +base::TimeTicks WebURLLoadTiming::ConnectStart() const { + return private_->ConnectStart(); } -void WebURLLoadTiming::SetConnectStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetConnectStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetConnectStart(base::TimeTicks start) { + private_->SetConnectStart(start); } -double WebURLLoadTiming::ConnectEnd() const { - return TimeTicksInSeconds(private_->ConnectEnd()); +base::TimeTicks WebURLLoadTiming::ConnectEnd() const { + return private_->ConnectEnd(); } -void WebURLLoadTiming::SetConnectEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetConnectEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetConnectEnd(base::TimeTicks end) { + private_->SetConnectEnd(end); } -double WebURLLoadTiming::WorkerStart() const { - return TimeTicksInSeconds(private_->WorkerStart()); +base::TimeTicks WebURLLoadTiming::WorkerStart() const { + return private_->WorkerStart(); } -void WebURLLoadTiming::SetWorkerStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetWorkerStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetWorkerStart(base::TimeTicks start) { + private_->SetWorkerStart(start); } -double WebURLLoadTiming::WorkerReady() const { - return TimeTicksInSeconds(private_->WorkerReady()); +base::TimeTicks WebURLLoadTiming::WorkerReady() const { + return private_->WorkerReady(); } -void WebURLLoadTiming::SetWorkerReady(double ready) { - DCHECK_GE(ready, 0.0); - private_->SetWorkerReady(TimeTicksFromSeconds(ready)); +void WebURLLoadTiming::SetWorkerReady(base::TimeTicks ready) { + private_->SetWorkerReady(ready); } -double WebURLLoadTiming::SendStart() const { - return TimeTicksInSeconds(private_->SendStart()); +base::TimeTicks WebURLLoadTiming::SendStart() const { + return private_->SendStart(); } -void WebURLLoadTiming::SetSendStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetSendStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetSendStart(base::TimeTicks start) { + private_->SetSendStart(start); } -double WebURLLoadTiming::SendEnd() const { - return TimeTicksInSeconds(private_->SendEnd()); +base::TimeTicks WebURLLoadTiming::SendEnd() const { + return private_->SendEnd(); } -void WebURLLoadTiming::SetSendEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetSendEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetSendEnd(base::TimeTicks end) { + private_->SetSendEnd(end); } -double WebURLLoadTiming::ReceiveHeadersEnd() const { - return TimeTicksInSeconds(private_->ReceiveHeadersEnd()); +base::TimeTicks WebURLLoadTiming::ReceiveHeadersEnd() const { + return private_->ReceiveHeadersEnd(); } -void WebURLLoadTiming::SetReceiveHeadersEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetReceiveHeadersEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetReceiveHeadersEnd(base::TimeTicks end) { + private_->SetReceiveHeadersEnd(end); } -double WebURLLoadTiming::SslStart() const { - return TimeTicksInSeconds(private_->SslStart()); +base::TimeTicks WebURLLoadTiming::SslStart() const { + return private_->SslStart(); } -void WebURLLoadTiming::SetSSLStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetSslStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetSSLStart(base::TimeTicks start) { + private_->SetSslStart(start); } -double WebURLLoadTiming::SslEnd() const { - return TimeTicksInSeconds(private_->SslEnd()); +base::TimeTicks WebURLLoadTiming::SslEnd() const { + return private_->SslEnd(); } -void WebURLLoadTiming::SetSSLEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetSslEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetSSLEnd(base::TimeTicks end) { + private_->SetSslEnd(end); } -double WebURLLoadTiming::PushStart() const { - return TimeTicksInSeconds(private_->PushStart()); +base::TimeTicks WebURLLoadTiming::PushStart() const { + return private_->PushStart(); } -void WebURLLoadTiming::SetPushStart(double start) { - DCHECK_GE(start, 0.0); - private_->SetPushStart(TimeTicksFromSeconds(start)); +void WebURLLoadTiming::SetPushStart(base::TimeTicks start) { + private_->SetPushStart(start); } -double WebURLLoadTiming::PushEnd() const { - return TimeTicksInSeconds(private_->PushEnd()); +base::TimeTicks WebURLLoadTiming::PushEnd() const { + return private_->PushEnd(); } -void WebURLLoadTiming::SetPushEnd(double end) { - DCHECK_GE(end, 0.0); - private_->SetPushEnd(TimeTicksFromSeconds(end)); +void WebURLLoadTiming::SetPushEnd(base::TimeTicks end) { + private_->SetPushEnd(end); } WebURLLoadTiming::WebURLLoadTiming(scoped_refptr<ResourceLoadTiming> value) diff --git a/chromium/third_party/blink/renderer/platform/exported/web_url_loader_test_delegate.cc b/chromium/third_party/blink/renderer/platform/exported/web_url_loader_test_delegate.cc index 08ec94e12a2..417aab048d2 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_url_loader_test_delegate.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_url_loader_test_delegate.cc @@ -40,7 +40,7 @@ void WebURLLoaderTestDelegate::DidFail(WebURLLoaderClient* original_client, void WebURLLoaderTestDelegate::DidFinishLoading( WebURLLoaderClient* original_client, - double finish_time, + base::TimeTicks finish_time, int64_t total_encoded_data_length, int64_t total_encoded_body_length, int64_t total_decoded_body_length) { 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 2420be2f0e8..632bf7f2566 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 @@ -392,7 +392,8 @@ network::mojom::CORSPreflightPolicy WebURLRequest::GetCORSPreflightPolicy() return resource_request_->CORSPreflightPolicy(); } -void WebURLRequest::SetNavigationStartTime(double navigation_start_seconds) { +void WebURLRequest::SetNavigationStartTime( + base::TimeTicks navigation_start_seconds) { resource_request_->SetNavigationStartTime(navigation_start_seconds); } @@ -423,6 +424,10 @@ bool WebURLRequest::IsAdResource() const { return resource_request_->IsAdResource(); } +const WebContentSecurityPolicyList& WebURLRequest::GetNavigationCSP() const { + return resource_request_->GetInitiatorCSP(); +} + const ResourceRequest& WebURLRequest::ToResourceRequest() const { DCHECK(resource_request_); return *resource_request_; diff --git a/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc b/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc index 83dfcf91463..10fe0edd98c 100644 --- a/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc +++ b/chromium/third_party/blink/renderer/platform/exported/web_video_frame_submitter.cc @@ -26,13 +26,10 @@ namespace blink { std::unique_ptr<WebVideoFrameSubmitter> WebVideoFrameSubmitter::Create( WebContextProviderCallback context_provider_callback, - viz::SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const cc::LayerTreeSettings& settings) { return std::make_unique<VideoFrameSubmitter>( - std::make_unique<VideoFrameResourceProvider>( - std::move(context_provider_callback), shared_bitmap_manager, - gpu_memory_buffer_manager, settings)); + std::move(context_provider_callback), + std::make_unique<VideoFrameResourceProvider>(settings)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/DEPS b/chromium/third_party/blink/renderer/platform/feature_policy/DEPS new file mode 100644 index 00000000000..76ebef5528b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/feature_policy/DEPS @@ -0,0 +1,17 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/feature_policy", + + # Dependencies. + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/json", + "+third_party/blink/renderer/platform/network/http_parsers.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/weborigin/security_origin.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc index bb9a13b1249..b7c27b6ad28 100644 --- a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc +++ b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.cc @@ -15,74 +15,6 @@ namespace blink { -namespace { - -// TODO(loonybear): Deprecate the methods in this namesapce when deprecating old -// allow syntax. -bool IsValidOldAllowSyntax(const String& policy, - scoped_refptr<const SecurityOrigin> src_origin) { - // Old syntax enable all features on src_origin, If src_origin does not exist - // (example, http header does not have a src_origin), then the syntax cannot - // be valid. - if (!src_origin) - return false; - // allow = "feature" is also supported by new syntax. - if (!policy.Contains(' ')) - return false; - // Old syntax only allows whitespace as valid delimiter. - if (policy.Contains(';') || policy.Contains(',')) - return false; - // An empty policy is also allowed in the new syntax. - if (policy.ContainsOnlyWhitespace()) - return false; - // Old syntax does not support specifying wildcards / origins for any feature. - if (policy.Contains("self") || policy.Contains("src") || - policy.Contains("none") || policy.Contains("*")) { - return false; - } - - // Verify that the policy follows this syntax: - // allow = "name1 name2 name3 ...", name* = 1*( ALPHA / DIGIT / "-" ) - auto IsValidFeatureNameCharacter = [](auto c) { - return IsASCIIAlphanumeric(c) || c == '-'; - }; - - for (unsigned i = 0; i < policy.length(); i++) { - if (!IsValidFeatureNameCharacter(policy[i]) && !IsASCIISpace(policy[i])) - return false; - } - return true; -} - -ParsedFeaturePolicy ParseOldAllowSyntax(const String& policy, - const url::Origin& origin, - Vector<String>* messages, - const FeatureNameMap& feature_names) { - ParsedFeaturePolicy whitelists; - if (messages) { - messages->push_back( - "The old syntax (allow=\"feature1 feature2 feature3 ...\") is " - "deprecated and will be removed in Chrome 68. Use semicolons to " - "separate features (allow=\"feature1; feature2; feature3; ...\")."); - } - Vector<String> tokens; - policy.Split(' ', tokens); - for (const String& token : tokens) { - if (!feature_names.Contains(token)) { - if (messages) - messages->push_back("Unrecognized feature: '" + token + "'."); - continue; - } - ParsedFeaturePolicyDeclaration whitelist; - whitelist.feature = feature_names.at(token); - whitelist.origins = {origin}; - whitelists.push_back(whitelist); - } - return whitelists; -} - -} // namespace - ParsedFeaturePolicy ParseFeaturePolicyHeader( const String& policy, scoped_refptr<const SecurityOrigin> origin, @@ -95,10 +27,9 @@ ParsedFeaturePolicy ParseFeaturePolicyAttribute( const String& policy, scoped_refptr<const SecurityOrigin> self_origin, scoped_refptr<const SecurityOrigin> src_origin, - Vector<String>* messages, - bool* old_syntax) { + Vector<String>* messages) { return ParseFeaturePolicy(policy, self_origin, src_origin, messages, - GetDefaultFeatureNameMap(), old_syntax); + GetDefaultFeatureNameMap()); } ParsedFeaturePolicy ParseFeaturePolicy( @@ -106,18 +37,7 @@ ParsedFeaturePolicy ParseFeaturePolicy( scoped_refptr<const SecurityOrigin> self_origin, scoped_refptr<const SecurityOrigin> src_origin, Vector<String>* messages, - const FeatureNameMap& feature_names, - bool* old_syntax) { - // Temporarily supporting old allow syntax: - // allow = "feature1 feature2 feature3 ... " - // TODO(loonybear): depracate this old syntax in the future. - if (IsValidOldAllowSyntax(policy, src_origin)) { - if (old_syntax) - *old_syntax = true; - return ParseOldAllowSyntax(policy, src_origin->ToUrlOrigin(), messages, - feature_names); - } - + const FeatureNameMap& feature_names) { ParsedFeaturePolicy whitelists; BitVector features_specified( static_cast<int>(mojom::FeaturePolicyFeature::kMaxValue)); @@ -225,15 +145,16 @@ bool IsSupportedInFeaturePolicy(mojom::FeaturePolicyFeature feature) { case mojom::FeaturePolicyFeature::kAmbientLightSensor: case mojom::FeaturePolicyFeature::kGyroscope: case mojom::FeaturePolicyFeature::kMagnetometer: - return true; case mojom::FeaturePolicyFeature::kPictureInPicture: - return RuntimeEnabledFeatures::PictureInPictureAPIEnabled(); case mojom::FeaturePolicyFeature::kSyncXHR: return true; case mojom::FeaturePolicyFeature::kUnsizedMedia: - return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled(); case mojom::FeaturePolicyFeature::kVerticalScroll: - return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled(); + case mojom::FeaturePolicyFeature::kLegacyImageFormats: + case mojom::FeaturePolicyFeature::kImageCompression: + case mojom::FeaturePolicyFeature::kDocumentStreamInsertion: + case mojom::FeaturePolicyFeature::kMaxDownscalingImage: + return RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled(); default: return false; } @@ -271,17 +192,20 @@ const FeatureNameMap& GetDefaultFeatureNameMap() { mojom::FeaturePolicyFeature::kGyroscope); default_feature_name_map.Set("magnetometer", mojom::FeaturePolicyFeature::kMagnetometer); - if (RuntimeEnabledFeatures::PictureInPictureAPIEnabled()) { + default_feature_name_map.Set("picture-in-picture", + mojom::FeaturePolicyFeature::kPictureInPicture); + if (RuntimeEnabledFeatures::ExperimentalProductivityFeaturesEnabled()) { default_feature_name_map.Set( - "picture-in-picture", mojom::FeaturePolicyFeature::kPictureInPicture); - } - if (RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled()) { + "document-stream-insertion", + mojom::FeaturePolicyFeature::kDocumentStreamInsertion); default_feature_name_map.Set( - "cookie", mojom::FeaturePolicyFeature::kDocumentCookie); + "image-compression", mojom::FeaturePolicyFeature::kImageCompression); default_feature_name_map.Set( - "domain", mojom::FeaturePolicyFeature::kDocumentDomain); - default_feature_name_map.Set("docwrite", - mojom::FeaturePolicyFeature::kDocumentWrite); + "legacy-image-formats", + mojom::FeaturePolicyFeature::kLegacyImageFormats); + default_feature_name_map.Set( + "max-downscaling-image", + mojom::FeaturePolicyFeature::kMaxDownscalingImage); default_feature_name_map.Set("sync-script", mojom::FeaturePolicyFeature::kSyncScript); default_feature_name_map.Set("unsized-media", @@ -289,6 +213,14 @@ const FeatureNameMap& GetDefaultFeatureNameMap() { default_feature_name_map.Set( "vertical-scroll", mojom::FeaturePolicyFeature::kVerticalScroll); } + if (RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled()) { + default_feature_name_map.Set("animations", + mojom::FeaturePolicyFeature::kAnimations); + default_feature_name_map.Set( + "cookie", mojom::FeaturePolicyFeature::kDocumentCookie); + default_feature_name_map.Set( + "domain", mojom::FeaturePolicyFeature::kDocumentDomain); + } if (RuntimeEnabledFeatures::FeaturePolicyAutoplayFeatureEnabled()) { default_feature_name_map.Set("autoplay", mojom::FeaturePolicyFeature::kAutoplay); diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h index fa88d3f3032..0176ce83cbe 100644 --- a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h +++ b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy.h @@ -41,34 +41,22 @@ ParseFeaturePolicyHeader(const String& policy, // input will cause as warning message to be appended to it. // Example of a feature policy string: // "vibrate a.com 'src'; fullscreen 'none'; payment 'self', payment *". -// If |old_syntax| is not null, it will be set true if the deprecated -// space-deparated feature list syntax is detected. -// TODO(loonybear): remove the boolean once the space separated feature list -// syntax is deprecated. -// https://crbug.com/761009. PLATFORM_EXPORT ParsedFeaturePolicy ParseFeaturePolicyAttribute(const String& policy, scoped_refptr<const SecurityOrigin> self_origin, scoped_refptr<const SecurityOrigin> src_origin, - Vector<String>* messages, - bool* old_syntax); + Vector<String>* messages); // Converts a feature policy string into a vector of whitelists (see comments // above), with an explicit FeatureNameMap. This algorithm is called by both // header policy parsing and container policy parsing. |self_origin| and // |src_origin| are both nullable. -// If |old_syntax| is not null, it will be set true if the deprecated -// space-deparated feature list syntax is detected. -// TODO(loonybear): remove the boolean once the space separated feature list -// syntax is deprecated. -// https://crbug.com/761009. PLATFORM_EXPORT ParsedFeaturePolicy ParseFeaturePolicy(const String& policy, scoped_refptr<const SecurityOrigin> self_origin, scoped_refptr<const SecurityOrigin> src_origin, Vector<String>* messages, - const FeatureNameMap& feature_names, - bool* old_syntax = nullptr); + const FeatureNameMap& feature_names); // Verifies whether feature policy is enabled and |feature| is supported in // feature policy. diff --git a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc index 0d3aafc951e..8701132aaa3 100644 --- a/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc +++ b/chromium/third_party/blink/renderer/platform/feature_policy/feature_policy_test.cc @@ -60,7 +60,7 @@ class FeaturePolicyTest : public testing::Test { protected: FeaturePolicyTest() = default; - ~FeaturePolicyTest() = default; + ~FeaturePolicyTest() override = default; scoped_refptr<const SecurityOrigin> origin_a_ = SecurityOrigin::CreateFromString(ORIGIN_A); @@ -186,35 +186,6 @@ TEST_F(FeaturePolicyTest, PolicyParsedCorrectly) { EXPECT_TRUE( parsed_policy[2].origins[0].IsSameOriginWith(expected_url_origin_a_)); - // Old (to be deprecated) iframe allow syntax. - messages.clear(); - parsed_policy = - ParseFeaturePolicy("geolocation badname fullscreen payment", nullptr, - origin_a_.get(), &messages, test_feature_name_map); - // Expect 2 messages: one about deprecation warning, one about unrecognized - // feature name. - EXPECT_EQ(2UL, messages.size()); - EXPECT_EQ(3UL, parsed_policy.size()); - EXPECT_EQ(mojom::FeaturePolicyFeature::kGeolocation, - parsed_policy[0].feature); - EXPECT_FALSE(parsed_policy[0].matches_all_origins); - EXPECT_FALSE(parsed_policy[0].matches_opaque_src); - EXPECT_EQ(1UL, parsed_policy[0].origins.size()); - EXPECT_TRUE( - parsed_policy[0].origins[0].IsSameOriginWith(expected_url_origin_a_)); - EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, parsed_policy[1].feature); - EXPECT_FALSE(parsed_policy[1].matches_all_origins); - EXPECT_FALSE(parsed_policy[1].matches_opaque_src); - EXPECT_EQ(1UL, parsed_policy[1].origins.size()); - EXPECT_TRUE( - parsed_policy[1].origins[0].IsSameOriginWith(expected_url_origin_a_)); - EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, parsed_policy[2].feature); - EXPECT_FALSE(parsed_policy[2].matches_all_origins); - EXPECT_FALSE(parsed_policy[2].matches_opaque_src); - EXPECT_EQ(1UL, parsed_policy[2].origins.size()); - EXPECT_TRUE( - parsed_policy[2].origins[0].IsSameOriginWith(expected_url_origin_a_)); - // Header policies with no optional origin lists. parsed_policy = ParseFeaturePolicy("geolocation;fullscreen;payment", origin_a_.get(), diff --git a/chromium/third_party/blink/renderer/platform/file_metadata.cc b/chromium/third_party/blink/renderer/platform/file_metadata.cc index b6929e479b7..31a9f9a9855 100644 --- a/chromium/third_party/blink/renderer/platform/file_metadata.cc +++ b/chromium/third_party/blink/renderer/platform/file_metadata.cc @@ -30,9 +30,16 @@ #include "third_party/blink/renderer/platform/file_metadata.h" +#include "base/optional.h" +#include "net/base/filename_util.h" +#include "third_party/blink/public/mojom/file/file_utilities.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/public/platform/web_file_info.h" -#include "third_party/blink/public/platform/web_file_utilities.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" +#include "third_party/blink/renderer/platform/wtf/thread_specific.h" +#include "url/gurl.h" namespace blink { @@ -53,22 +60,38 @@ bool GetFileModificationTime(const String& path, double& result) { } bool GetFileMetadata(const String& path, FileMetadata& metadata) { - WebFileInfo web_file_info; - if (!Platform::Current()->GetFileUtilities()->GetFileInfo(path, - web_file_info)) + DEFINE_THREAD_SAFE_STATIC_LOCAL( + ThreadSpecific<mojom::blink::FileUtilitiesHostPtr>, thread_specific_host, + ()); + auto& host = *thread_specific_host; + if (!host) { + Platform::Current()->GetInterfaceProvider()->GetInterface( + mojo::MakeRequest(&host)); + } + + base::Optional<base::File::Info> file_info; + if (!host->GetFileInfo(WebStringToFilePath(path), &file_info) || !file_info) return false; - metadata.modification_time = web_file_info.modification_time; - metadata.length = web_file_info.length; - metadata.type = static_cast<FileMetadata::Type>(web_file_info.type); + + // 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.length = file_info->size; + metadata.type = file_info->is_directory ? FileMetadata::kTypeDirectory + : FileMetadata::kTypeFile; return true; } String DirectoryName(const String& path) { - return Platform::Current()->GetFileUtilities()->DirectoryName(path); + return FilePathToWebString(WebStringToFilePath(path).DirName()); } KURL FilePathToURL(const String& path) { - return Platform::Current()->GetFileUtilities()->FilePathToURL(path); + GURL gurl = net::FilePathToFileURL(WebStringToFilePath(path)); + const std::string& url_spec = gurl.possibly_invalid_spec(); + return KURL(AtomicString::FromUTF8(url_spec.data(), url_spec.length()), + gurl.parsed_for_possibly_invalid_spec(), gurl.is_valid()); } STATIC_ASSERT_ENUM(WebFileInfo::kTypeUnknown, FileMetadata::kTypeUnknown); diff --git a/chromium/third_party/blink/renderer/platform/fonts/DEPS b/chromium/third_party/blink/renderer/platform/fonts/DEPS new file mode 100644 index 00000000000..baf61469c1b --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/fonts/DEPS @@ -0,0 +1,29 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/fonts", + + # Dependencies. + "+third_party/blink/renderer/platform/font_family_names.h", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap/handle.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/language.h", + "+third_party/blink/renderer/platform/layout_locale.h", + "+third_party/blink/renderer/platform/layout_test_support.h", + "+third_party/blink/renderer/platform/layout_unit.h", + "+third_party/blink/renderer/platform/mac/version_util_mac.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/resolution_units.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/text", + "+third_party/blink/renderer/platform/transforms/affine_transform.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/fonts/font.cc b/chromium/third_party/blink/renderer/platform/fonts/font.cc index 511b523682b..dad2347e3e7 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/font.cc @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" 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 5d3f4ce4fd5..c4b0b4afd9c 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/font_cache.cc @@ -168,7 +168,7 @@ FontPlatformData* FontCache::GetFontPlatformData( } if (result) { // Cache the result under the old name. - auto adding = + auto* adding = &font_platform_data_cache_.insert(key, SizedFontPlatformDataSet()) .stored_value->value; adding->Set(rounded_size, std::make_unique<FontPlatformData>(*result)); diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h b/chromium/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h index 461e3bef3e2..04ae4b0bc6d 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h +++ b/chromium/third_party/blink/renderer/platform/fonts/font_data_for_range_set.h @@ -70,7 +70,7 @@ class PLATFORM_EXPORT FontDataForRangeSetFromCache scoped_refptr<SimpleFontData> font_data, scoped_refptr<UnicodeRangeSet> range_set = nullptr) : FontDataForRangeSet(std::move(font_data), std::move(range_set)) {} - virtual ~FontDataForRangeSetFromCache(); + ~FontDataForRangeSetFromCache() override; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc index 77fb5e78008..e573d634fb5 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/font_description_test.cc @@ -48,11 +48,11 @@ TEST(FontDescriptionTest, TestHashCollision) { FontDescription source; WTF::Vector<unsigned> hashes; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(weights); i++) { + for (size_t i = 0; i < arraysize(weights); i++) { source.SetWeight(weights[i]); - for (size_t j = 0; j < WTF_ARRAY_LENGTH(stretches); j++) { + for (size_t j = 0; j < arraysize(stretches); j++) { source.SetStretch(stretches[j]); - for (size_t k = 0; k < WTF_ARRAY_LENGTH(slopes); k++) { + for (size_t k = 0; k < arraysize(slopes); k++) { source.SetStyle(slopes[k]); unsigned hash = source.StyleHashWithoutFamilyList(); ASSERT_FALSE(hashes.Contains(hash)); 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 e0c73ed0a07..fd825e721cc 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 @@ -33,7 +33,7 @@ FontFallbackIterator::FontFallbackIterator( font_fallback_priority_(font_fallback_priority) {} bool FontFallbackIterator::AlreadyLoadingRangeForHintChar(UChar32 hint_char) { - for (auto it = tracked_loading_range_sets_.begin(); + for (auto* it = tracked_loading_range_sets_.begin(); it != tracked_loading_range_sets_.end(); ++it) { if ((*it)->Contains(hint_char)) return true; @@ -44,7 +44,7 @@ bool FontFallbackIterator::AlreadyLoadingRangeForHintChar(UChar32 hint_char) { bool FontFallbackIterator::RangeSetContributesForHint( const Vector<UChar32> hint_list, const FontDataForRangeSet* segmented_face) { - for (auto it = hint_list.begin(); it != hint_list.end(); ++it) { + for (auto* it = hint_list.begin(); it != hint_list.end(); ++it) { if (segmented_face->Contains(*it)) { if (!AlreadyLoadingRangeForHintChar(*it)) return true; diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selection_algorithm.h b/chromium/third_party/blink/renderer/platform/fonts/font_selection_algorithm.h index 83dedcb6bb1..850ed1d93d5 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_selection_algorithm.h +++ b/chromium/third_party/blink/renderer/platform/fonts/font_selection_algorithm.h @@ -26,9 +26,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_SELECTION_ALGORITHM_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_SELECTION_ALGORITHM_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/fonts/font_selection_types.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { 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 66afc15d79c..2940116f782 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_selector.h +++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector.h @@ -44,7 +44,7 @@ class GenericFontFamilySettings; class PLATFORM_EXPORT FontSelector : public FontCacheClient { public: - virtual ~FontSelector() = default; + ~FontSelector() override = default; virtual scoped_refptr<FontData> GetFontData(const FontDescription&, const AtomicString& family_name) = 0; diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h index 259cf82d71f..649b054fb68 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h +++ b/chromium/third_party/blink/renderer/platform/fonts/font_selector_client.h @@ -17,7 +17,7 @@ class FontSelectorClient : public GarbageCollectedMixin { virtual void FontsNeedUpdate(FontSelector*) = 0; - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/fonts/font_test.cc b/chromium/third_party/blink/renderer/platform/fonts/font_test.cc index 69f39f0dc31..c4d1db5f42f 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/font_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/font_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/fonts/font.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/blink/renderer/platform/testing/font_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm index 1110c0e7f43..63b185c2bd8 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm +++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_family_matcher_mac.mm @@ -137,39 +137,18 @@ NSFont* MatchNSFontFamily(const AtomicString& desired_family_string, FontSelectionValue desired_weight, float size) { DCHECK_NE(desired_family_string, FontCache::LegacySystemFontFamily()); - if (desired_family_string == FontFamilyNames::system_ui) { - // On OSX 10.9, the default system font depends on the SDK version. When - // compiled against the OSX 10.10 SDK, the font is .LucidaGrandeUI. When - // compiled against the OSX 10.6 SDK, the font is Lucida Grande. Layout - // tests don't support different expectations based on the SDK version, - // so force layout tests to use "Lucida Grande". Once the 10.10 SDK - // switch is made, this should be changed to return .LucidaGrandeUI and - // the Layout Expectations should be updated. http://crbug.com/515836. - if (LayoutTestSupport::IsRunningLayoutTest() && IsOS10_9()) { - if (desired_weight >= BoldWeightValue()) - return [NSFont fontWithName:@"Lucida Grande Bold" size:size]; - else - return [NSFont fontWithName:@"Lucida Grande" size:size]; - } + if (desired_family_string == FontFamilyNames::system_ui) { NSFont* font = nil; - if (IsOS10_9()) { - // On older OSX versions, only bold and regular are available. - if (desired_weight >= BoldWeightValue()) - font = [NSFont boldSystemFontOfSize:size]; - else - font = [NSFont systemFontOfSize:size]; - } else { // Normally we'd use an availability macro here, but // systemFontOfSize:weight: is available but not visible on macOS 10.10, // so it's been forward declared earlier in this file. // On OSX 10.10+, the default system font has more weights. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunguarded-availability" - font = [NSFont systemFontOfSize:size - weight:toYosemiteFontWeight(desired_weight)]; + font = [NSFont systemFontOfSize:size + weight:toYosemiteFontWeight(desired_weight)]; #pragma clang diagnostic pop - } if (desired_traits & IMPORTANT_FONT_TRAITS) font = [[NSFontManager sharedFontManager] convertFont:font diff --git a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm index 4ed30b37a94..129804a9669 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm +++ b/chromium/third_party/blink/renderer/platform/fonts/mac/font_platform_data_mac.mm @@ -57,16 +57,15 @@ static CTFontDescriptorRef CascadeToLastResortFontDescriptor() { kAdoptCF, CTFontDescriptorCreateWithNameAndSize(CFSTR("LastResort"), 0)); const void* descriptors[] = {last_resort.Get()}; RetainPtr<CFArrayRef> values_array( - kAdoptCF, - CFArrayCreate(kCFAllocatorDefault, descriptors, - WTF_ARRAY_LENGTH(descriptors), &kCFTypeArrayCallBacks)); + kAdoptCF, CFArrayCreate(kCFAllocatorDefault, descriptors, + arraysize(descriptors), &kCFTypeArrayCallBacks)); const void* keys[] = {kCTFontCascadeListAttribute}; const void* values[] = {values_array.Get()}; RetainPtr<CFDictionaryRef> attributes( kAdoptCF, - CFDictionaryCreate(kCFAllocatorDefault, keys, values, - WTF_ARRAY_LENGTH(keys), &kCFTypeDictionaryKeyCallBacks, + CFDictionaryCreate(kCFAllocatorDefault, keys, values, arraysize(keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); descriptor = CTFontDescriptorCreateWithAttributes(attributes.Get()); diff --git a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc index 1201203ecdb..96d52776100 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/script_run_iterator.cc @@ -57,7 +57,7 @@ void ICUScriptData::GetScripts(UChar32 ch, Vector<UScriptCode>& dst) const { // Not common or primary, with extensions that are not in order. We know // the primary, so we insert it at the front and swap the previous front // to somewhere else in the list. - auto it = std::find(dst.begin() + 1, dst.end(), primary_script); + auto* it = std::find(dst.begin() + 1, dst.end(), primary_script); if (it == dst.end()) { dst.push_back(primary_script); } @@ -225,8 +225,8 @@ bool ScriptRunIterator::MergeSets() { return false; } - auto current_set_it = current_set_.begin(); - auto current_end = current_set_.end(); + auto* current_set_it = current_set_.begin(); + auto* current_end = current_set_.end(); // Most of the time, this is the only one. // Advance the current iterator, we won't need to check it again later. UScriptCode priority_script = *current_set_it++; @@ -249,8 +249,8 @@ bool ScriptRunIterator::MergeSets() { // Neither is common or inherited. If current is a singleton, // just see if it exists in the next set. This is the common case. - auto next_it = next_set_.begin(); - auto next_end = next_set_.end(); + auto* next_it = next_set_.begin(); + auto* next_end = next_set_.end(); if (current_set_it == current_end) { return std::find(next_it, next_end, priority_script) != next_end; } @@ -270,7 +270,7 @@ bool ScriptRunIterator::MergeSets() { // Note that we can never write more scripts into the current vector than // it already contains, so currentWriteIt won't ever exceed the size/capacity. - auto current_write_it = current_set_.begin(); + auto* current_write_it = current_set_.begin(); if (have_priority) { // keep the priority script. *current_write_it++ = priority_script; diff --git a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.cc b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.cc index 9834248df3f..f68af86ee42 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/segmented_font_data.cc @@ -32,8 +32,8 @@ namespace blink { const SimpleFontData* SegmentedFontData::FontDataForCharacter(UChar32 c) const { - auto end = faces_.end(); - for (auto it = faces_.begin(); it != end; ++it) { + auto* end = faces_.end(); + for (auto* it = faces_.begin(); it != end; ++it) { if ((*it)->Contains(c)) return (*it)->FontData(); } @@ -41,8 +41,8 @@ const SimpleFontData* SegmentedFontData::FontDataForCharacter(UChar32 c) const { } bool SegmentedFontData::ContainsCharacter(UChar32 c) const { - auto end = faces_.end(); - for (auto it = faces_.begin(); it != end; ++it) { + auto* end = faces_.end(); + for (auto* it = faces_.begin(); it != end; ++it) { if ((*it)->Contains(c)) return true; } @@ -55,8 +55,8 @@ bool SegmentedFontData::IsCustomFont() const { } bool SegmentedFontData::IsLoading() const { - auto end = faces_.end(); - for (auto it = faces_.begin(); it != end; ++it) { + auto* end = faces_.end(); + for (auto* it = faces_.begin(); it != end; ++it) { if ((*it)->FontData()->IsLoading()) return true; } @@ -65,8 +65,8 @@ bool SegmentedFontData::IsLoading() const { // Returns true if any of the sub fonts are loadingFallback. bool SegmentedFontData::IsLoadingFallback() const { - auto end = faces_.end(); - for (auto it = faces_.begin(); it != end; ++it) { + auto* end = faces_.end(); + for (auto* it = faces_.begin(); it != end; ++it) { if ((*it)->FontData()->IsLoadingFallback()) return true; } @@ -78,8 +78,8 @@ bool SegmentedFontData::IsSegmented() const { } bool SegmentedFontData::ShouldSkipDrawing() const { - auto end = faces_.end(); - for (auto it = faces_.begin(); it != end; ++it) { + auto* end = faces_.end(); + for (auto* it = faces_.begin(); it != end; ++it) { if ((*it)->FontData()->ShouldSkipDrawing()) return true; } diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc index 45e40d9d62b..0006c16dc46 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/platform/fonts/shaping/shape_cache.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_buffer.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/wtf/text/character_names.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h index 0b6a215fb45..ab719be4b34 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h @@ -40,6 +40,7 @@ class Font; class ShapeCache; class SimpleFontData; struct GlyphData; +struct TextRunPaintInfo; class PLATFORM_EXPORT CachingWordShaper final { STACK_ALLOCATED(); diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.cc index bf0a73e1184..352e502dd47 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.cc @@ -895,6 +895,28 @@ void HarfBuzzShaper::ShapeSegment(RangeData* range_data, } } +// Get a RunSegmenter for the specified range and FontOrientation. +// +// Because RunSegmenter needs pre-context but is foward-only, it needs to start +// from the beginning for each range. By caching the last-used RunSegmenter, +// when caller shapes multiple ranges of a string incrementally, we can re-use +// existing instance and avoid scanning from the beginning. +RunSegmenter* HarfBuzzShaper::CachedRunSegmenter( + unsigned start, + unsigned end, + FontOrientation orientation) const { + if (!run_segmenter_.has_value() || run_segmenter_->HasProgressedPast(start) || + !run_segmenter_->Supports(orientation)) { + // RunSegmenter is not created yet, or existing instance cannot be reused + // for the new range. Create a new instance. + // + // Run segmentation needs to operate on the entire string, regardless of the + // shaping window (defined by the start and end parameters). + run_segmenter_.emplace(text_, text_length_, orientation); + } + return &run_segmenter_.value(); +} + scoped_refptr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, TextDirection direction, unsigned start, @@ -905,12 +927,8 @@ scoped_refptr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, unsigned length = end - start; scoped_refptr<ShapeResult> result = ShapeResult::Create(font, length, direction); HarfBuzzScopedPtr<hb_buffer_t> buffer(hb_buffer_create(), hb_buffer_destroy); - - // Run segmentation needs to operate on the entire string, regardless of the - // shaping window (defined by the start and end parameters). - RunSegmenter::RunSegmenterRange segment_range = RunSegmenter::NullRange(); - RunSegmenter run_segmenter(text_, text_length_, - font->GetFontDescription().Orientation()); + RunSegmenter* run_segmenter = + CachedRunSegmenter(start, end, font->GetFontDescription().Orientation()); RangeData range_data; range_data.buffer = buffer.Get(); @@ -920,11 +938,20 @@ scoped_refptr<ShapeResult> HarfBuzzShaper::Shape(const Font* font, range_data.end = end; SetFontFeatures(font, &range_data.font_features); - while (run_segmenter.Consume(&segment_range)) { + RunSegmenter::RunSegmenterRange segment_range = RunSegmenter::NullRange(); + for (unsigned run_segmenter_start = start; + run_segmenter->ConsumePast(run_segmenter_start, &segment_range); + run_segmenter_start = segment_range.end) { // Only shape segments overlapping with the range indicated by start and // end. Not only those strictly within. if (start < segment_range.end && end > segment_range.start) ShapeSegment(&range_data, segment_range, result.get()); + + // Break if beyond the requested range. Because RunSegmenter is + // incremental, further ranges are not needed. This also allows reusing + // the segmenter state for next incremental calls. + if (segment_range.end >= end) + break; } // Ensure we have at least one run for StartIndexForResult(). diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.h index 5e86364a4ae..1f0de3eee16 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARF_BUZZ_SHAPER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_HARF_BUZZ_SHAPER_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -45,6 +46,8 @@ struct ReshapeQueueItem; struct RangeData; struct BufferSlice; +enum class FontOrientation; + class PLATFORM_EXPORT HarfBuzzShaper final { public: HarfBuzzShaper(const UChar*, unsigned length); @@ -100,8 +103,15 @@ class PLATFORM_EXPORT HarfBuzzShaper final { const BufferSlice&, ShapeResult*) const; + RunSegmenter* CachedRunSegmenter(unsigned start, + unsigned end, + FontOrientation) const; + const UChar* text_; unsigned text_length_; + + // Cache an instnace of |RunSegmenter|. See |CachedRunSegmenter()|. + mutable base::Optional<RunSegmenter> run_segmenter_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper_test.cc index f038dd7f45a..da081011960 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/harf_buzz_shaper_test.cc @@ -33,6 +33,22 @@ class HarfBuzzShaperTest : public testing::Test { void TearDown() override {} + Font CreateAhem(float size) { + FontDescription::VariantLigatures ligatures; + return blink::test::CreateTestFont( + "Ahem", blink::test::PlatformTestDataPath("Ahem.woff"), size, + &ligatures); + } + + scoped_refptr<ShapeResult> SplitRun(scoped_refptr<ShapeResult> shape_result, + unsigned offset) { + unsigned length = shape_result->NumCharacters(); + scoped_refptr<ShapeResult> run2 = shape_result->SubRange(offset, length); + shape_result = shape_result->SubRange(0, offset); + run2->CopyRange(offset, length, shape_result.get()); + return shape_result; + } + FontCachePurgePreventer font_cache_purge_preventer; FontDescription font_description; Font font; @@ -480,7 +496,7 @@ TEST_P(ShapeParameterTest, ZeroWidthSpace) { 0x0648, kZeroWidthSpaceCharacter, kZeroWidthSpaceCharacter}; - const unsigned length = WTF_ARRAY_LENGTH(string); + const unsigned length = arraysize(string); HarfBuzzShaper shaper(string, length); scoped_refptr<ShapeResult> result = ShapeWithParameter(&shaper); EXPECT_EQ(0u, result->StartIndexForResult()); @@ -547,6 +563,78 @@ TEST_F(HarfBuzzShaperTest, NegativeLetterSpacingToNegative) { EXPECT_GE(result->Bounds().MaxX(), char_width); } +static struct OffsetForPositionTestData { + float position; + unsigned offset_ltr; + unsigned offset_rtl; + unsigned hit_test_ltr; + unsigned hit_test_rtl; + unsigned fit_ltr_ltr; + unsigned fit_ltr_rtl; + unsigned fit_rtl_ltr; + unsigned fit_rtl_rtl; +} offset_for_position_fixed_pitch_test_data[] = { + // The left edge. + {-1, 0, 5, 0, 5, 0, 0, 5, 5}, + {0, 0, 5, 0, 5, 0, 0, 5, 5}, + // Hit test should round to the nearest glyph at the middle of a glyph. + {4, 0, 4, 0, 5, 0, 1, 5, 4}, + {6, 0, 4, 1, 4, 0, 1, 5, 4}, + // Glyph boundary between the 1st and the 2nd glyph. + // Avoid testing "10.0" to avoid rounding differences on Windows. + {9.9, 0, 4, 1, 4, 0, 1, 5, 4}, + {10.1, 1, 3, 1, 4, 1, 2, 4, 3}, + // Run boundary is at position 20. The 1st run has 2 characters. + {14, 1, 3, 1, 4, 1, 2, 4, 3}, + {16, 1, 3, 2, 3, 1, 2, 4, 3}, + {20.1, 2, 2, 2, 3, 2, 3, 3, 2}, + {24, 2, 2, 2, 3, 2, 3, 3, 2}, + {26, 2, 2, 3, 2, 2, 3, 3, 2}, + // The end of the ShapeResult. The result has 5 characters. + {44, 4, 0, 4, 1, 4, 5, 1, 0}, + {46, 4, 0, 5, 0, 4, 5, 1, 0}, + {50, 5, 0, 5, 0, 5, 5, 0, 0}, + // Beyond the right edge of the ShapeResult. + {51, 5, 0, 5, 0, 5, 5, 0, 0}, +}; + +std::ostream& operator<<(std::ostream& ostream, + const OffsetForPositionTestData& data) { + return ostream << data.position; +} + +class OffsetForPositionTest + : public HarfBuzzShaperTest, + public testing::WithParamInterface<OffsetForPositionTestData> {}; + +INSTANTIATE_TEST_CASE_P( + HarfBuzzShaperTest, + OffsetForPositionTest, + testing::ValuesIn(offset_for_position_fixed_pitch_test_data)); + +TEST_P(OffsetForPositionTest, Data) { + auto data = GetParam(); + String string(u"01234"); + HarfBuzzShaper shaper(string.Characters16(), string.length()); + Font ahem = CreateAhem(10); + scoped_refptr<ShapeResult> result = + SplitRun(shaper.Shape(&ahem, TextDirection::kLtr), 2); + EXPECT_EQ(data.offset_ltr, result->OffsetForPosition(data.position, false)); + EXPECT_EQ(data.hit_test_ltr, result->OffsetForPosition(data.position, true)); + EXPECT_EQ(data.fit_ltr_ltr, + result->OffsetToFit(data.position, TextDirection::kLtr)); + EXPECT_EQ(data.fit_ltr_rtl, + result->OffsetToFit(data.position, TextDirection::kRtl)); + + result = SplitRun(shaper.Shape(&ahem, TextDirection::kRtl), 3); + EXPECT_EQ(data.offset_rtl, result->OffsetForPosition(data.position, false)); + EXPECT_EQ(data.hit_test_rtl, result->OffsetForPosition(data.position, true)); + EXPECT_EQ(data.fit_rtl_ltr, + result->OffsetToFit(data.position, TextDirection::kLtr)); + EXPECT_EQ(data.fit_rtl_rtl, + result->OffsetToFit(data.position, TextDirection::kRtl)); +} + TEST_F(HarfBuzzShaperTest, PositionForOffsetLatin) { String string = To16Bit("Hello World!", 12); TextDirection direction = TextDirection::kLtr; @@ -819,7 +907,8 @@ TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeIntoArabicThaiHanLatin) { EXPECT_EQ(result->NumCharacters(), composite_result->NumCharacters()); EXPECT_EQ(result->SnappedWidth(), composite_result->SnappedWidth()); - EXPECT_EQ(result->Bounds(), composite_result->Bounds()); + EXPECT_TRUE(composite_result->Bounds().Contains(result->Bounds())) + << composite_result->Bounds() << "/" << result->Bounds(); EXPECT_EQ(result->SnappedStartPositionForOffset(0), composite_result->SnappedStartPositionForOffset(0)); EXPECT_EQ(result->SnappedStartPositionForOffset(1), @@ -880,6 +969,30 @@ TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeSegmentGlyphBoundingBox) { EXPECT_NEAR(result->Width(), result->Bounds().Width(), result->Width() * .1); } +TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeBoundsLtr) { + String string(u". "); + TextDirection direction = TextDirection::kLtr; + HarfBuzzShaper shaper(string.Characters16(), string.length()); + scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction); + + // Because a space character does not have ink, the bounds of "." should be + // the same as the bounds of ". ". + scoped_refptr<ShapeResult> sub_range = result->SubRange(0, 1); + EXPECT_EQ(sub_range->Bounds().Width(), result->Bounds().Width()); +} + +TEST_F(HarfBuzzShaperTest, ShapeResultCopyRangeBoundsRtl) { + String string(u". "); + TextDirection direction = TextDirection::kRtl; + HarfBuzzShaper shaper(string.Characters16(), string.length()); + scoped_refptr<ShapeResult> result = shaper.Shape(&font, direction); + + // Because a space character does not have ink, the bounds of "." should be + // the same as the bounds of ". ". + scoped_refptr<ShapeResult> sub_range = result->SubRange(0, 1); + EXPECT_EQ(sub_range->Bounds().Width(), result->Bounds().Width()); +} + TEST_F(HarfBuzzShaperTest, SubRange) { String string(u"Hello world"); TextDirection direction = TextDirection::kRtl; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc index 8a81e927d74..e3a4b5bba8d 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.cc @@ -35,7 +35,7 @@ RunSegmenter::RunSegmenter(const UChar* buffer, run_orientation == FontOrientation::kVerticalMixed ? 0 : buffer_size_), symbols_iterator_position_(0), - at_end_(false) {} + at_end_(!buffer_size_) {} void RunSegmenter::ConsumeScriptIteratorPastLastSplit() { DCHECK(script_run_iterator_); @@ -74,8 +74,35 @@ void RunSegmenter::ConsumeSymbolsIteratorPastLastSplit() { } } -bool RunSegmenter::Consume(RunSegmenterRange* next_range) { - if (at_end_ || !buffer_size_) +bool RunSegmenter::Supports(FontOrientation orientation) const { + bool needs_orientation_iterator = + orientation == FontOrientation::kVerticalMixed; + return (needs_orientation_iterator == !!orientation_iterator_.get()); +} + +bool RunSegmenter::HasProgressedPast(unsigned start) const { + return candidate_range_.start > start; +} + +bool RunSegmenter::ConsumePast(unsigned start, RunSegmenterRange* next_range) { + DCHECK(!HasProgressedPast(start)); + while (true) { + // Check the candidate range first, before checking |at_end_| because + // |Consume()| sets |at_end_| even when the current range is valid. + if (candidate_range_.start <= start && start < candidate_range_.end) { + *next_range = candidate_range_; + return true; + } + + if (!Consume()) + return false; + } +} + +// Consume the input until the next range. Returns false if no more ranges are +// available. +bool RunSegmenter::Consume() { + if (at_end_) return false; ConsumeScriptIteratorPastLastSplit(); @@ -99,7 +126,6 @@ bool RunSegmenter::Consume(RunSegmenterRange* next_range) { candidate_range_.start = candidate_range_.end; candidate_range_.end = last_split_; - *next_range = candidate_range_; at_end_ = last_split_ == buffer_size_; return true; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h index e5d8c6059df..c006aefdc5f 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter.h @@ -36,9 +36,23 @@ class PLATFORM_EXPORT RunSegmenter { FontFallbackPriority font_fallback_priority; }; + // Initialize a RunSegmenter. RunSegmenter(const UChar* buffer, unsigned buffer_size, FontOrientation); - bool Consume(RunSegmenterRange*); + // Returns true if the internal state is past |start|. RunSegmenter is forward + // incremental that once it's past a point, it cannot be used for text before + // it. On the ohter hand, if it's not, caller can use the existing instance. + bool HasProgressedPast(unsigned start) const; + + // Returns true if this instance supports the specified FontOrientation. + bool Supports(FontOrientation) const; + + // Advance to the range that includes |start| and return the range. Returns + // false if there are no such ranges. + // + // Callers need to update |start| of the next call to the previous range end + // when they need next range. + bool ConsumePast(unsigned start, RunSegmenterRange*); static RunSegmenterRange NullRange() { return {0, 0, USCRIPT_INVALID_CODE, OrientationIterator::kOrientationKeep, @@ -49,6 +63,7 @@ class PLATFORM_EXPORT RunSegmenter { void ConsumeOrientationIteratorPastLastSplit(); void ConsumeScriptIteratorPastLastSplit(); void ConsumeSymbolsIteratorPastLastSplit(); + bool Consume(); unsigned buffer_size_; RunSegmenterRange candidate_range_; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc index 231a4e9f895..caf858e62c1 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/run_segmenter_test.cc @@ -61,7 +61,9 @@ class RunSegmenterTest : public testing::Test { const Vector<SegmenterExpectedRun>& expect) { RunSegmenter::RunSegmenterRange segmenter_range; unsigned long run_count = 0; - while (run_segmenter->Consume(&segmenter_range)) { + for (unsigned run_segmenter_start = 0; + run_segmenter->ConsumePast(run_segmenter_start, &segmenter_range); + run_segmenter_start = segmenter_range.end) { ASSERT_LT(run_count, expect.size()); ASSERT_EQ(expect[run_count].start, segmenter_range.start); ASSERT_EQ(expect[run_count].limit, segmenter_range.end); @@ -96,7 +98,7 @@ TEST_F(RunSegmenterTest, Empty) { 0, 0, USCRIPT_INVALID_CODE, OrientationIterator::kOrientationKeep}; RunSegmenter run_segmenter(empty.Characters16(), empty.length(), FontOrientation::kVerticalMixed); - DCHECK(!run_segmenter.Consume(&segmenter_range)); + DCHECK(!run_segmenter.ConsumePast(0, &segmenter_range)); ASSERT_EQ(segmenter_range.start, 0u); ASSERT_EQ(segmenter_range.end, 0u); ASSERT_EQ(segmenter_range.script, USCRIPT_INVALID_CODE); @@ -248,4 +250,29 @@ TEST_F(RunSegmenterTest, EmojiSubdivisionFlags) { FontFallbackPriority::kEmojiEmoji}}); } +// Test ConsumePast with |start| advances to the run that includes |start|. +TEST_F(RunSegmenterTest, PastFirstRun) { + String text(u"αβγあいうabc"); + RunSegmenter run_segmenter(text.Characters16(), text.length(), + FontOrientation::kHorizontal); + RunSegmenter::RunSegmenterRange segmenter_range; + EXPECT_TRUE(run_segmenter.ConsumePast(7, &segmenter_range)); + EXPECT_EQ(segmenter_range.start, 6u); + EXPECT_EQ(segmenter_range.end, 9u); + EXPECT_EQ(segmenter_range.script, USCRIPT_LATIN); + EXPECT_EQ(segmenter_range.render_orientation, + OrientationIterator::kOrientationKeep); + EXPECT_EQ(segmenter_range.font_fallback_priority, + FontFallbackPriority::kText); +} + +// Test ConsumePast with |start| larger than buffer size returns false. +TEST_F(RunSegmenterTest, PastBufferLength) { + String text(u"abc"); + RunSegmenter run_segmenter(text.Characters16(), text.length(), + FontOrientation::kHorizontal); + RunSegmenter::RunSegmenterRange segmenter_range; + EXPECT_FALSE(run_segmenter.ConsumePast(4, &segmenter_range)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h index 0153c4c89a2..90d0cff2360 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_cache.h @@ -110,7 +110,7 @@ class ShapeCache { }; public: - ShapeCache() : weak_factory_(this), version_(0) { + ShapeCache() : weak_factory_(this) { // TODO(cavalcantii): Investigate tradeoffs of reserving space // in short_string_map. } @@ -236,8 +236,8 @@ class ShapeCache { SingleCharMap single_char_map_; SmallStringMap short_string_map_; + unsigned version_ = 0; base::WeakPtrFactory<ShapeCache> weak_factory_; - unsigned version_; }; inline bool operator==(const ShapeCache::SmallStringKey& a, diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc index f872c8c8451..50e7d5789bb 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc @@ -135,68 +135,45 @@ float ShapeResult::RunInfo::XPositionForOffset( return position; } -static bool TargetPastEdge(bool rtl, float target_x, float next_x) { - // In LTR, the edge belongs to the character on right. - if (!rtl) - return target_x < next_x; - - // In RTL, the edge belongs to the character on left. - return target_x <= next_x; -} - -int ShapeResult::RunInfo::CharacterIndexForXPosition( +void ShapeResult::RunInfo::CharacterIndexForXPosition( float target_x, - bool include_partial_glyphs) const { + GlyphIndexResult* result) const { DCHECK(target_x >= 0 && target_x <= width_); - if (target_x <= 0) - return !Rtl() ? 0 : num_characters_; const unsigned num_glyphs = glyph_data_.size(); float current_x = 0; - float current_advance = 0; unsigned glyph_index = 0; - unsigned prev_character_index = num_characters_; // used only when rtl() - while (glyph_index < num_glyphs) { - float prev_advance = current_advance; + while (true) { unsigned current_character_index = glyph_data_[glyph_index].character_index; - current_advance = glyph_data_[glyph_index].advance; - while (glyph_index < num_glyphs - 1 && + float current_advance = glyph_data_[glyph_index].advance; + unsigned next_glyph_index = glyph_index + 1; + while (next_glyph_index < num_glyphs && current_character_index == - glyph_data_[glyph_index + 1].character_index) - current_advance += glyph_data_[++glyph_index].advance; - float next_x; - if (include_partial_glyphs) { - // For hit testing, find the closest caret point by incuding - // end-half of the previous character and start-half of the current - // character. - current_advance = current_advance / 2.0; - next_x = current_x + prev_advance + current_advance; - // When include_partial_glyphs, "<=" or "<" is not a big deal because - // |next_x| is not at the character boundary. - if (target_x <= next_x) - return Rtl() ? prev_character_index : current_character_index; - } else { - next_x = current_x + current_advance; - if (TargetPastEdge(Rtl(), target_x, next_x)) - return current_character_index; + glyph_data_[next_glyph_index].character_index) + current_advance += glyph_data_[next_glyph_index++].advance; + float next_x = current_x + current_advance; + if (target_x < next_x || next_glyph_index == num_glyphs) { + result->glyph_index = glyph_index; + result->next_glyph_index = next_glyph_index; + result->character_index = current_character_index; + result->origin_x = current_x; + result->advance = current_advance; + return; } current_x = next_x; - prev_character_index = current_character_index; - ++glyph_index; + glyph_index = next_glyph_index; } - - return Rtl() ? 0 : num_characters_; + NOTREACHED(); } -void ShapeResult::RunInfo::SetGlyphAndPositions(unsigned index, - uint16_t glyph_id, +void HarfBuzzRunGlyphData::SetGlyphAndPositions(uint16_t glyph_id, + uint16_t character_index, float advance, - float offset_x, - float offset_y) { - HarfBuzzRunGlyphData& data = glyph_data_[index]; - data.glyph = glyph_id; - data.advance = advance; - data.offset = FloatSize(offset_x, offset_y); + const FloatSize& offset) { + glyph = glyph_id; + this->character_index = character_index; + this->advance = advance; + this->offset = offset; } ShapeResult::ShapeResult(const SimpleFontData* font_data, @@ -270,7 +247,7 @@ scoped_refptr<ShapeResult> ShapeResult::MutableUnique() const { } unsigned ShapeResult::NextSafeToBreakOffset(unsigned index) const { - for (auto it = runs_.begin(); it != runs_.end(); ++it) { + for (auto* it = runs_.begin(); it != runs_.end(); ++it) { const auto& run = *it; if (!run) continue; @@ -321,50 +298,107 @@ unsigned ShapeResult::PreviousSafeToBreakOffset(unsigned index) const { return StartIndexForResult(); } +// Returns the offset of the character of |result| for LTR. +unsigned ShapeResult::OffsetLtr(const GlyphIndexResult& result) const { + DCHECK(IsLtr(Direction())); + return result.characters_on_left_runs + result.character_index; +} + +// Returns the offset of the character of |result| for RTL. +unsigned ShapeResult::OffsetRtl(const GlyphIndexResult& result, float x) const { + DCHECK(IsRtl(Direction())); + if (!result.IsInRun()) + return NumCharacters() - result.characters_on_left_runs; + // In RTL, the boundary belongs to the left character. This subtle difference + // allows round trips between OffsetForPoint and PointForOffset. + if (UNLIKELY(x == result.origin_x)) + return OffsetLeftRtl(result); + return NumCharacters() - result.characters_on_left_runs - + runs_[result.run_index]->num_characters_ + result.character_index; +} + +// Returns the offset of the character on the right of |result| for LTR. +unsigned ShapeResult::OffsetRightLtr(const GlyphIndexResult& result) const { + DCHECK(IsLtr(Direction())); + if (result.run_index >= runs_.size()) + return NumCharacters(); + const RunInfo& run = *runs_[result.run_index]; + return result.characters_on_left_runs + + (result.next_glyph_index < run.glyph_data_.size() + ? run.glyph_data_[result.next_glyph_index].character_index + : run.num_characters_); +} + +// Returns the offset of the character on the left of |result| for RTL. +unsigned ShapeResult::OffsetLeftRtl(const GlyphIndexResult& result) const { + DCHECK(IsRtl(Direction())); + if (!result.glyph_index) + return NumCharacters() - result.characters_on_left_runs; + const RunInfo& run = *runs_[result.run_index]; + return NumCharacters() - result.characters_on_left_runs - + run.num_characters_ + + run.glyph_data_[result.glyph_index - 1].character_index; +} + // If the position is outside of the result, returns the start or the end offset // depends on the position. -unsigned ShapeResult::OffsetForPosition(float target_x, - bool include_partial_glyphs) const { +void ShapeResult::OffsetForPosition(float target_x, + GlyphIndexResult* result) const { + if (target_x <= 0) + return; + unsigned characters_so_far = 0; float current_x = 0; - - if (Rtl()) { - if (target_x <= 0) - return num_characters_; - characters_so_far = num_characters_; - for (unsigned i = 0; i < runs_.size(); ++i) { - if (!runs_[i]) - continue; - characters_so_far -= runs_[i]->num_characters_; - float next_x = current_x + runs_[i]->width_; - float offset_for_run = target_x - current_x; - if (offset_for_run >= 0 && offset_for_run <= runs_[i]->width_) { - // The x value in question is within this script run. - const unsigned index = runs_[i]->CharacterIndexForXPosition( - offset_for_run, include_partial_glyphs); - return characters_so_far + index; - } - current_x = next_x; - } - } else { - if (target_x <= 0) - return 0; - for (unsigned i = 0; i < runs_.size(); ++i) { - if (!runs_[i]) - continue; - float next_x = current_x + runs_[i]->width_; - float offset_for_run = target_x - current_x; - if (offset_for_run >= 0 && offset_for_run <= runs_[i]->width_) { - const unsigned index = runs_[i]->CharacterIndexForXPosition( - offset_for_run, include_partial_glyphs); - return characters_so_far + index; - } - characters_so_far += runs_[i]->num_characters_; - current_x = next_x; + for (unsigned i = 0; i < runs_.size(); ++i) { + const RunInfo* run = runs_[i].get(); + if (!run) + continue; + float next_x = current_x + run->width_; + float offset_for_run = target_x - current_x; + if (offset_for_run >= 0 && offset_for_run < run->width_) { + // The x value in question is within this script run. + run->CharacterIndexForXPosition(offset_for_run, result); + result->run_index = i; + result->characters_on_left_runs = characters_so_far; + result->origin_x += current_x; + DCHECK_LE(result->characters_on_left_runs + result->character_index, + NumCharacters()); + return; } + characters_so_far += run->num_characters_; + current_x = next_x; } - return characters_so_far; + result->run_index = runs_.size(); + result->characters_on_left_runs = characters_so_far; +} + +unsigned ShapeResult::OffsetForPosition(float x) const { + GlyphIndexResult result; + OffsetForPosition(x, &result); + return IsLtr(Direction()) ? OffsetLtr(result) : OffsetRtl(result, x); +} + +unsigned ShapeResult::OffsetForHitTest(float x) const { + GlyphIndexResult result; + OffsetForPosition(x, &result); + if (IsLtr(Direction())) { + if (result.IsInRun() && x > result.origin_x + result.advance / 2) + return OffsetRightLtr(result); + return OffsetLtr(result); + } + if (result.IsInRun() && x <= result.origin_x + result.advance / 2) + return OffsetLeftRtl(result); + return OffsetRtl(result, x); +} + +unsigned ShapeResult::OffsetToFit(float x, TextDirection line_direction) const { + GlyphIndexResult result; + OffsetForPosition(x, &result); + if (IsLtr(line_direction)) { + return IsLtr(Direction()) ? OffsetLtr(result) : OffsetLeftRtl(result); + } + return IsRtl(Direction()) ? OffsetRtl(result, x) : OffsetRightLtr(result); } float ShapeResult::PositionForOffset( @@ -534,6 +568,66 @@ float HarfBuzzPositionToFloat(hb_position_t value) { return static_cast<float>(value) / (1 << 16); } +// This is a helper class to accumulate glyph bounding box. +// +// Glyph positions and bounding boxes from HarfBuzz and fonts are in physical +// coordinate, while ShapeResult::glyph_bounding_box_ is in logical coordinate. +// To minimize the number of conversions, this class accumulates the bounding +// boxes in physical coordinate, and convert the accumulated box to logical. +struct GlyphBoundsAccumulator { + // Construct an accumulator with the logical glyph origin. + explicit GlyphBoundsAccumulator(float origin) : origin(origin) {} + + // The accumulated glyph bounding box in physical coordinate, until + // ConvertVerticalRunToLogical(). + FloatRect bounds; + // The current origin, in logical coordinate. + float origin; + + // Unite a glyph bounding box to |bounds|. + template <bool is_horizontal_run> + void Unite(const HarfBuzzRunGlyphData& glyph_data, + FloatRect bounds_for_glyph) { + if (UNLIKELY(bounds_for_glyph.IsEmpty())) + return; + + // Glyphs are drawn at |origin + offset|. Move glyph_bounds to that point. + // All positions in hb_glyph_position_t are relative to the current point. + // https://behdad.github.io/harfbuzz/harfbuzz-Buffers.html#hb-glyph-position-t-struct + if (is_horizontal_run) + bounds_for_glyph.SetX(bounds_for_glyph.X() + origin); + else + bounds_for_glyph.SetY(bounds_for_glyph.Y() + origin); + bounds_for_glyph.Move(glyph_data.offset); + + bounds.Unite(bounds_for_glyph); + } + + // Non-template version of |Unite()|, see above. + void Unite(bool is_horizontal_run, + const HarfBuzzRunGlyphData& glyph, + FloatRect bounds_for_glyph) { + is_horizontal_run ? Unite<true>(glyph, bounds_for_glyph) + : Unite<false>(glyph, bounds_for_glyph); + } + + // Convert vertical run glyph bounding box to logical. Horizontal runs do not + // need conversions because physical and logical are the same. + void ConvertVerticalRunToLogical(const FontMetrics& font_metrics) { + // Convert physical glyph_bounding_box to logical. + bounds = bounds.TransposedRect(); + + // The glyph bounding box of a vertical run uses ideographic baseline. + // Adjust the box Y position because the bounding box of a ShapeResult uses + // alphabetic baseline. + // See diagrams of base lines at + // https://drafts.csswg.org/css-writing-modes-3/#intro-baselines + int baseline_adjust = font_metrics.Ascent(kIdeographicBaseline) - + font_metrics.Ascent(kAlphabeticBaseline); + bounds.SetY(bounds.Y() + baseline_adjust); + } +}; + // Checks whether it's safe to break without reshaping before the given glyph. bool IsSafeToBreakBefore(const hb_glyph_info_t* glyph_infos, unsigned num_glyphs, @@ -562,10 +656,9 @@ template <bool is_horizontal_run> void ShapeResult::ComputeGlyphPositions(ShapeResult::RunInfo* run, unsigned start_glyph, unsigned num_glyphs, - hb_buffer_t* harf_buzz_buffer, - FloatRect* glyph_bounding_box) { + hb_buffer_t* harf_buzz_buffer) { DCHECK_EQ(is_horizontal_run, run->IsHorizontal()); - const SimpleFontData* current_font_data = run->font_data_.get(); + const SimpleFontData& current_font_data = *run->font_data_; const hb_glyph_info_t* glyph_infos = hb_buffer_get_glyph_infos(harf_buzz_buffer, nullptr); const hb_glyph_position_t* glyph_positions = @@ -579,66 +672,52 @@ void ShapeResult::ComputeGlyphPositions(ShapeResult::RunInfo* run, // and boudning box of glyphs are in physical. It's the caller's // responsibility to convert the united physical bounds to logical. float total_advance = 0.0f; - FloatPoint glyph_origin; - if (is_horizontal_run) - glyph_origin.SetX(width_); - else - glyph_origin.SetY(width_); + GlyphBoundsAccumulator bounds(width_); bool has_vertical_offsets = !is_horizontal_run; + // Because we reverse this later, it must be empty at this point. + DCHECK(run->safe_break_offsets_.IsEmpty()); + // HarfBuzz returns result in visual order, no need to flip for RTL. for (unsigned i = 0; i < num_glyphs; ++i) { uint16_t glyph = glyph_infos[start_glyph + i].codepoint; - hb_glyph_position_t pos = glyph_positions[start_glyph + i]; + const hb_glyph_position_t& pos = glyph_positions[start_glyph + i]; // Offset is primarily used when painting glyphs. Keep it in physical. - float offset_x = HarfBuzzPositionToFloat(pos.x_offset); - float offset_y = -HarfBuzzPositionToFloat(pos.y_offset); + FloatSize offset(HarfBuzzPositionToFloat(pos.x_offset), + -HarfBuzzPositionToFloat(pos.y_offset)); // One out of x_advance and y_advance is zero, depending on // whether the buffer direction is horizontal or vertical. // Convert to float and negate to avoid integer-overflow for ULONG_MAX. - float advance; - if (is_horizontal_run) - advance = HarfBuzzPositionToFloat(pos.x_advance); - else - advance = -HarfBuzzPositionToFloat(pos.y_advance); + float advance = is_horizontal_run ? HarfBuzzPositionToFloat(pos.x_advance) + : -HarfBuzzPositionToFloat(pos.y_advance); uint16_t character_index = glyph_infos[start_glyph + i].cluster - start_cluster; - run->glyph_data_[i].character_index = character_index; - - run->SetGlyphAndPositions(i, glyph, advance, offset_x, offset_y); + HarfBuzzRunGlyphData& glyph_data = run->glyph_data_[i]; + glyph_data.SetGlyphAndPositions(glyph, character_index, advance, offset); total_advance += advance; - has_vertical_offsets |= (offset_y != 0); + has_vertical_offsets |= (offset.Height() != 0); - // SetGlyphAndPositions() above sets to draw glyphs at |glyph_origin + - // offset_{x,y}|. Move glyph_bounds to that point. - // Then move the current point by |advance| from |glyph_origin|. - // All positions in hb_glyph_position_t are relative to the current point. - // https://behdad.github.io/harfbuzz/harfbuzz-Buffers.html#hb-glyph-position-t-struct - FloatRect glyph_bounds = current_font_data->BoundsForGlyph(glyph); - if (!glyph_bounds.IsEmpty()) { - glyph_bounds.Move(glyph_origin.X() + offset_x, - glyph_origin.Y() + offset_y); - glyph_bounding_box->Unite(glyph_bounds); - } - if (is_horizontal_run) - glyph_origin.SetX(glyph_origin.X() + advance); - else - glyph_origin.SetY(glyph_origin.Y() + advance); + bounds.Unite<is_horizontal_run>( + glyph_data, current_font_data.BoundsForGlyph(glyph_data.glyph)); + bounds.origin += advance; // Check if it is safe to break without reshaping before the cluster. - if (IsSafeToBreakBefore(glyph_infos + start_glyph, num_glyphs, i)) { - if (run->Rtl()) - run->safe_break_offsets_.push_front(character_index); - else - run->safe_break_offsets_.push_back(character_index); - } + if (IsSafeToBreakBefore(glyph_infos + start_glyph, num_glyphs, i)) + run->safe_break_offsets_.push_back(character_index); } run->width_ = std::max(0.0f, total_advance); has_vertical_offsets_ |= has_vertical_offsets; + + if (!is_horizontal_run) + bounds.ConvertVerticalRunToLogical(current_font_data.GetFontMetrics()); + glyph_bounding_box_.Unite(bounds.bounds); + + if (UNLIKELY(run->Rtl())) + run->safe_break_offsets_.Reverse(); } void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run_to_insert, @@ -649,30 +728,17 @@ void ShapeResult::InsertRun(std::unique_ptr<ShapeResult::RunInfo> run_to_insert, std::unique_ptr<ShapeResult::RunInfo> run(std::move(run_to_insert)); DCHECK_EQ(num_glyphs, run->glyph_data_.size()); - FloatRect glyph_bounding_box; if (run->IsHorizontal()) { // Inserting a horizontal run into a horizontal or vertical result. In both // cases, no adjustments are needed because |glyph_bounding_box_| is in // logical coordinates and uses alphabetic baseline. ComputeGlyphPositions<true>(run.get(), start_glyph, num_glyphs, - harf_buzz_buffer, &glyph_bounding_box); + harf_buzz_buffer); } else { // Inserting a vertical run to a vertical result. ComputeGlyphPositions<false>(run.get(), start_glyph, num_glyphs, - harf_buzz_buffer, &glyph_bounding_box); - // Convert physical glyph_bounding_box to logical. - glyph_bounding_box = glyph_bounding_box.TransposedRect(); - // The glyph bounding box of a vertical run uses ideographic baseline. - // Adjust the box Y position because the bounding box of a ShapeResult uses - // alphabetic baseline. - // See diagrams of base lines at - // https://drafts.csswg.org/css-writing-modes-3/#intro-baselines - const FontMetrics& font_metrics = run->font_data_->GetFontMetrics(); - int baseline_adjust = font_metrics.Ascent(kIdeographicBaseline) - - font_metrics.Ascent(kAlphabeticBaseline); - glyph_bounding_box.SetY(glyph_bounding_box.Y() + baseline_adjust); + harf_buzz_buffer); } - glyph_bounding_box_.Unite(glyph_bounding_box); width_ += run->width_; num_glyphs_ += num_glyphs; DCHECK_GE(num_glyphs_, num_glyphs); @@ -760,6 +826,54 @@ void ShapeResult::ReorderRtlRuns(unsigned run_size_before) { runs_.swap(new_runs); } +// Returns the left of the glyph bounding box of the left most character. +float ShapeResult::LineLeftBounds() const { + DCHECK(!runs_.IsEmpty()); + const RunInfo& run = *runs_.front(); + const bool is_horizontal_run = run.IsHorizontal(); + const SimpleFontData& font_data = *run.font_data_; + DCHECK(!run.glyph_data_.IsEmpty()) << ToString(); + const unsigned character_index = run.glyph_data_.front().character_index; + GlyphBoundsAccumulator bounds(0.f); + for (const auto& glyph : run.glyph_data_) { + if (character_index != glyph.character_index) + break; + bounds.Unite(is_horizontal_run, glyph, + font_data.BoundsForGlyph(glyph.glyph)); + bounds.origin += glyph.advance; + } + if (UNLIKELY(!is_horizontal_run)) + bounds.ConvertVerticalRunToLogical(font_data.GetFontMetrics()); + return bounds.bounds.X(); +} + +// Returns the right of the glyph bounding box of the right most character. +float ShapeResult::LineRightBounds() const { + DCHECK(!runs_.IsEmpty()); + const RunInfo& run = *runs_.back(); + const bool is_horizontal_run = run.IsHorizontal(); + const SimpleFontData& font_data = *run.font_data_; + DCHECK(!run.glyph_data_.IsEmpty()) << ToString(); + const unsigned character_index = run.glyph_data_.back().character_index; + GlyphBoundsAccumulator bounds(width_); + for (auto glyph_it = run.glyph_data_.rbegin(); + glyph_it != run.glyph_data_.rend(); ++glyph_it) { + const auto& glyph = *glyph_it; + if (character_index != glyph.character_index) + break; + bounds.origin -= glyph.advance; + bounds.Unite(is_horizontal_run, glyph, + font_data.BoundsForGlyph(glyph.glyph)); + } + // If the last character has no ink (e.g., space character), assume the + // character before will not overflow more than the width of the space. + if (UNLIKELY(bounds.bounds.IsEmpty())) + return width_; + if (UNLIKELY(!is_horizontal_run)) + bounds.ConvertVerticalRunToLogical(font_data.GetFontMetrics()); + return bounds.bounds.MaxX(); +} + void ShapeResult::CopyRange(unsigned start_offset, unsigned end_offset, ShapeResult* target) const { @@ -796,27 +910,31 @@ void ShapeResult::CopyRange(unsigned start_offset, } } - if (target->runs_.size() == target_run_size_before) + if (!target->num_glyphs_) return; // Runs in RTL result are in visual order, and that new runs should be // prepended. Reorder appended runs. DCHECK_EQ(Rtl(), target->Rtl()); - if (target->Rtl()) + if (UNLIKELY(Rtl() && target->runs_.size() != target_run_size_before)) target->ReorderRtlRuns(target_run_size_before); // Compute new glyph bounding box. - // If |start_offset| or |end_offset| are the start/end of |this|, use - // |glyph_bounding_box_| from |this| for the side. Otherwise, we cannot - // compute accurate glyph bounding box; approximate by assuming there are no - // glyph overflow nor underflow. - float left = target->width_; + // + // Computing glyph bounding box from Font is one of the most expensive + // operations. If |start_offset| or |end_offset| are the start/end of |this|, + // use the current |glyph_bounding_box_| for the side. + DCHECK(primary_font_.get() == target->primary_font_.get()); + bool know_left_edge = start_offset <= StartIndexForResult(); + bool know_right_edge = end_offset >= EndIndexForResult(); + if (UNLIKELY(Rtl())) + std::swap(know_left_edge, know_right_edge); + float left = know_left_edge ? target->width_ + glyph_bounding_box_.X() + : target->LineLeftBounds(); target->width_ += total_width; - float right = target->width_; - if (start_offset <= StartIndexForResult()) - left += glyph_bounding_box_.X(); - if (end_offset >= EndIndexForResult()) - right += glyph_bounding_box_.MaxX() - width_; + float right = know_right_edge + ? glyph_bounding_box_.MaxX() - width_ + target->width_ + : target->LineRightBounds(); FloatRect adjusted_box(left, glyph_bounding_box_.Y(), std::max(right - left, 0.0f), glyph_bounding_box_.Height()); @@ -841,6 +959,25 @@ scoped_refptr<ShapeResult> ShapeResult::SubRange(unsigned start_offset, return sub_range; } +scoped_refptr<ShapeResult> ShapeResult::CopyAdjustedOffset( + unsigned start_index) const { + scoped_refptr<ShapeResult> result = base::AdoptRef(new ShapeResult(*this)); + + if (start_index > result->StartIndexForResult()) { + unsigned delta = start_index - result->StartIndexForResult(); + for (auto& run : result->runs_) + run->start_index_ += delta; + } else { + unsigned delta = result->StartIndexForResult() - start_index; + for (auto& run : result->runs_) { + DCHECK(run->start_index_ >= delta); + run->start_index_ -= delta; + } + } + + return result; +} + #if DCHECK_IS_ON() void ShapeResult::CheckConsistency() const { if (runs_.IsEmpty()) { @@ -887,11 +1024,12 @@ scoped_refptr<ShapeResult> ShapeResult::CreateForTabulationCharacters( float start_position = position; for (unsigned i = 0; i < count; i++) { float advance = font->TabWidth(font_data, text_run.GetTabSize(), position); - run->glyph_data_[i].character_index = i; - run->SetGlyphAndPositions(i, font_data->SpaceGlyph(), advance, 0, 0); + HarfBuzzRunGlyphData& glyph_data = run->glyph_data_[i]; + glyph_data.SetGlyphAndPositions(font_data->SpaceGlyph(), i, advance, + FloatSize()); // Assume it's safe to break after a tab character. - run->safe_break_offsets_.push_back(run->glyph_data_[i].character_index); + run->safe_break_offsets_.push_back(glyph_data.character_index); position += advance; } run->width_ = position - start_position; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h index 3d842044e48..2505db6c7fd 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result.h @@ -112,7 +112,20 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { unsigned NextSafeToBreakOffset(unsigned offset) const; unsigned PreviousSafeToBreakOffset(unsigned offset) const; - unsigned OffsetForPosition(float target_x, bool include_partial_glyphs) const; + // Returns the offset whose (origin, origin+advance) contains |x|. + unsigned OffsetForPosition(float x) const; + // Returns the offset whose glyph boundary is nearest to |x|. Depends on + // whether |x| is on the left-half or the right-half of the glyph, it + // determines the left-boundary or the right-boundary, then computes the + // offset from the bidi direction. + unsigned OffsetForHitTest(float x) const; + // Returns the offset that can fit to between |x| and the left or the right + // edge. The side of the edge is determined by |line_direction|. + unsigned OffsetToFit(float x, TextDirection line_direction) const; + unsigned OffsetForPosition(float x, bool include_partial_glyphs) const { + return !include_partial_glyphs ? OffsetForPosition(x) : OffsetForHitTest(x); + } + float PositionForOffset(unsigned offset, AdjustMidCluster = AdjustMidCluster::kToEnd) const; LayoutUnit SnappedStartPositionForOffset(unsigned offset) const { @@ -131,10 +144,16 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { scoped_refptr<ShapeResult> ApplySpacingToCopy(ShapeResultSpacing<TextRun>&, const TextRun&) const; + // Append a copy of a range within an existing result to another result. void CopyRange(unsigned start, unsigned end, ShapeResult*) const; + + // Create a new ShapeResult instance from a range within an existing result. scoped_refptr<ShapeResult> SubRange(unsigned start_offset, unsigned end_offset) const; + // Create a new ShapeResult instance with the start offset adjusted. + scoped_refptr<ShapeResult> CopyAdjustedOffset(unsigned start_offset) const; + // Computes the list of fonts along with the number of glyphs for each font. struct RunFontData { SimpleFontData* font_data_; @@ -169,6 +188,33 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { return base::AdoptRef(new ShapeResult(other)); } + struct GlyphIndexResult { + STACK_ALLOCATED(); + + unsigned run_index = 0; + // The total number of characters of runs_[0..run_index - 1]. + unsigned characters_on_left_runs = 0; + unsigned character_index = 0; + unsigned glyph_index = 0; + // |next_glyph_index| may not be |glyph_index| + 1 when a cluster is of + // multiple glyphs; i.e., ligatures or combining glyphs. + unsigned next_glyph_index = 0; + // The glyph origin of the glyph. + float origin_x = 0; + // The advance of the glyph. + float advance = 0; + + // True if the position was found on a run. False otherwise. + bool IsInRun() const { return next_glyph_index; } + }; + + unsigned OffsetLtr(const GlyphIndexResult&) const; + unsigned OffsetRtl(const GlyphIndexResult&, float x) const; + unsigned OffsetRightLtr(const GlyphIndexResult&) const; + unsigned OffsetLeftRtl(const GlyphIndexResult&) const; + + void OffsetForPosition(float target_x, GlyphIndexResult*) const; + template <typename TextContainerType> void ApplySpacingImpl(ShapeResultSpacing<TextContainerType>&, int text_start_offset = 0); @@ -176,8 +222,7 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { void ComputeGlyphPositions(ShapeResult::RunInfo*, unsigned start_glyph, unsigned num_glyphs, - hb_buffer_t*, - FloatRect* glyph_bounding_box); + hb_buffer_t*); void InsertRun(std::unique_ptr<ShapeResult::RunInfo>, unsigned start_glyph, unsigned num_glyphs, @@ -186,6 +231,9 @@ class PLATFORM_EXPORT ShapeResult : public RefCounted<ShapeResult> { void InsertRunForIndex(unsigned start_character_index); void ReorderRtlRuns(unsigned run_size_before); + float LineLeftBounds() const; + float LineRightBounds() const; + float width_; FloatRect glyph_bounding_box_; Vector<std::unique_ptr<RunInfo>> runs_; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc index 43d94a6941b..ab70452701c 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/text/text_break_iterator.h" #include "third_party/blink/renderer/platform/text/text_run.h" diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h index 320e7305dfa..a3204c4739d 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h @@ -20,6 +20,7 @@ namespace blink { class Font; +struct TextRunPaintInfo; class PLATFORM_EXPORT ShapeResultBloberizer { WTF_MAKE_NONCOPYABLE(ShapeResultBloberizer); diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc index 25c450376ca..3704e85e4ee 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer_test.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h" #include <memory> +#include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/fonts/character_range.h" #include "third_party/blink/renderer/platform/fonts/font.h" @@ -12,8 +13,8 @@ #include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_test_info.h" #include "third_party/blink/renderer/platform/fonts/simple_font_data.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_typeface.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h index d24ea32cf99..38a9178c6e1 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shape_result_inline_headers.h @@ -48,6 +48,11 @@ struct HarfBuzzRunGlyphData { uint16_t character_index; float advance; FloatSize offset; + + void SetGlyphAndPositions(uint16_t glyph_id, + uint16_t character_index, + float advance, + const FloatSize& offset); }; struct ShapeResult::RunInfo { @@ -87,12 +92,7 @@ struct ShapeResult::RunInfo { unsigned PreviousSafeToBreakOffset(unsigned) const; float XPositionForVisualOffset(unsigned, AdjustMidCluster) const; float XPositionForOffset(unsigned, AdjustMidCluster) const; - int CharacterIndexForXPosition(float, bool include_partial_glyphs) const; - void SetGlyphAndPositions(unsigned index, - uint16_t glyph_id, - float advance, - float offset_x, - float offset_y); + void CharacterIndexForXPosition(float, GlyphIndexResult*) const; size_t GlyphToCharacterIndex(size_t i) const { return start_index_ + glyph_data_[i].character_index; diff --git a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc index 24daffd79dc..30cb27dbf6b 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/shaping/shaping_line_breaker_test.cc @@ -246,11 +246,12 @@ TEST_F(ShapingLineBreakerTest, DISABLED_ShapeLineArabicThaiHanLatin) { shaper.Shape(&font, direction, 5, 6), shaper.Shape(&font, direction, 6, 7), shaper.Shape(&font, direction, 7, 8)}; - const auto& longest_word = std::max_element( - std::begin(words), std::end(words), - [](const scoped_refptr<ShapeResult>& a, const scoped_refptr<ShapeResult>& b) { - return a->SnappedWidth() < b->SnappedWidth(); - }); + auto* const longest_word = + std::max_element(std::begin(words), std::end(words), + [](const scoped_refptr<ShapeResult>& a, + const scoped_refptr<ShapeResult>& b) { + return a->SnappedWidth() < b->SnappedWidth(); + }); LayoutUnit longest_word_width = (*longest_word)->SnappedWidth(); ShapingLineBreaker breaker(&shaper, &font, result.get(), &break_iterator); diff --git a/chromium/third_party/blink/renderer/platform/text/string_truncator.cc b/chromium/third_party/blink/renderer/platform/fonts/string_truncator.cc index ea7586d312f..900246ae7f0 100644 --- a/chromium/third_party/blink/renderer/platform/text/string_truncator.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/string_truncator.cc @@ -26,7 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/platform/text/string_truncator.h" +#include "third_party/blink/renderer/platform/fonts/string_truncator.h" #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/text/text_break_iterator.h" @@ -101,11 +101,6 @@ static unsigned RightTruncateToBuffer(const String& string, return truncated_length; } -static float StringWidth(const Font& renderer, const String& string) { - TextRun run(string); - return renderer.Width(run); -} - static float StringWidth(const Font& renderer, const UChar* characters, unsigned length) { @@ -214,8 +209,4 @@ String StringTruncator::RightTruncate(const String& string, return TruncateString(string, max_width, font, RightTruncateToBuffer); } -float StringTruncator::Width(const String& string, const Font& font) { - return StringWidth(font, string); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/string_truncator.h b/chromium/third_party/blink/renderer/platform/fonts/string_truncator.h index b93a48d82cc..0a8b2d1d8e0 100644 --- a/chromium/third_party/blink/renderer/platform/text/string_truncator.h +++ b/chromium/third_party/blink/renderer/platform/fonts/string_truncator.h @@ -26,8 +26,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_STRING_TRUNCATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_STRING_TRUNCATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_STRING_TRUNCATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_STRING_TRUNCATOR_H_ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -43,9 +43,8 @@ class PLATFORM_EXPORT StringTruncator { public: static String CenterTruncate(const String&, float max_width, const Font&); static String RightTruncate(const String&, float max_width, const Font&); - static float Width(const String&, const Font&); }; } // namespace blink -#endif // !defined(StringTruncator_h) +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_STRING_TRUNCATOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/fonts/text_run_paint_info.h b/chromium/third_party/blink/renderer/platform/fonts/text_run_paint_info.h new file mode 100644 index 00000000000..01d5332985a --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/fonts/text_run_paint_info.h @@ -0,0 +1,29 @@ +// 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_FONTS_TEXT_RUN_PAINT_INFO_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_TEXT_RUN_PAINT_INFO_H_ + +#include "third_party/blink/renderer/platform/geometry/float_rect.h" +#include "third_party/blink/renderer/platform/text/text_run.h" + +namespace blink { + +// Container for parameters needed to paint TextRun. +struct TextRunPaintInfo { + STACK_ALLOCATED(); + + public: + explicit TextRunPaintInfo(const TextRun& r) + : run(r), from(0), to(r.length()) {} + + const TextRun& run; + unsigned from; + unsigned to; + FloatRect bounds; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_TEXT_RUN_PAINT_INFO_H_ diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc index 6c6e206f803..03dad0c36b1 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_cache_skia_win.cc @@ -213,10 +213,10 @@ scoped_refptr<SimpleFontData> FontCache::PlatformFallbackFontForCharacter( int num_fonts = 0; if (script == USCRIPT_HAN) { pan_uni_fonts = kCjkFonts; - num_fonts = WTF_ARRAY_LENGTH(kCjkFonts); + num_fonts = arraysize(kCjkFonts); } else { pan_uni_fonts = kCommonFonts; - num_fonts = WTF_ARRAY_LENGTH(kCommonFonts); + num_fonts = arraysize(kCommonFonts); } // Font returned from getFallbackFamily may not cover |character| // because it's based on script to font mapping. This problem is @@ -292,7 +292,7 @@ static bool TypefacesHasWeightSuffix(const AtomicString& family, {L" ultrabold", 10, FontSelectionValue(800)}, {L" black", 6, FontSelectionValue(900)}, {L" heavy", 6, FontSelectionValue(900)}}; - size_t num_variants = WTF_ARRAY_LENGTH(kVariantForSuffix); + size_t num_variants = arraysize(kVariantForSuffix); for (size_t i = 0; i < num_variants; i++) { const FamilyWeightSuffix& entry = kVariantForSuffix[i]; if (family.EndsWith(entry.suffix, kTextCaseUnicodeInsensitive)) { @@ -329,7 +329,7 @@ static bool TypefacesHasStretchSuffix(const AtomicString& family, {L" expanded", 9, ExpandedWidthValue()}, {L" extraexpanded", 14, ExtraExpandedWidthValue()}, {L" ultraexpanded", 14, UltraExpandedWidthValue()}}; - size_t num_variants = WTF_ARRAY_LENGTH(kVariantForSuffix); + size_t num_variants = arraysize(kVariantForSuffix); for (size_t i = 0; i < num_variants; i++) { const FamilyStretchSuffix& entry = kVariantForSuffix[i]; if (family.EndsWith(entry.suffix, kTextCaseUnicodeInsensitive)) { diff --git a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc index aaf5982c76c..319f7290a2f 100644 --- a/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc +++ b/chromium/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc @@ -375,13 +375,13 @@ const UChar* GetFontBasedOnUnicodeBlock(UBlockCode block_code, static const UChar* math_font = 0; static bool initialized = false; if (!initialized) { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kEmojiFonts); i++) { + for (size_t i = 0; i < arraysize(kEmojiFonts); i++) { if (IsFontPresent(kEmojiFonts[i], font_manager)) { emoji_font = kEmojiFonts[i]; break; } } - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kMathFonts); i++) { + for (size_t i = 0; i < arraysize(kMathFonts); i++) { if (IsFontPresent(kMathFonts[i], font_manager)) { math_font = kMathFonts[i]; break; diff --git a/chromium/third_party/blink/renderer/platform/geometry/DEPS b/chromium/third_party/blink/renderer/platform/geometry/DEPS index 504247153f6..3d15f4018a3 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/DEPS +++ b/chromium/third_party/blink/renderer/platform/geometry/DEPS @@ -1,5 +1,16 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/geometry", + + # Dependencies. + "+cc/base/region.h", + "+third_party/blink/renderer/platform/json", + "+third_party/blink/renderer/platform/layout_unit.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/pod_interval_tree.h", + "+third_party/blink/renderer/platform/wtf", "+ui/gfx/geometry", ] diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_point.h b/chromium/third_party/blink/renderer/platform/geometry/double_point.h index e9e5f3f30ff..9b251482fd7 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/double_point.h +++ b/chromium/third_party/blink/renderer/platform/geometry/double_point.h @@ -111,7 +111,7 @@ inline DoublePoint operator-(const DoublePoint& a, const DoubleSize& b) { } inline IntPoint RoundedIntPoint(const DoublePoint& p) { - return IntPoint(clampTo<int>(roundf(p.X())), clampTo<int>(roundf(p.Y()))); + return IntPoint(clampTo<int>(round(p.X())), clampTo<int>(round(p.Y()))); } inline IntPoint CeiledIntPoint(const DoublePoint& p) { diff --git a/chromium/third_party/blink/renderer/platform/geometry/double_point_test.cc b/chromium/third_party/blink/renderer/platform/geometry/double_point_test.cc new file mode 100644 index 00000000000..640ed1fa443 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/geometry/double_point_test.cc @@ -0,0 +1,19 @@ +// 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/geometry/double_point.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(DoublePointTest, RoundedIntPoint) { + // Value not exactly representable as a float. + DoublePoint p1(16777217.0, -16777217.0); + IntPoint rounded_p1 = RoundedIntPoint(p1); + EXPECT_EQ(16777217, rounded_p1.X()); + EXPECT_EQ(-16777217, rounded_p1.Y()); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point.cc b/chromium/third_party/blink/renderer/platform/geometry/float_point.cc index 63095fa498f..75a820a3dcf 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_point.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_point.cc @@ -29,14 +29,17 @@ #include <math.h> #include <algorithm> #include <limits> + #include "SkPoint.h" #include "third_party/blink/renderer/platform/geometry/double_point.h" #include "third_party/blink/renderer/platform/geometry/layout_point.h" #include "third_party/blink/renderer/platform/geometry/layout_size.h" -#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/skia/include/core/SkPoint.h" +#include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/scroll_offset.h" namespace blink { @@ -78,11 +81,6 @@ void FloatPoint::MoveBy(const LayoutPoint& point) { y_ += point.Y(); } -SkPoint FloatPoint::Data() const { - SkPoint p = {WebCoreFloatToSkScalar(x_), WebCoreFloatToSkScalar(y_)}; - return p; -} - FloatPoint FloatPoint::NarrowPrecision(double x, double y) { return FloatPoint(clampTo<float>(x), clampTo<float>(y)); } @@ -110,8 +108,12 @@ bool FindIntersection(const FloatPoint& p1, return true; } -FloatPoint::operator SkPoint() const { - return SkPoint::Make(x_, y_); +FloatPoint::operator gfx::PointF() const { + return gfx::PointF(x_, y_); +} + +FloatPoint::operator gfx::ScrollOffset() const { + return gfx::ScrollOffset(x_, y_); } std::ostream& operator<<(std::ostream& ostream, const FloatPoint& point) { @@ -122,4 +124,11 @@ String FloatPoint::ToString() const { return String::Format("%lg,%lg", X(), Y()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const FloatPoint& p) { + ts << "(" << WTF::TextStream::FormatNumberRespectingIntegers(p.X()); + ts << "," << WTF::TextStream::FormatNumberRespectingIntegers(p.Y()); + ts << ")"; + return ts; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_point.h b/chromium/third_party/blink/renderer/platform/geometry/float_point.h index 6b3593ab8d1..fcabd69402c 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_point.h +++ b/chromium/third_party/blink/renderer/platform/geometry/float_point.h @@ -44,6 +44,11 @@ typedef struct CGPoint CGPoint; struct SkPoint; +namespace gfx { +class PointF; +class ScrollOffset; +} + namespace blink { class DoublePoint; @@ -128,10 +133,8 @@ class PLATFORM_EXPORT FloatPoint { operator CGPoint() const; #endif - // Can we remove this one? - SkPoint Data() const; - - operator SkPoint() const; + operator gfx::PointF() const; + explicit operator gfx::ScrollOffset() const; String ToString() const; @@ -236,6 +239,8 @@ PLATFORM_EXPORT bool FindIntersection(const FloatPoint& p1, FloatPoint& intersection); PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatPoint&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, + const FloatPoint&); } // namespace blink 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 79ac416facd..5a99342edbc 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 @@ -22,9 +22,11 @@ #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" #include <math.h> -#include "third_party/blink/renderer/platform/text/text_stream.h" + #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/geometry/point3_f.h" namespace blink { @@ -51,6 +53,10 @@ 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(); } @@ -59,7 +65,7 @@ String FloatPoint3D::ToString() const { return String::Format("%lg,%lg,%lg", X(), Y(), Z()); } -TextStream& operator<<(TextStream& ts, const FloatPoint3D& p) { +WTF::TextStream& operator<<(WTF::TextStream& ts, const FloatPoint3D& p) { ts << "x=" << p.X() << " y=" << p.Y() << " z=" << p.Z(); return ts; } 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 1f49a063af8..6717f3f16b3 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 @@ -25,11 +25,14 @@ #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/skia/include/core/SkPoint3.h" -namespace blink { +namespace gfx { +class Point3F; +} -class TextStream; +namespace blink { class PLATFORM_EXPORT FloatPoint3D { DISALLOW_NEW(); @@ -105,6 +108,7 @@ class PLATFORM_EXPORT FloatPoint3D { float DistanceTo(const FloatPoint3D& a) const; operator SkPoint3() const { return SkPoint3::Make(x_, y_, z_); } + operator gfx::Point3F() const; String ToString() const; @@ -158,7 +162,7 @@ inline float FloatPoint3D::DistanceTo(const FloatPoint3D& a) const { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatPoint3D&); -TextStream& operator<<(TextStream&, const FloatPoint3D&); +WTF::TextStream& operator<<(WTF::TextStream&, const FloatPoint3D&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_polygon.cc b/chromium/third_party/blink/renderer/platform/geometry/float_polygon.cc index ef20d12e884..2b348616915 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_polygon.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_polygon.cc @@ -85,9 +85,8 @@ static unsigned FindNextEdgeVertexIndex(const FloatPolygon& polygon, return vertex_index2; } -FloatPolygon::FloatPolygon(std::unique_ptr<Vector<FloatPoint>> vertices, - WindRule fill_rule) - : vertices_(std::move(vertices)), fill_rule_(fill_rule) { +FloatPolygon::FloatPolygon(std::unique_ptr<Vector<FloatPoint>> vertices) + : vertices_(std::move(vertices)) { unsigned n_vertices = NumberOfVertices(); edges_.resize(n_vertices); empty_ = n_vertices < 3; @@ -174,6 +173,8 @@ static inline float LeftSide(const FloatPoint& vertex1, } bool FloatPolygon::ContainsEvenOdd(const FloatPoint& point) const { + if (!bounding_box_.Contains(point)) + return false; unsigned crossing_count = 0; for (unsigned i = 0; i < NumberOfEdges(); ++i) { const FloatPoint& vertex1 = EdgeAt(i).Vertex1(); @@ -191,6 +192,8 @@ bool FloatPolygon::ContainsEvenOdd(const FloatPoint& point) const { } bool FloatPolygon::ContainsNonZero(const FloatPoint& point) const { + if (!bounding_box_.Contains(point)) + return false; int winding_number = 0; for (unsigned i = 0; i < NumberOfEdges(); ++i) { const FloatPoint& vertex1 = EdgeAt(i).Vertex1(); @@ -208,13 +211,6 @@ bool FloatPolygon::ContainsNonZero(const FloatPoint& point) const { return winding_number; } -bool FloatPolygon::Contains(const FloatPoint& point) const { - if (!bounding_box_.Contains(point)) - return false; - return (FillRule() == RULE_NONZERO) ? ContainsNonZero(point) - : ContainsEvenOdd(point); -} - bool VertexPair::Intersection(const VertexPair& other, FloatPoint& point) const { // See: http://paulbourke.net/geometry/pointlineplane/, diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_polygon.h b/chromium/third_party/blink/renderer/platform/geometry/float_polygon.h index 4ee37987c2c..d478d96d830 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_polygon.h +++ b/chromium/third_party/blink/renderer/platform/geometry/float_polygon.h @@ -33,7 +33,6 @@ #include <memory> #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" -#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/pod_interval_tree.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -53,16 +52,13 @@ class PLATFORM_EXPORT FloatPolygon { WTF_MAKE_NONCOPYABLE(FloatPolygon); public: - FloatPolygon(std::unique_ptr<Vector<FloatPoint>> vertices, - WindRule fill_rule); + explicit FloatPolygon(std::unique_ptr<Vector<FloatPoint>> vertices); const FloatPoint& VertexAt(unsigned index) const { return (*vertices_)[index]; } unsigned NumberOfVertices() const { return vertices_->size(); } - WindRule FillRule() const { return fill_rule_; } - const FloatPolygonEdge& EdgeAt(unsigned index) const { return edges_[index]; } unsigned NumberOfEdges() const { return edges_.size(); } @@ -70,18 +66,15 @@ class PLATFORM_EXPORT FloatPolygon { bool OverlappingEdges(float min_y, float max_y, Vector<const FloatPolygonEdge*>& result) const; - bool Contains(const FloatPoint&) const; + bool ContainsNonZero(const FloatPoint&) const; + bool ContainsEvenOdd(const FloatPoint&) const; bool IsEmpty() const { return empty_; } private: typedef PODInterval<float, FloatPolygonEdge*> EdgeInterval; typedef PODIntervalTree<float, FloatPolygonEdge*> EdgeIntervalTree; - bool ContainsNonZero(const FloatPoint&) const; - bool ContainsEvenOdd(const FloatPoint&) const; - std::unique_ptr<Vector<FloatPoint>> vertices_; - WindRule fill_rule_; FloatRect bounding_box_; bool empty_; Vector<FloatPolygonEdge> edges_; diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_polygon_test.cc b/chromium/third_party/blink/renderer/platform/geometry/float_polygon_test.cc index 49b8fde7db7..c15f0c997e5 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_polygon_test.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_polygon_test.cc @@ -39,15 +39,13 @@ namespace blink { class FloatPolygonTestValue { public: - FloatPolygonTestValue(const float* coordinates, - unsigned coordinates_length, - WindRule fill_rule) { + FloatPolygonTestValue(const float* coordinates, unsigned coordinates_length) { DCHECK(!(coordinates_length % 2)); std::unique_ptr<Vector<FloatPoint>> vertices = std::make_unique<Vector<FloatPoint>>(coordinates_length / 2); for (unsigned i = 0; i < coordinates_length; i += 2) (*vertices)[i / 2] = FloatPoint(coordinates[i], coordinates[i + 1]); - polygon_ = std::make_unique<FloatPolygon>(std::move(vertices), fill_rule); + polygon_ = std::make_unique<FloatPolygon>(std::move(vertices)); } const FloatPolygon& Polygon() const { return *polygon_; } @@ -88,11 +86,10 @@ SortedOverlappingEdges(const FloatPolygon& polygon, float min_y, float max_y) { */ TEST(FloatPolygonTest, basics) { const float kTriangleCoordinates[] = {200, 100, 200, 200, 100, 200}; - FloatPolygonTestValue triangle_test_value( - kTriangleCoordinates, SIZEOF_ARRAY(kTriangleCoordinates), RULE_NONZERO); + FloatPolygonTestValue triangle_test_value(kTriangleCoordinates, + SIZEOF_ARRAY(kTriangleCoordinates)); const FloatPolygon& triangle = triangle_test_value.Polygon(); - EXPECT_EQ(RULE_NONZERO, triangle.FillRule()); EXPECT_FALSE(triangle.IsEmpty()); EXPECT_EQ(3u, triangle.NumberOfVertices()); @@ -178,7 +175,7 @@ TEST(FloatPolygonTest, basics) { } /** - * Tests FloatPolygon::contains() with a right triangle, and fillRule = nonzero. + * Tests ContainsNonZero and ContainsEvenOdd with a right triangle. * * 200,100 * /| @@ -189,54 +186,35 @@ TEST(FloatPolygonTest, basics) { */ TEST(FloatPolygonTest, triangle_nonzero) { const float kTriangleCoordinates[] = {200, 100, 200, 200, 100, 200}; - FloatPolygonTestValue triangle_test_value( - kTriangleCoordinates, SIZEOF_ARRAY(kTriangleCoordinates), RULE_NONZERO); + FloatPolygonTestValue triangle_test_value(kTriangleCoordinates, + SIZEOF_ARRAY(kTriangleCoordinates)); const FloatPolygon& triangle = triangle_test_value.Polygon(); - EXPECT_EQ(RULE_NONZERO, triangle.FillRule()); - EXPECT_TRUE(triangle.Contains(FloatPoint(200, 100))); - EXPECT_TRUE(triangle.Contains(FloatPoint(200, 200))); - EXPECT_TRUE(triangle.Contains(FloatPoint(100, 200))); - EXPECT_TRUE(triangle.Contains(FloatPoint(150, 150))); - EXPECT_FALSE(triangle.Contains(FloatPoint(100, 100))); - EXPECT_FALSE(triangle.Contains(FloatPoint(149, 149))); - EXPECT_FALSE(triangle.Contains(FloatPoint(150, 200.5))); - EXPECT_FALSE(triangle.Contains(FloatPoint(201, 200.5))); + EXPECT_TRUE(triangle.ContainsNonZero(FloatPoint(200, 100))); + EXPECT_TRUE(triangle.ContainsNonZero(FloatPoint(200, 200))); + EXPECT_TRUE(triangle.ContainsNonZero(FloatPoint(100, 200))); + EXPECT_TRUE(triangle.ContainsNonZero(FloatPoint(150, 150))); + EXPECT_FALSE(triangle.ContainsNonZero(FloatPoint(100, 100))); + EXPECT_FALSE(triangle.ContainsNonZero(FloatPoint(149, 149))); + EXPECT_FALSE(triangle.ContainsNonZero(FloatPoint(150, 200.5))); + EXPECT_FALSE(triangle.ContainsNonZero(FloatPoint(201, 200.5))); + + EXPECT_TRUE(triangle.ContainsEvenOdd(FloatPoint(200, 100))); + EXPECT_TRUE(triangle.ContainsEvenOdd(FloatPoint(200, 200))); + EXPECT_TRUE(triangle.ContainsEvenOdd(FloatPoint(100, 200))); + EXPECT_TRUE(triangle.ContainsEvenOdd(FloatPoint(150, 150))); + EXPECT_FALSE(triangle.ContainsEvenOdd(FloatPoint(100, 100))); + EXPECT_FALSE(triangle.ContainsEvenOdd(FloatPoint(149, 149))); + EXPECT_FALSE(triangle.ContainsEvenOdd(FloatPoint(150, 200.5))); + EXPECT_FALSE(triangle.ContainsEvenOdd(FloatPoint(201, 200.5))); } -/** - * Tests FloatPolygon::contains() with a right triangle, and fillRule = evenodd; - * - * 200,100 - * /| - * / | - * / | - * ----- - * 100,200 200,200 - */ -TEST(FloatPolygonTest, triangle_evenodd) { - const float kTriangleCoordinates[] = {200, 100, 200, 200, 100, 200}; - FloatPolygonTestValue triangle_test_value( - kTriangleCoordinates, SIZEOF_ARRAY(kTriangleCoordinates), RULE_EVENODD); - const FloatPolygon& triangle = triangle_test_value.Polygon(); - - EXPECT_EQ(RULE_EVENODD, triangle.FillRule()); - EXPECT_TRUE(triangle.Contains(FloatPoint(200, 100))); - EXPECT_TRUE(triangle.Contains(FloatPoint(200, 200))); - EXPECT_TRUE(triangle.Contains(FloatPoint(100, 200))); - EXPECT_TRUE(triangle.Contains(FloatPoint(150, 150))); - EXPECT_FALSE(triangle.Contains(FloatPoint(100, 100))); - EXPECT_FALSE(triangle.Contains(FloatPoint(149, 149))); - EXPECT_FALSE(triangle.Contains(FloatPoint(150, 200.5))); - EXPECT_FALSE(triangle.Contains(FloatPoint(201, 200.5))); -} - -#define TEST_EMPTY(coordinates) \ - { \ - FloatPolygonTestValue empty_polygon_test_value( \ - coordinates, SIZEOF_ARRAY(coordinates), RULE_NONZERO); \ - const FloatPolygon& empty_polygon = empty_polygon_test_value.Polygon(); \ - EXPECT_TRUE(empty_polygon.IsEmpty()); \ +#define TEST_EMPTY(coordinates) \ + { \ + FloatPolygonTestValue empty_polygon_test_value(coordinates, \ + SIZEOF_ARRAY(coordinates)); \ + const FloatPolygon& empty_polygon = empty_polygon_test_value.Polygon(); \ + EXPECT_TRUE(empty_polygon.IsEmpty()); \ } TEST(FloatPolygonTest, emptyPolygons) { @@ -260,8 +238,8 @@ TEST(FloatPolygonTest, emptyPolygons) { } /* - * Test FloatPolygon::contains() with a trapezoid. The vertices are listed in - * counter-clockwise order. + * Test FloatPolygon::ContainsEvenOdd() with a trapezoid. The vertices are + * listed in counter-clockwise order. * * 150,100 250,100 * +----------+ @@ -274,23 +252,23 @@ TEST(FloatPolygonTest, trapezoid) { const float kTrapezoidCoordinates[] = {100, 150, 300, 150, 250, 100, 150, 100}; FloatPolygonTestValue trapezoid_test_value( - kTrapezoidCoordinates, SIZEOF_ARRAY(kTrapezoidCoordinates), RULE_EVENODD); + kTrapezoidCoordinates, SIZEOF_ARRAY(kTrapezoidCoordinates)); const FloatPolygon& trapezoid = trapezoid_test_value.Polygon(); EXPECT_FALSE(trapezoid.IsEmpty()); EXPECT_EQ(4u, trapezoid.NumberOfVertices()); EXPECT_EQ(FloatRect(100, 100, 200, 50), trapezoid.BoundingBox()); - EXPECT_TRUE(trapezoid.Contains(FloatPoint(150, 100))); - EXPECT_TRUE(trapezoid.Contains(FloatPoint(150, 101))); - EXPECT_TRUE(trapezoid.Contains(FloatPoint(200, 125))); - EXPECT_FALSE(trapezoid.Contains(FloatPoint(149, 100))); - EXPECT_FALSE(trapezoid.Contains(FloatPoint(301, 150))); + EXPECT_TRUE(trapezoid.ContainsEvenOdd(FloatPoint(150, 100))); + EXPECT_TRUE(trapezoid.ContainsEvenOdd(FloatPoint(150, 101))); + EXPECT_TRUE(trapezoid.ContainsEvenOdd(FloatPoint(200, 125))); + EXPECT_FALSE(trapezoid.ContainsEvenOdd(FloatPoint(149, 100))); + EXPECT_FALSE(trapezoid.ContainsEvenOdd(FloatPoint(301, 150))); } /* - * Test FloatPolygon::contains() with a non-convex rectilinear polygon. The - * polygon has the same shape as the letter "H": + * Test FloatPolygon::ContainsNonZero() with a non-convex rectilinear polygon. + * The polygon has the same shape as the letter "H": * * 100,100 150,100 200,100 250,100 * +--------+ +--------+ @@ -310,33 +288,33 @@ TEST(FloatPolygonTest, rectilinear) { const float kHCoordinates[] = {100, 100, 150, 100, 150, 150, 200, 150, 200, 100, 250, 100, 250, 250, 200, 250, 200, 200, 150, 200, 150, 250, 100, 250}; - FloatPolygonTestValue h_test_value(kHCoordinates, SIZEOF_ARRAY(kHCoordinates), - RULE_NONZERO); + FloatPolygonTestValue h_test_value(kHCoordinates, + SIZEOF_ARRAY(kHCoordinates)); const FloatPolygon& h = h_test_value.Polygon(); EXPECT_FALSE(h.IsEmpty()); EXPECT_EQ(12u, h.NumberOfVertices()); EXPECT_EQ(FloatRect(100, 100, 150, 150), h.BoundingBox()); - EXPECT_TRUE(h.Contains(FloatPoint(100, 100))); - EXPECT_TRUE(h.Contains(FloatPoint(125, 100))); - EXPECT_TRUE(h.Contains(FloatPoint(125, 125))); - EXPECT_TRUE(h.Contains(FloatPoint(150, 100))); - EXPECT_TRUE(h.Contains(FloatPoint(200, 200))); - EXPECT_TRUE(h.Contains(FloatPoint(225, 225))); - EXPECT_TRUE(h.Contains(FloatPoint(250, 250))); - EXPECT_TRUE(h.Contains(FloatPoint(100, 250))); - EXPECT_TRUE(h.Contains(FloatPoint(125, 250))); - - EXPECT_FALSE(h.Contains(FloatPoint(99, 100))); - EXPECT_FALSE(h.Contains(FloatPoint(251, 100))); - EXPECT_FALSE(h.Contains(FloatPoint(151, 100))); - EXPECT_FALSE(h.Contains(FloatPoint(199, 100))); - EXPECT_FALSE(h.Contains(FloatPoint(175, 125))); - EXPECT_FALSE(h.Contains(FloatPoint(151, 250))); - EXPECT_FALSE(h.Contains(FloatPoint(199, 250))); - EXPECT_FALSE(h.Contains(FloatPoint(199, 250))); - EXPECT_FALSE(h.Contains(FloatPoint(175, 225))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(100, 100))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(125, 100))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(125, 125))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(150, 100))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(200, 200))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(225, 225))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(250, 250))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(100, 250))); + EXPECT_TRUE(h.ContainsNonZero(FloatPoint(125, 250))); + + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(99, 100))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(251, 100))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(151, 100))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(199, 100))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(175, 125))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(151, 250))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(199, 250))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(199, 250))); + EXPECT_FALSE(h.ContainsNonZero(FloatPoint(175, 225))); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc b/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc index b5c2e4d9535..34741d1b592 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect.cc @@ -29,6 +29,7 @@ #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/skia/include/core/SkRect.h" #include "ui/gfx/geometry/rect_f.h" @@ -145,6 +146,26 @@ void FloatRect::Intersect(const FloatRect& other) { SetLocationAndSizeFromEdges(left, top, right, bottom); } +bool FloatRect::InclusiveIntersect(const FloatRect& other) { + float left = std::max(X(), other.X()); + float top = std::max(Y(), other.Y()); + float right = std::min(MaxX(), other.MaxX()); + float bottom = std::min(MaxY(), other.MaxY()); + + // Return a clean empty rectangle for non-intersecting cases. + if (left > right || top > bottom) { + left = 0; + top = 0; + right = 0; + bottom = 0; + SetLocationAndSizeFromEdges(left, top, right, bottom); + return false; + } + + SetLocationAndSizeFromEdges(left, top, right, bottom); + return true; +} + void FloatRect::Unite(const FloatRect& other) { // Handle empty special cases first. if (other.IsEmpty()) @@ -254,4 +275,12 @@ String FloatRect::ToString() const { Size().ToString().Ascii().data()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const FloatRect& r) { + ts << "at (" << WTF::TextStream::FormatNumberRespectingIntegers(r.X()); + ts << "," << WTF::TextStream::FormatNumberRespectingIntegers(r.Y()); + ts << ") size " << WTF::TextStream::FormatNumberRespectingIntegers(r.Width()); + ts << "x" << WTF::TextStream::FormatNumberRespectingIntegers(r.Height()); + return ts; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect.h b/chromium/third_party/blink/renderer/platform/geometry/float_rect.h index f0405c2ef40..26f2628e00f 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_rect.h +++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect.h @@ -141,6 +141,14 @@ class PLATFORM_EXPORT FloatRect { bool Contains(const FloatPoint&, ContainsMode = kInsideOrOnStroke) const; void Intersect(const FloatRect&); + // Set this rect to be the intersection of itself and the argument rect + // using edge-inclusive geometry. If the two rectangles overlap but the + // overlap region is zero-area (either because one of the two rectangles + // is zero-area, or because the rectangles overlap at an edge or a corner), + // the result is the zero-area intersection. The return value indicates + // whether the two rectangle actually have an intersection, since checking + // the result for isEmpty() is not conclusive. + bool InclusiveIntersect(const FloatRect&); void Unite(const FloatRect&); void UniteEvenIfEmpty(const FloatRect&); void UniteIfNonZero(const FloatRect&); @@ -257,6 +265,7 @@ PLATFORM_EXPORT FloatRect MapRect(const FloatRect&, const FloatRect& dest_rect); PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatRect&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatRect&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_rect_test.cc b/chromium/third_party/blink/renderer/platform/geometry/float_rect_test.cc index 787d1a7d78b..982e7a989a7 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_rect_test.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_rect_test.cc @@ -257,4 +257,22 @@ TEST(FloatRectTest, EnclosedIntRect) { EnclosedIntRect(max_rect)); } +TEST(FloatRectTest, InclusiveIntersect) { + FloatRect rect(11, 12, 0, 0); + EXPECT_TRUE(rect.InclusiveIntersect(FloatRect(11, 12, 13, 14))); + EXPECT_EQ(EnclosingIntRect(rect), IntRect(11, 12, 0, 0)); + + rect = FloatRect(11, 12, 13, 14); + EXPECT_TRUE(rect.InclusiveIntersect(FloatRect(24, 8, 0, 7))); + EXPECT_EQ(EnclosingIntRect(rect), IntRect(24, 12, 0, 3)); + + rect = FloatRect(11, 12, 13, 14); + EXPECT_TRUE(rect.InclusiveIntersect(FloatRect(9, 15, 4, 0))); + EXPECT_EQ(EnclosingIntRect(rect), IntRect(11, 15, 2, 0)); + + rect = FloatRect(11, 12, 0, 14); + EXPECT_FALSE(rect.InclusiveIntersect(FloatRect(12, 13, 15, 16))); + EXPECT_EQ(EnclosingIntRect(rect), IntRect()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_size.cc b/chromium/third_party/blink/renderer/platform/geometry/float_size.cc index 10fd7eeaacd..6fd6c331361 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_size.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/float_size.cc @@ -31,8 +31,11 @@ #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/geometry/layout_size.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/skia/include/core/SkSize.h" +#include "ui/gfx/geometry/size_f.h" +#include "ui/gfx/geometry/vector2d_f.h" namespace blink { @@ -58,6 +61,14 @@ FloatSize::operator SkSize() const { return SkSize::Make(width_, height_); } +FloatSize::operator gfx::SizeF() const { + return gfx::SizeF(width_, height_); +} + +FloatSize::operator gfx::Vector2dF() const { + return gfx::Vector2dF(width_, height_); +} + std::ostream& operator<<(std::ostream& ostream, const FloatSize& size) { return ostream << size.ToString(); } @@ -66,4 +77,11 @@ String FloatSize::ToString() const { return String::Format("%lgx%lg", Width(), Height()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const FloatSize& s) { + ts << "width=" << WTF::TextStream::FormatNumberRespectingIntegers(s.Width()); + ts << " height=" + << WTF::TextStream::FormatNumberRespectingIntegers(s.Height()); + return ts; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/float_size.h b/chromium/third_party/blink/renderer/platform/geometry/float_size.h index 0f1403c58ec..faf4827472b 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/float_size.h +++ b/chromium/third_party/blink/renderer/platform/geometry/float_size.h @@ -45,6 +45,11 @@ typedef struct CGSize CGSize; struct SkSize; +namespace gfx { +class SizeF; +class Vector2dF; +} // namespace gfx + namespace blink { class IntSize; @@ -129,6 +134,12 @@ class PLATFORM_EXPORT FloatSize { #endif operator SkSize() const; + // Use this only for logical sizes, which can not be negative. Things that are + // offsets instead, and can be negative, should use a gfx::Vector2dF. + explicit operator gfx::SizeF() const; + // FloatSize is used as an offset, which can be negative, but gfx::SizeF can + // not. The Vector2dF type is used for offsets instead. + explicit operator gfx::Vector2dF() const; String ToString() const; @@ -197,6 +208,7 @@ inline IntPoint FlooredIntPoint(const FloatSize& p) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const FloatSize&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FloatSize&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.cc b/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.cc deleted file mode 100644 index a48ec97a386..00000000000 --- a/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.cc +++ /dev/null @@ -1,52 +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/geometry/geometry_as_json.h" - -#include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" - -namespace blink { - -static double RoundCloseToZero(double number) { - return std::abs(number) < 1e-7 ? 0 : number; -} - -std::unique_ptr<JSONArray> TransformAsJSONArray(const TransformationMatrix& t) { - std::unique_ptr<JSONArray> array = JSONArray::Create(); - { - std::unique_ptr<JSONArray> row = JSONArray::Create(); - row->PushDouble(RoundCloseToZero(t.M11())); - row->PushDouble(RoundCloseToZero(t.M12())); - row->PushDouble(RoundCloseToZero(t.M13())); - row->PushDouble(RoundCloseToZero(t.M14())); - array->PushArray(std::move(row)); - } - { - std::unique_ptr<JSONArray> row = JSONArray::Create(); - row->PushDouble(RoundCloseToZero(t.M21())); - row->PushDouble(RoundCloseToZero(t.M22())); - row->PushDouble(RoundCloseToZero(t.M23())); - row->PushDouble(RoundCloseToZero(t.M24())); - array->PushArray(std::move(row)); - } - { - std::unique_ptr<JSONArray> row = JSONArray::Create(); - row->PushDouble(RoundCloseToZero(t.M31())); - row->PushDouble(RoundCloseToZero(t.M32())); - row->PushDouble(RoundCloseToZero(t.M33())); - row->PushDouble(RoundCloseToZero(t.M34())); - array->PushArray(std::move(row)); - } - { - std::unique_ptr<JSONArray> row = JSONArray::Create(); - row->PushDouble(RoundCloseToZero(t.M41())); - row->PushDouble(RoundCloseToZero(t.M42())); - row->PushDouble(RoundCloseToZero(t.M43())); - row->PushDouble(RoundCloseToZero(t.M44())); - array->PushArray(std::move(row)); - } - return array; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.h b/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.h index 1437b20bb6c..96aee5f98dd 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.h +++ b/chromium/third_party/blink/renderer/platform/geometry/geometry_as_json.h @@ -10,8 +10,6 @@ namespace blink { -class TransformationMatrix; - template <typename T> static std::unique_ptr<JSONArray> RectAsJSONArray(const T& rect) { std::unique_ptr<JSONArray> array = JSONArray::Create(); @@ -38,9 +36,6 @@ std::unique_ptr<JSONArray> SizeAsJSONArray(const T& size) { return array; } -PLATFORM_EXPORT std::unique_ptr<JSONArray> TransformAsJSONArray( - const TransformationMatrix&); - } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_GEOMETRY_AS_JSON_H_ diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_point.cc b/chromium/third_party/blink/renderer/platform/geometry/int_point.cc index 2bfd9fd9cdb..5efff72f178 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_point.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/int_point.cc @@ -4,7 +4,9 @@ #include "third_party/blink/renderer/platform/geometry/int_point.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/geometry/point.h" namespace blink { @@ -12,8 +14,16 @@ std::ostream& operator<<(std::ostream& ostream, const IntPoint& point) { return ostream << point.ToString(); } +IntPoint::operator gfx::Point() const { + return gfx::Point(X(), Y()); +} + String IntPoint::ToString() const { return String::Format("%d,%d", X(), Y()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const IntPoint& p) { + return ts << "(" << p.X() << "," << p.Y() << ")"; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_point.h b/chromium/third_party/blink/renderer/platform/geometry/int_point.h index 6e0072ecd50..14ca3909828 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_point.h +++ b/chromium/third_party/blink/renderer/platform/geometry/int_point.h @@ -43,6 +43,10 @@ typedef struct CGPoint CGPoint; #endif #endif +namespace gfx { +class Point; +} + namespace blink { class PLATFORM_EXPORT IntPoint { @@ -100,6 +104,8 @@ class PLATFORM_EXPORT IntPoint { operator CGPoint() const; #endif + operator gfx::Point() const; + String ToString() const; private: @@ -153,6 +159,7 @@ inline int IntPoint::DistanceSquaredToPoint(const IntPoint& point) const { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const IntPoint&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const IntPoint&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_rect.cc b/chromium/third_party/blink/renderer/platform/geometry/int_rect.cc index 5aeedea84df..cf792014c06 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_rect.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/int_rect.cc @@ -28,6 +28,7 @@ #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/wtf/checked_numeric.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/skia/include/core/SkRect.h" @@ -37,6 +38,9 @@ namespace blink { +IntRect::IntRect(const gfx::Rect& rect) + : location_(rect.x(), rect.y()), size_(rect.width(), rect.height()) {} + void IntRect::ShiftXEdgeTo(int edge) { int delta = edge - X(); SetX(edge); @@ -204,4 +208,9 @@ bool IntRect::IsValid() const { return max.IsValid(); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const IntRect& r) { + return ts << "at (" << r.X() << "," << r.Y() << ") size " << r.Width() << "x" + << r.Height(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_rect.h b/chromium/third_party/blink/renderer/platform/geometry/int_rect.h index a1909aa4a41..e9d86bf8714 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_rect.h +++ b/chromium/third_party/blink/renderer/platform/geometry/int_rect.h @@ -32,6 +32,7 @@ #include "third_party/blink/renderer/platform/geometry/int_rect_outsets.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/blink/renderer/platform/wtf/saturated_arithmetic.h" #if defined(OS_MACOSX) typedef struct CGRect CGRect; @@ -68,6 +69,8 @@ class PLATFORM_EXPORT IntRect { explicit IntRect(const FloatRect&) = delete; explicit IntRect(const LayoutRect&) = delete; + explicit IntRect(const gfx::Rect& rect); + IntPoint Location() const { return location_; } IntSize Size() const { return size_; } @@ -215,6 +218,11 @@ inline IntRect UnionRectEvenIfEmpty(const IntRect& a, const IntRect& b) { PLATFORM_EXPORT IntRect UnionRectEvenIfEmpty(const Vector<IntRect>&); +inline IntRect SaturatedRect(const IntRect& r) { + return IntRect(r.X(), r.Y(), ClampAdd(r.X(), r.Width()) - r.X(), + ClampAdd(r.Y(), r.Height()) - r.Y()); +} + inline bool operator==(const IntRect& a, const IntRect& b) { return a.Location() == b.Location() && a.Size() == b.Size(); } @@ -224,6 +232,7 @@ inline bool operator!=(const IntRect& a, const IntRect& b) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const IntRect&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const IntRect&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_size.cc b/chromium/third_party/blink/renderer/platform/geometry/int_size.cc index c9d57090496..42c21fb896a 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_size.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/int_size.cc @@ -6,13 +6,21 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/vector2d.h" namespace blink { +IntSize::IntSize(const gfx::Size& size) + : IntSize(size.width(), size.height()) {} + IntSize::operator gfx::Size() const { return gfx::Size(Width(), Height()); } +IntSize::operator gfx::Vector2d() const { + return gfx::Vector2d(Width(), Height()); +} + std::ostream& operator<<(std::ostream& ostream, const IntSize& size) { return ostream << size.ToString(); } diff --git a/chromium/third_party/blink/renderer/platform/geometry/int_size.h b/chromium/third_party/blink/renderer/platform/geometry/int_size.h index d1eb7ed159f..ca7913e5d60 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/int_size.h +++ b/chromium/third_party/blink/renderer/platform/geometry/int_size.h @@ -44,6 +44,7 @@ typedef struct CGSize CGSize; namespace gfx { class Size; +class Vector2d; } namespace blink { @@ -54,6 +55,7 @@ class PLATFORM_EXPORT IntSize { public: IntSize() : width_(0), height_(0) {} IntSize(int width, int height) : width_(width), height_(height) {} + explicit IntSize(const gfx::Size&); int Width() const { return width_; } int Height() const { return height_; } @@ -113,7 +115,12 @@ class PLATFORM_EXPORT IntSize { explicit operator CGSize() const; #endif - operator gfx::Size() const; + // Use this only for logical sizes, which can not be negative. Things that are + // offsets instead, and can be negative, should use a gfx::Vector2d. + explicit operator gfx::Size() const; + // IntSize is used as an offset, which can be negative, but gfx::Size can not. + // The Vector2d type is used for offsets instead. + explicit operator gfx::Vector2d() const; String ToString() const; diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_point.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_point.cc index 5ef657bacaa..8ead868ffcf 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_point.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_point.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/geometry/layout_point.h" #include <algorithm> +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -26,4 +27,8 @@ String LayoutPoint::ToString() const { Y().ToString().Ascii().data()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const LayoutPoint& point) { + return ts << FloatPoint(point); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_point.h b/chromium/third_party/blink/renderer/platform/geometry/layout_point.h index 2d16732abde..10726fb782c 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_point.h +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_point.h @@ -212,6 +212,8 @@ inline LayoutPoint FlooredLayoutPoint(const FloatSize& s) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const LayoutPoint&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, + const LayoutPoint&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.cc index 19af6e9b8dd..5f953944790 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.cc @@ -35,6 +35,7 @@ #include "third_party/blink/renderer/platform/geometry/double_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/layout_unit.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -174,4 +175,8 @@ String LayoutRect::ToString() const { Size().ToString().Ascii().data()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const LayoutRect& rect) { + return ts << FloatRect(rect); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h index 0c4022695a4..e05e54d40df 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect.h @@ -327,6 +327,8 @@ inline IntRect PixelSnappedIntRect(LayoutPoint location, LayoutSize size) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const LayoutRect&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, + const LayoutRect&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.cc index ceca3822dcc..2a4a35e7f34 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.cc @@ -49,19 +49,4 @@ void LayoutRectOutsets::Unite(const LayoutRectOutsets& other) { left_ = std::max(left_, other.left_); } -LayoutRectOutsets LayoutRectOutsets::LineOrientationOutsets( - WritingMode writing_mode) const { - if (!IsHorizontalWritingMode(writing_mode)) - return LayoutRectOutsets(left_, bottom_, right_, top_); - return *this; -} - -LayoutRectOutsets LayoutRectOutsets::LineOrientationOutsetsWithFlippedLines( - WritingMode writing_mode) const { - LayoutRectOutsets outsets = LineOrientationOutsets(writing_mode); - if (IsFlippedLinesWritingMode(writing_mode)) - std::swap(outsets.top_, outsets.bottom_); - return outsets; -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h index c8e75106300..e25a64b84b6 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets.h @@ -33,9 +33,9 @@ #include "third_party/blink/renderer/platform/geometry/float_rect_outsets.h" #include "third_party/blink/renderer/platform/geometry/int_rect_outsets.h" +#include "third_party/blink/renderer/platform/geometry/layout_size.h" #include "third_party/blink/renderer/platform/layout_unit.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/text/writing_mode.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" namespace blink { @@ -83,6 +83,7 @@ class PLATFORM_EXPORT LayoutRectOutsets { void SetBottom(LayoutUnit value) { bottom_ = value; } void SetLeft(LayoutUnit value) { left_ = value; } + LayoutSize Size() const { return LayoutSize(left_ + right_, top_ + bottom_); } bool IsZero() const { return !top_ && !right_ && !bottom_ && !left_; } void ClampNegativeToZero(); @@ -91,17 +92,6 @@ class PLATFORM_EXPORT LayoutRectOutsets { void FlipHorizontally() { std::swap(left_, right_); } - // Produces a new LayoutRectOutsets in line orientation - // (https://www.w3.org/TR/css-writing-modes-3/#line-orientation), whose - // - |top| is the logical 'over', - // - |right| is the logical 'line right', - // - |bottom| is the logical 'under', - // - |left| is the logical 'line left'. - LayoutRectOutsets LineOrientationOutsets(WritingMode) const; - - // The same as |logicalOutsets|, but also adjusting for flipped lines. - LayoutRectOutsets LineOrientationOutsetsWithFlippedLines(WritingMode) const; - bool operator==(const LayoutRectOutsets other) const { return Top() == other.Top() && Right() == other.Right() && Bottom() == other.Bottom() && Left() == other.Left(); diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets_test.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets_test.cc deleted file mode 100644 index 1c4e54c979e..00000000000 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_rect_outsets_test.cc +++ /dev/null @@ -1,40 +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/geometry/layout_rect_outsets.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace blink { -namespace { - -TEST(LayoutRectOutsetsTest, LineOrientationOutsets_Horizontal) { - LayoutRectOutsets outsets(1, 2, 3, 4); - EXPECT_EQ(LayoutRectOutsets(1, 2, 3, 4), - outsets.LineOrientationOutsets(WritingMode::kHorizontalTb)); -} - -TEST(LayoutRectOutsetsTest, LineOrientationOutsets_Vertical) { - LayoutRectOutsets outsets(1, 2, 3, 4); - EXPECT_EQ(LayoutRectOutsets(4, 3, 2, 1), - outsets.LineOrientationOutsets(WritingMode::kVerticalLr)); - EXPECT_EQ(LayoutRectOutsets(4, 3, 2, 1), - outsets.LineOrientationOutsets(WritingMode::kVerticalRl)); -} - -TEST(LayoutRectOutsetsTest, LineOrientationOutsetsWithFlippedLines) { - LayoutRectOutsets outsets(1, 2, 3, 4); - EXPECT_EQ(LayoutRectOutsets(1, 2, 3, 4), - outsets.LineOrientationOutsetsWithFlippedLines( - WritingMode::kHorizontalTb)); - EXPECT_EQ( - LayoutRectOutsets(2, 3, 4, 1), - outsets.LineOrientationOutsetsWithFlippedLines(WritingMode::kVerticalLr)); - EXPECT_EQ( - LayoutRectOutsets(4, 3, 2, 1), - outsets.LineOrientationOutsetsWithFlippedLines(WritingMode::kVerticalRl)); -} - -} // namespace -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_size.cc b/chromium/third_party/blink/renderer/platform/geometry/layout_size.cc index 23d797a7b2c..5c7c9851067 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_size.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_size.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/geometry/layout_size.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -17,4 +18,8 @@ String LayoutSize::ToString() const { Height().ToString().Ascii().data()); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const LayoutSize& size) { + return ts << FloatSize(size); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/layout_size.h b/chromium/third_party/blink/renderer/platform/geometry/layout_size.h index 8da95a7027f..280ee87ccf3 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/layout_size.h +++ b/chromium/third_party/blink/renderer/platform/geometry/layout_size.h @@ -190,6 +190,10 @@ inline LayoutSize operator-(const LayoutSize& size) { return LayoutSize(-size.Width(), -size.Height()); } +inline LayoutSize operator*(const LayoutSize& a, const float scale) { + return LayoutSize(a.Width() * scale, a.Height() * scale); +} + inline bool operator==(const LayoutSize& a, const LayoutSize& b) { return a.Width() == b.Width() && a.Height() == b.Height(); } @@ -202,6 +206,10 @@ inline bool operator!=(const LayoutSize& a, const LayoutSize& b) { return a.Width() != b.Width() || a.Height() != b.Height(); } +inline bool operator!=(const LayoutSize& a, const IntSize& b) { + return a.Width() != b.Width() || a.Height() != b.Height(); +} + inline FloatPoint operator+(const FloatPoint& a, const LayoutSize& b) { return FloatPoint(a.X() + b.Width(), a.Y() + b.Height()); } @@ -219,6 +227,8 @@ inline LayoutSize RoundedLayoutSize(const FloatSize& s) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const LayoutSize&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, + const LayoutSize&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/geometry/region.cc b/chromium/third_party/blink/renderer/platform/geometry/region.cc index 14db9d1b994..153f0df56d2 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/region.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/region.cc @@ -27,12 +27,6 @@ #include <stdio.h> -// A region class based on the paper "Scanline Coherent Shape Algebra" -// by Jonathan E. Steinhart from the book "Graphics Gems II". -// -// This implementation uses two vectors instead of linked list, and -// also compresses regions when possible. - namespace blink { Region::Region() = default; @@ -106,6 +100,22 @@ bool Region::Intersects(const Region& region) const { region.shape_); } +double Region::Area() const { + double area = 0.0; + for (Shape::SpanIterator span = shape_.SpansBegin(), end = shape_.SpansEnd(); + span != end && span + 1 != end; ++span) { + int height = (span + 1)->y - span->y; + + for (Shape::SegmentIterator segment = shape_.SegmentsBegin(span), + end = shape_.SegmentsEnd(span); + segment != end && segment + 1 != end; segment += 2) { + int width = *(segment + 1) - *segment; + area += height * width; + } + } + return area; +} + template <typename CompareOperation> bool Region::Shape::CompareShapes(const Shape& a_shape, const Shape& b_shape) { bool result = CompareOperation::kDefaultResult; diff --git a/chromium/third_party/blink/renderer/platform/geometry/region.h b/chromium/third_party/blink/renderer/platform/geometry/region.h index e27ff5be910..9b38631efd8 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/region.h +++ b/chromium/third_party/blink/renderer/platform/geometry/region.h @@ -26,13 +26,24 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_REGION_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_REGION_H_ +#include "cc/base/region.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +namespace cc { +class Region; +} + namespace blink { +// A region class based on the paper "Scanline Coherent Shape Algebra" +// by Jonathan E. Steinhart from the book "Graphics Gems II". +// +// This implementation uses two vectors instead of linked list, and +// also compresses regions when possible. + class PLATFORM_EXPORT Region { DISALLOW_NEW(); @@ -60,6 +71,8 @@ class PLATFORM_EXPORT Region { // Returns true if the query region intersects any part of this region. bool Intersects(const Region&) const; + double Area() const; + #ifndef NDEBUG void Dump() const; #endif @@ -73,6 +86,13 @@ class PLATFORM_EXPORT Region { size_t segment_index; }; + // Shape composed of non-overlapping rectangles implied by segments [x, max_x) + // within spans [y, max_y). + // + // Segment iteration returns x and max_x for each segment in a span, in order. + // Span iteration returns y via the Span object; spans are adjacent, so max_y + // is the next Span's y value. (The last Span contains no segments.) + class Shape { DISALLOW_NEW(); @@ -128,7 +148,10 @@ class PLATFORM_EXPORT Region { bool CanCoalesce(SegmentIterator begin, SegmentIterator end); + // Stores all segments for all spans, in order. Each Span's segment_index + // identifies the start of its segments within this vector. Vector<int, 32> segments_; + Vector<Span, 16> spans_; friend bool operator==(const Shape&, const Shape&); @@ -163,6 +186,15 @@ static inline Region Translate(const Region& region, const IntSize& offset) { return result; } +// Creates a cc::Region with the same data as |region|. +static inline cc::Region RegionToCCRegion(const Region& in_region) { + Vector<IntRect> rects = in_region.Rects(); + cc::Region out_region; + for (const IntRect& r : rects) + out_region.Union(gfx::Rect(r.X(), r.Y(), r.Width(), r.Height())); + return out_region; +} + inline bool operator==(const Region& a, const Region& b) { return a.bounds_ == b.bounds_ && a.shape_ == b.shape_; } diff --git a/chromium/third_party/blink/renderer/platform/geometry/region_test.cc b/chromium/third_party/blink/renderer/platform/geometry/region_test.cc index 2510b9d5e5a..2b207d52327 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/region_test.cc +++ b/chromium/third_party/blink/renderer/platform/geometry/region_test.cc @@ -381,4 +381,21 @@ TEST(RegionTest, unite) { EXPECT_EQ(Region(IntRect(0, 0, 500, 500)), r); } +TEST(RegionTest, Area) { + Region r; + EXPECT_EQ(0.0, r.Area()); + + r.Unite(IntRect(10, 20, 30, 10)); + EXPECT_EQ(300.0, r.Area()); + + r.Unite(IntRect(20, 10, 10, 30)); + EXPECT_EQ(500.0, r.Area()); + + r.Unite(IntRect(10, 10, 30, 30)); + EXPECT_EQ(900.0, r.Area()); + + r.Subtract(IntRect(20, 20, 10, 10)); + EXPECT_EQ(800.0, r.Area()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/DEPS b/chromium/third_party/blink/renderer/platform/graphics/DEPS index 865fc0fdd3a..9ab46b30e19 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/DEPS +++ b/chromium/third_party/blink/renderer/platform/graphics/DEPS @@ -1,18 +1,24 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/geometry", + + # Dependencies. "+base/bind.h", "+base/callback.h", "+base/compiler_specific.h", "+base/message_loop", + "+base/task_runner.h", "+base/task_runner_util.h", "+base/threading/sequenced_task_runner_handle.h", "+base/threading/thread.h", "+base/threading/thread_checker.h", "+cc", - "-cc/blink", "+components/viz/common", "+components/viz/test/fake_external_begin_frame_source.h", + "+gpu/config", "+gpu/command_buffer/client/gles2_interface.h", "+gpu/command_buffer/client/gpu_memory_buffer_manager.h", "+gpu/command_buffer/common/gpu_memory_buffer_support.h", @@ -21,8 +27,42 @@ include_rules = [ "+gpu/command_buffer/common/sync_token.h", "+media/base/media_switches.h", "+media/base/video_frame.h", + "+media/renderers/video_resource_updater.h", + "+services/ui/public/cpp/gpu/context_provider_command_buffer.h", "+services/viz/public/interfaces", + "+third_party/blink/renderer/platform/animation", + "+third_party/blink/renderer/platform/bindings/runtime_call_stats.h", + "+third_party/blink/renderer/platform/bindings", + "+third_party/blink/renderer/platform/cpu/mips/common_macros_msa.h", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/decimal.h", + "+third_party/blink/renderer/platform/drag_image.h", + "+third_party/blink/renderer/platform/fonts", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/image-decoders", + "+third_party/blink/renderer/platform/image-encoders", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/json/json_values.h", + "+third_party/blink/renderer/platform/length.h", + "+third_party/blink/renderer/platform/mojo/mojo_helper.h", + "+third_party/blink/renderer/platform/network/mime/mime_type_registry.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/scroll", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/text", + "+third_party/blink/renderer/platform/timer.h", + "+third_party/blink/renderer/platform/transforms", + "+third_party/blink/renderer/platform/waitable_event.h", + "+third_party/blink/renderer/platform/weborigin/kurl.h", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", "+third_party/blink/public/web/web_settings.h", + "+ui/gfx/geometry", ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc index 091c28f633d..ca4a16c2f59 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image_test.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "skia/ext/texture_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" diff --git a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc new file mode 100644 index 00000000000..cbc01649eab --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.cc @@ -0,0 +1,108 @@ +// 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/graphics/begin_frame_provider.h" + +#include "base/single_thread_task_runner.h" +#include "third_party/blink/public/platform/interface_provider.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/web_task_runner.h" + +namespace blink { + +BeginFrameProvider::BeginFrameProvider( + const BeginFrameProviderParams& begin_frame_provider_params, + BeginFrameProviderClient* client) + : needs_begin_frame_(false), + requested_needs_begin_frame_(false), + cfs_binding_(this), + efs_binding_(this), + frame_sink_id_(begin_frame_provider_params.frame_sink_id), + parent_frame_sink_id_(begin_frame_provider_params.parent_frame_sink_id), + begin_frame_client_(client), + weak_factory_(this) {} + +void BeginFrameProvider::ResetCompositorFrameSink() { + compositor_frame_sink_.reset(); + efs_binding_.Close(); + cfs_binding_.Close(); + if (needs_begin_frame_) { + needs_begin_frame_ = false; + RequestBeginFrame(); + } +} + +void BeginFrameProvider::OnMojoConnectionError(uint32_t custom_reason, + const std::string& description) { + if (custom_reason) { + DLOG(ERROR) << description; + } + ResetCompositorFrameSink(); +} + +void BeginFrameProvider::CreateCompositorFrameSinkIfNeeded() { + if (!parent_frame_sink_id_.is_valid() || !frame_sink_id_.is_valid()) { + return; + } + + if (compositor_frame_sink_.is_bound()) + return; + + mojom::blink::EmbeddedFrameSinkProviderPtr provider; + Platform::Current()->GetInterfaceProvider()->GetInterface( + mojo::MakeRequest(&provider)); + + scoped_refptr<base::SingleThreadTaskRunner> task_runner; + auto* scheduler = blink::Platform::Current()->CurrentThread()->Scheduler(); + if (scheduler) + task_runner = scheduler->CompositorTaskRunner(); + + mojom::blink::EmbeddedFrameSinkClientPtr efs_client; + efs_binding_.Bind(mojo::MakeRequest(&efs_client), task_runner); + + viz::mojom::blink::CompositorFrameSinkClientPtr client; + cfs_binding_.Bind(mojo::MakeRequest(&client), task_runner); + + provider->CreateSimpleCompositorFrameSink( + parent_frame_sink_id_, frame_sink_id_, std::move(efs_client), + std::move(client), mojo::MakeRequest(&compositor_frame_sink_)); + + compositor_frame_sink_.set_connection_error_with_reason_handler( + base::BindOnce(&BeginFrameProvider::OnMojoConnectionError, + weak_factory_.GetWeakPtr())); +} + +void BeginFrameProvider::RequestBeginFrame() { + requested_needs_begin_frame_ = true; + if (needs_begin_frame_) + return; + + CreateCompositorFrameSinkIfNeeded(); + + needs_begin_frame_ = true; + compositor_frame_sink_->SetNeedsBeginFrame(true); +} + +void BeginFrameProvider::OnBeginFrame(const viz::BeginFrameArgs& args) { + // If there was no need for a BeginFrame, just skip it. + if (needs_begin_frame_) { + requested_needs_begin_frame_ = false; + + begin_frame_client_->BeginFrame(); + + if (!requested_needs_begin_frame_) { + needs_begin_frame_ = false; + compositor_frame_sink_->SetNeedsBeginFrame(false); + } + } + + viz::BeginFrameAck ack; + ack.source_id = args.source_id; + ack.sequence_number = args.sequence_number; + ack.has_damage = false; + compositor_frame_sink_->DidNotProduceFrame(ack); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.h new file mode 100644 index 00000000000..6138658c20d --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/begin_frame_provider.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_GRAPHICS_BEGIN_FRAME_PROVIDER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_BEGIN_FRAME_PROVIDER_H_ + +#include "mojo/public/cpp/bindings/binding.h" +#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" +#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h" +#include "third_party/blink/renderer/platform/graphics/begin_frame_provider.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +struct PLATFORM_EXPORT BeginFrameProviderParams final { + viz::FrameSinkId parent_frame_sink_id; + viz::FrameSinkId frame_sink_id; +}; + +class PLATFORM_EXPORT BeginFrameProviderClient { + public: + virtual void BeginFrame() = 0; + virtual ~BeginFrameProviderClient() = default; +}; + +class PLATFORM_EXPORT BeginFrameProvider + : public viz::mojom::blink::CompositorFrameSinkClient, + public mojom::blink::EmbeddedFrameSinkClient { + public: + explicit BeginFrameProvider( + const BeginFrameProviderParams& begin_frame_provider_params, + BeginFrameProviderClient*); + + void CreateCompositorFrameSinkIfNeeded(); + + void RequestBeginFrame(); + + // viz::mojom::blink::CompositorFrameSinkClient implementation. + void DidReceiveCompositorFrameAck( + const WTF::Vector<viz::ReturnedResource>& resources) final { + NOTIMPLEMENTED(); + } + void DidPresentCompositorFrame(uint32_t presentation_token, + mojo_base::mojom::blink::TimeTicksPtr, + WTF::TimeDelta refresh, + uint32_t flags) final { + NOTIMPLEMENTED(); + } + void DidDiscardCompositorFrame(uint32_t presentation_token) final { + NOTIMPLEMENTED(); + } + void OnBeginFrame(const viz::BeginFrameArgs&) final; + void OnBeginFramePausedChanged(bool paused) final {} + void ReclaimResources( + const WTF::Vector<viz::ReturnedResource>& resources) final { + NOTIMPLEMENTED(); + } + + // viz::mojom::blink::EmbeddedFrameSinkClient implementation. + void OnFirstSurfaceActivation(const viz::SurfaceInfo& surface_info) final { + NOTIMPLEMENTED(); + } + + void ResetCompositorFrameSink(); + + ~BeginFrameProvider() override = default; + + private: + void OnMojoConnectionError(uint32_t custom_reason, + const std::string& description); + + bool needs_begin_frame_; + bool requested_needs_begin_frame_; + + mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> cfs_binding_; + mojo::Binding<mojom::blink::EmbeddedFrameSinkClient> efs_binding_; + viz::FrameSinkId frame_sink_id_; + viz::FrameSinkId parent_frame_sink_id_; + viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_; + BeginFrameProviderClient* begin_frame_client_; + + base::WeakPtrFactory<BeginFrameProvider> weak_factory_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_BEGIN_FRAME_PROVIDER_H_ diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc index 60bfede7bf7..edb6ebfcde3 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.cc @@ -45,7 +45,7 @@ #include "third_party/blink/renderer/platform/instrumentation/platform_instrumentation.h" #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/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -202,7 +202,7 @@ Image::SizeAvailability BitmapImage::DataChanged(bool all_data_received) { } bool BitmapImage::HasColorProfile() const { - return decoder_ && decoder_->HasEmbeddedColorSpace(); + return decoder_ && decoder_->HasEmbeddedColorProfile(); } String BitmapImage::FilenameExtension() const { diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h index 37534e485bf..76c65e58d16 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h +++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image.h @@ -30,6 +30,7 @@ #include <memory> #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/color.h" #include "third_party/blink/renderer/platform/graphics/deferred_image_decoder.h" @@ -39,7 +40,6 @@ #include "third_party/blink/renderer/platform/image-decoders/image_animation.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/forward.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/skia/include/core/SkRefCnt.h" 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 692fc31e657..e0e7a057267 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 @@ -8,6 +8,7 @@ #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/threading.h" +#include "third_party/skia/third_party/skcms/skcms.h" namespace blink { @@ -41,37 +42,28 @@ void BitmapImageMetrics::CountImageOrientation( orientation_histogram.Count(orientation); } -void BitmapImageMetrics::CountImageGammaAndGamut(SkColorSpace* color_space) { +void BitmapImageMetrics::CountImageGammaAndGamut( + const skcms_ICCProfile* color_profile) { DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gamma_named_histogram, ("Blink.ColorSpace.Source", kGammaEnd)); - gamma_named_histogram.Count(GetColorSpaceGamma(color_space)); + gamma_named_histogram.Count(GetColorSpaceGamma(color_profile)); DEFINE_THREAD_SAFE_STATIC_LOCAL( EnumerationHistogram, gamut_named_histogram, ("Blink.ColorGamut.Source", static_cast<int>(ColorSpaceGamut::kEnd))); gamut_named_histogram.Count( - static_cast<int>(ColorSpaceUtilities::GetColorSpaceGamut(color_space))); -} - -void BitmapImageMetrics::CountOutputGammaAndGamut(SkColorSpace* color_space) { - DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gamma_named_histogram, - ("Blink.ColorSpace.Destination", kGammaEnd)); - gamma_named_histogram.Count(GetColorSpaceGamma(color_space)); - - DEFINE_THREAD_SAFE_STATIC_LOCAL(EnumerationHistogram, gamut_named_histogram, - ("Blink.ColorGamut.Destination", - static_cast<int>(ColorSpaceGamut::kEnd))); - gamut_named_histogram.Count( - static_cast<int>(ColorSpaceUtilities::GetColorSpaceGamut(color_space))); + static_cast<int>(ColorSpaceUtilities::GetColorSpaceGamut(color_profile))); } BitmapImageMetrics::Gamma BitmapImageMetrics::GetColorSpaceGamma( - SkColorSpace* color_space) { + const skcms_ICCProfile* color_profile) { Gamma gamma = kGammaNull; - if (color_space) { - if (color_space->gammaCloseToSRGB()) { + if (color_profile) { + if (skcms_TRCs_AreApproximateInverse( + color_profile, skcms_sRGB_Inverse_TransferFunction())) { gamma = kGammaSRGB; - } else if (color_space->gammaIsLinear()) { + } else if (skcms_TRCs_AreApproximateInverse( + color_profile, skcms_Identity_TransferFunction())) { gamma = kGammaLinear; } else { gamma = kGammaNonStandard; diff --git a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h index fd1dfe070fd..5adc237e46f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h +++ b/chromium/third_party/blink/renderer/platform/graphics/bitmap_image_metrics.h @@ -9,7 +9,8 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" -#include "third_party/skia/include/core/SkColorSpace.h" + +struct skcms_ICCProfile; namespace blink { @@ -48,11 +49,10 @@ class PLATFORM_EXPORT BitmapImageMetrics { static void CountDecodedImageType(const String& type); static void CountImageOrientation(const ImageOrientationEnum); - static void CountImageGammaAndGamut(SkColorSpace*); - static void CountOutputGammaAndGamut(SkColorSpace*); + static void CountImageGammaAndGamut(const skcms_ICCProfile*); private: - static Gamma GetColorSpaceGamma(SkColorSpace*); + static Gamma GetColorSpaceGamma(const skcms_ICCProfile*); }; } // namespace blink 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 c7ccc1a2766..4eca0007073 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 @@ -60,7 +60,7 @@ class BitmapImageTest : public testing::Test { FakeImageObserver() : last_decoded_size_(0), last_decoded_size_changed_delta_(0) {} - virtual void DecodedSizeChangedTo(const Image*, size_t new_size) { + void DecodedSizeChangedTo(const Image*, size_t new_size) override { last_decoded_size_changed_delta_ = SafeCast<int>(new_size) - SafeCast<int>(last_decoded_size_); last_decoded_size_ = new_size; @@ -71,7 +71,7 @@ class BitmapImageTest : public testing::Test { } void AsyncLoadCompleted(const Image*) override { NOTREACHED(); } - virtual void ChangedInRect(const Image*, const IntRect&) {} + void ChangedInRect(const Image*, const IntRect&) override {} size_t last_decoded_size_; int last_decoded_size_changed_delta_; @@ -482,6 +482,14 @@ TEST_F(BitmapImageTest, APNGDecoder18) { VerifyBitmap(actual_bitmap, expected_bitmap); } +TEST_F(BitmapImageTest, APNGDecoder19) { + LoadImage("/images/resources/apng19.png"); + auto actual_bitmap = GenerateBitmap(12u); + auto expected_bitmap = + GenerateBitmapForImage("/images/resources/apng19-ref.png"); + VerifyBitmap(actual_bitmap, expected_bitmap); +} + TEST_F(BitmapImageTest, APNGDecoderDisposePrevious) { LoadImage("/images/resources/crbug722072.png"); auto actual_bitmap = GenerateBitmap(3u); 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 0122380a437..f03d90ef1e9 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 @@ -30,10 +30,10 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" +#include "cc/layers/texture_layer.h" #include "components/viz/common/resources/transferable_resource.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/renderer/platform/graphics/canvas_heuristic_parameters.h" #include "third_party/blink/renderer/platform/graphics/canvas_metrics.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource.h" @@ -46,7 +46,7 @@ #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkSurface.h" @@ -65,11 +65,9 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size, AccelerationMode acceleration_mode, const CanvasColorParams& color_params) : logger_(std::make_unique<Logger>()), - weak_ptr_factory_(this), msaa_sample_count_(msaa_sample_count), bytes_allocated_(0), have_recorded_draw_commands_(false), - destruction_in_progress_(false), filter_quality_(kLow_SkFilterQuality), is_hidden_(false), is_deferral_enabled_(true), @@ -78,7 +76,8 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size, color_params_(color_params), size_(size), snapshot_state_(kInitialSnapshotState), - resource_host_(nullptr) { + resource_host_(nullptr), + weak_ptr_factory_(this) { // Used by browser tests to detect the use of a Canvas2DLayerBridge. TRACE_EVENT_INSTANT0("test_gpu", "Canvas2DLayerBridgeCreation", TRACE_EVENT_SCOPE_GLOBAL); @@ -96,9 +95,25 @@ Canvas2DLayerBridge::Canvas2DLayerBridge(const IntSize& size, } Canvas2DLayerBridge::~Canvas2DLayerBridge() { - BeginDestruction(); - DCHECK(destruction_in_progress_); - layer_.reset(); + if (IsHibernating()) + logger_->ReportHibernationEvent(kHibernationEndedWithTeardown); + ResetResourceProvider(); + + if (layer_ && acceleration_mode_ != kDisableAcceleration) { + GraphicsLayer::UnregisterContentsLayer(layer_.get()); + layer_->ClearTexture(); + // Orphaning the layer is required to trigger the recration of a new layer + // in the case where destruction is caused by a canvas resize. Test: + // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html + layer_->RemoveFromParent(); + } + + DCHECK(!bytes_allocated_); + + if (layer_) { + layer_->ClearClient(); + layer_ = nullptr; + } } void Canvas2DLayerBridge::StartRecording() { @@ -188,11 +203,6 @@ void Canvas2DLayerBridge::Hibernate() { hibernation_scheduled_ = false; - if (destruction_in_progress_) { - logger_->ReportHibernationEvent(kHibernationAbortedDueToPendingDestruction); - return; - } - if (!resource_provider_) { logger_->ReportHibernationEvent(kHibernationAbortedBecauseNoSurface); return; @@ -298,13 +308,12 @@ CanvasResourceProvider* Canvas2DLayerBridge::GetOrCreateResourceProvider( } if (resource_provider_ && resource_provider_->IsAccelerated() && !layer_) { - layer_ = - Platform::Current()->CompositorSupport()->CreateExternalTextureLayer( - this); - layer_->SetOpaque(ColorParams().GetOpacityMode() == kOpaque); + layer_ = cc::TextureLayer::CreateForMailbox(this); + layer_->SetIsDrawable(true); + layer_->SetContentsOpaque(ColorParams().GetOpacityMode() == kOpaque); layer_->SetBlendBackgroundColor(ColorParams().GetOpacityMode() != kOpaque); - GraphicsLayer::RegisterContentsLayer(layer_->Layer()); layer_->SetNearestNeighbor(filter_quality_ == kNone_SkFilterQuality); + GraphicsLayer::RegisterContentsLayer(layer_.get()); } if (resource_provider_ && IsHibernating()) { @@ -384,31 +393,7 @@ void Canvas2DLayerBridge::DisableDeferral(DisableDeferralReason reason) { resource_host_->RestoreCanvasMatrixClipStack(resource_provider_->Canvas()); } -void Canvas2DLayerBridge::BeginDestruction() { - if (destruction_in_progress_) - return; - if (IsHibernating()) - logger_->ReportHibernationEvent(kHibernationEndedWithTeardown); - hibernation_image_.reset(); - recorder_.reset(); - destruction_in_progress_ = true; - SetIsHidden(true); - ResetResourceProvider(); - - if (layer_ && acceleration_mode_ != kDisableAcceleration) { - GraphicsLayer::UnregisterContentsLayer(layer_->Layer()); - layer_->ClearTexture(); - // Orphaning the layer is required to trigger the recration of a new layer - // in the case where destruction is caused by a canvas resize. Test: - // virtual/gpu/fast/canvas/canvas-resize-after-paint-without-layout.html - layer_->Layer()->RemoveFromParent(); - } - - DCHECK(!bytes_allocated_); -} - void Canvas2DLayerBridge::SetFilterQuality(SkFilterQuality filter_quality) { - DCHECK(!destruction_in_progress_); filter_quality_ = filter_quality; if (resource_provider_) resource_provider_->SetFilterQuality(filter_quality); @@ -417,16 +402,15 @@ void Canvas2DLayerBridge::SetFilterQuality(SkFilterQuality filter_quality) { } void Canvas2DLayerBridge::SetIsHidden(bool hidden) { - bool new_hidden_value = hidden || destruction_in_progress_; - if (is_hidden_ == new_hidden_value) + if (is_hidden_ == hidden) return; - is_hidden_ = new_hidden_value; + is_hidden_ = hidden; if (resource_provider_) resource_provider_->SetResourceRecyclingEnabled(!IsHidden()); if (CANVAS2D_HIBERNATION_ENABLED && resource_provider_ && IsHidden() && - !destruction_in_progress_ && !hibernation_scheduled_) { + !hibernation_scheduled_) { if (layer_) layer_->ClearTexture(); logger_->ReportHibernationEvent(kHibernationScheduled); @@ -512,7 +496,6 @@ void Canvas2DLayerBridge::SkipQueuedDrawCommands() { } void Canvas2DLayerBridge::FlushRecording() { - DCHECK(!destruction_in_progress_); if (have_recorded_draw_commands_ && GetOrCreateResourceProvider()) { TRACE_EVENT0("cc", "Canvas2DLayerBridge::flushRecording"); @@ -538,9 +521,6 @@ bool Canvas2DLayerBridge::IsValid() const { } bool Canvas2DLayerBridge::CheckResourceProviderValid() { - DCHECK(!destruction_in_progress_); - if (destruction_in_progress_) - return false; if (IsHibernating()) return true; if (!layer_ || acceleration_mode_ == kDisableAcceleration) @@ -552,7 +532,7 @@ bool Canvas2DLayerBridge::CheckResourceProviderValid() { context_lost_ = true; ResetResourceProvider(); if (resource_host_) - resource_host_->NotifySurfaceInvalid(); + resource_host_->NotifyGpuContextLost(); CanvasMetrics::CountCanvasContextUsage( CanvasMetrics::kAccelerated2DCanvasGPUContextLost); return false; @@ -563,9 +543,8 @@ bool Canvas2DLayerBridge::CheckResourceProviderValid() { } bool Canvas2DLayerBridge::Restore() { - DCHECK(!destruction_in_progress_); DCHECK(context_lost_); - if (destruction_in_progress_ || !IsAccelerated()) + if (!IsAccelerated()) return false; DCHECK(!resource_provider_); @@ -607,14 +586,6 @@ bool Canvas2DLayerBridge::PrepareTransferableResource( cc::SharedBitmapIdRegistrar* bitmap_registrar, viz::TransferableResource* out_resource, std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) { - if (destruction_in_progress_) { - // It can be hit in the following sequence. - // 1. Canvas draws something. - // 2. The compositor begins the frame. - // 3. Javascript makes a context be lost. - // 4. Here. - return false; - } DCHECK(layer_); // This explodes if FinalizeFrame() was not called. @@ -643,18 +614,15 @@ bool Canvas2DLayerBridge::PrepareTransferableResource( // Note frame is kept alive via a reference kept in out_release_callback. bool success = frame->PrepareTransferableResource(out_resource, out_release_callback); - if (success) - out_resource->color_space = color_params_.GetSamplerGfxColorSpace(); return success; } return false; } -WebLayer* Canvas2DLayerBridge::Layer() { - DCHECK(!destruction_in_progress_); +cc::Layer* Canvas2DLayerBridge::Layer() { // Trigger lazy layer creation GetOrCreateResourceProvider(kPreferAcceleration); - return layer_ ? layer_->Layer() : nullptr; + return layer_.get(); } void Canvas2DLayerBridge::DidDraw(const FloatRect& rect) { @@ -685,7 +653,6 @@ void Canvas2DLayerBridge::DidDraw(const FloatRect& rect) { void Canvas2DLayerBridge::FinalizeFrame() { TRACE_EVENT0("blink", "Canvas2DLayerBridge::FinalizeFrame"); - DCHECK(!destruction_in_progress_); // Make sure surface is ready for painting: fix the rendering mode now // because it will be too late during the paint invalidation phase. @@ -710,9 +677,8 @@ void Canvas2DLayerBridge::FinalizeFrame() { } void Canvas2DLayerBridge::DoPaintInvalidation(const FloatRect& dirty_rect) { - DCHECK(!destruction_in_progress_); if (layer_ && acceleration_mode_ != kDisableAcceleration) - layer_->Layer()->InvalidateRect(EnclosingIntRect(dirty_rect)); + layer_->SetNeedsDisplayRect(EnclosingIntRect(dirty_rect)); } scoped_refptr<StaticBitmapImage> Canvas2DLayerBridge::NewImageSnapshot( 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 7f062491ff6..d9eba20732a 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 @@ -32,7 +32,7 @@ #include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "cc/layers/texture_layer_client.h" -#include "third_party/blink/public/platform/web_external_texture_layer.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" #include "third_party/blink/renderer/platform/graphics/canvas_resource_host.h" @@ -50,6 +50,11 @@ struct SkImageInfo; +namespace cc { +class Layer; +class TextureLayer; +} + namespace blink { class Canvas2DLayerBridgeTest; @@ -96,7 +101,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient { void SetIsHidden(bool); void DidDraw(const FloatRect&); void DoPaintInvalidation(const FloatRect& dirty_rect); - WebLayer* Layer(); + cc::Layer* Layer(); bool Restore(); void DisableDeferral(DisableDeferralReason); void SetFilterQuality(SkFilterQuality); @@ -121,7 +126,6 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient { resource_host_ = host; } - void BeginDestruction(); void Hibernate(); bool IsHibernating() const { return hibernation_image_; } const CanvasColorParams& ColorParams() const { return color_params_; } @@ -138,7 +142,7 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient { enum HibernationEvent { kHibernationScheduled = 0, kHibernationAbortedDueToDestructionWhileHibernatePending = 1, - kHibernationAbortedDueToPendingDestruction = 2, + // kHibernationAbortedDueToPendingDestruction = 2, (obsolete) kHibernationAbortedDueToVisibilityChange = 3, kHibernationAbortedDueGpuContextLoss = 4, kHibernationAbortedDueToSwitchToUnacceleratedRendering = 5, @@ -181,15 +185,13 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient { std::unique_ptr<CanvasResourceProvider> resource_provider_; std::unique_ptr<PaintRecorder> recorder_; sk_sp<SkImage> hibernation_image_; - std::unique_ptr<WebExternalTextureLayer> layer_; + scoped_refptr<cc::TextureLayer> layer_; std::unique_ptr<SharedContextRateLimiter> rate_limiter_; std::unique_ptr<Logger> logger_; - base::WeakPtrFactory<Canvas2DLayerBridge> weak_ptr_factory_; int msaa_sample_count_; int frames_since_last_commit_ = 0; size_t bytes_allocated_; bool have_recorded_draw_commands_; - bool destruction_in_progress_; SkFilterQuality filter_quality_; bool is_hidden_; bool is_deferral_enabled_; @@ -216,6 +218,8 @@ class PLATFORM_EXPORT Canvas2DLayerBridge : public cc::TextureLayerClient { mutable SnapshotState snapshot_state_; CanvasResourceHost* resource_host_; + + base::WeakPtrFactory<Canvas2DLayerBridge> weak_ptr_factory_; }; } // namespace blink 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 b19e9ae1528..0dc24d3a986 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 @@ -39,7 +39,6 @@ #include "components/viz/test/test_gpu_memory_buffer_manager.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/capabilities.h" -#include "skia/ext/texture_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" @@ -53,7 +52,7 @@ #include "third_party/blink/renderer/platform/graphics/test/fake_gles2_interface.h" #include "third_party/blink/renderer/platform/graphics/test/fake_web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.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/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/waitable_event.h" @@ -83,12 +82,7 @@ class Canvas2DLayerBridgePtr { ~Canvas2DLayerBridgePtr() { Clear(); } - void Clear() { - if (layer_bridge_) { - layer_bridge_->BeginDestruction(); - layer_bridge_.reset(); - } - } + void Clear() { layer_bridge_.reset(); } void operator=(std::unique_ptr<Canvas2DLayerBridge> layer_bridge) { DCHECK(!layer_bridge_); // Existing ref must be removed with Clear() @@ -111,7 +105,7 @@ class MockGLES2InterfaceWithImageSupport : public FakeGLES2Interface { MOCK_METHOD2(GenTextures, void(GLsizei, GLuint*)); MOCK_METHOD2(DeleteTextures, void(GLsizei, const GLuint*)); // Fake - void GenMailboxCHROMIUM(GLbyte* name) { + void GenMailboxCHROMIUM(GLbyte* name) override { name[0] = 1; // Make non-zero mailbox names } }; @@ -206,13 +200,13 @@ class Canvas2DLayerBridgeTest : public Test { IntSize(300, 150), 0, Canvas2DLayerBridge::kDisableAcceleration, CanvasColorParams())); - const GrGLTextureInfo* texture_info = - skia::GrBackendObjectToGrGLTextureInfo( - bridge->NewImageSnapshot(kPreferAcceleration) - ->PaintImageForCurrentFrame() - .GetSkImage() - ->getTextureHandle(true)); - EXPECT_EQ(texture_info, nullptr); + GrBackendTexture backend_texture = + bridge->NewImageSnapshot(kPreferAcceleration) + ->PaintImageForCurrentFrame() + .GetSkImage() + ->getBackendTexture(true); + + EXPECT_FALSE(backend_texture.isValid()); bridge.Clear(); } @@ -459,14 +453,14 @@ class MockLogger : public Canvas2DLayerBridge::Logger { MOCK_METHOD1(ReportHibernationEvent, void(Canvas2DLayerBridge::HibernationEvent)); MOCK_METHOD0(DidStartHibernating, void()); - virtual ~MockLogger() = default; + ~MockLogger() override = default; }; class MockCanvasResourceHost : public CanvasResourceHost { public: - void NotifySurfaceInvalid() {} - void SetNeedsCompositingUpdate() {} - void UpdateMemoryUsage() {} + void NotifyGpuContextLost() override {} + void SetNeedsCompositingUpdate() override {} + void UpdateMemoryUsage() override {} MOCK_CONST_METHOD1(RestoreCanvasMatrixClipStack, void(PaintCanvas*)); }; @@ -927,40 +921,6 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_TeardownWhileHibernationIsPending) } #if CANVAS2D_HIBERNATION_ENABLED -TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToPendingTeardown) -#else -TEST_F(Canvas2DLayerBridgeTest, DISABLED_HibernationAbortedDueToPendingTeardown) -#endif -{ - ScopedTestingPlatformSupport<FakePlatformSupport> platform; - Canvas2DLayerBridgePtr bridge(std::make_unique<Canvas2DLayerBridge>( - IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration, - CanvasColorParams())); - bridge->DontUseIdleSchedulingForTesting(); - DrawSomething(bridge); - - // 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, - ReportHibernationEvent( - Canvas2DLayerBridge::kHibernationAbortedDueToPendingDestruction)) - .Times(1); - bridge->SetIsHidden(true); - bridge->BeginDestruction(); - platform->RunUntilIdle(); - - testing::Mock::VerifyAndClearExpectations(mock_logger_ptr); -} - -#if CANVAS2D_HIBERNATION_ENABLED TEST_F(Canvas2DLayerBridgeTest, HibernationAbortedDueToVisibilityChange) #else TEST_F(Canvas2DLayerBridgeTest, @@ -1123,6 +1083,7 @@ TEST_F(Canvas2DLayerBridgeTest, DISABLED_PrepareMailboxWhileBackgroundRendering) } TEST_F(Canvas2DLayerBridgeTest, GpuMemoryBufferRecycling) { + InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); ScopedTestingPlatformSupport<FakePlatformSupport> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() @@ -1134,10 +1095,10 @@ TEST_F(Canvas2DLayerBridgeTest, GpuMemoryBufferRecycling) { viz::TransferableResource resource2; std::unique_ptr<viz::SingleReleaseCallback> release_callback1; std::unique_ptr<viz::SingleReleaseCallback> release_callback2; - const GLuint texture_id1 = 1; - const GLuint texture_id2 = 2; - const GLuint image_id1 = 3; - const GLuint image_id2 = 4; + constexpr GLuint texture_id1 = 1; + constexpr GLuint texture_id2 = 2; + constexpr GLuint image_id1 = 3; + constexpr GLuint image_id2 = 4; Canvas2DLayerBridgePtr bridge(std::make_unique<Canvas2DLayerBridge>( IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting, @@ -1145,15 +1106,15 @@ TEST_F(Canvas2DLayerBridgeTest, GpuMemoryBufferRecycling) { testing::Mock::VerifyAndClearExpectations(&gl_); - EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id1)); EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id1)); + EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id1)); DrawSomething(bridge); bridge->PrepareTransferableResource(nullptr, &resource1, &release_callback1); testing::Mock::VerifyAndClearExpectations(&gl_); - EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id2)); EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id2)); + EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id2)); DrawSomething(bridge); bridge->PrepareTransferableResource(nullptr, &resource2, &release_callback2); @@ -1187,6 +1148,7 @@ TEST_F(Canvas2DLayerBridgeTest, GpuMemoryBufferRecycling) { } TEST_F(Canvas2DLayerBridgeTest, NoGpuMemoryBufferRecyclingWhenPageHidden) { + InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); ScopedTestingPlatformSupport<FakePlatformSupport> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() @@ -1198,10 +1160,10 @@ TEST_F(Canvas2DLayerBridgeTest, NoGpuMemoryBufferRecyclingWhenPageHidden) { viz::TransferableResource resource2; std::unique_ptr<viz::SingleReleaseCallback> release_callback1; std::unique_ptr<viz::SingleReleaseCallback> release_callback2; - const GLuint texture_id1 = 1; - const GLuint texture_id2 = 2; - const GLuint image_id1 = 3; - const GLuint image_id2 = 4; + constexpr GLuint texture_id1 = 1; + constexpr GLuint texture_id2 = 2; + constexpr GLuint image_id1 = 3; + constexpr GLuint image_id2 = 4; Canvas2DLayerBridgePtr bridge(std::make_unique<Canvas2DLayerBridge>( IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting, @@ -1209,15 +1171,15 @@ TEST_F(Canvas2DLayerBridgeTest, NoGpuMemoryBufferRecyclingWhenPageHidden) { testing::Mock::VerifyAndClearExpectations(&gl_); - EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id1)); EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id1)); + EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id1)); DrawSomething(bridge); bridge->PrepareTransferableResource(nullptr, &resource1, &release_callback1); testing::Mock::VerifyAndClearExpectations(&gl_); - EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id2)); EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id2)); + EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id2)); DrawSomething(bridge); bridge->PrepareTransferableResource(nullptr, &resource2, &release_callback2); @@ -1250,6 +1212,7 @@ TEST_F(Canvas2DLayerBridgeTest, NoGpuMemoryBufferRecyclingWhenPageHidden) { } TEST_F(Canvas2DLayerBridgeTest, ReleaseGpuMemoryBufferAfterBridgeDestroyed) { + InSequence s; ScopedCanvas2dImageChromiumForTest canvas_2d_image_chromium(true); ScopedTestingPlatformSupport<FakePlatformSupport> platform; const_cast<gpu::Capabilities&>(SharedGpuContext::ContextProviderWrapper() @@ -1259,8 +1222,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseGpuMemoryBufferAfterBridgeDestroyed) { viz::TransferableResource resource; std::unique_ptr<viz::SingleReleaseCallback> release_callback; - const GLuint texture_id = 1; - const GLuint image_id = 2; + constexpr GLuint texture_id = 1; + constexpr GLuint image_id = 2; Canvas2DLayerBridgePtr bridge(std::make_unique<Canvas2DLayerBridge>( IntSize(300, 150), 0, Canvas2DLayerBridge::kForceAccelerationForTesting, @@ -1268,8 +1231,8 @@ TEST_F(Canvas2DLayerBridgeTest, ReleaseGpuMemoryBufferAfterBridgeDestroyed) { testing::Mock::VerifyAndClearExpectations(&gl_); - EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id)); EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id)); + EXPECT_CALL(gl_, GenTextures(1, _)).WillOnce(SetArgPointee<1>(texture_id)); DrawSomething(bridge); bridge->PrepareTransferableResource(nullptr, &resource, &release_callback); @@ -1299,13 +1262,14 @@ TEST_F(Canvas2DLayerBridgeTest, EnsureCCImageCacheUse) { Canvas2DLayerBridgePtr bridge(std::make_unique<Canvas2DLayerBridge>( IntSize(300, 300), 0, Canvas2DLayerBridge::kEnableAcceleration, color_params)); + gfx::ColorSpace expected_color_space = gfx::ColorSpace::CreateSRGB(); std::vector<cc::DrawImage> images = { cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(10, 10)), SkIRect::MakeWH(10, 10), kNone_SkFilterQuality, - SkMatrix::I(), 0u, color_params.GetStorageGfxColorSpace()), + SkMatrix::I(), 0u, expected_color_space), cc::DrawImage(cc::CreateDiscardablePaintImage(gfx::Size(20, 20)), SkIRect::MakeWH(5, 5), kNone_SkFilterQuality, SkMatrix::I(), - 0u, color_params.GetStorageGfxColorSpace())}; + 0u, expected_color_space)}; bridge->Canvas()->drawImage(images[0].paint_image(), 0u, 0u, nullptr); bridge->Canvas()->drawImageRect( 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 8d0601a44fe..ad8322a4417 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 @@ -51,13 +51,13 @@ CanvasColorParams::CanvasColorParams(const SkImageInfo& info) { // format). if (!info.colorSpace()) return; - if (SkColorSpace::Equals(info.colorSpace(), SkColorSpace::MakeSRGB().get())) - color_space_ = kSRGBCanvasColorSpace; - else if (SkColorSpace::Equals( - info.colorSpace(), - SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, - SkColorSpace::kRec2020_Gamut) - .get())) + // kSRGBCanvasColorSpace covers sRGB and linear-rgb. We need to check for + // Rec2020 and P3. + if (SkColorSpace::Equals( + info.colorSpace(), + SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, + SkColorSpace::kRec2020_Gamut) + .get())) color_space_ = kRec2020CanvasColorSpace; else if (SkColorSpace::Equals( info.colorSpace(), @@ -210,7 +210,7 @@ GLenum CanvasColorParams::GLType() const { case kRGBA8CanvasPixelFormat: return GL_UNSIGNED_BYTE; case kF16CanvasPixelFormat: - return GL_HALF_FLOAT; + return GL_HALF_FLOAT_OES; default: break; } 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 727c44dcc99..a2c2b26f473 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.cc @@ -8,7 +8,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 "skia/ext/texture_handle.h" +#include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" @@ -19,8 +19,11 @@ namespace blink { CanvasResource::CanvasResource(base::WeakPtr<CanvasResourceProvider> provider, - SkFilterQuality filter_quality) - : provider_(std::move(provider)), filter_quality_(filter_quality) {} + SkFilterQuality filter_quality, + const CanvasColorParams& color_params) + : provider_(std::move(provider)), + filter_quality_(filter_quality), + color_params_(color_params) {} CanvasResource::~CanvasResource() { // Sync token should have been waited on in sub-class implementation of @@ -28,6 +31,15 @@ CanvasResource::~CanvasResource() { DCHECK(!sync_token_for_release_.HasData()); } +bool CanvasResource::IsBitmap() { + return false; +} + +scoped_refptr<StaticBitmapImage> CanvasResource::Bitmap() { + NOTREACHED(); + return nullptr; +} + gpu::gles2::GLES2Interface* CanvasResource::ContextGL() const { if (!ContextProviderWrapper()) return nullptr; @@ -39,7 +51,7 @@ void CanvasResource::SetSyncTokenForRelease(const gpu::SyncToken& token) { } void CanvasResource::WaitSyncTokenBeforeRelease() { - auto gl = ContextGL(); + auto* gl = ContextGL(); if (sync_token_for_release_.HasData() && gl) { gl->WaitSyncTokenCHROMIUM(sync_token_for_release_.GetData()); } @@ -70,7 +82,7 @@ bool CanvasResource::PrepareTransferableResource( // Gpu compositing is a prerequisite for accelerated 2D canvas // TODO: For WebGL to use this, we must add software composing support. DCHECK(SharedGpuContext::IsGpuCompositingEnabled()); - auto gl = ContextGL(); + auto* gl = ContextGL(); DCHECK(gl); const gpu::Mailbox& mailbox = GetOrCreateGpuMailbox(); @@ -81,6 +93,8 @@ bool CanvasResource::PrepareTransferableResource( mailbox, GLFilter(), TextureTarget(), GetSyncToken(), gfx::Size(Size()), IsOverlayCandidate()); + out_resource->color_space = color_params_.GetSamplerGfxColorSpace(); + scoped_refptr<CanvasResource> this_ref(this); auto func = WTF::Bind(&ReleaseFrameResources, provider_, WTF::Passed(std::move(this_ref))); @@ -98,35 +112,73 @@ GLenum CanvasResource::GLFilter() const { return filter_quality_ == kNone_SkFilterQuality ? GL_NEAREST : GL_LINEAR; } -// CanvasResource_Bitmap +// CanvasResourceBitmap //============================================================================== -CanvasResource_Bitmap::CanvasResource_Bitmap( +CanvasResourceBitmap::CanvasResourceBitmap( scoped_refptr<StaticBitmapImage> image, base::WeakPtr<CanvasResourceProvider> provider, - SkFilterQuality filter_quality) - : CanvasResource(std::move(provider), filter_quality), + SkFilterQuality filter_quality, + const CanvasColorParams& color_params) + : CanvasResource(std::move(provider), filter_quality, color_params), image_(std::move(image)) {} -scoped_refptr<CanvasResource_Bitmap> CanvasResource_Bitmap::Create( +scoped_refptr<CanvasResourceBitmap> CanvasResourceBitmap::Create( scoped_refptr<StaticBitmapImage> image, base::WeakPtr<CanvasResourceProvider> provider, - SkFilterQuality filter_quality) { - scoped_refptr<CanvasResource_Bitmap> resource = - AdoptRef(new CanvasResource_Bitmap(std::move(image), std::move(provider), - filter_quality)); + SkFilterQuality filter_quality, + const CanvasColorParams& color_params) { + scoped_refptr<CanvasResourceBitmap> resource = + AdoptRef(new CanvasResourceBitmap(std::move(image), std::move(provider), + filter_quality, color_params)); if (resource->IsValid()) return resource; return nullptr; } -bool CanvasResource_Bitmap::IsValid() const { +bool CanvasResourceBitmap::IsValid() const { if (!image_) return false; return image_->IsValid(); } -void CanvasResource_Bitmap::TearDown() { +bool CanvasResourceBitmap::IsAccelerated() const { + return image_->IsTextureBacked(); +} + +scoped_refptr<CanvasResource> CanvasResourceBitmap::MakeAccelerated( + base::WeakPtr<WebGraphicsContext3DProviderWrapper> + context_provider_wrapper) { + if (IsAccelerated()) + return base::WrapRefCounted(this); + if (!context_provider_wrapper) + return nullptr; + scoped_refptr<StaticBitmapImage> accelerated_image = + image_->MakeAccelerated(context_provider_wrapper); + // passing nullptr for the resource provider argument creates an orphan + // CanvasResource, which implies that it internal resources will not be + // recycled. + scoped_refptr<CanvasResource> accelerated_resource = + Create(accelerated_image, nullptr, FilterQuality(), ColorParams()); + if (!accelerated_resource) + return nullptr; + return accelerated_resource; +} + +scoped_refptr<CanvasResource> CanvasResourceBitmap::MakeUnaccelerated() { + if (!IsAccelerated()) + return base::WrapRefCounted(this); + scoped_refptr<StaticBitmapImage> unaccelerated_image = + image_->MakeUnaccelerated(); + // passing nullptr for the resource provider argument creates an orphan + // CanvasResource, which implies that it internal resources will not be + // recycled. + scoped_refptr<CanvasResource> unaccelerated_resource = + Create(unaccelerated_image, nullptr, FilterQuality(), ColorParams()); + return unaccelerated_resource; +} + +void CanvasResourceBitmap::TearDown() { WaitSyncTokenBeforeRelease(); // We must not disassociate the mailbox from the texture object here because // the texture may be recycled by skia and the associated cached mailbox @@ -134,54 +186,62 @@ void CanvasResource_Bitmap::TearDown() { image_ = nullptr; } -IntSize CanvasResource_Bitmap::Size() const { +IntSize CanvasResourceBitmap::Size() const { if (!image_) return IntSize(0, 0); return IntSize(image_->width(), image_->height()); } -GLenum CanvasResource_Bitmap::TextureTarget() const { +GLenum CanvasResourceBitmap::TextureTarget() const { return GL_TEXTURE_2D; } -const gpu::Mailbox& CanvasResource_Bitmap::GetOrCreateGpuMailbox() { +bool CanvasResourceBitmap::IsBitmap() { + return true; +} + +scoped_refptr<StaticBitmapImage> CanvasResourceBitmap::Bitmap() { + return image_; +} + +const gpu::Mailbox& CanvasResourceBitmap::GetOrCreateGpuMailbox() { DCHECK(image_); // Calling code should check IsValid() before calling this. image_->EnsureMailbox(kUnverifiedSyncToken, GLFilter()); return image_->GetMailbox(); } -bool CanvasResource_Bitmap::HasGpuMailbox() const { +bool CanvasResourceBitmap::HasGpuMailbox() const { return image_ && image_->HasMailbox(); } -const gpu::SyncToken& CanvasResource_Bitmap::GetSyncToken() { +const gpu::SyncToken& CanvasResourceBitmap::GetSyncToken() { DCHECK(image_); // Calling code should check IsValid() before calling this. return image_->GetSyncToken(); } base::WeakPtr<WebGraphicsContext3DProviderWrapper> -CanvasResource_Bitmap::ContextProviderWrapper() const { +CanvasResourceBitmap::ContextProviderWrapper() const { if (!image_) return nullptr; return image_->ContextProviderWrapper(); } -// CanvasResource_GpuMemoryBuffer +// CanvasResourceGpuMemoryBuffer //============================================================================== -CanvasResource_GpuMemoryBuffer::CanvasResource_GpuMemoryBuffer( +CanvasResourceGpuMemoryBuffer::CanvasResourceGpuMemoryBuffer( const IntSize& size, const CanvasColorParams& color_params, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper, base::WeakPtr<CanvasResourceProvider> provider, SkFilterQuality filter_quality) - : CanvasResource(provider, filter_quality), + : CanvasResource(provider, filter_quality, color_params), context_provider_wrapper_(std::move(context_provider_wrapper)), color_params_(color_params) { if (!context_provider_wrapper_) return; - auto gl = context_provider_wrapper_->ContextProvider()->ContextGL(); - auto gr = context_provider_wrapper_->ContextProvider()->GetGrContext(); + auto* gl = context_provider_wrapper_->ContextProvider()->ContextGL(); + auto* gr = context_provider_wrapper_->ContextProvider()->GetGrContext(); if (!gl || !gr) return; gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = @@ -205,33 +265,33 @@ CanvasResource_GpuMemoryBuffer::CanvasResource_GpuMemoryBuffer( gpu_memory_buffer_->SetColorSpace(color_params.GetStorageGfxColorSpace()); gl->GenTextures(1, &texture_id_); - const GLenum target = GL_TEXTURE_RECTANGLE_ARB; + const GLenum target = TextureTarget(); gl->BindTexture(target, texture_id_); gl->BindTexImage2DCHROMIUM(target, image_id_); } -CanvasResource_GpuMemoryBuffer::~CanvasResource_GpuMemoryBuffer() { +CanvasResourceGpuMemoryBuffer::~CanvasResourceGpuMemoryBuffer() { TearDown(); } -GLenum CanvasResource_GpuMemoryBuffer::TextureTarget() const { - return GL_TEXTURE_RECTANGLE_ARB; +GLenum CanvasResourceGpuMemoryBuffer::TextureTarget() const { + return gpu::GetPlatformSpecificTextureTarget(); } -IntSize CanvasResource_GpuMemoryBuffer::Size() const { +IntSize CanvasResourceGpuMemoryBuffer::Size() const { return IntSize(gpu_memory_buffer_->GetSize().width(), gpu_memory_buffer_->GetSize().height()); } -scoped_refptr<CanvasResource_GpuMemoryBuffer> -CanvasResource_GpuMemoryBuffer::Create( +scoped_refptr<CanvasResourceGpuMemoryBuffer> +CanvasResourceGpuMemoryBuffer::Create( const IntSize& size, const CanvasColorParams& color_params, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper, base::WeakPtr<CanvasResourceProvider> provider, SkFilterQuality filter_quality) { - scoped_refptr<CanvasResource_GpuMemoryBuffer> resource = - AdoptRef(new CanvasResource_GpuMemoryBuffer( + scoped_refptr<CanvasResourceGpuMemoryBuffer> resource = + AdoptRef(new CanvasResourceGpuMemoryBuffer( size, color_params, std::move(context_provider_wrapper), provider, filter_quality)); if (resource->IsValid()) @@ -239,26 +299,22 @@ CanvasResource_GpuMemoryBuffer::Create( return nullptr; } -void CanvasResource_GpuMemoryBuffer::TearDown() { +void CanvasResourceGpuMemoryBuffer::TearDown() { WaitSyncTokenBeforeRelease(); if (!context_provider_wrapper_ || !image_id_) return; - auto gl = context_provider_wrapper_->ContextProvider()->ContextGL(); - if (gl && texture_id_) { - GLenum target = TextureTarget(); - gl->BindTexture(target, texture_id_); - gl->ReleaseTexImage2DCHROMIUM(target, image_id_); + auto* gl = context_provider_wrapper_->ContextProvider()->ContextGL(); + if (gl && image_id_) gl->DestroyImageCHROMIUM(image_id_); + if (gl && texture_id_) gl->DeleteTextures(1, &texture_id_); - gl->BindTexture(target, 0); - } image_id_ = 0; texture_id_ = 0; gpu_memory_buffer_ = nullptr; } -const gpu::Mailbox& CanvasResource_GpuMemoryBuffer::GetOrCreateGpuMailbox() { - auto gl = ContextGL(); +const gpu::Mailbox& CanvasResourceGpuMemoryBuffer::GetOrCreateGpuMailbox() { + auto* gl = ContextGL(); DCHECK(gl); // caller should already have early exited if !gl. if (gpu_mailbox_.IsZero() && gl) { gl->GenMailboxCHROMIUM(gpu_mailbox_.name); @@ -268,13 +324,13 @@ const gpu::Mailbox& CanvasResource_GpuMemoryBuffer::GetOrCreateGpuMailbox() { return gpu_mailbox_; } -bool CanvasResource_GpuMemoryBuffer::HasGpuMailbox() const { +bool CanvasResourceGpuMemoryBuffer::HasGpuMailbox() const { return !gpu_mailbox_.IsZero(); } -const gpu::SyncToken& CanvasResource_GpuMemoryBuffer::GetSyncToken() { +const gpu::SyncToken& CanvasResourceGpuMemoryBuffer::GetSyncToken() { if (mailbox_needs_new_sync_token_) { - auto gl = ContextGL(); + auto* gl = ContextGL(); DCHECK(gl); // caller should already have early exited if !gl. mailbox_needs_new_sync_token_ = false; gl->GenUnverifiedSyncTokenCHROMIUM(sync_token_.GetData()); @@ -282,9 +338,9 @@ const gpu::SyncToken& CanvasResource_GpuMemoryBuffer::GetSyncToken() { return sync_token_; } -void CanvasResource_GpuMemoryBuffer::CopyFromTexture(GLuint source_texture, - GLenum format, - GLenum type) { +void CanvasResourceGpuMemoryBuffer::CopyFromTexture(GLuint source_texture, + GLenum format, + GLenum type) { if (!IsValid()) return; @@ -296,7 +352,7 @@ void CanvasResource_GpuMemoryBuffer::CopyFromTexture(GLuint source_texture, } base::WeakPtr<WebGraphicsContext3DProviderWrapper> -CanvasResource_GpuMemoryBuffer::ContextProviderWrapper() const { +CanvasResourceGpuMemoryBuffer::ContextProviderWrapper() const { return context_provider_wrapper_; } 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 e9efde9bdc2..69f6a596359 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h +++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource.h @@ -39,6 +39,7 @@ class PLATFORM_EXPORT CanvasResource : public WTF::RefCounted<CanvasResource> { virtual ~CanvasResource(); virtual void Abandon() = 0; virtual bool IsRecycleable() const = 0; + virtual bool IsAccelerated() const = 0; virtual bool IsValid() const = 0; virtual IntSize Size() const = 0; virtual const gpu::Mailbox& GetOrCreateGpuMailbox() = 0; @@ -47,6 +48,11 @@ class PLATFORM_EXPORT CanvasResource : public WTF::RefCounted<CanvasResource> { viz::TransferableResource* out_resource, std::unique_ptr<viz::SingleReleaseCallback>* out_callback); void SetSyncTokenForRelease(const gpu::SyncToken&); + virtual scoped_refptr<CanvasResource> MakeAccelerated( + base::WeakPtr<WebGraphicsContext3DProviderWrapper>) = 0; + virtual scoped_refptr<CanvasResource> MakeUnaccelerated() = 0; + virtual bool IsBitmap(); + virtual scoped_refptr<StaticBitmapImage> Bitmap(); void WaitSyncTokenBeforeRelease(); virtual void CopyFromTexture(GLuint source_texture, GLenum format, @@ -55,7 +61,9 @@ class PLATFORM_EXPORT CanvasResource : public WTF::RefCounted<CanvasResource> { } protected: - CanvasResource(base::WeakPtr<CanvasResourceProvider>, SkFilterQuality); + CanvasResource(base::WeakPtr<CanvasResourceProvider>, + SkFilterQuality, + const CanvasColorParams&); virtual GLenum TextureTarget() const = 0; virtual bool IsOverlayCandidate() const { return false; } virtual bool HasGpuMailbox() const = 0; @@ -67,29 +75,39 @@ class PLATFORM_EXPORT CanvasResource : public WTF::RefCounted<CanvasResource> { void PrepareTransferableResourceCommon( viz::TransferableResource* out_resource, std::unique_ptr<viz::SingleReleaseCallback>* out_callback); + SkFilterQuality FilterQuality() const { return filter_quality_; } + const CanvasColorParams& ColorParams() const { return color_params_; } private: // Sync token that was provided when resource was released gpu::SyncToken sync_token_for_release_; base::WeakPtr<CanvasResourceProvider> provider_; SkFilterQuality filter_quality_; + CanvasColorParams color_params_; }; // Resource type for skia Bitmaps (RAM and texture backed) -class PLATFORM_EXPORT CanvasResource_Bitmap final : public CanvasResource { +class PLATFORM_EXPORT CanvasResourceBitmap final : public CanvasResource { public: - static scoped_refptr<CanvasResource_Bitmap> Create( + static scoped_refptr<CanvasResourceBitmap> Create( scoped_refptr<StaticBitmapImage>, base::WeakPtr<CanvasResourceProvider>, - SkFilterQuality); - virtual ~CanvasResource_Bitmap() { Abandon(); } + SkFilterQuality, + const CanvasColorParams&); + ~CanvasResourceBitmap() override { Abandon(); } // Not recyclable: Skia handles texture recycling internally and bitmaps are // cheap to allocate. bool IsRecycleable() const final { return false; } + bool IsAccelerated() const final; bool IsValid() const final; void Abandon() final { TearDown(); } IntSize Size() const final; + bool IsBitmap() final; + scoped_refptr<StaticBitmapImage> Bitmap() final; + scoped_refptr<CanvasResource> MakeAccelerated( + base::WeakPtr<WebGraphicsContext3DProviderWrapper>) final; + scoped_refptr<CanvasResource> MakeUnaccelerated() final; private: void TearDown(); @@ -100,26 +118,38 @@ class PLATFORM_EXPORT CanvasResource_Bitmap final : public CanvasResource { bool HasGpuMailbox() const override; const gpu::SyncToken& GetSyncToken() override; - CanvasResource_Bitmap(scoped_refptr<StaticBitmapImage>, - base::WeakPtr<CanvasResourceProvider>, - SkFilterQuality); + CanvasResourceBitmap(scoped_refptr<StaticBitmapImage>, + base::WeakPtr<CanvasResourceProvider>, + SkFilterQuality, + const CanvasColorParams&); scoped_refptr<StaticBitmapImage> image_; }; // Resource type for GpuMemoryBuffers -class PLATFORM_EXPORT CanvasResource_GpuMemoryBuffer final +class PLATFORM_EXPORT CanvasResourceGpuMemoryBuffer final : public CanvasResource { public: - static scoped_refptr<CanvasResource_GpuMemoryBuffer> Create( + static scoped_refptr<CanvasResourceGpuMemoryBuffer> Create( const IntSize&, const CanvasColorParams&, base::WeakPtr<WebGraphicsContext3DProviderWrapper>, base::WeakPtr<CanvasResourceProvider>, SkFilterQuality); - virtual ~CanvasResource_GpuMemoryBuffer(); + ~CanvasResourceGpuMemoryBuffer() override; bool IsRecycleable() const final { return IsValid(); } - bool IsValid() const { return context_provider_wrapper_ && image_id_; } + bool IsAccelerated() const final { return true; } + bool IsValid() const override { + return context_provider_wrapper_ && image_id_; + } + scoped_refptr<CanvasResource> MakeAccelerated( + base::WeakPtr<WebGraphicsContext3DProviderWrapper>) final { + return base::WrapRefCounted(this); + }; + scoped_refptr<CanvasResource> MakeUnaccelerated() final { + NOTREACHED(); + return nullptr; + } void Abandon() final { TearDown(); } IntSize Size() const final; @@ -136,7 +166,7 @@ class PLATFORM_EXPORT CanvasResource_GpuMemoryBuffer final GLenum format, GLenum type) override; - CanvasResource_GpuMemoryBuffer( + CanvasResourceGpuMemoryBuffer( const IntSize&, const CanvasColorParams&, base::WeakPtr<WebGraphicsContext3DProviderWrapper>, diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h index d3bf9280122..a4518f8155a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h +++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_host.h @@ -13,7 +13,7 @@ namespace blink { class PLATFORM_EXPORT CanvasResourceHost { public: virtual ~CanvasResourceHost() = default; - virtual void NotifySurfaceInvalid() = 0; + virtual void NotifyGpuContextLost() = 0; virtual void SetNeedsCompositingUpdate() = 0; virtual void RestoreCanvasMatrixClipStack(PaintCanvas*) const = 0; virtual void UpdateMemoryUsage() = 0; 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 9c2c36925f7..e62cc06d337 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 @@ -9,10 +9,10 @@ #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" -#include "skia/ext/texture_handle.h" +#include "gpu/config/gpu_driver_bug_workaround_type.h" +#include "gpu/config/gpu_feature_info.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/canvas_resource.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/runtime_enabled_features.h" @@ -23,15 +23,15 @@ namespace blink { -// CanvasResourceProvider_Texture +// CanvasResourceProviderTexture //============================================================================== // // * Renders to a texture managed by skia. Mailboxes are straight GL textures. // * Layers are not overlay candidates -class CanvasResourceProvider_Texture : public CanvasResourceProvider { +class CanvasResourceProviderTexture : public CanvasResourceProvider { public: - CanvasResourceProvider_Texture( + CanvasResourceProviderTexture( const IntSize& size, unsigned msaa_sample_count, const CanvasColorParams color_params, @@ -42,16 +42,20 @@ class CanvasResourceProvider_Texture : public CanvasResourceProvider { std::move(context_provider_wrapper)), msaa_sample_count_(msaa_sample_count) {} - virtual ~CanvasResourceProvider_Texture() = default; + ~CanvasResourceProviderTexture() override = default; bool IsValid() const final { return GetSkSurface() && !IsGpuContextLost(); } bool IsAccelerated() const final { return true; } GLuint GetBackingTextureHandleForOverwrite() override { - return skia::GrBackendObjectToGrGLTextureInfo( - GetSkSurface()->getTextureHandle( - SkSurface::kDiscardWrite_TextureHandleAccess)) - ->fID; + GrBackendTexture backend_texture = GetSkSurface()->getBackendTexture( + SkSurface::kDiscardWrite_TextureHandleAccess); + if (!backend_texture.isValid()) + return 0; + GrGLTextureInfo info; + if (!backend_texture.getGLTextureInfo(&info)) + return 0; + return info.fID; } protected: @@ -61,7 +65,7 @@ class CanvasResourceProvider_Texture : public CanvasResourceProvider { if (IsGpuContextLost()) return nullptr; - auto gl = ContextGL(); + auto* gl = ContextGL(); DCHECK(gl); if (ContextProviderWrapper() @@ -88,18 +92,18 @@ class CanvasResourceProvider_Texture : public CanvasResourceProvider { scoped_refptr<StaticBitmapImage> image = StaticBitmapImage::Create(skia_image, ContextProviderWrapper()); - scoped_refptr<CanvasResource> resource = - CanvasResource_Bitmap::Create(image, CreateWeakPtr(), FilterQuality()); + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( + image, CreateWeakPtr(), FilterQuality(), ColorParams()); if (!resource) return nullptr; return resource; } - virtual sk_sp<SkSurface> CreateSkSurface() const { + sk_sp<SkSurface> CreateSkSurface() const override { if (IsGpuContextLost()) return nullptr; - auto gr = GetGrContext(); + auto* gr = GetGrContext(); DCHECK(gr); SkImageInfo info = SkImageInfo::Make( @@ -110,35 +114,35 @@ class CanvasResourceProvider_Texture : public CanvasResourceProvider { ColorParams().GetSkSurfaceProps()); } - unsigned msaa_sample_count_; + const unsigned msaa_sample_count_; }; -// CanvasResourceProvider_Texture_GpuMemoryBuffer +// CanvasResourceProviderTextureGpuMemoryBuffer //============================================================================== // // * Renders to a texture managed by skia. Mailboxes are // gpu-accelerated platform native surfaces. // * Layers are overlay candidates -class CanvasResourceProvider_Texture_GpuMemoryBuffer final - : public CanvasResourceProvider_Texture { +class CanvasResourceProviderTextureGpuMemoryBuffer final + : public CanvasResourceProviderTexture { public: - CanvasResourceProvider_Texture_GpuMemoryBuffer( + CanvasResourceProviderTextureGpuMemoryBuffer( const IntSize& size, unsigned msaa_sample_count, const CanvasColorParams color_params, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper) - : CanvasResourceProvider_Texture(size, - msaa_sample_count, - color_params, - std::move(context_provider_wrapper)) {} + : CanvasResourceProviderTexture(size, + msaa_sample_count, + color_params, + std::move(context_provider_wrapper)) {} - virtual ~CanvasResourceProvider_Texture_GpuMemoryBuffer() = default; + ~CanvasResourceProviderTextureGpuMemoryBuffer() override = default; - protected: + private: scoped_refptr<CanvasResource> CreateResource() final { - return CanvasResource_GpuMemoryBuffer::Create( + return CanvasResourceGpuMemoryBuffer::Create( Size(), ColorParams(), ContextProviderWrapper(), CreateWeakPtr(), FilterQuality()); } @@ -152,7 +156,7 @@ class CanvasResourceProvider_Texture_GpuMemoryBuffer final scoped_refptr<CanvasResource> output_resource = NewOrRecycledResource(); if (!output_resource) { // GpuMemoryBuffer creation failed, fallback to Texture resource - return CanvasResourceProvider_Texture::ProduceFrame(); + return CanvasResourceProviderTexture::ProduceFrame(); } sk_sp<SkImage> image = GetSkSurface()->makeImageSnapshot(); @@ -160,33 +164,66 @@ class CanvasResourceProvider_Texture_GpuMemoryBuffer final return nullptr; DCHECK(image->isTextureBacked()); - GLuint skia_texture_id = - skia::GrBackendObjectToGrGLTextureInfo(image->getTextureHandle(true)) - ->fID; + GrBackendTexture backend_texture = image->getBackendTexture(true); + DCHECK(backend_texture.isValid()); + + GrGLTextureInfo info; + if (!backend_texture.getGLTextureInfo(&info)) + return nullptr; + GLuint skia_texture_id = info.fID; output_resource->CopyFromTexture(skia_texture_id, ColorParams().GLInternalFormat(), ColorParams().GLType()); return output_resource; } + + void RecycleResource(scoped_refptr<CanvasResource> resource) override { + DCHECK(resource->HasOneRef()); + if (resource_recycling_enabled_) + recycled_resources_.push_back(std::move(resource)); + } + + void SetResourceRecyclingEnabled(bool value) override { + resource_recycling_enabled_ = value; + if (!resource_recycling_enabled_) + ClearRecycledResources(); + } + + void ClearRecycledResources() { recycled_resources_.clear(); } + + scoped_refptr<CanvasResource> NewOrRecycledResource() { + if (recycled_resources_.size()) { + scoped_refptr<CanvasResource> resource = + std::move(recycled_resources_.back()); + recycled_resources_.pop_back(); + // Recycling implies releasing the old content + resource->WaitSyncTokenBeforeRelease(); + return resource; + } + return CreateResource(); + } + + WTF::Vector<scoped_refptr<CanvasResource>> recycled_resources_; + bool resource_recycling_enabled_ = true; }; -// CanvasResourceProvider_Bitmap +// CanvasResourceProviderBitmap //============================================================================== // // * Renders to a skia RAM-backed bitmap // * Mailboxing is not supported : cannot be directly composited -class CanvasResourceProvider_Bitmap final : public CanvasResourceProvider { +class CanvasResourceProviderBitmap final : public CanvasResourceProvider { public: - CanvasResourceProvider_Bitmap(const IntSize& size, - const CanvasColorParams color_params) + CanvasResourceProviderBitmap(const IntSize& size, + const CanvasColorParams color_params) : CanvasResourceProvider(size, color_params, nullptr /*context_provider_wrapper*/) {} - ~CanvasResourceProvider_Bitmap() = default; + ~CanvasResourceProviderBitmap() override = default; bool IsValid() const final { return GetSkSurface(); } bool IsAccelerated() const final { return false; } @@ -203,8 +240,6 @@ class CanvasResourceProvider_Bitmap final : public CanvasResourceProvider { kPremul_SkAlphaType, ColorParams().GetSkColorSpaceForSkSurfaces()); return SkSurface::MakeRaster(info, ColorParams().GetSkSurfaceProps()); } - - sk_sp<SkSurface> surface_; }; // CanvasResourceProvider base class implementation @@ -266,35 +301,34 @@ std::unique_ptr<CanvasResourceProvider> CanvasResourceProvider::Create( switch (resource_type_fallback_list[i]) { case kTextureGpuMemoryBufferResourceType: DCHECK(SharedGpuContext::IsGpuCompositingEnabled()); - if (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) { - if (!gpu::IsImageFromGpuMemoryBufferFormatSupported( - colorParams.GetBufferFormat(), - context_provider_wrapper->ContextProvider() - ->GetCapabilities())) - continue; - if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat( - gfx::Size(size), colorParams.GetBufferFormat())) - continue; - DCHECK(gpu::IsImageFormatCompatibleWithGpuMemoryBufferFormat( - colorParams.GLInternalFormat(), colorParams.GetBufferFormat())); - - provider = - std::make_unique<CanvasResourceProvider_Texture_GpuMemoryBuffer>( - size, msaa_sample_count, colorParams, - context_provider_wrapper); + if (!RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) + break; + + if (!gpu::IsImageFromGpuMemoryBufferFormatSupported( + colorParams.GetBufferFormat(), + context_provider_wrapper->ContextProvider() + ->GetCapabilities())) { + continue; + } + if (!gpu::IsImageSizeValidForGpuMemoryBufferFormat( + gfx::Size(size), colorParams.GetBufferFormat())) { + continue; } + DCHECK(gpu::IsImageFormatCompatibleWithGpuMemoryBufferFormat( + colorParams.GLInternalFormat(), colorParams.GetBufferFormat())); + + provider = + std::make_unique<CanvasResourceProviderTextureGpuMemoryBuffer>( + size, msaa_sample_count, colorParams, context_provider_wrapper); break; case kTextureResourceType: - // TODO(xlai): Check gpu acclereration mode before using this Resource - // Type of CanvasResourceProvider and then Add - // "DCHECK(SharedGpuContext::IsGpuCompositingEnabled());" here. - // See crbug.com/802053. - provider = std::make_unique<CanvasResourceProvider_Texture>( + DCHECK(SharedGpuContext::IsGpuCompositingEnabled()); + provider = std::make_unique<CanvasResourceProviderTexture>( size, msaa_sample_count, colorParams, context_provider_wrapper); break; case kBitmapResourceType: provider = - std::make_unique<CanvasResourceProvider_Bitmap>(size, colorParams); + std::make_unique<CanvasResourceProviderBitmap>(size, colorParams); break; } if (provider && provider->IsValid()) @@ -348,11 +382,11 @@ CanvasResourceProvider::CanvasResourceProvider( const IntSize& size, const CanvasColorParams& color_params, base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper) - : weak_ptr_factory_(this), - context_provider_wrapper_(std::move(context_provider_wrapper)), + : context_provider_wrapper_(std::move(context_provider_wrapper)), size_(size), color_params_(color_params), - snapshot_paint_image_id_(cc::PaintImage::GetNextId()) { + snapshot_paint_image_id_(cc::PaintImage::GetNextId()), + weak_ptr_factory_(this) { if (context_provider_wrapper_) context_provider_wrapper_->AddObserver(this); } @@ -363,9 +397,8 @@ CanvasResourceProvider::~CanvasResourceProvider() { } SkSurface* CanvasResourceProvider::GetSkSurface() const { - if (!surface_) { + if (!surface_) surface_ = CreateSkSurface(); - } return surface_.get(); } @@ -373,15 +406,20 @@ PaintCanvas* CanvasResourceProvider::Canvas() { if (!canvas_) { DCHECK(!canvas_image_provider_); - cc::ImageProvider* image_provider = nullptr; - if (ImageDecodeCache()) { - canvas_image_provider_.emplace(ImageDecodeCache(), - ColorParams().GetStorageGfxColorSpace()); - image_provider = &*canvas_image_provider_; - } + gfx::ColorSpace target_color_space = + ColorParams().NeedsSkColorSpaceXformCanvas() + ? ColorParams().GetStorageGfxColorSpace() + : gfx::ColorSpace::CreateSRGB(); + + canvas_image_provider_.emplace(ImageDecodeCache(), target_color_space); + cc::ImageProvider* image_provider = &*canvas_image_provider_; cc::SkiaPaintCanvas::ContextFlushes context_flushes; - if (IsAccelerated()) { + if (IsAccelerated() && + !ContextProviderWrapper() + ->ContextProvider() + ->GetGpuFeatureInfo() + .IsWorkaroundEnabled(gpu::DISABLE_2D_CANVAS_AUTO_FLUSH)) { context_flushes.enable = CanvasHeuristicParameters::kEnableGrContextFlushes; context_flushes.max_draws_before_flush = @@ -390,11 +428,10 @@ PaintCanvas* CanvasResourceProvider::Canvas() { if (ColorParams().NeedsSkColorSpaceXformCanvas()) { canvas_ = std::make_unique<cc::SkiaPaintCanvas>( GetSkSurface()->getCanvas(), ColorParams().GetSkColorSpace(), - std::move(image_provider), context_flushes); + image_provider, context_flushes); } else { canvas_ = std::make_unique<cc::SkiaPaintCanvas>( - GetSkSurface()->getCanvas(), std::move(image_provider), - context_flushes); + GetSkSurface()->getCanvas(), image_provider, context_flushes); } } @@ -459,33 +496,13 @@ void CanvasResourceProvider::FlushSkia() const { GetSkSurface()->flush(); } -void CanvasResourceProvider::RecycleResource( - scoped_refptr<CanvasResource> resource) { - DCHECK(resource->HasOneRef()); - if (resource_recycling_enabled_) - recycled_resources_.push_back(std::move(resource)); -} - -void CanvasResourceProvider::SetResourceRecyclingEnabled(bool value) { - resource_recycling_enabled_ = value; - if (!resource_recycling_enabled_) - ClearRecycledResources(); -} - -scoped_refptr<CanvasResource> CanvasResourceProvider::NewOrRecycledResource() { - if (recycled_resources_.size()) { - scoped_refptr<CanvasResource> resource = - std::move(recycled_resources_.back()); - recycled_resources_.pop_back(); - // Recycling implies releasing the old content - resource->WaitSyncTokenBeforeRelease(); - return resource; - } - return CreateResource(); +void CanvasResourceProvider::RecycleResource(scoped_refptr<CanvasResource>) { + // To be implemented in subclasses that use resource recycling. + NOTREACHED(); } bool CanvasResourceProvider::IsGpuContextLost() const { - auto gl = ContextGL(); + auto* gl = ContextGL(); return !gl || gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR; } @@ -504,15 +521,10 @@ void CanvasResourceProvider::Clear() { // if this wasn't required, but the canvas is currently filled with the magic // transparency color. Can we have another way to manage this? DCHECK(IsValid()); - if (color_params_.GetOpacityMode() == kOpaque) { + if (color_params_.GetOpacityMode() == kOpaque) Canvas()->clear(SK_ColorBLACK); - } else { + else Canvas()->clear(SK_ColorTRANSPARENT); - } -} - -void CanvasResourceProvider::ClearRecycledResources() { - recycled_resources_.clear(); } void CanvasResourceProvider::InvalidateSurface() { @@ -533,10 +545,9 @@ scoped_refptr<CanvasResource> CanvasResourceProvider::CreateResource() { } cc::ImageDecodeCache* CanvasResourceProvider::ImageDecodeCache() { - // TODO(khushalsagar): Hook up a software cache. - if (!context_provider_wrapper_) - return nullptr; - return context_provider_wrapper_->ContextProvider()->ImageDecodeCache(); + if (context_provider_wrapper_) + return context_provider_wrapper_->ContextProvider()->ImageDecodeCache(); + return &Image::SharedCCDecodeCache(); } } // 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 24c56c7c690..c68faf8cf55 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 @@ -7,13 +7,14 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "cc/paint/skia_paint_canvas.h" #include "cc/raster/playback_image_provider.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" +#include "third_party/blink/renderer/platform/graphics/canvas_resource.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/khronos/GLES2/gl2.h" @@ -37,7 +38,6 @@ class GLES2Interface; namespace blink { -class CanvasResource; class StaticBitmapImage; class WebGraphicsContext3DProviderWrapper; @@ -93,9 +93,10 @@ class PLATFORM_EXPORT CanvasResourceProvider virtual bool IsValid() const = 0; virtual bool IsAccelerated() const = 0; uint32_t ContentUniqueID() const; - void ClearRecycledResources(); - void RecycleResource(scoped_refptr<CanvasResource>); - void SetResourceRecyclingEnabled(bool); + + virtual void RecycleResource(scoped_refptr<CanvasResource>); + virtual void SetResourceRecyclingEnabled(bool) {} + SkSurface* GetSkSurface() const; bool IsGpuContextLost() const; bool WritePixels(const SkImageInfo& orig_info, @@ -116,7 +117,6 @@ class PLATFORM_EXPORT CanvasResourceProvider base::WeakPtr<WebGraphicsContext3DProviderWrapper> ContextProviderWrapper() { return context_provider_wrapper_; } - scoped_refptr<CanvasResource> NewOrRecycledResource(); SkFilterQuality FilterQuality() const { return filter_quality_; } base::WeakPtr<CanvasResourceProvider> CreateWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); @@ -153,22 +153,21 @@ class PLATFORM_EXPORT CanvasResourceProvider virtual scoped_refptr<CanvasResource> CreateResource(); cc::ImageDecodeCache* ImageDecodeCache(); - base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_; base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper_; IntSize size_; CanvasColorParams color_params_; - Optional<CanvasImageProvider> canvas_image_provider_; + base::Optional<CanvasImageProvider> canvas_image_provider_; std::unique_ptr<cc::SkiaPaintCanvas> canvas_; mutable sk_sp<SkSurface> surface_; // mutable for lazy init std::unique_ptr<SkCanvas> xform_canvas_; - WTF::Vector<scoped_refptr<CanvasResource>> recycled_resources_; SkFilterQuality filter_quality_; - bool resource_recycling_enabled_ = true; const cc::PaintImage::Id snapshot_paint_image_id_; cc::PaintImage::ContentId snapshot_paint_image_content_id_ = cc::PaintImage::kInvalidContentId; uint32_t snapshot_sk_image_id_ = 0u; + + base::WeakPtrFactory<CanvasResourceProvider> weak_ptr_factory_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc index 7c1a70c0db5..a042c27bfcf 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/canvas_resource_test.cc @@ -6,6 +6,7 @@ #include "base/run_loop.h" #include "components/viz/test/test_gpu_memory_buffer_manager.h" +#include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" @@ -31,6 +32,7 @@ class MockGLES2InterfaceWithMailboxSupport : public FakeGLES2Interface { MOCK_METHOD1(GenUnverifiedSyncTokenCHROMIUM, void(GLbyte*)); MOCK_METHOD4(CreateImageCHROMIUM, GLuint(ClientBuffer, GLsizei, GLsizei, GLenum)); + MOCK_METHOD2(BindTexture, void(GLenum, GLuint)); }; class FakeCanvasResourcePlatformSupport : public TestingPlatformSupport { @@ -80,6 +82,7 @@ gpu::SyncToken GenTestSyncToken(int id) { } TEST_F(CanvasResourceTest, SkiaResourceNoMailboxLeak) { + testing::InSequence s; SkImageInfo image_info = SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); sk_sp<SkSurface> surface = @@ -88,10 +91,10 @@ TEST_F(CanvasResourceTest, SkiaResourceNoMailboxLeak) { testing::Mock::VerifyAndClearExpectations(&gl_); EXPECT_TRUE(!!context_provider_wrapper_); - scoped_refptr<CanvasResource> resource = CanvasResource_Bitmap::Create( + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( StaticBitmapImage::Create(surface->makeImageSnapshot(), context_provider_wrapper_), - nullptr, kLow_SkFilterQuality); + nullptr, kLow_SkFilterQuality, CanvasColorParams()); testing::Mock::VerifyAndClearExpectations(&gl_); @@ -100,6 +103,9 @@ TEST_F(CanvasResourceTest, SkiaResourceNoMailboxLeak) { EXPECT_CALL(gl_, GenMailboxCHROMIUM(_)) .WillOnce(SetArrayArgument<0>( test_mailbox.name, test_mailbox.name + GL_MAILBOX_SIZE_CHROMIUM)); + EXPECT_CALL(gl_, BindTexture(GL_TEXTURE_2D, _)).Times(2); + EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, _)); + EXPECT_CALL(gl_, GenUnverifiedSyncTokenCHROMIUM(_)); resource->GetOrCreateGpuMailbox(); testing::Mock::VerifyAndClearExpectations(&gl_); @@ -124,12 +130,14 @@ TEST_F(CanvasResourceTest, SkiaResourceNoMailboxLeak) { } TEST_F(CanvasResourceTest, GpuMemoryBufferSyncTokenRefresh) { + testing::InSequence s; ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; constexpr GLuint image_id = 1; EXPECT_CALL(gl_, CreateImageCHROMIUM(_, _, _, _)).WillOnce(Return(image_id)); + EXPECT_CALL(gl_, BindTexture(gpu::GetPlatformSpecificTextureTarget(), _)); scoped_refptr<CanvasResource> resource = - CanvasResource_GpuMemoryBuffer::Create( + CanvasResourceGpuMemoryBuffer::Create( IntSize(10, 10), CanvasColorParams(), SharedGpuContext::ContextProviderWrapper(), nullptr, // Resource provider @@ -144,6 +152,7 @@ TEST_F(CanvasResourceTest, GpuMemoryBufferSyncTokenRefresh) { EXPECT_CALL(gl_, GenMailboxCHROMIUM(_)) .WillOnce(SetArrayArgument<0>( test_mailbox.name, test_mailbox.name + GL_MAILBOX_SIZE_CHROMIUM)); + EXPECT_CALL(gl_, ProduceTextureDirectCHROMIUM(_, _)); resource->GetOrCreateGpuMailbox(); testing::Mock::VerifyAndClearExpectations(&gl_); @@ -185,4 +194,103 @@ TEST_F(CanvasResourceTest, GpuMemoryBufferSyncTokenRefresh) { testing::Mock::VerifyAndClearExpectations(&gl_); } +TEST_F(CanvasResourceTest, MakeAcceleratedFromAcceleratedResourceIsNoOp) { + ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + + SkImageInfo image_info = + SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); + sk_sp<SkSurface> surface = + SkSurface::MakeRenderTarget(GetGrContext(), SkBudgeted::kYes, image_info); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_TRUE(!!context_provider_wrapper_); + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( + StaticBitmapImage::Create(surface->makeImageSnapshot(), + context_provider_wrapper_), + nullptr, kLow_SkFilterQuality, CanvasColorParams()); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_TRUE(resource->IsAccelerated()); + scoped_refptr<CanvasResource> new_resource = + resource->MakeAccelerated(context_provider_wrapper_); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_EQ(new_resource.get(), resource.get()); + EXPECT_TRUE(new_resource->IsAccelerated()); +} + +TEST_F(CanvasResourceTest, MakeAcceleratedFromRasterResource) { + ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + + SkImageInfo image_info = + SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); + sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info); + + EXPECT_TRUE(!!context_provider_wrapper_); + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( + StaticBitmapImage::Create(surface->makeImageSnapshot(), + context_provider_wrapper_), + nullptr, kLow_SkFilterQuality, CanvasColorParams()); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_FALSE(resource->IsAccelerated()); + scoped_refptr<CanvasResource> new_resource = + resource->MakeAccelerated(context_provider_wrapper_); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_NE(new_resource.get(), resource.get()); + EXPECT_FALSE(resource->IsAccelerated()); + EXPECT_TRUE(new_resource->IsAccelerated()); +} + +TEST_F(CanvasResourceTest, MakeUnacceleratedFromUnacceleratedResourceIsNoOp) { + ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + + SkImageInfo image_info = + SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); + sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info); + + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( + StaticBitmapImage::Create(surface->makeImageSnapshot(), + context_provider_wrapper_), + nullptr, kLow_SkFilterQuality, CanvasColorParams()); + + EXPECT_FALSE(resource->IsAccelerated()); + scoped_refptr<CanvasResource> new_resource = resource->MakeUnaccelerated(); + + EXPECT_EQ(new_resource.get(), resource.get()); + EXPECT_FALSE(new_resource->IsAccelerated()); +} + +TEST_F(CanvasResourceTest, MakeUnacceleratedFromAcceleratedResource) { + ScopedTestingPlatformSupport<FakeCanvasResourcePlatformSupport> platform; + + SkImageInfo image_info = + SkImageInfo::MakeN32(10, 10, kPremul_SkAlphaType, nullptr); + sk_sp<SkSurface> surface = + SkSurface::MakeRenderTarget(GetGrContext(), SkBudgeted::kYes, image_info); + + EXPECT_TRUE(!!context_provider_wrapper_); + scoped_refptr<CanvasResource> resource = CanvasResourceBitmap::Create( + StaticBitmapImage::Create(surface->makeImageSnapshot(), + context_provider_wrapper_), + nullptr, kLow_SkFilterQuality, CanvasColorParams()); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_TRUE(resource->IsAccelerated()); + scoped_refptr<CanvasResource> new_resource = resource->MakeUnaccelerated(); + + testing::Mock::VerifyAndClearExpectations(&gl_); + + EXPECT_NE(new_resource.get(), resource.get()); + EXPECT_TRUE(resource->IsAccelerated()); + EXPECT_FALSE(new_resource->IsAccelerated()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc index a38fc0d3a53..736049dc555 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.cc @@ -5,7 +5,7 @@ #include "third_party/blink/renderer/platform/graphics/color_space_gamut.h" #include "third_party/blink/public/platform/web_screen_info.h" -#include "third_party/skia/include/core/SkColorSpaceXform.h" +#include "third_party/skia/third_party/skcms/skcms.h" namespace blink { @@ -17,30 +17,27 @@ ColorSpaceGamut GetColorSpaceGamut(const WebScreenInfo& screen_info) { return ColorSpaceGamut::kUnknown; // Return the gamut of the color space used for raster (this will return a // wide gamut for HDR profiles). - return ColorSpaceUtilities::GetColorSpaceGamut( - color_space.GetRasterColorSpace().ToSkColorSpace().get()); + skcms_ICCProfile color_profile; + color_space.GetRasterColorSpace().ToSkColorSpace()->toProfile(&color_profile); + return ColorSpaceUtilities::GetColorSpaceGamut(&color_profile); } -ColorSpaceGamut GetColorSpaceGamut(SkColorSpace* color_space) { - sk_sp<SkColorSpace> sc_rgb(SkColorSpace::MakeSRGBLinear()); - std::unique_ptr<SkColorSpaceXform> transform( - SkColorSpaceXform::New(color_space, sc_rgb.get())); - - if (!transform) +ColorSpaceGamut GetColorSpaceGamut(const skcms_ICCProfile* color_profile) { + if (!color_profile) return ColorSpaceGamut::kUnknown; - unsigned char in[3][4]; - float out[3][4]; + skcms_ICCProfile sc_rgb = *skcms_sRGB_profile(); + skcms_SetTransferFunction(&sc_rgb, skcms_Identity_TransferFunction()); + + unsigned char in[3][3]; + float out[3][3]; memset(in, 0, sizeof(in)); in[0][0] = 255; in[1][1] = 255; in[2][2] = 255; - in[0][3] = 255; - in[1][3] = 255; - in[2][3] = 255; - bool color_converison_successful = transform->apply( - SkColorSpaceXform::kRGBA_F32_ColorFormat, out, - SkColorSpaceXform::kRGBA_8888_ColorFormat, in, 3, kOpaque_SkAlphaType); + bool color_converison_successful = skcms_Transform( + in, skcms_PixelFormat_RGB_888, skcms_AlphaFormat_Opaque, color_profile, + out, skcms_PixelFormat_RGB_fff, skcms_AlphaFormat_Opaque, &sc_rgb, 3); DCHECK(color_converison_successful); float score = out[0][0] * out[1][1] * out[2][2]; diff --git a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.h b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.h index c935be809f1..20502a1a086 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.h +++ b/chromium/third_party/blink/renderer/platform/graphics/color_space_gamut.h @@ -7,7 +7,7 @@ #include "third_party/blink/renderer/platform/platform_export.h" -class SkColorSpace; +struct skcms_ICCProfile; namespace blink { @@ -32,7 +32,7 @@ enum class ColorSpaceGamut { namespace ColorSpaceUtilities { PLATFORM_EXPORT ColorSpaceGamut GetColorSpaceGamut(const WebScreenInfo&); -ColorSpaceGamut GetColorSpaceGamut(SkColorSpace*); +ColorSpaceGamut GetColorSpaceGamut(const skcms_ICCProfile*); } // namespace ColorSpaceUtilities diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.cc index 92f49af1a99..70f2a599430 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.cc @@ -12,8 +12,7 @@ namespace blink { void ChunkToLayerMapper::SwitchToChunk(const PaintChunk& chunk) { outset_for_raster_effects_ = chunk.outset_for_raster_effects; - const auto& new_chunk_state = - chunk.properties.property_tree_state.GetPropertyTreeState(); + const auto& new_chunk_state = chunk.properties.GetPropertyTreeState(); if (new_chunk_state == chunk_state_) return; diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc index 4e92ff1b554..96707191331 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper_test.cc @@ -4,11 +4,12 @@ #include "third_party/blink/renderer/platform/graphics/compositing/chunk_to_layer_mapper.h" +#include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" #include "third_party/blink/renderer/platform/testing/fake_display_item_client.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" +#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" namespace blink { @@ -17,9 +18,9 @@ class ChunkToLayerMapperTest : public testing::Test { static PaintChunk Chunk(const PropertyTreeState& state) { DEFINE_STATIC_LOCAL(FakeDisplayItemClient, fake_client, ()); DEFINE_STATIC_LOCAL( - Optional<PaintChunk::Id>, id, + base::Optional<PaintChunk::Id>, id, (PaintChunk::Id(fake_client, DisplayItem::kDrawingFirst))); - PaintChunk chunk(0, 0, *id, PaintChunkProperties(state)); + PaintChunk chunk(0, 0, *id, state); return chunk; } @@ -28,19 +29,19 @@ class ChunkToLayerMapperTest : public testing::Test { PropertyTreeState LayerState() { DEFINE_STATIC_REF( TransformPaintPropertyNode, transform, - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(123, 456), FloatPoint3D(1, 2, 3))); - DEFINE_STATIC_REF( - ClipPaintPropertyNode, clip, - ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), transform, - FloatRoundedRect(12, 34, 56, 78))); + CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(123, 456), + FloatPoint3D(1, 2, 3))); + DEFINE_STATIC_REF(ClipPaintPropertyNode, clip, + CreateClip(ClipPaintPropertyNode::Root(), transform, + FloatRoundedRect(12, 34, 56, 78))); DEFINE_STATIC_REF( EffectPaintPropertyNode, effect, EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), transform, clip, - kColorFilterLuminanceToAlpha, CompositorFilterOperations(), 0.789f, - SkBlendMode::kSrcIn)); + EffectPaintPropertyNode::Root(), + EffectPaintPropertyNode::State{ + transform, clip, kColorFilterLuminanceToAlpha, + CompositorFilterOperations(), 0.789f, SkBlendMode::kSrcIn})); return PropertyTreeState(transform, clip, effect); } @@ -91,13 +92,11 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkUsingLayerState) { TEST_F(ChunkToLayerMapperTest, TwoChunkSameState) { ChunkToLayerMapper mapper(LayerState(), gfx::Vector2dF(10, 20)); - auto transform = TransformPaintPropertyNode::Create( - LayerState().Transform(), TransformationMatrix().Scale(2), - FloatPoint3D()); - auto clip = ClipPaintPropertyNode::Create(LayerState().Clip(), - LayerState().Transform(), - FloatRoundedRect(10, 10, 100, 100)); - auto effect = LayerState().Effect(); + auto transform = CreateTransform(LayerState().Transform(), + TransformationMatrix().Scale(2)); + auto clip = CreateClip(LayerState().Clip(), LayerState().Transform(), + FloatRoundedRect(10, 10, 100, 100)); + auto* effect = LayerState().Effect(); auto chunk1 = Chunk(PropertyTreeState(transform.get(), clip.get(), effect)); auto chunk2 = Chunk(PropertyTreeState(transform.get(), clip.get(), effect)); @@ -124,19 +123,17 @@ TEST_F(ChunkToLayerMapperTest, TwoChunkSameState) { TEST_F(ChunkToLayerMapperTest, TwoChunkDifferentState) { ChunkToLayerMapper mapper(LayerState(), gfx::Vector2dF(10, 20)); - auto transform1 = TransformPaintPropertyNode::Create( - LayerState().Transform(), TransformationMatrix().Scale(2), - FloatPoint3D()); - auto clip1 = ClipPaintPropertyNode::Create( - LayerState().Clip(), LayerState().Transform(), - FloatRoundedRect(10, 10, 100, 100)); - auto effect = LayerState().Effect(); + auto transform1 = CreateTransform(LayerState().Transform(), + TransformationMatrix().Scale(2)); + auto clip1 = CreateClip(LayerState().Clip(), LayerState().Transform(), + FloatRoundedRect(10, 10, 100, 100)); + auto* effect = LayerState().Effect(); auto chunk1 = Chunk(PropertyTreeState(transform1.get(), clip1.get(), effect)); - auto transform2 = TransformPaintPropertyNode::Create( - transform1, TransformationMatrix().Translate(20, 30), FloatPoint3D()); - auto clip2 = ClipPaintPropertyNode::Create(LayerState().Clip(), transform2, - FloatRoundedRect(0, 0, 20, 20)); + auto transform2 = + CreateTransform(transform1, TransformationMatrix().Translate(20, 30)); + auto clip2 = CreateClip(LayerState().Clip(), transform2, + FloatRoundedRect(0, 0, 20, 20)); auto chunk2 = Chunk(PropertyTreeState(transform2.get(), clip2.get(), effect)); mapper.SwitchToChunk(chunk1); @@ -168,17 +165,13 @@ TEST_F(ChunkToLayerMapperTest, SlowPath) { // Chunk2 has a blur filter. Should use the slow path. CompositorFilterOperations filter2; filter2.AppendBlurFilter(20); - auto effect2 = EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), LayerState().Transform(), - LayerState().Clip(), kColorFilterNone, filter2, 1.f, SkBlendMode::kDstIn); + auto effect2 = CreateFilterEffect(LayerState().Effect(), std::move(filter2)); auto chunk2 = Chunk(PropertyTreeState(LayerState().Transform(), LayerState().Clip(), effect2.get())); // Chunk3 has a different effect which inherits from chunk2's effect. // Should use the slow path. - auto effect3 = EffectPaintPropertyNode::Create( - effect2.get(), LayerState().Transform(), LayerState().Clip(), - kColorFilterNone, CompositorFilterOperations(), 1.f, SkBlendMode::kDstIn); + auto effect3 = CreateOpacityEffect(effect2, 1.f); auto chunk3 = Chunk(PropertyTreeState(LayerState().Transform(), LayerState().Clip(), effect3.get())); @@ -186,9 +179,7 @@ TEST_F(ChunkToLayerMapperTest, SlowPath) { // Should use the fast path. CompositorFilterOperations filter4; filter4.AppendOpacityFilter(0.5); - auto effect4 = EffectPaintPropertyNode::Create( - LayerState().Effect(), LayerState().Transform(), LayerState().Clip(), - kColorFilterNone, CompositorFilterOperations(), 1.f, SkBlendMode::kDstIn); + auto effect4 = CreateFilterEffect(LayerState().Effect(), std::move(filter4)); auto chunk4 = Chunk(PropertyTreeState(LayerState().Transform(), LayerState().Clip(), effect4.get())); diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.cc index 33942364fc2..f6df3bc1161 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.cc @@ -10,7 +10,7 @@ #include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" namespace blink { @@ -24,7 +24,7 @@ void CompositedLayerRasterInvalidator::SetTracksRasterInvalidations( tracking_info_->old_client_debug_names.Set(&info.id.client, info.id.client.DebugName()); } - } else if (!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { + } else if (!RasterInvalidationTracking::ShouldAlwaysTrack()) { tracking_info_ = nullptr; } else if (tracking_info_) { tracking_info_->tracking.ClearInvalidations(); @@ -56,13 +56,10 @@ static bool ApproximatelyEqual(const SkMatrix& a, const SkMatrix& b) { PaintInvalidationReason CompositedLayerRasterInvalidator::ChunkPropertiesChanged( + const RefCountedPropertyTreeState& new_chunk_state, const PaintChunkInfo& new_chunk, const PaintChunkInfo& old_chunk, const PropertyTreeState& layer_state) const { - if (new_chunk.properties.backface_hidden != - old_chunk.properties.backface_hidden) - return PaintInvalidationReason::kPaintProperty; - // Special case for transform changes because we may create or delete some // transform nodes when no raster invalidation is needed. For example, when // a composited layer previously not transformed now gets transformed. @@ -74,9 +71,7 @@ CompositedLayerRasterInvalidator::ChunkPropertiesChanged( // Treat the chunk property as changed if the effect node pointer is // different, or the effect node's value changed between the layer state and // the chunk state. - const auto& new_chunk_state = new_chunk.properties.property_tree_state; - const auto& old_chunk_state = old_chunk.properties.property_tree_state; - if (new_chunk_state.Effect() != old_chunk_state.Effect() || + if (new_chunk_state.Effect() != old_chunk.effect_state || new_chunk_state.Effect()->Changed(*layer_state.Effect())) return PaintInvalidationReason::kPaintProperty; @@ -95,7 +90,7 @@ CompositedLayerRasterInvalidator::ChunkPropertiesChanged( // Otherwise treat the chunk property as changed if the clip node pointer is // different, or the clip node's value changed between the layer state and the // chunk state. - if (new_chunk_state.Clip() != old_chunk_state.Clip() || + if (new_chunk_state.Clip() != old_chunk.clip_state || new_chunk_state.Clip()->Changed(*layer_state.Clip())) return PaintInvalidationReason::kPaintProperty; @@ -113,6 +108,7 @@ CompositedLayerRasterInvalidator::ChunkPropertiesChanged( // common cases that most of the chunks can be matched in-order, the complexity // is slightly larger than O(n). void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( + const PaintArtifact& paint_artifact, const PaintChunkSubset& new_chunks, const PropertyTreeState& layer_state, const FloatSize& visual_rect_subpixel_offset, @@ -138,7 +134,7 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( if (matched_old_index == kNotFound) { // The new chunk doesn't match any old chunk. FullyInvalidateNewChunk(new_chunk_info, - PaintInvalidationReason::kAppeared); + PaintInvalidationReason::kChunkAppeared); continue; } @@ -153,8 +149,8 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( PaintInvalidationReason reason = matched_old_index < max_matched_old_index ? PaintInvalidationReason::kChunkReordered - : ChunkPropertiesChanged(new_chunk_info, old_chunk_info, - layer_state); + : ChunkPropertiesChanged(new_chunk.properties, new_chunk_info, + old_chunk_info, layer_state); if (IsFullPaintInvalidationReason(reason)) { // Invalidate both old and new bounds of the chunk if the chunk's paint @@ -175,7 +171,7 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( IncrementallyInvalidateChunk(old_chunk_info, new_chunk_info); // Add the raster invalidations found by PaintController within the chunk. - AddDisplayItemRasterInvalidations(new_chunk, mapper); + AddDisplayItemRasterInvalidations(paint_artifact, new_chunk, mapper); } old_index = matched_old_index + 1; @@ -190,30 +186,30 @@ void CompositedLayerRasterInvalidator::GenerateRasterInvalidations( continue; FullyInvalidateOldChunk(paint_chunks_info_[i], paint_chunks_info_[i].is_cacheable - ? PaintInvalidationReason::kDisappeared + ? PaintInvalidationReason::kChunkDisappeared : PaintInvalidationReason::kChunkUncacheable); } } void CompositedLayerRasterInvalidator::AddDisplayItemRasterInvalidations( + const PaintArtifact& paint_artifact, const PaintChunk& chunk, const ChunkToLayerMapper& mapper) { - DCHECK(chunk.raster_invalidation_tracking.IsEmpty() || - chunk.raster_invalidation_rects.size() == - chunk.raster_invalidation_tracking.size()); - - if (chunk.raster_invalidation_rects.IsEmpty()) + const auto* rects = paint_artifact.GetRasterInvalidationRects(chunk); + if (!rects || rects->IsEmpty()) return; - for (size_t i = 0; i < chunk.raster_invalidation_rects.size(); ++i) { - auto rect = ClipByLayerBounds( - mapper.MapVisualRect(chunk.raster_invalidation_rects[i])); + const auto* tracking = paint_artifact.GetRasterInvalidationTracking(chunk); + DCHECK(!tracking || tracking->IsEmpty() || tracking->size() == rects->size()); + + for (size_t i = 0; i < rects->size(); ++i) { + auto rect = ClipByLayerBounds(mapper.MapVisualRect((*rects)[i])); if (rect.IsEmpty()) continue; raster_invalidation_function_(rect); - if (!chunk.raster_invalidation_tracking.IsEmpty()) { - const auto& info = chunk.raster_invalidation_tracking[i]; + if (tracking && !tracking->IsEmpty()) { + const auto& info = (*tracking)[i]; tracking_info_->tracking.AddInvalidation( info.client, info.client_debug_name, rect, info.reason); } @@ -277,14 +273,24 @@ RasterInvalidationTracking& CompositedLayerRasterInvalidator::EnsureTracking() { } void CompositedLayerRasterInvalidator::Generate( + const PaintArtifact& paint_artifact, const gfx::Rect& layer_bounds, + const PropertyTreeState& layer_state, + const FloatSize& visual_rect_subpixel_offset) { + Generate(paint_artifact, paint_artifact.PaintChunks(), layer_bounds, + layer_state, visual_rect_subpixel_offset); +} + +void CompositedLayerRasterInvalidator::Generate( + const PaintArtifact& paint_artifact, const PaintChunkSubset& paint_chunks, + const gfx::Rect& layer_bounds, const PropertyTreeState& layer_state, const FloatSize& visual_rect_subpixel_offset) { if (RuntimeEnabledFeatures::DisableRasterInvalidationEnabled()) return; - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) + if (RasterInvalidationTracking::ShouldAlwaysTrack()) EnsureTracking(); if (tracking_info_) { @@ -311,7 +317,7 @@ void CompositedLayerRasterInvalidator::Generate( new_chunks_info.emplace_back(*this, mapper, chunk); } } else { - GenerateRasterInvalidations(paint_chunks, layer_state, + GenerateRasterInvalidations(paint_artifact, paint_chunks, layer_state, visual_rect_subpixel_offset, new_chunks_info); } @@ -321,12 +327,6 @@ void CompositedLayerRasterInvalidator::Generate( tracking_info_->old_client_debug_names = std::move(tracking_info_->new_client_debug_names); } - - for (const auto& chunk : paint_chunks) { - chunk.client_is_just_created = false; - chunk.raster_invalidation_rects.clear(); - chunk.raster_invalidation_tracking.clear(); - } } size_t CompositedLayerRasterInvalidator::ApproximateUnsharedMemoryUsage() diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h index 29f8f6ae698..cdf1dafe1fd 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h @@ -14,6 +14,7 @@ namespace blink { +class PaintArtifact; class PaintChunkSubset; class IntRect; @@ -32,9 +33,19 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { RasterInvalidationTracking& EnsureTracking(); - void Generate(const gfx::Rect& layer_bounds, + // Generate raster invalidations for all of the paint chunks in the paint + // artifact. + void Generate(const PaintArtifact&, + const gfx::Rect& layer_bounds, + const PropertyTreeState& layer_state, + const FloatSize& visual_rect_subpixel_offset = FloatSize()); + + // Generate raster invalidations for a subset of the paint chunks in the + // paint artifact. + void Generate(const PaintArtifact&, const PaintChunkSubset&, - const PropertyTreeState&, + const gfx::Rect& layer_bounds, + const PropertyTreeState& layer_state, const FloatSize& visual_rect_subpixel_offset = FloatSize()); bool Matches(const PaintChunk& paint_chunk) const { @@ -54,7 +65,8 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { const ChunkToLayerMapper& mapper, const PaintChunk& chunk) : id(chunk.id), - properties(chunk.properties), + clip_state(chunk.properties.Clip()), + effect_state(chunk.properties.Effect()), is_cacheable(chunk.is_cacheable), bounds_in_layer(invalidator.ClipByLayerBounds( mapper.MapVisualRect(chunk.bounds))), @@ -67,19 +79,26 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { } PaintChunk::Id id; - PaintChunkProperties properties; + // These two pointers are for property change detection. The pointed + // property nodes can be freed after this structure is created. As newly + // created property nodes always have Changed() flag set, it's not a problem + // that a new node is created at the address pointed by these pointers. + const void* clip_state; + const void* effect_state; bool is_cacheable; IntRect bounds_in_layer; FloatClipRect chunk_to_layer_clip; SkMatrix chunk_to_layer_transform; }; - void GenerateRasterInvalidations(const PaintChunkSubset& new_chunks, + void GenerateRasterInvalidations(const PaintArtifact&, + const PaintChunkSubset&, const PropertyTreeState& layer_state, const FloatSize& visual_rect_subpixel_offset, Vector<PaintChunkInfo>& new_chunks_info); size_t MatchNewChunkToOldChunk(const PaintChunk& new_chunk, size_t old_index); - void AddDisplayItemRasterInvalidations(const PaintChunk&, + void AddDisplayItemRasterInvalidations(const PaintArtifact&, + const PaintChunk&, const ChunkToLayerMapper&); void IncrementallyInvalidateChunk(const PaintChunkInfo& old_chunk, const PaintChunkInfo& new_chunk); @@ -95,6 +114,7 @@ class PLATFORM_EXPORT CompositedLayerRasterInvalidator { PaintInvalidationReason, const String* debug_name = nullptr); PaintInvalidationReason ChunkPropertiesChanged( + const RefCountedPropertyTreeState& new_chunk_state, const PaintChunkInfo& new_chunk, const PaintChunkInfo& old_chunk, const PropertyTreeState& layer_state) const; diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator_test.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator_test.cc index 36d6203febf..c12c25ee260 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator_test.cc @@ -5,8 +5,9 @@ #include "third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "third_party/blink/renderer/platform/testing/fake_display_item_client.h" +#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/dtoa/utils.h" @@ -17,39 +18,75 @@ static const IntRect kDefaultLayerBounds(-9999, -7777, 18888, 16666); class CompositedLayerRasterInvalidatorTest : public testing::Test, private ScopedSlimmingPaintV2ForTest { - protected: + public: CompositedLayerRasterInvalidatorTest() : ScopedSlimmingPaintV2ForTest(true) {} static PropertyTreeState DefaultPropertyTreeState() { - return PropertyTreeState(TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root()); + return PropertyTreeState::Root(); } - static PaintChunk Chunk( - int type, - int raster_invalidation_count = 0, - PaintChunk::Cacheable cacheable = PaintChunk::kCacheable) { + CompositedLayerRasterInvalidatorTest& Chunk(int type) { DEFINE_STATIC_LOCAL(FakeDisplayItemClient, fake_client, ()); fake_client.ClearIsJustCreated(); // The enum arithmetics and magic numbers are to produce different values // of paint chunk and raster invalidation properties. PaintChunk::Id id(fake_client, static_cast<DisplayItem::Type>( DisplayItem::kDrawingFirst + type)); - PaintChunk chunk(0, 0, id, PaintChunkProperties(DefaultPropertyTreeState()), - cacheable); - chunk.bounds = + data_.chunks.emplace_back(0, 0, id, DefaultPropertyTreeState()); + data_.chunks.back().bounds = FloatRect(type * 110, type * 220, type * 220 + 200, type * 110 + 200); - for (int i = 0; i < raster_invalidation_count; ++i) { - chunk.raster_invalidation_rects.push_back(FloatRect( - type * 11, type * 22, type * 22 + 100 + i, type * 11 + 100 + i)); - RasterInvalidationInfo info; - info.client = &id.client; - info.reason = static_cast<PaintInvalidationReason>( - static_cast<int>(PaintInvalidationReason::kFull) + type + i); - chunk.raster_invalidation_tracking.push_back(info); + return *this; + } + + CompositedLayerRasterInvalidatorTest& Properties( + const TransformPaintPropertyNode* t, + const ClipPaintPropertyNode* c = ClipPaintPropertyNode::Root(), + const EffectPaintPropertyNode* e = EffectPaintPropertyNode::Root()) { + auto& state = data_.chunks.back().properties; + state.SetTransform(t); + state.SetClip(c); + state.SetEffect(e); + return *this; + } + + CompositedLayerRasterInvalidatorTest& Properties( + const RefCountedPropertyTreeState& state) { + data_.chunks.back().properties = state; + return *this; + } + + CompositedLayerRasterInvalidatorTest& Uncacheable() { + data_.chunks.back().is_cacheable = false; + return *this; + } + + CompositedLayerRasterInvalidatorTest& Bounds(const FloatRect& bounds) { + data_.chunks.back().bounds = bounds; + return *this; + } + + CompositedLayerRasterInvalidatorTest& RasterInvalidationCount(int count) { + size_t size = data_.chunks.size(); + DCHECK_GT(size, 0u); + data_.raster_invalidation_rects.resize(size); + data_.raster_invalidation_trackings.resize(size); + int index = static_cast<int>(size - 1); + for (int i = 0; i < count; ++i) { + IntRect rect(index * 11, index * 22, index * 22 + 100 + i, + index * 11 + 100 + i); + data_.raster_invalidation_rects.back().push_back(FloatRect(rect)); + data_.raster_invalidation_trackings.back().push_back( + RasterInvalidationInfo{ + &data_.chunks.back().id.client, "Test", rect, + static_cast<PaintInvalidationReason>( + static_cast<int>(PaintInvalidationReason::kFull) + index + + i)}); } - return chunk; + return *this; + } + + PaintArtifact Build() { + return PaintArtifact(DisplayItemList(0), std::move(data_)); } static const Vector<RasterInvalidationInfo> TrackedRasterInvalidations( @@ -68,20 +105,26 @@ class CompositedLayerRasterInvalidatorTest CompositedLayerRasterInvalidator::RasterInvalidationFunction kNoopRasterInvalidation = [this](const IntRect& rect) {}; - Vector<IntRect> raster_invalidations_; + PaintChunksAndRasterInvalidations data_; }; -#define EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, index, chunk) \ - do { \ - for (size_t i = 0; i < (chunk).raster_invalidation_rects.size(); ++i) { \ - SCOPED_TRACE(index + i); \ - const auto& info = (invalidations)[index + i]; \ - EXPECT_EQ(ChunkRectToLayer((chunk).raster_invalidation_rects[i], \ - -kDefaultLayerBounds.Location()), \ - info.rect); \ - EXPECT_EQ(&(chunk).id.client, info.client); \ - EXPECT_EQ((chunk).raster_invalidation_tracking[i].reason, info.reason); \ - } \ +#define EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, invalidation_index, \ + artifact, chunk_index) \ + do { \ + const auto& chunk = (artifact).PaintChunks()[chunk_index]; \ + const auto* rects = (artifact).GetRasterInvalidationRects(chunk); \ + ASSERT_TRUE(rects); \ + const auto* tracking = (artifact).GetRasterInvalidationTracking(chunk); \ + ASSERT_TRUE(tracking); \ + for (size_t i = 0; i < rects->size(); ++i) { \ + SCOPED_TRACE(invalidation_index + i); \ + const auto& info = (invalidations)[invalidation_index + i]; \ + EXPECT_EQ( \ + ChunkRectToLayer((*rects)[i], -kDefaultLayerBounds.Location()), \ + info.rect); \ + EXPECT_EQ(&chunk.id.client, info.client); \ + EXPECT_EQ((*tracking)[i].reason, info.reason); \ + } \ } while (false) #define EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( \ @@ -110,40 +153,49 @@ class CompositedLayerRasterInvalidatorTest TEST_F(CompositedLayerRasterInvalidatorTest, LayerBounds) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); invalidator.SetTracksRasterInvalidations(true); - Vector<PaintChunk> chunks = {Chunk(0)}; + auto artifact = Chunk(0).Build(); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); // No raster invalidations needed for a new layer. EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); // No raster invalidations needed if layer origin doesn't change. EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); auto new_layer_bounds = kDefaultLayerBounds; new_layer_bounds.Move(66, 77); - invalidator.Generate(new_layer_bounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, new_layer_bounds, DefaultPropertyTreeState()); // Change of layer origin causes change of chunk0's transform to layer. const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(2u, invalidations.size()); - EXPECT_CHUNK_INVALIDATION(invalidations, 0, chunks[0], + EXPECT_CHUNK_INVALIDATION(invalidations, 0, artifact.PaintChunks()[0], PaintInvalidationReason::kPaintProperty); EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( - invalidations, 1, chunks[0], PaintInvalidationReason::kPaintProperty, - -new_layer_bounds.Location()); + invalidations, 1, artifact.PaintChunks()[0], + PaintInvalidationReason::kPaintProperty, -new_layer_bounds.Location()); } TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunks) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1), Chunk(2)}; + auto artifact = Chunk(0).Chunk(1).Chunk(2).Build(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Swap chunk 1 and 2. All chunks have their own local raster invalidations. - Vector<PaintChunk> new_chunks = {Chunk(0, 2), Chunk(2, 4), Chunk(1, 3)}; - new_chunks[2].bounds = FloatRect(11, 22, 33, 44); - invalidator.Generate(kDefaultLayerBounds, new_chunks, + auto new_artifact = Chunk(0) + .RasterInvalidationCount(2) + .Chunk(2) + .RasterInvalidationCount(4) + .Chunk(1) + .RasterInvalidationCount(3) + .Bounds(FloatRect(11, 22, 33, 44)) + .Build(); + invalidator.Generate(new_artifact, kDefaultLayerBounds, DefaultPropertyTreeState()); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(8u, invalidations.size()); @@ -151,30 +203,39 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunks) { // CompositedLayerRasterInvalidator (which is according to the first chunk's // id). For matched chunk, we issue raster invalidations if any found by // PaintController. - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_chunks[0]); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_chunks[1]); - // Invalidated new chunk 2's old (as chunks[1]) and new (as new_chunks[2]) + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_artifact, 0); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_artifact, 1); + // Invalidated new chunk 2's old (as chunks[1]) and new (as new_artifact[2]) // bounds. - EXPECT_CHUNK_INVALIDATION(invalidations, 6, chunks[1], + EXPECT_CHUNK_INVALIDATION(invalidations, 6, artifact.PaintChunks()[1], PaintInvalidationReason::kChunkReordered); - EXPECT_CHUNK_INVALIDATION(invalidations, 7, new_chunks[2], + EXPECT_CHUNK_INVALIDATION(invalidations, 7, new_artifact.PaintChunks()[2], PaintInvalidationReason::kChunkReordered); } TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunkSubsequences) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1), Chunk(2), Chunk(3), - Chunk(4)}; + auto artifact = Chunk(0).Chunk(1).Chunk(2).Chunk(3).Chunk(4).Build(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Swap chunk (1,2) and (3,4). All chunks have their own local raster // invalidations. - Vector<PaintChunk> new_chunks = {Chunk(0, 2), Chunk(3, 3), Chunk(4, 4), - Chunk(1, 1), Chunk(2, 2)}; - new_chunks[3].bounds = FloatRect(11, 22, 33, 44); - invalidator.Generate(kDefaultLayerBounds, new_chunks, + auto new_artifact = Chunk(0) + .RasterInvalidationCount(2) + .Chunk(3) + .RasterInvalidationCount(3) + .Chunk(4) + .RasterInvalidationCount(4) + .Chunk(1) + .RasterInvalidationCount(1) + .Bounds(FloatRect(11, 22, 33, 44)) + .Chunk(2) + .RasterInvalidationCount(2) + .Build(); + invalidator.Generate(new_artifact, kDefaultLayerBounds, DefaultPropertyTreeState()); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(12u, invalidations.size()); @@ -182,146 +243,178 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ReorderChunkSubsequences) { // CompositedLayerRasterInvalidator (which is according to the first chunk's // id). For matched chunk, we issue raster invalidations if any found by // PaintController. - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_chunks[0]); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_chunks[1]); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 5, new_chunks[2]); - // Invalidated new chunk 3's old (as chunks[1]) and new (as new_chunks[3]) + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_artifact, 0); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_artifact, 1); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 5, new_artifact, 2); + // Invalidated new chunk 3's old (as chunks[1]) and new (as new_artifact[3]) // bounds. - EXPECT_CHUNK_INVALIDATION(invalidations, 9, chunks[1], + EXPECT_CHUNK_INVALIDATION(invalidations, 9, artifact.PaintChunks()[1], PaintInvalidationReason::kChunkReordered); - EXPECT_CHUNK_INVALIDATION(invalidations, 10, new_chunks[3], + EXPECT_CHUNK_INVALIDATION(invalidations, 10, new_artifact.PaintChunks()[3], PaintInvalidationReason::kChunkReordered); // Invalidated new chunk 4's new bounds. Didn't invalidate old bounds because // it's the same as the new bounds. - EXPECT_CHUNK_INVALIDATION(invalidations, 11, new_chunks[4], + EXPECT_CHUNK_INVALIDATION(invalidations, 11, new_artifact.PaintChunks()[4], PaintInvalidationReason::kChunkReordered); } TEST_F(CompositedLayerRasterInvalidatorTest, AppearAndDisappear) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1), Chunk(2)}; + auto artifact = Chunk(0).Chunk(1).Chunk(2).Build(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Chunk 1 and 2 disappeared, 3 and 4 appeared. All chunks have their own // local raster invalidations. - Vector<PaintChunk> new_chunks = {Chunk(0, 2), Chunk(3, 3), Chunk(4, 3)}; - invalidator.Generate(kDefaultLayerBounds, new_chunks, + auto new_artifact = Chunk(0) + .RasterInvalidationCount(2) + .Chunk(3) + .RasterInvalidationCount(3) + .Chunk(4) + .RasterInvalidationCount(3) + .Build(); + invalidator.Generate(new_artifact, kDefaultLayerBounds, DefaultPropertyTreeState()); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(6u, invalidations.size()); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_chunks[0]); - EXPECT_CHUNK_INVALIDATION(invalidations, 2, new_chunks[1], - PaintInvalidationReason::kAppeared); - EXPECT_CHUNK_INVALIDATION(invalidations, 3, new_chunks[2], - PaintInvalidationReason::kAppeared); - EXPECT_CHUNK_INVALIDATION(invalidations, 4, chunks[1], - PaintInvalidationReason::kDisappeared); - EXPECT_CHUNK_INVALIDATION(invalidations, 5, chunks[2], - PaintInvalidationReason::kDisappeared); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_artifact, 0); + EXPECT_CHUNK_INVALIDATION(invalidations, 2, new_artifact.PaintChunks()[1], + PaintInvalidationReason::kChunkAppeared); + EXPECT_CHUNK_INVALIDATION(invalidations, 3, new_artifact.PaintChunks()[2], + PaintInvalidationReason::kChunkAppeared); + EXPECT_CHUNK_INVALIDATION(invalidations, 4, artifact.PaintChunks()[1], + PaintInvalidationReason::kChunkDisappeared); + EXPECT_CHUNK_INVALIDATION(invalidations, 5, artifact.PaintChunks()[2], + PaintInvalidationReason::kChunkDisappeared); } TEST_F(CompositedLayerRasterInvalidatorTest, AppearAtEnd) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0)}; + auto artifact = Chunk(0).Build(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); - Vector<PaintChunk> new_chunks = {Chunk(0, 2), Chunk(1, 3), Chunk(2, 3)}; - invalidator.Generate(kDefaultLayerBounds, new_chunks, + auto new_artifact = Chunk(0) + .RasterInvalidationCount(2) + .Chunk(1) + .RasterInvalidationCount(3) + .Chunk(2) + .RasterInvalidationCount(3) + .Build(); + invalidator.Generate(new_artifact, kDefaultLayerBounds, DefaultPropertyTreeState()); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(4u, invalidations.size()); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_chunks[0]); - EXPECT_CHUNK_INVALIDATION(invalidations, 2, new_chunks[1], - PaintInvalidationReason::kAppeared); - EXPECT_CHUNK_INVALIDATION(invalidations, 3, new_chunks[2], - PaintInvalidationReason::kAppeared); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_artifact, 0); + EXPECT_CHUNK_INVALIDATION(invalidations, 2, new_artifact.PaintChunks()[1], + PaintInvalidationReason::kChunkAppeared); + EXPECT_CHUNK_INVALIDATION(invalidations, 3, new_artifact.PaintChunks()[2], + PaintInvalidationReason::kChunkAppeared); } TEST_F(CompositedLayerRasterInvalidatorTest, UncacheableChunks) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1, 0, PaintChunk::kUncacheable), - Chunk(2)}; + auto artifact = Chunk(0).Chunk(1).Uncacheable().Chunk(2).Build(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, DefaultPropertyTreeState()); + invalidator.Generate(artifact, kDefaultLayerBounds, + DefaultPropertyTreeState()); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); - Vector<PaintChunk> new_chunks = {Chunk(0, 2), Chunk(2, 3), - Chunk(1, 3, PaintChunk::kUncacheable)}; - invalidator.Generate(kDefaultLayerBounds, new_chunks, + auto new_artifact = Chunk(0) + .RasterInvalidationCount(2) + .Chunk(2) + .RasterInvalidationCount(3) + .Chunk(1) + .RasterInvalidationCount(3) + .Uncacheable() + .Build(); + invalidator.Generate(new_artifact, kDefaultLayerBounds, DefaultPropertyTreeState()); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(7u, invalidations.size()); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_chunks[0]); - EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_chunks[1]); - EXPECT_CHUNK_INVALIDATION(invalidations, 5, new_chunks[2], + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 0, new_artifact, 0); + EXPECT_DISPLAY_ITEM_INVALIDATIONS(invalidations, 2, new_artifact, 1); + EXPECT_CHUNK_INVALIDATION(invalidations, 5, new_artifact.PaintChunks()[2], PaintInvalidationReason::kChunkUncacheable); - EXPECT_CHUNK_INVALIDATION(invalidations, 6, chunks[1], + EXPECT_CHUNK_INVALIDATION(invalidations, 6, artifact.PaintChunks()[1], PaintInvalidationReason::kChunkUncacheable); } // Tests the path based on ClipPaintPropertyNode::Changed(). TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeRounded) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1), Chunk(2)}; FloatRoundedRect::Radii radii(FloatSize(1, 2), FloatSize(2, 3), FloatSize(3, 4), FloatSize(4, 5)); FloatRoundedRect clip_rect(FloatRect(-1000, -1000, 2000, 2000), radii); - scoped_refptr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - clip_rect); - scoped_refptr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( - clip0, TransformPaintPropertyNode::Root(), clip_rect); + scoped_refptr<ClipPaintPropertyNode> clip0 = + CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), clip_rect); + scoped_refptr<ClipPaintPropertyNode> clip2 = + CreateClip(clip0, TransformPaintPropertyNode::Root(), clip_rect); PropertyTreeState layer_state(TransformPaintPropertyNode::Root(), clip0.get(), EffectPaintPropertyNode::Root()); - chunks[0].properties = PaintChunkProperties(layer_state); - chunks[1].properties = PaintChunkProperties(layer_state); - chunks[2].properties = PaintChunkProperties( - PropertyTreeState(TransformPaintPropertyNode::Root(), clip2.get(), - EffectPaintPropertyNode::Root())); + auto artifact = + Chunk(0) + .Properties(layer_state) + .Chunk(1) + .Properties(layer_state) + .Chunk(2) + .Properties(TransformPaintPropertyNode::Root(), clip2.get()) + .Build(); GeometryMapperClipCache::ClearCache(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, layer_state); + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Change both clip0 and clip2. - Vector<PaintChunk> new_chunks = {Chunk(0), Chunk(1), Chunk(2)}; + auto new_artifact = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Chunk(2) + .Properties(artifact.PaintChunks()[2].properties) + .Build(); FloatRoundedRect new_clip_rect(FloatRect(-2000, -2000, 4000, 4000), radii); - clip0->Update(clip0->Parent(), clip0->LocalTransformSpace(), new_clip_rect); - clip2->Update(clip2->Parent(), clip2->LocalTransformSpace(), new_clip_rect); - new_chunks[0].properties = chunks[0].properties; - new_chunks[1].properties = chunks[1].properties; - new_chunks[2].properties = chunks[2].properties; + clip0->Update(clip0->Parent(), + ClipPaintPropertyNode::State{clip0->LocalTransformSpace(), + new_clip_rect}); + clip2->Update(clip2->Parent(), + ClipPaintPropertyNode::State{clip2->LocalTransformSpace(), + new_clip_rect}); GeometryMapperClipCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks, layer_state); + invalidator.Generate(new_artifact, kDefaultLayerBounds, layer_state); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(1u, invalidations.size()); // Property change in the layer state should not trigger raster invalidation. // |clip2| change should trigger raster invalidation. - EXPECT_CHUNK_INVALIDATION(invalidations, 0, new_chunks[2], + EXPECT_CHUNK_INVALIDATION(invalidations, 0, new_artifact.PaintChunks()[2], PaintInvalidationReason::kPaintProperty); invalidator.SetTracksRasterInvalidations(false); clip2->ClearChangedToRoot(); // Change chunk1's properties to use a different property tree state. - Vector<PaintChunk> new_chunks1 = {Chunk(0), Chunk(1), Chunk(2)}; - new_chunks1[0].properties = chunks[0].properties; - new_chunks1[1].properties = chunks[2].properties; - new_chunks1[2].properties = chunks[2].properties; + auto new_artifact1 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[2].properties) + .Chunk(2) + .Properties(artifact.PaintChunks()[2].properties) + .Build(); GeometryMapperClipCache::ClearCache(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state); + invalidator.Generate(new_artifact1, kDefaultLayerBounds, layer_state); const auto& invalidations1 = TrackedRasterInvalidations(invalidator); ASSERT_EQ(1u, invalidations1.size()); - EXPECT_CHUNK_INVALIDATION(invalidations1, 0, new_chunks1[1], + EXPECT_CHUNK_INVALIDATION(invalidations1, 0, new_artifact1.PaintChunks()[1], PaintInvalidationReason::kPaintProperty); invalidator.SetTracksRasterInvalidations(false); } @@ -329,85 +422,101 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeRounded) { // Tests the path detecting change of PaintChunkInfo::chunk_to_layer_clip. TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeSimple) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1)}; FloatRoundedRect clip_rect(-1000, -1000, 2000, 2000); - scoped_refptr<ClipPaintPropertyNode> clip0 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - clip_rect); - scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create( - clip0, TransformPaintPropertyNode::Root(), clip_rect); + scoped_refptr<ClipPaintPropertyNode> clip0 = + CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), clip_rect); + scoped_refptr<ClipPaintPropertyNode> clip1 = + CreateClip(clip0, TransformPaintPropertyNode::Root(), clip_rect); PropertyTreeState layer_state = PropertyTreeState::Root(); - chunks[0].properties = PaintChunkProperties( - PropertyTreeState(TransformPaintPropertyNode::Root(), clip0.get(), - EffectPaintPropertyNode::Root())); - chunks[0].bounds = clip_rect.Rect(); - chunks[1].properties = PaintChunkProperties( - PropertyTreeState(TransformPaintPropertyNode::Root(), clip1.get(), - EffectPaintPropertyNode::Root())); - chunks[1].bounds = clip_rect.Rect(); + auto artifact = + Chunk(0) + .Properties(TransformPaintPropertyNode::Root(), clip0.get()) + .Bounds(clip_rect.Rect()) + .Chunk(1) + .Properties(TransformPaintPropertyNode::Root(), clip1.get()) + .Bounds(clip_rect.Rect()) + .Build(); GeometryMapperClipCache::ClearCache(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, layer_state); + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Change clip1 to bigger, which is still bound by clip0, resulting no actual // visual change. - Vector<PaintChunk> new_chunks1 = {Chunk(0), Chunk(1)}; FloatRoundedRect new_clip_rect1(-2000, -2000, 4000, 4000); - clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect1); - new_chunks1[0].properties = chunks[0].properties; - new_chunks1[0].bounds = chunks[0].bounds; - new_chunks1[1].properties = chunks[1].properties; - new_chunks1[1].bounds = chunks[1].bounds; + clip1->Update(clip1->Parent(), + ClipPaintPropertyNode::State{clip1->LocalTransformSpace(), + new_clip_rect1}); + auto new_artifact1 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Bounds(artifact.PaintChunks()[0].bounds) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Bounds(artifact.PaintChunks()[1].bounds) + .Build(); GeometryMapperClipCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state); + invalidator.Generate(new_artifact1, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); clip1->ClearChangedToRoot(); // Change clip1 to smaller. - Vector<PaintChunk> new_chunks2 = {Chunk(0), Chunk(1)}; FloatRoundedRect new_clip_rect2(-500, -500, 1000, 1000); - clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect2); - new_chunks2[0].properties = chunks[0].properties; - new_chunks2[0].bounds = chunks[0].bounds; - new_chunks2[1].properties = chunks[1].properties; - new_chunks2[1].bounds = new_clip_rect2.Rect(); + clip1->Update(clip1->Parent(), + ClipPaintPropertyNode::State{clip1->LocalTransformSpace(), + new_clip_rect2}); + auto new_artifact2 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Bounds(artifact.PaintChunks()[0].bounds) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Bounds(new_clip_rect2.Rect()) + .Build(); GeometryMapperClipCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks2, layer_state); + invalidator.Generate(new_artifact2, kDefaultLayerBounds, layer_state); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(4u, invalidations.size()); // |clip1| change should trigger incremental raster invalidation. - EXPECT_INCREMENTAL_INVALIDATION(invalidations, 0, new_chunks2[1], + EXPECT_INCREMENTAL_INVALIDATION(invalidations, 0, + new_artifact2.PaintChunks()[1], IntRect(-1000, -1000, 2000, 500)); - EXPECT_INCREMENTAL_INVALIDATION(invalidations, 1, new_chunks2[1], + EXPECT_INCREMENTAL_INVALIDATION(invalidations, 1, + new_artifact2.PaintChunks()[1], IntRect(-1000, -500, 500, 1000)); - EXPECT_INCREMENTAL_INVALIDATION(invalidations, 2, new_chunks2[1], + EXPECT_INCREMENTAL_INVALIDATION(invalidations, 2, + new_artifact2.PaintChunks()[1], IntRect(500, -500, 500, 1000)); - EXPECT_INCREMENTAL_INVALIDATION(invalidations, 3, new_chunks2[1], + EXPECT_INCREMENTAL_INVALIDATION(invalidations, 3, + new_artifact2.PaintChunks()[1], IntRect(-1000, 500, 2000, 500)); invalidator.SetTracksRasterInvalidations(false); clip1->ClearChangedToRoot(); // Change clip1 bigger at one side. - Vector<PaintChunk> new_chunks3 = {Chunk(0), Chunk(1)}; FloatRoundedRect new_clip_rect3(-500, -500, 2000, 1000); - clip1->Update(clip1->Parent(), clip1->LocalTransformSpace(), new_clip_rect3); - new_chunks3[0].properties = chunks[0].properties; - new_chunks3[0].bounds = chunks[0].bounds; - new_chunks3[1].properties = chunks[1].properties; - new_chunks3[1].bounds = new_clip_rect3.Rect(); + clip1->Update(clip1->Parent(), + ClipPaintPropertyNode::State{clip1->LocalTransformSpace(), + new_clip_rect3}); + auto new_artifact3 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Bounds(artifact.PaintChunks()[0].bounds) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Bounds(new_clip_rect3.Rect()) + .Build(); GeometryMapperClipCache::ClearCache(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, new_chunks3, layer_state); + invalidator.Generate(new_artifact3, kDefaultLayerBounds, layer_state); const auto& invalidations1 = TrackedRasterInvalidations(invalidator); ASSERT_EQ(1u, invalidations1.size()); // |clip1| change should trigger incremental raster invalidation. - EXPECT_INCREMENTAL_INVALIDATION(invalidations1, 0, new_chunks3[1], + EXPECT_INCREMENTAL_INVALIDATION(invalidations1, 0, + new_artifact3.PaintChunks()[1], IntRect(500, -500, 500, 1000)); invalidator.SetTracksRasterInvalidations(false); clip1->ClearChangedToRoot(); @@ -415,99 +524,106 @@ TEST_F(CompositedLayerRasterInvalidatorTest, ClipPropertyChangeSimple) { TEST_F(CompositedLayerRasterInvalidatorTest, TransformPropertyChange) { CompositedLayerRasterInvalidator invalidator(kNoopRasterInvalidation); - Vector<PaintChunk> chunks = {Chunk(0), Chunk(1)}; - auto layer_transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix().Scale(5), - FloatPoint3D()); - auto transform0 = TransformPaintPropertyNode::Create( - layer_transform, TransformationMatrix().Translate(10, 20), - FloatPoint3D()); - auto transform1 = TransformPaintPropertyNode::Create( - transform0, TransformationMatrix().Translate(-50, -60), FloatPoint3D()); + auto layer_transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Scale(5)); + auto transform0 = CreateTransform(layer_transform, + TransformationMatrix().Translate(10, 20)); + auto transform1 = + CreateTransform(transform0, TransformationMatrix().Translate(-50, -60)); PropertyTreeState layer_state(layer_transform.get(), ClipPaintPropertyNode::Root(), EffectPaintPropertyNode::Root()); - chunks[0].properties = PaintChunkProperties( - PropertyTreeState(transform0.get(), ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root())); - chunks[1].properties = PaintChunkProperties( - PropertyTreeState(transform1.get(), ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root())); + auto artifact = Chunk(0) + .Properties(transform0.get()) + .Chunk(1) + .Properties(transform1.get()) + .Build(); GeometryMapperTransformCache::ClearCache(); invalidator.SetTracksRasterInvalidations(true); - invalidator.Generate(kDefaultLayerBounds, chunks, layer_state); + invalidator.Generate(artifact, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Change layer_transform should not cause raster invalidation in the layer. - Vector<PaintChunk> new_chunks = {Chunk(0), Chunk(1)}; - layer_transform->Update(layer_transform->Parent(), - TransformationMatrix().Scale(10), FloatPoint3D()); - new_chunks[0].properties = chunks[0].properties; - new_chunks[1].properties = chunks[1].properties; + layer_transform->Update( + layer_transform->Parent(), + TransformPaintPropertyNode::State{TransformationMatrix().Scale(10)}); + auto new_artifact = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Build(); GeometryMapperTransformCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks, layer_state); + invalidator.Generate(new_artifact, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Inserting another node between layer_transform and transform0 and letting // the new node become the transform of the layer state should not cause // raster invalidation in the layer. This simulates a composited layer is // scrolled from its original location. - Vector<PaintChunk> new_chunks1 = {Chunk(0), Chunk(1)}; - auto new_layer_transform = TransformPaintPropertyNode::Create( - layer_transform, TransformationMatrix().Translate(-100, -200), - FloatPoint3D()); + auto new_layer_transform = CreateTransform( + layer_transform, TransformationMatrix().Translate(-100, -200)); layer_state = PropertyTreeState(new_layer_transform.get(), ClipPaintPropertyNode::Root(), EffectPaintPropertyNode::Root()); - transform0->Update(new_layer_transform, transform0->Matrix(), FloatPoint3D()); - new_chunks1[0].properties = chunks[0].properties; - new_chunks1[1].properties = chunks[1].properties; + transform0->Update(new_layer_transform, + TransformPaintPropertyNode::State{transform0->Matrix()}); + auto new_artifact1 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Build(); GeometryMapperTransformCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks1, layer_state); + invalidator.Generate(new_artifact1, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Removing transform nodes above the layer state should not cause raster // invalidation in the layer. - Vector<PaintChunk> new_chunks2 = {Chunk(0), Chunk(1)}; layer_state = DefaultPropertyTreeState(); - transform0->Update(layer_state.Transform(), transform0->Matrix(), - FloatPoint3D()); - new_chunks2[0].properties = chunks[0].properties; - new_chunks2[1].properties = chunks[1].properties; + transform0->Update(layer_state.Transform(), + TransformPaintPropertyNode::State{transform0->Matrix()}); + auto new_artifact2 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Build(); GeometryMapperTransformCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks2, layer_state); + invalidator.Generate(new_artifact2, kDefaultLayerBounds, layer_state); EXPECT_TRUE(TrackedRasterInvalidations(invalidator).IsEmpty()); // Change transform0 and transform1, while keeping the combined transform0 // and transform1 unchanged for chunk 2. We should invalidate only chunk 0 // for changed paint property. - Vector<PaintChunk> new_chunks3 = {Chunk(0), Chunk(1)}; transform0->Update( layer_state.Transform(), - TransformationMatrix(transform0->Matrix()).Translate(20, 30), - FloatPoint3D()); + TransformPaintPropertyNode::State{ + TransformationMatrix(transform0->Matrix()).Translate(20, 30)}); transform1->Update( transform0, - TransformationMatrix(transform1->Matrix()).Translate(-20, -30), - FloatPoint3D()); - new_chunks3[0].properties = new_chunks2[0].properties; - new_chunks3[1].properties = new_chunks2[1].properties; + TransformPaintPropertyNode::State{ + TransformationMatrix(transform1->Matrix()).Translate(-20, -30)}); + auto new_artifact3 = Chunk(0) + .Properties(artifact.PaintChunks()[0].properties) + .Chunk(1) + .Properties(artifact.PaintChunks()[1].properties) + .Build(); GeometryMapperTransformCache::ClearCache(); - invalidator.Generate(kDefaultLayerBounds, new_chunks3, layer_state); + invalidator.Generate(new_artifact3, kDefaultLayerBounds, layer_state); const auto& invalidations = TrackedRasterInvalidations(invalidator); ASSERT_EQ(2u, invalidations.size()); EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( - invalidations, 0, new_chunks3[0], PaintInvalidationReason::kPaintProperty, + invalidations, 0, new_artifact3.PaintChunks()[0], + PaintInvalidationReason::kPaintProperty, -kDefaultLayerBounds.Location() + IntSize(10, 20)); EXPECT_CHUNK_INVALIDATION_WITH_LAYER_OFFSET( - invalidations, 1, new_chunks3[0], PaintInvalidationReason::kPaintProperty, + invalidations, 1, new_artifact3.PaintChunks()[0], + PaintInvalidationReason::kPaintProperty, -kDefaultLayerBounds.Location() + IntSize(30, 50)); invalidator.SetTracksRasterInvalidations(false); } 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 8a4467b8a42..7b8194422f1 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 @@ -5,20 +5,34 @@ #include "third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h" #include <memory> +#include "base/optional.h" +#include "base/trace_event/trace_event_argument.h" #include "cc/paint/paint_op_buffer.h" #include "third_party/blink/renderer/platform/geometry/geometry_as_json.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h" #include "third_party/blink/renderer/platform/graphics/logging_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" #include "third_party/blink/renderer/platform/json/json_values.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" namespace blink { +ContentLayerClientImpl::ContentLayerClientImpl() + : cc_picture_layer_(cc::PictureLayer::Create(this)), + raster_invalidator_([this](const IntRect& rect) { + cc_picture_layer_->SetNeedsDisplayRect(rect); + }), + layer_state_(nullptr, nullptr, nullptr), + weak_ptr_factory_(this) { + cc_picture_layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr()); +} + +ContentLayerClientImpl::~ContentLayerClientImpl() = default; + static int GetTransformId(const TransformPaintPropertyNode* transform, ContentLayerClientImpl::LayerAsJSONContext& context) { if (!transform) @@ -126,6 +140,21 @@ std::unique_ptr<JSONObject> ContentLayerClientImpl::LayerAsJSON( return json; } +std::unique_ptr<base::trace_event::TracedValue> +ContentLayerClientImpl::TakeDebugInfo(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", + WTF::StringUTF8Adaptor(debug_name_).AsStringPiece()); + 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; +} + static SkColor DisplayItemBackgroundColor(const DisplayItem& item) { if (item.GetType() != DisplayItem::kBoxDecorationBackground && item.GetType() != DisplayItem::kDocumentBackground) @@ -150,12 +179,13 @@ static SkColor DisplayItemBackgroundColor(const DisplayItem& item) { } scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( - const DisplayItemList& display_item_list, - const gfx::Rect& layer_bounds, + const PaintArtifact& paint_artifact, const PaintChunkSubset& paint_chunks, + const gfx::Rect& layer_bounds, const PropertyTreeState& layer_state) { // 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() paint_chunk_debug_data_ = JSONArray::Create(); @@ -163,23 +193,23 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( auto json = JSONObject::Create(); json->SetString("data", chunk.ToString()); json->SetArray("displayItems", - display_item_list.SubsequenceAsJSON( + paint_artifact.GetDisplayItemList().SubsequenceAsJSON( chunk.begin_index, chunk.end_index, DisplayItemList::kSkipNonDrawings | DisplayItemList::kShownOnlyDisplayItemTypes)); - json->SetString("propertyTreeState", - chunk.properties.property_tree_state.ToTreeString()); + json->SetString("propertyTreeState", chunk.properties.ToTreeString()); paint_chunk_debug_data_->PushObject(std::move(json)); } #endif - raster_invalidator_.Generate(layer_bounds, paint_chunks, layer_state); + raster_invalidator_.Generate(paint_artifact, paint_chunks, layer_bounds, + layer_state); layer_state_ = layer_state; cc_picture_layer_->SetBounds(layer_bounds.size()); cc_picture_layer_->SetIsDrawable(true); - Optional<RasterUnderInvalidationCheckingParams> params; + base::Optional<RasterUnderInvalidationCheckingParams> params; if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { params.emplace(*raster_invalidator_.GetTracking(), IntRect(0, 0, layer_bounds.width(), layer_bounds.height()), @@ -188,7 +218,7 @@ scoped_refptr<cc::PictureLayer> ContentLayerClientImpl::UpdateCcPictureLayer( cc_display_item_list_ = PaintChunksToCcLayer::Convert( paint_chunks, layer_state, layer_bounds.OffsetFromOrigin(), display_item_list, cc::DisplayItemList::kTopLevelDisplayItemList, - WTF::OptionalOrNullptr(params)); + base::OptionalOrNullptr(params)); if (paint_chunks[0].size()) { cc_picture_layer_->SetBackgroundColor(DisplayItemBackgroundColor( 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 c404df60d1a..d29639e8cda 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 @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_COMPOSITING_CONTENT_LAYER_CLIENT_IMPL_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/composited_layer_raster_invalidator.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" @@ -16,23 +17,19 @@ namespace blink { -class DisplayItemList; class JSONArray; class JSONObject; +class PaintArtifact; class PaintChunkSubset; -class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { +class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient, + public cc::LayerClient { WTF_MAKE_NONCOPYABLE(ContentLayerClientImpl); USING_FAST_MALLOC(ContentLayerClientImpl); public: - ContentLayerClientImpl() - : cc_picture_layer_(cc::PictureLayer::Create(this)), - raster_invalidator_([this](const IntRect& rect) { - cc_picture_layer_->SetNeedsDisplayRect(rect); - }), - layer_state_(nullptr, nullptr, nullptr) {} - ~ContentLayerClientImpl() override = default; + ContentLayerClientImpl(); + ~ContentLayerClientImpl() override; // cc::ContentLayerClient gfx::Rect PaintableRegion() override { @@ -48,6 +45,11 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { return 0; } + // cc::LayerClient + std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo( + cc::Layer*) override; + void DidChangeScrollbarsHiddenIfOverlay(bool) override {} + void SetTracksRasterInvalidations(bool should_track) { raster_invalidator_.SetTracksRasterInvalidations(should_track); } @@ -68,9 +70,9 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { std::unique_ptr<JSONObject> LayerAsJSON(LayerAsJSONContext&) const; scoped_refptr<cc::PictureLayer> UpdateCcPictureLayer( - const DisplayItemList&, - const gfx::Rect& layer_bounds, + const PaintArtifact&, const PaintChunkSubset&, + const gfx::Rect& layer_bounds, const PropertyTreeState&); private: @@ -83,6 +85,8 @@ class PLATFORM_EXPORT ContentLayerClientImpl : public cc::ContentLayerClient { #if DCHECK_IS_ON() std::unique_ptr<JSONArray> paint_chunk_debug_data_; #endif + + base::WeakPtrFactory<ContentLayerClientImpl> weak_ptr_factory_; }; } // namespace blink 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 39060a8bbab..6756dda99da 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 @@ -12,9 +12,6 @@ #include "cc/paint/display_item_list.h" #include "cc/trees/layer_tree_host.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_layer.h" -#include "third_party/blink/public/platform/web_layer_scroll_client.h" #include "third_party/blink/renderer/platform/graphics/compositing/content_layer_client_impl.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" @@ -22,6 +19,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" +#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/scroll_hit_test_display_item.h" @@ -39,16 +37,24 @@ namespace blink { // http://crbug.com/692842#c4. static int g_s_property_tree_sequence_number = 1; -PaintArtifactCompositor::PaintArtifactCompositor(WebLayerScrollClient& client) - : scroll_client_(client), tracks_raster_invalidations_(false) { - if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) +PaintArtifactCompositor::PaintArtifactCompositor( + base::RepeatingCallback<void(const gfx::ScrollOffset&, + const cc::ElementId&)> scroll_callback) + : scroll_callback_(std::move(scroll_callback)), + tracks_raster_invalidations_(false) { + if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() && + !RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) return; root_layer_ = cc::Layer::Create(); - web_layer_ = Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( - root_layer_.get()); } PaintArtifactCompositor::~PaintArtifactCompositor() { + // TODO(crbug.com/836897, crbug.com/836912): + // In BlinkGenPropertyTrees mode, some of the layers passed from Blink core + // have pre-filled element ID. Need to figure out what is the best place to + // setup them. + if (RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) + return; for (auto child : root_layer_->children()) DCHECK(!child->element_id()); } @@ -118,8 +124,11 @@ static scoped_refptr<cc::Layer> ForeignLayerForPaintChunk( layer_offset = gfx::Vector2dF(foreign_layer_display_item.Location().X(), foreign_layer_display_item.Location().Y()); scoped_refptr<cc::Layer> layer = foreign_layer_display_item.GetLayer(); - layer->SetBounds(foreign_layer_display_item.Bounds()); - layer->SetIsDrawable(true); + DCHECK(layer->bounds() == + static_cast<gfx::Size>(foreign_layer_display_item.Bounds())) + << "\n layer bounds: " << layer->bounds().ToString() + << "\n display item bounds: " << foreign_layer_display_item.Bounds(); + DCHECK(layer->DrawsContent()); return layer; } @@ -192,13 +201,11 @@ PaintArtifactCompositor::ScrollHitTestLayerForPendingLayer( auto bounds = scroll_node.ContainerRect().Size(); // Mark the layer as scrollable. // TODO(pdr): When SPV2 launches this parameter for bounds will not be needed. - scroll_layer->SetScrollable(bounds); + 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(bounds); - scroll_layer->set_did_scroll_callback( - base::BindRepeating(&blink::WebLayerScrollClient::DidScroll, - base::Unretained(&scroll_client_))); + scroll_layer->SetBounds(static_cast<gfx::Size>(bounds)); + scroll_layer->set_did_scroll_callback(scroll_callback_); return scroll_layer; } @@ -256,11 +263,18 @@ PaintArtifactCompositor::CompositedLayerForPendingLayer( layer_offset = cc_combined_bounds.OffsetFromOrigin(); auto cc_layer = content_layer_client->UpdateCcPictureLayer( - paint_artifact.GetDisplayItemList(), cc_combined_bounds, paint_chunks, + paint_artifact, paint_chunks, cc_combined_bounds, pending_layer.property_tree_state); 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 + // GraphicsLayer on the ContentsLayer() or by video clients etc. + cc_layer->SetContentsOpaque(pending_layer.rect_known_to_be_opaque.Contains( + FloatRect(EnclosingIntRect(pending_layer.bounds)))); + return cc_layer; } @@ -271,16 +285,13 @@ PaintArtifactCompositor::PendingLayer::PendingLayer( : bounds(first_paint_chunk.bounds), rect_known_to_be_opaque( first_paint_chunk.known_to_be_opaque ? bounds : FloatRect()), - backface_hidden(first_paint_chunk.properties.backface_hidden), - property_tree_state(first_paint_chunk.properties.property_tree_state - .GetPropertyTreeState()), + property_tree_state(first_paint_chunk.properties.GetPropertyTreeState()), requires_own_layer(chunk_requires_own_layer) { paint_chunk_indices.push_back(chunk_index); } void PaintArtifactCompositor::PendingLayer::Merge(const PendingLayer& guest) { DCHECK(!requires_own_layer && !guest.requires_own_layer); - DCHECK_EQ(backface_hidden, guest.backface_hidden); paint_chunk_indices.AppendVector(guest.paint_chunk_indices); FloatClipRect guest_bounds_in_home(guest.bounds); @@ -299,8 +310,6 @@ bool PaintArtifactCompositor::PendingLayer::CanMerge( const PendingLayer& guest) const { if (requires_own_layer || guest.requires_own_layer) return false; - if (backface_hidden != guest.backface_hidden) - return false; if (property_tree_state.Effect() != guest.property_tree_state.Effect()) return false; return CanUpcastTo(guest.property_tree_state, property_tree_state); @@ -334,20 +343,33 @@ static bool IsNonCompositingAncestorOf( return true; } +static bool IsBackfaceHidden(const TransformPaintPropertyNode* node) { + while (node && node->GetBackfaceVisibility() == + TransformPaintPropertyNode::BackfaceVisibility::kInherited) + node = node->Parent(); + return node && node->GetBackfaceVisibility() == + TransformPaintPropertyNode::BackfaceVisibility::kHidden; +} + // 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. -// 2. The guest clip must be a descendant of the home clip. -// 3. The local space of each clip and effect node on the ancestor chain must +// 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. -// 4. 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) { DCHECK_EQ(home.Effect(), guest.Effect()); + if (IsBackfaceHidden(home.Transform()) != IsBackfaceHidden(guest.Transform())) + return false; + for (const ClipPaintPropertyNode* current_clip = guest.Clip(); current_clip != home.Clip(); current_clip = current_clip->Parent()) { if (!current_clip || current_clip->HasDirectCompositingReasons()) @@ -418,8 +440,7 @@ bool PaintArtifactCompositor::CanDecompositeEffect( static bool EffectGroupContainsChunk( const EffectPaintPropertyNode& group_effect, const PaintChunk& chunk) { - const EffectPaintPropertyNode* effect = - chunk.properties.property_tree_state.Effect(); + const auto* effect = chunk.properties.Effect(); return effect == &group_effect || StrictChildOfAlongPath(&group_effect, effect); } @@ -482,8 +503,7 @@ void PaintArtifactCompositor::LayerizeGroup( // A. The next chunk belongs to the current group but no subgroup. // B. The next chunk does not belong to the current group. // C. The next chunk belongs to some subgroup of the current group. - const EffectPaintPropertyNode* chunk_effect = - chunk_it->properties.property_tree_state.Effect(); + const auto* chunk_effect = chunk_it->properties.Effect(); if (chunk_effect == ¤t_group) { // Case A: The next chunk belongs to the current group but no subgroup. const auto& last_display_item = @@ -771,10 +791,10 @@ void PaintArtifactCompositor::Update( layer->SetScrollTreeIndex(scroll_id); layer->SetClipTreeIndex(clip_id); layer->SetEffectTreeIndex(effect_id); - layer->SetContentsOpaque(pending_layer.rect_known_to_be_opaque.Contains( - FloatRect(EnclosingIntRect(pending_layer.bounds)))); - layer->SetDoubleSided(!pending_layer.backface_hidden); - layer->SetShouldCheckBackfaceVisibility(pending_layer.backface_hidden); + bool backface_hidden = + IsBackfaceHidden(pending_layer.property_tree_state.Transform()); + layer->SetDoubleSided(!backface_hidden); + layer->SetShouldCheckBackfaceVisibility(backface_hidden); } property_tree_manager.Finalize(); content_layer_clients_.swap(new_content_layer_clients); @@ -799,10 +819,6 @@ void PaintArtifactCompositor::Update( g_s_property_tree_sequence_number++; - // Clear paint property change flags that are for this update only. - for (const auto& chunk : paint_artifact.PaintChunks()) - chunk.properties.property_tree_state.ClearChangedToRoot(); - #if DCHECK_IS_ON() if (VLOG_IS_ON(2)) { static String s_previous_output; @@ -818,17 +834,10 @@ void PaintArtifactCompositor::Update( #endif } -std::unique_ptr<WebLayer> -PaintArtifactCompositor::ExtraDataForTesting::ContentWebLayerAt( - unsigned index) { - return Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( - content_layers[index].get()); -} -std::unique_ptr<WebLayer> +cc::Layer* PaintArtifactCompositor::ExtraDataForTesting::ScrollHitTestWebLayerAt( unsigned index) { - return Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( - scroll_hit_test_layers[index].get()); + return scroll_hit_test_layers[index].get(); } #if DCHECK_IS_ON() 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 d8751ef40c4..fc97de0b4da 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,6 +7,7 @@ #include <memory> +#include "base/callback.h" #include "base/memory/ptr_util.h" #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.h" @@ -17,11 +18,13 @@ #include "third_party/blink/renderer/platform/wtf/vector.h" namespace cc { +struct ElementId; class Layer; } namespace gfx { class Vector2dF; +class ScrollOffset; } namespace blink { @@ -30,8 +33,6 @@ class ContentLayerClientImpl; class JSONObject; class PaintArtifact; class SynthesizedClip; -class WebLayer; -class WebLayerScrollClient; struct PaintChunk; // Responsible for managing compositing in terms of a PaintArtifact. @@ -50,8 +51,10 @@ class PLATFORM_EXPORT PaintArtifactCompositor final ~PaintArtifactCompositor(); static std::unique_ptr<PaintArtifactCompositor> Create( - WebLayerScrollClient& client) { - return base::WrapUnique(new PaintArtifactCompositor(client)); + base::RepeatingCallback<void(const gfx::ScrollOffset&, + const cc::ElementId&)> scroll_callback) { + return base::WrapUnique( + new PaintArtifactCompositor(std::move(scroll_callback))); } // Updates the layer tree to match the provided paint artifact. @@ -64,17 +67,17 @@ class PLATFORM_EXPORT PaintArtifactCompositor final // The root layer of the tree managed by this object. cc::Layer* RootLayer() const { return root_layer_.get(); } - // Wraps rootLayer(), so that it can be attached as a child of another - // WebLayer. - WebLayer* GetWebLayer() const { return web_layer_.get(); } + // Wraps RootLayer(), so that it can be attached as a child of another + // cc::Layer. + // TODO(danakj): Remove this, use RootLayer() directly. + cc::Layer* GetCcLayer() 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 { - std::unique_ptr<WebLayer> ContentWebLayerAt(unsigned index); - std::unique_ptr<WebLayer> ScrollHitTestWebLayerAt(unsigned index); + cc::Layer* ScrollHitTestWebLayerAt(unsigned index); Vector<scoped_refptr<cc::Layer>> content_layers; Vector<scoped_refptr<cc::Layer>> synthesized_clip_layers; @@ -120,12 +123,13 @@ class PLATFORM_EXPORT PaintArtifactCompositor final FloatRect bounds; Vector<size_t> paint_chunk_indices; FloatRect rect_known_to_be_opaque; - bool backface_hidden; PropertyTreeState property_tree_state; bool requires_own_layer; }; - PaintArtifactCompositor(WebLayerScrollClient&); + PaintArtifactCompositor( + base::RepeatingCallback<void(const gfx::ScrollOffset&, + const cc::ElementId&)> scroll_callback); void RemoveChildLayers(); @@ -200,12 +204,12 @@ class PLATFORM_EXPORT PaintArtifactCompositor final CompositorElementId& mask_effect_id) final; // Provides a callback for notifying blink of composited scrolling. - WebLayerScrollClient& scroll_client_; + base::RepeatingCallback<void(const gfx::ScrollOffset&, const cc::ElementId&)> + scroll_callback_; bool tracks_raster_invalidations_; scoped_refptr<cc::Layer> root_layer_; - std::unique_ptr<WebLayer> web_layer_; Vector<std::unique_ptr<ContentLayerClientImpl>> content_layer_clients_; struct SynthesizedClipEntry { const ClipPaintPropertyNode* key; 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 f6e3259974d..f215b498529 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 @@ -19,7 +19,6 @@ #include "cc/trees/transform_node.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_layer_scroll_client.h" #include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h" @@ -29,10 +28,10 @@ #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/test_paint_artifact.h" #include "third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { -using ::blink::test::CreateOpacityOnlyEffect; using testing::Pointee; PaintChunk::Id DefaultId() { @@ -40,15 +39,8 @@ PaintChunk::Id DefaultId() { return PaintChunk::Id(fake_client, DisplayItem::kDrawingFirst); } -PaintChunkProperties DefaultPaintChunkProperties() { - PropertyTreeState property_tree_state(TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root()); - return PaintChunkProperties(property_tree_state); -} - PaintChunk DefaultChunk() { - return PaintChunk(0, 1, DefaultId(), DefaultPaintChunkProperties()); + return PaintChunk(0, 1, DefaultId(), PropertyTreeState::Root()); } gfx::Transform Translation(SkMScalar x, SkMScalar y) { @@ -70,12 +62,11 @@ class WebLayerTreeViewWithLayerTreeFrameSink } }; -class FakeScrollClient : public WebLayerScrollClient { +class FakeScrollClient { public: FakeScrollClient() : did_scroll_count(0) {} - void DidScroll(const gfx::ScrollOffset& offset, - const CompositorElementId&) final { + void DidScroll(const gfx::ScrollOffset& offset, const CompositorElementId&) { did_scroll_count++; last_scroll_offset = offset; }; @@ -95,7 +86,8 @@ class PaintArtifactCompositorTest : public testing::Test, void SetUp() override { // Delay constructing the compositor until after the feature is set. paint_artifact_compositor_ = - PaintArtifactCompositor::Create(scroll_client_); + PaintArtifactCompositor::Create(WTF::BindRepeating( + &FakeScrollClient::DidScroll, WTF::Unretained(&scroll_client_))); paint_artifact_compositor_->EnableExtraDataForTesting(); cc::LayerTreeSettings settings = @@ -105,7 +97,7 @@ class PaintArtifactCompositorTest : public testing::Test, web_layer_tree_view_ = std::make_unique<WebLayerTreeViewWithLayerTreeFrameSink>(settings); web_layer_tree_view_->SetRootLayer( - *paint_artifact_compositor_->GetWebLayer()); + paint_artifact_compositor_->GetCcLayer()); } void TearDown() override { @@ -217,8 +209,7 @@ class PaintArtifactCompositorTest : public testing::Test, bool include_subsequent_chunk) { if (include_preceding_chunk) AddSimpleRectChunk(artifact); - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), opacity); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), opacity); artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), effect) @@ -265,7 +256,7 @@ TEST_F(PaintArtifactCompositorTest, EmptyPaintArtifact) { TEST_F(PaintArtifactCompositorTest, OneChunkWithAnOffset) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(50, -50, 100, 100), Color::kWhite); Update(artifact.Build()); @@ -280,10 +271,9 @@ TEST_F(PaintArtifactCompositorTest, OneChunkWithAnOffset) { TEST_F(PaintArtifactCompositorTest, OneTransform) { // A 90 degree clockwise rotation about (100, 100). - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), - FloatPoint3D(100, 100, 0), false, 0, CompositingReason::k3DTransform); + auto transform = CreateTransform( + TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), + FloatPoint3D(100, 100, 0), CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact @@ -327,14 +317,12 @@ TEST_F(PaintArtifactCompositorTest, OneTransform) { TEST_F(PaintArtifactCompositorTest, TransformCombining) { // A translation by (5, 5) within a 2x scale about (10, 10). - scoped_refptr<TransformPaintPropertyNode> transform1 = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix().Scale(2), - FloatPoint3D(10, 10, 0), false, 0, CompositingReason::k3DTransform); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform1, TransformationMatrix().Translate(5, 5), FloatPoint3D(), - false, 0, CompositingReason::k3DTransform); + auto transform1 = CreateTransform( + TransformPaintPropertyNode::Root(), TransformationMatrix().Scale(2), + FloatPoint3D(10, 10, 0), CompositingReason::k3DTransform); + auto transform2 = + CreateTransform(transform1, TransformationMatrix().Translate(5, 5), + FloatPoint3D(), CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact @@ -370,6 +358,48 @@ TEST_F(PaintArtifactCompositorTest, TransformCombining) { ContentLayerAt(1)->transform_tree_index()); } +TEST_F(PaintArtifactCompositorTest, BackfaceVisibility) { + TransformPaintPropertyNode::State backface_hidden_state; + backface_hidden_state.backface_visibility = + TransformPaintPropertyNode::BackfaceVisibility::kHidden; + auto backface_hidden_transform = TransformPaintPropertyNode::Create( + TransformPaintPropertyNode::Root(), std::move(backface_hidden_state)); + + auto backface_inherited_transform = TransformPaintPropertyNode::Create( + backface_hidden_transform, TransformPaintPropertyNode::State{}); + + TransformPaintPropertyNode::State backface_visible_state; + backface_visible_state.backface_visibility = + TransformPaintPropertyNode::BackfaceVisibility::kVisible; + auto backface_visible_transform = TransformPaintPropertyNode::Create( + backface_hidden_transform, std::move(backface_visible_state)); + + TestPaintArtifact artifact; + artifact + .Chunk(backface_hidden_transform, ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()) + .RectDrawing(FloatRect(0, 0, 300, 200), Color::kWhite); + artifact + .Chunk(backface_inherited_transform, ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()) + .RectDrawing(FloatRect(100, 100, 100, 100), Color::kBlack); + artifact + .Chunk(backface_visible_transform, ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()) + .RectDrawing(FloatRect(0, 0, 300, 200), Color::kDarkGray); + Update(artifact.Build()); + + ASSERT_EQ(2u, ContentLayerCount()); + EXPECT_THAT( + ContentLayerAt(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(), + Pointee(DrawsRectangle(FloatRect(0, 0, 300, 200), Color::kDarkGray))); +} + TEST_F(PaintArtifactCompositorTest, FlattensInheritedTransform) { for (bool transform_is_flattened : {true, false}) { SCOPED_TRACE(transform_is_flattened); @@ -378,18 +408,15 @@ TEST_F(PaintArtifactCompositorTest, FlattensInheritedTransform) { // transform node flattens the transform. This is because Blink's notion of // flattening determines whether content within the node's local transform // is flattened, while cc's notion applies in the parent's coordinate space. - scoped_refptr<TransformPaintPropertyNode> transform1 = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix(), - FloatPoint3D()); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform1, TransformationMatrix().Rotate3d(0, 45, 0), - FloatPoint3D()); - scoped_refptr<TransformPaintPropertyNode> transform3 = - TransformPaintPropertyNode::Create( - transform2, TransformationMatrix().Rotate3d(0, 45, 0), - FloatPoint3D(), transform_is_flattened); + auto transform1 = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix()); + auto transform2 = + CreateTransform(transform1, TransformationMatrix().Rotate3d(0, 45, 0)); + TransformPaintPropertyNode::State transform3_state; + transform3_state.matrix = TransformationMatrix().Rotate3d(0, 45, 0); + transform3_state.flattens_inherited_transform = transform_is_flattened; + auto transform3 = TransformPaintPropertyNode::Create( + transform2, std::move(transform3_state)); TestPaintArtifact artifact; artifact @@ -429,25 +456,24 @@ TEST_F(PaintArtifactCompositorTest, FlattensInheritedTransform) { TEST_F(PaintArtifactCompositorTest, SortingContextID) { // Has no 3D rendering context. - scoped_refptr<TransformPaintPropertyNode> transform1 = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix(), - FloatPoint3D()); + auto transform1 = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix()); // Establishes a 3D rendering context. - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create(transform1, TransformationMatrix(), - FloatPoint3D(), false, 1, - CompositingReason::k3DTransform); + TransformPaintPropertyNode::State transform2_3_state; + transform2_3_state.rendering_context_id = 1; + transform2_3_state.direct_compositing_reasons = + CompositingReason::k3DTransform; + auto transform2 = TransformPaintPropertyNode::Create( + transform1, std::move(transform2_3_state)); // Extends the 3D rendering context of transform2. - scoped_refptr<TransformPaintPropertyNode> transform3 = - TransformPaintPropertyNode::Create(transform2, TransformationMatrix(), - FloatPoint3D(), false, 1, - CompositingReason::k3DTransform); + auto transform3 = TransformPaintPropertyNode::Create( + transform2, std::move(transform2_3_state)); // Establishes a 3D rendering context distinct from transform2. - scoped_refptr<TransformPaintPropertyNode> transform4 = - TransformPaintPropertyNode::Create(transform2, TransformationMatrix(), - FloatPoint3D(), false, 2, - CompositingReason::k3DTransform); + TransformPaintPropertyNode::State transform4_state; + transform4_state.rendering_context_id = 2; + transform4_state.direct_compositing_reasons = CompositingReason::k3DTransform; + auto transform4 = TransformPaintPropertyNode::Create( + transform2, std::move(transform4_state)); TestPaintArtifact artifact; artifact @@ -514,9 +540,9 @@ TEST_F(PaintArtifactCompositorTest, SortingContextID) { } TEST_F(PaintArtifactCompositorTest, OneClip) { - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(100, 100, 300, 200)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(100, 100, 300, 200)); TestPaintArtifact artifact; artifact @@ -542,14 +568,13 @@ TEST_F(PaintArtifactCompositorTest, OneClip) { } TEST_F(PaintArtifactCompositorTest, NestedClips) { - scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(100, 100, 700, 700), nullptr, nullptr, - CompositingReason::kOverflowScrollingTouch); - scoped_refptr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( - clip1, TransformPaintPropertyNode::Root(), - FloatRoundedRect(200, 200, 700, 700), nullptr, nullptr, - CompositingReason::kOverflowScrollingTouch); + auto clip1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(100, 100, 700, 700), + CompositingReason::kOverflowScrollingTouch); + auto clip2 = CreateClip(clip1, TransformPaintPropertyNode::Root(), + FloatRoundedRect(200, 200, 700, 700), + CompositingReason::kOverflowScrollingTouch); TestPaintArtifact artifact; artifact @@ -614,7 +639,7 @@ TEST_F(PaintArtifactCompositorTest, NestedClips) { TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips) { Vector<scoped_refptr<ClipPaintPropertyNode>> clips; for (unsigned i = 1; i <= 10; i++) { - clips.push_back(ClipPaintPropertyNode::Create( + clips.push_back(CreateClip( clips.IsEmpty() ? ClipPaintPropertyNode::Root() : clips.back(), TransformPaintPropertyNode::Root(), FloatRoundedRect(5 * i, 0, 100, 200 - 10 * i))); @@ -649,16 +674,13 @@ TEST_F(PaintArtifactCompositorTest, DeeplyNestedClips) { } TEST_F(PaintArtifactCompositorTest, SiblingClips) { - scoped_refptr<ClipPaintPropertyNode> common_clip = - ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - FloatRoundedRect(0, 0, 800, 600)); - scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create( - common_clip, TransformPaintPropertyNode::Root(), - FloatRoundedRect(0, 0, 400, 600)); - scoped_refptr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( - common_clip, TransformPaintPropertyNode::Root(), - FloatRoundedRect(400, 0, 400, 600)); + auto common_clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(0, 0, 800, 600)); + auto clip1 = CreateClip(common_clip, TransformPaintPropertyNode::Root(), + FloatRoundedRect(0, 0, 400, 600)); + auto clip2 = CreateClip(common_clip, TransformPaintPropertyNode::Root(), + FloatRoundedRect(400, 0, 400, 600)); TestPaintArtifact artifact; artifact @@ -705,13 +727,15 @@ TEST_F(PaintArtifactCompositorTest, SiblingClips) { TEST_F(PaintArtifactCompositorTest, ForeignLayerPassesThrough) { scoped_refptr<cc::Layer> layer = cc::Layer::Create(); + layer->SetIsDrawable(true); + layer->SetBounds(gfx::Size(400, 300)); TestPaintArtifact test_artifact; test_artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), EffectPaintPropertyNode::Root()) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite); - test_artifact.Chunk(DefaultPaintChunkProperties()) + test_artifact.Chunk(PropertyTreeState::Root()) .ForeignLayer(FloatPoint(50, 60), IntSize(400, 300), layer); test_artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -729,24 +753,17 @@ TEST_F(PaintArtifactCompositorTest, ForeignLayerPassesThrough) { } TEST_F(PaintArtifactCompositorTest, EffectTreeConversion) { - scoped_refptr<EffectPaintPropertyNode> effect1 = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 0.5, SkBlendMode::kSrcOver, - CompositingReason::kAll, CompositorElementId(2)); - scoped_refptr<EffectPaintPropertyNode> effect2 = - EffectPaintPropertyNode::Create( - effect1, TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 0.3, SkBlendMode::kSrcOver, - CompositingReason::kAll); - scoped_refptr<EffectPaintPropertyNode> effect3 = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 0.2, SkBlendMode::kSrcOver, - CompositingReason::kAll); + EffectPaintPropertyNode::State effect1_state; + effect1_state.local_transform_space = TransformPaintPropertyNode::Root(); + effect1_state.output_clip = ClipPaintPropertyNode::Root(); + effect1_state.opacity = 0.5; + effect1_state.direct_compositing_reasons = CompositingReason::kAll; + effect1_state.compositor_element_id = CompositorElementId(2); + auto effect1 = EffectPaintPropertyNode::Create( + EffectPaintPropertyNode::Root(), std::move(effect1_state)); + auto effect2 = CreateOpacityEffect(effect1, 0.3, CompositingReason::kAll); + auto effect3 = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.2, + CompositingReason::kAll); TestPaintArtifact artifact; artifact @@ -794,18 +811,57 @@ TEST_F(PaintArtifactCompositorTest, EffectTreeConversion) { EXPECT_EQ(converted_effect3.id, ContentLayerAt(2)->effect_tree_index()); } +// Returns a ScrollPaintPropertyNode::State with some arbitrary values. +static ScrollPaintPropertyNode::State ScrollState1() { + ScrollPaintPropertyNode::State state; + state.container_rect = IntRect(3, 5, 11, 13); + state.contents_rect = IntRect(-3, -5, 27, 31); + state.user_scrollable_horizontal = true; + return state; +} + +// Returns a ScrollPaintPropertyNode::State with another set arbitrary values. +static ScrollPaintPropertyNode::State ScrollState2() { + ScrollPaintPropertyNode::State state; + state.container_rect = IntRect(0, 0, 19, 23); + state.contents_rect = IntRect(0, 0, 29, 31); + state.user_scrollable_horizontal = true; + return state; +} + +static scoped_refptr<ScrollPaintPropertyNode> CreateScroll( + scoped_refptr<const ScrollPaintPropertyNode> parent, + const ScrollPaintPropertyNode::State& state_arg, + MainThreadScrollingReasons main_thread_scrolling_reasons = + MainThreadScrollingReason::kNotScrollingOnMain, + CompositorElementId scroll_element_id = CompositorElementId()) { + ScrollPaintPropertyNode::State state = state_arg; + state.main_thread_scrolling_reasons = main_thread_scrolling_reasons; + state.compositor_element_id = scroll_element_id; + return ScrollPaintPropertyNode::Create(parent, std::move(state)); +} + +static void CheckCcScrollNode(const ScrollPaintPropertyNode& blink_scroll, + const cc::ScrollNode& cc_scroll) { + EXPECT_EQ(static_cast<gfx::Size>(blink_scroll.ContainerRect().Size()), + cc_scroll.container_bounds); + EXPECT_EQ(static_cast<gfx::Size>(blink_scroll.ContentsRect().Size()), + cc_scroll.bounds); + EXPECT_EQ(blink_scroll.UserScrollableHorizontal(), + cc_scroll.user_scrollable_horizontal); + EXPECT_EQ(blink_scroll.UserScrollableVertical(), + cc_scroll.user_scrollable_vertical); + EXPECT_EQ(blink_scroll.GetCompositorElementId(), cc_scroll.element_id); + EXPECT_EQ(blink_scroll.GetMainThreadScrollingReasons(), + cc_scroll.main_thread_scrolling_reasons); +} + TEST_F(PaintArtifactCompositorTest, OneScrollNode) { CompositorElementId scroll_element_id = ScrollElementId(2); - scoped_refptr<ScrollPaintPropertyNode> scroll = - ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), - IntRect(3, 5, 11, 13), - IntRect(-3, -5, 27, 31), true, false, - kNotScrollingOnMain, scroll_element_id); - scoped_refptr<TransformPaintPropertyNode> scroll_translation = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - CompositingReason::kNone, CompositorElementId(), scroll); + auto scroll = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(), + kNotScrollingOnMain, scroll_element_id); + auto scroll_translation = + CreateScrollTranslation(TransformPaintPropertyNode::Root(), 7, 9, scroll); TestPaintArtifact artifact; artifact @@ -822,14 +878,10 @@ TEST_F(PaintArtifactCompositorTest, OneScrollNode) { // Node #0 reserved for null; #1 for root render surface. ASSERT_EQ(3u, scroll_tree.size()); const cc::ScrollNode& scroll_node = *scroll_tree.Node(2); - EXPECT_EQ(gfx::Size(11, 13), scroll_node.container_bounds); - EXPECT_EQ(gfx::Size(27, 31), scroll_node.bounds); - EXPECT_TRUE(scroll_node.user_scrollable_horizontal); - EXPECT_FALSE(scroll_node.user_scrollable_vertical); + CheckCcScrollNode(*scroll, scroll_node); EXPECT_EQ(1, scroll_node.parent_id); - EXPECT_EQ(scroll_element_id, scroll_node.element_id); - EXPECT_EQ(scroll_node.id, ElementIdToScrollNodeIndex(scroll_element_id)); EXPECT_EQ(scroll_element_id, ScrollHitTestLayerAt(0)->element_id()); + EXPECT_EQ(scroll_node.id, ElementIdToScrollNodeIndex(scroll_element_id)); const cc::TransformTree& transform_tree = GetPropertyTrees().transform_tree; const cc::TransformNode& transform_node = @@ -867,21 +919,13 @@ TEST_F(PaintArtifactCompositorTest, OneScrollNode) { } TEST_F(PaintArtifactCompositorTest, TransformUnderScrollNode) { - scoped_refptr<ScrollPaintPropertyNode> scroll = - ScrollPaintPropertyNode::Create( - ScrollPaintPropertyNode::Root(), IntRect(0, 0, 11, 13), - IntRect(-3, -5, 27, 31), true, false, kNotScrollingOnMain, - CompositorElementId()); - scoped_refptr<TransformPaintPropertyNode> scroll_translation = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - CompositingReason::kNone, CompositorElementId(), scroll); - - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - scroll_translation, TransformationMatrix(), FloatPoint3D(), false, 0, - CompositingReason::k3DTransform); + auto scroll = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1()); + auto scroll_translation = + CreateScrollTranslation(TransformPaintPropertyNode::Root(), 7, 9, scroll); + + auto transform = + CreateTransform(scroll_translation, TransformationMatrix(), + FloatPoint3D(), CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact @@ -925,34 +969,22 @@ TEST_F(PaintArtifactCompositorTest, TransformUnderScrollNode) { } TEST_F(PaintArtifactCompositorTest, NestedScrollNodes) { - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); CompositorElementId scroll_element_id_a = ScrollElementId(2); - scoped_refptr<ScrollPaintPropertyNode> scroll_a = - ScrollPaintPropertyNode::Create( - ScrollPaintPropertyNode::Root(), IntRect(0, 0, 2, 3), - IntRect(0, 0, 5, 7), false, true, - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, - scroll_element_id_a); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_a = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(11, 13), FloatPoint3D(), false, 0, - CompositingReason::kLayerForScrollingContents, CompositorElementId(), - scroll_a); + auto scroll_a = CreateScroll( + ScrollPaintPropertyNode::Root(), ScrollState1(), + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects, + scroll_element_id_a); + auto scroll_translation_a = CreateScrollTranslation( + TransformPaintPropertyNode::Root(), 11, 13, scroll_a, + CompositingReason::kLayerForScrollingContents); CompositorElementId scroll_element_id_b = ScrollElementId(3); - scoped_refptr<ScrollPaintPropertyNode> scroll_b = - ScrollPaintPropertyNode::Create(scroll_translation_a->ScrollNode(), - IntRect(0, 0, 19, 23), - IntRect(0, 0, 29, 31), true, false, - kNotScrollingOnMain, scroll_element_id_b); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_b = - TransformPaintPropertyNode::Create( - scroll_translation_a, TransformationMatrix().Translate(37, 41), - FloatPoint3D(), false, 0, CompositingReason::kNone, - CompositorElementId(), scroll_b); + auto scroll_b = CreateScroll(scroll_a, ScrollState2(), kNotScrollingOnMain, + scroll_element_id_b); + auto scroll_translation_b = + CreateScrollTranslation(scroll_translation_a, 37, 41, scroll_b); TestPaintArtifact artifact; artifact.Chunk(scroll_translation_a, ClipPaintPropertyNode::Root(), effect) .RectDrawing(FloatRect(7, 11, 13, 17), Color::kWhite); @@ -972,16 +1004,10 @@ TEST_F(PaintArtifactCompositorTest, NestedScrollNodes) { // Node #0 reserved for null; #1 for root render surface. ASSERT_EQ(4u, scroll_tree.size()); const cc::ScrollNode& scroll_node_a = *scroll_tree.Node(2); - EXPECT_EQ(gfx::Size(2, 3), scroll_node_a.container_bounds); - EXPECT_EQ(gfx::Size(5, 7), scroll_node_a.bounds); - EXPECT_FALSE(scroll_node_a.user_scrollable_horizontal); - EXPECT_TRUE(scroll_node_a.user_scrollable_vertical); + CheckCcScrollNode(*scroll_a, scroll_node_a); EXPECT_EQ(1, scroll_node_a.parent_id); - EXPECT_EQ(scroll_element_id_a, scroll_node_a.element_id); - EXPECT_EQ(scroll_node_a.id, ElementIdToScrollNodeIndex(scroll_element_id_a)); - EXPECT_TRUE(scroll_node_a.main_thread_scrolling_reasons & - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); EXPECT_EQ(scroll_element_id_a, ScrollHitTestLayerAt(0)->element_id()); + EXPECT_EQ(scroll_node_a.id, ElementIdToScrollNodeIndex(scroll_element_id_a)); const cc::TransformTree& transform_tree = GetPropertyTrees().transform_tree; const cc::TransformNode& transform_node_a = @@ -990,12 +1016,10 @@ TEST_F(PaintArtifactCompositorTest, NestedScrollNodes) { EXPECT_EQ(gfx::ScrollOffset(-11, -13), transform_node_a.scroll_offset); const cc::ScrollNode& scroll_node_b = *scroll_tree.Node(3); - EXPECT_EQ(gfx::Size(19, 23), scroll_node_b.container_bounds); - EXPECT_EQ(gfx::Size(29, 31), scroll_node_b.bounds); + CheckCcScrollNode(*scroll_b, scroll_node_b); EXPECT_EQ(scroll_node_a.id, scroll_node_b.parent_id); - EXPECT_EQ(scroll_element_id_b, scroll_node_b.element_id); - EXPECT_EQ(scroll_node_b.id, ElementIdToScrollNodeIndex(scroll_element_id_b)); EXPECT_EQ(scroll_element_id_b, ScrollHitTestLayerAt(1)->element_id()); + EXPECT_EQ(scroll_node_b.id, ElementIdToScrollNodeIndex(scroll_element_id_b)); const cc::TransformNode& transform_node_b = *transform_tree.Node(scroll_node_b.transform_id); @@ -1004,27 +1028,20 @@ TEST_F(PaintArtifactCompositorTest, NestedScrollNodes) { } TEST_F(PaintArtifactCompositorTest, ScrollHitTestLayerOrder) { - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(0, 0, 100, 100)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(0, 0, 100, 100)); CompositorElementId scroll_element_id = ScrollElementId(2); - scoped_refptr<ScrollPaintPropertyNode> scroll = - ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), - IntRect(0, 0, 100, 100), - IntRect(0, 0, 100, 100), true, false, - kNotScrollingOnMain, scroll_element_id); - scoped_refptr<TransformPaintPropertyNode> scroll_translation = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - CompositingReason::kWillChangeCompositingHint, CompositorElementId(), - scroll); - - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - scroll_translation, TransformationMatrix().Translate(5, 5), - FloatPoint3D(), false, 0, CompositingReason::k3DTransform); + auto scroll = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(), + kNotScrollingOnMain, scroll_element_id); + auto scroll_translation = + CreateScrollTranslation(TransformPaintPropertyNode::Root(), 7, 9, scroll, + CompositingReason::kWillChangeCompositingHint); + + auto transform = CreateTransform( + scroll_translation, TransformationMatrix().Translate(5, 5), + FloatPoint3D(), CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact.Chunk(scroll_translation, clip, EffectPaintPropertyNode::Root()) @@ -1055,36 +1072,24 @@ TEST_F(PaintArtifactCompositorTest, ScrollHitTestLayerOrder) { } TEST_F(PaintArtifactCompositorTest, NestedScrollHitTestLayerOrder) { - scoped_refptr<ClipPaintPropertyNode> clip_1 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(0, 0, 100, 100)); + auto clip_1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(0, 0, 100, 100)); CompositorElementId scroll_1_element_id = ScrollElementId(1); - scoped_refptr<ScrollPaintPropertyNode> scroll_1 = - ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), - IntRect(0, 0, 100, 100), - IntRect(0, 0, 100, 100), true, false, - kNotScrollingOnMain, scroll_1_element_id); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_1 = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(7, 9), FloatPoint3D(), false, 0, - CompositingReason::kWillChangeCompositingHint, CompositorElementId(), - scroll_1); - - scoped_refptr<ClipPaintPropertyNode> clip_2 = ClipPaintPropertyNode::Create( - clip_1, scroll_translation_1, FloatRoundedRect(0, 0, 50, 50)); + auto scroll_1 = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(), + kNotScrollingOnMain, scroll_1_element_id); + auto scroll_translation_1 = CreateScrollTranslation( + TransformPaintPropertyNode::Root(), 7, 9, scroll_1, + CompositingReason::kWillChangeCompositingHint); + + auto clip_2 = + CreateClip(clip_1, scroll_translation_1, FloatRoundedRect(0, 0, 50, 50)); CompositorElementId scroll_2_element_id = ScrollElementId(2); - scoped_refptr<ScrollPaintPropertyNode> scroll_2 = - ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), - IntRect(0, 0, 50, 50), - IntRect(0, 0, 50, 50), true, false, - kNotScrollingOnMain, scroll_2_element_id); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_2 = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(0, 0), FloatPoint3D(), false, 0, - CompositingReason::kWillChangeCompositingHint, CompositorElementId(), - scroll_2); + auto scroll_2 = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState2(), + kNotScrollingOnMain, scroll_2_element_id); + auto scroll_translation_2 = CreateScrollTranslation( + TransformPaintPropertyNode::Root(), 0, 0, scroll_2, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact @@ -1130,29 +1135,17 @@ TEST_F(PaintArtifactCompositorTest, NestedScrollHitTestLayerOrder) { // node is correctly created. TEST_F(PaintArtifactCompositorTest, AncestorScrollNodes) { CompositorElementId scroll_element_id_a = ScrollElementId(2); - scoped_refptr<ScrollPaintPropertyNode> scroll_a = - ScrollPaintPropertyNode::Create(ScrollPaintPropertyNode::Root(), - IntRect(0, 0, 2, 3), IntRect(0, 0, 5, 7), - false, true, kNotScrollingOnMain, - scroll_element_id_a); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_a = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(11, 13), FloatPoint3D(), false, 0, - CompositingReason::kLayerForScrollingContents, CompositorElementId(), - scroll_a); + auto scroll_a = CreateScroll(ScrollPaintPropertyNode::Root(), ScrollState1(), + kNotScrollingOnMain, scroll_element_id_a); + auto scroll_translation_a = CreateScrollTranslation( + TransformPaintPropertyNode::Root(), 11, 13, scroll_a, + CompositingReason::kLayerForScrollingContents); CompositorElementId scroll_element_id_b = ScrollElementId(3); - scoped_refptr<ScrollPaintPropertyNode> scroll_b = - ScrollPaintPropertyNode::Create(scroll_translation_a->ScrollNode(), - IntRect(0, 0, 19, 23), - IntRect(0, 0, 29, 31), true, false, - kNotScrollingOnMain, scroll_element_id_b); - scoped_refptr<TransformPaintPropertyNode> scroll_translation_b = - TransformPaintPropertyNode::Create( - scroll_translation_a, TransformationMatrix().Translate(37, 41), - FloatPoint3D(), false, 0, CompositingReason::kNone, - CompositorElementId(), scroll_b); + auto scroll_b = CreateScroll(scroll_a, ScrollState2(), kNotScrollingOnMain, + scroll_element_id_b); + auto scroll_translation_b = + CreateScrollTranslation(scroll_translation_a, 37, 41, scroll_b); TestPaintArtifact artifact; artifact @@ -1227,9 +1220,9 @@ TEST_F(PaintArtifactCompositorTest, MergeSimpleChunks) { } TEST_F(PaintArtifactCompositorTest, MergeClip) { - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 20, 50, 60)); TestPaintArtifact test_artifact; test_artifact @@ -1267,11 +1260,9 @@ TEST_F(PaintArtifactCompositorTest, MergeClip) { } TEST_F(PaintArtifactCompositorTest, Merge2DTransform) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(50, 50), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(50, 50), + FloatPoint3D(100, 100, 0)); TestPaintArtifact test_artifact; test_artifact @@ -1309,15 +1300,13 @@ TEST_F(PaintArtifactCompositorTest, Merge2DTransform) { } TEST_F(PaintArtifactCompositorTest, Merge2DTransformDirectAncestor) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix(), - FloatPoint3D(), false, 0, CompositingReason::k3DTransform); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix(), FloatPoint3D(), + CompositingReason::k3DTransform); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform.get(), TransformationMatrix().Translate(50, 50), - FloatPoint3D(100, 100, 0), false, 0); + auto transform2 = + CreateTransform(transform.get(), TransformationMatrix().Translate(50, 50), + FloatPoint3D(100, 100, 0)); TestPaintArtifact test_artifact; test_artifact @@ -1350,10 +1339,9 @@ TEST_F(PaintArtifactCompositorTest, Merge2DTransformDirectAncestor) { } TEST_F(PaintArtifactCompositorTest, MergeTransformOrigin) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix().Rotate(45), - FloatPoint3D(100, 100, 0), false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Rotate(45), + FloatPoint3D(100, 100, 0)); TestPaintArtifact test_artifact; test_artifact @@ -1391,8 +1379,7 @@ TEST_F(PaintArtifactCompositorTest, MergeTransformOrigin) { TEST_F(PaintArtifactCompositorTest, MergeOpacity) { float opacity = 2.0 / 255.0; - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), opacity); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), opacity); TestPaintArtifact test_artifact; test_artifact @@ -1433,22 +1420,16 @@ TEST_F(PaintArtifactCompositorTest, MergeNested) { // Tests merging of an opacity effect, inside of a clip, inside of a // transform. - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(50, 50), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(50, 50), + FloatPoint3D(100, 100, 0)); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), transform.get(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), transform.get(), + FloatRoundedRect(10, 20, 50, 60)); float opacity = 2.0 / 255.0; - scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), transform.get(), clip.get(), - kColorFilterNone, CompositorFilterOperations(), opacity, - SkBlendMode::kSrcOver); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), transform, + clip, opacity); TestPaintArtifact test_artifact; test_artifact @@ -1488,20 +1469,16 @@ TEST_F(PaintArtifactCompositorTest, ClipPushedUp) { // but has an ancestor transform of them. This can happen for fixed- // or absolute-position elements which escape scroll transforms. - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(20, 25), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform.get(), TransformationMatrix().Translate(20, 25), - FloatPoint3D(100, 100, 0), false, 0); + auto transform2 = + CreateTransform(transform.get(), TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), transform2.get(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), transform2.get(), + FloatRoundedRect(10, 20, 50, 60)); TestPaintArtifact test_artifact; test_artifact @@ -1546,23 +1523,17 @@ TEST_F(PaintArtifactCompositorTest, EffectPushedUp_DISABLED) { // but has an ancestor transform of them. This can happen for fixed- // or absolute-position elements which escape scroll transforms. - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(20, 25), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform.get(), TransformationMatrix().Translate(20, 25), - FloatPoint3D(100, 100, 0), false, 0); + auto transform2 = + CreateTransform(transform.get(), TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); float opacity = 2.0 / 255.0; - scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), transform2.get(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), opacity, SkBlendMode::kSrcOver); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), transform2, + ClipPaintPropertyNode::Root(), opacity); TestPaintArtifact test_artifact; test_artifact @@ -1606,27 +1577,20 @@ TEST_F(PaintArtifactCompositorTest, EffectAndClipPushedUp_DISABLED) { // but has an ancestor transform of them. This can happen for fixed- // or absolute-position elements which escape scroll transforms. - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(20, 25), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform.get(), TransformationMatrix().Translate(20, 25), - FloatPoint3D(100, 100, 0), false, 0); + auto transform2 = + CreateTransform(transform.get(), TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), transform.get(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), transform.get(), + FloatRoundedRect(10, 20, 50, 60)); float opacity = 2.0 / 255.0; - scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), transform2.get(), clip.get(), - kColorFilterNone, CompositorFilterOperations(), opacity, - SkBlendMode::kSrcOver); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), transform2, + clip, opacity); TestPaintArtifact test_artifact; test_artifact @@ -1667,16 +1631,14 @@ TEST_F(PaintArtifactCompositorTest, ClipAndEffectNoTransform) { // Tests merging of an element which has a clip and effect in the root // transform space. - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 20, 50, 60)); float opacity = 2.0 / 255.0; - scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - clip.get(), kColorFilterNone, CompositorFilterOperations(), opacity, - SkBlendMode::kSrcOver); + auto effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), clip, opacity); TestPaintArtifact test_artifact; test_artifact @@ -1715,13 +1677,12 @@ TEST_F(PaintArtifactCompositorTest, TwoClips) { // Tests merging of an element which has two clips in the root // transform space. - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(20, 30, 10, 20)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(20, 30, 10, 20)); - scoped_refptr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( - clip.get(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 20, 50, 60)); + auto clip2 = CreateClip(clip.get(), TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 20, 50, 60)); TestPaintArtifact test_artifact; test_artifact @@ -1758,18 +1719,15 @@ TEST_F(PaintArtifactCompositorTest, TwoClips) { } TEST_F(PaintArtifactCompositorTest, TwoTransformsClipBetween) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(20, 25), FloatPoint3D(100, 100, 0), - false, 0); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(0, 0, 50, 60)); - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - transform.get(), TransformationMatrix().Translate(20, 25), - FloatPoint3D(100, 100, 0), false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(0, 0, 50, 60)); + auto transform2 = + CreateTransform(transform.get(), TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); TestPaintArtifact test_artifact; test_artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -1802,20 +1760,19 @@ TEST_F(PaintArtifactCompositorTest, TwoTransformsClipBetween) { } TEST_F(PaintArtifactCompositorTest, OverlapTransform) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(50, 50), FloatPoint3D(100, 100, 0), - false, 0, CompositingReason::k3DTransform); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(50, 50), + FloatPoint3D(100, 100, 0), + CompositingReason::k3DTransform); TestPaintArtifact test_artifact; - test_artifact.Chunk(DefaultPaintChunkProperties()) + test_artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kWhite); test_artifact .Chunk(transform.get(), ClipPaintPropertyNode::Root(), EffectPaintPropertyNode::Root()) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack); - test_artifact.Chunk(DefaultPaintChunkProperties()) + test_artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(0, 0, 200, 300), Color::kGray); const PaintArtifact& artifact = test_artifact.Build(); @@ -1840,24 +1797,20 @@ TEST_F(PaintArtifactCompositorTest, MightOverlap) { EXPECT_TRUE(MightOverlap(pending_layer, pending_layer2)); } - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(99, 0), FloatPoint3D(100, 100, 0), - false); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(99, 0), + FloatPoint3D(100, 100, 0)); { - paint_chunk2.properties.property_tree_state.SetTransform(transform.get()); + paint_chunk2.properties.SetTransform(transform.get()); PendingLayer pending_layer2(paint_chunk2, 1, false); EXPECT_TRUE(MightOverlap(pending_layer, pending_layer2)); } - scoped_refptr<TransformPaintPropertyNode> transform2 = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(100, 0), FloatPoint3D(100, 100, 0), - false); + auto transform2 = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(100, 0), + FloatPoint3D(100, 100, 0)); { - paint_chunk2.properties.property_tree_state.SetTransform(transform2.get()); + paint_chunk2.properties.SetTransform(transform2.get()); PendingLayer pending_layer2(paint_chunk2, 1, false); EXPECT_FALSE(MightOverlap(pending_layer, pending_layer2)); } @@ -1865,57 +1818,47 @@ TEST_F(PaintArtifactCompositorTest, MightOverlap) { TEST_F(PaintArtifactCompositorTest, PendingLayer) { PaintChunk chunk1 = DefaultChunk(); - chunk1.properties.property_tree_state = PropertyTreeState( - TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root()); - chunk1.properties.backface_hidden = true; + chunk1.properties = PropertyTreeState::Root(); chunk1.known_to_be_opaque = true; chunk1.bounds = FloatRect(0, 0, 30, 40); PendingLayer pending_layer(chunk1, 0, false); - EXPECT_TRUE(pending_layer.backface_hidden); EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); EXPECT_EQ((Vector<size_t>{0}), pending_layer.paint_chunk_indices); EXPECT_EQ(pending_layer.bounds, pending_layer.rect_known_to_be_opaque); PaintChunk chunk2 = DefaultChunk(); - chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; - chunk2.properties.backface_hidden = true; + chunk2.properties = chunk1.properties; chunk2.known_to_be_opaque = true; chunk2.bounds = FloatRect(10, 20, 30, 40); pending_layer.Merge(PendingLayer(chunk2, 1, false)); - EXPECT_TRUE(pending_layer.backface_hidden); // Bounds not equal to one PaintChunk. EXPECT_EQ(FloatRect(0, 0, 40, 60), pending_layer.bounds); EXPECT_EQ((Vector<size_t>{0, 1}), pending_layer.paint_chunk_indices); EXPECT_NE(pending_layer.bounds, pending_layer.rect_known_to_be_opaque); PaintChunk chunk3 = DefaultChunk(); - chunk3.properties.property_tree_state = chunk1.properties.property_tree_state; - chunk3.properties.backface_hidden = true; + chunk3.properties = chunk1.properties; chunk3.known_to_be_opaque = true; chunk3.bounds = FloatRect(-5, -25, 20, 20); pending_layer.Merge(PendingLayer(chunk3, 2, false)); - EXPECT_TRUE(pending_layer.backface_hidden); EXPECT_EQ(FloatRect(-5, -25, 45, 85), pending_layer.bounds); EXPECT_EQ((Vector<size_t>{0, 1, 2}), pending_layer.paint_chunk_indices); EXPECT_NE(pending_layer.bounds, pending_layer.rect_known_to_be_opaque); } TEST_F(PaintArtifactCompositorTest, PendingLayerWithGeometry) { - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(20, 25), FloatPoint3D(100, 100, 0), - false, 0); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(20, 25), + FloatPoint3D(100, 100, 0)); PaintChunk chunk1 = DefaultChunk(); - chunk1.properties.property_tree_state = PropertyTreeState( - TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root()); + chunk1.properties = PropertyTreeState(TransformPaintPropertyNode::Root(), + ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()); chunk1.bounds = FloatRect(0, 0, 30, 40); PendingLayer pending_layer(chunk1, 0, false); @@ -1923,8 +1866,8 @@ TEST_F(PaintArtifactCompositorTest, PendingLayerWithGeometry) { EXPECT_EQ(FloatRect(0, 0, 30, 40), pending_layer.bounds); PaintChunk chunk2 = DefaultChunk(); - chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; - chunk2.properties.property_tree_state.SetTransform(transform); + chunk2.properties = chunk1.properties; + chunk2.properties.SetTransform(transform); chunk2.bounds = FloatRect(0, 0, 50, 60); pending_layer.Merge(PendingLayer(chunk2, 1, false)); @@ -1935,9 +1878,9 @@ TEST_F(PaintArtifactCompositorTest, PendingLayerWithGeometry) { // The test is disabled because opaque rect mapping is not implemented yet. TEST_F(PaintArtifactCompositorTest, PendingLayerKnownOpaque_DISABLED) { PaintChunk chunk1 = DefaultChunk(); - chunk1.properties.property_tree_state = PropertyTreeState( - TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - EffectPaintPropertyNode::Root()); + chunk1.properties = PropertyTreeState(TransformPaintPropertyNode::Root(), + ClipPaintPropertyNode::Root(), + EffectPaintPropertyNode::Root()); chunk1.bounds = FloatRect(0, 0, 30, 40); chunk1.known_to_be_opaque = false; PendingLayer pending_layer(chunk1, 0, false); @@ -1945,7 +1888,7 @@ TEST_F(PaintArtifactCompositorTest, PendingLayerKnownOpaque_DISABLED) { EXPECT_TRUE(pending_layer.rect_known_to_be_opaque.IsEmpty()); PaintChunk chunk2 = DefaultChunk(); - chunk2.properties.property_tree_state = chunk1.properties.property_tree_state; + chunk2.properties = chunk1.properties; chunk2.bounds = FloatRect(0, 0, 25, 35); chunk2.known_to_be_opaque = true; pending_layer.Merge(PendingLayer(chunk2, 1, false)); @@ -1955,7 +1898,7 @@ TEST_F(PaintArtifactCompositorTest, PendingLayerKnownOpaque_DISABLED) { EXPECT_NE(pending_layer.bounds, pending_layer.rect_known_to_be_opaque); PaintChunk chunk3 = DefaultChunk(); - chunk3.properties.property_tree_state = chunk1.properties.property_tree_state; + chunk3.properties = chunk1.properties; chunk3.bounds = FloatRect(0, 0, 50, 60); chunk3.known_to_be_opaque = true; pending_layer.Merge(PendingLayer(chunk3, 2, false)); @@ -1966,28 +1909,29 @@ TEST_F(PaintArtifactCompositorTest, PendingLayerKnownOpaque_DISABLED) { } scoped_refptr<EffectPaintPropertyNode> CreateSampleEffectNodeWithElementId() { - CompositorElementId expected_compositor_element_id(2); - float opacity = 2.0 / 255.0; - return EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), opacity, SkBlendMode::kSrcOver, - CompositingReason::kActiveOpacityAnimation, - expected_compositor_element_id); + EffectPaintPropertyNode::State state; + state.local_transform_space = TransformPaintPropertyNode::Root(); + state.output_clip = ClipPaintPropertyNode::Root(); + state.opacity = 2.0 / 255.0; + state.direct_compositing_reasons = CompositingReason::kActiveOpacityAnimation; + state.compositor_element_id = CompositorElementId(2); + return EffectPaintPropertyNode::Create(EffectPaintPropertyNode::Root(), + std::move(state)); } scoped_refptr<TransformPaintPropertyNode> CreateSampleTransformNodeWithElementId() { - CompositorElementId expected_compositor_element_id(3); - return TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), - FloatPoint3D(100, 100, 0), false, 0, CompositingReason::k3DTransform, - expected_compositor_element_id); + TransformPaintPropertyNode::State state; + state.matrix.Rotate(90); + state.origin = FloatPoint3D(100, 100, 0); + state.direct_compositing_reasons = CompositingReason::k3DTransform; + state.compositor_element_id = CompositorElementId(3); + return TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), + std::move(state)); } TEST_F(PaintArtifactCompositorTest, TransformWithElementId) { - scoped_refptr<TransformPaintPropertyNode> transform = - CreateSampleTransformNodeWithElementId(); + auto transform = CreateSampleTransformNodeWithElementId(); TestPaintArtifact artifact; artifact .Chunk(transform, ClipPaintPropertyNode::Root(), @@ -2000,8 +1944,7 @@ TEST_F(PaintArtifactCompositorTest, TransformWithElementId) { } TEST_F(PaintArtifactCompositorTest, EffectWithElementId) { - scoped_refptr<EffectPaintPropertyNode> effect = - CreateSampleEffectNodeWithElementId(); + auto effect = CreateSampleEffectNodeWithElementId(); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -2013,18 +1956,18 @@ TEST_F(PaintArtifactCompositorTest, EffectWithElementId) { } TEST_F(PaintArtifactCompositorTest, CompositedLuminanceMask) { - scoped_refptr<EffectPaintPropertyNode> masked = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 1.0, SkBlendMode::kSrcOver, - CompositingReason::kIsolateCompositedDescendants); - scoped_refptr<EffectPaintPropertyNode> masking = - EffectPaintPropertyNode::Create( - masked, TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterLuminanceToAlpha, - CompositorFilterOperations(), 1.0, SkBlendMode::kDstIn, - CompositingReason::kSquashingDisallowed); + auto masked = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 1.0, + CompositingReason::kIsolateCompositedDescendants); + EffectPaintPropertyNode::State masking_state; + masking_state.local_transform_space = TransformPaintPropertyNode::Root(); + masking_state.output_clip = ClipPaintPropertyNode::Root(); + masking_state.color_filter = kColorFilterLuminanceToAlpha; + masking_state.blend_mode = SkBlendMode::kDstIn; + masking_state.direct_compositing_reasons = + CompositingReason::kSquashingDisallowed; + auto masking = + EffectPaintPropertyNode::Create(masked, std::move(masking_state)); TestPaintArtifact artifact; artifact @@ -2064,17 +2007,15 @@ TEST_F(PaintArtifactCompositorTest, CompositedLuminanceMask) { TEST_F(PaintArtifactCompositorTest, UpdateProducesNewSequenceNumber) { // A 90 degree clockwise rotation about (100, 100). - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), - FloatPoint3D(100, 100, 0), false, 0, CompositingReason::k3DTransform); + auto transform = CreateTransform( + TransformPaintPropertyNode::Root(), TransformationMatrix().Rotate(90), + FloatPoint3D(100, 100, 0), CompositingReason::k3DTransform); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(100, 100, 300, 200)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(100, 100, 300, 200)); - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); TestPaintArtifact artifact; artifact.Chunk(transform, clip, effect) @@ -2117,9 +2058,9 @@ TEST_F(PaintArtifactCompositorTest, DecompositeClip) { // A clipped paint chunk that gets merged into a previous layer should // only contribute clipped bounds to the layer bound. - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(75, 75, 100, 100)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(75, 75, 100, 100)); TestPaintArtifact artifact; artifact @@ -2143,8 +2084,7 @@ TEST_F(PaintArtifactCompositorTest, DecompositeEffect) { // group compositing descendants should not be composited and can merge // with other chunks. - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); TestPaintArtifact artifact; artifact @@ -2170,12 +2110,8 @@ TEST_F(PaintArtifactCompositorTest, DecompositeEffect) { TEST_F(PaintArtifactCompositorTest, DirectlyCompositedEffect) { // An effect node with direct compositing shall be composited. - scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 0.5f, SkBlendMode::kSrcOver, - CompositingReason::kAll); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5f, + CompositingReason::kAll); TestPaintArtifact artifact; artifact @@ -2216,16 +2152,9 @@ TEST_F(PaintArtifactCompositorTest, DecompositeDeepEffect) { // A paint chunk may enter multiple level effects with or without compositing // reasons. This test verifies we still decomposite effects without a direct // reason, but stop at a directly composited effect. - scoped_refptr<EffectPaintPropertyNode> effect1 = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.1f); - scoped_refptr<EffectPaintPropertyNode> effect2 = - EffectPaintPropertyNode::Create( - effect1, TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 0.2f, SkBlendMode::kSrcOver, - CompositingReason::kAll); - scoped_refptr<EffectPaintPropertyNode> effect3 = - CreateOpacityOnlyEffect(effect2, 0.3f); + auto effect1 = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.1f); + auto effect2 = CreateOpacityEffect(effect1, 0.2f, CompositingReason::kAll); + auto effect3 = CreateOpacityEffect(effect2, 0.3f); TestPaintArtifact artifact; artifact @@ -2268,12 +2197,10 @@ TEST_F(PaintArtifactCompositorTest, DecompositeDeepEffect) { TEST_F(PaintArtifactCompositorTest, IndirectlyCompositedEffect) { // An effect node without direct compositing still needs to be composited // for grouping, if some chunks need to be composited. - scoped_refptr<EffectPaintPropertyNode> effect = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5f); - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix(), - FloatPoint3D(), false, 0, CompositingReason::k3DTransform); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5f); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix(), FloatPoint3D(), + CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact @@ -2311,14 +2238,11 @@ TEST_F(PaintArtifactCompositorTest, IndirectlyCompositedEffect) { TEST_F(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) { // This tests an effect that doesn't need to be composited, but needs // separate backing due to overlap with a previous composited effect. - scoped_refptr<EffectPaintPropertyNode> effect1 = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.1f); - scoped_refptr<EffectPaintPropertyNode> effect2 = - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.2f); - scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix(), - FloatPoint3D(), false, 0, CompositingReason::k3DTransform); + auto effect1 = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.1f); + auto effect2 = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.2f); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix(), FloatPoint3D(), + CompositingReason::k3DTransform); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -2372,10 +2296,8 @@ TEST_F(PaintArtifactCompositorTest, DecompositedEffectNotMergingDueToOverlap) { } TEST_F(PaintArtifactCompositorTest, UpdatePopulatesCompositedElementIds) { - scoped_refptr<TransformPaintPropertyNode> transform = - CreateSampleTransformNodeWithElementId(); - scoped_refptr<EffectPaintPropertyNode> effect = - CreateSampleEffectNodeWithElementId(); + auto transform = CreateSampleTransformNodeWithElementId(); + auto effect = CreateSampleEffectNodeWithElementId(); TestPaintArtifact artifact; artifact .Chunk(transform, ClipPaintPropertyNode::Root(), @@ -2487,21 +2409,10 @@ TEST_F(PaintArtifactCompositorTest, DontSkipChunkWithAboveMinimumOpacity) { } } -scoped_refptr<EffectPaintPropertyNode> CreateEffectWithOpacityAndReason( - float opacity, - CompositingReasons reason, - scoped_refptr<EffectPaintPropertyNode> parent = nullptr) { - return EffectPaintPropertyNode::Create( - parent ? parent : EffectPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - kColorFilterNone, CompositorFilterOperations(), opacity, - SkBlendMode::kSrcOver, reason); -} - TEST_F(PaintArtifactCompositorTest, DontSkipChunkWithTinyOpacityAndDirectCompositingReason) { - scoped_refptr<EffectPaintPropertyNode> effect = - CreateEffectWithOpacityAndReason(0.0001f, CompositingReason::kCanvas); + auto effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.0001f, + CompositingReason::kCanvas); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -2513,15 +2424,14 @@ TEST_F(PaintArtifactCompositorTest, TEST_F(PaintArtifactCompositorTest, SkipChunkWithTinyOpacityAndVisibleChildEffectNode) { - scoped_refptr<EffectPaintPropertyNode> tinyEffect = - CreateEffectWithOpacityAndReason(0.0001f, CompositingReason::kNone); - scoped_refptr<EffectPaintPropertyNode> visibleEffect = - CreateEffectWithOpacityAndReason(0.5f, CompositingReason::kNone, - tinyEffect); + auto tiny_effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), + 0.0001f, CompositingReason::kNone); + auto visible_effect = + CreateOpacityEffect(tiny_effect, 0.5f, CompositingReason::kNone); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - visibleEffect) + visible_effect) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack); Update(artifact.Build()); ASSERT_EQ(0u, ContentLayerCount()); @@ -2530,15 +2440,13 @@ TEST_F(PaintArtifactCompositorTest, TEST_F( PaintArtifactCompositorTest, DontSkipChunkWithTinyOpacityAndVisibleChildEffectNodeWithCompositingParent) { - scoped_refptr<EffectPaintPropertyNode> tinyEffect = - CreateEffectWithOpacityAndReason(0.0001f, CompositingReason::kCanvas); - scoped_refptr<EffectPaintPropertyNode> visibleEffect = - CreateEffectWithOpacityAndReason(0.5f, CompositingReason::kNone, - tinyEffect); + auto tiny_effect = CreateOpacityEffect(EffectPaintPropertyNode::Root(), + 0.0001f, CompositingReason::kCanvas); + auto visible_effect = CreateOpacityEffect(tiny_effect, 0.5f); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - visibleEffect) + visible_effect) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack); Update(artifact.Build()); ASSERT_EQ(1u, ContentLayerCount()); @@ -2546,23 +2454,21 @@ TEST_F( TEST_F(PaintArtifactCompositorTest, SkipChunkWithTinyOpacityAndVisibleChildEffectNodeWithCompositingChild) { - scoped_refptr<EffectPaintPropertyNode> tinyEffect = - CreateEffectWithOpacityAndReason(0.0001f, CompositingReason::kNone); - scoped_refptr<EffectPaintPropertyNode> visibleEffect = - CreateEffectWithOpacityAndReason(0.5f, CompositingReason::kCanvas, - tinyEffect); + auto tiny_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.0001f); + auto visible_effect = + CreateOpacityEffect(tiny_effect, 0.5f, CompositingReason::kCanvas); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), - visibleEffect) + visible_effect) .RectDrawing(FloatRect(0, 0, 100, 100), Color::kBlack); Update(artifact.Build()); ASSERT_EQ(0u, ContentLayerCount()); } TEST_F(PaintArtifactCompositorTest, UpdateManagesLayerElementIds) { - scoped_refptr<TransformPaintPropertyNode> transform = - CreateSampleTransformNodeWithElementId(); + auto transform = CreateSampleTransformNodeWithElementId(); CompositorElementId element_id = transform->GetCompositorElementId(); { @@ -2592,9 +2498,8 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipSimple) { FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -2642,13 +2547,9 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipIndirectlyCompositedClipPath) { // This tests the case that a clip node needs to be synthesized due to // applying clip path to a composited effect. - FloatRoundedRect clip_rect(50, 50, 300, 200); - scoped_refptr<RefCountedPath> clip_path = base::AdoptRef(new RefCountedPath); - scoped_refptr<ClipPaintPropertyNode> c1 = - ClipPaintPropertyNode::Create(c0(), t0(), clip_rect, nullptr, clip_path); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c1, ColorFilter(), CompositorFilterOperations(), 1, - SkBlendMode::kSrcOver, CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClipPathClip(c0(), t0(), FloatRoundedRect(50, 50, 300, 200)); + auto e1 = CreateOpacityEffect(e0(), t0(), c1, 1, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e1) @@ -2700,17 +2601,14 @@ TEST_F(PaintArtifactCompositorTest, TEST_F(PaintArtifactCompositorTest, SynthesizedClipContiguous) { // This tests the case that a two back-to-back composited layers having // the same composited rounded clip can share the synthesized mask. - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix(), FloatPoint3D(), false, 0, - CompositingReason::kWillChangeCompositingHint); + auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(), + CompositingReason::kWillChangeCompositingHint); FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -2772,17 +2670,14 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipDiscontiguous) { // This tests the case that a two composited layers having the same // composited rounded clip cannot share the synthesized mask if there is // another layer in the middle. - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix(), FloatPoint3D(), false, 0, - CompositingReason::kWillChangeCompositingHint); + auto t1 = CreateTransform(t0(), TransformationMatrix(), FloatPoint3D(), + CompositingReason::kWillChangeCompositingHint); FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -2870,13 +2765,11 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipAcrossChildEffect) { FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c1, ColorFilter(), CompositorFilterOperations(), 1, - SkBlendMode::kSrcOver, CompositingReason::kWillChangeCompositingHint); + auto e1 = CreateOpacityEffect(e0(), t0(), c1, 1, + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -2943,15 +2836,13 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipRespectOutputClip) { FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); CompositorFilterOperations non_trivial_filter; non_trivial_filter.AppendBlurFilter(5); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c0(), ColorFilter(), non_trivial_filter, 1, - SkBlendMode::kSrcOver, CompositingReason::kWillChangeCompositingHint); + auto e1 = CreateFilterEffect(e0(), non_trivial_filter, FloatPoint(), + CompositingReason::kWillChangeCompositingHint); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -3050,13 +2941,16 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) { FloatSize corner(5, 5); FloatRoundedRect rrect(FloatRect(50, 50, 300, 200), corner, corner, corner, corner); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), rrect, nullptr, nullptr, - CompositingReason::kWillChangeCompositingHint); + auto c1 = CreateClip(c0(), t0(), rrect, + CompositingReason::kWillChangeCompositingHint); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c1, ColorFilter(), CompositorFilterOperations(), 1, - SkBlendMode::kMultiply, CompositingReason::kWillChangeCompositingHint); + EffectPaintPropertyNode::State e1_state; + e1_state.local_transform_space = t0(); + e1_state.output_clip = c1; + e1_state.blend_mode = SkBlendMode::kMultiply; + e1_state.direct_compositing_reasons = + CompositingReason::kWillChangeCompositingHint; + auto e1 = EffectPaintPropertyNode::Create(e0(), std::move(e1_state)); TestPaintArtifact artifact; artifact.Chunk(t0(), c1, e0()) @@ -3149,8 +3043,7 @@ TEST_F(PaintArtifactCompositorTest, SynthesizedClipDelegateBlending) { } TEST_F(PaintArtifactCompositorTest, WillBeRemovedFromFrame) { - scoped_refptr<EffectPaintPropertyNode> effect = - CreateSampleEffectNodeWithElementId(); + auto effect = CreateSampleEffectNodeWithElementId(); TestPaintArtifact artifact; artifact .Chunk(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -3167,7 +3060,7 @@ TEST_F(PaintArtifactCompositorTest, WillBeRemovedFromFrame) { TEST_F(PaintArtifactCompositorTest, ContentsNonOpaque) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack); Update(artifact.Build()); ASSERT_EQ(1u, ContentLayerCount()); @@ -3176,7 +3069,7 @@ TEST_F(PaintArtifactCompositorTest, ContentsNonOpaque) { TEST_F(PaintArtifactCompositorTest, ContentsOpaque) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack) .KnownToBeOpaque(); Update(artifact.Build()); @@ -3186,7 +3079,7 @@ TEST_F(PaintArtifactCompositorTest, ContentsOpaque) { TEST_F(PaintArtifactCompositorTest, ContentsOpaqueSubpixel) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100.5, 100.5, 200, 200), Color::kBlack) .KnownToBeOpaque(); Update(artifact.Build()); @@ -3197,10 +3090,10 @@ TEST_F(PaintArtifactCompositorTest, ContentsOpaqueSubpixel) { TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack) .KnownToBeOpaque() - .Chunk(DefaultPaintChunkProperties()) + .Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack) .KnownToBeOpaque(); Update(artifact.Build()); @@ -3211,10 +3104,10 @@ TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedNonOpaque) { TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 300, 300), Color::kBlack) .KnownToBeOpaque() - .Chunk(DefaultPaintChunkProperties()) + .Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(200, 200, 200, 200), Color::kBlack) .KnownToBeOpaque(); Update(artifact.Build()); @@ -3225,10 +3118,10 @@ TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque1) { TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque2) { TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 200, 200), Color::kBlack) .KnownToBeOpaque() - .Chunk(DefaultPaintChunkProperties()) + .Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(100, 100, 300, 300), Color::kBlack) .KnownToBeOpaque(); Update(artifact.Build()); @@ -3242,18 +3135,16 @@ TEST_F(PaintArtifactCompositorTest, ContentsOpaqueUnitedOpaque2) { TEST_F(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) { // This test verifies effect nodes with no output clip correctly decomposites // if there is no compositing reasons. - scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(75, 75, 100, 100)); + auto clip1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(75, 75, 100, 100)); - scoped_refptr<EffectPaintPropertyNode> effect1 = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - nullptr, kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); + auto effect1 = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), nullptr, 0.5); TestPaintArtifact artifact; - artifact.Chunk(DefaultPaintChunkProperties()) + artifact.Chunk(PropertyTreeState::Root()) .RectDrawing(FloatRect(50, 50, 100, 100), Color::kGray); artifact.Chunk(TransformPaintPropertyNode::Root(), clip1.get(), effect1.get()) .RectDrawing(FloatRect(100, 100, 100, 100), Color::kGray); @@ -3269,15 +3160,13 @@ TEST_F(PaintArtifactCompositorTest, DecompositeEffectWithNoOutputClip) { TEST_F(PaintArtifactCompositorTest, CompositedEffectWithNoOutputClip) { // This test verifies effect nodes with no output clip but has compositing // reason correctly squash children chunks and assign clip node. - scoped_refptr<ClipPaintPropertyNode> clip1 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(75, 75, 100, 100)); + auto clip1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(75, 75, 100, 100)); - scoped_refptr<EffectPaintPropertyNode> effect1 = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - nullptr, kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver, CompositingReason::kAll); + auto effect1 = CreateOpacityEffect(EffectPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + nullptr, 0.5, CompositingReason::kAll); TestPaintArtifact artifact; artifact @@ -3298,9 +3187,9 @@ TEST_F(PaintArtifactCompositorTest, CompositedEffectWithNoOutputClip) { TEST_F(PaintArtifactCompositorTest, LayerRasterInvalidationWithClip) { // The layer's painting is initially not clipped. - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 20, 300, 400)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 20, 300, 400)); TestPaintArtifact artifact1; artifact1 .Chunk(TransformPaintPropertyNode::Root(), clip, 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 ce6373cede5..47f5994fc88 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 @@ -164,16 +164,11 @@ class ConversionContext { void UpdateEffectBounds(const FloatRect&, const TransformPaintPropertyNode*); // Starts a clip state by adjusting the transform state, applying - // |combined_clip_rect| which is combined from multiple rectangular - // consecutive clips, and updating the current state. - // |lowest_combined_clip_node| is the lowest node of the combined clips. - void StartCombinedClip( - const FloatRect& combined_clip_rect, - const ClipPaintPropertyNode* lowest_combined_clip_node); - // Starts a clip state by adjusting the transform state, applying the single - // clip node which can't be combined with other clips, and updating the - // current state. - void StartSingleClip(const ClipPaintPropertyNode*); + // |combined_clip_rect| which is combined from one or more consecutive clips, + // and updating the current state. |lowest_combined_clip_node| is the lowest + // node of the combined clips. + void StartClip(const FloatRoundedRect& combined_clip_rect, + const ClipPaintPropertyNode* lowest_combined_clip_node); // Pop one clip state from the top of the stack. void EndClip(); // Pop clip states from the top of the stack until the top is an effect state @@ -268,12 +263,53 @@ void ConversionContext::TranslateForLayerOffsetOnce() { void ConversionContext::SwitchToChunkState(const PaintChunk& chunk) { chunk_to_layer_mapper_.SwitchToChunk(chunk); - const auto& chunk_state = chunk.properties.property_tree_state; + const auto& chunk_state = chunk.properties; SwitchToEffect(chunk_state.Effect()); SwitchToClip(chunk_state.Clip()); SwitchToTransform(chunk_state.Transform()); } +// Tries to combine a clip node's clip rect into |combined_clip_rect|. +// Returns whether the clip has been combined. +static bool CombineClip(const ClipPaintPropertyNode* clip, + FloatRoundedRect& combined_clip_rect) { + // Don't combine into a clip with clip path. + if (clip->Parent()->ClipPath()) + return false; + + // Don't combine clips in different transform spaces. + const auto* transform_space = clip->LocalTransformSpace(); + const auto* parent_transform_space = clip->Parent()->LocalTransformSpace(); + if (transform_space != parent_transform_space && + (transform_space->Parent() != parent_transform_space || + !transform_space->Matrix().IsIdentity())) + return false; + + // Don't combine two rounded clip rects. + bool clip_is_rounded = clip->ClipRect().IsRounded(); + bool combined_is_rounded = combined_clip_rect.IsRounded(); + if (clip_is_rounded && combined_is_rounded) + return false; + + // If one is rounded and the other contains the rounded bounds, use the + // rounded as the combined. + if (combined_is_rounded) + return clip->ClipRect().Rect().Contains(combined_clip_rect.Rect()); + if (clip_is_rounded) { + if (combined_clip_rect.Rect().Contains(clip->ClipRect().Rect())) { + combined_clip_rect = clip->ClipRect(); + return true; + } + return false; + } + + // The combined is the intersection if both are rectangular. + DCHECK(!combined_is_rounded && !clip_is_rounded); + combined_clip_rect = FloatRoundedRect( + Intersection(combined_clip_rect.Rect(), clip->ClipRect().Rect())); + return true; +} + void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { if (target_clip == current_clip_) return; @@ -317,49 +353,29 @@ void ConversionContext::SwitchToClip(const ClipPaintPropertyNode* target_clip) { } // Step 3: Now apply the list of clips in top-down order. - Optional<FloatRect> pending_combined_clip_rect; - const ClipPaintPropertyNode* lowest_combined_clip_node = nullptr; - for (size_t i = pending_clips.size(); i--;) { + DCHECK(pending_clips.size()); + auto pending_combined_clip_rect = pending_clips.back()->ClipRect(); + const auto* lowest_combined_clip_node = pending_clips.back(); + for (size_t i = pending_clips.size() - 1; i--;) { const auto* sub_clip = pending_clips[i]; - bool has_rounded_clip_or_clip_path = - sub_clip->ClipRect().IsRounded() || sub_clip->ClipPath(); - if (!has_rounded_clip_or_clip_path && pending_combined_clip_rect && - (sub_clip->Parent()->LocalTransformSpace() == - sub_clip->LocalTransformSpace() || - GeometryMapper::SourceToDestinationProjection( - sub_clip->Parent()->LocalTransformSpace(), - sub_clip->LocalTransformSpace()) - .IsIdentity())) { - // Continue to combine rectangular clips in the same transform space. - pending_combined_clip_rect->Intersect(sub_clip->ClipRect().Rect()); + if (CombineClip(sub_clip, pending_combined_clip_rect)) { + // Continue to combine. lowest_combined_clip_node = sub_clip; - continue; - } - - if (pending_combined_clip_rect) { - StartCombinedClip(*pending_combined_clip_rect, lowest_combined_clip_node); - lowest_combined_clip_node = nullptr; - pending_combined_clip_rect.reset(); - } - - if (has_rounded_clip_or_clip_path) { - // The clip can't be combined with others. - StartSingleClip(sub_clip); } else { - // Start to combine clips. - pending_combined_clip_rect = sub_clip->ClipRect().Rect(); + // |sub_clip| can't be combined to previous clips. Output the current + // combined clip, and start new combination. + StartClip(pending_combined_clip_rect, lowest_combined_clip_node); + pending_combined_clip_rect = sub_clip->ClipRect(); lowest_combined_clip_node = sub_clip; } } - - if (pending_combined_clip_rect) - StartCombinedClip(*pending_combined_clip_rect, lowest_combined_clip_node); + StartClip(pending_combined_clip_rect, lowest_combined_clip_node); DCHECK_EQ(current_clip_, target_clip); } -void ConversionContext::StartCombinedClip( - const FloatRect& combined_clip_rect, +void ConversionContext::StartClip( + const FloatRoundedRect& combined_clip_rect, const ClipPaintPropertyNode* lowest_combined_clip_node) { if (lowest_combined_clip_node->LocalTransformSpace() != current_transform_) EndTransform(); @@ -367,37 +383,23 @@ void ConversionContext::StartCombinedClip( cc_list_.push<cc::SaveOp>(); ApplyTransform(lowest_combined_clip_node->LocalTransformSpace()); const bool antialias = true; - cc_list_.push<cc::ClipRectOp>(combined_clip_rect, SkClipOp::kIntersect, - antialias); - cc_list_.EndPaintOfPairedBegin(); - - PushState(StateEntry::kClip, 1); - current_clip_ = lowest_combined_clip_node; - current_transform_ = lowest_combined_clip_node->LocalTransformSpace(); -} - -void ConversionContext::StartSingleClip(const ClipPaintPropertyNode* clip) { - if (clip->LocalTransformSpace() != current_transform_) - EndTransform(); - cc_list_.StartPaint(); - cc_list_.push<cc::SaveOp>(); - ApplyTransform(clip->LocalTransformSpace()); - const bool antialias = true; - cc_list_.push<cc::ClipRectOp>(static_cast<SkRect>(clip->ClipRect().Rect()), - SkClipOp::kIntersect, antialias); - if (clip->ClipRect().IsRounded()) { - cc_list_.push<cc::ClipRRectOp>(static_cast<SkRRect>(clip->ClipRect()), - SkClipOp::kIntersect, antialias); - } - if (clip->ClipPath()) { - cc_list_.push<cc::ClipPathOp>(clip->ClipPath()->GetSkPath(), + if (combined_clip_rect.IsRounded()) { + cc_list_.push<cc::ClipRRectOp>(combined_clip_rect, SkClipOp::kIntersect, + antialias); + } else { + cc_list_.push<cc::ClipRectOp>(combined_clip_rect.Rect(), SkClipOp::kIntersect, antialias); } + if (lowest_combined_clip_node->ClipPath()) { + cc_list_.push<cc::ClipPathOp>( + lowest_combined_clip_node->ClipPath()->GetSkPath(), + SkClipOp::kIntersect, antialias); + } cc_list_.EndPaintOfPairedBegin(); PushState(StateEntry::kClip, 1); - current_clip_ = clip; - current_transform_ = clip->LocalTransformSpace(); + current_clip_ = lowest_combined_clip_node; + current_transform_ = lowest_combined_clip_node->LocalTransformSpace(); } void ConversionContext::SwitchToEffect( @@ -450,10 +452,17 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode* effect) { else EndClips(); - // Apply effects. int saved_count = 0; size_t save_layer_id = kNotFound; - const auto* target_transform = current_transform_; + + // Adjust transform first. Though a non-filter effect itself doesn't depend on + // the transform, switching to the target transform before SaveLayer[Alpha]Op + // will help the rasterizer optimize a non-filter SaveLayer[Alpha]Op/ + // DrawRecord/Restore sequence into a single DrawRecord which is much faster. + // This also avoids multiple Save/Concat/.../Restore pairs for multiple + // consecutive effects in the same transform space, by issuing only one pair + // around all of the effects. + SwitchToTransform(effect->LocalTransformSpace()); // We always create separate effect nodes for normal effects and filter // effects, so we can handle them separately. @@ -463,10 +472,9 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode* effect) { effect->GetColorFilter() != kColorFilterNone; DCHECK(!has_filter || !(has_opacity || has_other_effects)); + // Apply effects. + cc_list_.StartPaint(); if (!has_filter) { - cc_list_.StartPaint(); - // No need to adjust transform for non-filter effects because transform - // doesn't matter. // TODO(ajuma): This should really be rounding instead of flooring the // alpha value, but that breaks slimming paint reftests. auto alpha = @@ -484,22 +492,13 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode* effect) { nullptr, alpha, preserve_lcd_text_requests); } saved_count++; - cc_list_.EndPaintOfPairedBegin(); } else { - // Handle filter effect. Adjust transform first. - target_transform = effect->LocalTransformSpace(); + // Handle filter effect. FloatPoint filter_origin = effect->PaintOffset(); - if (current_transform_ != target_transform || - filter_origin != FloatPoint()) { - EndTransform(); - auto matrix = GetSkMatrix(target_transform); - matrix.preTranslate(filter_origin.X(), filter_origin.Y()); - cc_list_.StartPaint(); + if (filter_origin != FloatPoint()) { cc_list_.push<cc::SaveOp>(); - cc_list_.push<cc::ConcatOp>(matrix); + cc_list_.push<cc::TranslateOp>(filter_origin.X(), filter_origin.Y()); saved_count++; - } else { - cc_list_.StartPaint(); } // The size parameter is only used to computed the origin of zoom @@ -509,12 +508,12 @@ void ConversionContext::StartEffect(const EffectPaintPropertyNode* effect) { filter_flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter( effect->Filter().AsCcFilterOperations(), empty)); save_layer_id = cc_list_.push<cc::SaveLayerOp>(nullptr, &filter_flags); + saved_count++; if (filter_origin != FloatPoint()) cc_list_.push<cc::TranslateOp>(-filter_origin.X(), -filter_origin.Y()); - cc_list_.EndPaintOfPairedBegin(); - saved_count++; } + cc_list_.EndPaintOfPairedBegin(); DCHECK_GT(saved_count, 0); DCHECK_LE(saved_count, 2); @@ -525,8 +524,7 @@ 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, target_transform}); - current_transform_ = target_transform; + EffectBoundsInfo{save_layer_id, current_transform_}); current_clip_ = input_clip; current_effect_ = effect; } @@ -643,7 +641,7 @@ void ConversionContext::EndTransform() { void ConversionContext::Convert(const PaintChunkSubset& paint_chunks, const DisplayItemList& display_items) { for (const auto& chunk : paint_chunks) { - const auto& chunk_state = chunk.properties.property_tree_state; + const auto& chunk_state = chunk.properties; bool switched_to_chunk_state = false; for (const auto& item : display_items.ItemsInPaintChunk(chunk)) { 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 75f6a0b42de..6fc715970d6 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 @@ -10,7 +10,6 @@ #include "cc/paint/paint_op_buffer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/graphics/logging_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" @@ -22,24 +21,34 @@ #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" -namespace cc { -std::ostream& operator<<(std::ostream& os, const PaintRecord& record) { - return os << "PaintRecord(" - << blink::RecordAsDebugString(record).Utf8().data() << ")"; +void PrintTo(const Vector<cc::PaintOpType>& ops, std::ostream* os) { + *os << "["; + bool first = true; + for (auto op : ops) { + if (first) + first = false; + else + *os << ", "; + *os << op; + } + *os << "]"; +} + +void PrintTo(const cc::PaintRecord& record, std::ostream* os) { + Vector<cc::PaintOpType> ops; + for (const auto* op : cc::PaintOpBuffer::Iterator(&record)) + ops.push_back(op->GetType()); + PrintTo(ops, os); } -} // namespace cc -std::ostream& operator<<(std::ostream& os, const SkRect& rect) { - if (cc::PaintOp::IsUnsetRect(rect)) - return os << "(unset)"; - return os << blink::FloatRect(rect).ToString(); +void PrintTo(const SkRect& rect, std::ostream* os) { + *os << (cc::PaintOp::IsUnsetRect(rect) ? "(unset)" + : blink::FloatRect(rect).ToString()); } namespace blink { namespace { -using test::CreateOpacityOnlyEffect; - class PaintChunksToCcLayerTest : public testing::Test, private ScopedSlimmingPaintV2ForTest { protected: @@ -84,16 +93,7 @@ class PaintRecordMatcher } void DescribeTo(::std::ostream* os) const override { - *os << "["; - bool first = true; - for (auto op : expected_ops_) { - if (first) - first = false; - else - *os << ", "; - *os << op; - } - *os << "]"; + PrintTo(expected_ops_, os); } private: @@ -119,7 +119,8 @@ class PaintRecordMatcher do { \ const auto* concat = (op_buffer).GetOpAtForTesting<cc::ConcatOp>(index); \ ASSERT_NE(nullptr, concat); \ - EXPECT_EQ(transform, TransformationMatrix(concat->matrix)); \ + EXPECT_EQ(SkMatrix(TransformationMatrix::ToSkMatrix44(transform)), \ + concat->matrix); \ } while (false) #define EXPECT_TRANSLATE(x, y, op_buffer, index) \ @@ -131,6 +132,22 @@ class PaintRecordMatcher EXPECT_EQ(y, translate->dy); \ } while (false) +#define EXPECT_CLIP(r, op_buffer, index) \ + do { \ + const auto* clip_op = \ + (op_buffer).GetOpAtForTesting<cc::ClipRectOp>(index); \ + ASSERT_NE(nullptr, clip_op); \ + EXPECT_EQ(SkRect(r), clip_op->rect); \ + } while (false) + +#define EXPECT_ROUNDED_CLIP(r, op_buffer, index) \ + do { \ + const auto* clip_op = \ + (op_buffer).GetOpAtForTesting<cc::ClipRRectOp>(index); \ + ASSERT_NE(nullptr, clip_op); \ + EXPECT_EQ(SkRRect(r), clip_op->rrect); \ + } while (false) + // Convenient shorthands. const TransformPaintPropertyNode* t0() { return TransformPaintPropertyNode::Root(); @@ -171,16 +188,14 @@ struct TestChunks { size_t i = items.size(); items.AllocateAndConstruct<DrawingDisplayItem>( DefaultId().client, DefaultId().type, std::move(record)); - chunks.emplace_back(i, i + 1, DefaultId(), - PaintChunkProperties(PropertyTreeState(t, c, e))); + chunks.emplace_back(i, i + 1, DefaultId(), PropertyTreeState(t, c, e)); chunks.back().bounds = bounds; } }; TEST_F(PaintChunksToCcLayerTest, EffectGroupingSimple) { // This test verifies effects are applied as a group. - scoped_refptr<EffectPaintPropertyNode> e1 = - CreateOpacityOnlyEffect(e0(), 0.5f); + auto e1 = CreateOpacityEffect(e0(), 0.5f); TestChunks chunks; chunks.AddChunk(t0(), c0(), e1.get(), FloatRect(0, 0, 50, 50)); chunks.AddChunk(t0(), c0(), e1.get(), FloatRect(20, 20, 70, 70)); @@ -201,12 +216,9 @@ TEST_F(PaintChunksToCcLayerTest, EffectGroupingSimple) { TEST_F(PaintChunksToCcLayerTest, EffectGroupingNested) { // This test verifies nested effects are grouped properly. - scoped_refptr<EffectPaintPropertyNode> e1 = - CreateOpacityOnlyEffect(e0(), 0.5f); - scoped_refptr<EffectPaintPropertyNode> e2 = - CreateOpacityOnlyEffect(e1.get(), 0.5f); - scoped_refptr<EffectPaintPropertyNode> e3 = - CreateOpacityOnlyEffect(e1.get(), 0.5f); + auto e1 = CreateOpacityEffect(e0(), 0.5f); + auto e2 = CreateOpacityEffect(e1, 0.5f); + auto e3 = CreateOpacityEffect(e1, 0.5f); TestChunks chunks; chunks.AddChunk(t0(), c0(), e2.get()); chunks.AddChunk(t0(), c0(), e3.get(), FloatRect(111, 222, 333, 444)); @@ -233,20 +245,13 @@ TEST_F(PaintChunksToCcLayerTest, EffectGroupingNested) { TEST_F(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) { // This test verifies nested effects with transforms are grouped properly. - auto t1 = TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - auto t2 = TransformPaintPropertyNode::Create( - t1.get(), TransformationMatrix().Translate(-50, -50), FloatPoint3D()); - auto e1 = EffectPaintPropertyNode::Create(e0(), t2.get(), c0(), ColorFilter(), - CompositorFilterOperations(), .5f, - SkBlendMode::kSrcOver); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto t2 = CreateTransform(t1, TransformationMatrix().Translate(-50, -50)); + auto e1 = CreateOpacityEffect(e0(), t2, c0(), 0.5); + CompositorFilterOperations filter; filter.AppendBlurFilter(5); - auto e2 = EffectPaintPropertyNode::Create( - e1.get(), t2.get(), c0(), ColorFilter(), filter, 1.f, - SkBlendMode::kSrcOver, CompositingReason::kNone, CompositorElementId(), - FloatPoint(60, 60)); - CreateOpacityOnlyEffect(e1.get(), 0.5f); + auto e2 = CreateFilterEffect(e1, filter, FloatPoint(60, 60)); TestChunks chunks; chunks.AddChunk(t2.get(), c0(), e1.get(), FloatRect(0, 0, 50, 50)); chunks.AddChunk(t1.get(), c0(), e2.get(), FloatRect(20, 20, 70, 70)); @@ -259,28 +264,30 @@ TEST_F(PaintChunksToCcLayerTest, EffectFilterGroupingNestedWithTransforms) { EXPECT_THAT( *output, PaintRecordMatcher::Make( - {cc::PaintOpType::SaveLayerAlpha, // <e1> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*t2> - cc::PaintOpType::DrawRecord, // <p1/> - cc::PaintOpType::Restore, // </t1*t2> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*t2+e2_offset> - cc::PaintOpType::SaveLayer, // <e2> - cc::PaintOpType::Translate, // </e2_offset> + {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::Concat, // <t2^-1> cc::PaintOpType::DrawRecord, // <p2/> cc::PaintOpType::Restore, // </t2^-1> cc::PaintOpType::Restore, // </e2> - cc::PaintOpType::Restore, // </t1*t2> - cc::PaintOpType::Restore})); // </e1> - // t1(t2(chunk1.bounds + e2(t2^-1(chunk2.bounds)))) - EXPECT_EFFECT_BOUNDS(-100, -100, 310, 310, *output, 0); - EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->Matrix(), *output, 2); - EXPECT_TRANSFORM_MATRIX((t1->Matrix() * t2->Matrix()).Translate(60, 60), - *output, 6); + cc::PaintOpType::Restore, // </e2_offset> + cc::PaintOpType::Restore, // </e1> + cc::PaintOpType::Restore})); // </t1*t2> + EXPECT_TRANSFORM_MATRIX(t1->Matrix() * t2->Matrix(), *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, 7); - EXPECT_TRANSLATE(-60, -60, *output, 8); - EXPECT_TRANSFORM_MATRIX(t2->Matrix().Inverse(), *output, 10); + EXPECT_EFFECT_BOUNDS(10, 10, 70, 70, *output, 6); + // -e2_offset + EXPECT_TRANSLATE(-60, -60, *output, 7); + // t2^1 + EXPECT_TRANSFORM_MATRIX(t2->Matrix().Inverse(), *output, 9); } TEST_F(PaintChunksToCcLayerTest, InterleavedClipEffect) { @@ -289,20 +296,12 @@ TEST_F(PaintChunksToCcLayerTest, InterleavedClipEffect) { // ConversionContext. // Refer to PaintChunksToCcLayer.cpp for detailed explanation. // (Search "State management example".) - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c2 = ClipPaintPropertyNode::Create( - c1.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c3 = ClipPaintPropertyNode::Create( - c2.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c4 = ClipPaintPropertyNode::Create( - c3.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c2.get(), ColorFilter(), CompositorFilterOperations(), 0.5f, - SkBlendMode::kSrcOver); - scoped_refptr<EffectPaintPropertyNode> e2 = EffectPaintPropertyNode::Create( - e1.get(), t0(), c4.get(), ColorFilter(), CompositorFilterOperations(), - 0.5f, SkBlendMode::kSrcOver); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c2 = CreateClip(c1, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c3 = CreateClip(c2, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c4 = CreateClip(c3, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), t0(), c2, 0.5); + auto e2 = CreateOpacityEffect(e1, t0(), c4, 0.5); TestChunks chunks; chunks.AddChunk(t0(), c2.get(), e0()); chunks.AddChunk(t0(), c3.get(), e0()); @@ -350,11 +349,8 @@ TEST_F(PaintChunksToCcLayerTest, ClipSpaceInversion) { // <div style="position:absolute; clip:rect(...)"> // <div style="position:fixed;">Clipped but not scroll along.</div> // </div> - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t1.get(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto c1 = CreateClip(c0(), t1, FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e0()); @@ -381,12 +377,8 @@ TEST_F(PaintChunksToCcLayerTest, OpacityEffectSpaceInversion) { // <div style="position:absolute;">Transparent but not scroll along.</div> // </div> // </div> - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t1.get(), c0(), ColorFilter(), CompositorFilterOperations(), 0.5f, - SkBlendMode::kSrcOver); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto e1 = CreateOpacityEffect(e0(), t1, c0(), 0.5); TestChunks chunks; chunks.AddChunk(t0(), c0(), e1.get()); chunks.AddChunk(t1.get(), c0(), e1.get()); @@ -396,17 +388,19 @@ TEST_F(PaintChunksToCcLayerTest, OpacityEffectSpaceInversion) { chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(), chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) ->ReleaseAsRecord(); - EXPECT_THAT( - *output, - PaintRecordMatcher::Make({cc::PaintOpType::SaveLayerAlpha, // <e1> - cc::PaintOpType::DrawRecord, // <p0/> - cc::PaintOpType::Save, - cc::PaintOpType::Concat, // <t1> - cc::PaintOpType::DrawRecord, // <p1/> - cc::PaintOpType::Restore, // </t1> - cc::PaintOpType::Restore})); // </e1> - EXPECT_EFFECT_BOUNDS(0, 0, 200, 200, *output, 0); - EXPECT_TRANSFORM_MATRIX(t1->Matrix(), *output, 3); + 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); } TEST_F(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) { @@ -417,13 +411,10 @@ TEST_F(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) { // <div style="position:absolute;">Filtered but not scroll along.</div> // </div> // </div> - auto t1 = TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); CompositorFilterOperations filter; filter.AppendBlurFilter(5); - auto e1 = EffectPaintPropertyNode::Create( - e0(), t1.get(), c0(), ColorFilter(), filter, 1.f, SkBlendMode::kSrcOver, - CompositingReason::kNone, CompositorElementId(), FloatPoint(66, 88)); + auto e1 = CreateFilterEffect(e0(), t1, c0(), filter, FloatPoint(66, 88)); TestChunks chunks; chunks.AddChunk(t0(), c0(), e1.get()); @@ -435,31 +426,29 @@ TEST_F(PaintChunksToCcLayerTest, FilterEffectSpaceInversion) { EXPECT_THAT( *output, PaintRecordMatcher::Make( - {cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1*e1_offset> - cc::PaintOpType::SaveLayer, // <e1> - cc::PaintOpType::Translate, // </e1_offset> + {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(TransformationMatrix(t1->Matrix()).Translate(66, 88), - *output, 1); - EXPECT_EFFECT_BOUNDS(-66, -88, 50, 50, *output, 2); - EXPECT_TRANSLATE(-66, -88, *output, 3); - EXPECT_TRANSFORM_MATRIX(t1->Matrix().Inverse(), *output, 5); + 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); } TEST_F(PaintChunksToCcLayerTest, NonRootLayerSimple) { // This test verifies a layer with composited property state does not // apply properties again internally. - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = - CreateOpacityOnlyEffect(e0(), 0.5f); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), 0.5f); TestChunks chunks; chunks.AddChunk(t1.get(), c1.get(), e1.get()); @@ -475,13 +464,9 @@ TEST_F(PaintChunksToCcLayerTest, NonRootLayerSimple) { TEST_F(PaintChunksToCcLayerTest, NonRootLayerTransformEscape) { // This test verifies chunks that have a shallower transform state than the // layer can still be painted. - scoped_refptr<TransformPaintPropertyNode> t1 = - TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = - CreateOpacityOnlyEffect(e0(), 0.5f); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), 0.5f); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e1.get()); @@ -500,13 +485,9 @@ TEST_F(PaintChunksToCcLayerTest, NonRootLayerTransformEscape) { TEST_F(PaintChunksToCcLayerTest, EffectWithNoOutputClip) { // This test verifies effect with no output clip can be correctly processed. - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c2 = ClipPaintPropertyNode::Create( - c1.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), nullptr, kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c2 = CreateClip(c1, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), t0(), nullptr, 0.5); TestChunks chunks; chunks.AddChunk(t0(), c2.get(), e1.get()); @@ -530,14 +511,9 @@ TEST_F(PaintChunksToCcLayerTest, EffectWithNoOutputClip) { TEST_F(PaintChunksToCcLayerTest, EffectWithNoOutputClipNestedInDecompositedEffect) { - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c0(), kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); - scoped_refptr<EffectPaintPropertyNode> e2 = EffectPaintPropertyNode::Create( - e1.get(), t0(), nullptr, kColorFilterNone, CompositorFilterOperations(), - 0.5, SkBlendMode::kSrcOver); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), 0.5); + auto e2 = CreateOpacityEffect(e1, t0(), nullptr, 0.5); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e2.get()); @@ -563,14 +539,9 @@ TEST_F(PaintChunksToCcLayerTest, TEST_F(PaintChunksToCcLayerTest, EffectWithNoOutputClipNestedInCompositedEffect) { - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c0(), kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); - scoped_refptr<EffectPaintPropertyNode> e2 = EffectPaintPropertyNode::Create( - e1.get(), t0(), nullptr, kColorFilterNone, CompositorFilterOperations(), - 0.5, SkBlendMode::kSrcOver); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), 0.5); + auto e2 = CreateOpacityEffect(e1, t0(), nullptr, 0.5); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e2.get()); @@ -594,14 +565,9 @@ TEST_F(PaintChunksToCcLayerTest, TEST_F(PaintChunksToCcLayerTest, EffectWithNoOutputClipNestedInCompositedEffectAndClip) { - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c0(), kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); - scoped_refptr<EffectPaintPropertyNode> e2 = EffectPaintPropertyNode::Create( - e1.get(), t0(), nullptr, kColorFilterNone, CompositorFilterOperations(), - 0.5, SkBlendMode::kSrcOver); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto e1 = CreateOpacityEffect(e0(), 0.5); + auto e2 = CreateOpacityEffect(e1, t0(), nullptr, 0.5); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e2.get()); @@ -621,11 +587,10 @@ TEST_F(PaintChunksToCcLayerTest, } TEST_F(PaintChunksToCcLayerTest, VisualRect) { - auto layer_transform = TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(20), FloatPoint3D()); - auto chunk_transform = TransformPaintPropertyNode::Create( - layer_transform.get(), TransformationMatrix().Translate(50, 100), - FloatPoint3D()); + auto layer_transform = + CreateTransform(t0(), TransformationMatrix().Scale(20)); + auto chunk_transform = CreateTransform( + layer_transform, TransformationMatrix().Translate(50, 100)); TestChunks chunks; chunks.AddChunk(chunk_transform.get(), c0(), e0()); @@ -649,11 +614,7 @@ TEST_F(PaintChunksToCcLayerTest, VisualRect) { } TEST_F(PaintChunksToCcLayerTest, NoncompositedClipPath) { - scoped_refptr<RefCountedPath> clip_path = base::AdoptRef(new RefCountedPath); - auto c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(25.f, 25.f, 100.f, 100.f), nullptr, - clip_path); - + auto c1 = CreateClipPathClip(c0(), t0(), FloatRoundedRect(1, 2, 3, 4)); TestChunks chunks; chunks.AddChunk(t0(), c1.get(), e0()); @@ -673,12 +634,9 @@ TEST_F(PaintChunksToCcLayerTest, NoncompositedClipPath) { } TEST_F(PaintChunksToCcLayerTest, EmptyClipsAreElided) { - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c1c2 = ClipPaintPropertyNode::Create( - c1.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c2 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c1c2 = CreateClip(c1, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c2 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); TestChunks chunks; chunks.AddChunk(nullptr, t0(), c1.get(), e0()); @@ -705,12 +663,9 @@ TEST_F(PaintChunksToCcLayerTest, EmptyClipsAreElided) { } TEST_F(PaintChunksToCcLayerTest, NonEmptyClipsAreStored) { - scoped_refptr<ClipPaintPropertyNode> c1 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c1c2 = ClipPaintPropertyNode::Create( - c1.get(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); - scoped_refptr<ClipPaintPropertyNode> c2 = ClipPaintPropertyNode::Create( - c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c1 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c1c2 = CreateClip(c1, t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); + auto c2 = CreateClip(c0(), t0(), FloatRoundedRect(0.f, 0.f, 1.f, 1.f)); TestChunks chunks; chunks.AddChunk(nullptr, t0(), c1.get(), e0()); @@ -740,9 +695,7 @@ TEST_F(PaintChunksToCcLayerTest, NonEmptyClipsAreStored) { } TEST_F(PaintChunksToCcLayerTest, EmptyEffectsAreStored) { - scoped_refptr<EffectPaintPropertyNode> e1 = EffectPaintPropertyNode::Create( - e0(), t0(), c0(), kColorFilterNone, CompositorFilterOperations(), 0.5, - SkBlendMode::kSrcOver); + auto e1 = CreateOpacityEffect(e0(), 0.5); TestChunks chunks; chunks.AddChunk(nullptr, t0(), c0(), e0()); @@ -763,18 +716,13 @@ TEST_F(PaintChunksToCcLayerTest, EmptyEffectsAreStored) { TEST_F(PaintChunksToCcLayerTest, CombineClips) { FloatRoundedRect clip_rect(0, 0, 100, 100); - FloatSize corner(5, 5); - FloatRoundedRect rounded_clip_rect(clip_rect.Rect(), corner, corner, corner, - corner); - auto t1 = TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - auto c1 = ClipPaintPropertyNode::Create(c0(), t0(), clip_rect); - auto c2 = ClipPaintPropertyNode::Create(c1.get(), t0(), clip_rect); - auto c3 = ClipPaintPropertyNode::Create(c2.get(), t1.get(), clip_rect); - auto c4 = ClipPaintPropertyNode::Create(c3.get(), t1.get(), clip_rect); - auto c5 = - ClipPaintPropertyNode::Create(c4.get(), t1.get(), rounded_clip_rect); - auto c6 = ClipPaintPropertyNode::Create(c5.get(), t1.get(), clip_rect); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto c1 = CreateClip(c0(), t0(), clip_rect); + auto c2 = CreateClip(c1, t0(), clip_rect); + auto c3 = CreateClip(c2, t1, clip_rect); + auto c4 = CreateClip(c3, t1, clip_rect); + auto c5 = CreateClipPathClip(c4, t1, clip_rect); + auto c6 = CreateClip(c5, t1, clip_rect); TestChunks chunks; chunks.AddChunk(t1.get(), c6.get(), e0()); @@ -789,30 +737,115 @@ TEST_F(PaintChunksToCcLayerTest, CombineClips) { EXPECT_THAT( *output, PaintRecordMatcher::Make( - {cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 - cc::PaintOpType::ClipRect, // c3+c4> - cc::PaintOpType::Save, cc::PaintOpType::ClipRect, - cc::PaintOpType::ClipRRect, // <c5> - cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c6> - cc::PaintOpType::DrawRecord, // <p0/> - cc::PaintOpType::Restore, // </c6> - cc::PaintOpType::Restore, // </c5> - cc::PaintOpType::Restore, // </c3+c4 t1> - cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 - cc::PaintOpType::ClipRect, // c3> - cc::PaintOpType::DrawRecord, // <p1/> - cc::PaintOpType::Restore, // </c3 t1> - cc::PaintOpType::Restore})); // </c1+c2> + {cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 + cc::PaintOpType::ClipRect, cc::PaintOpType::ClipPath, // c3+c4+c5> + cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c6> + cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Restore, // </c6> + cc::PaintOpType::Restore, // </c3+c4+c5 t1> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1 + cc::PaintOpType::ClipRect, // c3> + cc::PaintOpType::DrawRecord, // <p1/> + cc::PaintOpType::Restore, // </c3 t1> + cc::PaintOpType::Restore})); // </c1+c2> +} + +TEST_F(PaintChunksToCcLayerTest, CombineClipsAcrossTransform) { + FloatRoundedRect clip_rect(0, 0, 100, 100); + auto identity = CreateTransform(t0(), TransformationMatrix()); + auto non_identity = + CreateTransform(*identity, TransformationMatrix().Scale(2)); + auto non_invertible = + CreateTransform(*non_identity, TransformationMatrix().Scale(0)); + EXPECT_FALSE(non_invertible->Matrix().IsInvertible()); + auto c1 = CreateClip(c0(), &t0(), FloatRoundedRect(0, 0, 100, 100)); + auto c2 = CreateClip(*c1, identity.get(), FloatRoundedRect(50, 50, 100, 100)); + auto c3 = CreateClip(*c2, non_identity.get(), FloatRoundedRect(1, 2, 3, 4)); + auto c4 = CreateClip(*c3, non_invertible.get(), FloatRoundedRect(5, 6, 7, 8)); + + TestChunks chunks; + chunks.AddChunk(*non_invertible, *c4, e0()); + + sk_sp<PaintRecord> output = + PaintChunksToCcLayer::Convert( + chunks.chunks, PropertyTreeState::Root(), gfx::Vector2dF(), + chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + // We combine c1/c2 across |identity|, but not c2/c3 across |non_identity| + // and c3/c4 across |non_invertible|. + EXPECT_THAT( + *output, + PaintRecordMatcher::Make( + {cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c1+c2> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <non_identity + cc::PaintOpType::ClipRect, // c3> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <non_invertible + cc::PaintOpType::ClipRect, // c4> + cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Restore, // </c4 non_invertible> + cc::PaintOpType::Restore, // </c3 non_identity> + cc::PaintOpType::Restore})); // </c1+c2> + + EXPECT_CLIP(FloatRect(50, 50, 50, 50), *output, 1); + EXPECT_TRANSFORM_MATRIX(non_identity->Matrix(), *output, 3); + EXPECT_CLIP(FloatRect(1, 2, 3, 4), *output, 4); + EXPECT_TRANSFORM_MATRIX(non_invertible->Matrix(), *output, 6); + EXPECT_CLIP(FloatRect(5, 6, 7, 8), *output, 7); +} + +TEST_F(PaintChunksToCcLayerTest, CombineClipsWithRoundedRects) { + FloatRoundedRect clip_rect(0, 0, 100, 100); + FloatSize corner(5, 5); + FloatRoundedRect big_rounded_clip_rect(FloatRect(0, 0, 200, 200), corner, + corner, corner, corner); + FloatRoundedRect small_rounded_clip_rect(FloatRect(0, 0, 100, 100), corner, + corner, corner, corner); + + auto c1 = CreateClip(c0(), t0(), clip_rect); + auto c2 = CreateClip(c1, t0(), small_rounded_clip_rect); + auto c3 = CreateClip(c2, t0(), clip_rect); + auto c4 = CreateClip(c3, t0(), big_rounded_clip_rect); + auto c5 = CreateClip(c4, t0(), clip_rect); + auto c6 = CreateClip(c5, t0(), big_rounded_clip_rect); + auto c7 = CreateClip(c6, t0(), small_rounded_clip_rect); + + TestChunks chunks; + chunks.AddChunk(t0(), c7.get(), e0()); + + sk_sp<PaintRecord> output = + PaintChunksToCcLayer::Convert( + chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(), + chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + EXPECT_THAT( + *output, + PaintRecordMatcher::Make( + {cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c1+c2+c3> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c4> + cc::PaintOpType::Save, cc::PaintOpType::ClipRect, // <c5> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c6> + cc::PaintOpType::Save, cc::PaintOpType::ClipRRect, // <c7> + cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Restore, // </c7> + cc::PaintOpType::Restore, // </c6> + cc::PaintOpType::Restore, // </c5> + cc::PaintOpType::Restore, // </c4> + cc::PaintOpType::Restore})); // </c1+c2+c3> + + EXPECT_ROUNDED_CLIP(small_rounded_clip_rect, *output, 1); + EXPECT_ROUNDED_CLIP(big_rounded_clip_rect, *output, 3); + EXPECT_CLIP(clip_rect.Rect(), *output, 5); + EXPECT_ROUNDED_CLIP(big_rounded_clip_rect, *output, 7); + EXPECT_ROUNDED_CLIP(small_rounded_clip_rect, *output, 9); } TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) { - auto t1 = TransformPaintPropertyNode::Create( - t0(), TransformationMatrix().Scale(2.f), FloatPoint3D()); - auto t2 = TransformPaintPropertyNode::Create( - t1.get(), TransformationMatrix().Scale(3.f), FloatPoint3D()); - auto c1 = ClipPaintPropertyNode::Create(c0(), t1.get(), - FloatRoundedRect(0, 0, 100, 100)); + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2.f)); + auto t2 = CreateTransform(t1, TransformationMatrix().Scale(3.f)); + auto c1 = CreateClip(c0(), t1, FloatRoundedRect(0, 0, 100, 100)); TestChunks chunks; chunks.AddChunk(t0(), c0(), e0()); @@ -843,20 +876,15 @@ TEST_F(PaintChunksToCcLayerTest, ChunksSamePropertyTreeState) { cc::PaintOpType::DrawRecord, // <p6/> cc::PaintOpType::Restore, // </t2> cc::PaintOpType::Restore, // </c1> - cc::PaintOpType::Restore})); // </c1></t1> + cc::PaintOpType::Restore})); // </t1> } TEST_F(PaintChunksToCcLayerTest, NoOpForIdentityTransforms) { - auto t1 = TransformPaintPropertyNode::Create(t0(), TransformationMatrix(), - FloatPoint3D()); - auto t2 = TransformPaintPropertyNode::Create(t1.get(), TransformationMatrix(), - FloatPoint3D()); - auto t3 = TransformPaintPropertyNode::Create(t2.get(), TransformationMatrix(), - FloatPoint3D()); - auto c1 = - ClipPaintPropertyNode::Create(c0(), t2, FloatRoundedRect(0, 0, 100, 100)); - auto c2 = - ClipPaintPropertyNode::Create(c1, t3, FloatRoundedRect(0, 0, 200, 50)); + auto t1 = CreateTransform(t0(), TransformationMatrix()); + auto t2 = CreateTransform(t1, TransformationMatrix()); + auto t3 = CreateTransform(t2, TransformationMatrix()); + auto c1 = CreateClip(c0(), t2, FloatRoundedRect(0, 0, 100, 100)); + auto c2 = CreateClip(c1, t3, FloatRoundedRect(0, 0, 200, 50)); TestChunks chunks; chunks.AddChunk(t0(), c0(), e0()); @@ -886,5 +914,63 @@ TEST_F(PaintChunksToCcLayerTest, NoOpForIdentityTransforms) { cc::PaintOpType::Restore})); // </c1+c2> } +TEST_F(PaintChunksToCcLayerTest, EffectsWithSameTransform) { + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2)); + auto e1 = CreateOpacityEffect(e0(), t1, c0(), 0.1f); + auto e2 = CreateOpacityEffect(e0(), t1, c0(), 0.2f); + + TestChunks chunks; + chunks.AddChunk(t0(), c0(), e0()); + chunks.AddChunk(t1.get(), c0(), e1.get()); + chunks.AddChunk(t1.get(), c0(), e2.get()); + + auto output = + PaintChunksToCcLayer::Convert( + chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(), + chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + EXPECT_THAT(*output, + PaintRecordMatcher::Make( + {cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1> + cc::PaintOpType::SaveLayerAlpha, // <e1> + cc::PaintOpType::DrawRecord, // <p1/> + cc::PaintOpType::Restore, // </e1> + cc::PaintOpType::SaveLayerAlpha, // <e2> + cc::PaintOpType::DrawRecord, // <p2> + cc::PaintOpType::Restore, // </e2> + cc::PaintOpType::Restore})); // </t1> +} + +TEST_F(PaintChunksToCcLayerTest, NestedEffectsWithSameTransform) { + auto t1 = CreateTransform(t0(), TransformationMatrix().Scale(2)); + auto e1 = CreateOpacityEffect(e0(), t1, c0(), 0.1f); + auto e2 = CreateOpacityEffect(e1, t1, c0(), 0.2f); + + TestChunks chunks; + chunks.AddChunk(t0(), c0(), e0()); + chunks.AddChunk(t1.get(), c0(), e1.get()); + chunks.AddChunk(t1.get(), c0(), e2.get()); + + auto output = + PaintChunksToCcLayer::Convert( + chunks.chunks, PropertyTreeState(t0(), c0(), e0()), gfx::Vector2dF(), + chunks.items, cc::DisplayItemList::kToBeReleasedAsPaintOpBuffer) + ->ReleaseAsRecord(); + + EXPECT_THAT(*output, + PaintRecordMatcher::Make( + {cc::PaintOpType::DrawRecord, // <p0/> + cc::PaintOpType::Save, cc::PaintOpType::Concat, // <t1> + cc::PaintOpType::SaveLayerAlpha, // <e1> + cc::PaintOpType::DrawRecord, // <p1/> + cc::PaintOpType::SaveLayerAlpha, // <e2> + cc::PaintOpType::DrawRecord, // <p2> + cc::PaintOpType::Restore, // </e2> + cc::PaintOpType::Restore, // </e1> + cc::PaintOpType::Restore})); // </t1> +} + } // namespace } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc index 3015d23785c..403b74ed641 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing/property_tree_manager.cc @@ -255,8 +255,10 @@ void PropertyTreeManager::CreateCompositorScrollNode( cc::ScrollNode& compositor_node = *GetScrollTree().Node(id); compositor_node.scrollable = true; - compositor_node.container_bounds = scroll_node->ContainerRect().Size(); - compositor_node.bounds = scroll_node->ContentsRect().Size(); + compositor_node.container_bounds = + static_cast<gfx::Size>(scroll_node->ContainerRect().Size()); + compositor_node.bounds = + static_cast<gfx::Size>(scroll_node->ContentsRect().Size()); compositor_node.user_scrollable_horizontal = scroll_node->UserScrollableHorizontal(); compositor_node.user_scrollable_vertical = @@ -584,6 +586,9 @@ bool PropertyTreeManager::BuildEffectNodesRecursively( nullptr))); } else { effect_node.filters = next_effect->Filter().AsCcFilterOperations(); + effect_node.filters_origin = next_effect->PaintOffset(); + effect_node.transform_id = + EnsureCompositorTransformNode(next_effect->LocalTransformSpace()); } effect_node.blend_mode = used_blend_mode; CompositorElementId compositor_element_id = 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 d5f9b73cad6..4e8166c7f60 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h +++ b/chromium/third_party/blink/renderer/platform/graphics/compositing_reasons.h @@ -35,6 +35,7 @@ using CompositingReasons = uint64_t; V(WillChangeCompositingHint) \ V(BackdropFilter) \ V(RootScroller) \ + V(ScrollTimelineTarget) \ \ /* Overlap reasons that require knowing what's behind you in paint-order \ before knowing the answer. */ \ diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_animator.h b/chromium/third_party/blink/renderer/platform/graphics/compositor_animator.h index 0346e123251..f23806bfd5c 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositor_animator.h +++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_animator.h @@ -16,7 +16,7 @@ class PLATFORM_EXPORT CompositorAnimator : public GarbageCollectedMixin { // Runs the animation frame callback. virtual std::unique_ptr<CompositorMutatorOutputState> Mutate( const CompositorMutatorInputState&) = 0; - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_client.h b/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_client.h index 48c36549b4d..77e0819d92a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_client.h +++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_client.h @@ -16,12 +16,12 @@ class CompositorMutatorImpl; class PLATFORM_EXPORT CompositorMutatorClient : public cc::LayerTreeMutator { public: explicit CompositorMutatorClient(std::unique_ptr<CompositorMutatorImpl>); - virtual ~CompositorMutatorClient(); + ~CompositorMutatorClient() override; void SetMutationUpdate(std::unique_ptr<cc::MutatorOutputState>); // cc::LayerTreeMutator - void SetClient(cc::LayerTreeMutatorClient*); + void SetClient(cc::LayerTreeMutatorClient*) override; void Mutate(std::unique_ptr<cc::MutatorInputState>) override; bool HasAnimators() override; diff --git a/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h b/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h index 1e8116c43fd..fccc38928e4 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h +++ b/chromium/third_party/blink/renderer/platform/graphics/compositor_mutator_impl.h @@ -42,7 +42,7 @@ class PLATFORM_EXPORT CompositorMutatorImpl final : public CompositorMutator { scoped_refptr<base::SingleThreadTaskRunner>* mutatee_runner); CompositorMutatorImpl(); - ~CompositorMutatorImpl(); + ~CompositorMutatorImpl() override; // CompositorMutator implementation. void Mutate(std::unique_ptr<CompositorMutatorInputState>) override; diff --git a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container_test.cc b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container_test.cc index 8530f5c26ae..e936bfb7619 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/contiguous_container_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/contiguous_container_test.cc @@ -208,7 +208,7 @@ TEST(ContiguousContainerTest, ElementAddressesAreStable) { EXPECT_EQ(kNumElements, pointers.size()); auto list_it = list.begin(); - auto vector_it = pointers.begin(); + auto** vector_it = pointers.begin(); for (; list_it != list.end(); ++list_it, ++vector_it) EXPECT_EQ(&*list_it, *vector_it); } diff --git a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc index 59dc7d42520..2f481cb7421 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/crossfade_generated_image.cc @@ -61,8 +61,7 @@ void CrossfadeGeneratedImage::DrawCrossfade(PaintCanvas* canvas, PaintFlags image_flags(flags); image_flags.setBlendMode(SkBlendMode::kSrcOver); - int image_alpha = ClampedAlphaForBlending(1 - percentage_); - image_flags.setAlpha(image_alpha > 255 ? 255 : image_alpha); + image_flags.setColor(ScaleAlpha(flags.getColor(), 1 - percentage_)); image_flags.setAntiAlias(flags.isAntiAlias()); // TODO(junov): This code should probably be propagating the // RespectImageOrientationEnum from CrossfadeGeneratedImage::draw(). Code was @@ -71,8 +70,7 @@ void CrossfadeGeneratedImage::DrawCrossfade(PaintCanvas* canvas, from_image_->Draw(canvas, image_flags, dest_rect, from_image_rect, kDoNotRespectImageOrientation, clamp_mode, decode_mode); image_flags.setBlendMode(SkBlendMode::kPlus); - image_alpha = ClampedAlphaForBlending(percentage_); - image_flags.setAlpha(image_alpha > 255 ? 255 : image_alpha); + image_flags.setColor(ScaleAlpha(flags.getColor(), percentage_)); to_image_->Draw(canvas, image_flags, dest_rect, to_image_rect, kDoNotRespectImageOrientation, clamp_mode, decode_mode); } 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 29a8629c141..b500aea830d 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 @@ -186,9 +186,9 @@ bool DeferredImageDecoder::IsSizeAvailable() { return metadata_decoder_ ? metadata_decoder_->IsSizeAvailable() : true; } -bool DeferredImageDecoder::HasEmbeddedColorSpace() const { - return metadata_decoder_ ? metadata_decoder_->HasEmbeddedColorSpace() - : has_embedded_color_space_; +bool DeferredImageDecoder::HasEmbeddedColorProfile() const { + return metadata_decoder_ ? metadata_decoder_->HasEmbeddedColorProfile() + : has_embedded_color_profile_; } IntSize DeferredImageDecoder::Size() const { @@ -268,7 +268,7 @@ void DeferredImageDecoder::ActivateLazyDecoding() { // future.) can_yuv_decode_ = RuntimeEnabledFeatures::DecodeToYUVEnabled() && (filename_extension_ == "jpg"); - has_embedded_color_space_ = metadata_decoder_->HasEmbeddedColorSpace(); + has_embedded_color_profile_ = metadata_decoder_->HasEmbeddedColorProfile(); color_space_for_sk_images_ = metadata_decoder_->ColorSpaceForSkImages(); const bool is_single_frame = diff --git a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h index 82c05c43f0a..552f47248c1 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h +++ b/chromium/third_party/blink/renderer/platform/graphics/deferred_image_decoder.h @@ -68,7 +68,7 @@ class PLATFORM_EXPORT DeferredImageDecoder final { void SetData(scoped_refptr<SharedBuffer> data, bool all_data_received); bool IsSizeAvailable(); - bool HasEmbeddedColorSpace() const; + bool HasEmbeddedColorProfile() const; IntSize Size() const; IntSize FrameSizeAtIndex(size_t index) const; size_t FrameCount(); @@ -101,7 +101,7 @@ class PLATFORM_EXPORT DeferredImageDecoder final { String filename_extension_; IntSize size_; int repetition_count_; - bool has_embedded_color_space_ = false; + bool has_embedded_color_profile_ = false; bool all_data_received_; bool can_yuv_decode_; bool has_hot_spot_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.cc index eb2937a6799..6f92358bf7d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.cc @@ -30,7 +30,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/distant_light_source.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -48,7 +48,8 @@ bool DistantLightSource::SetElevation(float elevation) { return true; } -TextStream& DistantLightSource::ExternalRepresentation(TextStream& ts) const { +WTF::TextStream& DistantLightSource::ExternalRepresentation( + WTF::TextStream& ts) const { ts << "[type=DISTANT-LIGHT] "; ts << "[azimuth=\"" << Azimuth() << "\"]"; ts << "[elevation=\"" << Elevation() << "\"]"; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.h b/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.h index ca75b46c991..f48373d54a8 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/distant_light_source.h @@ -40,7 +40,7 @@ class PLATFORM_EXPORT DistantLightSource final : public LightSource { bool SetAzimuth(float) override; bool SetElevation(float) override; - TextStream& ExternalRepresentation(TextStream&) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&) const override; private: DistantLightSource(float azimuth, float elevation) diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc index f8dd282537b..dc633651cf0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.cc @@ -27,22 +27,18 @@ #include "SkXfermodeImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { -FEBlend::FEBlend(Filter* filter, WebBlendMode mode) +FEBlend::FEBlend(Filter* filter, BlendMode mode) : FilterEffect(filter), mode_(mode) {} -FEBlend* FEBlend::Create(Filter* filter, WebBlendMode mode) { +FEBlend* FEBlend::Create(Filter* filter, BlendMode mode) { return new FEBlend(filter, mode); } -WebBlendMode FEBlend::BlendMode() const { - return mode_; -} - -bool FEBlend::SetBlendMode(WebBlendMode mode) { +bool FEBlend::SetBlendMode(BlendMode mode) { if (mode_ == mode) return false; mode_ = mode; @@ -61,12 +57,13 @@ sk_sp<PaintFilter> FEBlend::CreateImageFilter() { std::move(foreground), &crop_rect); } -TextStream& FEBlend::ExternalRepresentation(TextStream& ts, int indent) const { +WTF::TextStream& FEBlend::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feBlend"; FilterEffect::ExternalRepresentation(ts); ts << " mode=\"" - << (mode_ == WebBlendMode::kNormal + << (mode_ == BlendMode::kNormal ? "normal" : CompositeOperatorName(kCompositeSourceOver, mode_)) << "\"]\n"; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.h index 696605e998a..4dbbf31c668 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_blend.h @@ -23,26 +23,27 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_FILTERS_FE_BLEND_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_FILTERS_FE_BLEND_H_ -#include "third_party/blink/public/platform/web_blend_mode.h" #include "third_party/blink/renderer/platform/graphics/filters/filter_effect.h" +#include "third_party/blink/renderer/platform/graphics/graphics_types.h" namespace blink { class PLATFORM_EXPORT FEBlend final : public FilterEffect { public: - static FEBlend* Create(Filter*, WebBlendMode); + static FEBlend* Create(Filter*, BlendMode); - WebBlendMode BlendMode() const; - bool SetBlendMode(WebBlendMode); + BlendMode GetBlendMode() const { return mode_; } + bool SetBlendMode(BlendMode); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: - FEBlend(Filter*, WebBlendMode); + FEBlend(Filter*, BlendMode); sk_sp<PaintFilter> CreateImageFilter() override; - WebBlendMode mode_; + BlendMode mode_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc index bdab56eb758..1b956a66f99 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.cc @@ -7,6 +7,7 @@ #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -19,8 +20,8 @@ FloatRect FEBoxReflect::MapEffect(const FloatRect& rect) const { return reflection_.MapRect(rect); } -TextStream& FEBoxReflect::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEBoxReflect::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { // Only called for SVG layout tree printing. NOTREACHED(); return ts; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.h index 9127df947d4..f7227790c0f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_box_reflect.h @@ -19,7 +19,8 @@ class PLATFORM_EXPORT FEBoxReflect final : public FilterEffect { } // FilterEffect implementation - TextStream& ExternalRepresentation(TextStream&, int indentation) const final; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indentation) const final; private: FEBoxReflect(Filter*, const BoxReflection&); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc index ee82ceb2dc9..78384c99086 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.cc @@ -26,7 +26,7 @@ #include "SkColorFilterImageFilter.h" #include "SkColorMatrixFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -161,7 +161,8 @@ sk_sp<PaintFilter> FEColorMatrix::CreateImageFilter() { &rect); } -static TextStream& operator<<(TextStream& ts, const ColorMatrixType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const ColorMatrixType& type) { switch (type) { case FECOLORMATRIX_TYPE_UNKNOWN: ts << "UNKNOWN"; @@ -199,8 +200,8 @@ static bool ValuesIsValidForType(ColorMatrixType type, return false; } -TextStream& FEColorMatrix::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEColorMatrix::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feColorMatrix"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h index a267d3988b5..2cd73e87872 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_color_matrix.h @@ -46,7 +46,8 @@ class PLATFORM_EXPORT FEColorMatrix final : public FilterEffect { const Vector<float>& Values() const; bool SetValues(const Vector<float>&); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; static inline void CalculateSaturateComponents(float* components, float value); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc index bfc9b3dfc4c..ba73a1f815e 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.cc @@ -27,8 +27,8 @@ #include <algorithm> #include "SkTableColorFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -161,14 +161,14 @@ void FEComponentTransfer::GetValues(unsigned char r_values[256], for (unsigned channel = 0; channel < 4; channel++) { SECURITY_DCHECK(static_cast<size_t>(transfer_function[channel].type) < - WTF_ARRAY_LENGTH(call_effect)); + arraysize(call_effect)); (*call_effect[transfer_function[channel].type])(tables[channel], transfer_function[channel]); } } -static TextStream& operator<<(TextStream& ts, - const ComponentTransferType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const ComponentTransferType& type) { switch (type) { case FECOMPONENTTRANSFER_TYPE_UNKNOWN: ts << "UNKNOWN"; @@ -192,8 +192,8 @@ static TextStream& operator<<(TextStream& ts, return ts; } -static TextStream& operator<<(TextStream& ts, - const ComponentTransferFunction& function) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const ComponentTransferFunction& function) { ts << "type=\"" << function.type << "\" slope=\"" << function.slope << "\" intercept=\"" << function.intercept << "\" amplitude=\"" << function.amplitude << "\" exponent=\"" << function.exponent @@ -201,8 +201,9 @@ static TextStream& operator<<(TextStream& ts, return ts; } -TextStream& FEComponentTransfer::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEComponentTransfer::ExternalRepresentation( + WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feComponentTransfer"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.h index 278fe470ce3..74738c4dc1b 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_component_transfer.h @@ -67,7 +67,8 @@ class PLATFORM_EXPORT FEComponentTransfer final : public FilterEffect { const ComponentTransferFunction& blue_func, const ComponentTransferFunction& alpha_func); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEComponentTransfer(Filter*, diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc index 047e93f73d5..b62ac9f8a77 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.cc @@ -29,7 +29,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -210,8 +210,8 @@ sk_sp<PaintFilter> FEComposite::CreateImageFilterInternal( std::move(foreground), &crop_rect); } -static TextStream& operator<<(TextStream& ts, - const CompositeOperationType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const CompositeOperationType& type) { switch (type) { case FECOMPOSITE_OPERATOR_UNKNOWN: ts << "UNKNOWN"; @@ -241,8 +241,8 @@ static TextStream& operator<<(TextStream& ts, return ts; } -TextStream& FEComposite::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEComposite::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feComposite"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.h index 5a469c4bb50..3841eb7b411 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_composite.h @@ -63,7 +63,8 @@ class PLATFORM_EXPORT FEComposite final : public FilterEffect { float K4() const; bool SetK4(float); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; protected: bool MayProduceInvalidPreMultipliedPixels() override { diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc index d9ac47ac002..c09fd849111 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.cc @@ -27,8 +27,8 @@ #include <memory> #include "SkMatrixConvolutionImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/checked_numeric.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -160,7 +160,8 @@ sk_sp<PaintFilter> FEConvolveMatrix::CreateImageFilter() { std::move(input), &crop_rect); } -static TextStream& operator<<(TextStream& ts, const EdgeModeType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const EdgeModeType& type) { switch (type) { case EDGEMODE_UNKNOWN: ts << "UNKNOWN"; @@ -178,8 +179,8 @@ static TextStream& operator<<(TextStream& ts, const EdgeModeType& type) { return ts; } -TextStream& FEConvolveMatrix::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEConvolveMatrix::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feConvolveMatrix"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.h index f53f6d9f3ea..615e29cf88a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_convolve_matrix.h @@ -56,7 +56,8 @@ class PLATFORM_EXPORT FEConvolveMatrix final : public FilterEffect { bool SetEdgeMode(EdgeModeType); bool SetPreserveAlpha(bool); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEConvolveMatrix(Filter*, diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.cc index 69459d5b7a4..344387f83fd 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.cc @@ -23,7 +23,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.h" #include "third_party/blink/renderer/platform/graphics/filters/light_source.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -96,8 +96,8 @@ void FEDiffuseLighting::SetLightSource( light_source_ = std::move(light_source); } -TextStream& FEDiffuseLighting::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEDiffuseLighting::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feDiffuseLighting"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.h index a29cdf617c7..8c57b151a76 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_diffuse_lighting.h @@ -50,7 +50,8 @@ class PLATFORM_EXPORT FEDiffuseLighting final : public FELighting { const LightSource* GetLightSource() const; void SetLightSource(scoped_refptr<LightSource>); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEDiffuseLighting(Filter*, diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc index 3515d88a43e..79d35126a50 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.cc @@ -27,7 +27,7 @@ #include "SkDisplacementMapEffect.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -137,7 +137,8 @@ sk_sp<PaintFilter> FEDisplacementMap::CreateImageFilter() { std::move(displ), std::move(color), &crop_rect); } -static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const ChannelSelectorType& type) { switch (type) { case CHANNEL_UNKNOWN: ts << "UNKNOWN"; @@ -158,8 +159,8 @@ static TextStream& operator<<(TextStream& ts, const ChannelSelectorType& type) { return ts; } -TextStream& FEDisplacementMap::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEDisplacementMap::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feDisplacementMap"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.h index cd99d19e32d..a224f92a065 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_displacement_map.h @@ -51,7 +51,8 @@ class PLATFORM_EXPORT FEDisplacementMap final : public FilterEffect { float Scale() const; bool SetScale(float); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEDisplacementMap(Filter*, diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc index cad25647e74..113995770d0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.cc @@ -23,7 +23,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" namespace blink { @@ -91,8 +91,8 @@ sk_sp<PaintFilter> FEDropShadow::CreateImageFilter() { std::move(input), &crop_rect); } -TextStream& FEDropShadow::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEDropShadow::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feDropShadow"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.h index 6b1690268ea..bbdf2838f03 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_drop_shadow.h @@ -40,7 +40,8 @@ class PLATFORM_EXPORT FEDropShadow final : public FilterEffect { void SetShadowColor(const Color& color) { shadow_color_ = color; } void SetShadowOpacity(float opacity) { shadow_opacity_ = opacity; } - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEDropShadow(Filter*, float, float, float, float, const Color&, float); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.cc index e3b09cce37d..27d749cd8b7 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.cc @@ -25,7 +25,7 @@ #include "SkColorFilter.h" #include "SkColorFilterImageFilter.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -72,7 +72,8 @@ sk_sp<PaintFilter> FEFlood::CreateImageFilter() { &rect); } -TextStream& FEFlood::ExternalRepresentation(TextStream& ts, int indent) const { +WTF::TextStream& FEFlood::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feFlood"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.h index 8f049fc1179..6ebaae3aafe 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_flood.h @@ -43,7 +43,8 @@ class PLATFORM_EXPORT FEFlood final : public FilterEffect { // color-interpolation-filters. void SetOperatingInterpolationSpace(InterpolationSpace) override {} - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEFlood(Filter*, const Color&, float); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc index 7f6eb5e12bb..f04200b8805 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.cc @@ -27,7 +27,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "SkBlurImageFilter.h" @@ -92,8 +92,8 @@ sk_sp<PaintFilter> FEGaussianBlur::CreateImageFilter() { &rect); } -TextStream& FEGaussianBlur::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEGaussianBlur::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feGaussianBlur"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.h index 55ea8f34cf0..73ec88b7263 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_gaussian_blur.h @@ -35,7 +35,8 @@ class PLATFORM_EXPORT FEGaussianBlur final : public FilterEffect { // blur effect with |stdDeviation| to an area |rect|. static FloatRect MapEffect(const FloatSize& std_deviation, const FloatRect&); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEGaussianBlur(Filter*, float, float); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc index d587315b248..57aec415e97 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.cc @@ -25,7 +25,7 @@ #include <memory> #include "SkMergeImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -47,7 +47,8 @@ sk_sp<PaintFilter> FEMerge::CreateImageFilter() { return sk_make_sp<MergePaintFilter>(input_refs.get(), size, &rect); } -TextStream& FEMerge::ExternalRepresentation(TextStream& ts, int indent) const { +WTF::TextStream& FEMerge::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feMerge"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.h index a5ffee7ee56..0577157d77a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_merge.h @@ -31,7 +31,8 @@ class PLATFORM_EXPORT FEMerge final : public FilterEffect { public: static FEMerge* Create(Filter*); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: explicit FEMerge(Filter*); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc index b95c0dd8b2f..40842ec1d32 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.cc @@ -27,7 +27,7 @@ #include "SkMorphologyImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -103,8 +103,8 @@ sk_sp<PaintFilter> FEMorphology::CreateImageFilter() { std::move(input), &rect); } -static TextStream& operator<<(TextStream& ts, - const MorphologyOperatorType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const MorphologyOperatorType& type) { switch (type) { case FEMORPHOLOGY_OPERATOR_UNKNOWN: ts << "UNKNOWN"; @@ -119,8 +119,8 @@ static TextStream& operator<<(TextStream& ts, return ts; } -TextStream& FEMorphology::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FEMorphology::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feMorphology"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.h index a711006f039..93b7048cea9 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_morphology.h @@ -48,7 +48,8 @@ class PLATFORM_EXPORT FEMorphology final : public FilterEffect { float RadiusY() const; bool SetRadiusY(float); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEMorphology(Filter*, MorphologyOperatorType, float radius_x, float radius_y); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc index 9910549dfd5..01236fda004 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.cc @@ -27,7 +27,7 @@ #include "SkOffsetImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -71,7 +71,8 @@ sk_sp<PaintFilter> FEOffset::CreateImageFilter() { &crop_rect); } -TextStream& FEOffset::ExternalRepresentation(TextStream& ts, int indent) const { +WTF::TextStream& FEOffset::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feOffset"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.h index 3a571149f4d..2a456246cdb 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_offset.h @@ -37,7 +37,8 @@ class PLATFORM_EXPORT FEOffset final : public FilterEffect { float Dy() const; void SetDy(float); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FEOffset(Filter*, float dx, float dy); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.cc index 9eab482ef6a..427ef6715ef 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.cc @@ -24,8 +24,8 @@ #include <algorithm> #include "third_party/blink/renderer/platform/graphics/filters/light_source.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -113,8 +113,8 @@ void FESpecularLighting::SetLightSource( light_source_ = std::move(light_source); } -TextStream& FESpecularLighting::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FESpecularLighting::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feSpecularLighting"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.h index 2a0ea3775e9..da68cb2136f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_specular_lighting.h @@ -52,7 +52,8 @@ class PLATFORM_EXPORT FESpecularLighting final : public FELighting { const LightSource* GetLightSource() const; void SetLightSource(scoped_refptr<LightSource>); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FESpecularLighting(Filter*, diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc index 3b4d8bb93c5..31292c463e9 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.cc @@ -24,7 +24,7 @@ #include "SkTileImageFilter.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -53,7 +53,8 @@ sk_sp<PaintFilter> FETile::CreateImageFilter() { return sk_make_sp<TilePaintFilter>(src_rect, dst_rect, std::move(input)); } -TextStream& FETile::ExternalRepresentation(TextStream& ts, int indent) const { +WTF::TextStream& FETile::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feTile"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h index 7a40b038a21..29c4cbf4894 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_tile.h @@ -31,7 +31,8 @@ class PLATFORM_EXPORT FETile final : public FilterEffect { public: static FETile* Create(Filter*); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FETile(Filter*); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc index 94d60f6380e..da06cbabff0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.cc @@ -28,7 +28,7 @@ #include "SkPaintImageFilter.h" #include "SkPerlinNoiseShader.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -148,7 +148,8 @@ sk_sp<PaintFilter> FETurbulence::CreateImageFilter() { StitchTiles() ? &size : nullptr, &rect); } -static TextStream& operator<<(TextStream& ts, const TurbulenceType& type) { +static WTF::TextStream& operator<<(WTF::TextStream& ts, + const TurbulenceType& type) { switch (type) { case FETURBULENCE_TYPE_UNKNOWN: ts << "UNKNOWN"; @@ -163,8 +164,8 @@ static TextStream& operator<<(TextStream& ts, const TurbulenceType& type) { return ts; } -TextStream& FETurbulence::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& FETurbulence::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[feTurbulence"; FilterEffect::ExternalRepresentation(ts); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.h b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.h index 8edb1a7b9f7..8f07b2d1b73 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/fe_turbulence.h @@ -58,7 +58,8 @@ class PLATFORM_EXPORT FETurbulence final : public FilterEffect { bool StitchTiles() const; bool SetStitchTiles(bool); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: FETurbulence(Filter*, TurbulenceType, float, float, int, float, bool); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc index 0af548ed950..f440f58c937 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.cc @@ -108,7 +108,8 @@ Color FilterEffect::AdaptColorToOperatingInterpolationSpace( device_color, OperatingInterpolationSpace()); } -TextStream& FilterEffect::ExternalRepresentation(TextStream& ts, int) const { +WTF::TextStream& FilterEffect::ExternalRepresentation(WTF::TextStream& ts, + int) const { // FIXME: We should dump the subRegions of the filter primitives here later. // This isn't possible at the moment, because we need more detailed // information from the target object. diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h index 7bb18ff967a..70856a53280 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/filter_effect.h @@ -30,6 +30,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_filter.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -37,7 +38,6 @@ namespace blink { class Filter; class FilterEffect; -class TextStream; typedef HeapVector<Member<FilterEffect>> FilterEffectVector; @@ -82,8 +82,8 @@ class PLATFORM_EXPORT FilterEffect return kFilterEffectTypeUnknown; } - virtual TextStream& ExternalRepresentation(TextStream&, - int indention = 0) const; + virtual WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention = 0) const; FloatRect FilterPrimitiveSubregion() const { return filter_primitive_subregion_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc index a226148ad9e..1f15afc01c3 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/image_filter_builder_test.cc @@ -52,7 +52,7 @@ class ImageFilterBuilderTest : public Test { // Add a blend effect (with inputs : blur, source) FilterEffect* blend_effect = - FEBlend::Create(reference_filter, WebBlendMode::kNormal); + FEBlend::Create(reference_filter, BlendMode::kNormal); blend_effect->SetOperatingInterpolationSpace(kInterpolationSpaceSRGB); FilterEffectVector& blend_inputs = blend_effect->InputEffects(); blend_inputs.ReserveCapacity(2); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/light_source.h b/chromium/third_party/blink/renderer/platform/graphics/filters/light_source.h index 37ab76da294..46dc4958716 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/light_source.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/light_source.h @@ -27,6 +27,7 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/platform/geometry/float_point_3d.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" @@ -34,8 +35,6 @@ namespace blink { enum LightType { LS_DISTANT, LS_POINT, LS_SPOT }; -class TextStream; - class PLATFORM_EXPORT LightSource : public RefCounted<LightSource> { WTF_MAKE_NONCOPYABLE(LightSource); @@ -45,7 +44,7 @@ class PLATFORM_EXPORT LightSource : public RefCounted<LightSource> { virtual ~LightSource(); LightType GetType() const { return type_; } - virtual TextStream& ExternalRepresentation(TextStream&) const = 0; + virtual WTF::TextStream& ExternalRepresentation(WTF::TextStream&) const = 0; virtual bool SetAzimuth(float) { return false; } virtual bool SetElevation(float) { return false; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc index 588d27e4f66..6686196539d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.cc @@ -5,7 +5,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/skia/include/effects/SkPaintImageFilter.h" namespace blink { @@ -26,8 +26,8 @@ sk_sp<PaintFilter> PaintFilterEffect::CreateImageFilter() { return sk_make_sp<PaintFlagsPaintFilter>(flags_); } -TextStream& PaintFilterEffect::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& PaintFilterEffect::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[PaintFilterEffect]\n"; return ts; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h b/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h index f320efec706..599f5cc175f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/paint_filter_effect.h @@ -19,7 +19,8 @@ class PLATFORM_EXPORT PaintFilterEffect : public FilterEffect { return kFilterEffectTypeSourceInput; } - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; sk_sp<PaintFilter> CreateImageFilter() override; private: diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.cc index 2c6f4f115bd..d6045247fe6 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.cc @@ -30,7 +30,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/point_light_source.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -41,7 +41,8 @@ bool PointLightSource::SetPosition(const FloatPoint3D& position) { return true; } -TextStream& PointLightSource::ExternalRepresentation(TextStream& ts) const { +WTF::TextStream& PointLightSource::ExternalRepresentation( + WTF::TextStream& ts) const { ts << "[type=POINT-LIGHT] "; ts << "[position=\"" << GetPosition() << "\"]"; return ts; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.h b/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.h index 5e4d625631c..5c89bf91502 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/point_light_source.h @@ -36,7 +36,7 @@ class PLATFORM_EXPORT PointLightSource final : public LightSource { const FloatPoint3D& GetPosition() const { return position_; } bool SetPosition(const FloatPoint3D&) override; - TextStream& ExternalRepresentation(TextStream&) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&) const override; private: PointLightSource(const FloatPoint3D& position) diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc index 5ea8cdecc69..0d08d1eb646 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.cc @@ -22,7 +22,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/filter.h" #include "third_party/blink/renderer/platform/graphics/filters/paint_filter_builder.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" #include "third_party/skia/include/effects/SkColorMatrixFilter.h" @@ -50,8 +50,8 @@ sk_sp<PaintFilter> SourceAlpha::CreateImageFilter() { std::move(source_graphic)); } -TextStream& SourceAlpha::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& SourceAlpha::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[SourceAlpha]\n"; return ts; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.h b/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.h index fedadb144b0..6b4cd7adc8a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/source_alpha.h @@ -29,7 +29,8 @@ class PLATFORM_EXPORT SourceAlpha final : public FilterEffect { public: static SourceAlpha* Create(FilterEffect*); - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; private: explicit SourceAlpha(FilterEffect*); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.cc index 02b0bf8293a..d06b534ddfa 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.cc @@ -21,7 +21,7 @@ #include "third_party/blink/renderer/platform/graphics/filters/source_graphic.h" #include "third_party/blink/renderer/platform/graphics/filters/filter.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -43,8 +43,8 @@ void SourceGraphic::SetSourceRect(const IntRect& source_rect) { source_rect_ = source_rect; } -TextStream& SourceGraphic::ExternalRepresentation(TextStream& ts, - int indent) const { +WTF::TextStream& SourceGraphic::ExternalRepresentation(WTF::TextStream& ts, + int indent) const { WriteIndent(ts, indent); ts << "[SourceGraphic]\n"; return ts; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.h b/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.h index 0e06362b759..753b71ac8e8 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/source_graphic.h @@ -32,7 +32,8 @@ class PLATFORM_EXPORT SourceGraphic final : public FilterEffect { static SourceGraphic* Create(Filter*); ~SourceGraphic() override; - TextStream& ExternalRepresentation(TextStream&, int indention) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&, + int indention) const override; void SetSourceRect(const IntRect&); diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.cc b/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.cc index a47abedb89e..c694e4b2c13 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.cc @@ -31,8 +31,8 @@ #include "third_party/blink/renderer/platform/graphics/filters/spot_light_source.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" namespace blink { @@ -65,7 +65,8 @@ bool SpotLightSource::SetLimitingConeAngle(float limiting_cone_angle) { return true; } -TextStream& SpotLightSource::ExternalRepresentation(TextStream& ts) const { +WTF::TextStream& SpotLightSource::ExternalRepresentation( + WTF::TextStream& ts) const { ts << "[type=SPOT-LIGHT] "; ts << "[position=\"" << GetPosition() << "\"]"; ts << "[direction=\"" << Direction() << "\"]"; diff --git a/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.h b/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.h index 463b0c0d356..7ae7b635a95 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.h +++ b/chromium/third_party/blink/renderer/platform/graphics/filters/spot_light_source.h @@ -49,7 +49,7 @@ class PLATFORM_EXPORT SpotLightSource final : public LightSource { bool SetSpecularExponent(float) override; bool SetLimitingConeAngle(float) override; - TextStream& ExternalRepresentation(TextStream&) const override; + WTF::TextStream& ExternalRepresentation(WTF::TextStream&) const override; private: SpotLightSource(const FloatPoint3D& position, diff --git a/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.cc b/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.cc deleted file mode 100644 index e3d723e9133..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.cc +++ /dev/null @@ -1,11 +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/graphics/first_paint_invalidation_tracking.h" - -namespace blink { - -bool FirstPaintInvalidationTracking::enabled_for_show_paint_rects_ = false; - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.h b/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.h deleted file mode 100644 index a338c3798e7..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.h +++ /dev/null @@ -1,35 +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_GRAPHICS_FIRST_PAINT_INVALIDATION_TRACKING_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_FIRST_PAINT_INVALIDATION_TRACKING_H_ - -#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace blink { - -class PLATFORM_EXPORT FirstPaintInvalidationTracking { - public: - static bool IsEnabled() { - if (enabled_for_show_paint_rects_) - return true; - - bool is_tracing_enabled; - TRACE_EVENT_CATEGORY_GROUP_ENABLED( - TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), &is_tracing_enabled); - return is_tracing_enabled; - } - - static void SetEnabledForShowPaintRects(bool enabled) { - enabled_for_show_paint_rects_ = enabled; - } - - private: - static bool enabled_for_show_paint_rects_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_FIRST_PAINT_INVALIDATION_TRACKING_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 dded64ab9ff..29a1b56cbbd 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 @@ -46,10 +46,7 @@ #include "gpu/command_buffer/common/gpu_memory_buffer_support.h" #include "gpu/config/gpu_driver_bug_workaround_type.h" #include "gpu/config/gpu_feature_info.h" -#include "skia/ext/texture_handle.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_external_texture_layer.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/gpu/extensions_3d_util.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -190,8 +187,12 @@ DrawingBuffer::DrawingBuffer( DrawingBuffer::~DrawingBuffer() { DCHECK(destruction_in_progress_); - layer_.reset(); - context_provider_.reset(); + SwapPreviousFrameCallback(nullptr); + if (layer_) { + layer_->ClearClient(); + layer_ = nullptr; + } + context_provider_ = nullptr; } bool DrawingBuffer::MarkContentsChanged() { @@ -264,24 +265,32 @@ bool DrawingBuffer::DefaultBufferRequiresAlphaChannelToBePreserved() { DrawingBuffer::RegisteredBitmap DrawingBuffer::CreateOrRecycleBitmap( cc::SharedBitmapIdRegistrar* bitmap_registrar) { - auto it = std::remove_if(recycled_bitmaps_.begin(), recycled_bitmaps_.end(), - [this](const RegisteredBitmap& registered) { - return registered.bitmap->size() != size_; - }); + // When searching for a hit in SharedBitmap, we don't consider the bitmap + // format (RGBA 8888 vs F16). We expect to always have the same bitmap format, + // matching the back storage of the drawing buffer. + auto* it = std::remove_if(recycled_bitmaps_.begin(), recycled_bitmaps_.end(), + [this](const RegisteredBitmap& registered) { + return registered.bitmap->size() != + static_cast<gfx::Size>(size_); + }); recycled_bitmaps_.Shrink(it - recycled_bitmaps_.begin()); if (!recycled_bitmaps_.IsEmpty()) { RegisteredBitmap recycled = std::move(recycled_bitmaps_.back()); recycled_bitmaps_.pop_back(); - DCHECK(recycled.bitmap->size() == size_); + DCHECK(recycled.bitmap->size() == static_cast<gfx::Size>(size_)); return recycled; } viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); + viz::ResourceFormat format = viz::RGBA_8888; + if (use_half_float_storage_) + format = viz::RGBA_F16; std::unique_ptr<base::SharedMemory> shm = - viz::bitmap_allocation::AllocateMappedBitmap(size_, viz::RGBA_8888); + viz::bitmap_allocation::AllocateMappedBitmap( + static_cast<gfx::Size>(size_), format); auto bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( - id, std::move(shm), size_, viz::RGBA_8888); + id, std::move(shm), static_cast<gfx::Size>(size_), format); RegisteredBitmap registered = { bitmap, bitmap_registrar->RegisterSharedBitmapId(id, bitmap)}; return registered; @@ -357,8 +366,11 @@ void DrawingBuffer::FinishPrepareTransferableResourceSoftware( op); } + viz::ResourceFormat format = viz::RGBA_8888; + if (use_half_float_storage_) + format = viz::RGBA_F16; *out_resource = viz::TransferableResource::MakeSoftware( - registered.bitmap->id(), /*sequence_number=*/0, size_, viz::RGBA_8888); + registered.bitmap->id(), static_cast<gfx::Size>(size_), format); out_resource->color_space = storage_color_space_; // This holds a ref on the DrawingBuffer that will keep it alive until the @@ -451,6 +463,8 @@ void DrawingBuffer::FinishPrepareTransferableResourceGpu( is_overlay_candidate); out_resource->color_space = sampler_color_space_; out_resource->format = viz::RGBA_8888; + if (use_half_float_storage_) + out_resource->format = viz::RGBA_F16; // This holds a ref on the DrawingBuffer that will keep it alive until the // mailbox is released (and while the release callback is running). @@ -501,7 +515,7 @@ void DrawingBuffer::MailboxReleasedSoftware(RegisteredBitmap registered, bool lost_resource) { DCHECK(!sync_token.HasData()); // No sync tokens for software resources. if (destruction_in_progress_ || lost_resource || is_hidden_ || - registered.bitmap->size() != size_) { + registered.bitmap->size() != static_cast<gfx::Size>(size_)) { // Just delete the RegisteredBitmap, which will free the memory and // unregister it with the compositor. return; @@ -861,13 +875,12 @@ bool DrawingBuffer::CopyToPlatformTexture(gpu::gles2::GLES2Interface* dst_gl, return true; } -WebLayer* DrawingBuffer::PlatformLayer() { +cc::Layer* DrawingBuffer::CcLayer() { if (!layer_) { - layer_ = - Platform::Current()->CompositorSupport()->CreateExternalTextureLayer( - this); + layer_ = cc::TextureLayer::CreateForMailbox(this); - layer_->SetOpaque(!want_alpha_channel_); + layer_->SetIsDrawable(true); + layer_->SetContentsOpaque(!want_alpha_channel_); layer_->SetBlendBackgroundColor(want_alpha_channel_); // If premultiplied_alpha_false_texture_ exists, then premultiplied_alpha_ // has already been handled via CopySubTextureCHROMIUM -- the alpha channel @@ -882,13 +895,14 @@ WebLayer* DrawingBuffer::PlatformLayer() { layer_->SetPremultipliedAlpha(premultiplied_alpha_ || premultiplied_alpha_false_texture_); layer_->SetNearestNeighbor(filter_quality_ == kNone_SkFilterQuality); - GraphicsLayer::RegisterContentsLayer(layer_->Layer()); + + GraphicsLayer::RegisterContentsLayer(layer_.get()); } - return layer_->Layer(); + return layer_.get(); } -void DrawingBuffer::ClearPlatformLayer() { +void DrawingBuffer::ClearCcLayer() { if (layer_) layer_->ClearTexture(); @@ -899,7 +913,7 @@ void DrawingBuffer::BeginDestruction() { DCHECK(!destruction_in_progress_); destruction_in_progress_ = true; - ClearPlatformLayer(); + ClearCcLayer(); recycled_color_buffer_queue_.clear(); // If the drawing buffer is being destroyed due to a real context loss these @@ -930,7 +944,7 @@ void DrawingBuffer::BeginDestruction() { fbo_ = 0; if (layer_) - GraphicsLayer::UnregisterContentsLayer(layer_->Layer()); + GraphicsLayer::UnregisterContentsLayer(layer_.get()); client_ = nullptr; } @@ -1594,6 +1608,15 @@ DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() { client->DrawingBufferClientRestorePixelPackBufferBinding(); } +void DrawingBuffer::SwapPreviousFrameCallback( + std::unique_ptr<viz::SingleReleaseCallback> release_callback) { + if (previous_image_release_callback_) { + previous_image_release_callback_->Run(gpu::SyncToken(), false); + } + + previous_image_release_callback_ = std::move(release_callback); +} + bool DrawingBuffer::ShouldUseChromiumImage() { return RuntimeEnabledFeatures::WebGLImageChromiumEnabled() && chromium_image_usage_ == kAllowChromiumImage && 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 e19db7bcc26..092f0bb2b7c 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 @@ -50,6 +50,10 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/color_space.h" +namespace cc { +class Layer; +} + namespace gfx { class GpuMemoryBuffer; } @@ -64,13 +68,11 @@ namespace blink { class CanvasColorParams; class Extensions3DUtil; class StaticBitmapImage; -class WebExternalTextureLayer; class WebGraphicsContext3DProvider; class WebGraphicsContext3DProviderWrapper; -class WebLayer; // Manages a rendering target (framebuffer + attachment) for a canvas. Can -// publish its rendering results to a WebLayer for compositing. +// publish its rendering results to a cc::Layer for compositing. class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, public RefCounted<DrawingBuffer> { WTF_MAKE_NONCOPYABLE(DrawingBuffer); @@ -191,7 +193,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, // default framebuffer. bool DefaultBufferRequiresAlphaChannelToBePreserved(); - WebLayer* PlatformLayer(); + cc::Layer* CcLayer(); gpu::gles2::GLES2Interface* ContextGL(); WebGraphicsContext3DProvider* ContextProvider(); @@ -239,6 +241,11 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, // Restore all state that may have been dirtied by any call. void RestoreAllState(); + // Run the previous release callback if it exists. If the release_callback is + // not null, assign it to the previous_image_release_callback_. + void SwapPreviousFrameCallback( + std::unique_ptr<viz::SingleReleaseCallback> release_callback); + // This class helps implement correct semantics for BlitFramebuffer // when the DrawingBuffer is using a CHROMIUM image for its backing // store and RGB emulation is in use (basically, macOS only). @@ -401,7 +408,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, // the operation was successful. bool ResizeDefaultFramebuffer(const IntSize&); - void ClearPlatformLayer(); + void ClearCcLayer(); RegisteredBitmap CreateOrRecycleBitmap( cc::SharedBitmapIdRegistrar* bitmap_registrar); @@ -558,7 +565,7 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, bool is_hidden_ = false; SkFilterQuality filter_quality_ = kLow_SkFilterQuality; - std::unique_ptr<WebExternalTextureLayer> layer_; + scoped_refptr<cc::TextureLayer> layer_; // Mailboxes that were released by the compositor can be used again by this // DrawingBuffer. @@ -578,6 +585,10 @@ class PLATFORM_EXPORT DrawingBuffer : public cc::TextureLayerClient, // DisallowChromiumImage in the case of OffscreenCanvas. ChromiumImageUsage chromium_image_usage_; bool ShouldUseChromiumImage(); + + // A release callback that is run when the previouis image passed to + // OffscreenCanvas::Commit() is no longer needed. + std::unique_ptr<viz::SingleReleaseCallback> previous_image_release_callback_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_software_rendering_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_software_rendering_test.cc index c8e07ba0c7a..7c9065f0dd6 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_software_rendering_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer_software_rendering_test.cc @@ -21,9 +21,9 @@ namespace blink { namespace { class TestSharedBitmapIdRegistar : public cc::SharedBitmapIdRegistrar { - virtual cc::SharedBitmapIdRegistration RegisterSharedBitmapId( + cc::SharedBitmapIdRegistration RegisterSharedBitmapId( const viz::SharedBitmapId& id, - scoped_refptr<cc::CrossThreadSharedBitmap> bitmap) { + scoped_refptr<cc::CrossThreadSharedBitmap> bitmap) override { return {}; } }; 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 e4171a1f293..e67ef2b7e61 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 @@ -439,7 +439,7 @@ TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) { &release_callback)); EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); - EXPECT_EQ(initial_size, resource.size); + EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); testing::Mock::VerifyAndClearExpectations(gl_); VerifyStateWasRestored(); @@ -464,7 +464,7 @@ TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) { &release_callback)); EXPECT_EQ(alternate_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); - EXPECT_EQ(alternate_size, resource.size); + EXPECT_EQ(static_cast<gfx::Size>(alternate_size), resource.size); testing::Mock::VerifyAndClearExpectations(gl_); GLuint image_id4 = gl_->NextImageIdToBeCreated(); @@ -488,7 +488,7 @@ TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) { &release_callback)); EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); - EXPECT_EQ(initial_size, resource.size); + EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); testing::Mock::VerifyAndClearExpectations(gl_); // Prepare one final resource and verify that it's the correct size. @@ -498,7 +498,7 @@ TEST_F(DrawingBufferImageChromiumTest, VerifyResizingReallocatesImages) { &release_callback)); EXPECT_EQ(initial_size, gl_->MostRecentlyProducedSize()); EXPECT_TRUE(resource.is_overlay_candidate); - EXPECT_EQ(initial_size, resource.size); + EXPECT_EQ(static_cast<gfx::Size>(initial_size), resource.size); release_callback->Run(gpu::SyncToken(), false /* lostResource */); EXPECT_CALL(*gl_, DestroyImageMock(image_id5)).Times(1); @@ -649,7 +649,7 @@ TEST(DrawingBufferDepthStencilTest, packedDepthStencilSupported) { DepthStencilTestCase(true, true, 1, "both"), }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(cases); i++) { + for (size_t i = 0; i < arraysize(cases); i++) { SCOPED_TRACE(cases[i].test_case_name); auto gl = std::make_unique<DepthStencilTrackingGLES2Interface>(); DepthStencilTrackingGLES2Interface* tracking_gl = gl.get(); 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 308e30ab5a2..3982c821752 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 @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_DRAWING_BUFFER_TEST_HELPERS_H_ #include "build/build_config.h" +#include "cc/test/stub_decode_cache.h" #include "gpu/command_buffer/common/capabilities.h" #include "gpu/config/gpu_feature_info.h" #include "testing/gmock/include/gmock/gmock.h" @@ -51,11 +52,13 @@ class WebGraphicsContext3DProviderForTests viz::GLHelper* GetGLHelper() override { return nullptr; } void SetLostContextCallback(base::Closure) override {} void SetErrorMessageCallback( - base::RepeatingCallback<void(const char*, int32_t id)>) {} - void SignalQuery(uint32_t, base::OnceClosure) override {} - cc::ImageDecodeCache* ImageDecodeCache() override { return nullptr; } + base::RepeatingCallback<void(const char*, int32_t id)>) override {} + cc::ImageDecodeCache* ImageDecodeCache() override { + return &image_decode_cache_; + } private: + cc::StubDecodeCache image_decode_cache_; std::unique_ptr<gpu::gles2::GLES2Interface> gl_; gpu::Capabilities capabilities_; gpu::GpuFeatureInfo gpu_feature_info_; @@ -108,12 +111,12 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, state_.renderbuffer_binding = renderbuffer; } - void Enable(GLenum cap) { + void Enable(GLenum cap) override { if (cap == GL_SCISSOR_TEST) state_.scissor_enabled = true; } - void Disable(GLenum cap) { + void Disable(GLenum cap) override { if (cap == GL_SCISSOR_TEST) state_.scissor_enabled = false; } @@ -232,7 +235,7 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, } MOCK_METHOD1(DestroyImageMock, void(GLuint imageId)); - void DestroyImageCHROMIUM(GLuint image_id) { + void DestroyImageCHROMIUM(GLuint image_id) override { image_sizes_.erase(image_id); // No textures should be bound to this. CHECK(image_to_texture_map_.find(image_id) == image_to_texture_map_.end()); @@ -241,7 +244,7 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, } MOCK_METHOD1(BindTexImage2DMock, void(GLint imageId)); - void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) { + void BindTexImage2DCHROMIUM(GLenum target, GLint image_id) override { if (target == ImageCHROMIUMTextureTarget()) { texture_sizes_.Set(bound_textures_[target], image_sizes_.find(image_id)->value); @@ -251,7 +254,7 @@ class GLES2InterfaceForTests : public gpu::gles2::GLES2InterfaceStub, } MOCK_METHOD1(ReleaseTexImage2DMock, void(GLint imageId)); - void ReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id) { + void ReleaseTexImage2DCHROMIUM(GLenum target, GLint image_id) override { if (target == ImageCHROMIUMTextureTarget()) { image_sizes_.Set(current_image_id_, IntSize()); image_to_texture_map_.erase(image_id); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc index 0adc80a4a48..5ba8ed67981 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/gpu/graphics_context_3d_utils.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "skia/ext/texture_handle.h" #include "third_party/blink/renderer/platform/graphics/web_graphics_context_3d_provider_wrapper.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -63,9 +62,14 @@ void GraphicsContext3DUtils::GetMailboxForSkImage(gpu::Mailbox& out_mailbox, cached_mailboxes_.insert(gr_texture, out_mailbox); } - GLuint texture_id = - skia::GrBackendObjectToGrGLTextureInfo(image->getTextureHandle(true)) - ->fID; + GrBackendTexture backend_texture = image->getBackendTexture(true); + DCHECK(backend_texture.isValid()); + + GrGLTextureInfo info; + bool result = backend_texture.getGLTextureInfo(&info); + DCHECK(result); + + GLuint texture_id = info.fID; gl->BindTexture(GL_TEXTURE_2D, texture_id); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); gl->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); 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 10f2d7faeda..8f6c3f88718 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 @@ -4,30 +4,35 @@ #include "third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h" +#include "cc/layers/texture_layer.h" +#include "cc/resources/cross_thread_shared_bitmap.h" #include "components/viz/common/quads/shared_bitmap.h" +#include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/transferable_resource.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_external_texture_layer.h" #include "third_party/blink/public/platform/web_graphics_context_3d_provider.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" +#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h" #include "third_party/blink/renderer/platform/graphics/color_behavior.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" +#include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "ui/gfx/geometry/size.h" namespace blink { ImageLayerBridge::ImageLayerBridge(OpacityMode opacity_mode) : opacity_mode_(opacity_mode) { - layer_ = Platform::Current()->CompositorSupport()->CreateExternalTextureLayer( - this); - GraphicsLayer::RegisterContentsLayer(layer_->Layer()); + layer_ = cc::TextureLayer::CreateForMailbox(this); + layer_->SetIsDrawable(true); layer_->SetNearestNeighbor(filter_quality_ == kNone_SkFilterQuality); if (opacity_mode_ == kOpaque) { - layer_->SetOpaque(true); + layer_->SetContentsOpaque(true); layer_->SetBlendBackgroundColor(false); } + GraphicsLayer::RegisterContentsLayer(layer_.get()); } ImageLayerBridge::~ImageLayerBridge() { @@ -42,7 +47,7 @@ void ImageLayerBridge::SetImage(scoped_refptr<StaticBitmapImage> image) { image_ = std::move(image); if (image_) { if (opacity_mode_ == kNonOpaque) { - layer_->SetOpaque(image_->CurrentFrameKnownToBeOpaque()); + layer_->SetContentsOpaque(image_->CurrentFrameKnownToBeOpaque()); layer_->SetBlendBackgroundColor(!image_->CurrentFrameKnownToBeOpaque()); } } @@ -53,26 +58,25 @@ void ImageLayerBridge::SetImage(scoped_refptr<StaticBitmapImage> image) { // m_image->EnsureMailbox() call of // ImageLayerBridge::PrepareTransferableResource. To prevent a potential // memory leak we must flush the GrContext here. - image_->PaintImageForCurrentFrame().GetSkImage()->getTextureHandle( + image_->PaintImageForCurrentFrame().GetSkImage()->getBackendTexture( true); // GrContext flush. } has_presented_since_last_set_image_ = false; } -void ImageLayerBridge::SetUV(const FloatPoint left_top, - const FloatPoint right_bottom) { +void ImageLayerBridge::SetUV(const FloatPoint& left_top, + const FloatPoint& right_bottom) { if (disposed_) return; - layer_->SetUV(WebFloatPoint(left_top.X(), left_top.Y()), - WebFloatPoint(right_bottom.X(), right_bottom.Y())); + layer_->SetUV(left_top, right_bottom); } void ImageLayerBridge::Dispose() { if (layer_) { - GraphicsLayer::UnregisterContentsLayer(layer_->Layer()); + GraphicsLayer::UnregisterContentsLayer(layer_.get()); layer_->ClearTexture(); - layer_.reset(); + layer_ = nullptr; } image_ = nullptr; disposed_ = true; @@ -129,58 +133,76 @@ bool ImageLayerBridge::PrepareTransferableResource( WrapWeakPersistent(this), std::move(image_for_compositor)); *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); } else { - std::unique_ptr<viz::SharedBitmap> bitmap = - CreateOrRecycleBitmap(image_for_compositor->Size()); - if (!bitmap) - return false; - sk_sp<SkImage> sk_image = image_for_compositor->PaintImageForCurrentFrame().GetSkImage(); if (!sk_image) return false; + const gfx::Size size(image_for_compositor->width(), + image_for_compositor->height()); + viz::ResourceFormat resource_format = viz::RGBA_8888; + if (sk_image->colorType() == SkColorType::kRGBA_F16_SkColorType) + resource_format = viz::RGBA_F16; + RegisteredBitmap registered = + CreateOrRecycleBitmap(size, resource_format, bitmap_registrar); + SkImageInfo dst_info = - SkImageInfo::MakeN32Premul(image_for_compositor->width(), 1); - dst_info = dst_info.makeColorSpace(sk_image->refColorSpace()); - size_t row_bytes = image_for_compositor->width() * 4; - - // Copy from SkImage into |bitmap|, while flipping the Y axis. - for (int row = 0; row < image_for_compositor->height(); row++) { - if (!sk_image->readPixels(dst_info, bitmap->pixels(), row_bytes, 0, 0)) - return false; - } + SkImageInfo::Make(size.width(), size.height(), sk_image->colorType(), + kPremul_SkAlphaType, sk_image->refColorSpace()); + void* pixels = registered.bitmap->shared_memory()->memory(); + + // Copy from SkImage into SharedMemory owned by |registered|. + if (!sk_image->readPixels(dst_info, pixels, dst_info.minRowBytes(), 0, 0)) + return false; *out_resource = viz::TransferableResource::MakeSoftware( - bitmap->id(), bitmap->sequence_number(), - gfx::Size(image_for_compositor->width(), - image_for_compositor->height()), - viz::RGBA_8888); + registered.bitmap->id(), size, resource_format); + if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) { + out_resource->color_space = + SkColorSpaceToGfxColorSpace(sk_image->refColorSpace()); + } auto func = WTF::Bind(&ImageLayerBridge::ResourceReleasedSoftware, - WrapWeakPersistent(this), std::move(bitmap), - image_for_compositor->Size()); + WrapWeakPersistent(this), std::move(registered)); *out_release_callback = viz::SingleReleaseCallback::Create(std::move(func)); } - // TODO(junov): Figure out how to get the color space info. - // out_resource->color_space = ...; - return true; } -std::unique_ptr<viz::SharedBitmap> ImageLayerBridge::CreateOrRecycleBitmap( - const IntSize& size) { - auto it = std::remove_if( +ImageLayerBridge::RegisteredBitmap ImageLayerBridge::CreateOrRecycleBitmap( + const gfx::Size& size, + viz::ResourceFormat format, + cc::SharedBitmapIdRegistrar* bitmap_registrar) { + auto* it = std::remove_if( recycled_bitmaps_.begin(), recycled_bitmaps_.end(), - [&size](const RecycledBitmap& bitmap) { return bitmap.size != size; }); + [&size, &format](const RegisteredBitmap& registered) { + unsigned src_bytes_per_pixel = + (registered.bitmap->format() == viz::RGBA_8888) ? 4 : 8; + unsigned target_bytes_per_pixel = (format == viz::RGBA_8888) ? 4 : 8; + return (registered.bitmap->size().GetArea() * src_bytes_per_pixel != + size.GetArea() * target_bytes_per_pixel); + }); recycled_bitmaps_.Shrink(it - recycled_bitmaps_.begin()); if (!recycled_bitmaps_.IsEmpty()) { - RecycledBitmap recycled = std::move(recycled_bitmaps_.back()); + RegisteredBitmap registered = std::move(recycled_bitmaps_.back()); recycled_bitmaps_.pop_back(); - DCHECK(recycled.size == size); - return std::move(recycled.bitmap); + DCHECK(registered.bitmap->size() == size); + return registered; } - return Platform::Current()->AllocateSharedBitmap(size, viz::RGBA_8888); + + // There are no bitmaps to recycle so allocate a new one. + viz::SharedBitmapId id = viz::SharedBitmap::GenerateId(); + std::unique_ptr<base::SharedMemory> shm = + viz::bitmap_allocation::AllocateMappedBitmap(size, format); + + RegisteredBitmap registered; + registered.bitmap = base::MakeRefCounted<cc::CrossThreadSharedBitmap>( + id, std::move(shm), size, format); + registered.registration = + bitmap_registrar->RegisterSharedBitmapId(id, registered.bitmap); + + return registered; } void ImageLayerBridge::ResourceReleasedGpu( @@ -199,19 +221,22 @@ void ImageLayerBridge::ResourceReleasedGpu( } void ImageLayerBridge::ResourceReleasedSoftware( - std::unique_ptr<viz::SharedBitmap> bitmap, - const IntSize& size, + RegisteredBitmap registered, const gpu::SyncToken& sync_token, bool lost_resource) { DCHECK(!sync_token.HasData()); // No sync tokens for software resources. - if (!disposed_ && !lost_resource) { - RecycledBitmap recycled = {std::move(bitmap), size}; - recycled_bitmaps_.push_back(std::move(recycled)); - } + if (!disposed_ && !lost_resource) + recycled_bitmaps_.push_back(std::move(registered)); } -WebLayer* ImageLayerBridge::PlatformLayer() const { - return layer_->Layer(); +cc::Layer* ImageLayerBridge::CcLayer() const { + return layer_.get(); } +ImageLayerBridge::RegisteredBitmap::RegisteredBitmap() = default; +ImageLayerBridge::RegisteredBitmap::RegisteredBitmap(RegisteredBitmap&& other) = + default; +ImageLayerBridge::RegisteredBitmap& ImageLayerBridge::RegisteredBitmap:: +operator=(RegisteredBitmap&& other) = default; + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h index 9dfaae76c1c..2b274d4b5fa 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.h @@ -5,21 +5,28 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_IMAGE_LAYER_BRIDGE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_IMAGE_LAYER_BRIDGE_H_ +#include <memory> + #include "cc/layers/texture_layer_client.h" +#include "cc/resources/shared_bitmap_id_registrar.h" +#include "components/viz/common/resources/resource_format.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/platform_export.h" -namespace viz { -class SharedBitmap; +namespace cc { +class CrossThreadSharedBitmap; +class Layer; +class TextureLayer; } -namespace blink { +namespace gfx { +class Size; +} -class WebLayer; -class WebExternalTextureLayer; +namespace blink { class PLATFORM_EXPORT ImageLayerBridge : public GarbageCollectedFinalized<ImageLayerBridge>, @@ -28,7 +35,7 @@ class PLATFORM_EXPORT ImageLayerBridge public: ImageLayerBridge(OpacityMode); - ~ImageLayerBridge(); + ~ImageLayerBridge() override; void SetImage(scoped_refptr<StaticBitmapImage>); void Dispose(); @@ -40,42 +47,53 @@ class PLATFORM_EXPORT ImageLayerBridge std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback) override; - void ResourceReleasedGpu(scoped_refptr<StaticBitmapImage>, - const gpu::SyncToken&, - bool lost_resource); - - void ResourceReleasedSoftware(std::unique_ptr<viz::SharedBitmap>, - const IntSize&, - const gpu::SyncToken&, - bool lost_resource); - scoped_refptr<StaticBitmapImage> GetImage() { return image_; } - WebLayer* PlatformLayer() const; + cc::Layer* CcLayer() const; void SetFilterQuality(SkFilterQuality filter_quality) { filter_quality_ = filter_quality; } - void SetUV(const FloatPoint left_top, const FloatPoint right_bottom); + void SetUV(const FloatPoint& left_top, const FloatPoint& right_bottom); bool IsAccelerated() { return image_->IsTextureBacked(); } void Trace(blink::Visitor* visitor) {} private: - std::unique_ptr<viz::SharedBitmap> CreateOrRecycleBitmap(const IntSize& size); + // SharedMemory bitmap that was registered with SharedBitmapIdRegistrar. Used + // only with software compositing. + struct RegisteredBitmap { + RegisteredBitmap(); + RegisteredBitmap(RegisteredBitmap&& other); + RegisteredBitmap& operator=(RegisteredBitmap&& other); + + scoped_refptr<cc::CrossThreadSharedBitmap> bitmap; + cc::SharedBitmapIdRegistration registration; + }; + + // Returns a SharedMemory bitmap of |size|. Tries to recycle returned bitmaps + // first and allocates a new bitmap if necessary. Note this will delete + // recycled bitmaps that are the wrong size. + RegisteredBitmap CreateOrRecycleBitmap( + const gfx::Size& size, + viz::ResourceFormat format, + cc::SharedBitmapIdRegistrar* bitmap_registrar); + + void ResourceReleasedGpu(scoped_refptr<StaticBitmapImage>, + const gpu::SyncToken&, + bool lost_resource); + + void ResourceReleasedSoftware(RegisteredBitmap registered, + const gpu::SyncToken&, + bool lost_resource); scoped_refptr<StaticBitmapImage> image_; - std::unique_ptr<WebExternalTextureLayer> layer_; + scoped_refptr<cc::TextureLayer> layer_; SkFilterQuality filter_quality_ = kLow_SkFilterQuality; - // Shared memory bitmaps that were released by the compositor and can be used - // again by this ImageLayerBridge. - struct RecycledBitmap { - std::unique_ptr<viz::SharedBitmap> bitmap; - IntSize size; - }; - Vector<RecycledBitmap> recycled_bitmaps_; + // SharedMemory bitmaps that can be recycled. + Vector<RegisteredBitmap> recycled_bitmaps_; bool disposed_ = false; bool has_presented_since_last_set_image_ = false; @@ -84,4 +102,4 @@ class PLATFORM_EXPORT ImageLayerBridge } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_IMAGE_LAYER_BRIDGE_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 cfddf674cfc..fe1ff3529c5 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 @@ -67,7 +67,7 @@ static void CreateContextProviderOnMainThread( Platform::GraphicsInfo graphics_info; auto context_provider = Platform::Current()->CreateOffscreenGraphicsContext3DProvider( - context_attributes, WebURL(), nullptr, &graphics_info); + context_attributes, WebURL(), &graphics_info); if (context_provider) { *wrapper = std::make_unique<WebGraphicsContext3DProviderWrapper>( std::move(context_provider)); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc index 368d8cb03db..55858bbac7e 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc @@ -133,7 +133,6 @@ TEST_F(SharedGpuContextTest, Canvas2DLayerBridgeAutoRecovery) { color_params); EXPECT_TRUE(bridge->IsAccelerated()); EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring()); - bridge->BeginDestruction(); } TEST_F(SharedGpuContextTest, IsValidWithoutRestoring) { diff --git a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h index ad66c2f7ca1..10ee7d4d309 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h +++ b/chromium/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.h @@ -6,12 +6,12 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GPU_WEBGL_IMAGE_CONVERSION_H_ #include "base/memory/scoped_refptr.h" +#include "base/optional.h" #include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/skia/image_pixel_locker.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/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/khronos/GLES2/gl2ext.h" #include "third_party/khronos/GLES3/gl3.h" @@ -155,7 +155,7 @@ class PLATFORM_EXPORT WebGLImageConversion final { void ExtractImage(bool premultiply_alpha, bool ignore_color_space); Image* image_; - Optional<ImagePixelLocker> image_pixel_locker_; + base::Optional<ImagePixelLocker> image_pixel_locker_; ImageHtmlDomSource image_html_dom_source_; unsigned image_width_; unsigned image_height_; 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 8956cfa76cf..08c8e3376a5 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 @@ -118,7 +118,8 @@ void XRFrameTransport::FrameSubmit( if (!frame_copier_ || !last_transfer_succeeded_) { frame_copier_ = std::make_unique<GpuMemoryBufferImageCopy>(gl); } - auto gpu_memory_buffer = frame_copier_->CopyImage(image_ref.get()); + gfx::GpuMemoryBuffer* gpu_memory_buffer = + frame_copier_->CopyImage(image_ref.get()); drawing_buffer_client->DrawingBufferClientRestoreTexture2DBinding(); drawing_buffer_client->DrawingBufferClientRestoreFramebufferBinding(); drawing_buffer_client->DrawingBufferClientRestoreRenderbufferBinding(); @@ -134,7 +135,8 @@ void XRFrameTransport::FrameSubmit( gfx::GpuMemoryBufferHandle gpu_handle = CloneHandleForIPC(gpu_memory_buffer->GetHandle()); vr_presentation_provider->SubmitFrameWithTextureHandle( - vr_frame_id, mojo::WrapPlatformFile(gpu_handle.handle.GetHandle())); + vr_frame_id, + mojo::WrapPlatformFile(gpu_handle.dxgi_handle.GetHandle())); } #else NOTIMPLEMENTED(); 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 f416c8821d4..f2c88fafb57 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 @@ -33,7 +33,7 @@ class PLATFORM_EXPORT XRFrameTransport final public device::mojom::blink::VRSubmitFrameClient { public: explicit XRFrameTransport(); - ~XRFrameTransport(); + ~XRFrameTransport() override; device::mojom::blink::VRSubmitFrameClientPtr GetSubmitFrameClient(); 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 8eca5b8fa6e..73f10fcb8f4 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 @@ -8,6 +8,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/instrumentation/tracing/trace_event.h" #include "third_party/skia/include/core/SkSurface.h" namespace blink { @@ -204,6 +205,42 @@ IntSize XRWebGLDrawingBuffer::AdjustSize(const IntSize& new_size) { return IntSize(width, height); } +void XRWebGLDrawingBuffer::OverwriteColorBufferFromMailboxTexture( + const gpu::MailboxHolder& mailbox_holder, + const IntSize& size_in) { + TRACE_EVENT0("gpu", __FUNCTION__); + gpu::gles2::GLES2Interface* gl = drawing_buffer_->ContextGL(); + + gl->WaitSyncTokenCHROMIUM(mailbox_holder.sync_token.GetConstData()); + + GLuint source_texture = + gl->CreateAndConsumeTextureCHROMIUM(mailbox_holder.mailbox.name); + + GLuint dest_texture = back_color_buffer_->texture_id; + + // TODO(836496): clean this up and move some of the math to call site. + int dest_width = size_.Width(); + int dest_height = size_.Height(); + int source_width = size_in.Width(); + int source_height = size_in.Height(); + + int copy_width = std::min(source_width, dest_width); + int copy_height = std::min(source_height, dest_height); + + // If the source is too small, center the image. + int dest_x0 = source_width < dest_width ? (dest_width - source_width) / 2 : 0; + int dest_y0 = + source_height < dest_height ? (dest_height - source_height) / 2 : 0; + int src_x0 = source_width > dest_width ? (source_width - dest_width) / 2 : 0; + int src_y0 = + source_height > dest_height ? (source_height - dest_height) / 2 : 0; + + gl->CopySubTextureCHROMIUM( + source_texture, 0, GL_TEXTURE_2D, dest_texture, 0, dest_x0, dest_y0, + src_x0, src_y0, copy_width, copy_height, false /* flipY */, + false /* premultiplyAlpha */, false /* unmultiplyAlpha */); +} + void XRWebGLDrawingBuffer::UseSharedBuffer( const gpu::MailboxHolder& buffer_mailbox_holder) { DVLOG(3) << __FUNCTION__; @@ -250,6 +287,8 @@ void XRWebGLDrawingBuffer::UseSharedBuffer( } DrawingBuffer::Client* client = drawing_buffer_->client(); + if (!client) + return; client->DrawingBufferClientRestoreFramebufferBinding(); } @@ -284,6 +323,8 @@ void XRWebGLDrawingBuffer::DoneWithSharedBuffer() { shared_buffer_texture_id_ = 0; DrawingBuffer::Client* client = drawing_buffer_->client(); + if (!client) + return; client->DrawingBufferClientRestoreFramebufferBinding(); } 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 99514de6d6d..8a14d3426ab 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 @@ -45,6 +45,9 @@ class PLATFORM_EXPORT XRWebGLDrawingBuffer void Resize(const IntSize&); + void OverwriteColorBufferFromMailboxTexture(const gpu::MailboxHolder&, + const IntSize& size); + scoped_refptr<StaticBitmapImage> TransferToStaticBitmapImage( std::unique_ptr<viz::SingleReleaseCallback>* out_release_callback); diff --git a/chromium/third_party/blink/renderer/platform/graphics/gradient.cc b/chromium/third_party/blink/renderer/platform/graphics/gradient.cc index d46687d087f..a30acd776cd 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/gradient.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/gradient.cc @@ -199,7 +199,7 @@ class LinearGradient final : public Gradient { uint32_t flags, const SkMatrix& local_matrix, SkColor fallback_color) const override { - SkPoint pts[2] = {p0_.Data(), p1_.Data()}; + SkPoint pts[2] = {FloatPointToSkPoint(p0_), FloatPointToSkPoint(p1_)}; return PaintShader::MakeLinearGradient( pts, colors.data(), pos.data(), static_cast<int>(colors.size()), tile_mode, flags, &local_matrix, fallback_color); @@ -247,9 +247,9 @@ class RadialGradient final : public Gradient { const SkScalar radius0 = std::max(WebCoreFloatToSkScalar(r0_), 0.0f); const SkScalar radius1 = std::max(WebCoreFloatToSkScalar(r1_), 0.0f); return PaintShader::MakeTwoPointConicalGradient( - p0_.Data(), radius0, p1_.Data(), radius1, colors.data(), pos.data(), - static_cast<int>(colors.size()), tile_mode, flags, - adjusted_local_matrix, fallback_color); + FloatPointToSkPoint(p0_), radius0, FloatPointToSkPoint(p1_), radius1, + colors.data(), pos.data(), static_cast<int>(colors.size()), tile_mode, + flags, adjusted_local_matrix, fallback_color); } private: 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 e4d10c228b3..9aea136fcc4 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.cc @@ -30,6 +30,7 @@ #include "build/build_config.h" #include "skia/ext/platform_canvas.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" 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 5a7394e9e39..961d4a9961d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_context.h @@ -59,6 +59,7 @@ class FloatRoundedRect; class KURL; class PaintController; class Path; +struct TextRunPaintInfo; class PLATFORM_EXPORT GraphicsContext { WTF_MAKE_NONCOPYABLE(GraphicsContext); 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 09694f3d582..b42248de806 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.cc @@ -29,16 +29,16 @@ #include <cmath> #include <memory> #include <utility> -#include "SkMatrix44.h" + #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event_argument.h" #include "cc/layers/layer.h" +#include "cc/layers/picture_image_layer.h" +#include "cc/layers/picture_layer.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_display_item_list.h" #include "third_party/blink/public/platform/web_float_point.h" #include "third_party/blink/public/platform/web_float_rect.h" -#include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/public/platform/web_point.h" #include "third_party/blink/public/platform/web_size.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" @@ -52,7 +52,6 @@ #include "third_party/blink/renderer/platform/graphics/compositing/composited_layer_raster_invalidator.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h" #include "third_party/blink/renderer/platform/graphics/compositor_filter_operations.h" -#include "third_party/blink/renderer/platform/graphics/first_paint_invalidation_tracking.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/link_highlight.h" @@ -61,17 +60,19 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.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/skia/skia_utils.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/scroll/scroll_snap_data.h" #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" -#include "third_party/blink/renderer/platform/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/time.h" +#include "third_party/skia/include/core/SkMatrix44.h" namespace blink { @@ -84,9 +85,10 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client) : client_(client), background_color_(Color::kTransparent), opacity_(1), - blend_mode_(WebBlendMode::kNormal), + blend_mode_(BlendMode::kNormal), has_transform_origin_(false), contents_opaque_(false), + prevent_contents_opaque_changes_(false), should_flatten_transform_(true), backface_visibility_(true), draws_content_(false), @@ -110,15 +112,15 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient& client) #if DCHECK_IS_ON() client.VerifyNotPainting(); #endif - layer_ = Platform::Current()->CompositorSupport()->CreateContentLayer(this); - layer_->Layer()->SetDrawsContent(draws_content_ && contents_visible_); - layer_->Layer()->SetLayerClient(weak_ptr_factory_.GetWeakPtr()); + layer_ = cc::PictureLayer::Create(this); + layer_->SetIsDrawable(draws_content_ && contents_visible_); + layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr()); UpdateTrackingRasterInvalidations(); } GraphicsLayer::~GraphicsLayer() { - layer_->Layer()->SetLayerClient(nullptr); + layer_->SetLayerClient(nullptr); SetContentsLayer(nullptr); for (size_t i = 0; i < link_highlights_.size(); ++i) link_highlights_[i]->ClearCurrentGraphicsLayer(); @@ -146,26 +148,26 @@ LayoutRect GraphicsLayer::VisualRect() const { void GraphicsLayer::SetHasWillChangeTransformHint( bool has_will_change_transform) { - layer_->Layer()->SetHasWillChangeTransformHint(has_will_change_transform); + layer_->SetHasWillChangeTransformHint(has_will_change_transform); } void GraphicsLayer::SetOverscrollBehavior( - const WebOverscrollBehavior& behavior) { - layer_->Layer()->SetOverscrollBehavior(behavior); + const cc::OverscrollBehavior& behavior) { + layer_->SetOverscrollBehavior(behavior); } -void GraphicsLayer::SetSnapContainerData(Optional<SnapContainerData> data) { - layer_->Layer()->SetSnapContainerData(std::move(data)); +void GraphicsLayer::SetSnapContainerData( + base::Optional<SnapContainerData> data) { + layer_->SetSnapContainerData(std::move(data)); } void GraphicsLayer::SetIsResizedByBrowserControls( bool is_resized_by_browser_controls) { - PlatformLayer()->SetIsResizedByBrowserControls( - is_resized_by_browser_controls); + CcLayer()->SetIsResizedByBrowserControls(is_resized_by_browser_controls); } void GraphicsLayer::SetIsContainerForFixedPositionLayers(bool is_container) { - PlatformLayer()->SetIsContainerForFixedPositionLayers(is_container); + CcLayer()->SetIsContainerForFixedPositionLayers(is_container); } void GraphicsLayer::SetParent(GraphicsLayer* layer) { @@ -259,7 +261,7 @@ void GraphicsLayer::RemoveFromParent() { SetParent(nullptr); } - PlatformLayer()->RemoveFromParent(); + CcLayer()->RemoveFromParent(); } void GraphicsLayer::SetOffsetFromLayoutObject( @@ -275,7 +277,7 @@ void GraphicsLayer::SetOffsetDoubleFromLayoutObject( return; offset_from_layout_object_ = offset; - PlatformLayer()->SetFiltersOrigin(FloatPoint() - ToFloatSize(offset)); + CcLayer()->SetFiltersOrigin(FloatPoint() - ToFloatSize(offset)); // If the compositing layer offset changes, we need to repaint. if (should_set_needs_display == kSetNeedsDisplay) @@ -296,12 +298,10 @@ void GraphicsLayer::PaintRecursively() { PaintRecursivelyInternal(repainted_layers); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - // Clear paint property change flags that are for this paint only. - for (auto* layer : repainted_layers) { - for (const auto& chunk : - layer->GetPaintController().GetPaintArtifact().PaintChunks()) - chunk.properties.property_tree_state.ClearChangedToRoot(); - } + // Notify the controllers that the artifact has been pushed and some + // lifecycle state can be freed (such as raster invalidations). + for (auto* layer : repainted_layers) + layer->GetPaintController().FinishCycle(); } #if DCHECK_IS_ON() @@ -337,6 +337,13 @@ void GraphicsLayer::PaintRecursivelyInternal( bool GraphicsLayer::Paint(const IntRect* interest_rect, GraphicsContext::DisabledMode disabled_mode) { +#if !DCHECK_IS_ON() + // TODO(crbug.com/853096): Investigate why we can ever reach here without + // a valid layer state. Seems to only happen on Android builds. + if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled() && !layer_state_) + return false; +#endif + if (PaintWithoutCommit(interest_rect, disabled_mode)) GetPaintController().CommitNewDisplayItems(); else if (!needs_check_raster_invalidation_) @@ -353,9 +360,9 @@ bool GraphicsLayer::Paint(const IntRect* interest_rect, DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName(); // Generate raster invalidations for SPv175 (but not SPv2). IntRect layer_bounds(layer_state_->offset, ExpandedIntSize(Size())); - EnsureRasterInvalidator().Generate( - layer_bounds, GetPaintController().GetPaintArtifact().PaintChunks(), - layer_state_->state, VisualRectSubpixelOffset()); + EnsureRasterInvalidator().Generate(GetPaintController().GetPaintArtifact(), + layer_bounds, layer_state_->state, + VisualRectSubpixelOffset()); } if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() && @@ -369,7 +376,7 @@ bool GraphicsLayer::Paint(const IntRect* interest_rect, *this, std::move(record), layer_state_ ? &layer_state_->state : nullptr); // Ensure the compositor will raster the under-invalidation overlay. - layer_->Layer()->Invalidate(); + layer_->SetNeedsDisplay(); } } @@ -385,8 +392,6 @@ bool GraphicsLayer::PaintWithoutCommit( if (client_.ShouldThrottleRendering()) return false; - if (FirstPaintInvalidationTracking::IsEnabled()) - debug_info_.ClearAnnotatedInvalidateRects(); IncrementPaintCount(); IntRect new_interest_rect; @@ -406,8 +411,8 @@ bool GraphicsLayer::PaintWithoutCommit( GraphicsContext context(GetPaintController(), disabled_mode, nullptr); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName(); - GetPaintController().UpdateCurrentPaintChunkProperties( - WTF::nullopt, PaintChunkProperties(layer_state_->state)); + GetPaintController().UpdateCurrentPaintChunkProperties(base::nullopt, + layer_state_->state); } previous_interest_rect_ = *interest_rect; @@ -416,7 +421,7 @@ bool GraphicsLayer::PaintWithoutCommit( } void GraphicsLayer::UpdateChildList() { - WebLayer* child_host = layer_->Layer(); + cc::Layer* child_host = layer_.get(); child_host->RemoveAllChildren(); ClearContentsLayerIfUnregistered(); @@ -430,7 +435,7 @@ void GraphicsLayer::UpdateChildList() { } for (size_t i = 0; i < children_.size(); ++i) - child_host->AddChild(children_[i]->PlatformLayer()); + child_host->AddChild(children_[i]->CcLayer()); for (size_t i = 0; i < link_highlights_.size(); ++i) child_host->AddChild(link_highlights_[i]->Layer()); @@ -443,30 +448,50 @@ void GraphicsLayer::UpdateLayerIsDrawable() { // shouldn't receive the drawsContent flag, so it is only given // contentsVisible. - layer_->Layer()->SetDrawsContent(draws_content_ && contents_visible_); - if (WebLayer* contents_layer = ContentsLayerIfRegistered()) - contents_layer->SetDrawsContent(contents_visible_); + layer_->SetIsDrawable(draws_content_ && contents_visible_); + if (cc::Layer* contents_layer = ContentsLayerIfRegistered()) + contents_layer->SetIsDrawable(contents_visible_); if (draws_content_) { - layer_->Layer()->Invalidate(); + layer_->SetNeedsDisplay(); for (size_t i = 0; i < link_highlights_.size(); ++i) link_highlights_[i]->Invalidate(); } } void GraphicsLayer::UpdateContentsRect() { - WebLayer* contents_layer = ContentsLayerIfRegistered(); + cc::Layer* contents_layer = ContentsLayerIfRegistered(); if (!contents_layer) return; contents_layer->SetPosition( FloatPoint(contents_rect_.X(), contents_rect_.Y())); - contents_layer->SetBounds( - IntSize(contents_rect_.Width(), contents_rect_.Height())); + if (!image_layer_) { + contents_layer->SetBounds(static_cast<gfx::Size>(contents_rect_.Size())); + } else { + DCHECK_EQ(image_layer_.get(), contents_layer_); + // The image_layer_ has fixed bounds, and we apply bounds changes via the + // transform instead. Since we never change the transform on the + // |image_layer_| otherwise, we can assume it is identity and just apply + // the bounds to it directly. Same thing for transform origin. + DCHECK(image_layer_->transform_origin() == gfx::Point3F()); + + if (contents_rect_.Size().IsEmpty() || image_size_.IsEmpty()) { + image_layer_->SetTransform(gfx::Transform()); + contents_layer->SetBounds(static_cast<gfx::Size>(contents_rect_.Size())); + } else { + gfx::Transform image_transform; + image_transform.Scale( + static_cast<float>(contents_rect_.Width()) / image_size_.Width(), + static_cast<float>(contents_rect_.Height()) / image_size_.Height()); + image_layer_->SetTransform(image_transform); + image_layer_->SetBounds(static_cast<gfx::Size>(image_size_)); + } + } if (contents_clipping_mask_layer_) { if (contents_clipping_mask_layer_->Size() != contents_rect_.Size()) { - contents_clipping_mask_layer_->SetSize(FloatSize(contents_rect_.Size())); + contents_clipping_mask_layer_->SetSize(contents_rect_.Size()); contents_clipping_mask_layer_->SetNeedsDisplay(); } contents_clipping_mask_layer_->SetPosition(FloatPoint()); @@ -478,30 +503,32 @@ void GraphicsLayer::UpdateContentsRect() { static HashSet<int>* g_registered_layer_set; -void GraphicsLayer::RegisterContentsLayer(WebLayer* layer) { +void GraphicsLayer::RegisterContentsLayer(cc::Layer* layer) { if (!g_registered_layer_set) g_registered_layer_set = new HashSet<int>; - CHECK(!g_registered_layer_set->Contains(layer->Id())); - g_registered_layer_set->insert(layer->Id()); + CHECK(!g_registered_layer_set->Contains(layer->id())); + g_registered_layer_set->insert(layer->id()); } -void GraphicsLayer::UnregisterContentsLayer(WebLayer* layer) { +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()); + CHECK(g_registered_layer_set->Contains(layer->id())); + g_registered_layer_set->erase(layer->id()); layer->SetLayerClient(nullptr); } -void GraphicsLayer::SetContentsTo(WebLayer* layer) { +void GraphicsLayer::SetContentsTo(cc::Layer* layer, + bool prevent_contents_opaque_changes) { bool children_changed = false; if (layer) { DCHECK(g_registered_layer_set); - CHECK(g_registered_layer_set->Contains(layer->Id())); - if (contents_layer_id_ != layer->Id()) { + CHECK(g_registered_layer_set->Contains(layer->id())); + if (contents_layer_id_ != layer->id()) { SetupContentsLayer(layer); children_changed = true; } UpdateContentsRect(); + prevent_contents_opaque_changes_ = prevent_contents_opaque_changes; } else { if (contents_layer_) { children_changed = true; @@ -515,28 +542,27 @@ void GraphicsLayer::SetContentsTo(WebLayer* layer) { UpdateChildList(); } -void GraphicsLayer::SetupContentsLayer(WebLayer* contents_layer) { +void GraphicsLayer::SetupContentsLayer(cc::Layer* contents_layer) { DCHECK(contents_layer); SetContentsLayer(contents_layer); contents_layer_->SetTransformOrigin(FloatPoint3D()); contents_layer_->SetUseParentBackfaceVisibility(true); - // It is necessary to call setDrawsContent as soon as we receive the new - // contentsLayer, for the correctness of early exit conditions in - // setDrawsContent() and setContentsVisible(). - contents_layer_->SetDrawsContent(contents_visible_); + // It is necessary to call SetDrawsContent() as soon as we receive the new + // contents_layer, for the correctness of early exit conditions in + // SetDrawsContent() and SetContentsVisible(). + contents_layer_->SetIsDrawable(contents_visible_); // Insert the content layer first. Video elements require this, because they // have shadow content that must display in front of the video. - layer_->Layer()->InsertChild(contents_layer_, 0); - WebLayer* border_web_layer = - contents_clipping_mask_layer_ - ? contents_clipping_mask_layer_->PlatformLayer() - : nullptr; - contents_layer_->SetMaskLayer(border_web_layer); + layer_->InsertChild(contents_layer_, 0); + cc::Layer* border_cc_layer = contents_clipping_mask_layer_ + ? contents_clipping_mask_layer_->CcLayer() + : nullptr; + contents_layer_->SetMaskLayer(border_cc_layer); - contents_layer_->SetRenderingContext(rendering_context3d_); + contents_layer_->Set3dSortingContextId(rendering_context3d_); } void GraphicsLayer::ClearContentsLayerIfUnregistered() { @@ -547,7 +573,7 @@ void GraphicsLayer::ClearContentsLayerIfUnregistered() { SetContentsLayer(nullptr); } -void GraphicsLayer::SetContentsLayer(WebLayer* contents_layer) { +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. @@ -559,14 +585,10 @@ void GraphicsLayer::SetContentsLayer(WebLayer* contents_layer) { return; } contents_layer_->SetLayerClient(weak_ptr_factory_.GetWeakPtr()); - contents_layer_id_ = contents_layer_->Id(); + contents_layer_id_ = contents_layer_->id(); } -GraphicsLayerDebugInfo& GraphicsLayer::DebugInfo() { - return debug_info_; -} - -WebLayer* GraphicsLayer::ContentsLayerIfRegistered() { +cc::Layer* GraphicsLayer::ContentsLayerIfRegistered() { ClearContentsLayerIfUnregistered(); return contents_layer_; } @@ -611,20 +633,17 @@ RasterInvalidationTracking* GraphicsLayer::GetRasterInvalidationTracking() void GraphicsLayer::TrackRasterInvalidation(const DisplayItemClient& client, const IntRect& rect, PaintInvalidationReason reason) { - if (FirstPaintInvalidationTracking::IsEnabled()) - debug_info_.AppendAnnotatedInvalidateRect(rect, reason); - - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) + if (RasterInvalidationTracking::ShouldAlwaysTrack()) EnsureRasterInvalidator().EnsureTracking(); - // For SPv175, this only tracks invalidations that the WebLayer is fully + // For SPv175, this only tracks invalidations that the cc::Layer is fully // invalidated directly, e.g. from SetContentsNeedsDisplay(), etc. if (auto* tracking = GetRasterInvalidationTracking()) tracking->AddInvalidation(&client, client.DebugName(), rect, reason); } static String PointerAsString(const void* ptr) { - TextStream ts; + WTF::TextStream ts; ts << ptr; return ts.Release(); } @@ -661,16 +680,9 @@ class GraphicsLayer::LayersAsJSONArray { } static FloatPoint ScrollPosition(const GraphicsLayer& layer) { - const auto* scrollable_area = layer.GetScrollableArea(); - if (!RuntimeEnabledFeatures::RootLayerScrollingEnabled()) { - // The LayoutView layer's scrollable area is on the "Frame Scrolling - // Layer" ancestor. - if (layer.DebugName() == "LayoutView #document") - scrollable_area = layer.Parent()->Parent()->GetScrollableArea(); - else if (layer.DebugName() == "Frame Scrolling Layer") - scrollable_area = nullptr; - } - return scrollable_area ? scrollable_area->ScrollPosition() : FloatPoint(); + if (const auto* scrollable_area = layer.GetScrollableArea()) + return scrollable_area->ScrollPosition(); + return FloatPoint(); } void AddLayer(const GraphicsLayer& layer, @@ -722,7 +734,7 @@ class GraphicsLayer::LayersAsJSONArray { FloatPoint position = parent_position + layer.position_; int transform_id = parent_transform_id; AddLayer(layer, transform_id, position); - for (auto& child : layer.children_) + for (auto* const child : layer.children_) Walk(*child, transform_id, position); } @@ -771,7 +783,7 @@ std::unique_ptr<JSONObject> GraphicsLayer::LayerAsJSONInternal( if (opacity_ != 1) json->SetDouble("opacity", opacity_); - if (blend_mode_ != WebBlendMode::kNormal) { + if (blend_mode_ != BlendMode::kNormal) { json->SetString("blendMode", CompositeOperatorName(kCompositeSourceOver, blend_mode_)); } @@ -849,9 +861,8 @@ std::unique_ptr<JSONObject> GraphicsLayer::LayerAsJSONInternal( bool debug = flags & kLayerTreeIncludesDebugInfo; { std::unique_ptr<JSONArray> compositing_reasons_json = JSONArray::Create(); - auto reasons = debug_info_.GetCompositingReasons(); - auto names = debug ? CompositingReason::Descriptions(reasons) - : CompositingReason::ShortNames(reasons); + auto names = debug ? CompositingReason::Descriptions(compositing_reasons_) + : CompositingReason::ShortNames(compositing_reasons_); for (const char* name : names) compositing_reasons_json->PushString(name); json->SetArray("compositingReasons", std::move(compositing_reasons_json)); @@ -859,9 +870,10 @@ std::unique_ptr<JSONObject> GraphicsLayer::LayerAsJSONInternal( { std::unique_ptr<JSONArray> squashing_disallowed_reasons_json = JSONArray::Create(); - auto reasons = debug_info_.GetSquashingDisallowedReasons(); - auto names = debug ? SquashingDisallowedReason::Descriptions(reasons) - : SquashingDisallowedReason::ShortNames(reasons); + 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", @@ -951,54 +963,36 @@ String GraphicsLayer::GetLayerTreeAsTextForTesting(LayerTreeFlags flags) const { return LayerTreeAsJSON(flags)->ToPrettyJSONString(); } -static const cc::Layer* CcLayerForWebLayer(const WebLayer* web_layer) { - return web_layer ? web_layer->CcLayer() : nullptr; -} - String GraphicsLayer::DebugName(cc::Layer* layer) const { if (layer->id() == contents_layer_id_) return "ContentsLayer for " + client_.DebugName(this); for (size_t i = 0; i < link_highlights_.size(); ++i) { - if (layer == CcLayerForWebLayer(link_highlights_[i]->Layer())) { + if (layer == link_highlights_[i]->Layer()) { return "LinkHighlight[" + String::Number(i) + "] for " + client_.DebugName(this); } } - if (layer == CcLayerForWebLayer(layer_->Layer())) + if (layer == layer_.get()) return client_.DebugName(this); NOTREACHED(); return ""; } -void GraphicsLayer::SetCompositingReasons(CompositingReasons reasons) { - debug_info_.SetCompositingReasons(reasons); -} - -void GraphicsLayer::SetSquashingDisallowedReasons( - SquashingDisallowedReasons reasons) { - debug_info_.SetSquashingDisallowedReasons(reasons); -} - -void GraphicsLayer::SetOwnerNodeId(int node_id) { - debug_info_.SetOwnerNodeId(node_id); -} - void GraphicsLayer::SetPosition(const FloatPoint& point) { position_ = point; - PlatformLayer()->SetPosition(position_); + CcLayer()->SetPosition(position_); } -void GraphicsLayer::SetSize(const FloatSize& size) { +void GraphicsLayer::SetSize(const IntSize& size) { // We are receiving negative sizes here that cause assertions to fail in the // compositor. Clamp them to 0 to avoid those assertions. // FIXME: This should be an DCHECK instead, as negative sizes should not exist // in WebCore. - FloatSize clamped_size = size; - if (clamped_size.Width() < 0 || clamped_size.Height() < 0) - clamped_size = FloatSize(); + auto clamped_size = size; + clamped_size.ClampNegativeToZero(); if (clamped_size == size_) return; @@ -1008,19 +1002,19 @@ void GraphicsLayer::SetSize(const FloatSize& size) { // Invalidate the layer as a DisplayItemClient. SetDisplayItemsUncached(); - layer_->Layer()->SetBounds(FlooredIntSize(size_)); + layer_->SetBounds(static_cast<gfx::Size>(size_)); // Note that we don't resize m_contentsLayer. It's up the caller to do that. } void GraphicsLayer::SetTransform(const TransformationMatrix& transform) { transform_ = transform; - PlatformLayer()->SetTransform(TransformationMatrix::ToSkMatrix44(transform_)); + CcLayer()->SetTransform(TransformationMatrix::ToTransform(transform)); } void GraphicsLayer::SetTransformOrigin(const FloatPoint3D& transform_origin) { has_transform_origin_ = true; transform_origin_ = transform_origin; - PlatformLayer()->SetTransformOrigin(transform_origin); + CcLayer()->SetTransformOrigin(transform_origin); } void GraphicsLayer::SetShouldFlattenTransform(bool should_flatten) { @@ -1029,7 +1023,7 @@ void GraphicsLayer::SetShouldFlattenTransform(bool should_flatten) { should_flatten_transform_ = should_flatten; - layer_->Layer()->SetShouldFlattenTransform(should_flatten); + layer_->SetShouldFlattenTransform(should_flatten); } void GraphicsLayer::SetRenderingContext(int context) { @@ -1037,24 +1031,24 @@ void GraphicsLayer::SetRenderingContext(int context) { return; rendering_context3d_ = context; - layer_->Layer()->SetRenderingContext(context); + layer_->Set3dSortingContextId(context); if (contents_layer_) - contents_layer_->SetRenderingContext(rendering_context3d_); + contents_layer_->Set3dSortingContextId(rendering_context3d_); } bool GraphicsLayer::MasksToBounds() const { - return layer_->Layer()->MasksToBounds(); + return layer_->masks_to_bounds(); } void GraphicsLayer::SetMasksToBounds(bool masks_to_bounds) { - layer_->Layer()->SetMasksToBounds(masks_to_bounds); + layer_->SetMasksToBounds(masks_to_bounds); } void GraphicsLayer::SetDrawsContent(bool draws_content) { // NOTE: This early-exit is only correct because we also properly call - // WebLayer::setDrawsContent() whenever |m_contentsLayer| is set to a new - // layer in setupContentsLayer(). + // cc::Layer::SetIsDrawable() whenever |contents_layer_| is set to a new + // layer in SetupContentsLayer(). if (draws_content == draws_content_) return; @@ -1069,8 +1063,8 @@ void GraphicsLayer::SetDrawsContent(bool draws_content) { void GraphicsLayer::SetContentsVisible(bool contents_visible) { // NOTE: This early-exit is only correct because we also properly call - // WebLayer::setDrawsContent() whenever |m_contentsLayer| is set to a new - // layer in setupContentsLayer(). + // cc::Layer::SetIsDrawable() whenever |contents_layer_| is set to a new + // layer in SetupContentsLayer(). if (contents_visible == contents_visible_) return; @@ -1078,14 +1072,14 @@ void GraphicsLayer::SetContentsVisible(bool contents_visible) { UpdateLayerIsDrawable(); } -void GraphicsLayer::SetClipParent(WebLayer* parent) { +void GraphicsLayer::SetClipParent(cc::Layer* parent) { has_clip_parent_ = !!parent; - layer_->Layer()->SetClipParent(parent); + layer_->SetClipParent(parent); } -void GraphicsLayer::SetScrollParent(WebLayer* parent) { +void GraphicsLayer::SetScrollParent(cc::Layer* parent) { has_scroll_parent_ = !!parent; - layer_->Layer()->SetScrollParent(parent); + layer_->SetScrollParent(parent); } void GraphicsLayer::SetBackgroundColor(const Color& color) { @@ -1093,15 +1087,15 @@ void GraphicsLayer::SetBackgroundColor(const Color& color) { return; background_color_ = color; - layer_->Layer()->SetBackgroundColor(background_color_.Rgb()); + layer_->SetBackgroundColor(background_color_.Rgb()); } void GraphicsLayer::SetContentsOpaque(bool opaque) { contents_opaque_ = opaque; - layer_->Layer()->SetOpaque(contents_opaque_); + layer_->SetContentsOpaque(contents_opaque_); ClearContentsLayerIfUnregistered(); - if (contents_layer_) - contents_layer_->SetOpaque(opaque); + if (contents_layer_ && !prevent_contents_opaque_changes_) + contents_layer_->SetContentsOpaque(opaque); } void GraphicsLayer::SetMaskLayer(GraphicsLayer* mask_layer) { @@ -1109,9 +1103,7 @@ void GraphicsLayer::SetMaskLayer(GraphicsLayer* mask_layer) { return; mask_layer_ = mask_layer; - WebLayer* mask_web_layer = - mask_layer_ ? mask_layer_->PlatformLayer() : nullptr; - layer_->Layer()->SetMaskLayer(mask_web_layer); + layer_->SetMaskLayer(mask_layer_ ? mask_layer_->CcLayer() : nullptr); } void GraphicsLayer::SetContentsClippingMaskLayer( @@ -1120,52 +1112,51 @@ void GraphicsLayer::SetContentsClippingMaskLayer( return; contents_clipping_mask_layer_ = contents_clipping_mask_layer; - WebLayer* contents_layer = ContentsLayerIfRegistered(); + cc::Layer* contents_layer = ContentsLayerIfRegistered(); if (!contents_layer) return; - WebLayer* contents_clipping_mask_web_layer = - contents_clipping_mask_layer_ - ? contents_clipping_mask_layer_->PlatformLayer() - : nullptr; - contents_layer->SetMaskLayer(contents_clipping_mask_web_layer); + cc::Layer* contents_clipping_mask_cc_layer = + contents_clipping_mask_layer_ ? contents_clipping_mask_layer_->CcLayer() + : nullptr; + contents_layer->SetMaskLayer(contents_clipping_mask_cc_layer); UpdateContentsRect(); } void GraphicsLayer::SetBackfaceVisibility(bool visible) { backface_visibility_ = visible; - PlatformLayer()->SetDoubleSided(backface_visibility_); + CcLayer()->SetDoubleSided(backface_visibility_); } void GraphicsLayer::SetOpacity(float opacity) { float clamped_opacity = clampTo(opacity, 0.0f, 1.0f); opacity_ = clamped_opacity; - PlatformLayer()->SetOpacity(opacity); + CcLayer()->SetOpacity(opacity); } -void GraphicsLayer::SetBlendMode(WebBlendMode blend_mode) { +void GraphicsLayer::SetBlendMode(BlendMode blend_mode) { if (blend_mode_ == blend_mode) return; blend_mode_ = blend_mode; - PlatformLayer()->SetBlendMode(blend_mode); + CcLayer()->SetBlendMode(WebCoreBlendModeToSkBlendMode(blend_mode)); } void GraphicsLayer::SetIsRootForIsolatedGroup(bool isolated) { if (is_root_for_isolated_group_ == isolated) return; is_root_for_isolated_group_ = isolated; - PlatformLayer()->SetIsRootForIsolatedGroup(isolated); + CcLayer()->SetIsRootForIsolatedGroup(isolated); } void GraphicsLayer::SetHitTestableWithoutDrawsContent(bool should_hit_test) { if (hit_testable_without_draws_content_ == should_hit_test) return; hit_testable_without_draws_content_ = should_hit_test; - PlatformLayer()->SetHitTestableWithoutDrawsContent(should_hit_test); + CcLayer()->SetHitTestableWithoutDrawsContent(should_hit_test); } void GraphicsLayer::SetContentsNeedsDisplay() { - if (WebLayer* contents_layer = ContentsLayerIfRegistered()) { - contents_layer->Invalidate(); + if (cc::Layer* contents_layer = ContentsLayerIfRegistered()) { + contents_layer->SetNeedsDisplay(); TrackRasterInvalidation(*this, contents_rect_, PaintInvalidationReason::kFull); } @@ -1177,12 +1168,12 @@ void GraphicsLayer::SetNeedsDisplay() { // TODO(chrishtr): Stop invalidating the rects once // FrameView::paintRecursively() does so. - layer_->Layer()->Invalidate(); + layer_->SetNeedsDisplay(); for (size_t i = 0; i < link_highlights_.size(); ++i) link_highlights_[i]->Invalidate(); GetPaintController().InvalidateAll(); - TrackRasterInvalidation(*this, IntRect(IntPoint(), ExpandedIntSize(size_)), + TrackRasterInvalidation(*this, IntRect(IntPoint(), size_), PaintInvalidationReason::kFull); } @@ -1204,7 +1195,7 @@ void GraphicsLayer::SetNeedsDisplayInRect( void GraphicsLayer::SetNeedsDisplayInRectInternal(const IntRect& rect) { DCHECK(DrawsContent()); - layer_->Layer()->InvalidateRect(rect); + layer_->SetNeedsDisplayRect(rect); for (auto* link_highlight : link_highlights_) link_highlight->Invalidate(); } @@ -1230,14 +1221,19 @@ void GraphicsLayer::SetContentsToImage( if (paint_image && image->IsBitmapImage() && respect_image_orientation == kRespectImageOrientation) { image_orientation = ToBitmapImage(image)->CurrentFrameOrientation(); - FloatSize size(paint_image.width(), paint_image.height()); + image_size_ = IntSize(paint_image.width(), paint_image.height()); if (image_orientation.UsesWidthAsHeight()) - size = size.TransposedSize(); - auto affine = image_orientation.TransformFromDefault(size); + image_size_ = image_size_.TransposedSize(); + auto affine = + image_orientation.TransformFromDefault(FloatSize(image_size_)); auto transform = affine.ToTransformationMatrix(); matrix = TransformationMatrix::ToSkMatrix44(transform); + } else if (paint_image) { + matrix = SkMatrix::I(); + image_size_ = IntSize(paint_image.width(), paint_image.height()); } else { matrix = SkMatrix::I(); + image_size_ = IntSize(); } if (paint_image) { @@ -1246,37 +1242,37 @@ void GraphicsLayer::SetContentsToImage( .set_decoding_mode(Image::ToPaintImageDecodingMode(decode_mode)) .TakePaintImage(); if (!image_layer_) { - image_layer_ = - Platform::Current()->CompositorSupport()->CreateImageLayer(); - RegisterContentsLayer(image_layer_->Layer()); + image_layer_ = cc::PictureImageLayer::Create(); + RegisterContentsLayer(image_layer_.get()); } image_layer_->SetImage(std::move(paint_image), matrix, image_orientation.UsesWidthAsHeight()); - image_layer_->Layer()->SetOpaque(image->CurrentFrameKnownToBeOpaque()); + image_layer_->SetContentsOpaque(image->CurrentFrameKnownToBeOpaque()); UpdateContentsRect(); } else if (image_layer_) { - UnregisterContentsLayer(image_layer_->Layer()); - image_layer_.reset(); + UnregisterContentsLayer(image_layer_.get()); + image_layer_ = nullptr; } - SetContentsTo(image_layer_ ? image_layer_->Layer() : nullptr); + SetContentsTo(image_layer_.get(), + /*prevent_contents_opaque_changes=*/true); } -WebLayer* GraphicsLayer::PlatformLayer() const { - return layer_->Layer(); +cc::Layer* GraphicsLayer::CcLayer() const { + return layer_.get(); } void GraphicsLayer::SetFilters(CompositorFilterOperations filters) { - PlatformLayer()->SetFilters(filters.ReleaseCcFilterOperations()); + CcLayer()->SetFilters(filters.ReleaseCcFilterOperations()); } void GraphicsLayer::SetBackdropFilters(CompositorFilterOperations filters) { - PlatformLayer()->SetBackgroundFilters(filters.ReleaseCcFilterOperations()); + CcLayer()->SetBackgroundFilters(filters.ReleaseCcFilterOperations()); } void GraphicsLayer::SetStickyPositionConstraint( - const WebLayerStickyPositionConstraint& sticky_constraint) { - layer_->Layer()->SetStickyPositionConstraint(sticky_constraint); + const cc::LayerStickyPositionConstraint& sticky_constraint) { + layer_->SetStickyPositionConstraint(sticky_constraint); } void GraphicsLayer::SetFilterQuality(SkFilterQuality filter_quality) { @@ -1309,21 +1305,41 @@ void GraphicsLayer::SetScrollableArea(ScrollableArea* scrollable_area) { scrollable_area_ = scrollable_area; } -std::unique_ptr<base::trace_event::ConvertableToTraceFormat> -GraphicsLayer::TakeDebugInfo(cc::Layer* layer) { - std::unique_ptr<base::trace_event::TracedValue> traced_value( - debug_info_.AsTracedValue()); +void GraphicsLayer::ScrollableAreaDisposed() { + scrollable_area_.Clear(); +} + +std::unique_ptr<base::trace_event::TracedValue> GraphicsLayer::TakeDebugInfo( + cc::Layer* layer) { + auto traced_value = std::make_unique<base::trace_event::TracedValue>(); + traced_value->SetString( "layer_name", WTF::StringUTF8Adaptor(DebugName(layer)).AsStringPiece()); - return std::move(traced_value); -} -void GraphicsLayer::didUpdateMainThreadScrollingReasons() { - debug_info_.SetMainThreadScrollingReasons( - PlatformLayer()->MainThreadScrollingReasons()); + traced_value->BeginArray("compositing_reasons"); + for (const char* description : + CompositingReason::Descriptions(compositing_reasons_)) + 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 (owner_node_id_) + traced_value->SetInteger("owner_node", owner_node_id_); + + if (auto* tracking = GetRasterInvalidationTracking()) { + tracking->AddToTracedValue(*traced_value); + tracking->ClearInvalidations(); + } + + return traced_value; } -void GraphicsLayer::didChangeScrollbarsHiddenIfOverlay(bool hidden) { +void GraphicsLayer::DidChangeScrollbarsHiddenIfOverlay(bool hidden) { if (scrollable_area_) scrollable_area_->SetScrollbarsHiddenIfOverlay(hidden); } @@ -1341,13 +1357,13 @@ PaintController& GraphicsLayer::GetPaintController() const { } void GraphicsLayer::SetElementId(const CompositorElementId& id) { - if (WebLayer* layer = PlatformLayer()) + if (cc::Layer* layer = CcLayer()) layer->SetElementId(id); } CompositorElementId GraphicsLayer::GetElementId() const { - if (WebLayer* layer = PlatformLayer()) - return layer->GetElementId(); + if (cc::Layer* layer = CcLayer()) + return layer->element_id(); return CompositorElementId(); } @@ -1384,60 +1400,64 @@ void GraphicsLayer::SetLayerState(const PropertyTreeState& layer_state, layer_state_->offset = layer_offset; } -void GraphicsLayer::PaintContents(WebDisplayItemList* web_display_item_list, - PaintingControlSetting painting_control) { +scoped_refptr<cc::DisplayItemList> GraphicsLayer::PaintContentsToDisplayList( + PaintingControlSetting painting_control) { TRACE_EVENT0("blink,benchmark", "GraphicsLayer::PaintContents"); PaintController& paint_controller = GetPaintController(); paint_controller.SetDisplayItemConstructionIsDisabled( - painting_control == kDisplayListConstructionDisabled); - paint_controller.SetSubsequenceCachingIsDisabled(painting_control == - kSubsequenceCachingDisabled); + painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED); + paint_controller.SetSubsequenceCachingIsDisabled( + painting_control == SUBSEQUENCE_CACHING_DISABLED); - if (painting_control == kPartialInvalidation) + if (painting_control == PARTIAL_INVALIDATION) client_.InvalidateTargetElementForTesting(); // We also disable caching when Painting or Construction are disabled. In both // cases we would like to compare assuming the full cost of recording, not the // cost of re-using cached content. - if (painting_control == kDisplayListCachingDisabled || - painting_control == kDisplayListPaintingDisabled || - painting_control == kDisplayListConstructionDisabled) + if (painting_control == DISPLAY_LIST_CACHING_DISABLED || + painting_control == DISPLAY_LIST_PAINTING_DISABLED || + painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED) paint_controller.InvalidateAll(); GraphicsContext::DisabledMode disabled_mode = GraphicsContext::kNothingDisabled; - if (painting_control == kDisplayListPaintingDisabled || - painting_control == kDisplayListConstructionDisabled) + if (painting_control == DISPLAY_LIST_PAINTING_DISABLED || + painting_control == DISPLAY_LIST_CONSTRUCTION_DISABLED) disabled_mode = GraphicsContext::kFullyDisabled; - // Anything other than PaintDefaultBehavior is for testing. In non-testing + // Anything other than PAINTING_BEHAVIOR_NORMAL is for testing. In non-testing // scenarios, it is an error to call GraphicsLayer::Paint. Actual painting // occurs in LocalFrameView::PaintTree() which calls GraphicsLayer::Paint(); - // this method merely copies the painted output to the WebDisplayItemList. - if (painting_control != kPaintDefaultBehavior) + // this method merely copies the painted output to the cc::DisplayItemList. + if (painting_control != PAINTING_BEHAVIOR_NORMAL) Paint(nullptr, disabled_mode); + auto display_list = base::MakeRefCounted<cc::DisplayItemList>(); + if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { DCHECK(layer_state_) << "No layer state for GraphicsLayer: " << DebugName(); PaintChunksToCcLayer::ConvertInto( - GetPaintController().GetPaintArtifact().PaintChunks(), - layer_state_->state, + GetPaintController().PaintChunks(), layer_state_->state, gfx::Vector2dF(layer_state_->offset.X(), layer_state_->offset.Y()), VisualRectSubpixelOffset(), paint_controller.GetPaintArtifact().GetDisplayItemList(), - *web_display_item_list->GetCcDisplayItemList()); + *display_list); } else { - paint_controller.GetPaintArtifact().AppendToWebDisplayItemList( + paint_controller.GetPaintArtifact().AppendToDisplayItemList( FloatSize(OffsetFromLayoutObjectWithSubpixelAccumulation()), - web_display_item_list); + *display_list); } paint_controller.SetDisplayItemConstructionIsDisabled(false); paint_controller.SetSubsequenceCachingIsDisabled(false); + + display_list->Finalize(); + return display_list; } -size_t GraphicsLayer::ApproximateUnsharedMemoryUsage() const { +size_t GraphicsLayer::GetApproximateUnsharedMemoryUsage() const { size_t result = sizeof(*this); result += GetPaintController().ApproximateUnsharedMemoryUsage(); if (raster_invalidator_) 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 2e9d925ea52..2108bee42bc 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer.h @@ -28,26 +28,26 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_H_ #include <memory> + #include "base/memory/weak_ptr.h" +#include "cc/input/overscroll_behavior.h" +#include "cc/layers/content_layer_client.h" #include "cc/layers/layer_client.h" -#include "third_party/blink/public/platform/web_content_layer.h" -#include "third_party/blink/public/platform/web_content_layer_client.h" -#include "third_party/blink/public/platform/web_image_layer.h" -#include "third_party/blink/public/platform/web_layer_sticky_position_constraint.h" -#include "third_party/blink/public/platform/web_overscroll_behavior.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_reasons.h" #include "third_party/blink/renderer/platform/graphics/compositor_element_id.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer_client.h" -#include "third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.h" +#include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item_client.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h" +#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" @@ -55,6 +55,12 @@ #include "third_party/skia/include/core/SkFilterQuality.h" #include "third_party/skia/include/core/SkRefCnt.h" +namespace cc { +class Layer; +class PictureImageLayer; +class PictureLayer; +} + namespace blink { class CompositorFilterOperations; @@ -65,7 +71,6 @@ class LinkHighlight; class PaintController; class RasterInvalidationTracking; class ScrollableArea; -class WebLayer; typedef Vector<GraphicsLayer*, 64> GraphicsLayerVector; @@ -73,7 +78,7 @@ typedef Vector<GraphicsLayer*, 64> GraphicsLayerVector; // which may have associated transformation and animations. class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, public DisplayItemClient, - private WebContentLayerClient { + private cc::ContentLayerClient { WTF_MAKE_NONCOPYABLE(GraphicsLayer); USING_FAST_MALLOC(GraphicsLayer); @@ -84,14 +89,16 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, GraphicsLayerClient& Client() const { return client_; } - GraphicsLayerDebugInfo& DebugInfo(); - - void SetCompositingReasons(CompositingReasons); + void SetCompositingReasons(CompositingReasons reasons) { + compositing_reasons_ = reasons; + } CompositingReasons GetCompositingReasons() const { - return debug_info_.GetCompositingReasons(); + return compositing_reasons_; + } + void SetSquashingDisallowedReasons(SquashingDisallowedReasons reasons) { + squashing_disallowed_reasons_ = reasons; } - void SetSquashingDisallowedReasons(SquashingDisallowedReasons); - void SetOwnerNodeId(int); + void SetOwnerNodeId(int id) { owner_node_id_ = id; } GraphicsLayer* Parent() const { return parent_; } void SetParent(GraphicsLayer*); // Internal use only. @@ -145,8 +152,8 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, void SetTransformOrigin(const FloatPoint3D&); // The size of the layer. - const FloatSize& Size() const { return size_; } - void SetSize(const FloatSize&); + const IntSize& Size() const { return size_; } + void SetSize(const IntSize&); const TransformationMatrix& Transform() const { return transform_; } void SetTransform(const TransformationMatrix&); @@ -162,8 +169,8 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, bool ContentsAreVisible() const { return contents_visible_; } void SetContentsVisible(bool); - void SetScrollParent(WebLayer*); - void SetClipParent(WebLayer*); + void SetScrollParent(cc::Layer*); + void SetClipParent(cc::Layer*); // For special cases, e.g. drawing missing tiles on Android. // The compositor should never paint this color in normal cases because the @@ -171,7 +178,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, Color BackgroundColor() const { return background_color_; } void SetBackgroundColor(const Color&); - // opaque means that we know the layer contents have no alpha + // Opaque means that we know the layer contents have no alpha. bool ContentsOpaque() const { return contents_opaque_; } void SetContentsOpaque(bool); @@ -181,7 +188,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, float Opacity() const { return opacity_; } void SetOpacity(float); - void SetBlendMode(WebBlendMode); + void SetBlendMode(BlendMode); void SetIsRootForIsolatedGroup(bool); void SetHitTestableWithoutDrawsContent(bool); @@ -192,7 +199,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, void SetFilters(CompositorFilterOperations); void SetBackdropFilters(CompositorFilterOperations); - void SetStickyPositionConstraint(const WebLayerStickyPositionConstraint&); + void SetStickyPositionConstraint(const cc::LayerStickyPositionConstraint&); void SetFilterQuality(SkFilterQuality); @@ -216,11 +223,19 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, Image*, Image::ImageDecodingMode decode_mode, RespectImageOrientationEnum = kDoNotRespectImageOrientation); - void SetContentsToPlatformLayer(WebLayer* layer) { SetContentsTo(layer); } + // If |prevent_contents_opaque_changes| is set to true, then calls to + // SetContentsOpaque() will not be passed on to the |layer|. Use when + // the client wants to have control of the opaqueness of the contents + // |layer| independently of what outcome painting produces. + void SetContentsToCcLayer(cc::Layer* layer, + bool prevent_contents_opaque_changes) { + SetContentsTo(layer, prevent_contents_opaque_changes); + } bool HasContentsLayer() const { return contents_layer_; } + cc::Layer* ContentsLayer() const { return contents_layer_; } // For hosting this GraphicsLayer in a native layer hierarchy. - WebLayer* PlatformLayer() const; + cc::Layer* CcLayer() const; int PaintCount() const { return paint_count_; } @@ -248,10 +263,12 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, void SetScrollableArea(ScrollableArea*); ScrollableArea* GetScrollableArea() const { return scrollable_area_; } - WebContentLayer* ContentLayer() const { return layer_.get(); } + void ScrollableAreaDisposed(); - static void RegisterContentsLayer(WebLayer*); - static void UnregisterContentsLayer(WebLayer*); + cc::PictureLayer* ContentLayer() const { return layer_.get(); } + + static void RegisterContentsLayer(cc::Layer*); + static void UnregisterContentsLayer(cc::Layer*); IntRect InterestRect(); void PaintRecursively(); @@ -260,35 +277,33 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, GraphicsContext::DisabledMode = GraphicsContext::kNothingDisabled); // cc::LayerClient implementation. - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo( + std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo( cc::Layer*) override; - void didUpdateMainThreadScrollingReasons() override; - void didChangeScrollbarsHiddenIfOverlay(bool) override; + void DidChangeScrollbarsHiddenIfOverlay(bool) override; PaintController& GetPaintController() const; - // Exposed for tests. - WebLayer* ContentsLayer() const { return contents_layer_; } - void SetElementId(const CompositorElementId&); CompositorElementId GetElementId() const; - WebContentLayerClient& WebContentLayerClientForTesting() { return *this; } - // DisplayItemClient methods String DebugName() const final { return client_.DebugName(this); } LayoutRect VisualRect() const override; void SetHasWillChangeTransformHint(bool); - void SetOverscrollBehavior(const WebOverscrollBehavior&); + void SetOverscrollBehavior(const cc::OverscrollBehavior&); - void SetSnapContainerData(Optional<cc::SnapContainerData>); + void SetSnapContainerData(base::Optional<cc::SnapContainerData>); void SetIsResizedByBrowserControls(bool); void SetIsContainerForFixedPositionLayers(bool); void SetLayerState(const PropertyTreeState&, const IntPoint& layer_offset); + const PropertyTreeState& GetPropertyTreeState() const { + return layer_state_->state; + } + IntPoint GetOffsetFromTransformNode() const { return layer_state_->offset; } // Capture the last painted result into a PaintRecord. This GraphicsLayer // must DrawsContent. The result is never nullptr. @@ -309,11 +324,12 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, friend class GraphicsLayerTest; private: - // WebContentLayerClient implementation. + // cc::ContentLayerClient implementation. gfx::Rect PaintableRegion() final { return InterestRect(); } - void PaintContents(WebDisplayItemList*, - PaintingControlSetting = kPaintDefaultBehavior) final; - size_t ApproximateUnsharedMemoryUsage() const final; + scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( + PaintingControlSetting painting_control) final; + bool FillsBoundsCompletely() const override { return false; } + size_t GetApproximateUnsharedMemoryUsage() const final; void PaintRecursivelyInternal(Vector<GraphicsLayer*>& repainted_layers); @@ -337,11 +353,11 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, void UpdateLayerIsDrawable(); void UpdateContentsRect(); - void SetContentsTo(WebLayer*); - void SetupContentsLayer(WebLayer*); + void SetContentsTo(cc::Layer*, bool prevent_contents_opaque_changes); + void SetupContentsLayer(cc::Layer*); void ClearContentsLayerIfUnregistered(); - WebLayer* ContentsLayerIfRegistered(); - void SetContentsLayer(WebLayer*); + cc::Layer* ContentsLayerIfRegistered(); + void SetContentsLayer(cc::Layer*); typedef HashMap<int, int> RenderingContextMap; std::unique_ptr<JSONObject> LayerTreeAsJSONInternal( @@ -367,7 +383,7 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, // Position is relative to the parent GraphicsLayer FloatPoint position_; - FloatSize size_; + IntSize size_; TransformationMatrix transform_; FloatPoint3D transform_origin_; @@ -375,10 +391,11 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, Color background_color_; float opacity_; - WebBlendMode blend_mode_; + BlendMode blend_mode_; bool has_transform_origin_ : 1; bool contents_opaque_ : 1; + bool prevent_contents_opaque_changes_ : 1; bool should_flatten_transform_ : 1; bool backface_visibility_ : 1; bool draws_content_ : 1; @@ -397,30 +414,36 @@ class PLATFORM_EXPORT GraphicsLayer : public cc::LayerClient, Vector<GraphicsLayer*> children_; GraphicsLayer* parent_; - GraphicsLayer* mask_layer_; // Reference to mask layer. We don't own this. - GraphicsLayer* contents_clipping_mask_layer_; // Reference to clipping mask - // layer. We don't own this. + // Reference to mask layer. We don't own this. + GraphicsLayer* mask_layer_; + // Reference to clipping mask layer. We don't own this. + GraphicsLayer* contents_clipping_mask_layer_; IntRect contents_rect_; int paint_count_; - std::unique_ptr<WebContentLayer> layer_; - std::unique_ptr<WebImageLayer> image_layer_; - WebLayer* contents_layer_; - // We don't have ownership of m_contentsLayer, but we do want to know if a - // given layer is the same as our current layer in setContentsTo(). Since - // |m_contentsLayer| may be deleted at this point, we stash an ID away when we - // know |m_contentsLayer| is alive and use that for comparisons from that + scoped_refptr<cc::PictureLayer> layer_; + scoped_refptr<cc::PictureImageLayer> image_layer_; + IntSize image_size_; + cc::Layer* contents_layer_; + // We don't have ownership of contents_layer_, but we do want to know if a + // given layer is the same as our current layer in SetContentsTo(). Since + // |contents_layer_| may be deleted at this point, we stash an ID away when we + // know |contents_layer_| is alive and use that for comparisons from that // point on. int contents_layer_id_; Vector<LinkHighlight*> link_highlights_; WeakPersistent<ScrollableArea> scrollable_area_; - GraphicsLayerDebugInfo debug_info_; int rendering_context3d_; + CompositingReasons compositing_reasons_ = CompositingReason::kNone; + SquashingDisallowedReasons squashing_disallowed_reasons_ = + SquashingDisallowedReason::kNone; + int owner_node_id_ = 0; + mutable std::unique_ptr<PaintController> paint_controller_; IntRect previous_interest_rect_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.cc deleted file mode 100644 index 1f38d00b074..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.cc +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.h" - -#include "base/trace_event/trace_event_argument.h" -#include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" - -namespace blink { - -GraphicsLayerDebugInfo::GraphicsLayerDebugInfo() - : compositing_reasons_(CompositingReason::kNone), - squashing_disallowed_reasons_(SquashingDisallowedReason::kNone), - owner_node_id_(0), - main_thread_scrolling_reasons_(0) {} - -GraphicsLayerDebugInfo::~GraphicsLayerDebugInfo() = default; - -std::unique_ptr<base::trace_event::TracedValue> -GraphicsLayerDebugInfo::AsTracedValue() const { - std::unique_ptr<base::trace_event::TracedValue> traced_value( - new base::trace_event::TracedValue()); - AppendAnnotatedInvalidateRects(traced_value.get()); - AppendCompositingReasons(traced_value.get()); - AppendSquashingDisallowedReasons(traced_value.get()); - AppendOwnerNodeId(traced_value.get()); - AppendMainThreadScrollingReasons(traced_value.get()); - return traced_value; -} - -void GraphicsLayerDebugInfo::AppendAnnotatedInvalidateRects( - base::trace_event::TracedValue* traced_value) const { - traced_value->BeginArray("annotated_invalidation_rects"); - for (const auto& annotated_rect : previous_invalidations_) { - const FloatRect& rect = annotated_rect.rect; - traced_value->BeginDictionary(); - traced_value->BeginArray("geometry_rect"); - traced_value->AppendDouble(rect.X()); - traced_value->AppendDouble(rect.Y()); - traced_value->AppendDouble(rect.Width()); - traced_value->AppendDouble(rect.Height()); - traced_value->EndArray(); - traced_value->SetString( - "reason", PaintInvalidationReasonToString(annotated_rect.reason)); - traced_value->EndDictionary(); - } - traced_value->EndArray(); -} - -void GraphicsLayerDebugInfo::AppendCompositingReasons( - base::trace_event::TracedValue* traced_value) const { - traced_value->BeginArray("compositing_reasons"); - for (const char* description : - CompositingReason::Descriptions(compositing_reasons_)) - traced_value->AppendString(description); - traced_value->EndArray(); -} - -void GraphicsLayerDebugInfo::AppendSquashingDisallowedReasons( - base::trace_event::TracedValue* traced_value) const { - traced_value->BeginArray("squashing_disallowed_reasons"); - for (const char* description : - SquashingDisallowedReason::Descriptions(squashing_disallowed_reasons_)) - traced_value->AppendString(description); - traced_value->EndArray(); -} - -void GraphicsLayerDebugInfo::AppendOwnerNodeId( - base::trace_event::TracedValue* traced_value) const { - if (!owner_node_id_) - return; - - traced_value->SetInteger("owner_node", owner_node_id_); -} - -void GraphicsLayerDebugInfo::AppendAnnotatedInvalidateRect( - const FloatRect& rect, - PaintInvalidationReason invalidation_reason) { - AnnotatedInvalidationRect annotated_rect = {rect, invalidation_reason}; - invalidations_.push_back(annotated_rect); -} - -void GraphicsLayerDebugInfo::ClearAnnotatedInvalidateRects() { - previous_invalidations_.clear(); - previous_invalidations_.swap(invalidations_); -} - -void GraphicsLayerDebugInfo::AppendMainThreadScrollingReasons( - base::trace_event::TracedValue* traced_value) const { - MainThreadScrollingReason::mainThreadScrollingReasonsAsTracedValue( - main_thread_scrolling_reasons_, traced_value); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.h b/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.h deleted file mode 100644 index 575e9469580..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_layer_debug_info.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2014 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_GRAPHICS_GRAPHICS_LAYER_DEBUG_INFO_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_LAYER_DEBUG_INFO_H_ - -#include "third_party/blink/renderer/platform/geometry/float_rect.h" -#include "third_party/blink/renderer/platform/graphics/compositing_reasons.h" -#include "third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h" -#include "third_party/blink/renderer/platform/graphics/squashing_disallowed_reasons.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -#include <memory> - -namespace base { -namespace trace_event { -class TracedValue; -} -} - -namespace blink { - -class GraphicsLayerDebugInfo final { - DISALLOW_NEW(); - WTF_MAKE_NONCOPYABLE(GraphicsLayerDebugInfo); - - public: - GraphicsLayerDebugInfo(); - ~GraphicsLayerDebugInfo(); - - std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; - - CompositingReasons GetCompositingReasons() const { - return compositing_reasons_; - } - void SetCompositingReasons(CompositingReasons reasons) { - compositing_reasons_ = reasons; - } - - SquashingDisallowedReasons GetSquashingDisallowedReasons() const { - return squashing_disallowed_reasons_; - } - void SetSquashingDisallowedReasons(SquashingDisallowedReasons reasons) { - squashing_disallowed_reasons_ = reasons; - } - void SetOwnerNodeId(int id) { owner_node_id_ = id; } - - void AppendAnnotatedInvalidateRect(const FloatRect&, PaintInvalidationReason); - void ClearAnnotatedInvalidateRects(); - - uint32_t GetMainThreadScrollingReasons() const { - return main_thread_scrolling_reasons_; - } - void SetMainThreadScrollingReasons(uint32_t reasons) { - main_thread_scrolling_reasons_ = reasons; - } - - private: - void AppendAnnotatedInvalidateRects(base::trace_event::TracedValue*) const; - void AppendCompositingReasons(base::trace_event::TracedValue*) const; - void AppendSquashingDisallowedReasons(base::trace_event::TracedValue*) const; - void AppendOwnerNodeId(base::trace_event::TracedValue*) const; - void AppendMainThreadScrollingReasons(base::trace_event::TracedValue*) const; - - struct AnnotatedInvalidationRect { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - FloatRect rect; - PaintInvalidationReason reason; - }; - - CompositingReasons compositing_reasons_; - SquashingDisallowedReasons squashing_disallowed_reasons_; - int owner_node_id_; - Vector<AnnotatedInvalidationRect> invalidations_; - Vector<AnnotatedInvalidationRect> previous_invalidations_; - uint32_t main_thread_scrolling_reasons_; -}; - -} // namespace blink - -#endif 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 c7dfe1e0d57..0f9b03a07da 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 @@ -28,10 +28,9 @@ #include <memory> #include <utility> +#include "cc/layers/layer.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/platform/animation/compositor_animation.h" @@ -46,10 +45,11 @@ #include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h" #include "third_party/blink/renderer/platform/graphics/test/fake_scrollable_area.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h" #include "third_party/blink/renderer/platform/testing/fake_graphics_layer_client.h" +#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" #include "third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h" #include "third_party/blink/renderer/platform/transforms/matrix_3d_transform_operation.h" @@ -69,18 +69,16 @@ class GraphicsLayerTest : public testing::Test, public PaintTestConfigurations { clip_layer_->AddChild(scroll_elasticity_layer_.get()); scroll_elasticity_layer_->AddChild(page_scale_layer_.get()); page_scale_layer_->AddChild(graphics_layer_.get()); - graphics_layer_->PlatformLayer()->SetScrollable( - clip_layer_->PlatformLayer()->Bounds()); - platform_layer_ = graphics_layer_->PlatformLayer(); + graphics_layer_->CcLayer()->SetScrollable(clip_layer_->CcLayer()->bounds()); + cc_layer_ = graphics_layer_->CcLayer(); layer_tree_view_ = std::make_unique<WebLayerTreeViewImplForTesting>(); DCHECK(layer_tree_view_); - layer_tree_view_->SetRootLayer(*clip_layer_->PlatformLayer()); + layer_tree_view_->SetRootLayer(clip_layer_->CcLayer()); WebLayerTreeView::ViewportLayers viewport_layers; - viewport_layers.overscroll_elasticity = - scroll_elasticity_layer_->PlatformLayer(); - viewport_layers.page_scale = page_scale_layer_->PlatformLayer(); - viewport_layers.inner_viewport_container = clip_layer_->PlatformLayer(); - viewport_layers.inner_viewport_scroll = graphics_layer_->PlatformLayer(); + viewport_layers.overscroll_elasticity = scroll_elasticity_layer_->CcLayer(); + viewport_layers.page_scale = page_scale_layer_->CcLayer(); + viewport_layers.inner_viewport_container = clip_layer_->CcLayer(); + viewport_layers.inner_viewport_scroll = graphics_layer_->CcLayer(); layer_tree_view_->RegisterViewportLayers(viewport_layers); layer_tree_view_->SetViewportSize(WebSize(1, 1)); @@ -117,7 +115,7 @@ class GraphicsLayerTest : public testing::Test, public PaintTestConfigurations { return layer.paint_controller_.get(); } - WebLayer* platform_layer_; + cc::Layer* cc_layer_; std::unique_ptr<FakeGraphicsLayer> graphics_layer_; std::unique_ptr<FakeGraphicsLayer> page_scale_layer_; std::unique_ptr<FakeGraphicsLayer> scroll_elasticity_layer_; @@ -130,7 +128,9 @@ class GraphicsLayerTest : public testing::Test, public PaintTestConfigurations { INSTANTIATE_TEST_CASE_P(All, GraphicsLayerTest, - testing::Values(0, kSlimmingPaintV175)); + testing::Values(0, + kSlimmingPaintV175, + kBlinkGenPropertyTrees)); class AnimationForTesting : public CompositorAnimationClient { public: @@ -146,7 +146,7 @@ class AnimationForTesting : public CompositorAnimationClient { }; TEST_P(GraphicsLayerTest, updateLayerShouldFlattenTransformWithAnimations) { - ASSERT_FALSE(platform_layer_->HasTickingAnimationForTesting()); + ASSERT_FALSE(cc_layer_->HasTickingAnimationForTesting()); std::unique_ptr<CompositorFloatAnimationCurve> curve = CompositorFloatAnimationCurve::Create(); @@ -168,32 +168,31 @@ TEST_P(GraphicsLayerTest, updateLayerShouldFlattenTransformWithAnimations) { host.AddTimeline(*compositor_timeline); compositor_timeline->AnimationAttached(animation); - platform_layer_->SetElementId(CompositorElementId(platform_layer_->Id())); + cc_layer_->SetElementId(CompositorElementId(cc_layer_->id())); - animation.GetCompositorAnimation()->AttachElement( - platform_layer_->GetElementId()); + animation.GetCompositorAnimation()->AttachElement(cc_layer_->element_id()); ASSERT_TRUE(animation.GetCompositorAnimation()->IsElementAttached()); animation.GetCompositorAnimation()->AddKeyframeModel( std::move(float_keyframe_model)); - ASSERT_TRUE(platform_layer_->HasTickingAnimationForTesting()); + ASSERT_TRUE(cc_layer_->HasTickingAnimationForTesting()); graphics_layer_->SetShouldFlattenTransform(false); - platform_layer_ = graphics_layer_->PlatformLayer(); - ASSERT_TRUE(platform_layer_); + cc_layer_ = graphics_layer_->CcLayer(); + ASSERT_TRUE(cc_layer_); - ASSERT_TRUE(platform_layer_->HasTickingAnimationForTesting()); + ASSERT_TRUE(cc_layer_->HasTickingAnimationForTesting()); animation.GetCompositorAnimation()->RemoveKeyframeModel(keyframe_model_id); - ASSERT_FALSE(platform_layer_->HasTickingAnimationForTesting()); + ASSERT_FALSE(cc_layer_->HasTickingAnimationForTesting()); graphics_layer_->SetShouldFlattenTransform(true); - platform_layer_ = graphics_layer_->PlatformLayer(); - ASSERT_TRUE(platform_layer_); + cc_layer_ = graphics_layer_->CcLayer(); + ASSERT_TRUE(cc_layer_); - ASSERT_FALSE(platform_layer_->HasTickingAnimationForTesting()); + ASSERT_FALSE(cc_layer_->HasTickingAnimationForTesting()); animation.GetCompositorAnimation()->DetachElement(); ASSERT_FALSE(animation.GetCompositorAnimation()->IsElementAttached()); @@ -230,30 +229,33 @@ TEST_P(GraphicsLayerTest, PaintRecursively) { return; IntRect interest_rect(1, 2, 3, 4); - auto transform_root = TransformPaintPropertyNode::Root(); - auto transform1 = TransformPaintPropertyNode::Create( - transform_root, TransformationMatrix().Translate(10, 20), FloatPoint3D()); - auto transform2 = TransformPaintPropertyNode::Create( - transform1, TransformationMatrix().Scale(2), FloatPoint3D()); + auto* transform_root = TransformPaintPropertyNode::Root(); + auto transform1 = + CreateTransform(transform_root, TransformationMatrix().Translate(10, 20)); + auto transform2 = + CreateTransform(transform1, TransformationMatrix().Scale(2)); client_.SetPainter([&](const GraphicsLayer* layer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect&) { { - ScopedPaintChunkProperties properties( - context.GetPaintController(), transform1, *layer, kBackgroundType); + ScopedPaintChunkProperties properties(context.GetPaintController(), + transform1.get(), *layer, + kBackgroundType); PaintControllerTestBase::DrawRect(context, *layer, kBackgroundType, interest_rect); } { - ScopedPaintChunkProperties properties( - context.GetPaintController(), transform2, *layer, kForegroundType); + ScopedPaintChunkProperties properties(context.GetPaintController(), + transform2.get(), *layer, + kForegroundType); PaintControllerTestBase::DrawRect(context, *layer, kForegroundType, interest_rect); } }); - transform1->Update(transform_root, TransformationMatrix().Translate(20, 30), - FloatPoint3D()); + transform1->Update(transform_root, + TransformPaintPropertyNode::State{ + TransformationMatrix().Translate(20, 30)}); EXPECT_TRUE(transform1->Changed(*transform_root)); EXPECT_TRUE(transform2->Changed(*transform_root)); client_.SetNeedsRepaint(true); diff --git a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc index 01cb7157199..703a49cea2d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.cc @@ -26,6 +26,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_types.h" +#include "base/stl_util.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -44,29 +45,28 @@ static const char* const kCompositeOperatorNames[] = {"clear", "xor", "lighter"}; -static const char* const kBlendOperatorNames[] = { +static const char* const kBlendModeNames[] = { "normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"}; -const int kNumCompositeOperatorNames = - WTF_ARRAY_LENGTH(kCompositeOperatorNames); -const int kNumBlendOperatorNames = WTF_ARRAY_LENGTH(kBlendOperatorNames); +const int kNumCompositeOperatorNames = base::size(kCompositeOperatorNames); +const int kNumBlendModeNames = base::size(kBlendModeNames); -bool ParseCompositeAndBlendOperator(const String& s, - CompositeOperator& op, - WebBlendMode& blend_op) { +bool ParseCompositeAndBlendMode(const String& s, + CompositeOperator& op, + BlendMode& blend_op) { for (int i = 0; i < kNumCompositeOperatorNames; i++) { if (s == kCompositeOperatorNames[i]) { op = static_cast<CompositeOperator>(i); - blend_op = WebBlendMode::kNormal; + blend_op = BlendMode::kNormal; return true; } } - for (int i = 0; i < kNumBlendOperatorNames; i++) { - if (s == kBlendOperatorNames[i]) { - blend_op = static_cast<WebBlendMode>(i); + for (int i = 0; i < kNumBlendModeNames; i++) { + if (s == kBlendModeNames[i]) { + blend_op = static_cast<BlendMode>(i); op = kCompositeSourceOver; return true; } @@ -75,12 +75,12 @@ bool ParseCompositeAndBlendOperator(const String& s, return false; } -String CompositeOperatorName(CompositeOperator op, WebBlendMode blend_op) { +String CompositeOperatorName(CompositeOperator op, BlendMode blend_op) { DCHECK_GE(op, 0); DCHECK_LT(op, kNumCompositeOperatorNames); DCHECK_GE(static_cast<unsigned>(blend_op), 0u); - if (blend_op != WebBlendMode::kNormal) - return kBlendOperatorNames[static_cast<unsigned>(blend_op)]; + if (blend_op != BlendMode::kNormal) + return kBlendModeNames[static_cast<unsigned>(blend_op)]; return kCompositeOperatorNames[op]; } 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 bec1ca3fc7f..636dd547f31 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h +++ b/chromium/third_party/blink/renderer/platform/graphics/graphics_types.h @@ -26,7 +26,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_TYPES_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_GRAPHICS_TYPES_H_ -#include "third_party/blink/public/platform/web_blend_mode.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/skia/include/core/SkFilterQuality.h" @@ -87,6 +86,25 @@ enum CompositeOperator { kCompositePlusLighter }; +enum class BlendMode { + kNormal, + kMultiply, + kScreen, + kOverlay, + kDarken, + kLighten, + kColorDodge, + kColorBurn, + kHardLight, + kSoftLight, + kDifference, + kExclusion, + kHue, + kSaturation, + kColor, + kLuminosity, +}; + enum OpacityMode { kNonOpaque, kOpaque, @@ -191,10 +209,10 @@ enum WindRule { RULE_EVENODD = SkPath::kEvenOdd_FillType }; -PLATFORM_EXPORT String CompositeOperatorName(CompositeOperator, WebBlendMode); -PLATFORM_EXPORT bool ParseCompositeAndBlendOperator(const String&, - CompositeOperator&, - WebBlendMode&); +PLATFORM_EXPORT String CompositeOperatorName(CompositeOperator, BlendMode); +PLATFORM_EXPORT bool ParseCompositeAndBlendMode(const String&, + CompositeOperator&, + BlendMode&); PLATFORM_EXPORT String LineCapName(LineCap); PLATFORM_EXPORT bool ParseLineCap(const String&, LineCap&); diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.cc b/chromium/third_party/blink/renderer/platform/graphics/image.cc index e5ebd15b343..f803141e166 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/image.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/image.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/graphics/image.h" #include "build/build_config.h" +#include "cc/tiles/software_image_decode_cache.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_data.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" @@ -54,26 +55,6 @@ #include <tuple> namespace blink { -namespace { - -bool HasCheckerableDimensions(const IntSize& size) { - CheckedNumeric<size_t> checked_size = 4u; - checked_size *= size.Width(); - checked_size *= size.Height(); - -// The constants used here should remain consistent with the values used for -// LayerTreeSettings in render_widget_compositor.cc. -#if defined(OS_ANDROID) - static const size_t kMinImageSizeCheckered = 512 * 1024; -#else - static const size_t kMinImageSizeCheckered = 1 * 1024 * 1024; -#endif - - return checked_size.ValueOrDefault(std::numeric_limits<size_t>::max()) >= - kMinImageSizeCheckered; -} - -} // namespace Image::Image(ImageObserver* observer, bool is_multipart) : image_observer_disabled_(false), @@ -91,6 +72,18 @@ Image* Image::NullImage() { return null_image; } +// static +cc::ImageDecodeCache& Image::SharedCCDecodeCache() { + // This denotes the allocated locked memory budget for the cache used for + // book-keeping. The cache indicates when the total memory locked exceeds this + // budget in cc::DecodedDrawImage. + static const size_t kLockedMemoryLimitBytes = 64 * 1024 * 1024; + DEFINE_THREAD_SAFE_STATIC_LOCAL(cc::SoftwareImageDecodeCache, + image_decode_cache, + (kN32_SkColorType, kLockedMemoryLimitBytes)); + return image_decode_cache; +} + scoped_refptr<Image> Image::LoadPlatformResource(const char* name) { const WebData& resource = Platform::Current()->GetDataResource(name); if (resource.IsEmpty()) @@ -408,13 +401,8 @@ FloatRect Image::ComputeTileContaining(const FloatPoint& point, const FloatSize& tile_spacing) { const FloatSize actual_tile_size(tile_size + tile_spacing); return FloatRect( - FloatPoint( - point.X() + fmodf(fmodf(-tile_phase.X(), actual_tile_size.Width()) - - actual_tile_size.Width(), - actual_tile_size.Width()), - point.Y() + fmodf(fmodf(-tile_phase.Y(), actual_tile_size.Height()) - - actual_tile_size.Height(), - actual_tile_size.Height())), + FloatPoint(point.X() + fmodf(-tile_phase.X(), actual_tile_size.Width()), + point.Y() + fmodf(-tile_phase.Y(), actual_tile_size.Height())), tile_size); } @@ -435,36 +423,4 @@ FloatRect Image::ComputeSubsetForTile(const FloatRect& tile, return subset; } -// static -void Image::RecordCheckerableImageUMA(Image& image, ImageType type) { - // This enum is used in UMA counting so should be treated as append only. - // Please keep it in sync with CheckerableImageType in enums.xml. - enum class CheckerableImageType { - kCheckerableImg = 0, - kCheckerableSvg = 1, - kCheckerableCss = 2, - kNotCheckerable = 3, - kCount = 4 - }; - - CheckerableImageType checkerable_type = CheckerableImageType::kNotCheckerable; - if (image.IsSizeAvailable() && !image.MaybeAnimated() && - HasCheckerableDimensions(image.Size())) { - switch (type) { - case ImageType::kImg: - checkerable_type = CheckerableImageType::kCheckerableImg; - break; - case ImageType::kSvg: - checkerable_type = CheckerableImageType::kCheckerableSvg; - break; - case ImageType::kCss: - checkerable_type = CheckerableImageType::kCheckerableCss; - break; - } - } - - UMA_HISTOGRAM_ENUMERATION("Blink.CheckerableImageCount", checkerable_type, - CheckerableImageType::kCount); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/image.h b/chromium/third_party/blink/renderer/platform/graphics/image.h index a952174716a..35e9e3f431e 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/image.h +++ b/chromium/third_party/blink/renderer/platform/graphics/image.h @@ -47,6 +47,7 @@ class SkMatrix; namespace cc { +class ImageDecodeCache; class PaintCanvas; class PaintFlags; } // namespace cc @@ -75,6 +76,8 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { public: virtual ~Image(); + static cc::ImageDecodeCache& SharedCCDecodeCache(); + static scoped_refptr<Image> LoadPlatformResource(const char* name); static bool SupportsType(const String&); @@ -236,9 +239,6 @@ class PLATFORM_EXPORT Image : public ThreadSafeRefCounted<Image> { const FloatRect& dest, const FloatSize& image_size); - enum class ImageType { kImg, kSvg, kCss }; - static void RecordCheckerableImageUMA(Image&, ImageType); - virtual sk_sp<PaintRecord> PaintRecordForContainer( const KURL& url, const IntSize& container_size, 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 f6a1acd85a2..40687fdf81f 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 @@ -42,6 +42,7 @@ #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSwizzle.h" #include "third_party/skia/include/encode/SkJpegEncoder.h" @@ -119,6 +120,13 @@ const unsigned char* ImageDataBuffer::Pixels() const { bool ImageDataBuffer::EncodeImage(const String& mime_type, const double& quality, Vector<unsigned char>* encoded_image) const { + return EncodeImageInternal(mime_type, quality, encoded_image, pixmap_); +} + +bool ImageDataBuffer::EncodeImageInternal(const String& mime_type, + const double& quality, + Vector<unsigned char>* encoded_image, + const SkPixmap& pixmap) const { DCHECK(is_valid_); if (mime_type == "image/jpeg") { @@ -130,19 +138,19 @@ bool ImageDataBuffer::EncodeImage(const String& mime_type, // kRespect or kIgnore, but the JPEG encoder does not support kIgnore with // F16 for some reason, so we switch to kRespect in that case, with no // consequence on the encoded output. - options.fBlendBehavior = pixmap_.colorType() == kRGBA_F16_SkColorType + options.fBlendBehavior = pixmap.colorType() == kRGBA_F16_SkColorType ? SkTransferFunctionBehavior::kRespect : SkTransferFunctionBehavior::kIgnore; if (options.fQuality == 100) { options.fDownsample = SkJpegEncoder::Downsample::k444; } - return ImageEncoder::Encode(encoded_image, pixmap_, options); + return ImageEncoder::Encode(encoded_image, pixmap, options); } if (mime_type == "image/webp") { SkWebpEncoder::Options options = ImageEncoder::ComputeWebpOptions( quality, SkTransferFunctionBehavior::kIgnore); - return ImageEncoder::Encode(encoded_image, pixmap_, options); + return ImageEncoder::Encode(encoded_image, pixmap, options); } DCHECK_EQ(mime_type, "image/png"); @@ -150,7 +158,7 @@ bool ImageDataBuffer::EncodeImage(const String& mime_type, options.fFilterFlags = SkPngEncoder::FilterFlag::kSub; options.fZLibLevel = 3; options.fUnpremulBehavior = SkTransferFunctionBehavior::kIgnore; - return ImageEncoder::Encode(encoded_image, pixmap_, options); + return ImageEncoder::Encode(encoded_image, pixmap, options); } String ImageDataBuffer::ToDataURL(const String& mime_type, @@ -158,8 +166,22 @@ String ImageDataBuffer::ToDataURL(const String& mime_type, DCHECK(is_valid_); DCHECK(MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding(mime_type)); + // toDataURL always encodes in sRGB and does not include the color space + // information. + sk_sp<SkImage> skia_image = nullptr; + SkPixmap pixmap = pixmap_; + if (pixmap.colorSpace()) { + if (!pixmap.colorSpace()->isSRGB()) { + skia_image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); + skia_image = skia_image->makeColorSpace( + SkColorSpace::MakeSRGB(), SkTransferFunctionBehavior::kIgnore); + skia_image->peekPixels(&pixmap); + } + pixmap.setColorSpace(nullptr); + } + Vector<unsigned char> result; - if (!EncodeImage(mime_type, quality, &result)) + if (!EncodeImageInternal(mime_type, quality, &result, pixmap)) return "data:,"; return "data:" + mime_type + ";base64," + Base64Encode(result); 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 489906bc7e1..3002ac9875b 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 @@ -51,6 +51,7 @@ class PLATFORM_EXPORT ImageDataBuffer { bool EncodeImage(const String& mime_type, const double& quality, Vector<unsigned char>* encoded_image) const; + const unsigned char* Pixels() const; const IntSize& size() const { return size_; } int Height() const { return size_.Height(); } @@ -65,6 +66,11 @@ class PLATFORM_EXPORT ImageDataBuffer { bool IsValid() { return is_valid_; } // Only used by Create() + bool EncodeImageInternal(const String& mime_type, + const double& quality, + Vector<unsigned char>* encoded_image, + const SkPixmap& pixmap) const; + sk_sp<SkImage> retained_image_; SkPixmap pixmap_; bool is_valid_ = false; diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc b/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc index f61755d7a24..01342d3ac8c 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/image_layer_chromium_test.cc @@ -26,6 +26,7 @@ #include "third_party/blink/renderer/platform/graphics/image.h" #include <memory> + #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/testing/fake_graphics_layer.h" @@ -129,11 +130,11 @@ TEST(ImageLayerChromiumTest, opaqueImages) { graphics_layer->SetContentsToImage(opaque_image.get(), Image::kUnspecifiedDecode); - ASSERT_TRUE(graphics_layer->ContentsLayer()->Opaque()); + ASSERT_TRUE(graphics_layer->ContentsLayer()->contents_opaque()); graphics_layer->SetContentsToImage(non_opaque_image.get(), Image::kUnspecifiedDecode); - ASSERT_FALSE(graphics_layer->ContentsLayer()->Opaque()); + ASSERT_FALSE(graphics_layer->ContentsLayer()->contents_opaque()); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/image_observer.h b/chromium/third_party/blink/renderer/platform/graphics/image_observer.h index 9417c7794ae..6c609242f4d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/image_observer.h +++ b/chromium/third_party/blink/renderer/platform/graphics/image_observer.h @@ -51,7 +51,7 @@ class PLATFORM_EXPORT ImageObserver : public GarbageCollectedMixin { // See the comment of Image::SetData(). virtual void AsyncLoadCompleted(const Image*) = 0; - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h b/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h index f419ef4ac53..b352afe5919 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h +++ b/chromium/third_party/blink/renderer/platform/graphics/link_highlight.h @@ -7,15 +7,17 @@ #include "third_party/blink/renderer/platform/platform_export.h" -namespace blink { +namespace cc { +class Layer; +} -class WebLayer; +namespace blink { class PLATFORM_EXPORT LinkHighlight { public: virtual void Invalidate() = 0; virtual void ClearCurrentGraphicsLayer() = 0; - virtual WebLayer* Layer() = 0; + virtual cc::Layer* Layer() = 0; protected: virtual ~LinkHighlight() = default; 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 89b92fa9686..b5fa145035f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.cc @@ -232,7 +232,7 @@ std::unique_ptr<JSONObject> ObjectForSkPath(const SkPath& path) { std::unique_ptr<JSONObject> path_point_item = JSONObject::Create(); path_point_item->SetString("verb", verb_params.name); DCHECK_LE(verb_params.point_count + verb_params.point_offset, - WTF_ARRAY_LENGTH(points)); + arraysize(points)); path_point_item->SetArray( "points", ArrayForSkPoints(verb_params.point_count, points + verb_params.point_offset)); @@ -483,11 +483,8 @@ std::unique_ptr<JSONObject> ObjectForSkPaint(const SkPaint& paint) { paint_item->SetString("hinting", HintingName(paint.getHinting())); if (paint.getBlendMode() != SkBlendMode::kSrcOver) paint_item->SetString("blendMode", SkBlendMode_Name(paint.getBlendMode())); - if (const auto* filter = paint.getImageFilter()) { - SkString str; - filter->toString(&str); - paint_item->SetString("imageFilter", str.c_str()); - } + if (paint.getImageFilter()) + paint_item->SetString("imageFilter", "SkImageFilter"); return paint_item; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h index c27afc5b61b..bb8ac6139c7 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h +++ b/chromium/third_party/blink/renderer/platform/graphics/logging_canvas.h @@ -106,7 +106,9 @@ class LoggingCanvas : public InterceptingCanvasBase { void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override; void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override; void onClipRegion(const SkRegion&, SkClipOp) override; - virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*); + void onDrawPicture(const SkPicture*, + const SkMatrix*, + const SkPaint*) override; void didSetMatrix(const SkMatrix&) override; void didConcat(const SkMatrix&) override; void willSave() override; diff --git a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc b/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc index 886205c9ce5..fa33e6641e0 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/mailbox_texture_holder.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/mailbox_texture_holder.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "skia/ext/texture_handle.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.cc index ed5638d1880..4772ef9271a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.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/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.h" +#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h" #include <memory> #include "base/single_thread_task_runner.h" @@ -10,14 +10,14 @@ #include "components/viz/common/quads/texture_draw_quad.h" #include "components/viz/common/resources/resource_format.h" #include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom-blink.h" +#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.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/cross_thread_functional.h" #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h" #include "third_party/blink/renderer/platform/graphics/offscreen_canvas_placeholder.h" #include "third_party/blink/renderer/platform/histogram.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/web_task_runner.h" namespace blink { @@ -27,46 +27,40 @@ enum { kMaxUnreclaimedPlaceholderFrames = 3, }; -OffscreenCanvasFrameDispatcherImpl::OffscreenCanvasFrameDispatcherImpl( +OffscreenCanvasFrameDispatcher::OffscreenCanvasFrameDispatcher( OffscreenCanvasFrameDispatcherClient* client, uint32_t client_id, uint32_t sink_id, int canvas_id, - int width, - int height) - : OffscreenCanvasFrameDispatcher(client), - frame_sink_id_(viz::FrameSinkId(client_id, sink_id)), - width_(width), - height_(height), + const IntSize& size) + : frame_sink_id_(viz::FrameSinkId(client_id, sink_id)), + size_(size), change_size_for_next_commit_(false), needs_begin_frame_(false), binding_(this), placeholder_canvas_id_(canvas_id), - num_unreclaimed_frames_posted_(0) { + num_unreclaimed_frames_posted_(0), + client_(client), + weak_ptr_factory_(this) { if (frame_sink_id_.is_valid()) { // Only frameless canvas pass an invalid frame sink id; we don't create // mojo channel for this special case. - current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId(); DCHECK(!sink_.is_bound()); - mojom::blink::OffscreenCanvasProviderPtr provider; + mojom::blink::EmbeddedFrameSinkProviderPtr provider; Platform::Current()->GetInterfaceProvider()->GetInterface( mojo::MakeRequest(&provider)); + DCHECK(provider); - scoped_refptr<base::SingleThreadTaskRunner> task_runner; - auto scheduler = blink::Platform::Current()->CurrentThread()->Scheduler(); - if (scheduler) - task_runner = scheduler->CompositorTaskRunner(); - viz::mojom::blink::CompositorFrameSinkClientPtr client; - binding_.Bind(mojo::MakeRequest(&client), task_runner); - provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client), + binding_.Bind(mojo::MakeRequest(&client_ptr_)); + provider->CreateCompositorFrameSink(frame_sink_id_, std::move(client_ptr_), mojo::MakeRequest(&sink_)); } offscreen_canvas_resource_provider_ = - std::make_unique<OffscreenCanvasResourceProvider>(width, height); + std::make_unique<OffscreenCanvasResourceProvider>(size_.Width(), + size_.Height(), this); } -OffscreenCanvasFrameDispatcherImpl::~OffscreenCanvasFrameDispatcherImpl() = - default; +OffscreenCanvasFrameDispatcher::~OffscreenCanvasFrameDispatcher() = default; namespace { @@ -75,7 +69,7 @@ void UpdatePlaceholderImage( scoped_refptr<base::SingleThreadTaskRunner> task_runner, int placeholder_canvas_id, scoped_refptr<blink::StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { DCHECK(IsMainThread()); OffscreenCanvasPlaceholder* placeholder_canvas = OffscreenCanvasPlaceholder::GetPlaceholderById(placeholder_canvas_id); @@ -88,9 +82,9 @@ void UpdatePlaceholderImage( } // namespace -void OffscreenCanvasFrameDispatcherImpl::PostImageToPlaceholderIfNotBlocked( +void OffscreenCanvasFrameDispatcher::PostImageToPlaceholderIfNotBlocked( scoped_refptr<StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { if (placeholder_canvas_id_ == kInvalidPlaceholderCanvasId) { offscreen_canvas_resource_provider_->ReclaimResource(resource_id); return; @@ -116,9 +110,9 @@ void OffscreenCanvasFrameDispatcherImpl::PostImageToPlaceholderIfNotBlocked( } } -void OffscreenCanvasFrameDispatcherImpl::PostImageToPlaceholder( +void OffscreenCanvasFrameDispatcher::PostImageToPlaceholder( scoped_refptr<StaticBitmapImage> image, - unsigned resource_id) { + viz::ResourceId resource_id) { scoped_refptr<base::SingleThreadTaskRunner> dispatcher_task_runner = Platform::Current()->CurrentThread()->GetTaskRunner(); @@ -130,24 +124,56 @@ void OffscreenCanvasFrameDispatcherImpl::PostImageToPlaceholder( placeholder_canvas_id_, std::move(image), resource_id)); } -void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( +void OffscreenCanvasFrameDispatcher::DispatchFrameSync( scoped_refptr<StaticBitmapImage> image, double commit_start_time, const SkIRect& damage_rect) { - if (!image || !VerifyImageSize(image->Size())) + viz::CompositorFrame frame; + if (!PrepareFrame(std::move(image), commit_start_time, damage_rect, &frame)) + return; + + pending_compositor_frames_++; + WTF::Vector<viz::ReturnedResource> resources; + sink_->SubmitCompositorFrameSync( + parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(), + std::move(frame), nullptr, 0, &resources); + DidReceiveCompositorFrameAck(resources); +} + +void OffscreenCanvasFrameDispatcher::DispatchFrame( + scoped_refptr<StaticBitmapImage> image, + double commit_start_time, + const SkIRect& damage_rect) { + viz::CompositorFrame frame; + if (!PrepareFrame(std::move(image), commit_start_time, damage_rect, &frame)) return; + pending_compositor_frames_++; + sink_->SubmitCompositorFrame( + parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(), + std::move(frame), nullptr, 0); +} + +bool OffscreenCanvasFrameDispatcher::PrepareFrame( + scoped_refptr<StaticBitmapImage> image, + double commit_start_time, + const SkIRect& damage_rect, + viz::CompositorFrame* frame) { + if (!image || !VerifyImageSize(image->Size())) + return false; + offscreen_canvas_resource_provider_->IncNextResourceId(); + // For frameless canvas, we don't get a valid frame_sink_id and should drop. if (!frame_sink_id_.is_valid()) { PostImageToPlaceholderIfNotBlocked( std::move(image), offscreen_canvas_resource_provider_->GetNextResourceId()); - return; + return false; } - viz::CompositorFrame frame; + // TODO(crbug.com/652931): update the device_scale_factor - frame.metadata.device_scale_factor = 1.0f; + frame->metadata.device_scale_factor = 1.0f; if (current_begin_frame_ack_.sequence_number == viz::BeginFrameArgs::kInvalidFrameNumber) { // TODO(eseckler): This shouldn't be necessary when OffscreenCanvas no @@ -156,9 +182,9 @@ void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( } else { current_begin_frame_ack_.has_damage = true; } - frame.metadata.begin_frame_ack = current_begin_frame_ack_; + frame->metadata.begin_frame_ack = current_begin_frame_ack_; - const gfx::Rect bounds(width_, height_); + const gfx::Rect bounds(size_.Width(), size_.Height()); const int kRenderPassId = 1; bool is_clipped = false; // TODO(crbug.com/705019): optimize for contexts that have {alpha: false} @@ -206,7 +232,7 @@ void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( scoped_refptr<StaticBitmapImage> accelerated_image = image->MakeAccelerated(SharedGpuContext::ContextProviderWrapper()); if (!accelerated_image) - return; + return false; offscreen_canvas_resource_provider_ ->SetTransferableResourceToStaticBitmapImage(resource, accelerated_image); @@ -224,11 +250,11 @@ void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( std::move(image), offscreen_canvas_resource_provider_->GetNextResourceId()); - frame.resource_list.push_back(std::move(resource)); + frame->resource_list.push_back(std::move(resource)); viz::TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<viz::TextureDrawQuad>(); - gfx::Size rect_size(width_, height_); + gfx::Size rect_size(size_.Width(), size_.Height()); // TODO(crbug.com/705019): optimize for contexts that have {alpha: false} const bool kNeedsBlending = true; @@ -249,7 +275,7 @@ void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( SK_ColorTRANSPARENT, vertex_opacity, yflipped, kNearestNeighbor, false); - frame.render_pass_list.push_back(std::move(pass)); + frame->render_pass_list.push_back(std::move(pass)); double elapsed_time = WTF::CurrentTimeTicksInSeconds() - commit_start_time; @@ -338,23 +364,21 @@ void OffscreenCanvasFrameDispatcherImpl::DispatchFrame( } if (change_size_for_next_commit_) { - current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId(); + parent_local_surface_id_allocator_.GenerateId(); change_size_for_next_commit_ = false; } - pending_compositor_frames_++; - sink_->SubmitCompositorFrame(current_local_surface_id_, std::move(frame), - nullptr, 0); + return true; } -void OffscreenCanvasFrameDispatcherImpl::DidReceiveCompositorFrameAck( +void OffscreenCanvasFrameDispatcher::DidReceiveCompositorFrameAck( const WTF::Vector<viz::ReturnedResource>& resources) { ReclaimResources(resources); pending_compositor_frames_--; DCHECK_GE(pending_compositor_frames_, 0); } -void OffscreenCanvasFrameDispatcherImpl::DidPresentCompositorFrame( +void OffscreenCanvasFrameDispatcher::DidPresentCompositorFrame( uint32_t presentation_token, mojo_base::mojom::blink::TimeTicksPtr time, WTF::TimeDelta refresh, @@ -362,12 +386,12 @@ void OffscreenCanvasFrameDispatcherImpl::DidPresentCompositorFrame( NOTIMPLEMENTED(); } -void OffscreenCanvasFrameDispatcherImpl::DidDiscardCompositorFrame( +void OffscreenCanvasFrameDispatcher::DidDiscardCompositorFrame( uint32_t presentation_token) { NOTIMPLEMENTED(); } -void OffscreenCanvasFrameDispatcherImpl::SetNeedsBeginFrame( +void OffscreenCanvasFrameDispatcher::SetNeedsBeginFrame( bool needs_begin_frame) { if (needs_begin_frame_ == needs_begin_frame) return; @@ -376,7 +400,7 @@ void OffscreenCanvasFrameDispatcherImpl::SetNeedsBeginFrame( SetNeedsBeginFrameInternal(); } -void OffscreenCanvasFrameDispatcherImpl::SetSuspendAnimation( +void OffscreenCanvasFrameDispatcher::SetSuspendAnimation( bool suspend_animation) { if (suspend_animation_ == suspend_animation) return; @@ -385,19 +409,18 @@ void OffscreenCanvasFrameDispatcherImpl::SetSuspendAnimation( SetNeedsBeginFrameInternal(); } -void OffscreenCanvasFrameDispatcherImpl::SetNeedsBeginFrameInternal() { +void OffscreenCanvasFrameDispatcher::SetNeedsBeginFrameInternal() { if (sink_) { sink_->SetNeedsBeginFrame(needs_begin_frame_ && !suspend_animation_); } } -void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( +void OffscreenCanvasFrameDispatcher::OnBeginFrame( const viz::BeginFrameArgs& begin_frame_args) { DCHECK(Client()); current_begin_frame_ack_ = viz::BeginFrameAck( begin_frame_args.source_id, begin_frame_args.sequence_number, false); - if (pending_compositor_frames_ >= kMaxPendingCompositorFrames || (begin_frame_args.type == viz::BeginFrameArgs::MISSED && base::TimeTicks::Now() > begin_frame_args.deadline)) { @@ -410,12 +433,14 @@ void OffscreenCanvasFrameDispatcherImpl::OnBeginFrame( current_begin_frame_ack_.sequence_number = viz::BeginFrameArgs::kInvalidFrameNumber; } -void OffscreenCanvasFrameDispatcherImpl::ReclaimResources( + +void OffscreenCanvasFrameDispatcher::ReclaimResources( const WTF::Vector<viz::ReturnedResource>& resources) { offscreen_canvas_resource_provider_->ReclaimResources(resources); } -void OffscreenCanvasFrameDispatcherImpl::ReclaimResource(unsigned resource_id) { +void OffscreenCanvasFrameDispatcher::ReclaimResource( + viz::ResourceId resource_id) { offscreen_canvas_resource_provider_->ReclaimResource(resource_id); num_unreclaimed_frames_posted_--; @@ -430,20 +455,29 @@ void OffscreenCanvasFrameDispatcherImpl::ReclaimResource(unsigned resource_id) { } } -bool OffscreenCanvasFrameDispatcherImpl::VerifyImageSize( - const IntSize image_size) { - if (image_size.Width() == width_ && image_size.Height() == height_) +bool OffscreenCanvasFrameDispatcher::VerifyImageSize(const IntSize image_size) { + if (image_size == size_) return true; return false; } -void OffscreenCanvasFrameDispatcherImpl::Reshape(int width, int height) { - if (width_ != width || height_ != height) { - width_ = width; - height_ = height; - offscreen_canvas_resource_provider_->Reshape(width, height); +void OffscreenCanvasFrameDispatcher::Reshape(const IntSize& size) { + if (size_ != size) { + size_ = size; + offscreen_canvas_resource_provider_->Reshape(size_.Width(), size_.Height()); change_size_for_next_commit_ = true; } } +void OffscreenCanvasFrameDispatcher::DidAllocateSharedBitmap( + mojo::ScopedSharedBufferHandle buffer, + ::gpu::mojom::blink::MailboxPtr id) { + sink_->DidAllocateSharedBitmap(std::move(buffer), std::move(id)); +} + +void OffscreenCanvasFrameDispatcher::DidDeleteSharedBitmap( + ::gpu::mojom::blink::MailboxPtr id) { + sink_->DidDeleteSharedBitmap(std::move(id)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h index f2fde10df9d..557e0a3b230 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h +++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h @@ -5,47 +5,130 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_H_ -#include "base/memory/scoped_refptr.h" -#include "base/memory/weak_ptr.h" -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/platform_export.h" +#include <memory> +#include "components/viz/common/frame_sinks/begin_frame_args.h" +#include "components/viz/common/resources/resource_id.h" +#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" +#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h" +#include "third_party/blink/renderer/platform/wtf/compiler.h" namespace blink { -class StaticBitmapImage; - class OffscreenCanvasFrameDispatcherClient { public: virtual void BeginFrame() = 0; }; -class PLATFORM_EXPORT OffscreenCanvasFrameDispatcher { +class PLATFORM_EXPORT OffscreenCanvasFrameDispatcher + : public viz::mojom::blink::CompositorFrameSinkClient { public: - virtual ~OffscreenCanvasFrameDispatcher() = default; - virtual void DispatchFrame(scoped_refptr<StaticBitmapImage>, - double commit_start_time, - const SkIRect& damage_rect) = 0; - virtual void ReclaimResource(unsigned resource_id) = 0; - virtual void SetNeedsBeginFrame(bool) = 0; - virtual void SetSuspendAnimation(bool) = 0; - virtual bool NeedsBeginFrame() const = 0; - virtual bool IsAnimationSuspended() const = 0; - - virtual void Reshape(int width, int height) = 0; - base::WeakPtr<OffscreenCanvasFrameDispatcher> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } OffscreenCanvasFrameDispatcherClient* Client() { return client_; } - protected: - OffscreenCanvasFrameDispatcher(OffscreenCanvasFrameDispatcherClient* client) - : weak_ptr_factory_(this), client_(client) {} + enum { + kInvalidPlaceholderCanvasId = -1, + }; + + OffscreenCanvasFrameDispatcher(OffscreenCanvasFrameDispatcherClient*, + uint32_t client_id, + uint32_t sink_id, + int placeholder_canvas_id, + const IntSize&); + + ~OffscreenCanvasFrameDispatcher() override; + void SetNeedsBeginFrame(bool); + void SetSuspendAnimation(bool); + bool NeedsBeginFrame() const { return needs_begin_frame_; } + bool IsAnimationSuspended() const { return suspend_animation_; } + void DispatchFrame(scoped_refptr<StaticBitmapImage>, + double commit_start_time, + const SkIRect& damage_rect); + void ReclaimResource(viz::ResourceId); + void DispatchFrameSync(scoped_refptr<StaticBitmapImage>, + double commit_start_time, + const SkIRect& damage_rect); + + void Reshape(const IntSize&); + + // viz::mojom::blink::CompositorFrameSinkClient implementation. + void DidReceiveCompositorFrameAck( + const WTF::Vector<viz::ReturnedResource>& resources) final; + void DidPresentCompositorFrame(uint32_t presentation_token, + mojo_base::mojom::blink::TimeTicksPtr, + WTF::TimeDelta refresh, + uint32_t flags) final; + void DidDiscardCompositorFrame(uint32_t presentation_token) final; + void OnBeginFrame(const viz::BeginFrameArgs&) final; + void OnBeginFramePausedChanged(bool paused) final{}; + void ReclaimResources( + const WTF::Vector<viz::ReturnedResource>& resources) final; + + void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle buffer, + ::gpu::mojom::blink::MailboxPtr id); + void DidDeleteSharedBitmap(::gpu::mojom::blink::MailboxPtr id); + + // This enum is used in histogram, so it should be append-only. + enum OffscreenCanvasCommitType { + kCommitGPUCanvasGPUCompositing = 0, + kCommitGPUCanvasSoftwareCompositing = 1, + kCommitSoftwareCanvasGPUCompositing = 2, + kCommitSoftwareCanvasSoftwareCompositing = 3, + kOffscreenCanvasCommitTypeCount, + + }; private: - base::WeakPtrFactory<OffscreenCanvasFrameDispatcher> weak_ptr_factory_; + friend class OffscreenCanvasFrameDispatcherTest; + + bool PrepareFrame(scoped_refptr<StaticBitmapImage>, + double commit_start_time, + const SkIRect& damage_rect, + viz::CompositorFrame* frame); + + // Surface-related + viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; + const viz::FrameSinkId frame_sink_id_; + + IntSize size_; + bool change_size_for_next_commit_; + bool suspend_animation_ = false; + bool needs_begin_frame_ = false; + int pending_compositor_frames_ = 0; + + void SetNeedsBeginFrameInternal(); + + bool VerifyImageSize(const IntSize); + void PostImageToPlaceholderIfNotBlocked(scoped_refptr<StaticBitmapImage>, + viz::ResourceId resource_id); + // virtual for testing + virtual void PostImageToPlaceholder(scoped_refptr<StaticBitmapImage>, + viz::ResourceId resource_id); + + viz::mojom::blink::CompositorFrameSinkPtr sink_; + mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_; + viz::mojom::blink::CompositorFrameSinkClientPtr client_ptr_; + + int placeholder_canvas_id_; + + // The latest_unposted_resource_id_ always refers to the Id of the frame + // resource used by the latest_unposted_image_. + scoped_refptr<StaticBitmapImage> latest_unposted_image_; + viz::ResourceId latest_unposted_resource_id_; + unsigned num_unreclaimed_frames_posted_; + + viz::BeginFrameAck current_begin_frame_ack_; + OffscreenCanvasFrameDispatcherClient* client_; + + std::unique_ptr<OffscreenCanvasResourceProvider> + offscreen_canvas_resource_provider_; + + base::WeakPtrFactory<OffscreenCanvasFrameDispatcher> weak_ptr_factory_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.h b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.h deleted file mode 100644 index 0630852971d..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl.h +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_IMPL_H_ - -#include <memory> -#include "components/viz/common/frame_sinks/begin_frame_args.h" -#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" -#include "mojo/public/cpp/bindings/binding.h" -#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" -#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h" -#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h" -#include "third_party/blink/renderer/platform/wtf/compiler.h" - -namespace blink { - -class PLATFORM_EXPORT OffscreenCanvasFrameDispatcherImpl - : public OffscreenCanvasFrameDispatcher, - public viz::mojom::blink::CompositorFrameSinkClient { - public: - enum { - kInvalidPlaceholderCanvasId = -1, - }; - - OffscreenCanvasFrameDispatcherImpl(OffscreenCanvasFrameDispatcherClient*, - uint32_t client_id, - uint32_t sink_id, - int placeholder_canvas_id, - int width, - int height); - - // OffscreenCanvasFrameDispatcher implementation. - virtual ~OffscreenCanvasFrameDispatcherImpl(); - void SetNeedsBeginFrame(bool) final; - void SetSuspendAnimation(bool) final; - bool NeedsBeginFrame() const final { return needs_begin_frame_; } - bool IsAnimationSuspended() const final { return suspend_animation_; } - void DispatchFrame(scoped_refptr<StaticBitmapImage>, - double commit_start_time, - const SkIRect& damage_rect) final; - void ReclaimResource(unsigned resource_id) final; - void Reshape(int width, int height) final; - - // viz::mojom::blink::CompositorFrameSinkClient implementation. - void DidReceiveCompositorFrameAck( - const WTF::Vector<viz::ReturnedResource>& resources) final; - void DidPresentCompositorFrame(uint32_t presentation_token, - mojo_base::mojom::blink::TimeTicksPtr, - WTF::TimeDelta refresh, - uint32_t flags) final; - void DidDiscardCompositorFrame(uint32_t presentation_token) final; - void OnBeginFrame(const viz::BeginFrameArgs&) final; - void OnBeginFramePausedChanged(bool paused) final{}; - void ReclaimResources( - const WTF::Vector<viz::ReturnedResource>& resources) final; - - // This enum is used in histogram, so it should be append-only. - enum OffscreenCanvasCommitType { - kCommitGPUCanvasGPUCompositing = 0, - kCommitGPUCanvasSoftwareCompositing = 1, - kCommitSoftwareCanvasGPUCompositing = 2, - kCommitSoftwareCanvasSoftwareCompositing = 3, - kOffscreenCanvasCommitTypeCount, - }; - - private: - friend class OffscreenCanvasFrameDispatcherImplTest; - - // Surface-related - viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; - const viz::FrameSinkId frame_sink_id_; - viz::LocalSurfaceId current_local_surface_id_; - - int width_; - int height_; - bool change_size_for_next_commit_; - bool suspend_animation_ = false; - bool needs_begin_frame_ = false; - int pending_compositor_frames_ = 0; - - void SetNeedsBeginFrameInternal(); - - std::unique_ptr<OffscreenCanvasResourceProvider> - offscreen_canvas_resource_provider_; - - bool VerifyImageSize(const IntSize); - void PostImageToPlaceholderIfNotBlocked(scoped_refptr<StaticBitmapImage>, - unsigned resource_id); - // virtual for testing - virtual void PostImageToPlaceholder(scoped_refptr<StaticBitmapImage>, - unsigned resource_id); - - viz::mojom::blink::CompositorFrameSinkPtr sink_; - mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_; - - int placeholder_canvas_id_; - - // The latest_unposted_resource_id_ always refers to the Id of the frame - // resource used by the latest_unposted_image_. - scoped_refptr<StaticBitmapImage> latest_unposted_image_; - unsigned latest_unposted_resource_id_; - unsigned num_unreclaimed_frames_posted_; - - viz::BeginFrameAck current_begin_frame_ack_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_FRAME_DISPATCHER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl_test.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc index c3ec43e599a..f0906bf72f3 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_impl_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher_test.cc @@ -2,10 +2,11 @@ // 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/offscreen_canvas_frame_dispatcher_impl.h" +#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.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" #include "third_party/skia/include/core/SkSurface.h" @@ -15,17 +16,17 @@ using testing::Mock; namespace blink { -class MockOffscreenCanvasFrameDispatcherImpl - : public OffscreenCanvasFrameDispatcherImpl { +class MockOffscreenCanvasFrameDispatcher + : public OffscreenCanvasFrameDispatcher { public: - MockOffscreenCanvasFrameDispatcherImpl() - : OffscreenCanvasFrameDispatcherImpl(nullptr, 0, 0, 0, 10, 10) {} + MockOffscreenCanvasFrameDispatcher() + : OffscreenCanvasFrameDispatcher(nullptr, 0, 0, 0, {10, 10}) {} MOCK_METHOD2(PostImageToPlaceholder, void(scoped_refptr<StaticBitmapImage>, unsigned resource_id)); }; -class OffscreenCanvasFrameDispatcherImplTest : public testing::Test { +class OffscreenCanvasFrameDispatcherTest : public testing::Test { public: void DispatchOneFrame(); OffscreenCanvasResourceProvider* GetResourceProvider() { @@ -45,27 +46,25 @@ class OffscreenCanvasFrameDispatcherImplTest : public testing::Test { } protected: - OffscreenCanvasFrameDispatcherImplTest() { - dispatcher_ = std::make_unique<MockOffscreenCanvasFrameDispatcherImpl>(); + OffscreenCanvasFrameDispatcherTest() { + dispatcher_ = std::make_unique<MockOffscreenCanvasFrameDispatcher>(); } - MockOffscreenCanvasFrameDispatcherImpl* Dispatcher() { - return dispatcher_.get(); - } + MockOffscreenCanvasFrameDispatcher* Dispatcher() { return dispatcher_.get(); } private: scoped_refptr<StaticBitmapImage> PrepareStaticBitmapImage(); - std::unique_ptr<MockOffscreenCanvasFrameDispatcherImpl> dispatcher_; + std::unique_ptr<MockOffscreenCanvasFrameDispatcher> dispatcher_; }; -void OffscreenCanvasFrameDispatcherImplTest::DispatchOneFrame() { +void OffscreenCanvasFrameDispatcherTest::DispatchOneFrame() { sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10); dispatcher_->DispatchFrame( StaticBitmapImage::Create(surface->makeImageSnapshot()), 0.0, SkIRect::MakeEmpty()); } -TEST_F(OffscreenCanvasFrameDispatcherImplTest, PlaceholderRunsNormally) { +TEST_F(OffscreenCanvasFrameDispatcherTest, PlaceholderRunsNormally) { /* We allow OffscreenCanvas to post up to 3 frames without hearing a response * from placeholder. */ // Post first frame @@ -111,7 +110,7 @@ TEST_F(OffscreenCanvasFrameDispatcherImplTest, PlaceholderRunsNormally) { EXPECT_EQ(0u, GetNumUnreclaimedFramesPosted()); } -TEST_F(OffscreenCanvasFrameDispatcherImplTest, PlaceholderBeingBlocked) { +TEST_F(OffscreenCanvasFrameDispatcherTest, PlaceholderBeingBlocked) { /* When main thread is blocked, attempting to post more than 3 frames will * result in only 3 PostImageToPlaceholder. The latest unposted image will * be saved. */ 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 4fd962d917d..d46bf03849b 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 @@ -24,7 +24,7 @@ PlaceholderIdMap& placeholderRegistry() { void releaseFrameToDispatcher( base::WeakPtr<blink::OffscreenCanvasFrameDispatcher> dispatcher, scoped_refptr<blink::Image> oldImage, - unsigned resourceId) { + viz::ResourceId resourceId) { oldImage = nullptr; // Needed to unref'ed on the right thread if (dispatcher) { dispatcher->ReclaimResource(resourceId); @@ -74,7 +74,7 @@ void OffscreenCanvasPlaceholder::SetPlaceholderFrame( scoped_refptr<StaticBitmapImage> new_frame, base::WeakPtr<OffscreenCanvasFrameDispatcher> dispatcher, scoped_refptr<base::SingleThreadTaskRunner> task_runner, - unsigned resource_id) { + viz::ResourceId resource_id) { DCHECK(IsPlaceholderRegistered()); DCHECK(new_frame); ReleasePlaceholderFrame(); 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 37820d2a726..9db25c5ad8a 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 @@ -9,6 +9,7 @@ #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" +#include "components/viz/common/resources/resource_id.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { @@ -24,7 +25,7 @@ class PLATFORM_EXPORT OffscreenCanvasPlaceholder { scoped_refptr<StaticBitmapImage>, base::WeakPtr<OffscreenCanvasFrameDispatcher>, scoped_refptr<base::SingleThreadTaskRunner>, - unsigned resource_id); + viz::ResourceId resource_id); void ReleasePlaceholderFrame(); void SetSuspendOffscreenCanvasAnimation(bool); @@ -48,7 +49,7 @@ class PLATFORM_EXPORT OffscreenCanvasPlaceholder { scoped_refptr<StaticBitmapImage> placeholder_frame_; base::WeakPtr<OffscreenCanvasFrameDispatcher> frame_dispatcher_; scoped_refptr<base::SingleThreadTaskRunner> frame_dispatcher_task_runner_; - unsigned placeholder_frame_resource_id_ = 0; + viz::ResourceId placeholder_frame_resource_id_ = 0; enum { kNoPlaceholderId = -1, diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc index 4fd69838c42..8c140158bfd 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.cc @@ -4,12 +4,18 @@ #include "third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h" +#include "base/memory/shared_memory.h" #include "base/numerics/checked_math.h" +#include "components/viz/common/quads/shared_bitmap.h" +#include "components/viz/common/resources/bitmap_allocation.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "gpu/command_buffer/common/capabilities.h" +#include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.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/shared_gpu_context.h" +#include "third_party/blink/renderer/platform/graphics/offscreen_canvas_frame_dispatcher.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/typed_arrays/array_buffer.h" #include "third_party/blink/renderer/platform/wtf/typed_arrays/uint8_array.h" #include "third_party/khronos/GLES2/gl2.h" @@ -19,18 +25,35 @@ #include "third_party/skia/include/core/SkSwizzle.h" #include "third_party/skia/include/gpu/GrContext.h" +namespace { + +// TODO(danakj): One day the gpu::mojom::Mailbox type should be shared with +// blink directly and we won't need to use gpu::mojom::blink::Mailbox, nor the +// conversion through WTF::Vector. +gpu::mojom::blink::MailboxPtr SharedBitmapIdToGpuMailboxPtr( + const viz::SharedBitmapId& id) { + WTF::Vector<int8_t> name(GL_MAILBOX_SIZE_CHROMIUM); + for (int i = 0; i < GL_MAILBOX_SIZE_CHROMIUM; ++i) + name[i] = id.name[i]; + return {base::in_place, name}; +} + +} // namespace + namespace blink { -OffscreenCanvasResourceProvider::OffscreenCanvasResourceProvider(int width, - int height) - : width_(width), height_(height), next_resource_id_(0u) {} +OffscreenCanvasResourceProvider::OffscreenCanvasResourceProvider( + int width, + int height, + OffscreenCanvasFrameDispatcher* frame_dispatcher) + : frame_dispatcher_(frame_dispatcher), width_(width), height_(height) {} OffscreenCanvasResourceProvider::~OffscreenCanvasResourceProvider() = default; std::unique_ptr<OffscreenCanvasResourceProvider::FrameResource> OffscreenCanvasResourceProvider::CreateOrRecycleFrameResource() { if (recyclable_resource_) { - recyclable_resource_->spare_lock_ = true; + recyclable_resource_->spare_lock = true; return std::move(recyclable_resource_); } return std::make_unique<FrameResource>(); @@ -48,24 +71,27 @@ void OffscreenCanvasResourceProvider::TransferResource( resource->is_overlay_candidate = false; } -// TODO(xlai): Handle error cases when, by any reason, -// OffscreenCanvasResourceProvider fails to get image data. void OffscreenCanvasResourceProvider::SetTransferableResourceToSharedBitmap( viz::TransferableResource& resource, scoped_refptr<StaticBitmapImage> image) { std::unique_ptr<FrameResource> frame_resource = CreateOrRecycleFrameResource(); - if (!frame_resource->shared_bitmap_) { - frame_resource->shared_bitmap_ = Platform::Current()->AllocateSharedBitmap( - IntSize(width_, height_), viz::ResourceFormat::RGBA_8888); - if (!frame_resource->shared_bitmap_) - return; + if (!frame_resource->shared_memory) { + frame_resource->provider = this; + frame_resource->shared_bitmap_id = viz::SharedBitmap::GenerateId(); + frame_resource->shared_memory = + viz::bitmap_allocation::AllocateMappedBitmap(gfx::Size(width_, height_), + resource.format); + frame_dispatcher_->DidAllocateSharedBitmap( + viz::bitmap_allocation::DuplicateAndCloseMappedBitmap( + frame_resource->shared_memory.get(), gfx::Size(width_, height_), + resource.format), + SharedBitmapIdToGpuMailboxPtr(frame_resource->shared_bitmap_id)); } - unsigned char* pixels = frame_resource->shared_bitmap_->pixels(); + void* pixels = frame_resource->shared_memory->memory(); DCHECK(pixels); - // TODO(xlai): Optimize to avoid copying pixels. See crbug.com/651456. - // However, in the case when |image| is texture backed, this function call - // does a GPU readback which is required. + // When |image| is texture backed, this function does a GPU readback which is + // required. sk_sp<SkImage> sk_image = image->PaintImageForCurrentFrame().GetSkImage(); if (sk_image->bounds().isEmpty()) return; @@ -75,12 +101,19 @@ void OffscreenCanvasResourceProvider::SetTransferableResourceToSharedBitmap( sk_image->refColorSpace()); if (image_info.isEmpty()) return; + + if (RuntimeEnabledFeatures::CanvasColorManagementEnabled()) { + image_info = image_info.makeColorType(sk_image->colorType()); + } + + // TODO(junov): Optimize to avoid copying pixels for non-texture-backed + // sk_image. See crbug.com/651456. bool read_pixels_successful = sk_image->readPixels(image_info, pixels, image_info.minRowBytes(), 0, 0); DCHECK(read_pixels_successful); if (!read_pixels_successful) return; - resource.mailbox_holder.mailbox = frame_resource->shared_bitmap_->id(); + resource.mailbox_holder.mailbox = frame_resource->shared_bitmap_id; resource.mailbox_holder.texture_target = 0; resource.is_software = true; @@ -102,12 +135,11 @@ void OffscreenCanvasResourceProvider:: std::unique_ptr<FrameResource> frame_resource = CreateOrRecycleFrameResource(); - frame_resource->image_ = std::move(image); + frame_resource->provider = this; + frame_resource->image = std::move(image); resources_.insert(next_resource_id_, std::move(frame_resource)); } -OffscreenCanvasResourceProvider::FrameResource::~FrameResource() = default; - void OffscreenCanvasResourceProvider::ReclaimResources( const WTF::Vector<viz::ReturnedResource>& resources) { for (const auto& resource : resources) { @@ -117,9 +149,9 @@ void OffscreenCanvasResourceProvider::ReclaimResources( if (it == resources_.end()) continue; - if (it->value->image_ && it->value->image_->ContextProviderWrapper() && + if (it->value->image && it->value->image->ContextProviderWrapper() && resource.sync_token.HasData()) { - it->value->image_->ContextProviderWrapper() + it->value->image->ContextProviderWrapper() ->ContextProvider() ->ContextGL() ->WaitSyncTokenCHROMIUM(resource.sync_token.GetConstData()); @@ -137,15 +169,20 @@ void OffscreenCanvasResourceProvider::ReclaimResource(unsigned resource_id) { void OffscreenCanvasResourceProvider::ReclaimResourceInternal( const ResourceMap::iterator& it) { - if (it->value->spare_lock_) { - it->value->spare_lock_ = false; + if (it->value->spare_lock) { + it->value->spare_lock = false; } else { - // Really reclaim the resources + // Really reclaim the resources. recyclable_resource_ = std::move(it->value); - // release SkImage immediately since it is not recyclable - recyclable_resource_->image_ = nullptr; + // Release SkImage immediately since it is not recyclable. + recyclable_resource_->image = nullptr; resources_.erase(it); } } +OffscreenCanvasResourceProvider::FrameResource::~FrameResource() { + provider->frame_dispatcher_->DidDeleteSharedBitmap( + SharedBitmapIdToGpuMailboxPtr(shared_bitmap_id)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h index 16b1b81b253..b8932cb9cb9 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h +++ b/chromium/third_party/blink/renderer/platform/graphics/offscreen_canvas_resource_provider.h @@ -5,16 +5,34 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_RESOURCE_PROVIDER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_OFFSCREEN_CANVAS_RESOURCE_PROVIDER_H_ -#include "components/viz/common/quads/shared_bitmap.h" #include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/resources/transferable_resource.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" +namespace base { +class SharedMemory; +} + +namespace viz { +namespace mojom { +namespace blink { +class CompositorFrameSink; +} +} // namespace mojom +} // namespace viz + namespace blink { +class OffscreenCanvasFrameDispatcher; + class PLATFORM_EXPORT OffscreenCanvasResourceProvider { public: - OffscreenCanvasResourceProvider(int width, int height); + // The CompositorFrameSink given here must be kept alive as long as this + // class is, as it is used to free the software-backed resources in the + // display compositor. + OffscreenCanvasResourceProvider(int width, + int height, + OffscreenCanvasFrameDispatcher*); ~OffscreenCanvasResourceProvider(); @@ -33,31 +51,43 @@ class PLATFORM_EXPORT OffscreenCanvasResourceProvider { void Reshape(int width, int height) { width_ = width; height_ = height; + // TODO(junov): Prevent recycling resources of the wrong size. } private: - int width_; - int height_; - unsigned next_resource_id_; - struct FrameResource { - scoped_refptr<StaticBitmapImage> image_; - std::unique_ptr<viz::SharedBitmap> shared_bitmap_; - - bool spare_lock_ = true; - gpu::Mailbox mailbox_; - FrameResource() = default; ~FrameResource(); + + // TODO(junov): What does this do? + bool spare_lock = true; + + // Holds the backing for a gpu-backed resource. The Mailbox() of the image + // is given to the display compositor to present it. + scoped_refptr<StaticBitmapImage> image; + + // Holds the backing for a software-backed resource. + std::unique_ptr<base::SharedMemory> shared_memory; + // The id given to the display compositor to display a software-backed + // resource. + viz::SharedBitmapId shared_bitmap_id; + + // Back-pointer to the OffscreenCanvasResourceProvider. FrameResource does + // not outlive the provider. + OffscreenCanvasResourceProvider* provider = nullptr; }; - std::unique_ptr<FrameResource> recyclable_resource_; - std::unique_ptr<FrameResource> CreateOrRecycleFrameResource(); + using ResourceMap = HashMap<unsigned, std::unique_ptr<FrameResource>>; void SetNeedsBeginFrameInternal(); - - typedef HashMap<unsigned, std::unique_ptr<FrameResource>> ResourceMap; + std::unique_ptr<FrameResource> CreateOrRecycleFrameResource(); void ReclaimResourceInternal(const ResourceMap::iterator&); + + OffscreenCanvasFrameDispatcher* frame_dispatcher_; + int width_; + int height_; + unsigned next_resource_id_ = 0; + std::unique_ptr<FrameResource> recyclable_resource_; ResourceMap resources_; }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.cc index d3b15fecc71..0d64b57d11c 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/clip_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/skia/include/core/SkScalar.h" @@ -25,24 +25,35 @@ void ClipDisplayItem::Replay(GraphicsContext& context) const { context.ClipRoundedRect(rounded_rect); } -void ClipDisplayItem::AppendToWebDisplayItemList( - const FloatSize&, - WebDisplayItemList* list) const { - WebVector<SkRRect> web_rounded_rects(rounded_rect_clips_.size()); - for (size_t i = 0; i < rounded_rect_clips_.size(); ++i) - web_rounded_rects[i] = rounded_rect_clips_[i]; - - list->AppendClipItem(clip_rect_, web_rounded_rects); +void ClipDisplayItem::AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::SaveOp>(); + list.push<cc::ClipRectOp>(clip_rect_, SkClipOp::kIntersect, + /*antialias=*/true); + for (const FloatRoundedRect& rrect : rounded_rect_clips_) { + SkRRect skrrect = rrect; + if (skrrect.isRect()) { + list.push<cc::ClipRectOp>(skrrect.rect(), SkClipOp::kIntersect, + /*antialias=*/true); + } else { + list.push<cc::ClipRRectOp>(skrrect, SkClipOp::kIntersect, + /*antialias=*/true); + } + } + list.EndPaintOfPairedBegin(); } void EndClipDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndClipDisplayItem::AppendToWebDisplayItemList( +void EndClipDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndClipItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.h index d63595f08cf..006f66bc935 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_display_item.h @@ -33,8 +33,8 @@ class PLATFORM_EXPORT ClipDisplayItem final : public PairedBeginDisplayItem { } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() @@ -60,8 +60,8 @@ class PLATFORM_EXPORT EndClipDisplayItem final : public PairedEndDisplayItem { } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc index 8647c0c1c22..2f4ae851bbe 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.cc @@ -9,10 +9,11 @@ namespace blink { ClipPaintPropertyNode* ClipPaintPropertyNode::Root() { - DEFINE_STATIC_REF(ClipPaintPropertyNode, root, - (ClipPaintPropertyNode::Create( - nullptr, TransformPaintPropertyNode::Root(), - FloatRoundedRect(LayoutRect::InfiniteIntRect())))); + DEFINE_STATIC_REF( + ClipPaintPropertyNode, root, + (ClipPaintPropertyNode::Create( + nullptr, State{TransformPaintPropertyNode::Root(), + FloatRoundedRect(LayoutRect::InfiniteIntRect())}))); return root; } @@ -21,20 +22,30 @@ std::unique_ptr<JSONObject> ClipPaintPropertyNode::ToJSON() const { if (Parent()) json->SetString("parent", String::Format("%p", Parent())); json->SetString("localTransformSpace", - String::Format("%p", local_transform_space_.get())); - json->SetString("rect", clip_rect_.ToString()); - if (clip_rect_excluding_overlay_scrollbars_ != clip_rect_) { + String::Format("%p", state_.local_transform_space.get())); + json->SetString("rect", state_.clip_rect.ToString()); + if (state_.clip_rect_excluding_overlay_scrollbars) { json->SetString("rectExcludingOverlayScrollbars", - clip_rect_excluding_overlay_scrollbars_.ToString()); + state_.clip_rect_excluding_overlay_scrollbars->ToString()); } - if (clip_path_) { + if (state_.clip_path) { json->SetBoolean("hasClipPath", true); } - if (direct_compositing_reasons_ != CompositingReason::kNone) { - json->SetString("directCompositingReasons", - CompositingReason::ToString(direct_compositing_reasons_)); + if (state_.direct_compositing_reasons != CompositingReason::kNone) { + json->SetString( + "directCompositingReasons", + CompositingReason::ToString(state_.direct_compositing_reasons)); } return json; } +size_t ClipPaintPropertyNode::CacheMemoryUsageInBytes() const { + size_t total_bytes = sizeof(*this); + if (geometry_mapper_clip_cache_) + total_bytes += sizeof(*geometry_mapper_clip_cache_); + if (Parent()) + total_bytes += Parent()->CacheMemoryUsageInBytes(); + return total_bytes; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h index 20a4799929e..1702e55b189 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h @@ -5,15 +5,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_CLIP_PAINT_PROPERTY_NODE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_CLIP_PAINT_PROPERTY_NODE_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/geometry_mapper_clip_cache.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -#include <iosfwd> namespace blink { @@ -28,103 +26,98 @@ class GeometryMapperClipCache; class PLATFORM_EXPORT ClipPaintPropertyNode : public PaintPropertyNode<ClipPaintPropertyNode> { public: - // This node is really a sentinel, and does not represent a real clip - // space. + // To make it less verbose and more readable to construct and update a node, + // a struct with default values is used to represent the state. + struct State { + scoped_refptr<const TransformPaintPropertyNode> local_transform_space; + FloatRoundedRect clip_rect; + base::Optional<FloatRoundedRect> clip_rect_excluding_overlay_scrollbars; + scoped_refptr<const RefCountedPath> clip_path; + CompositingReasons direct_compositing_reasons = CompositingReason::kNone; + + // Returns true if the states are equal, ignoring the clip rect excluding + // overlay scrollbars which is only used for hit testing. + bool EqualIgnoringHitTestRects(const State& o) const { + return local_transform_space == o.local_transform_space && + clip_rect == o.clip_rect && + clip_path == o.clip_path && + direct_compositing_reasons == o.direct_compositing_reasons; + } + + bool operator==(const State& o) const { + if (!EqualIgnoringHitTestRects(o)) + return false; + return clip_rect_excluding_overlay_scrollbars == + o.clip_rect_excluding_overlay_scrollbars; + } + }; + + // This node is really a sentinel, and does not represent a real clip space. static ClipPaintPropertyNode* Root(); static scoped_refptr<ClipPaintPropertyNode> Create( scoped_refptr<const ClipPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - const FloatRoundedRect& clip_rect, - const FloatRoundedRect* clip_rect_excluding_overlay_scrollbars = nullptr, - scoped_refptr<const RefCountedPath> clip_path = nullptr, - CompositingReasons direct_compositing_reasons = - CompositingReason::kNone) { - return base::AdoptRef(new ClipPaintPropertyNode( - std::move(parent), std::move(local_transform_space), clip_rect, - clip_rect_excluding_overlay_scrollbars - ? *clip_rect_excluding_overlay_scrollbars - : clip_rect, - std::move(clip_path), direct_compositing_reasons)); + State&& state) { + return base::AdoptRef( + new ClipPaintPropertyNode(std::move(parent), std::move(state))); } - bool Update( - scoped_refptr<const ClipPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - const FloatRoundedRect& clip_rect, - const FloatRoundedRect* clip_rect_excluding_overlay_scrollbars = nullptr, - scoped_refptr<const RefCountedPath> clip_path = nullptr) { - bool parent_changed = PaintPropertyNode::Update(std::move(parent)); - - if (local_transform_space == local_transform_space_ && - clip_rect == clip_rect_ && - (!clip_rect_excluding_overlay_scrollbars || - *clip_rect_excluding_overlay_scrollbars == - clip_rect_excluding_overlay_scrollbars_) && - clip_path == clip_path_) + bool Update(scoped_refptr<const ClipPaintPropertyNode> parent, + State&& state) { + bool parent_changed = SetParent(parent); + if (state == state_) return parent_changed; SetChanged(); - local_transform_space_ = std::move(local_transform_space); - clip_rect_ = clip_rect; - clip_rect_excluding_overlay_scrollbars_ = - clip_rect_excluding_overlay_scrollbars - ? *clip_rect_excluding_overlay_scrollbars - : clip_rect; - clip_path_ = std::move(clip_path); + state_ = std::move(state); return true; } + bool EqualIgnoringHitTestRects( + scoped_refptr<const ClipPaintPropertyNode> parent, + const State& state) const { + return parent == Parent() && state_.EqualIgnoringHitTestRects(state); + } + const TransformPaintPropertyNode* LocalTransformSpace() const { - return local_transform_space_.get(); + return state_.local_transform_space.get(); } - const FloatRoundedRect& ClipRect() const { return clip_rect_; } + const FloatRoundedRect& ClipRect() const { return state_.clip_rect; } const FloatRoundedRect& ClipRectExcludingOverlayScrollbars() const { - return clip_rect_excluding_overlay_scrollbars_; + return state_.clip_rect_excluding_overlay_scrollbars + ? *state_.clip_rect_excluding_overlay_scrollbars + : state_.clip_rect; } - const RefCountedPath* ClipPath() const { return clip_path_.get(); } + const RefCountedPath* ClipPath() const { return state_.clip_path.get(); } + + bool HasDirectCompositingReasons() const { + return state_.direct_compositing_reasons != CompositingReason::kNone; + } #if DCHECK_IS_ON() // The clone function is used by FindPropertiesNeedingUpdate.h for recording // a clip node before it has been updated, to later detect changes. scoped_refptr<ClipPaintPropertyNode> Clone() const { - return base::AdoptRef(new ClipPaintPropertyNode( - Parent(), local_transform_space_, clip_rect_, clip_rect_, clip_path_, - direct_compositing_reasons_)); + return base::AdoptRef(new ClipPaintPropertyNode(Parent(), State(state_))); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking // if a clip node has changed. bool operator==(const ClipPaintPropertyNode& o) const { - return Parent() == o.Parent() && - local_transform_space_ == o.local_transform_space_ && - clip_rect_ == o.clip_rect_ && clip_path_ == o.clip_path_ && - direct_compositing_reasons_ == o.direct_compositing_reasons_; + return Parent() == o.Parent() && state_ == o.state_; } #endif std::unique_ptr<JSONObject> ToJSON() const; - bool HasDirectCompositingReasons() const { - return direct_compositing_reasons_ != CompositingReason::kNone; - } + // Returns memory usage of the clip cache of this node plus ancestors. + size_t CacheMemoryUsageInBytes() const; private: - ClipPaintPropertyNode( - scoped_refptr<const ClipPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - const FloatRoundedRect& clip_rect, - const FloatRoundedRect& clip_rect_excluding_overlay_scrollbars, - scoped_refptr<const RefCountedPath> clip_path, - CompositingReasons direct_compositing_reasons) - : PaintPropertyNode(std::move(parent)), - local_transform_space_(std::move(local_transform_space)), - clip_rect_(clip_rect), - clip_rect_excluding_overlay_scrollbars_( - clip_rect_excluding_overlay_scrollbars), - clip_path_(clip_path), - direct_compositing_reasons_(direct_compositing_reasons) {} + ClipPaintPropertyNode(scoped_refptr<const ClipPaintPropertyNode> parent, + State&& state) + : PaintPropertyNode(std::move(parent)), state_(std::move(state)) {} // For access to GetClipCache(); friend class GeometryMapper; @@ -140,12 +133,7 @@ class PLATFORM_EXPORT ClipPaintPropertyNode return *geometry_mapper_clip_cache_.get(); } - scoped_refptr<const TransformPaintPropertyNode> local_transform_space_; - FloatRoundedRect clip_rect_; - FloatRoundedRect clip_rect_excluding_overlay_scrollbars_; - scoped_refptr<const RefCountedPath> clip_path_; - CompositingReasons direct_compositing_reasons_; - + State state_; std::unique_ptr<GeometryMapperClipCache> geometry_mapper_clip_cache_; }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.cc index 2cd4a1a2530..ee7c9fe9f6b 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/skia/include/core/SkScalar.h" @@ -16,20 +16,26 @@ void BeginClipPathDisplayItem::Replay(GraphicsContext& context) const { context.ClipPath(clip_path_, kAntiAliased); } -void BeginClipPathDisplayItem::AppendToWebDisplayItemList( +void BeginClipPathDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendClipPathItem(clip_path_, true); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::SaveOp>(); + list.push<cc::ClipPathOp>(clip_path_, SkClipOp::kIntersect, + /*antialias=*/true); + list.EndPaintOfPairedBegin(); } void EndClipPathDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndClipPathDisplayItem::AppendToWebDisplayItemList( +void EndClipPathDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndClipPathItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h index 63f85f72ce6..b8ce24ab04d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/clip_path_display_item.h @@ -21,8 +21,8 @@ class PLATFORM_EXPORT BeginClipPathDisplayItem final clip_path_(clip_path.GetSkPath()) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() @@ -44,8 +44,8 @@ class PLATFORM_EXPORT EndClipPathDisplayItem final : PairedEndDisplayItem(client, kEndClipPath, sizeof(*this)) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.cc index 7c451e164e4..48b9c4f627b 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/compositing_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" @@ -15,14 +15,41 @@ void BeginCompositingDisplayItem::Replay(GraphicsContext& context) const { color_filter_); } -void BeginCompositingDisplayItem::AppendToWebDisplayItemList( +void BeginCompositingDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - SkRect bounds = bounds_; - list->AppendCompositingItem( - opacity_, xfer_mode_, has_bounds_ ? &bounds : nullptr, - GraphicsContext::WebCoreColorFilterToSkiaColorFilter(color_filter_) - .get()); + cc::DisplayItemList& list) const { + DCHECK_GE(opacity_, 0.f); + DCHECK_LE(opacity_, 1.f); + + // TODO(ajuma): This should really be rounding instead of flooring the alpha + // value, but that breaks slimming paint reftests. + auto alpha = static_cast<uint8_t>(gfx::ToFlooredInt(255 * opacity_)); + sk_sp<SkColorFilter> color_filter = + GraphicsContext::WebCoreColorFilterToSkiaColorFilter(color_filter_); + SkRect sk_bounds = bounds_; + SkRect* maybe_bounds = has_bounds_ ? &sk_bounds : nullptr; + + if (xfer_mode_ == SkBlendMode::kSrcOver && !color_filter) { + list.StartPaint(); + list.push<cc::SaveLayerAlphaOp>(maybe_bounds, alpha, false); + if (maybe_bounds) { + list.push<cc::ClipRectOp>(sk_bounds, SkClipOp::kIntersect, false); + } + list.EndPaintOfPairedBegin(); + return; + } + + cc::PaintFlags flags; + flags.setBlendMode(xfer_mode_); + flags.setAlpha(alpha); + flags.setColorFilter(std::move(color_filter)); + + list.StartPaint(); + list.push<cc::SaveLayerOp>(maybe_bounds, &flags); + if (maybe_bounds) { + list.push<cc::ClipRectOp>(sk_bounds, SkClipOp::kIntersect, false); + } + list.EndPaintOfPairedBegin(); } #if DCHECK_IS_ON() @@ -39,10 +66,12 @@ void EndCompositingDisplayItem::Replay(GraphicsContext& context) const { context.EndLayer(); } -void EndCompositingDisplayItem::AppendToWebDisplayItemList( +void EndCompositingDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndCompositingItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.h index ba7ca463fa9..fb2e26c413f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/compositing_display_item.h @@ -5,10 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_COMPOSITING_DISPLAY_ITEM_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_COMPOSITING_DISPLAY_ITEM_H_ -#include "third_party/blink/public/platform/web_blend_mode.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_types.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" +#include "third_party/skia/include/core/SkBlendMode.h" namespace blink { @@ -30,8 +30,8 @@ class PLATFORM_EXPORT BeginCompositingDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() @@ -66,8 +66,8 @@ class PLATFORM_EXPORT EndCompositingDisplayItem final : PairedEndDisplayItem(client, kEndCompositing, sizeof(*this)) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() 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 6cc1a24450c..7fd7f5ae3be 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 @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" +#include "cc/paint/display_item_list.h" + namespace blink { struct SameSizeAsDisplayItem { @@ -122,6 +124,8 @@ static String ForeignLayerTypeAsDebugString(DisplayItem::Type type) { DEBUG_STRING_CASE(ForeignLayerCanvas); DEBUG_STRING_CASE(ForeignLayerPlugin); DEBUG_STRING_CASE(ForeignLayerVideo); + DEBUG_STRING_CASE(ForeignLayerWrapper); + DEBUG_STRING_CASE(ForeignLayerContentsWrapper); DEFAULT_CASE; } } @@ -214,6 +218,12 @@ WTF::String DisplayItem::TypeAsDebugString(Type type) { DEBUG_STRING_CASE(EndTransform); DEBUG_STRING_CASE(BeginClipPath); DEBUG_STRING_CASE(EndClipPath); + DEBUG_STRING_CASE(LayerChunkBackground); + DEBUG_STRING_CASE(LayerChunkNegativeZOrderChildren); + DEBUG_STRING_CASE(LayerChunkDescendantBackgrounds); + DEBUG_STRING_CASE(LayerChunkFloat); + DEBUG_STRING_CASE(LayerChunkForeground); + DEBUG_STRING_CASE(LayerChunkNormalFlowAndPositiveZOrderChildren); 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 b56dfee069c..430a896e2f5 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 @@ -19,12 +19,15 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #endif +namespace cc { +class DisplayItemList; +} + namespace blink { class GraphicsContext; class FloatSize; enum class PaintPhase; -class WebDisplayItemList; class PLATFORM_EXPORT DisplayItem { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); @@ -116,7 +119,9 @@ class PLATFORM_EXPORT DisplayItem { kForeignLayerCanvas = kForeignLayerFirst, kForeignLayerPlugin, kForeignLayerVideo, - kForeignLayerLast = kForeignLayerVideo, + kForeignLayerWrapper, + kForeignLayerContentsWrapper, + kForeignLayerLast = kForeignLayerContentsWrapper, kClipFirst, kClipBoxPaintPhaseFirst = kClipFirst, @@ -182,6 +187,14 @@ class PLATFORM_EXPORT DisplayItem { kBeginClipPath, kEndClipPath, kScrollHitTest, + + kLayerChunkBackground, + kLayerChunkNegativeZOrderChildren, + kLayerChunkDescendantBackgrounds, + kLayerChunkFloat, + kLayerChunkForeground, + kLayerChunkNormalFlowAndPositiveZOrderChildren, + kUninitializedType, kTypeLast = kUninitializedType }; @@ -260,12 +273,12 @@ class PLATFORM_EXPORT DisplayItem { void SetSkippedCache() { skipped_cache_ = true; } bool SkippedCache() const { return skipped_cache_; } - // Appends this display item to the WebDisplayItemList, if applicable. + // Appends this display item to the cc::DisplayItemList, if applicable. // |visual_rect_offset| is the offset between the space of the GraphicsLayer // which owns the display item and the coordinate space of VisualRect(). // TODO(wangxianzhu): Remove the parameter for slimming paint v2. - virtual void AppendToWebDisplayItemList(const FloatSize& visual_rect_offset, - WebDisplayItemList*) const {} + virtual void AppendToDisplayItemList(const FloatSize& visual_rect_offset, + cc::DisplayItemList&) const {} // See comments of enum Type for usage of the following macros. #define DEFINE_CATEGORY_METHODS(Category) \ diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc index 613ccf3ef05..e26780fc64f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -18,14 +18,16 @@ void DrawingDisplayItem::Replay(GraphicsContext& context) const { context.DrawRecord(record_); } -void DrawingDisplayItem::AppendToWebDisplayItemList( +void DrawingDisplayItem::AppendToDisplayItemList( const FloatSize& visual_rect_offset, - WebDisplayItemList* list) const { + cc::DisplayItemList& list) const { if (record_) { + list.StartPaint(); + list.push<cc::DrawRecordOp>(record_); // Convert visual rect into the GraphicsLayer's coordinate space. auto visual_rect = VisualRect(); visual_rect.Move(-visual_rect_offset); - list->AppendDrawingItem(EnclosingIntRect(visual_rect), record_); + list.EndPaintOfUnpaired(EnclosingIntRect(visual_rect)); } } diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h index 22e55592f04..00cf611d07d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h @@ -34,8 +34,8 @@ class PLATFORM_EXPORT DrawingDisplayItem final : public DisplayItem { bool known_to_be_opaque); void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize& visual_rect_offset, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize& visual_rect_offset, + cc::DisplayItemList&) const override; bool DrawsContent() const override; const sk_sp<const PaintRecord>& GetPaintRecord() const { return record_; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item_test.cc index b2a78e582c7..319b420d613 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_display_item_test.cc @@ -4,13 +4,13 @@ #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" -#include "SkTypes.h" +#include "cc/paint/display_item_list.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_display_item_list.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h" #include "third_party/blink/renderer/platform/testing/fake_display_item_client.h" +#include "third_party/skia/include/core/SkTypes.h" namespace blink { namespace { @@ -22,12 +22,6 @@ class DrawingDisplayItemTest : public testing::Test { FakeDisplayItemClient client_; }; -class MockWebDisplayItemList : public WebDisplayItemList { - public: - MOCK_METHOD2(AppendDrawingItem, - void(const WebRect& visual_rect, sk_sp<const cc::PaintRecord>)); -}; - static sk_sp<PaintRecord> CreateRectRecord(const FloatRect& record_bounds) { PaintRecorder recorder; PaintCanvas* canvas = @@ -59,18 +53,17 @@ TEST_F(DrawingDisplayItemTest, VisualRectAndDrawingBounds) { CreateRectRecord(record_bounds)); EXPECT_EQ(FloatRect(drawing_bounds), item.VisualRect()); - MockWebDisplayItemList list1; - WebRect expected_rect = EnclosingIntRect(drawing_bounds); - EXPECT_CALL(list1, AppendDrawingItem(expected_rect, _)).Times(1); - item.AppendToWebDisplayItemList(FloatSize(), &list1); + auto list1 = base::MakeRefCounted<cc::DisplayItemList>(); + item.AppendToDisplayItemList(FloatSize(), *list1); + EXPECT_EQ(EnclosingIntRect(drawing_bounds), list1->VisualRectForTesting(0)); FloatSize offset(2.1, 3.6); + auto list2 = base::MakeRefCounted<cc::DisplayItemList>(); + item.AppendToDisplayItemList(offset, *list2); FloatRect visual_rect_with_offset(drawing_bounds); visual_rect_with_offset.Move(-offset); - WebRect expected_visual_rect = EnclosingIntRect(visual_rect_with_offset); - MockWebDisplayItemList list2; - EXPECT_CALL(list2, AppendDrawingItem(expected_visual_rect, _)).Times(1); - item.AppendToWebDisplayItemList(offset, &list2); + EXPECT_EQ(EnclosingIntRect(visual_rect_with_offset), + list2->VisualRectForTesting(0)); } TEST_F(DrawingDisplayItemTest, Equals) { diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h index 0addcf1e460..f4afbeff75d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/drawing_recorder.h @@ -7,13 +7,13 @@ #include "third_party/blink/renderer/platform/platform_export.h" +#include "base/auto_reset.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" namespace blink { @@ -80,7 +80,7 @@ class DisableListModificationCheck { DisableListModificationCheck(); private: - AutoReset<bool> disabler_; + base::AutoReset<bool> disabler_; }; #endif // DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc index c5277282c14..70852c21b84 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.cc @@ -7,20 +7,18 @@ namespace blink { EffectPaintPropertyNode* EffectPaintPropertyNode::Root() { - DEFINE_STATIC_REF( - EffectPaintPropertyNode, root, - (EffectPaintPropertyNode::Create( - nullptr, TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 1.0, SkBlendMode::kSrcOver))); + DEFINE_STATIC_REF(EffectPaintPropertyNode, root, + (EffectPaintPropertyNode::Create( + nullptr, State{TransformPaintPropertyNode::Root(), + ClipPaintPropertyNode::Root()}))); return root; } FloatRect EffectPaintPropertyNode::MapRect(const FloatRect& input_rect) const { FloatRect rect = input_rect; - rect.MoveBy(-paint_offset_); - FloatRect result = filter_.MapRect(rect); - result.MoveBy(paint_offset_); + rect.MoveBy(-state_.paint_offset); + FloatRect result = state_.filter.MapRect(rect); + result.MoveBy(state_.paint_offset); return result; } @@ -29,26 +27,27 @@ std::unique_ptr<JSONObject> EffectPaintPropertyNode::ToJSON() const { if (Parent()) json->SetString("parent", String::Format("%p", Parent())); json->SetString("localTransformSpace", - String::Format("%p", local_transform_space_.get())); - json->SetString("outputClip", String::Format("%p", output_clip_.get())); - if (color_filter_ != kColorFilterNone) - json->SetInteger("colorFilter", color_filter_); - if (!filter_.IsEmpty()) - json->SetString("filter", filter_.ToString()); - if (opacity_ != 1.0f) - json->SetDouble("opacity", opacity_); - if (blend_mode_ != SkBlendMode::kSrcOver) - json->SetString("blendMode", SkBlendMode_Name(blend_mode_)); - if (direct_compositing_reasons_ != CompositingReason::kNone) { - json->SetString("directCompositingReasons", - CompositingReason::ToString(direct_compositing_reasons_)); + String::Format("%p", state_.local_transform_space.get())); + json->SetString("outputClip", String::Format("%p", state_.output_clip.get())); + if (state_.color_filter != kColorFilterNone) + json->SetInteger("colorFilter", state_.color_filter); + if (!state_.filter.IsEmpty()) + json->SetString("filter", state_.filter.ToString()); + if (state_.opacity != 1.0f) + json->SetDouble("opacity", state_.opacity); + if (state_.blend_mode != SkBlendMode::kSrcOver) + json->SetString("blendMode", SkBlendMode_Name(state_.blend_mode)); + if (state_.direct_compositing_reasons != CompositingReason::kNone) { + json->SetString( + "directCompositingReasons", + CompositingReason::ToString(state_.direct_compositing_reasons)); } - if (compositor_element_id_) { + if (state_.compositor_element_id) { json->SetString("compositorElementId", - compositor_element_id_.ToString().c_str()); + state_.compositor_element_id.ToString().c_str()); } - if (paint_offset_ != FloatPoint()) - json->SetString("paintOffset", paint_offset_.ToString()); + if (state_.paint_offset != FloatPoint()) + json->SetString("paintOffset", state_.paint_offset.ToString()); return json; } 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 93980d76191..fea3860261a 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 @@ -13,10 +13,6 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -#include <iosfwd> namespace blink { @@ -28,172 +24,125 @@ namespace blink { class PLATFORM_EXPORT EffectPaintPropertyNode : public PaintPropertyNode<EffectPaintPropertyNode> { public: + // To make it less verbose and more readable to construct and update a node, + // a struct with default values is used to represent the state. + struct State { + // The local transform space serves two purposes: + // 1. Assign a depth mapping for 3D depth sorting against other paint chunks + // and effects under the same parent. + // 2. Some effects are spatial (namely blur filter and reflection), the + // effect parameters will be specified in the local space. + scoped_refptr<const TransformPaintPropertyNode> local_transform_space; + // The output of the effect can be optionally clipped when composited onto + // the current backdrop. + scoped_refptr<const ClipPaintPropertyNode> output_clip; + // Optionally a number of effects can be applied to the composited output. + // The chain of effects will be applied in the following order: + // === Begin of effects === + ColorFilter color_filter = kColorFilterNone; + CompositorFilterOperations filter; + float opacity = 1; + SkBlendMode blend_mode = SkBlendMode::kSrcOver; + // === End of effects === + CompositingReasons direct_compositing_reasons = CompositingReason::kNone; + CompositorElementId compositor_element_id; + // The offset of the effect's local space in m_localTransformSpace. Some + // effects e.g. reflection need this to apply geometry effects in the local + // space. + FloatPoint paint_offset = FloatPoint(); + + bool operator==(const State& o) const { + return local_transform_space == o.local_transform_space && + output_clip == o.output_clip && color_filter == o.color_filter && + filter == o.filter && opacity == o.opacity && + blend_mode == o.blend_mode && + direct_compositing_reasons == o.direct_compositing_reasons && + compositor_element_id == o.compositor_element_id && + paint_offset == o.paint_offset; + } + }; + // This node is really a sentinel, and does not represent a real effect. static EffectPaintPropertyNode* Root(); static scoped_refptr<EffectPaintPropertyNode> Create( scoped_refptr<const EffectPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - scoped_refptr<const ClipPaintPropertyNode> output_clip, - ColorFilter color_filter, - CompositorFilterOperations filter, - float opacity, - SkBlendMode blend_mode, - CompositingReasons direct_compositing_reasons = CompositingReason::kNone, - const CompositorElementId& compositor_element_id = CompositorElementId(), - const FloatPoint& paint_offset = FloatPoint()) { - return base::AdoptRef(new EffectPaintPropertyNode( - std::move(parent), std::move(local_transform_space), - std::move(output_clip), color_filter, std::move(filter), opacity, - blend_mode, direct_compositing_reasons, compositor_element_id, - paint_offset)); + State&& state) { + return base::AdoptRef( + new EffectPaintPropertyNode(std::move(parent), std::move(state))); } - bool Update( - scoped_refptr<const EffectPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - scoped_refptr<const ClipPaintPropertyNode> output_clip, - ColorFilter color_filter, - CompositorFilterOperations filter, - float opacity, - SkBlendMode blend_mode, - CompositingReasons direct_compositing_reasons = CompositingReason::kNone, - const CompositorElementId& compositor_element_id = CompositorElementId(), - const FloatPoint& paint_offset = FloatPoint()) { - bool parent_changed = PaintPropertyNode::Update(std::move(parent)); - - if (local_transform_space == local_transform_space_ && - output_clip == output_clip_ && color_filter == color_filter_ && - filter == filter_ && opacity == opacity_ && blend_mode == blend_mode_ && - (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || - (direct_compositing_reasons == direct_compositing_reasons_ && - compositor_element_id == compositor_element_id_)) && - paint_offset == paint_offset_) + bool Update(scoped_refptr<const EffectPaintPropertyNode> parent, + State&& state) { + bool parent_changed = SetParent(parent); + if (state == state_) return parent_changed; SetChanged(); - local_transform_space_ = std::move(local_transform_space); - output_clip_ = std::move(output_clip); - color_filter_ = color_filter; - filter_ = std::move(filter); - opacity_ = opacity; - blend_mode_ = blend_mode; - direct_compositing_reasons_ = direct_compositing_reasons; - compositor_element_id_ = compositor_element_id; - paint_offset_ = paint_offset; + state_ = std::move(state); return true; } const TransformPaintPropertyNode* LocalTransformSpace() const { - return local_transform_space_.get(); + return state_.local_transform_space.get(); + } + const ClipPaintPropertyNode* OutputClip() const { + return state_.output_clip.get(); } - const ClipPaintPropertyNode* OutputClip() const { return output_clip_.get(); } - SkBlendMode BlendMode() const { return blend_mode_; } - float Opacity() const { return opacity_; } - const CompositorFilterOperations& Filter() const { return filter_; } - ColorFilter GetColorFilter() const { return color_filter_; } + SkBlendMode BlendMode() const { return state_.blend_mode; } + float Opacity() const { return state_.opacity; } + const CompositorFilterOperations& Filter() const { return state_.filter; } + ColorFilter GetColorFilter() const { return state_.color_filter; } bool HasFilterThatMovesPixels() const { - return filter_.HasFilterThatMovesPixels(); + return state_.filter.HasFilterThatMovesPixels(); } - FloatPoint PaintOffset() const { return paint_offset_; } + FloatPoint PaintOffset() const { return state_.paint_offset; } // Returns a rect covering the pixels that can be affected by pixels in // |inputRect|. The rects are in the space of localTransformSpace. FloatRect MapRect(const FloatRect& input_rect) const; + bool HasDirectCompositingReasons() const { + return state_.direct_compositing_reasons != CompositingReason::kNone; + } + + bool RequiresCompositingForAnimation() const { + return state_.direct_compositing_reasons & + CompositingReason::kComboActiveAnimation; + } + + const CompositorElementId& GetCompositorElementId() const { + return state_.compositor_element_id; + } + #if DCHECK_IS_ON() // The clone function is used by FindPropertiesNeedingUpdate.h for recording // an effect node before it has been updated, to later detect changes. scoped_refptr<EffectPaintPropertyNode> Clone() const { - return base::AdoptRef(new EffectPaintPropertyNode( - Parent(), local_transform_space_, output_clip_, color_filter_, filter_, - opacity_, blend_mode_, direct_compositing_reasons_, - compositor_element_id_, paint_offset_)); + return base::AdoptRef(new EffectPaintPropertyNode(Parent(), State(state_))); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking - // if an effect node has changed. It ignores changes of reference filters - // because SkImageFilter doesn't have an equality operator. + // if an effect node has changed. bool operator==(const EffectPaintPropertyNode& o) const { - return Parent() == o.Parent() && - local_transform_space_ == o.local_transform_space_ && - output_clip_ == o.output_clip_ && color_filter_ == o.color_filter_ && - filter_ == o.filter_ && opacity_ == o.opacity_ && - blend_mode_ == o.blend_mode_ && - (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || - (direct_compositing_reasons_ == o.direct_compositing_reasons_ && - compositor_element_id_ == o.compositor_element_id_)) && - paint_offset_ == o.paint_offset_; + return Parent() == o.Parent() && state_ == o.state_; } #endif std::unique_ptr<JSONObject> ToJSON() const; - bool HasDirectCompositingReasons() const { - return direct_compositing_reasons_ != CompositingReason::kNone; - } - - bool RequiresCompositingForAnimation() const { - return direct_compositing_reasons_ & - CompositingReason::kComboActiveAnimation; - } - - const CompositorElementId& GetCompositorElementId() const { - return compositor_element_id_; - } + // Returns memory usage of this node plus ancestors. + size_t TreeMemoryUsageInBytes() const; private: - EffectPaintPropertyNode( - scoped_refptr<const EffectPaintPropertyNode> parent, - scoped_refptr<const TransformPaintPropertyNode> local_transform_space, - scoped_refptr<const ClipPaintPropertyNode> output_clip, - ColorFilter color_filter, - CompositorFilterOperations filter, - float opacity, - SkBlendMode blend_mode, - CompositingReasons direct_compositing_reasons, - CompositorElementId compositor_element_id, - const FloatPoint& paint_offset) - : PaintPropertyNode(std::move(parent)), - local_transform_space_(std::move(local_transform_space)), - output_clip_(std::move(output_clip)), - color_filter_(color_filter), - filter_(std::move(filter)), - opacity_(opacity), - blend_mode_(blend_mode), - direct_compositing_reasons_(direct_compositing_reasons), - compositor_element_id_(compositor_element_id), - paint_offset_(paint_offset) {} - - // The local transform space serves two purposes: - // 1. Assign a depth mapping for 3D depth sorting against other paint chunks - // and effects under the same parent. - // 2. Some effects are spatial (namely blur filter and reflection), the - // effect parameters will be specified in the local space. - scoped_refptr<const TransformPaintPropertyNode> local_transform_space_; - // The output of the effect can be optionally clipped when composited onto - // the current backdrop. - scoped_refptr<const ClipPaintPropertyNode> output_clip_; - - // Optionally a number of effects can be applied to the composited output. - // The chain of effects will be applied in the following order: - // === Begin of effects === - ColorFilter color_filter_; - CompositorFilterOperations filter_; - float opacity_; - SkBlendMode blend_mode_; - // === End of effects === - - CompositingReasons direct_compositing_reasons_; - CompositorElementId compositor_element_id_; - - // The offset of the effect's local space in m_localTransformSpace. Some - // effects e.g. reflection need this to apply geometry effects in the local - // space. - FloatPoint paint_offset_; + EffectPaintPropertyNode(scoped_refptr<const EffectPaintPropertyNode> parent, + State&& state) + : PaintPropertyNode(std::move(parent)), state_(std::move(state)) {} + + State state_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.cc index e1b0acd0078..88a5b4de076 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.cc @@ -4,8 +4,11 @@ #include "third_party/blink/renderer/platform/graphics/paint/filter_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" +#include "cc/paint/render_surface_filters.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" +#include "ui/gfx/geometry/point_f.h" +#include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -19,11 +22,28 @@ void BeginFilterDisplayItem::Replay(GraphicsContext& context) const { context.Translate(-origin_.X(), -origin_.Y()); } -void BeginFilterDisplayItem::AppendToWebDisplayItemList( +void BeginFilterDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendFilterItem(compositor_filter_operations_.AsCcFilterOperations(), - bounds_, origin_); + cc::DisplayItemList& list) const { + list.StartPaint(); + + // TODO(danakj): Skip the save+translate+restore if the origin is 0,0. This + // should be easier to do when this code is part of the blink DisplayItem + // which can keep related state. + list.push<cc::SaveOp>(); + list.push<cc::TranslateOp>(origin_.X(), origin_.Y()); + + cc::PaintFlags flags; + flags.setImageFilter(cc::RenderSurfaceFilters::BuildImageFilter( + compositor_filter_operations_.AsCcFilterOperations(), + static_cast<gfx::SizeF>(bounds_.Size()))); + + SkRect layer_bounds = bounds_; + layer_bounds.offset(-origin_.X(), -origin_.Y()); + list.push<cc::SaveLayerOp>(&layer_bounds, &flags); + list.push<cc::TranslateOp>(-origin_.X(), -origin_.Y()); + + list.EndPaintOfPairedBegin(EnclosingIntRect(bounds_)); } bool BeginFilterDisplayItem::DrawsContent() const { @@ -44,10 +64,13 @@ void EndFilterDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndFilterDisplayItem::AppendToWebDisplayItemList( +void EndFilterDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndFilterItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); // For SaveLayerOp. + list.push<cc::RestoreOp>(); // For SaveOp. + list.EndPaintOfPairedEnd(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.h index 160eb05a3ed..ce9bc179b4a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/filter_display_item.h @@ -28,8 +28,8 @@ class PLATFORM_EXPORT BeginFilterDisplayItem final origin_(origin) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; bool DrawsContent() const override; private: @@ -61,8 +61,8 @@ class PLATFORM_EXPORT EndFilterDisplayItem final : public PairedEndDisplayItem { : PairedEndDisplayItem(client, kEndFilter, sizeof(*this)) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.cc index 9818bc1e87c..6b6843efaaf 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.cc @@ -4,9 +4,10 @@ #include "third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/skia/include/core/SkScalar.h" +#include "ui/gfx/geometry/rect_f.h" namespace blink { @@ -15,20 +16,26 @@ void FloatClipDisplayItem::Replay(GraphicsContext& context) const { context.ClipRect(clip_rect_, kAntiAliased); } -void FloatClipDisplayItem::AppendToWebDisplayItemList( +void FloatClipDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendFloatClipItem(clip_rect_); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::SaveOp>(); + list.push<cc::ClipRectOp>(clip_rect_, SkClipOp::kIntersect, + /*antialias=*/true); + list.EndPaintOfPairedBegin(); } void EndFloatClipDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndFloatClipDisplayItem::AppendToWebDisplayItemList( +void EndFloatClipDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndFloatClipItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.h index 831955aba95..66f15e9edc3 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_display_item.h @@ -23,8 +23,8 @@ class PLATFORM_EXPORT FloatClipDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() @@ -48,8 +48,8 @@ class PLATFORM_EXPORT EndFloatClipDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h index a2eaac5b447..2272f7620e4 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h @@ -56,6 +56,21 @@ class PLATFORM_EXPORT FloatClipRect { ClearIsTight(); } + bool InclusiveIntersect(const FloatClipRect& other) { + bool retval = true; + if (is_infinite_) { + is_infinite_ = other.is_infinite_; + rect_ = other.rect_; + } else { + retval = rect_.InclusiveIntersect(other.Rect()); + } + if (other.HasRadius()) + SetHasRadius(); + else if (!other.IsTight()) + ClearIsTight(); + return retval; + } + bool HasRadius() const { return has_radius_; } void SetHasRadius() { has_radius_ = true; 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 3a06f64ede8..360913c2920 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 @@ -5,8 +5,8 @@ #include "third_party/blink/renderer/platform/graphics/paint/foreign_layer_display_item.h" #include <utility> + #include "cc/layers/layer.h" -#include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -23,7 +23,8 @@ ForeignLayerDisplayItem::ForeignLayerDisplayItem( layer_(std::move(layer)), location_(location), bounds_(bounds) { - DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled()); + DCHECK(RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || + RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()); DCHECK(IsForeignLayerType(type)); DCHECK(layer_); } @@ -34,9 +35,9 @@ void ForeignLayerDisplayItem::Replay(GraphicsContext&) const { NOTREACHED(); } -void ForeignLayerDisplayItem::AppendToWebDisplayItemList( +void ForeignLayerDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList*) const { + cc::DisplayItemList&) const { NOTREACHED(); } @@ -59,7 +60,7 @@ void ForeignLayerDisplayItem::PropertiesAsJSON(JSONObject& json) const { void RecordForeignLayer(GraphicsContext& context, const DisplayItemClient& client, DisplayItem::Type type, - WebLayer* web_layer, + scoped_refptr<cc::Layer> layer, const FloatPoint& location, const IntSize& bounds) { PaintController& paint_controller = context.GetPaintController(); @@ -67,7 +68,7 @@ void RecordForeignLayer(GraphicsContext& context, return; paint_controller.CreateAndAppend<ForeignLayerDisplayItem>( - client, type, web_layer->CcLayer(), location, bounds); + client, type, std::move(layer), location, bounds); } } // 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 b8dec3d94f6..b65bab8bd11 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 @@ -16,7 +16,6 @@ class Layer; namespace blink { class GraphicsContext; -class WebLayer; // 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 @@ -31,7 +30,7 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem { scoped_refptr<cc::Layer>, const FloatPoint& location, const IntSize& bounds); - ~ForeignLayerDisplayItem(); + ~ForeignLayerDisplayItem() override; cc::Layer* GetLayer() const { return layer_.get(); } const FloatPoint& Location() const { return location_; } @@ -39,8 +38,8 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem { // DisplayItem void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; bool DrawsContent() const override; bool Equals(const DisplayItem&) const override; #if DCHECK_IS_ON() @@ -58,7 +57,7 @@ class PLATFORM_EXPORT ForeignLayerDisplayItem final : public DisplayItem { PLATFORM_EXPORT void RecordForeignLayer(GraphicsContext&, const DisplayItemClient&, DisplayItem::Type, - WebLayer*, + scoped_refptr<cc::Layer>, const FloatPoint& location, const IntSize& bounds); diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc index efbba23f75f..fba18feb109 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.cc @@ -127,14 +127,16 @@ void GeometryMapper::SourceToDestinationRect( success ? source_to_destination.MapRect(mapping_rect) : FloatRect(); } -void GeometryMapper::LocalToAncestorVisualRect( +bool GeometryMapper::LocalToAncestorVisualRect( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect, - OverlayScrollbarClipBehavior clip_behavior) { + OverlayScrollbarClipBehavior clip_behavior, + InclusiveIntersectOrNot inclusive_behavior) { bool success = false; - LocalToAncestorVisualRectInternal(local_state, ancestor_state, mapping_rect, - clip_behavior, success); + return LocalToAncestorVisualRectInternal(local_state, ancestor_state, + mapping_rect, clip_behavior, + inclusive_behavior, success); DCHECK(success); } @@ -160,21 +162,22 @@ bool GeometryMapper::PointVisibleInAncestorSpace( return true; } -void GeometryMapper::LocalToAncestorVisualRectInternal( +bool GeometryMapper::LocalToAncestorVisualRectInternal( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& rect_to_map, OverlayScrollbarClipBehavior clip_behavior, + InclusiveIntersectOrNot inclusive_behavior, bool& success) { if (local_state == ancestor_state) { success = true; - return; + return true; } if (local_state.Effect() != ancestor_state.Effect()) { - SlowLocalToAncestorVisualRectWithEffects( - local_state, ancestor_state, rect_to_map, clip_behavior, success); - return; + return SlowLocalToAncestorVisualRectWithEffects( + local_state, ancestor_state, rect_to_map, clip_behavior, + inclusive_behavior, success); } const auto& transform_matrix = SourceToDestinationProjectionInternal( @@ -193,18 +196,20 @@ void GeometryMapper::LocalToAncestorVisualRectInternal( // Either way, the element won't be renderable thus returning empty rect. success = true; rect_to_map = FloatClipRect(FloatRect()); - return; + return false; } rect_to_map.Map(transform_matrix); FloatClipRect clip_rect = LocalToAncestorClipRectInternal( local_state.Clip(), ancestor_state.Clip(), ancestor_state.Transform(), - clip_behavior, success); + clip_behavior, inclusive_behavior, success); if (success) { // This is where we propagate the roundedness and tightness of |clip_rect| // to |rect_to_map|. + if (inclusive_behavior == kInclusiveIntersect) + return rect_to_map.InclusiveIntersect(clip_rect); rect_to_map.Intersect(clip_rect); - return; + return !rect_to_map.Rect().IsEmpty(); } if (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled()) { @@ -217,13 +222,15 @@ void GeometryMapper::LocalToAncestorVisualRectInternal( success = true; rect_to_map.ClearIsTight(); } + return !rect_to_map.Rect().IsEmpty(); } -void GeometryMapper::SlowLocalToAncestorVisualRectWithEffects( +bool GeometryMapper::SlowLocalToAncestorVisualRectWithEffects( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect, OverlayScrollbarClipBehavior clip_behavior, + InclusiveIntersectOrNot inclusive_behavior, bool& success) { PropertyTreeState last_transform_and_clip_state(local_state.Transform(), local_state.Clip(), nullptr); @@ -236,13 +243,13 @@ void GeometryMapper::SlowLocalToAncestorVisualRectWithEffects( DCHECK(effect->OutputClip()); PropertyTreeState transform_and_clip_state(effect->LocalTransformSpace(), effect->OutputClip(), nullptr); - LocalToAncestorVisualRectInternal(last_transform_and_clip_state, - transform_and_clip_state, mapping_rect, - clip_behavior, success); - if (!success) { + bool intersects = LocalToAncestorVisualRectInternal( + last_transform_and_clip_state, transform_and_clip_state, mapping_rect, + clip_behavior, inclusive_behavior, success); + if (!success || !intersects) { success = true; mapping_rect = FloatClipRect(FloatRect()); - return; + return false; } mapping_rect = FloatClipRect(effect->MapRect(mapping_rect.Rect())); @@ -251,12 +258,13 @@ void GeometryMapper::SlowLocalToAncestorVisualRectWithEffects( PropertyTreeState final_transform_and_clip_state( ancestor_state.Transform(), ancestor_state.Clip(), nullptr); - LocalToAncestorVisualRectInternal(last_transform_and_clip_state, - final_transform_and_clip_state, - mapping_rect, clip_behavior, success); + LocalToAncestorVisualRectInternal( + last_transform_and_clip_state, final_transform_and_clip_state, + mapping_rect, clip_behavior, inclusive_behavior, success); // Many effects (e.g. filters, clip-paths) can make a clip rect not tight. mapping_rect.ClearIsTight(); + return true; } FloatClipRect GeometryMapper::LocalToAncestorClipRect( @@ -269,7 +277,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRect( bool success = false; auto result = LocalToAncestorClipRectInternal( local_state.Clip(), ancestor_state.Clip(), ancestor_state.Transform(), - clip_behavior, success); + clip_behavior, kNonInclusiveIntersect, success); DCHECK(success); // Many effects (e.g. filters, clip-paths) can make a clip rect not tight. @@ -295,6 +303,7 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal( const ClipPaintPropertyNode* ancestor_clip, const TransformPaintPropertyNode* ancestor_transform, OverlayScrollbarClipBehavior clip_behavior, + InclusiveIntersectOrNot inclusive_behavior, bool& success) { if (descendant == ancestor_clip) { success = true; @@ -316,8 +325,12 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal( // Iterate over the path from localState.clip to ancestor_state.clip. Stop if // we've found a memoized (precomputed) clip for any particular node. while (clip_node && clip_node != ancestor_clip) { - if (const FloatClipRect* cached_clip = - clip_node->GetClipCache().GetCachedClip(clip_and_transform)) { + const FloatClipRect* cached_clip = nullptr; + // Inclusive intersected clips are not cached at present. + if (inclusive_behavior != kInclusiveIntersect) + cached_clip = clip_node->GetClipCache().GetCachedClip(clip_and_transform); + + if (cached_clip) { clip = *cached_clip; break; } @@ -357,12 +370,17 @@ FloatClipRect GeometryMapper::LocalToAncestorClipRectInternal( // from clip and transform properties, and propagate them to |clip|. FloatClipRect mapped_rect(GetClipRect((*it), clip_behavior)); mapped_rect.Map(transform_matrix); - clip.Intersect(mapped_rect); - - (*it)->GetClipCache().SetCachedClip(clip_and_transform, clip); + if (inclusive_behavior == kInclusiveIntersect) { + clip.InclusiveIntersect(mapped_rect); + } else { + clip.Intersect(mapped_rect); + // Inclusive intersected clips are not cached at present. + (*it)->GetClipCache().SetCachedClip(clip_and_transform, clip); + } } - - DCHECK(*descendant->GetClipCache().GetCachedClip(clip_and_transform) == clip); + // Inclusive intersected clips are not cached at present. + DCHECK(inclusive_behavior == kInclusiveIntersect || + *descendant->GetClipCache().GetCachedClip(clip_and_transform) == clip); success = true; return clip; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h index 6d23bbd2c51..e4a0637fd38 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper.h @@ -5,16 +5,19 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GEOMETRY_MAPPER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_GEOMETRY_MAPPER_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/graphics/paint/float_clip_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { class TransformationMatrix; +// Clips can use FloatRect::Intersect or FloatRect::InclusiveIntersect. +enum InclusiveIntersectOrNot { kNonInclusiveIntersect, kInclusiveIntersect }; + // GeometryMapper is a helper class for fast computations of transformed and // visual rects in different PropertyTreeStates. The design document has a // number of details on use cases, algorithmic definitions, and running times. @@ -28,8 +31,6 @@ class TransformationMatrix; // If needed, callers must store local copies of the return values. // // Design document: http://bit.ly/28P4FDA -// -// TODO(chrishtr): take effect tree into account. class PLATFORM_EXPORT GeometryMapper { STATIC_ONLY(GeometryMapper); @@ -67,6 +68,7 @@ class PLATFORM_EXPORT GeometryMapper { // The output FloatClipRect may contain false positives for rounded-ness // if a rounded clip is clipped out, and overly conservative results // in the presences of transforms. + static FloatClipRect LocalToAncestorClipRect( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, @@ -92,11 +94,27 @@ class PLATFORM_EXPORT GeometryMapper { // The output FloatClipRect may contain false positives for rounded-ness // if a rounded clip is clipped out, and overly conservative results // in the presences of transforms. - static void LocalToAncestorVisualRect( + // + // Returns true if the mapped rect is non-empty. (Note: this has special + // meaning in the presence of inclusive intersection.) + // + // Note: if inclusive intersection is specified, then the + // GeometryMapperClipCache is bypassed (the GeometryMapperTRansformCache is + // still used, however). + // + // If kInclusiveIntersect is set, clipping operations will + // use FloatRect::InclusiveIntersect, and the return value of + // InclusiveIntersect will be propagated to the return value of this method. + // Otherwise, clipping operations will use LayoutRect::intersect, and the + // return value will be true only if the clipped rect has non-zero area. + // See the documentation for FloatRect::InclusiveIntersect for more + // information. + static bool LocalToAncestorVisualRect( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect, - OverlayScrollbarClipBehavior = kIgnorePlatformOverlayScrollbarSize); + OverlayScrollbarClipBehavior = kIgnorePlatformOverlayScrollbarSize, + InclusiveIntersectOrNot = kNonInclusiveIntersect); // Returns true if |local_rect| is *not* clipped out by any clips // between |local_state| and |ancestor_state|. This includes not just @@ -127,20 +145,27 @@ class PLATFORM_EXPORT GeometryMapper { const ClipPaintPropertyNode* ancestor_clip, const TransformPaintPropertyNode* ancestor_transform, OverlayScrollbarClipBehavior, + InclusiveIntersectOrNot, bool& success); - static void LocalToAncestorVisualRectInternal( + // The return value has the same meaning as that for + // LocalToAncestorVisualRect. + static bool LocalToAncestorVisualRectInternal( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect, OverlayScrollbarClipBehavior, + InclusiveIntersectOrNot, bool& success); - static void SlowLocalToAncestorVisualRectWithEffects( + // The return value has the same meaning as that for + // LocalToAncestorVisualRect. + static bool SlowLocalToAncestorVisualRectWithEffects( const PropertyTreeState& local_state, const PropertyTreeState& ancestor_state, FloatClipRect& mapping_rect, OverlayScrollbarClipBehavior, + InclusiveIntersectOrNot, bool& success); friend class GeometryMapperTest; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc index 42f1e3d3bb5..58e7eac21bf 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/geometry_mapper_test.cc @@ -37,7 +37,7 @@ class GeometryMapperTest : public testing::Test, bool& success) { GeometryMapper::LocalToAncestorVisualRectInternal( local_state, ancestor_state, mapping_rect, - kIgnorePlatformOverlayScrollbarSize, success); + kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect, success); } // Variables required by CHECK_MAPPINGS(). The tests should set these @@ -51,9 +51,7 @@ class GeometryMapperTest : public testing::Test, FloatRect expected_transformed_rect; }; -INSTANTIATE_TEST_CASE_P(All, - GeometryMapperTest, - testing::ValuesIn(kSlimmingPaintVersions)); +INSTANTIATE_PAINT_TEST_CASE_P(GeometryMapperTest); #define EXPECT_FLOAT_RECT_NEAR(expected, actual) \ do { \ @@ -159,9 +157,8 @@ TEST_P(GeometryMapperTest, Root) { } TEST_P(GeometryMapperTest, IdentityTransform) { - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix(), - FloatPoint3D()); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix()); local_state.SetTransform(transform.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -172,8 +169,8 @@ TEST_P(GeometryMapperTest, IdentityTransform) { TEST_P(GeometryMapperTest, TranslationTransform) { expected_transform = TransformationMatrix().Translate(20, 10); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, FloatPoint3D()); + auto transform = + CreateTransform(TransformPaintPropertyNode::Root(), expected_transform); local_state.SetTransform(transform.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -189,9 +186,8 @@ TEST_P(GeometryMapperTest, TranslationTransform) { TEST_P(GeometryMapperTest, RotationAndScaleTransform) { expected_transform = TransformationMatrix().Rotate(45).Scale(2); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, - FloatPoint3D(0, 0, 0)); + auto transform = + CreateTransform(TransformPaintPropertyNode::Root(), expected_transform); local_state.SetTransform(transform.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -203,9 +199,8 @@ TEST_P(GeometryMapperTest, RotationAndScaleTransform) { TEST_P(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) { expected_transform = TransformationMatrix().Rotate(45).Scale(2); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, - FloatPoint3D(50, 50, 0)); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + expected_transform, FloatPoint3D(50, 50, 0)); local_state.SetTransform(transform.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -218,12 +213,11 @@ TEST_P(GeometryMapperTest, RotationAndScaleTransformWithTransformOrigin) { TEST_P(GeometryMapperTest, NestedTransforms) { auto rotate_transform = TransformationMatrix().Rotate(45); - auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform, FloatPoint3D()); + auto transform1 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform); auto scale_transform = TransformationMatrix().Scale(2); - auto transform2 = TransformPaintPropertyNode::Create( - transform1, scale_transform, FloatPoint3D()); + auto transform2 = CreateTransform(transform1, scale_transform); local_state.SetTransform(transform2.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -235,19 +229,22 @@ TEST_P(GeometryMapperTest, NestedTransforms) { } TEST_P(GeometryMapperTest, NestedTransformsFlattening) { - auto rotate_transform = TransformationMatrix().Rotate3d(45, 0, 0); + TransformPaintPropertyNode::State rotate_transform; + rotate_transform.matrix.Rotate3d(45, 0, 0); auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform, FloatPoint3D()); + TransformPaintPropertyNode::Root(), std::move(rotate_transform)); - auto inverse_rotate_transform = TransformationMatrix().Rotate3d(-45, 0, 0); + TransformPaintPropertyNode::State inverse_rotate_transform; + inverse_rotate_transform.matrix.Rotate3d(-45, 0, 0); + inverse_rotate_transform.flattens_inherited_transform = true; auto transform2 = TransformPaintPropertyNode::Create( - transform1, inverse_rotate_transform, FloatPoint3D(), - true); // Flattens + transform1, std::move(inverse_rotate_transform)); local_state.SetTransform(transform2.get()); input_rect = FloatRect(0, 0, 100, 100); - rotate_transform.FlattenTo2d(); - expected_transform = rotate_transform * inverse_rotate_transform; + rotate_transform.matrix.FlattenTo2d(); + expected_transform = + rotate_transform.matrix * inverse_rotate_transform.matrix; expected_transform.FlattenTo2d(); expected_transformed_rect = expected_transform.MapRect(input_rect); expected_visual_rect = FloatClipRect(expected_transformed_rect); @@ -257,12 +254,11 @@ TEST_P(GeometryMapperTest, NestedTransformsFlattening) { TEST_P(GeometryMapperTest, NestedTransformsScaleAndTranslation) { auto scale_transform = TransformationMatrix().Scale(2); - auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), scale_transform, FloatPoint3D()); + auto transform1 = + CreateTransform(TransformPaintPropertyNode::Root(), scale_transform); auto translate_transform = TransformationMatrix().Translate(100, 0); - auto transform2 = TransformPaintPropertyNode::Create( - transform1, translate_transform, FloatPoint3D()); + auto transform2 = CreateTransform(transform1, translate_transform); local_state.SetTransform(transform2.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -277,12 +273,11 @@ TEST_P(GeometryMapperTest, NestedTransformsScaleAndTranslation) { TEST_P(GeometryMapperTest, NestedTransformsIntermediateDestination) { auto rotate_transform = TransformationMatrix().Rotate(45); - auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform, FloatPoint3D()); + auto transform1 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform); auto scale_transform = TransformationMatrix().Translate(10, 20); - auto transform2 = TransformPaintPropertyNode::Create( - transform1, scale_transform, FloatPoint3D()); + auto transform2 = CreateTransform(transform1, scale_transform); local_state.SetTransform(transform2.get()); ancestor_state.SetTransform(transform1.get()); @@ -295,9 +290,9 @@ TEST_P(GeometryMapperTest, NestedTransformsIntermediateDestination) { } TEST_P(GeometryMapperTest, SimpleClip) { - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 50, 50)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 10, 50, 50)); local_state.SetClip(clip.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -308,10 +303,13 @@ TEST_P(GeometryMapperTest, SimpleClip) { } TEST_P(GeometryMapperTest, SimpleClipOverlayScrollbars) { - FloatRoundedRect rect_without_overlay_scrollbars(10, 10, 45, 43); - auto clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 50, 50), &rect_without_overlay_scrollbars); + ClipPaintPropertyNode::State clip_state; + clip_state.local_transform_space = TransformPaintPropertyNode::Root(); + clip_state.clip_rect = FloatRoundedRect(10, 10, 50, 50); + clip_state.clip_rect_excluding_overlay_scrollbars = + FloatRoundedRect(10, 10, 45, 43); + auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), + std::move(clip_state)); local_state.SetClip(clip.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -345,12 +343,37 @@ TEST_P(GeometryMapperTest, SimpleClipOverlayScrollbars) { actual_clip_rect); } +TEST_P(GeometryMapperTest, SimpleClipInclusiveIntersect) { + ClipPaintPropertyNode::State clip_state; + clip_state.local_transform_space = TransformPaintPropertyNode::Root(); + clip_state.clip_rect = FloatRoundedRect(10, 10, 50, 50); + auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), + std::move(clip_state)); + + local_state.SetClip(clip.get()); + + FloatClipRect actual_clip_rect(FloatRect(60, 10, 10, 10)); + GeometryMapper::LocalToAncestorVisualRect( + local_state, ancestor_state, actual_clip_rect, + kIgnorePlatformOverlayScrollbarSize, kInclusiveIntersect); + EXPECT_CLIP_RECT_EQ(FloatClipRect(FloatRect(60, 10, 0, 10)), + actual_clip_rect); + + // Check that not passing kExcludeOverlayScrollbarSizeForHitTesting gives + // a different result. + actual_clip_rect.SetRect(FloatRect(60, 10, 10, 10)); + GeometryMapper::LocalToAncestorVisualRect( + local_state, ancestor_state, actual_clip_rect, + kIgnorePlatformOverlayScrollbarSize, kNonInclusiveIntersect); + EXPECT_CLIP_RECT_EQ(FloatClipRect(FloatRect()), actual_clip_rect); +} + TEST_P(GeometryMapperTest, RoundedClip) { FloatRoundedRect rect(FloatRect(10, 10, 50, 50), FloatRoundedRect::Radii(FloatSize(1, 1), FloatSize(), FloatSize(), FloatSize())); - auto clip = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), rect); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), rect); local_state.SetClip(clip.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -384,13 +407,11 @@ TEST_P(GeometryMapperTest, TwoClips) { FloatRoundedRect::Radii(FloatSize(1, 1), FloatSize(), FloatSize(), FloatSize())); - auto clip1 = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - clip_rect1); + auto clip1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), clip_rect1); - auto clip2 = - ClipPaintPropertyNode::Create(clip1, TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 50, 50)); + auto clip2 = CreateClip(clip1, TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 10, 50, 50)); local_state.SetClip(clip2.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -407,20 +428,19 @@ TEST_P(GeometryMapperTest, TwoClips) { } TEST_P(GeometryMapperTest, TwoClipsTransformAbove) { - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), TransformationMatrix(), - FloatPoint3D()); + auto transform = CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix()); FloatRoundedRect clip_rect1( FloatRect(10, 10, 50, 50), FloatRoundedRect::Radii(FloatSize(1, 1), FloatSize(), FloatSize(), FloatSize())); - auto clip1 = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - transform.get(), clip_rect1); + auto clip1 = + CreateClip(ClipPaintPropertyNode::Root(), transform.get(), clip_rect1); - auto clip2 = ClipPaintPropertyNode::Create(clip1, transform.get(), - FloatRoundedRect(10, 10, 30, 40)); + auto clip2 = + CreateClip(clip1, transform.get(), FloatRoundedRect(10, 10, 30, 40)); local_state.SetClip(clip2.get()); input_rect = FloatRect(0, 0, 100, 100); @@ -439,11 +459,10 @@ TEST_P(GeometryMapperTest, TwoClipsTransformAbove) { TEST_P(GeometryMapperTest, ClipBeforeTransform) { expected_transform = TransformationMatrix().Rotate(45); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, FloatPoint3D()); - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - transform.get(), - FloatRoundedRect(10, 10, 50, 50)); + auto transform = + CreateTransform(TransformPaintPropertyNode::Root(), expected_transform); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), transform.get(), + FloatRoundedRect(10, 10, 50, 50)); local_state.SetClip(clip.get()); local_state.SetTransform(transform.get()); @@ -461,11 +480,11 @@ TEST_P(GeometryMapperTest, ClipBeforeTransform) { TEST_P(GeometryMapperTest, ClipAfterTransform) { expected_transform = TransformationMatrix().Rotate(45); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, FloatPoint3D()); - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 200, 200)); + auto transform = + CreateTransform(TransformPaintPropertyNode::Root(), expected_transform); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 10, 200, 200)); local_state.SetClip(clip.get()); local_state.SetTransform(transform.get()); @@ -481,16 +500,16 @@ TEST_P(GeometryMapperTest, ClipAfterTransform) { } TEST_P(GeometryMapperTest, TwoClipsWithTransformBetween) { - auto clip1 = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 200, 200)); + auto clip1 = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 10, 200, 200)); expected_transform = TransformationMatrix().Rotate(45); - auto transform = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), expected_transform, FloatPoint3D()); + auto transform = + CreateTransform(TransformPaintPropertyNode::Root(), expected_transform); - auto clip2 = ClipPaintPropertyNode::Create( - clip1, transform.get(), FloatRoundedRect(10, 10, 200, 200)); + auto clip2 = + CreateClip(clip1, transform.get(), FloatRoundedRect(10, 10, 200, 200)); input_rect = FloatRect(0, 0, 100, 100); expected_transformed_rect = expected_transform.MapRect(input_rect); @@ -534,12 +553,12 @@ TEST_P(GeometryMapperTest, SiblingTransforms) { // These transforms are siblings. Thus mapping from one to the other requires // going through the root. auto rotate_transform1 = TransformationMatrix().Rotate(45); - auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform1, FloatPoint3D()); + auto transform1 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform1); auto rotate_transform2 = TransformationMatrix().Rotate(-45); - auto transform2 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform2, FloatPoint3D()); + auto transform2 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform2); auto transform1_state = PropertyTreeState::Root(); transform1_state.SetTransform(transform1.get()); @@ -578,16 +597,15 @@ TEST_P(GeometryMapperTest, SiblingTransformsWithClip) { // These transforms are siblings. Thus mapping from one to the other requires // going through the root. auto rotate_transform1 = TransformationMatrix().Rotate(45); - auto transform1 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform1, FloatPoint3D()); + auto transform1 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform1); auto rotate_transform2 = TransformationMatrix().Rotate(-45); - auto transform2 = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), rotate_transform2, FloatPoint3D()); + auto transform2 = + CreateTransform(TransformPaintPropertyNode::Root(), rotate_transform2); - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - transform2.get(), - FloatRoundedRect(10, 20, 30, 40)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), transform2.get(), + FloatRoundedRect(10, 20, 30, 40)); auto transform1_state = PropertyTreeState::Root(); transform1_state.SetTransform(transform1.get()); @@ -623,27 +641,25 @@ TEST_P(GeometryMapperTest, SiblingTransformsWithClip) { } TEST_P(GeometryMapperTest, FilterWithClipsAndTransforms) { - auto transform_above_effect = TransformPaintPropertyNode::Create( - TransformPaintPropertyNode::Root(), - TransformationMatrix().Translate(40, 50), FloatPoint3D()); - auto transform_below_effect = TransformPaintPropertyNode::Create( - transform_above_effect, TransformationMatrix().Translate(20, 30), - FloatPoint3D()); + auto transform_above_effect = + CreateTransform(TransformPaintPropertyNode::Root(), + TransformationMatrix().Translate(40, 50)); + auto transform_below_effect = CreateTransform( + transform_above_effect, TransformationMatrix().Translate(20, 30)); // This clip is between transformAboveEffect and the effect. - auto clip_above_effect = ClipPaintPropertyNode::Create( - ClipPaintPropertyNode::Root(), transform_above_effect, - FloatRoundedRect(-100, -100, 200, 200)); + auto clip_above_effect = + CreateClip(ClipPaintPropertyNode::Root(), transform_above_effect, + FloatRoundedRect(-100, -100, 200, 200)); // This clip is between the effect and transformBelowEffect. - auto clip_below_effect = - ClipPaintPropertyNode::Create(clip_above_effect, transform_above_effect, - FloatRoundedRect(10, 10, 100, 100)); + auto clip_below_effect = CreateClip(clip_above_effect, transform_above_effect, + FloatRoundedRect(10, 10, 100, 100)); CompositorFilterOperations filters; filters.AppendBlurFilter(20); - auto effect = EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), transform_above_effect, - clip_above_effect, kColorFilterNone, filters, 1.0, SkBlendMode::kSrcOver); + auto effect = + CreateFilterEffect(EffectPaintPropertyNode::Root(), + transform_above_effect, clip_above_effect, filters); local_state = PropertyTreeState(transform_below_effect.get(), clip_below_effect.get(), effect.get()); @@ -678,11 +694,8 @@ TEST_P(GeometryMapperTest, ReflectionWithPaintOffset) { CompositorFilterOperations filters; filters.AppendReferenceFilter(PaintFilterBuilder::BuildBoxReflectFilter( BoxReflection(BoxReflection::kHorizontalReflection, 0), nullptr)); - auto effect = EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, filters, 1.0, - SkBlendMode::kSrcOver, CompositingReason::kNone, CompositorElementId(), - FloatPoint(100, 100)); + auto effect = CreateFilterEffect(EffectPaintPropertyNode::Root(), filters, + FloatPoint(100, 100)); local_state.SetEffect(effect.get()); input_rect = FloatRect(100, 100, 50, 50); @@ -698,9 +711,9 @@ TEST_P(GeometryMapperTest, InvertedClip) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) return; - auto clip = ClipPaintPropertyNode::Create(ClipPaintPropertyNode::Root(), - TransformPaintPropertyNode::Root(), - FloatRoundedRect(10, 10, 50, 50)); + auto clip = CreateClip(ClipPaintPropertyNode::Root(), + TransformPaintPropertyNode::Root(), + FloatRoundedRect(10, 10, 50, 50)); PropertyTreeState dest(TransformPaintPropertyNode::Root(), clip.get(), EffectPaintPropertyNode::Root()); diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h new file mode 100644 index 00000000000..48d154d8fca --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/hit_test_data.h @@ -0,0 +1,41 @@ +// 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_GRAPHICS_PAINT_HIT_TEST_DATA_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DATA_H_ + +#include "third_party/blink/renderer/platform/geometry/float_rect.h" +#include "third_party/blink/renderer/platform/geometry/region.h" +#include "third_party/blink/renderer/platform/graphics/touch_action_rect.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +struct PLATFORM_EXPORT HitTestData { + FloatRect border_rect; + TouchActionRect touch_action_rect = + TouchActionRect(LayoutRect(), cc::kTouchActionNone); + Region wheel_event_handler_region; + Region non_fast_scrollable_region; + + HitTestData() = default; + HitTestData(const HitTestData& other) + : border_rect(other.border_rect), + touch_action_rect(other.touch_action_rect), + wheel_event_handler_region(other.wheel_event_handler_region), + non_fast_scrollable_region(other.non_fast_scrollable_region) {} + + bool operator==(const HitTestData& rhs) const { + return border_rect == rhs.border_rect && + touch_action_rect == rhs.touch_action_rect && + wheel_event_handler_region == rhs.wheel_event_handler_region && + non_fast_scrollable_region == rhs.non_fast_scrollable_region; + } + + bool operator!=(const HitTestData& rhs) const { return !(*this == rhs); } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_HIT_TEST_DATA_H_ diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc index acab9ab196b..bc8a9648f61 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "cc/paint/display_item_list.h" -#include "third_party/blink/public/platform/web_display_item_list.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/graphics/compositing/paint_chunks_to_cc_layer.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" @@ -20,6 +19,10 @@ namespace { void ComputeChunkBoundsAndOpaqueness(const DisplayItemList& display_items, Vector<PaintChunk>& paint_chunks) { + // This happens in tests testing paint chunks without display items. + if (display_items.IsEmpty()) + return; + for (PaintChunk& chunk : paint_chunks) { FloatRect bounds; SkRegion known_to_be_opaque_region; @@ -46,33 +49,43 @@ void ComputeChunkBoundsAndOpaqueness(const DisplayItemList& display_items, PaintArtifact::PaintArtifact() : display_item_list_(0) {} PaintArtifact::PaintArtifact(DisplayItemList display_items, - Vector<PaintChunk> paint_chunks) + PaintChunksAndRasterInvalidations data) : display_item_list_(std::move(display_items)), - paint_chunks_(std::move(paint_chunks)) { - if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) - ComputeChunkBoundsAndOpaqueness(display_item_list_, paint_chunks_); + chunks_and_invalidations_(std::move(data)) { + if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { + ComputeChunkBoundsAndOpaqueness(display_item_list_, + chunks_and_invalidations_.chunks); + } } PaintArtifact::PaintArtifact(PaintArtifact&& source) : display_item_list_(std::move(source.display_item_list_)), - paint_chunks_(std::move(source.paint_chunks_)) {} + chunks_and_invalidations_(std::move(source.chunks_and_invalidations_)) {} PaintArtifact::~PaintArtifact() = default; PaintArtifact& PaintArtifact::operator=(PaintArtifact&& source) { display_item_list_ = std::move(source.display_item_list_); - paint_chunks_ = std::move(source.paint_chunks_); + chunks_and_invalidations_ = std::move(source.chunks_and_invalidations_); return *this; } void PaintArtifact::Reset() { display_item_list_.Clear(); - paint_chunks_.clear(); + chunks_and_invalidations_.Clear(); } size_t PaintArtifact::ApproximateUnsharedMemoryUsage() const { - return sizeof(*this) + display_item_list_.MemoryUsageInBytes() + - paint_chunks_.capacity() * sizeof(paint_chunks_[0]); + // This function must be called after a full document life cycle update, + // when we have cleared raster invalidation information. + DCHECK(chunks_and_invalidations_.raster_invalidation_rects.IsEmpty()); + DCHECK(chunks_and_invalidations_.raster_invalidation_trackings.IsEmpty()); + size_t total_size = sizeof(*this) + display_item_list_.MemoryUsageInBytes() + + chunks_and_invalidations_.chunks.capacity() * + sizeof(chunks_and_invalidations_.chunks[0]); + for (const auto& chunk : chunks_and_invalidations_.chunks) + total_size += chunk.MemoryUsageInBytes(); + return total_size; } void PaintArtifact::Replay(GraphicsContext& graphics_context, @@ -102,12 +115,20 @@ void PaintArtifact::Replay(PaintCanvas& canvas, } DISABLE_CFI_PERF -void PaintArtifact::AppendToWebDisplayItemList( - const FloatSize& visual_rect_offset, - WebDisplayItemList* list) const { - TRACE_EVENT0("blink,benchmark", "PaintArtifact::appendToWebDisplayItemList"); +void PaintArtifact::AppendToDisplayItemList(const FloatSize& visual_rect_offset, + cc::DisplayItemList& list) const { + TRACE_EVENT0("blink,benchmark", "PaintArtifact::AppendToDisplayItemList"); for (const DisplayItem& item : display_item_list_) - item.AppendToWebDisplayItemList(visual_rect_offset, list); + item.AppendToDisplayItemList(visual_rect_offset, list); +} + +void PaintArtifact::FinishCycle() { + for (auto& chunk : chunks_and_invalidations_.chunks) { + chunk.client_is_just_created = false; + chunk.properties.ClearChangedToRoot(); + } + chunks_and_invalidations_.raster_invalidation_rects.clear(); + chunks_and_invalidations_.raster_invalidation_trackings.clear(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h index f54b92f4370..d181e81a28a 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_artifact.h @@ -9,6 +9,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_subset.h" +#include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" @@ -17,11 +18,35 @@ namespace blink { class GraphicsContext; -class WebDisplayItemList; +class PaintChunkSubset; -// The output of painting, consisting of a series of drawings in paint order, -// partitioned into discontiguous chunks with a common set of paint properties -// (i.e. associated with the same transform, clip, effects, etc.). +using ChunkRasterInvalidationRects = Vector<FloatRect, 2>; +using ChunkRasterInvalidationTracking = Vector<RasterInvalidationInfo>; + +struct PaintChunksAndRasterInvalidations { + void Clear() { + chunks.clear(); + raster_invalidation_rects.clear(); + raster_invalidation_trackings.clear(); + } + + Vector<PaintChunk> chunks; + Vector<ChunkRasterInvalidationRects> raster_invalidation_rects; + Vector<ChunkRasterInvalidationTracking> raster_invalidation_trackings; +}; + +// The output of painting, consisting of +// - display item list (in DisplayItemList), +// - paint chunks and their paint invalidations (in +// PaintChunksAndRasterInvalidations). +// +// Display item list and paint chunks not only represent the output of the +// current painting, but also serve as cache of individual display items and +// paint chunks for later paintings as long as the display items and chunks are +// valid. +// +// Raster invalidations are consumed by CompositedLayerRasterInvalidator and +// will be cleared after a cycle is complete via |FinishCycle()|. // // It represents a particular state of the world, and should be immutable // (const) to most of its users. @@ -37,7 +62,7 @@ class PLATFORM_EXPORT PaintArtifact final { public: PaintArtifact(); - PaintArtifact(DisplayItemList, Vector<PaintChunk>); + PaintArtifact(DisplayItemList, PaintChunksAndRasterInvalidations); PaintArtifact(PaintArtifact&&); ~PaintArtifact(); @@ -50,24 +75,26 @@ class PLATFORM_EXPORT PaintArtifact final { return display_item_list_; } - Vector<PaintChunk>& PaintChunks() { return paint_chunks_; } - const Vector<PaintChunk>& PaintChunks() const { return paint_chunks_; } + Vector<PaintChunk>& PaintChunks() { return chunks_and_invalidations_.chunks; } + const Vector<PaintChunk>& PaintChunks() const { + return chunks_and_invalidations_.chunks; + } PaintChunkSubset GetPaintChunkSubset( const Vector<size_t>& subset_indices) const { - return PaintChunkSubset(paint_chunks_, subset_indices); + return PaintChunkSubset(PaintChunks(), subset_indices); } Vector<PaintChunk>::const_iterator FindChunkByDisplayItemIndex( size_t index) const { - return FindChunkInVectorByDisplayItemIndex(paint_chunks_, index); + return FindChunkInVectorByDisplayItemIndex(PaintChunks(), index); } // Resets to an empty paint artifact. void Reset(); // Returns the approximate memory usage, excluding memory likely to be - // shared with the embedder after copying to WebDisplayItemList. + // shared with the embedder after copying to cc::DisplayItemList. size_t ApproximateUnsharedMemoryUsage() const; // Draws the paint artifact to a GraphicsContext. @@ -82,13 +109,48 @@ class PLATFORM_EXPORT PaintArtifact final { const PropertyTreeState& replay_state, const IntPoint& offset = IntPoint()) const; - // Writes the paint artifact into a WebDisplayItemList. - void AppendToWebDisplayItemList(const FloatSize& visual_rect_offset, - WebDisplayItemList*) const; + // Writes the paint artifact into a cc::DisplayItemList. + void AppendToDisplayItemList(const FloatSize& visual_rect_offset, + cc::DisplayItemList& display_list) const; + + const ChunkRasterInvalidationRects* GetRasterInvalidationRects( + size_t chunk_index) const { + return chunk_index < + chunks_and_invalidations_.raster_invalidation_rects.size() + ? &chunks_and_invalidations_ + .raster_invalidation_rects[chunk_index] + : nullptr; + } + + const ChunkRasterInvalidationRects* GetRasterInvalidationRects( + const PaintChunk& chunk) const { + return GetRasterInvalidationRects( + &chunk - &chunks_and_invalidations_.chunks.front()); + } + + const ChunkRasterInvalidationTracking* GetRasterInvalidationTracking( + size_t chunk_index) const { + return chunk_index < chunks_and_invalidations_.raster_invalidation_trackings + .size() + ? &chunks_and_invalidations_ + .raster_invalidation_trackings[chunk_index] + : nullptr; + } + + const ChunkRasterInvalidationTracking* GetRasterInvalidationTracking( + const PaintChunk& chunk) const { + return GetRasterInvalidationTracking( + &chunk - &chunks_and_invalidations_.chunks.front()); + } + + // Called when the caller finishes updating a full document life cycle. + // Will cleanup data (e.g. raster invalidations) that will no longer be used + // for the next cycle, and update status to be ready for the next cycle. + void FinishCycle(); private: DisplayItemList display_item_list_; - Vector<PaintChunk> paint_chunks_; + PaintChunksAndRasterInvalidations chunks_and_invalidations_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc index 61d995b0914..10489b4bab8 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.cc @@ -8,13 +8,47 @@ namespace blink { +struct SameSizeAsPaintChunk { + size_t begin; + size_t end; + PaintChunk::Id id; + PropertyTreeState properties; + unsigned bools; + float extend; + FloatRect bounds; + void* pointers[1]; +}; + +static_assert(sizeof(PaintChunk) == sizeof(SameSizeAsPaintChunk), + "PaintChunk should stay small"); + String PaintChunk::ToString() const { - return String::Format( + String ret_val = String::Format( "PaintChunk(begin=%zu, end=%zu, id=%s cacheable=%d props=(%s) bounds=%s " - "known_to_be_opaque=%d raster_invalidation_rects=%zu)", + "known_to_be_opaque=%d", begin_index, end_index, id.ToString().Ascii().data(), is_cacheable, properties.ToString().Ascii().data(), bounds.ToString().Ascii().data(), - known_to_be_opaque, raster_invalidation_rects.size()); + known_to_be_opaque); + if (hit_test_data) { + ret_val.append(String::Format( + ", border_rect=(%s), touch_action_rect=((%s), %s), " + "wheel_event_handler_region=(%s) non_fast_scrollable_region=(%s))", + hit_test_data->border_rect.ToString().Ascii().data(), + hit_test_data->touch_action_rect.rect.ToString().Ascii().data(), + TouchActionToString( + hit_test_data->touch_action_rect.whitelisted_touch_action), + hit_test_data->wheel_event_handler_region.Bounds() + .ToString() + .Ascii() + .data(), + hit_test_data->non_fast_scrollable_region.Bounds() + .ToString() + .Ascii() + .data())); + } else { + ret_val.append(")"); + } + return ret_val; } std::ostream& operator<<(std::ostream& os, const PaintChunk& chunk) { diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h index 16c2ab11ee8..4504b5e2ae2 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk.h @@ -6,10 +6,12 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_H_ #include <iosfwd> +#include <memory> #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h" +#include "third_party/blink/renderer/platform/graphics/paint/hit_test_data.h" #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" +#include "third_party/blink/renderer/platform/graphics/paint/ref_counted_property_tree_state.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/forward.h" @@ -36,7 +38,7 @@ struct PLATFORM_EXPORT PaintChunk { PaintChunk(size_t begin, size_t end, const Id& id, - const PaintChunkProperties& props, + const PropertyTreeState& props, Cacheable cacheable = kCacheable) : begin_index(begin), end_index(end), @@ -45,7 +47,8 @@ struct PLATFORM_EXPORT PaintChunk { outset_for_raster_effects(0), known_to_be_opaque(false), is_cacheable(cacheable == kCacheable), - client_is_just_created(id.client.IsJustCreated()) {} + client_is_just_created(id.client.IsJustCreated()), + hit_test_data(nullptr) {} size_t size() const { DCHECK_GE(end_index, begin_index); @@ -71,6 +74,19 @@ struct PLATFORM_EXPORT PaintChunk { return !client_is_just_created; } + HitTestData& EnsureHitTestData() { + if (!hit_test_data) + hit_test_data = std::make_unique<HitTestData>(); + return *hit_test_data.get(); + } + + size_t MemoryUsageInBytes() const { + size_t total_size = sizeof(*this); + if (hit_test_data) + total_size += sizeof(*hit_test_data); + return total_size; + } + // Index of the first drawing in this chunk. size_t begin_index; @@ -78,17 +94,13 @@ struct PLATFORM_EXPORT PaintChunk { // |endIndex - beginIndex| drawings in the chunk. size_t end_index; - // Identifier of this chunk. If it has a value, it should be unique. This is - // used to match a new chunk to a cached old chunk to track changes of chunk - // contents, so the id should be stable across document cycles. If the - // contents of the chunk can't be cached (e.g. it's created when - // PaintController is skipping the cache, normally because display items can't - // be uniquely identified), |id| is nullopt so that the chunk won't match any - // other chunk. + // Identifier of this chunk. It should be unique if |is_cacheable| is true. + // This is used to match a new chunk to a cached old chunk to track changes + // of chunk contents, so the id should be stable across document cycles. Id id; // The paint properties which apply to this chunk. - PaintChunkProperties properties; + RefCountedPropertyTreeState properties; // The total bounds of this paint chunk's contents, in the coordinate space of // the containing transform node. @@ -104,31 +116,24 @@ struct PLATFORM_EXPORT PaintChunk { bool is_cacheable : 1; - // TODO(wangxianzhu): The following fields are 'mutable' for - // ContentLayerClientImpl to clear them, which will be unnecessary if we don't - // call PaintArtifactCompositor::Update() when paint artifact is unchanged. - mutable bool client_is_just_created : 1; - - // Rectangles that need to be re-rasterized in this chunk, in the coordinate - // space of the containing transform node. - mutable Vector<FloatRect> raster_invalidation_rects; - - mutable Vector<RasterInvalidationInfo> raster_invalidation_tracking; + bool client_is_just_created : 1; String ToString() const; -}; -inline bool operator==(const PaintChunk& a, const PaintChunk& b) { - return a.begin_index == b.begin_index && a.end_index == b.end_index && - a.id == b.id && a.properties == b.properties && a.bounds == b.bounds && - a.known_to_be_opaque == b.known_to_be_opaque && - a.is_cacheable == b.is_cacheable && - a.raster_invalidation_rects == b.raster_invalidation_rects; -} + bool operator==(const PaintChunk& rhs) const { + return begin_index == rhs.begin_index && end_index == rhs.end_index && + id == rhs.id && properties == rhs.properties && + is_cacheable == rhs.is_cacheable && + ((!hit_test_data && !rhs.hit_test_data) || + (hit_test_data && rhs.hit_test_data && + *hit_test_data == *rhs.hit_test_data)); + } -inline bool operator!=(const PaintChunk& a, const PaintChunk& b) { - return !(a == b); -} + bool operator!=(const PaintChunk& rhs) const { return !(*this == rhs); } + + private: + std::unique_ptr<HitTestData> hit_test_data; +}; inline bool ChunkLessThanIndex(const PaintChunk& chunk, size_t index) { return chunk.end_index <= index; @@ -137,7 +142,7 @@ inline bool ChunkLessThanIndex(const PaintChunk& chunk, size_t index) { inline Vector<PaintChunk>::iterator FindChunkInVectorByDisplayItemIndex( Vector<PaintChunk>& chunks, size_t index) { - auto chunk = + auto* chunk = std::lower_bound(chunks.begin(), chunks.end(), index, ChunkLessThanIndex); DCHECK(chunk == chunks.end() || (index >= chunk->begin_index && index < chunk->end_index)); diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.cc deleted file mode 100644 index c3d59636b88..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.cc +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h" - -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -namespace blink { - -String PaintChunkProperties::ToString() const { - StringBuilder sb; - if (property_tree_state.Transform()) { - sb.Append("transform=("); - sb.Append(property_tree_state.Transform()->ToString()); - sb.Append(")"); - } - if (property_tree_state.Clip()) { - if (sb.length()) - sb.Append(", "); - sb.Append("clip=("); - sb.Append(property_tree_state.Clip()->ToString()); - sb.Append(")"); - } - if (property_tree_state.Effect()) { - if (sb.length()) - sb.Append(", "); - sb.Append("effect=("); - sb.Append(property_tree_state.Effect()->ToString()); - sb.Append(")"); - } - if (sb.length()) - sb.Append(", "); - sb.Append("backface_hidden="); - sb.Append(backface_hidden ? "1" : "0"); - return sb.ToString(); -} - -std::ostream& operator<<(std::ostream& os, - const PaintChunkProperties& properties) { - return os << properties.ToString().Utf8().data(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h deleted file mode 100644 index 0de460ada6a..00000000000 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h +++ /dev/null @@ -1,60 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_PROPERTIES_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_PROPERTIES_H_ - -#include <iosfwd> -#include "third_party/blink/renderer/platform/graphics/paint/ref_counted_property_tree_state.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/forward.h" -#include "third_party/blink/renderer/platform/wtf/noncopyable.h" - -namespace blink { - -// The set of paint properties applying to a |PaintChunk|. These properties are -// not local-only paint style parameters such as color, but instead represent -// the hierarchy of transforms, clips, and effects that apply to a contiguous -// chunk of display items. A single DisplayItemClient can generate multiple -// properties of the same type and this struct represents the total state of all -// properties for a given |PaintChunk|. -// -// This differs from |ObjectPaintProperties| because it only stores one property -// for each type (e.g., either transform or perspective, but not both). -struct PLATFORM_EXPORT PaintChunkProperties { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); - - explicit PaintChunkProperties(const PropertyTreeState& state) - : property_tree_state(state), backface_hidden(false) {} - - PaintChunkProperties() - : property_tree_state(nullptr, nullptr, nullptr), - backface_hidden(false) {} - - RefCountedPropertyTreeState property_tree_state; - bool backface_hidden; - - String ToString() const; -}; - -// Equality is based only on the pointers and is not 'deep' which would require -// crawling the entire property tree to compute. -inline bool operator==(const PaintChunkProperties& a, - const PaintChunkProperties& b) { - return a.property_tree_state == b.property_tree_state && - a.backface_hidden == b.backface_hidden; -} - -inline bool operator!=(const PaintChunkProperties& a, - const PaintChunkProperties& b) { - return !(a == b); -} - -PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, - const PaintChunkProperties); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNK_PROPERTIES_H_ diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_test.cc index 309b621bc5b..486b9c24691 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunk_test.cc @@ -4,14 +4,14 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" +#include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/testing/fake_display_item_client.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { -TEST(PaintChunkTest, matchesSame) { - PaintChunkProperties properties; +TEST(PaintChunkTest, MatchesSame) { + auto properties = PropertyTreeState::Root(); FakeDisplayItemClient client; client.UpdateCacheGeneration(); DisplayItem::Id id(client, DisplayItem::kDrawingFirst); @@ -19,8 +19,8 @@ TEST(PaintChunkTest, matchesSame) { .Matches(PaintChunk(0, 1, id, properties))); } -TEST(PaintChunkTest, matchesEqual) { - PaintChunkProperties properties; +TEST(PaintChunkTest, MatchesEqual) { + auto properties = PropertyTreeState::Root(); FakeDisplayItemClient client; client.UpdateCacheGeneration(); DisplayItem::Id id(client, DisplayItem::kDrawingFirst); @@ -32,7 +32,7 @@ TEST(PaintChunkTest, matchesEqual) { } TEST(PaintChunkTest, IdNotMatches) { - PaintChunkProperties properties; + auto properties = PropertyTreeState::Root(); FakeDisplayItemClient client1; client1.UpdateCacheGeneration(); DisplayItem::Id id1(client1, DisplayItem::kDrawingFirst); @@ -45,7 +45,7 @@ TEST(PaintChunkTest, IdNotMatches) { } TEST(PaintChunkTest, IdNotMatchesUncacheable) { - PaintChunkProperties properties; + auto properties = PropertyTreeState::Root(); FakeDisplayItemClient client; client.UpdateCacheGeneration(); DisplayItem::Id id(client, DisplayItem::kDrawingFirst); @@ -60,8 +60,8 @@ TEST(PaintChunkTest, IdNotMatchesUncacheable) { } TEST(PaintChunkTest, IdNotMatchesJustCreated) { - PaintChunkProperties properties; - Optional<FakeDisplayItemClient> client; + auto properties = PropertyTreeState::Root(); + base::Optional<FakeDisplayItemClient> client; client.emplace(); EXPECT_TRUE(client->IsJustCreated()); // Invalidation won't change the "just created" status. @@ -79,7 +79,7 @@ TEST(PaintChunkTest, IdNotMatchesJustCreated) { .Matches(PaintChunk(0, 1, id, properties))); // Delete the current object and create a new object at the same address. - client = WTF::nullopt; + client = base::nullopt; client.emplace(); EXPECT_TRUE(client->IsJustCreated()); EXPECT_FALSE(PaintChunk(0, 1, id, properties) 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 408269c0ade..d07e470b9cb 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 @@ -8,58 +8,74 @@ namespace blink { -PaintChunker::PaintChunker() : force_new_chunk_(false) {} +static const PropertyTreeState& UninitializedProperties() { + DEFINE_STATIC_LOCAL(PropertyTreeState, initial_properties, + (nullptr, nullptr, nullptr)); + return initial_properties; +} + +PaintChunker::PaintChunker() + : current_properties_(UninitializedProperties()), force_new_chunk_(false) {} PaintChunker::~PaintChunker() = default; +bool PaintChunker::IsInInitialState() const { + if (current_properties_ != UninitializedProperties()) + return false; + + DCHECK(data_.chunks.IsEmpty()); + return true; +} + void PaintChunker::UpdateCurrentPaintChunkProperties( - const Optional<PaintChunk::Id>& chunk_id, - const PaintChunkProperties& properties) { + const base::Optional<PaintChunk::Id>& chunk_id, + const PropertyTreeState& properties) { DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled()); - - if (chunk_id) - current_chunk_id_.emplace(*chunk_id); - else - current_chunk_id_ = WTF::nullopt; + // If properties are the same, continue to use the previously set + // |next_chunk_id_| because the id of the outer painting is likely to be + // more stable to reduce invalidation because of chunk id changes. + if (!next_chunk_id_ || current_properties_ != properties) { + if (chunk_id) + next_chunk_id_.emplace(*chunk_id); + else + next_chunk_id_ = base::nullopt; + } current_properties_ = properties; } +void PaintChunker::ForceNewChunk() { + force_new_chunk_ = true; + // Always use a new chunk id for a force chunk which may be for a subsequence + // which needs the chunk id to be independence with previous chunks. + next_chunk_id_ = base::nullopt; +} + bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) { DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled()); - -#if DCHECK_IS_ON() // Property nodes should never be null because they should either be set to // properties created by a LayoutObject/FrameView, or be set to a non-null // root node. If these DCHECKs are hit we are missing a call to update the // properties. See: ScopedPaintChunkProperties. - // TODO(trchen): Enable this check for SPv175 too. Some drawable layers - // don't paint with property tree yet, e.g. scrollbar layers. - if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - DCHECK(current_properties_.property_tree_state.Transform()); - DCHECK(current_properties_.property_tree_state.Clip()); - DCHECK(current_properties_.property_tree_state.Effect()); - } -#endif + DCHECK(current_properties_.Transform()); + DCHECK(current_properties_.Clip()); + DCHECK(current_properties_.Effect()); bool item_forces_new_chunk = item.IsForeignLayer() || item.IsScrollHitTest(); - if (item_forces_new_chunk) { + if (item_forces_new_chunk) force_new_chunk_ = true; - // Clear current_chunk_id_ so that we will use the current display item's id - // as the chunk id, and any display items after the forcing item without a - // new chunk id will be treated as having no id to avoid the chunk from - // using the same id as the chunk before the forced chunk. - current_chunk_id_ = WTF::nullopt; - } size_t new_chunk_begin_index; - if (chunks_.IsEmpty()) { + if (data_.chunks.IsEmpty()) { new_chunk_begin_index = 0; } else { - auto& last_chunk = chunks_.back(); - if (!force_new_chunk_ && current_properties_ == last_chunk.properties && - (!current_chunk_id_ || current_chunk_id_ == last_chunk.id)) { + auto& last_chunk = LastChunk(); + if (!force_new_chunk_ && current_properties_ == last_chunk.properties) { // Continue the current chunk. last_chunk.end_index++; + // We don't create a new chunk when UpdateCurrentPaintChunkProperties() + // just changed |next_chunk_id_| but not |current_properties_|. Clear + // |next_chunk_id_| which has been ignored. + next_chunk_id_ = base::nullopt; return false; } new_chunk_begin_index = last_chunk.end_index; @@ -67,10 +83,10 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) { auto cacheable = item.SkippedCache() ? PaintChunk::kUncacheable : PaintChunk::kCacheable; - PaintChunk new_chunk(new_chunk_begin_index, new_chunk_begin_index + 1, - current_chunk_id_ ? *current_chunk_id_ : item.GetId(), - current_properties_, cacheable); - chunks_.push_back(new_chunk); + data_.chunks.emplace_back(new_chunk_begin_index, new_chunk_begin_index + 1, + next_chunk_id_ ? *next_chunk_id_ : item.GetId(), + current_properties_, cacheable); + next_chunk_id_ = base::nullopt; // When forcing a new chunk, we still need to force new chunk for the next // display item. Otherwise reset force_new_chunk_ to false. @@ -80,18 +96,27 @@ bool PaintChunker::IncrementDisplayItemIndex(const DisplayItem& item) { return true; } +void PaintChunker::TrackRasterInvalidation(const PaintChunk& chunk, + const RasterInvalidationInfo& info) { + size_t index = ChunkIndex(chunk); + auto& trackings = data_.raster_invalidation_trackings; + if (trackings.size() <= index) + trackings.resize(index + 1); + trackings[index].push_back(info); +} + void PaintChunker::Clear() { - chunks_.clear(); - current_chunk_id_ = WTF::nullopt; - current_properties_ = PaintChunkProperties(); + data_.Clear(); + next_chunk_id_ = base::nullopt; + current_properties_ = UninitializedProperties(); } -Vector<PaintChunk> PaintChunker::ReleasePaintChunks() { - Vector<PaintChunk> chunks; - chunks.swap(chunks_); - current_chunk_id_ = WTF::nullopt; - current_properties_ = PaintChunkProperties(); - return chunks; +PaintChunksAndRasterInvalidations PaintChunker::ReleaseData() { + next_chunk_id_ = base::nullopt; + current_properties_ = UninitializedProperties(); + data_.chunks.ShrinkToFit(); + data_.raster_invalidation_rects.ShrinkToFit(); + return std::move(data_); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h index 18ce23899b3..17fdb5b9d85 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_chunker.h @@ -5,20 +5,21 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNKER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_PAINT_CHUNKER_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_artifact.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h" +#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/vector.h" namespace blink { -// Accepts information about changes to |PaintChunkProperties| as drawings are +// Accepts information about changes to chunk properties as drawings are // accumulated, and produces a series of paint chunks: contiguous ranges of the -// display list with identical |PaintChunkProperties|. +// display list with identical properties. class PLATFORM_EXPORT PaintChunker final { DISALLOW_NEW(); WTF_MAKE_NONCOPYABLE(PaintChunker); @@ -27,51 +28,72 @@ class PLATFORM_EXPORT PaintChunker final { PaintChunker(); ~PaintChunker(); - bool IsInInitialState() const { - return chunks_.IsEmpty() && current_properties_ == PaintChunkProperties(); - } + bool IsInInitialState() const; - const PaintChunkProperties& CurrentPaintChunkProperties() const { + const PropertyTreeState& CurrentPaintChunkProperties() const { return current_properties_; } - void UpdateCurrentPaintChunkProperties(const Optional<PaintChunk::Id>&, - const PaintChunkProperties&); + void UpdateCurrentPaintChunkProperties(const base::Optional<PaintChunk::Id>&, + const PropertyTreeState&); - void ForceNewChunk() { force_new_chunk_ = true; } + void ForceNewChunk(); // Returns true if a new chunk is created. bool IncrementDisplayItemIndex(const DisplayItem&); - const Vector<PaintChunk>& PaintChunks() const { return chunks_; } + const Vector<PaintChunk>& PaintChunks() const { return data_.chunks; } - PaintChunk& PaintChunkAt(size_t i) { return chunks_[i]; } + PaintChunk& PaintChunkAt(size_t i) { return data_.chunks[i]; } size_t LastChunkIndex() const { - return chunks_.IsEmpty() ? kNotFound : chunks_.size() - 1; + return data_.chunks.IsEmpty() ? kNotFound : data_.chunks.size() - 1; } - PaintChunk& LastChunk() { return chunks_.back(); } + PaintChunk& LastChunk() { return data_.chunks.back(); } PaintChunk& FindChunkByDisplayItemIndex(size_t index) { - auto chunk = FindChunkInVectorByDisplayItemIndex(chunks_, index); - DCHECK(chunk != chunks_.end()); + auto* chunk = FindChunkInVectorByDisplayItemIndex(data_.chunks, index); + DCHECK(chunk != data_.chunks.end()); return *chunk; } + void AddRasterInvalidation(const PaintChunk& chunk, const FloatRect& rect) { + size_t index = ChunkIndex(chunk); + auto& rects = data_.raster_invalidation_rects; + if (rects.size() <= index) + rects.resize(index + 1); + rects[index].push_back(rect); + } + + void TrackRasterInvalidation(const PaintChunk&, + const RasterInvalidationInfo&); + void Clear(); - // Releases the generated paint chunk list and resets the state of this - // object. - Vector<PaintChunk> ReleasePaintChunks(); + // Releases the generated paint chunk list and raster invalidations and + // resets the state of this object. + PaintChunksAndRasterInvalidations ReleaseData(); private: - Vector<PaintChunk> chunks_; - // TODO(pdr): Refactor current_chunk_id_ so that it is always the equal to - // the current chunk id. This is currently not true when there is a forced - // chunk because the current_chunk_id_ is cleared for subsequent chunks, even - // though those subsequent chunks will have valid chunk ids. - Optional<PaintChunk::Id> current_chunk_id_; - PaintChunkProperties current_properties_; + size_t ChunkIndex(const PaintChunk& chunk) const { + size_t index = &chunk - &data_.chunks.front(); + DCHECK_LT(index, data_.chunks.size()); + return index; + } + + PaintChunksAndRasterInvalidations data_; + + // The id specified by UpdateCurrentPaintChunkProperties(). If it is not + // nullopt, we will use it as the id of the next new chunk. Otherwise we will + // use the id of the first display item of the new chunk as the id. + // It's cleared when we create a new chunk with the id, or decide not to + // create a chunk with it (e.g. when properties don't change and we are not + // forced to create a new chunk). + base::Optional<PaintChunk::Id> next_chunk_id_; + + PropertyTreeState current_properties_; + // True when an item forces a new chunk (e.g., foreign display items), and for - // the item following a forced chunk. + // the item following a forced chunk. PaintController also forces new chunks + // before and after subsequences by calling ForceNewChunk(). bool force_new_chunk_; }; 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 3071d77976a..074f9f87d14 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 @@ -9,11 +9,10 @@ #include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" -using ::blink::test::CreateOpacityOnlyEffect; -using ::blink::test::DefaultPaintChunkProperties; using testing::ElementsAre; namespace blink { + namespace { class PaintChunkerTest : public testing::Test, @@ -40,8 +39,8 @@ class TestChunkerDisplayItem : public DisplayItem { : DisplayItem(client, type, sizeof(*this)) {} void Replay(GraphicsContext&) const final { NOTREACHED(); } - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const final { + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const final { NOTREACHED(); } }; @@ -53,8 +52,11 @@ class TestDisplayItemRequiringSeparateChunk : public TestChunkerDisplayItem { }; TEST_F(PaintChunkerTest, Empty) { - Vector<PaintChunk> chunks = PaintChunker().ReleasePaintChunks(); - ASSERT_TRUE(chunks.IsEmpty()); + PaintChunker chunker; + EXPECT_TRUE(chunker.PaintChunks().IsEmpty()); + + auto chunks_data = chunker.ReleaseData(); + EXPECT_TRUE(chunks_data.chunks.IsEmpty()); } TEST_F(PaintChunkerTest, SingleNonEmptyRange) { @@ -63,10 +65,16 @@ TEST_F(PaintChunkerTest, SingleNonEmptyRange) { chunker.UpdateCurrentPaintChunkProperties(id, DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 2, id, DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 1u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id, DefaultPaintChunkProperties())); + + auto chunks_data = chunker.ReleaseData(); + EXPECT_TRUE(chunker.PaintChunks().IsEmpty()); + EXPECT_EQ(chunks_data.chunks.size(), 1u); + EXPECT_EQ(chunks_data.chunks[0], + PaintChunk(0, 2, id, DefaultPaintChunkProperties())); } TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) { @@ -77,10 +85,16 @@ TEST_F(PaintChunkerTest, SamePropertiesTwiceCombineIntoOneChunk) { chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.UpdateCurrentPaintChunkProperties(id, DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 3, id, DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 1u); + EXPECT_EQ(chunks[0], PaintChunk(0, 3, id, DefaultPaintChunkProperties())); + + auto chunks_data = chunker.ReleaseData(); + EXPECT_TRUE(chunker.PaintChunks().IsEmpty()); + EXPECT_EQ(chunks_data.chunks.size(), 1u); + EXPECT_EQ(chunks_data.chunks[0], + PaintChunk(0, 3, id, DefaultPaintChunkProperties())); } TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) { @@ -90,33 +104,28 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithSinglePropertyChanging) { chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform = DefaultPaintChunkProperties(); - simple_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 1, 2, 3, 4, 5), - FloatPoint3D(9, 8, 7)) - .get()); + auto simple_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); + auto simple_transform = DefaultPaintChunkProperties(); + simple_transform.SetTransform(simple_transform_node.get()); PaintChunk::Id id2(client_, DisplayItemType(2)); chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties another_transform = DefaultPaintChunkProperties(); - another_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 1, 2, 3, 4, 5), - FloatPoint3D(9, 8, 7)) - .get()); + auto another_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); + auto another_transform = DefaultPaintChunkProperties(); + another_transform.SetTransform(another_transform_node.get()); PaintChunk::Id id3(client_, DisplayItemType(3)); chunker.UpdateCurrentPaintChunkProperties(id3, another_transform); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 2, id1, DefaultPaintChunkProperties()), - PaintChunk(2, 3, id2, simple_transform), - PaintChunk(3, 4, id3, another_transform))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(2, 3, id2, simple_transform)); + EXPECT_EQ(chunks[2], PaintChunk(3, 4, id3, another_transform)); } TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) { @@ -125,41 +134,35 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) { chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform = DefaultPaintChunkProperties(); - simple_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 0, 0, 0, 0, 0), - FloatPoint3D(9, 8, 7)) - .get()); + auto simple_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 0, 0, 0, 0, 0), FloatPoint3D(9, 8, 7)); + auto simple_transform = DefaultPaintChunkProperties(); + simple_transform.SetTransform(simple_transform_node.get()); PaintChunk::Id id2(client_, DisplayItemType(2)); chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform_and_effect = - DefaultPaintChunkProperties(); - simple_transform_and_effect.property_tree_state.SetTransform( - simple_transform.property_tree_state.Transform()); - simple_transform_and_effect.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5f).get()); + auto simple_effect_node = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5f); + auto simple_transform_and_effect = DefaultPaintChunkProperties(); + simple_transform_and_effect.SetTransform(simple_transform_node.get()); + simple_transform_and_effect.SetEffect(simple_effect_node.get()); PaintChunk::Id id3(client_, DisplayItemType(3)); chunker.UpdateCurrentPaintChunkProperties(id3, simple_transform_and_effect); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform_and_effect_with_updated_transform = + auto new_transform_node = CreateTransform( + nullptr, TransformationMatrix(1, 1, 0, 0, 0, 0), FloatPoint3D(9, 8, 7)); + auto simple_transform_and_effect_with_updated_transform = DefaultPaintChunkProperties(); - simple_transform_and_effect_with_updated_transform.property_tree_state - .SetTransform(TransformPaintPropertyNode::Create( - nullptr, TransformationMatrix(1, 1, 0, 0, 0, 0), - FloatPoint3D(9, 8, 7)) - .get()); - simple_transform_and_effect_with_updated_transform.property_tree_state - .SetEffect(CreateOpacityOnlyEffect( - EffectPaintPropertyNode::Root(), - simple_transform_and_effect.property_tree_state.Effect() - ->Opacity()) - .get()); + auto new_effect_node = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5f); + simple_transform_and_effect_with_updated_transform.SetTransform( + new_transform_node.get()); + simple_transform_and_effect_with_updated_transform.SetEffect( + new_effect_node.get()); PaintChunk::Id id4(client_, DisplayItemType(4)); chunker.UpdateCurrentPaintChunkProperties( id4, simple_transform_and_effect_with_updated_transform); @@ -168,24 +171,22 @@ TEST_F(PaintChunkerTest, BuildMultipleChunksWithDifferentPropertyChanges) { // Test that going back to a previous chunk property still creates a new // chunk. - chunker.UpdateCurrentPaintChunkProperties(WTF::nullopt, + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, simple_transform_and_effect); TestChunkerDisplayItem item_after_restore(client_, DisplayItemType(10)); chunker.IncrementDisplayItemIndex(item_after_restore); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - - EXPECT_THAT( - chunks, - ElementsAre( - PaintChunk(0, 1, id1, DefaultPaintChunkProperties()), - PaintChunk(1, 3, id2, simple_transform), - PaintChunk(3, 5, id3, simple_transform_and_effect), - PaintChunk(5, 7, id4, - simple_transform_and_effect_with_updated_transform), - PaintChunk(7, 9, item_after_restore.GetId(), - simple_transform_and_effect))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 5u); + EXPECT_EQ(chunks[0], PaintChunk(0, 1, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(1, 3, id2, simple_transform)); + EXPECT_EQ(chunks[2], PaintChunk(3, 5, id3, simple_transform_and_effect)); + EXPECT_EQ(chunks[3], + PaintChunk(5, 7, id4, + simple_transform_and_effect_with_updated_transform)); + EXPECT_EQ(chunks[4], PaintChunk(7, 9, item_after_restore.GetId(), + simple_transform_and_effect)); } TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) { @@ -203,29 +204,26 @@ TEST_F(PaintChunkerTest, BuildChunksFromNestedTransforms) { chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform = DefaultPaintChunkProperties(); - simple_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 1, 2, 3, 4, 5), - FloatPoint3D(9, 8, 7)) - .get()); + auto simple_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); + auto simple_transform = DefaultPaintChunkProperties(); + simple_transform.SetTransform(simple_transform_node.get()); PaintChunk::Id id2(client_, DisplayItemType(2)); chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - chunker.UpdateCurrentPaintChunkProperties(WTF::nullopt, + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, DefaultPaintChunkProperties()); TestChunkerDisplayItem item_after_restore(client_, DisplayItemType(10)); chunker.IncrementDisplayItemIndex(item_after_restore); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 1, id1, DefaultPaintChunkProperties()), - PaintChunk(1, 3, id2, simple_transform), - PaintChunk(3, 4, item_after_restore.GetId(), - DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 1, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(1, 3, id2, simple_transform)); + EXPECT_EQ(chunks[2], PaintChunk(3, 4, item_after_restore.GetId(), + DefaultPaintChunkProperties())); } TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) { @@ -235,30 +233,25 @@ TEST_F(PaintChunkerTest, ChangingPropertiesWithoutItems) { chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties first_transform = DefaultPaintChunkProperties(); - first_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 1, 2, 3, 4, 5), - FloatPoint3D(9, 8, 7)) - .get()); + auto first_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); + auto first_transform = DefaultPaintChunkProperties(); + first_transform.SetTransform(first_transform_node.get()); PaintChunk::Id id2(client_, DisplayItemType(2)); - chunker.UpdateCurrentPaintChunkProperties(WTF::nullopt, first_transform); - - PaintChunkProperties second_transform = DefaultPaintChunkProperties(); - second_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(9, 8, 7, 6, 5, 4), - FloatPoint3D(3, 2, 1)) - .get()); + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, first_transform); + + auto second_transform_node = CreateTransform( + nullptr, TransformationMatrix(9, 8, 7, 6, 5, 4), FloatPoint3D(3, 2, 1)); + auto second_transform = DefaultPaintChunkProperties(); + second_transform.SetTransform(second_transform_node.get()); PaintChunk::Id id3(client_, DisplayItemType(3)); chunker.UpdateCurrentPaintChunkProperties(id3, second_transform); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 1, id1, DefaultPaintChunkProperties()), - PaintChunk(1, 2, id3, second_transform))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 2u); + EXPECT_EQ(chunks[0], PaintChunk(0, 1, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(1, 2, id3, second_transform)); } TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) { @@ -282,18 +275,20 @@ TEST_F(PaintChunkerTest, CreatesSeparateChunksWhenRequested) { chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(i3); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT( - chunks, - ElementsAre( - PaintChunk(0, 1, id0, DefaultPaintChunkProperties()), - PaintChunk(1, 2, i1.GetId(), DefaultPaintChunkProperties()), - PaintChunk(2, 3, i2.GetId(), DefaultPaintChunkProperties()), - PaintChunk(3, 5, after_i2.GetId(), DefaultPaintChunkProperties()), - PaintChunk(5, 6, i3.GetId(), DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 5u); + EXPECT_EQ(chunks[0], PaintChunk(0, 1, id0, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], + PaintChunk(1, 2, i1.GetId(), DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[2], + PaintChunk(2, 3, i2.GetId(), DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[3], + PaintChunk(3, 5, after_i2.GetId(), DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[4], + PaintChunk(5, 6, i3.GetId(), DefaultPaintChunkProperties())); } -TEST_F(PaintChunkerTest, ForceNewChunk) { +TEST_F(PaintChunkerTest, ForceNewChunkWithNewId) { PaintChunker chunker; PaintChunk::Id id0(client_, DisplayItemType(0)); chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties()); @@ -306,18 +301,69 @@ TEST_F(PaintChunkerTest, ForceNewChunk) { chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + chunker.ForceNewChunk(); PaintChunk::Id id2(client_, DisplayItemType(20)); chunker.UpdateCurrentPaintChunkProperties(id2, DefaultPaintChunkProperties()); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id0, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(2, 4, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[2], PaintChunk(4, 6, id2, DefaultPaintChunkProperties())); +} + +TEST_F(PaintChunkerTest, ForceNewChunkWithoutNewId) { + PaintChunker chunker; + PaintChunk::Id id0(client_, DisplayItemType(0)); + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, + DefaultPaintChunkProperties()); + chunker.IncrementDisplayItemIndex( + TestChunkerDisplayItem(id0.client, id0.type)); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + + chunker.ForceNewChunk(); + PaintChunk::Id id1(client_, DisplayItemType(10)); + chunker.IncrementDisplayItemIndex( + TestChunkerDisplayItem(id1.client, id1.type)); + chunker.IncrementDisplayItemIndex( + TestChunkerDisplayItem(client_, DisplayItemType(11))); + chunker.ForceNewChunk(); + PaintChunk::Id id2(client_, DisplayItemType(20)); + chunker.IncrementDisplayItemIndex( + TestChunkerDisplayItem(id2.client, id2.type)); + chunker.IncrementDisplayItemIndex( + TestChunkerDisplayItem(client_, DisplayItemType(21))); + + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id0, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], PaintChunk(2, 4, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[2], PaintChunk(4, 6, id2, DefaultPaintChunkProperties())); +} + +TEST_F(PaintChunkerTest, NoNewChunkForSamePropertyDifferentIds) { + PaintChunker chunker; + PaintChunk::Id id0(client_, DisplayItemType(0)); + chunker.UpdateCurrentPaintChunkProperties(id0, DefaultPaintChunkProperties()); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + + PaintChunk::Id id1(client_, DisplayItemType(1)); + chunker.UpdateCurrentPaintChunkProperties(id1, DefaultPaintChunkProperties()); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); + + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, + DefaultPaintChunkProperties()); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT( - chunks, - ElementsAre(PaintChunk(0, 2, id0, DefaultPaintChunkProperties()), - PaintChunk(2, 4, id1, DefaultPaintChunkProperties()), - PaintChunk(4, 6, id2, DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 1u); + EXPECT_EQ(chunks[0], PaintChunk(0, 6, id0, DefaultPaintChunkProperties())); } class TestScrollHitTestRequiringSeparateChunk : public TestChunkerDisplayItem { @@ -348,13 +394,13 @@ TEST_F(PaintChunkerTest, ChunksFollowingForcedChunk) { chunker.IncrementDisplayItemIndex(after_forced1); chunker.IncrementDisplayItemIndex(after_forced2); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT(chunks, - ElementsAre(PaintChunk(0, 2, id0, DefaultPaintChunkProperties()), - PaintChunk(2, 3, forced.GetId(), - DefaultPaintChunkProperties()), - PaintChunk(3, 5, after_forced1.GetId(), - DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id0, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], + PaintChunk(2, 3, forced.GetId(), DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[2], PaintChunk(3, 5, after_forced1.GetId(), + DefaultPaintChunkProperties())); } TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) { @@ -365,12 +411,10 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) { chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); chunker.IncrementDisplayItemIndex(TestChunkerDisplayItem(client_)); - PaintChunkProperties simple_transform = DefaultPaintChunkProperties(); - simple_transform.property_tree_state.SetTransform( - TransformPaintPropertyNode::Create(nullptr, - TransformationMatrix(0, 1, 2, 3, 4, 5), - FloatPoint3D(9, 8, 7)) - .get()); + auto simple_transform_node = CreateTransform( + nullptr, TransformationMatrix(0, 1, 2, 3, 4, 5), FloatPoint3D(9, 8, 7)); + auto simple_transform = DefaultPaintChunkProperties(); + simple_transform.SetTransform(simple_transform_node.get()); PaintChunk::Id id2(client_, DisplayItemType(2)); chunker.UpdateCurrentPaintChunkProperties(id2, simple_transform); @@ -387,22 +431,22 @@ TEST_F(PaintChunkerTest, ChunkIdsSkippingCache) { TestChunkerDisplayItem after_separate_chunk(client_, DisplayItemType(3)); chunker.IncrementDisplayItemIndex(after_separate_chunk); - chunker.UpdateCurrentPaintChunkProperties(WTF::nullopt, + chunker.UpdateCurrentPaintChunkProperties(base::nullopt, DefaultPaintChunkProperties()); TestChunkerDisplayItem after_restore(client_, DisplayItemType(4)); chunker.IncrementDisplayItemIndex(after_restore); - Vector<PaintChunk> chunks = chunker.ReleasePaintChunks(); - EXPECT_THAT( - chunks, - ElementsAre( - PaintChunk(0, 2, id1, DefaultPaintChunkProperties()), - PaintChunk(2, 4, id2, simple_transform, PaintChunk::kUncacheable), - PaintChunk(4, 5, uncacheable_separate_chunk_item.GetId(), - simple_transform, PaintChunk::kUncacheable), - PaintChunk(5, 6, after_separate_chunk.GetId(), simple_transform), - PaintChunk(6, 7, after_restore.GetId(), - DefaultPaintChunkProperties()))); + const auto& chunks = chunker.PaintChunks(); + EXPECT_EQ(chunks.size(), 5u); + EXPECT_EQ(chunks[0], PaintChunk(0, 2, id1, DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[1], + PaintChunk(2, 4, id2, simple_transform, PaintChunk::kUncacheable)); + EXPECT_EQ(chunks[2], PaintChunk(4, 5, uncacheable_separate_chunk_item.GetId(), + simple_transform, PaintChunk::kUncacheable)); + EXPECT_EQ(chunks[3], + PaintChunk(5, 6, after_separate_chunk.GetId(), simple_transform)); + EXPECT_EQ(chunks[4], PaintChunk(6, 7, after_restore.GetId(), + DefaultPaintChunkProperties())); } } // namespace diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc index 8b5679c085d..16706fcb86f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.cc @@ -5,11 +5,11 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" #include <memory> +#include "base/auto_reset.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/graphics/logging_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/drawing_display_item.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -26,12 +26,9 @@ void PaintController::SetTracksRasterInvalidations(bool value) { raster_invalidation_tracking_info_->old_client_debug_names.Set( &item.Client(), item.Client().DebugName()); } - } else if (!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { + } else if (!RasterInvalidationTracking::ShouldAlwaysTrack()) { raster_invalidation_tracking_info_ = nullptr; } - - for (auto& chunk : current_paint_artifact_.PaintChunks()) - chunk.raster_invalidation_tracking.clear(); } void PaintController::EnsureRasterInvalidationTracking() { @@ -122,6 +119,16 @@ bool PaintController::UseCachedSubsequenceIfPossible( return false; } + if (current_paint_artifact_.GetDisplayItemList()[markers->start] + .IsTombstone()) { + // The subsequence has already been copied, indicating that the same client + // created multiple subsequences. If DCHECK_IS_ON(), then we should have + // encountered the DCHECK at the end of EndSubsequence() during the previous + // paint. + NOTREACHED(); + return false; + } + EnsureNewDisplayItemListInitialCapacity(); if (next_item_to_match_ == markers->start) { @@ -494,14 +501,14 @@ void PaintController::CopyCachedSubsequence(size_t begin_index, size_t end_index) { DCHECK(!RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()); - AutoReset<size_t> subsequence_begin_index( + base::AutoReset<size_t> subsequence_begin_index( ¤t_cached_subsequence_begin_index_in_new_list_, new_display_item_list_.size()); DisplayItem* cached_item = ¤t_paint_artifact_.GetDisplayItemList()[begin_index]; Vector<PaintChunk>::const_iterator cached_chunk; - PaintChunkProperties properties_before_subsequence; + base::Optional<PropertyTreeState> properties_before_subsequence; if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { cached_chunk = current_paint_artifact_.FindChunkByDisplayItemIndex(begin_index); @@ -509,9 +516,8 @@ void PaintController::CopyCachedSubsequence(size_t begin_index, properties_before_subsequence = new_paint_chunks_.CurrentPaintChunkProperties(); - new_paint_chunks_.ForceNewChunk(); UpdateCurrentPaintChunkPropertiesUsingIdWithFragment( - cached_chunk->id, cached_chunk->properties); + cached_chunk->id, cached_chunk->properties.GetPropertyTreeState()); } else { // Avoid uninitialized variable error on Windows. cached_chunk = current_paint_artifact_.PaintChunks().begin(); @@ -531,7 +537,7 @@ void PaintController::CopyCachedSubsequence(size_t begin_index, DCHECK(cached_chunk != current_paint_artifact_.PaintChunks().end()); new_paint_chunks_.ForceNewChunk(); UpdateCurrentPaintChunkPropertiesUsingIdWithFragment( - cached_chunk->id, cached_chunk->properties); + cached_chunk->id, cached_chunk->properties.GetPropertyTreeState()); } #if DCHECK_IS_ON() @@ -562,8 +568,8 @@ void PaintController::CopyCachedSubsequence(size_t begin_index, // Restore properties and force new chunk for any trailing display items // after the cached subsequence without new properties. new_paint_chunks_.ForceNewChunk(); - UpdateCurrentPaintChunkProperties(WTF::nullopt, - properties_before_subsequence); + UpdateCurrentPaintChunkProperties(base::nullopt, + *properties_before_subsequence); } } @@ -634,9 +640,8 @@ void PaintController::CommitNewDisplayItems() { // The new list will not be appended to again so we can release unused memory. new_display_item_list_.ShrinkToFit(); - current_paint_artifact_ = - PaintArtifact(std::move(new_display_item_list_), - new_paint_chunks_.ReleasePaintChunks()); + current_paint_artifact_ = PaintArtifact(std::move(new_display_item_list_), + new_paint_chunks_.ReleaseData()); ResetCurrentListIndices(); out_of_order_item_indices_.clear(); @@ -676,6 +681,13 @@ void PaintController::CommitNewDisplayItems() { #endif } +void PaintController::FinishCycle() { + DCHECK(new_display_item_list_.IsEmpty()); + DCHECK(new_paint_chunks_.IsInInitialState()); + + current_paint_artifact_.FinishCycle(); +} + size_t PaintController::ApproximateUnsharedMemoryUsage() const { size_t memory_usage = sizeof(*this); @@ -724,10 +736,9 @@ void PaintController::AppendDebugDrawingAfterCommit( if (property_tree_state) { DCHECK(RuntimeEnabledFeatures::SlimmingPaintV175Enabled()); // Create a PaintChunk for the debug drawing. - PaintChunk chunk(display_item_list.size() - 1, display_item_list.size(), - display_item.GetId(), - PaintChunkProperties(*property_tree_state)); - current_paint_artifact_.PaintChunks().push_back(chunk); + current_paint_artifact_.PaintChunks().emplace_back( + display_item_list.size() - 1, display_item_list.size(), + display_item.GetId(), *property_tree_state); } } @@ -784,8 +795,8 @@ void PaintController::AddRasterInvalidation(const DisplayItemClient& client, PaintChunk& chunk, const FloatRect& rect, PaintInvalidationReason reason) { - chunk.raster_invalidation_rects.push_back(rect); - if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) + new_paint_chunks_.AddRasterInvalidation(chunk, rect); + if (RasterInvalidationTracking::ShouldAlwaysTrack()) EnsureRasterInvalidationTracking(); if (raster_invalidation_tracking_info_) TrackRasterInvalidation(client, chunk, reason); @@ -814,7 +825,7 @@ void PaintController::TrackRasterInvalidation(const DisplayItemClient& client, info.client_debug_name = client.DebugName(); } - chunk.raster_invalidation_tracking.push_back(info); + new_paint_chunks_.TrackRasterInvalidation(chunk, info); } void PaintController::GenerateRasterInvalidationsComparingChunks( diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h index e2190272cf6..e9a8e1d3e39 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller.h @@ -75,8 +75,8 @@ class PLATFORM_EXPORT PaintController { // Provide a new set of paint chunk properties to apply to recorded display // items, for Slimming Paint v175+. void UpdateCurrentPaintChunkProperties( - const Optional<PaintChunk::Id>& id, - const PaintChunkProperties& properties) { + const base::Optional<PaintChunk::Id>& id, + const PropertyTreeState& properties) { if (id) { PaintChunk::Id id_with_fragment(*id, current_fragment_); UpdateCurrentPaintChunkPropertiesUsingIdWithFragment(id_with_fragment, @@ -85,15 +85,21 @@ class PLATFORM_EXPORT PaintController { CheckDuplicatePaintChunkId(id_with_fragment); #endif } else { - new_paint_chunks_.UpdateCurrentPaintChunkProperties(WTF::nullopt, + new_paint_chunks_.UpdateCurrentPaintChunkProperties(base::nullopt, properties); } } - const PaintChunkProperties& CurrentPaintChunkProperties() const { + const PropertyTreeState& CurrentPaintChunkProperties() const { return new_paint_chunks_.CurrentPaintChunkProperties(); } + void ForceNewChunk(const DisplayItemClient& client, DisplayItem::Type type) { + new_paint_chunks_.ForceNewChunk(); + new_paint_chunks_.UpdateCurrentPaintChunkProperties( + PaintChunk::Id(client, type), CurrentPaintChunkProperties()); + } + template <typename DisplayItemClass, typename... Args> void CreateAndAppend(Args&&... args) { static_assert(WTF::IsSubclass<DisplayItemClass, DisplayItem>::value, @@ -159,6 +165,11 @@ class PLATFORM_EXPORT PaintController { // Must be called when a painting is finished. void CommitNewDisplayItems(); + // Called when the caller finishes updating a full document life cycle. + // The PaintController will cleanup data that will no longer be used for the + // next cycle, and update status to be ready for the next cycle. + void FinishCycle(); + // Returns the approximate memory usage, excluding memory likely to be // shared with the embedder after copying to WebPaintController. // Should only be called after a full document life cycle update. @@ -295,7 +306,7 @@ class PLATFORM_EXPORT PaintController { void UpdateCurrentPaintChunkPropertiesUsingIdWithFragment( const PaintChunk::Id& id_with_fragment, - const PaintChunkProperties& properties) { + const PropertyTreeState& properties) { new_paint_chunks_.UpdateCurrentPaintChunkProperties(id_with_fragment, properties); } diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc index 611bb004452..3a7daf0a4a2 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_debug_data.cc @@ -131,8 +131,7 @@ void PaintController::DisplayItemListAsJSON::AppendSubsequenceAsJSON( json_object->SetString( "chunk", ClientName(chunk.id.client) + " " + chunk.id.ToString()); - json_object->SetString("state", - chunk.properties.property_tree_state.ToString()); + json_object->SetString("state", chunk.properties.ToString()); if (flags_ & DisplayItemList::kShowPaintRecords) json_object->SetString("chunkData", chunk.ToString()); diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc index 2bf51931fc5..ca3bad069f9 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.cc @@ -19,7 +19,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/testing/paint_test_configurations.h" -using blink::test::CreateOpacityOnlyEffect; +using testing::ElementsAre; using testing::UnorderedElementsAre; namespace blink { @@ -35,9 +35,11 @@ INSTANTIATE_TEST_CASE_P( PaintControllerTest, testing::Values(0, kSlimmingPaintV175, + kBlinkGenPropertyTrees, kSlimmingPaintV2, kUnderInvalidationChecking, kSlimmingPaintV175 | kUnderInvalidationChecking, + kBlinkGenPropertyTrees | kUnderInvalidationChecking, kSlimmingPaintV2 | kUnderInvalidationChecking)); TEST_P(PaintControllerTest, NestedRecorders) { @@ -59,9 +61,7 @@ TEST_P(PaintControllerTest, NestedRecorders) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); // Raster invalidation for the whole chunk will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); } else { EXPECT_DISPLAY_LIST( GetPaintController().GetDisplayItemList(), 3, @@ -94,9 +94,7 @@ TEST_P(PaintControllerTest, UpdateBasic) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); // Raster invalidation for the whole chunk will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); InitRootChunk(); } @@ -119,7 +117,7 @@ TEST_P(PaintControllerTest, UpdateBasic) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // |second| disappeared from the chunk. UnorderedElementsAre(FloatRect(100, 100, 200, 200))); } @@ -175,7 +173,7 @@ TEST_P(PaintControllerTest, UpdateSwapOrder) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Bounds of |second| (old and new are the same). UnorderedElementsAre(FloatRect(100, 100, 50, 200))); } @@ -232,7 +230,7 @@ TEST_P(PaintControllerTest, UpdateSwapOrderWithInvalidation) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Bounds of |first| (old and new are the same). UnorderedElementsAre(FloatRect(100, 100, 100, 100))); // No need to invalidate raster of |second|, because the client (|first|) @@ -277,7 +275,7 @@ TEST_P(PaintControllerTest, UpdateNewItemInMiddle) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // |third| newly appeared in the chunk. UnorderedElementsAre(FloatRect(125, 100, 200, 50))); } @@ -335,7 +333,7 @@ TEST_P(PaintControllerTest, UpdateInvalidationWithPhases) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Bounds of |second| (old and new are the same). UnorderedElementsAre(FloatRect(100, 100, 50, 200))); } @@ -372,7 +370,7 @@ TEST_P(PaintControllerTest, IncrementalRasterInvalidation) { GetPaintController().CommitNewDisplayItems(); EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre(FloatRect(200, 100, 50, 100), // 0: right FloatRect(100, 200, 100, 50), // 1: bottom FloatRect(200, 100, 50, 80), // 2: right @@ -422,7 +420,7 @@ TEST_P(PaintControllerTest, UpdateAddFirstOverlap) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); EXPECT_THAT( - GetPaintController().PaintChunks()[0].raster_invalidation_rects, + *GetRasterInvalidationRects(0), UnorderedElementsAre( // |first| newly appeared in the chunk. FloatRect(100, 100, 150, 150), @@ -450,7 +448,7 @@ TEST_P(PaintControllerTest, UpdateAddFirstOverlap) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // |first| disappeared from the chunk. UnorderedElementsAre(FloatRect(100, 100, 150, 150))); } @@ -490,7 +488,7 @@ TEST_P(PaintControllerTest, UpdateAddLastOverlap) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre( // The bigger of old and new bounds of |first|. FloatRect(100, 100, 150, 150), @@ -514,7 +512,7 @@ TEST_P(PaintControllerTest, UpdateAddLastOverlap) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre( // The bigger of old and new bounds of |first|. FloatRect(100, 100, 150, 150), @@ -528,14 +526,14 @@ TEST_P(PaintControllerTest, UpdateClip) { FakeDisplayItemClient second("second", LayoutRect(100, 100, 200, 200)); GraphicsContext context(GetPaintController()); - scoped_refptr<ClipPaintPropertyNode> clip = ClipPaintPropertyNode::Create( - nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2)); + scoped_refptr<ClipPaintPropertyNode> clip = + CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2)); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { PaintChunk::Id id(first, kClipType); - PaintChunkProperties properties = test::DefaultPaintChunkProperties(); - properties.property_tree_state.SetClip(clip.get()); + auto properties = DefaultPaintChunkProperties(); + properties.SetClip(clip.get()); GetPaintController().UpdateCurrentPaintChunkProperties(id, properties); } ClipRecorder clip_recorder(context, first, kClipType, IntRect(1, 1, 2, 2)); @@ -580,9 +578,7 @@ TEST_P(PaintControllerTest, UpdateClip) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); // This is a new chunk. Raster invalidation for the whole chunk will be // issued during PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); InitRootChunk(); } @@ -590,15 +586,14 @@ TEST_P(PaintControllerTest, UpdateClip) { second.SetDisplayItemsUncached(); DrawRect(context, first, kBackgroundType, FloatRect(100, 100, 150, 150)); - scoped_refptr<ClipPaintPropertyNode> clip2 = ClipPaintPropertyNode::Create( - nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2)); + scoped_refptr<ClipPaintPropertyNode> clip2 = + CreateClip(nullptr, nullptr, FloatRoundedRect(1, 1, 2, 2)); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { PaintChunk::Id id(second, kClipType); - PaintChunkProperties properties = test::DefaultPaintChunkProperties(); - properties.property_tree_state.SetClip(clip2.get()); - + auto properties = DefaultPaintChunkProperties(); + properties.SetClip(clip2.get()); GetPaintController().UpdateCurrentPaintChunkProperties(id, properties); } ClipRecorder clip_recorder(context, second, kClipType, IntRect(1, 1, 2, 2)); @@ -612,14 +607,12 @@ TEST_P(PaintControllerTest, UpdateClip) { TestDisplayItem(second, kBackgroundType)); EXPECT_EQ(2u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // |second| disappeared from the first chunk. UnorderedElementsAre(FloatRect(100, 100, 200, 200))); // This is a new chunk. Raster invalidation for the whole chunk will be // issued during PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[1] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(1)); } else { EXPECT_DISPLAY_LIST( GetPaintController().GetDisplayItemList(), 4, @@ -747,7 +740,7 @@ TEST_P(PaintControllerTest, UpdateSwapOrderWithChildren) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); EXPECT_THAT( - GetPaintController().PaintChunks()[0].raster_invalidation_rects, + *GetRasterInvalidationRects(0), UnorderedElementsAre( // Bounds of |container2| which was moved behind |container1|. FloatRect(100, 200, 100, 100), @@ -814,7 +807,7 @@ TEST_P(PaintControllerTest, UpdateSwapOrderWithChildrenAndInvalidation) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); EXPECT_THAT( - GetPaintController().PaintChunks()[0].raster_invalidation_rects, + *GetRasterInvalidationRects(0), UnorderedElementsAre( // Bounds of |container1| (old and new are the same). FloatRect(100, 100, 100, 100), @@ -833,18 +826,15 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) { GraphicsContext context(GetPaintController()); FakeDisplayItemClient root("root"); - auto root_properties = test::DefaultPaintChunkProperties(); + auto root_properties = DefaultPaintChunkProperties(); PaintChunk::Id root_id(root, DisplayItem::kCaret); - // Record a first chunk with backface_hidden == false GetPaintController().UpdateCurrentPaintChunkProperties(root_id, root_properties); DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100)); FakeDisplayItemClient container("container"); { - // Record a second chunk with backface_hidden == true - auto container_properties = test::DefaultPaintChunkProperties(); - container_properties.backface_hidden = true; + auto container_properties = DefaultPaintChunkProperties(); PaintChunk::Id container_id(container, DisplayItem::kCaret); SubsequenceRecorder r(context, container); @@ -860,8 +850,16 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) { GetPaintController().CommitNewDisplayItems(); - root_properties.backface_hidden = true; - // This time, record the fist chunk with backface_hidden == true + // Even though the paint properties match, |container| should receive its + // own PaintChunk because it created a subsequence. + EXPECT_EQ(3u, GetPaintController().GetPaintArtifact().PaintChunks().size()); + EXPECT_EQ(root, + GetPaintController().GetPaintArtifact().PaintChunks()[0].id.client); + EXPECT_EQ(container, + GetPaintController().GetPaintArtifact().PaintChunks()[1].id.client); + EXPECT_EQ(root, + GetPaintController().GetPaintArtifact().PaintChunks()[2].id.client); + GetPaintController().UpdateCurrentPaintChunkProperties(root_id, root_properties); DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100)); @@ -869,8 +867,8 @@ TEST_P(PaintControllerTest, CachedSubsequenceForcePaintChunk) { DrawRect(context, root, kForegroundType, FloatRect(100, 100, 100, 100)); GetPaintController().CommitNewDisplayItems(); - // Even though the paint properties match, |container| should receive its - // own PaintChunk because it is a cached subsequence. + // |container| should still receive its own PaintChunk because it is a cached + // subsequence. EXPECT_EQ(3u, GetPaintController().GetPaintArtifact().PaintChunks().size()); EXPECT_EQ(root, GetPaintController().GetPaintArtifact().PaintChunks()[0].id.client); @@ -889,18 +887,20 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) { FakeDisplayItemClient content2("content2", LayoutRect(100, 200, 50, 200)); GraphicsContext context(GetPaintController()); - PaintChunkProperties container1_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties container2_properties = - test::DefaultPaintChunkProperties(); + auto container1_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); + auto container1_properties = DefaultPaintChunkProperties(); + container1_properties.SetEffect(container1_effect.get()); + + auto container2_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); + auto container2_properties = DefaultPaintChunkProperties(); + container2_properties.SetEffect(container2_effect.get()); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kBackgroundType); - container1_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_properties); + PaintChunk::Id(container1, kBackgroundType), container1_properties); } SubsequenceRecorder r(context, container1); DrawRect(context, container1, kBackgroundType, @@ -912,11 +912,8 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) { } { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container2, kBackgroundType); - container2_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container2_properties); + PaintChunk::Id(container2, kBackgroundType), container2_properties); } SubsequenceRecorder r(context, container2); DrawRect(context, container2, kBackgroundType, @@ -957,12 +954,8 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) { GetPaintController().PaintChunks()[1].id); // Raster invalidation for the whole chunks will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[1] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); + EXPECT_FALSE(GetRasterInvalidationRects(1)); } // Simulate the situation when |container1| gets a z-index that is greater @@ -1050,10 +1043,8 @@ TEST_P(PaintControllerTest, CachedSubsequenceSwapOrder) { EXPECT_EQ(PaintChunk::Id(container1, kBackgroundType), GetPaintController().PaintChunks()[1].id); // Swapping order of chunks should not invalidate anything. - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, - UnorderedElementsAre()); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, - UnorderedElementsAre()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); + EXPECT_FALSE(GetRasterInvalidationRects(1)); } } @@ -1147,7 +1138,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceAndDisplayItemsSwapOrder) { EXPECT_EQ(4u, markers->end); } -TEST_P(PaintControllerTest, CachedSubsequenceWithFragments) { +TEST_P(PaintControllerTest, CachedSubsequenceContainingFragments) { if (!RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) return; @@ -1162,7 +1153,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceWithFragments) { for (size_t i = 0; i < kFragmentCount; ++i) { ScopedDisplayItemFragment scoped_fragment(context, i); ScopedPaintChunkProperties content_chunk_properties( - GetPaintController(), test::DefaultPaintChunkProperties(), container, + GetPaintController(), DefaultPaintChunkProperties(), container, kBackgroundType); DrawRect(context, container, kBackgroundType, FloatRect(100, 100, 100, 100)); @@ -1170,7 +1161,7 @@ TEST_P(PaintControllerTest, CachedSubsequenceWithFragments) { }; { ScopedPaintChunkProperties root_chunk_properties( - GetPaintController(), test::DefaultPaintChunkProperties(), root, + GetPaintController(), DefaultPaintChunkProperties(), root, kBackgroundType); DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100)); paint_container(); @@ -1178,29 +1169,26 @@ TEST_P(PaintControllerTest, CachedSubsequenceWithFragments) { } GetPaintController().CommitNewDisplayItems(); - // Check results of the first paint. - auto check_paint_results = [this, &root, &container, kFragmentCount]() { + auto check_paint_results = [this, &root, &container]() { const auto& chunks = GetPaintController().PaintChunks(); - ASSERT_EQ(2u + kFragmentCount, chunks.size()); - EXPECT_EQ(root, chunks[0].id.client); - EXPECT_EQ(kBackgroundType, chunks[0].id.type); - EXPECT_EQ(0u, chunks[0].id.fragment); - for (size_t i = 0; i < kFragmentCount; ++i) { - const auto& id = chunks[i + 1].id; - EXPECT_EQ(container, id.client); - EXPECT_EQ(kBackgroundType, id.type); - EXPECT_EQ(i, id.fragment); - } - EXPECT_EQ(root, chunks.back().id.client); - EXPECT_EQ(kForegroundType, chunks.back().id.type); - EXPECT_EQ(0u, chunks.back().id.fragment); + EXPECT_EQ(chunks.size(), 3u); + EXPECT_EQ(chunks[0], PaintChunk(0, 1, PaintChunk::Id(root, kBackgroundType), + DefaultPaintChunkProperties())); + // One chunk for all of the fragments because they have the + // same properties. + EXPECT_EQ(chunks[1], + PaintChunk(1, 4, PaintChunk::Id(container, kBackgroundType), + DefaultPaintChunkProperties())); + EXPECT_EQ(chunks[2], PaintChunk(4, 5, PaintChunk::Id(root, kForegroundType), + DefaultPaintChunkProperties())); }; + // Check results of the first paint. check_paint_results(); // The second paint. { ScopedPaintChunkProperties root_chunk_properties( - GetPaintController(), test::DefaultPaintChunkProperties(), root, + GetPaintController(), DefaultPaintChunkProperties(), root, kBackgroundType); DrawRect(context, root, kBackgroundType, FloatRect(100, 100, 100, 100)); @@ -1229,18 +1217,20 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) { FakeDisplayItemClient content2("content2", LayoutRect(100, 200, 50, 200)); GraphicsContext context(GetPaintController()); - PaintChunkProperties container1_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties container2_properties = - test::DefaultPaintChunkProperties(); + auto container1_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); + auto container1_properties = DefaultPaintChunkProperties(); + container1_properties.SetEffect(container1_effect.get()); + + auto container2_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); + auto container2_properties = DefaultPaintChunkProperties(); + container2_properties.SetEffect(container2_effect.get()); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kBackgroundType); - container1_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_properties); + PaintChunk::Id(container1, kBackgroundType), container1_properties); } DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100)); @@ -1248,11 +1238,8 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) { } { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container2, kBackgroundType); - container2_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container2_properties); + PaintChunk::Id(container2, kBackgroundType), container2_properties); } DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100)); @@ -1274,27 +1261,21 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) { GetPaintController().PaintChunks()[1].id); // Raster invalidation for the whole chunks will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[1] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); + EXPECT_FALSE(GetRasterInvalidationRects(1)); } // Move content2 into container1, without invalidation. if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kBackgroundType); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_properties); + PaintChunk::Id(container1, kBackgroundType), container1_properties); } DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100)); DrawRect(context, content1, kBackgroundType, FloatRect(100, 100, 50, 200)); DrawRect(context, content2, kBackgroundType, FloatRect(100, 200, 50, 200)); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container2, kBackgroundType); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container2_properties); + PaintChunk::Id(container2, kBackgroundType), container2_properties); } DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100)); @@ -1320,9 +1301,9 @@ TEST_P(PaintControllerTest, UpdateSwapOrderCrossingChunks) { EXPECT_EQ(PaintChunk::Id(container2, kBackgroundType), GetPaintController().PaintChunks()[1].id); // |content2| is invalidated raster on both the old chunk and the new chunk. - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre(FloatRect(100, 200, 50, 200))); - EXPECT_THAT(GetPaintController().PaintChunks()[1].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(1), UnorderedElementsAre(FloatRect(100, 200, 50, 200))); } } @@ -1365,36 +1346,42 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { FakeDisplayItemClient content2("content2", LayoutRect(100, 200, 50, 200)); GraphicsContext context(GetPaintController()); - PaintChunkProperties container1_background_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties content1_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties container1_foreground_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties container2_background_properties = - test::DefaultPaintChunkProperties(); - PaintChunkProperties content2_properties = - test::DefaultPaintChunkProperties(); + auto container1_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.5); + auto container1_background_properties = DefaultPaintChunkProperties(); + container1_background_properties.SetEffect(container1_effect.get()); + auto container1_foreground_properties = DefaultPaintChunkProperties(); + container1_foreground_properties.SetEffect(container1_effect.get()); + + auto content1_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.6); + auto content1_properties = DefaultPaintChunkProperties(); + content1_properties.SetEffect(content1_effect.get()); + + auto container2_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.7); + auto container2_background_properties = DefaultPaintChunkProperties(); + container2_background_properties.SetEffect(container2_effect.get()); + + auto content2_effect = + CreateOpacityEffect(EffectPaintPropertyNode::Root(), 0.8); + auto content2_properties = DefaultPaintChunkProperties(); + content2_properties.SetEffect(content2_effect.get()); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kBackgroundType); - container1_background_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_background_properties); + PaintChunk::Id(container1, kBackgroundType), + container1_background_properties); } SubsequenceRecorder r(context, container1); DrawRect(context, container1, kBackgroundType, FloatRect(100, 100, 100, 100)); + { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(content1, kBackgroundType); - content1_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.6) - .get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, content1_properties); + PaintChunk::Id(content1, kBackgroundType), content1_properties); } SubsequenceRecorder r(context, content1); DrawRect(context, content1, kBackgroundType, @@ -1403,34 +1390,26 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { FloatRect(100, 100, 50, 200)); } if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kForegroundType); - container1_foreground_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.5).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_foreground_properties); + PaintChunk::Id(container1, kForegroundType), + container1_foreground_properties); } DrawRect(context, container1, kForegroundType, FloatRect(100, 100, 100, 100)); } { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container2, kBackgroundType); - container2_background_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.7).get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container2_background_properties); + PaintChunk::Id(container2, kBackgroundType), + container2_background_properties); } SubsequenceRecorder r(context, container2); DrawRect(context, container2, kBackgroundType, FloatRect(100, 200, 100, 100)); { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(content2, kBackgroundType); - content2_properties.property_tree_state.SetEffect( - CreateOpacityOnlyEffect(EffectPaintPropertyNode::Root(), 0.8) - .get()); GetPaintController().UpdateCurrentPaintChunkProperties( - id, content2_properties); + PaintChunk::Id(content2, kBackgroundType), content2_properties); } SubsequenceRecorder r(context, content2); DrawRect(context, content2, kBackgroundType, @@ -1481,21 +1460,11 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { GetPaintController().PaintChunks()[4].id); // Raster invalidation for the whole chunks will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[1] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[2] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[3] - .raster_invalidation_rects.IsEmpty()); - EXPECT_TRUE(GetPaintController() - .PaintChunks()[4] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); + EXPECT_FALSE(GetRasterInvalidationRects(1)); + EXPECT_FALSE(GetRasterInvalidationRects(2)); + EXPECT_FALSE(GetRasterInvalidationRects(3)); + EXPECT_FALSE(GetRasterInvalidationRects(4)); } // Invalidate container1 but not content1. @@ -1513,9 +1482,8 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { // Content2 now outputs foreground only. { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(content2, kForegroundType); GetPaintController().UpdateCurrentPaintChunkProperties( - id, content2_properties); + PaintChunk::Id(content2, kForegroundType), content2_properties); } SubsequenceRecorder r(context, content2); DrawRect(context, content2, kForegroundType, FloatRect(100, 200, 50, 200)); @@ -1533,9 +1501,8 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { EXPECT_FALSE(SubsequenceRecorder::UseCachedSubsequenceIfPossible( context, content1)); if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(content1, kBackgroundType); GetPaintController().UpdateCurrentPaintChunkProperties( - id, content1_properties); + PaintChunk::Id(content1, kBackgroundType), content1_properties); } SubsequenceRecorder r(context, content1); DrawRect(context, content1, kBackgroundType, @@ -1547,9 +1514,9 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { context, content1)); } if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - PaintChunk::Id id(container1, kForegroundType); GetPaintController().UpdateCurrentPaintChunkProperties( - id, container1_foreground_properties); + PaintChunk::Id(container1, kForegroundType), + container1_foreground_properties); } DrawRect(context, container1, kForegroundType, FloatRect(100, 100, 100, 100)); @@ -1595,15 +1562,11 @@ TEST_P(PaintControllerTest, CachedNestedSubsequenceUpdate) { GetPaintController().PaintChunks()[2].id); // This is a new chunk. Raster invalidation of the whole chunk will be // issued during PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetRasterInvalidationRects(0)->IsEmpty()); // This chunk didn't change. - EXPECT_TRUE(GetPaintController() - .PaintChunks()[1] - .raster_invalidation_rects.IsEmpty()); + EXPECT_TRUE(GetRasterInvalidationRects(1)->IsEmpty()); // |container1| is invalidated. - EXPECT_THAT(GetPaintController().PaintChunks()[2].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(2), UnorderedElementsAre(FloatRect(100, 100, 100, 100))); } } @@ -1645,9 +1608,7 @@ TEST_P(PaintControllerTest, SkipCache) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); // Raster invalidation for the whole chunk will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); InitRootChunk(); } @@ -1683,7 +1644,7 @@ TEST_P(PaintControllerTest, SkipCache) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Bounds of |content| (old and new are the same); UnorderedElementsAre(FloatRect(100, 100, 100, 100))); @@ -1717,7 +1678,7 @@ TEST_P(PaintControllerTest, SkipCache) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { EXPECT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre( // Bounds of |multicol| (old and new are the same); FloatRect(100, 100, 200, 200), @@ -1857,10 +1818,7 @@ TEST_P(PaintControllerTest, SmallPaintControllerHasOnePaintChunk) { ScopedSlimmingPaintV2ForTest enable_s_pv2(true); FakeDisplayItemClient client("test client"); - if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { - GetPaintController().UpdateCurrentPaintChunkProperties( - WTF::nullopt, test::DefaultPaintChunkProperties()); - } + InitRootChunk(); GraphicsContext context(GetPaintController()); DrawRect(context, client, kBackgroundType, FloatRect(0, 0, 100, 100)); @@ -1950,9 +1908,7 @@ TEST_P(PaintControllerTest, PartialInvalidation) { ASSERT_EQ(1u, GetPaintController().PaintChunks().size()); // Raster invalidation for the whole new chunk will be issued during // PaintArtifactCompositor::Update(). - EXPECT_TRUE(GetPaintController() - .PaintChunks()[0] - .raster_invalidation_rects.IsEmpty()); + EXPECT_FALSE(GetRasterInvalidationRects(0)); EXPECT_EQ(LayoutRect(), client.PartialInvalidationRect()); // Test partial rect invalidation without other invalidations. @@ -1961,7 +1917,7 @@ TEST_P(PaintControllerTest, PartialInvalidation) { DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 300, 300)); GetPaintController().CommitNewDisplayItems(); ASSERT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Partial invalidation. UnorderedElementsAre( RuntimeEnabledFeatures::PartialRasterInvalidationEnabled() @@ -1976,7 +1932,7 @@ TEST_P(PaintControllerTest, PartialInvalidation) { DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 300, 300)); GetPaintController().CommitNewDisplayItems(); ASSERT_EQ(1u, GetPaintController().PaintChunks().size()); - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Partial invalidation is shadowed by full invalidation. UnorderedElementsAre(FloatRect(100, 100, 300, 300))); EXPECT_EQ(LayoutRect(), client.PartialInvalidationRect()); @@ -1989,12 +1945,12 @@ TEST_P(PaintControllerTest, PartialInvalidation) { GetPaintController().CommitNewDisplayItems(); ASSERT_EQ(1u, GetPaintController().PaintChunks().size()); if (RuntimeEnabledFeatures::PartialRasterInvalidationEnabled()) { - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), // Both partial invalidation and incremental invalidation. UnorderedElementsAre(FloatRect(100, 400, 300, 100), FloatRect(150, 160, 170, 180))); } else { - EXPECT_THAT(GetPaintController().PaintChunks()[0].raster_invalidation_rects, + EXPECT_THAT(*GetRasterInvalidationRects(0), UnorderedElementsAre(FloatRect(100, 100, 300, 400))); } EXPECT_EQ(LayoutRect(), client.PartialInvalidationRect()); @@ -2032,6 +1988,49 @@ TEST_P(PaintControllerTest, InvalidateAll) { // Death tests don't work properly on Android. #if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID) +TEST_P(PaintControllerTest, DuplicatedSubsequences) { + FakeDisplayItemClient client("test", LayoutRect(100, 100, 100, 100)); + GraphicsContext context(GetPaintController()); + + auto paint_duplicated_subsequences = [&]() { + InitRootChunk(); + { + SubsequenceRecorder r(context, client); + DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 100, 100)); + } + { + SubsequenceRecorder r(context, client); + DrawRect(context, client, kForegroundType, FloatRect(100, 100, 100, 100)); + } + GetPaintController().CommitNewDisplayItems(); + }; + +#if DCHECK_IS_ON() + EXPECT_DEATH(paint_duplicated_subsequences(), + "Multiple subsequences for client: \"test\""); + return; +#endif + + // The following is for non-DCHECK path. No security CHECK should trigger. + paint_duplicated_subsequences(); + // Paint again. + InitRootChunk(); + if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) { + EXPECT_FALSE(GetPaintController().UseCachedSubsequenceIfPossible(client)); + SubsequenceRecorder r(context, client); + DrawRect(context, client, kBackgroundType, FloatRect(100, 100, 100, 100)); + } else { + EXPECT_TRUE(GetPaintController().UseCachedSubsequenceIfPossible(client)); + } + { + // Should not use the cached duplicated subsequence. + EXPECT_FALSE(GetPaintController().UseCachedSubsequenceIfPossible(client)); + SubsequenceRecorder r(context, client); + DrawRect(context, client, kForegroundType, FloatRect(100, 100, 100, 100)); + } + GetPaintController().CommitNewDisplayItems(); +} + class PaintControllerUnderInvalidationTest : public PaintControllerTestBase, private ScopedPaintUnderInvalidationCheckingForTest { diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h index f5f06c69e3f..e7a0d4c4b83 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_controller_test.h @@ -46,7 +46,7 @@ class PaintControllerTestBase : public testing::Test { void InitRootChunk() { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { GetPaintController().UpdateCurrentPaintChunkProperties( - root_paint_chunk_id_, test::DefaultPaintChunkProperties()); + root_paint_chunk_id_, DefaultPaintChunkProperties()); } } @@ -83,6 +83,11 @@ class PaintControllerTestBase : public testing::Test { return ClientCacheIsValid(*paint_controller_, client); } + const ChunkRasterInvalidationRects* GetRasterInvalidationRects(size_t i) { + return GetPaintController().GetPaintArtifact().GetRasterInvalidationRects( + i); + } + private: FakeDisplayItemClient root_paint_property_client_; PaintChunk::Id root_paint_chunk_id_; @@ -95,8 +100,8 @@ class TestDisplayItem final : public DisplayItem { : DisplayItem(client, type, sizeof(*this)) {} void Replay(GraphicsContext&) const final { NOTREACHED(); } - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const final { + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const final { NOTREACHED(); } }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h index fa6ea39b181..cd010c4c3c5 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node.h @@ -16,6 +16,8 @@ #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #endif +#include <iosfwd> + namespace blink { class ClipPaintPropertyNode; @@ -114,9 +116,9 @@ class PaintPropertyNode : public RefCounted<NodeType> { protected: PaintPropertyNode(scoped_refptr<const NodeType> parent) - : parent_(std::move(parent)), changed_(false) {} + : parent_(std::move(parent)) {} - bool Update(scoped_refptr<const NodeType> parent) { + bool SetParent(scoped_refptr<const NodeType> parent) { DCHECK(!IsRoot()); DCHECK(parent != this); if (parent == parent_) @@ -131,7 +133,7 @@ class PaintPropertyNode : public RefCounted<NodeType> { private: scoped_refptr<const NodeType> parent_; - mutable bool changed_; + mutable bool changed_ = true; #if DCHECK_IS_ON() String debug_name_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc index b9b51f0e5bd..88820aa6095 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_property_node_test.cc @@ -7,6 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/geometry/float_rounded_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" +#include "third_party/blink/renderer/platform/testing/paint_property_test_helpers.h" namespace blink { @@ -14,13 +15,11 @@ class PaintPropertyNodeTest : public testing::Test { protected: void SetUp() override { root = ClipPaintPropertyNode::Root(); - node = ClipPaintPropertyNode::Create(root, nullptr, FloatRoundedRect()); - child1 = ClipPaintPropertyNode::Create(node, nullptr, FloatRoundedRect()); - child2 = ClipPaintPropertyNode::Create(node, nullptr, FloatRoundedRect()); - grandchild1 = - ClipPaintPropertyNode::Create(child1, nullptr, FloatRoundedRect()); - grandchild2 = - ClipPaintPropertyNode::Create(child2, nullptr, FloatRoundedRect()); + node = CreateClip(root, nullptr, FloatRoundedRect()); + child1 = CreateClip(node, nullptr, FloatRoundedRect()); + child2 = CreateClip(node, nullptr, FloatRoundedRect()); + grandchild1 = CreateClip(child1, nullptr, FloatRoundedRect()); + grandchild2 = CreateClip(child2, nullptr, FloatRoundedRect()); // root // | @@ -36,8 +35,24 @@ class PaintPropertyNodeTest : public testing::Test { grandchild2->ClearChangedToRoot(); } + static void Update(scoped_refptr<ClipPaintPropertyNode> node, + scoped_refptr<const ClipPaintPropertyNode> new_parent, + const FloatRoundedRect& new_clip_rect) { + node->Update(std::move(new_parent), + ClipPaintPropertyNode::State{nullptr, new_clip_rect}); + } + void ExpectInitialState() { EXPECT_FALSE(root->Changed(*root)); + EXPECT_TRUE(node->Changed(*root)); + EXPECT_TRUE(child1->Changed(*node)); + EXPECT_TRUE(child2->Changed(*node)); + EXPECT_TRUE(grandchild1->Changed(*child1)); + EXPECT_TRUE(grandchild2->Changed(*child2)); + } + + void ExpectUnchangedState() { + EXPECT_FALSE(root->Changed(*root)); EXPECT_FALSE(node->Changed(*root)); EXPECT_FALSE(child1->Changed(*root)); EXPECT_FALSE(child2->Changed(*root)); @@ -74,11 +89,12 @@ TEST_F(PaintPropertyNodeTest, LowestCommonAncestor) { TEST_F(PaintPropertyNodeTest, InitialStateAndReset) { ExpectInitialState(); ResetAllChanged(); - ExpectInitialState(); + ExpectUnchangedState(); } TEST_F(PaintPropertyNodeTest, ChangeNode) { - node->Update(root, nullptr, FloatRoundedRect(1, 2, 3, 4)); + ResetAllChanged(); + Update(node, root, FloatRoundedRect(1, 2, 3, 4)); EXPECT_TRUE(node->Changed(*root)); EXPECT_FALSE(node->Changed(*node)); EXPECT_TRUE(child1->Changed(*root)); @@ -90,11 +106,12 @@ TEST_F(PaintPropertyNodeTest, ChangeNode) { EXPECT_FALSE(grandchild1->Changed(*grandchild2)); ResetAllChanged(); - ExpectInitialState(); + ExpectUnchangedState(); } TEST_F(PaintPropertyNodeTest, ChangeOneChild) { - child1->Update(node, nullptr, FloatRoundedRect(1, 2, 3, 4)); + ResetAllChanged(); + Update(child1, node, FloatRoundedRect(1, 2, 3, 4)); EXPECT_FALSE(node->Changed(*root)); EXPECT_FALSE(node->Changed(*node)); EXPECT_TRUE(child1->Changed(*root)); @@ -114,11 +131,12 @@ TEST_F(PaintPropertyNodeTest, ChangeOneChild) { EXPECT_TRUE(grandchild2->Changed(*grandchild1)); ResetAllChanged(); - ExpectInitialState(); + ExpectUnchangedState(); } TEST_F(PaintPropertyNodeTest, Reparent) { - child1->Update(child2, nullptr, FloatRoundedRect(1, 2, 3, 4)); + ResetAllChanged(); + Update(child1, child2, FloatRoundedRect(1, 2, 3, 4)); EXPECT_FALSE(node->Changed(*root)); EXPECT_TRUE(child1->Changed(*node)); EXPECT_TRUE(child1->Changed(*child2)); @@ -128,7 +146,7 @@ TEST_F(PaintPropertyNodeTest, Reparent) { EXPECT_TRUE(grandchild1->Changed(*child2)); ResetAllChanged(); - ExpectInitialState(); + ExpectUnchangedState(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc index 97b549c0a19..ddf2f3433c1 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.cc @@ -28,7 +28,7 @@ PaintRecordBuilder::PaintRecordBuilder(SkMetaData* meta_data, if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { paint_controller_->UpdateCurrentPaintChunkProperties( - WTF::nullopt, PaintChunkProperties(PropertyTreeState::Root())); + base::nullopt, PropertyTreeState::Root()); } const HighContrastSettings* high_contrast_settings = 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 744bb330022..9365ce05d7b 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 @@ -67,7 +67,7 @@ class PLATFORM_EXPORT PaintRecordBuilder final : public DisplayItemClient { PaintController* paint_controller_; std::unique_ptr<PaintController> own_paint_controller_; std::unique_ptr<GraphicsContext> context_; - Optional<DisplayItemCacheSkipper> cache_skipper_; + base::Optional<DisplayItemCacheSkipper> cache_skipper_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc index df7646149b2..ec9bd09306e 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/paint_record_builder_test.cc @@ -36,7 +36,7 @@ TEST_F(PaintRecordBuilderTest, TransientPaintController) { TEST_F(PaintRecordBuilderTest, LastingPaintController) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { GetPaintController().UpdateCurrentPaintChunkProperties( - WTF::nullopt, PaintChunkProperties(PropertyTreeState::Root())); + base::nullopt, PropertyTreeState::Root()); } PaintRecordBuilder builder(nullptr, nullptr, &GetPaintController()); @@ -60,7 +60,7 @@ TEST_F(PaintRecordBuilderTest, LastingPaintController) { if (RuntimeEnabledFeatures::SlimmingPaintV175Enabled()) { GetPaintController().UpdateCurrentPaintChunkProperties( - WTF::nullopt, PaintChunkProperties(PropertyTreeState::Root())); + base::nullopt, PropertyTreeState::Root()); } EXPECT_TRUE(DrawingRecorder::UseCachedDrawingIfPossible(context, client, diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc index 096ddf9f3a5..736b61c2c61 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.cc @@ -54,4 +54,9 @@ String PropertyTreeState::ToTreeString() const { #endif +size_t PropertyTreeState::CacheMemoryUsageInBytes() const { + return Clip()->CacheMemoryUsageInBytes() + + Transform()->CacheMemoryUsageInBytes(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h index 55650c5cf7b..521aa15cd49 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state.h @@ -58,6 +58,10 @@ class PLATFORM_EXPORT PropertyTreeState { String ToTreeString() const; #endif + // Returns memory usage of the transform & clip caches of this state plus + // ancestors. + size_t CacheMemoryUsageInBytes() const; + private: const TransformPaintPropertyNode* transform_; const ClipPaintPropertyNode* clip_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state_test.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state_test.cc index d6850e89221..26bf33b13ae 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/property_tree_state_test.cc @@ -10,6 +10,24 @@ namespace blink { class PropertyTreeStateTest : public testing::Test {}; +static scoped_refptr<TransformPaintPropertyNode> +CreateTransformWithCompositorElementId( + const CompositorElementId& compositor_element_id) { + TransformPaintPropertyNode::State state; + state.compositor_element_id = compositor_element_id; + return TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), + std::move(state)); +} + +static scoped_refptr<EffectPaintPropertyNode> +CreateEffectWithCompositorElementId( + const CompositorElementId& compositor_element_id) { + EffectPaintPropertyNode::State state; + state.compositor_element_id = compositor_element_id; + return EffectPaintPropertyNode::Create(EffectPaintPropertyNode::Root(), + std::move(state)); +} + TEST_F(PropertyTreeStateTest, CompositorElementIdNoElementIdOnAnyNode) { PropertyTreeState state(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), @@ -21,10 +39,7 @@ TEST_F(PropertyTreeStateTest, CompositorElementIdNoElementIdOnAnyNode) { TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnTransformNode) { CompositorElementId expected_compositor_element_id = CompositorElementId(2); scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix(), FloatPoint3D(), - false, 0, CompositingReason::kNone, - expected_compositor_element_id); + CreateTransformWithCompositorElementId(expected_compositor_element_id); PropertyTreeState state(transform.get(), ClipPaintPropertyNode::Root(), EffectPaintPropertyNode::Root()); EXPECT_EQ(expected_compositor_element_id, @@ -34,11 +49,7 @@ TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnTransformNode) { TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnEffectNode) { CompositorElementId expected_compositor_element_id = CompositorElementId(2); scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 1.0, SkBlendMode::kSrcOver, - CompositingReason::kNone, expected_compositor_element_id); + CreateEffectWithCompositorElementId(expected_compositor_element_id); PropertyTreeState state(TransformPaintPropertyNode::Root(), ClipPaintPropertyNode::Root(), effect.get()); EXPECT_EQ(expected_compositor_element_id, @@ -48,16 +59,9 @@ TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnEffectNode) { TEST_F(PropertyTreeStateTest, CompositorElementIdWithElementIdOnMultipleNodes) { CompositorElementId expected_compositor_element_id = CompositorElementId(2); scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix(), FloatPoint3D(), - false, 0, CompositingReason::kNone, - expected_compositor_element_id); + CreateTransformWithCompositorElementId(expected_compositor_element_id); scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 1.0, SkBlendMode::kSrcOver, - CompositingReason::kNone, expected_compositor_element_id); + CreateEffectWithCompositorElementId(expected_compositor_element_id); PropertyTreeState state(transform.get(), ClipPaintPropertyNode::Root(), effect.get()); EXPECT_EQ(expected_compositor_element_id, @@ -68,16 +72,9 @@ TEST_F(PropertyTreeStateTest, CompositorElementIdWithDifferingElementIds) { CompositorElementId first_compositor_element_id = CompositorElementId(2); CompositorElementId second_compositor_element_id = CompositorElementId(3); scoped_refptr<TransformPaintPropertyNode> transform = - TransformPaintPropertyNode::Create(TransformPaintPropertyNode::Root(), - TransformationMatrix(), FloatPoint3D(), - false, 0, CompositingReason::kNone, - first_compositor_element_id); + CreateTransformWithCompositorElementId(first_compositor_element_id); scoped_refptr<EffectPaintPropertyNode> effect = - EffectPaintPropertyNode::Create( - EffectPaintPropertyNode::Root(), TransformPaintPropertyNode::Root(), - ClipPaintPropertyNode::Root(), kColorFilterNone, - CompositorFilterOperations(), 1.0, SkBlendMode::kSrcOver, - CompositingReason::kNone, second_compositor_element_id); + CreateEffectWithCompositorElementId(second_compositor_element_id); PropertyTreeState state(transform.get(), ClipPaintPropertyNode::Root(), effect.get()); 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 a5a9e132de1..4cf2f05cb2e 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 @@ -5,11 +5,15 @@ #include "third_party/blink/renderer/platform/graphics/paint/raster_invalidation_tracking.h" #include "SkImageFilter.h" +#include "base/trace_event/trace_event_argument.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" #include "third_party/blink/renderer/platform/graphics/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_recorder.h" +#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/text/string_utf8_adaptor.h" namespace blink { @@ -19,6 +23,16 @@ void RasterInvalidationTracking::SimulateRasterUnderInvalidations(bool enable) { g_simulate_raster_under_invalidations = enable; } +bool RasterInvalidationTracking::ShouldAlwaysTrack() { + if (RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled()) + return true; + + bool tracing_enabled; + TRACE_EVENT_CATEGORY_GROUP_ENABLED( + TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), &tracing_enabled); + return tracing_enabled; +} + void RasterInvalidationTracking::AddInvalidation( const DisplayItemClient* client, const String& debug_name, @@ -105,6 +119,38 @@ 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); + 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(); + } + traced_value.EndArray(); +} + static bool PixelComponentsDiffer(int c1, int c2) { // Compare strictly for saturated values. if (c1 == 0 || c1 == 255 || c2 == 0 || c2 == 255) 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 cba2bac99b4..00ffa55fcec 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,6 +14,12 @@ #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 base + namespace blink { class DisplayItemClient; @@ -30,11 +36,6 @@ struct RasterInvalidationInfo { PaintInvalidationReason reason = PaintInvalidationReason::kFull; }; -inline bool operator==(const RasterInvalidationInfo& a, - const RasterInvalidationInfo& b) { - return a.rect == b.rect; -} - struct RasterUnderInvalidation { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); int x; @@ -48,11 +49,16 @@ class PLATFORM_EXPORT RasterInvalidationTracking { DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); // When RuntimeEnabledFeatures::PaintUnderInvalidationCheckingEnabled() and - // simulateRasterUnderInvalidation(true) is called, all changed pixels will + // SimulateRasterUnderInvalidation(true) is called, all changed pixels will // be reported as raster under-invalidations. Used to visually test raster // under-invalidation checking feature. static void SimulateRasterUnderInvalidations(bool enable); + // Whether we should always track because RuntimeEnabledFeatures:: + // PaintUnderInvalidationCheckingEnabled() is true, or we are tracing + // "disabled-by-default-blink.invalidation" category. + static bool ShouldAlwaysTrack(); + void AddInvalidation(const DisplayItemClient*, const String& debug_name, const IntRect&, @@ -73,6 +79,7 @@ class PLATFORM_EXPORT RasterInvalidationTracking { const IntRect& new_interest_rect); void AsJSON(JSONObject*); + void AddToTracedValue(base::trace_event::TracedValue&); // 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/scoped_paint_chunk_properties.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h index 9e9d2bfd0fa..4a7d064377e 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scoped_paint_chunk_properties.h @@ -5,13 +5,13 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCOPED_PAINT_CHUNK_PROPERTIES_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_PAINT_SCOPED_PAINT_CHUNK_PROPERTIES_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_chunk.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_controller.h" +#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { @@ -20,9 +20,9 @@ class ScopedPaintChunkProperties { WTF_MAKE_NONCOPYABLE(ScopedPaintChunkProperties); public: - // Use new PaintChunkProperties for the scope. + // Use new PropertyTreeState for the scope. ScopedPaintChunkProperties(PaintController& paint_controller, - const PaintChunkProperties& properties, + const PropertyTreeState& properties, const DisplayItemClient& client, DisplayItem::Type type) : paint_controller_(paint_controller), @@ -31,32 +31,20 @@ class ScopedPaintChunkProperties { PaintChunk::Id(client, type), properties); } - // Use new PropertyTreeState, and keep the current backface_hidden. + // Use new transform state, and keep the current other properties. ScopedPaintChunkProperties(PaintController& paint_controller, - const PropertyTreeState& state, + const TransformPaintPropertyNode* transform, const DisplayItemClient& client, DisplayItem::Type type) : ScopedPaintChunkProperties( paint_controller, - GetPaintChunkProperties(state, paint_controller), - client, - type) {} - - // Use new transform state, and keep the current other properties. - ScopedPaintChunkProperties( - PaintController& paint_controller, - scoped_refptr<const TransformPaintPropertyNode> transform, - const DisplayItemClient& client, - DisplayItem::Type type) - : ScopedPaintChunkProperties( - paint_controller, GetPaintChunkProperties(transform, paint_controller), client, type) {} // Use new clip state, and keep the current other properties. ScopedPaintChunkProperties(PaintController& paint_controller, - scoped_refptr<const ClipPaintPropertyNode> clip, + const ClipPaintPropertyNode* clip, const DisplayItemClient& client, DisplayItem::Type type) : ScopedPaintChunkProperties( @@ -66,11 +54,10 @@ class ScopedPaintChunkProperties { type) {} // Use new effect state, and keep the current other properties. - ScopedPaintChunkProperties( - PaintController& paint_controller, - scoped_refptr<const EffectPaintPropertyNode> effect, - const DisplayItemClient& client, - DisplayItem::Type type) + ScopedPaintChunkProperties(PaintController& paint_controller, + const EffectPaintPropertyNode* effect, + const DisplayItemClient& client, + DisplayItem::Type type) : ScopedPaintChunkProperties( paint_controller, GetPaintChunkProperties(effect, paint_controller), @@ -83,49 +70,40 @@ class ScopedPaintChunkProperties { // ScopedPaintChunkProperties. The painter should create another scope of // paint properties with new id, or the new chunk will use the id of the // first display item as its id. - paint_controller_.UpdateCurrentPaintChunkProperties(WTF::nullopt, + paint_controller_.UpdateCurrentPaintChunkProperties(base::nullopt, previous_properties_); } private: - static PaintChunkProperties GetPaintChunkProperties( - const PropertyTreeState& state, - PaintController& paint_controller) { - PaintChunkProperties properties(state); - properties.backface_hidden = - paint_controller.CurrentPaintChunkProperties().backface_hidden; - return properties; - } - - static PaintChunkProperties GetPaintChunkProperties( - scoped_refptr<const TransformPaintPropertyNode> transform, + static PropertyTreeState GetPaintChunkProperties( + const TransformPaintPropertyNode* transform, PaintController& paint_controller) { - PaintChunkProperties properties( + PropertyTreeState properties( paint_controller.CurrentPaintChunkProperties()); - properties.property_tree_state.SetTransform(std::move(transform)); + properties.SetTransform(transform); return properties; } - static PaintChunkProperties GetPaintChunkProperties( - scoped_refptr<const ClipPaintPropertyNode> clip, + static PropertyTreeState GetPaintChunkProperties( + const ClipPaintPropertyNode* clip, PaintController& paint_controller) { - PaintChunkProperties properties( + PropertyTreeState properties( paint_controller.CurrentPaintChunkProperties()); - properties.property_tree_state.SetClip(std::move(clip)); + properties.SetClip(clip); return properties; } - static PaintChunkProperties GetPaintChunkProperties( - scoped_refptr<const EffectPaintPropertyNode> effect, + static PropertyTreeState GetPaintChunkProperties( + const EffectPaintPropertyNode* effect, PaintController& paint_controller) { - PaintChunkProperties properties( + PropertyTreeState properties( paint_controller.CurrentPaintChunkProperties()); - properties.property_tree_state.SetEffect(std::move(effect)); + properties.SetEffect(effect); return properties; } PaintController& paint_controller_; - PaintChunkProperties previous_properties_; + PropertyTreeState previous_properties_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.cc index 3e52d0ab021..673094d245b 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.cc @@ -4,9 +4,8 @@ #include "third_party/blink/renderer/platform/graphics/paint/scroll_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" -#include "third_party/blink/renderer/platform/transforms/affine_transform.h" namespace blink { @@ -15,11 +14,14 @@ void BeginScrollDisplayItem::Replay(GraphicsContext& context) const { context.Translate(-current_offset_.Width(), -current_offset_.Height()); } -void BeginScrollDisplayItem::AppendToWebDisplayItemList( +void BeginScrollDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - WebDisplayItemList::ScrollContainerId scroll_container_id = &Client(); - list->AppendScrollItem(current_offset_, scroll_container_id); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::SaveOp>(); + list.push<cc::TranslateOp>(static_cast<float>(-current_offset_.Width()), + static_cast<float>(-current_offset_.Height())); + list.EndPaintOfPairedBegin(); } #if DCHECK_IS_ON() @@ -33,10 +35,12 @@ void EndScrollDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndScrollDisplayItem::AppendToWebDisplayItemList( +void EndScrollDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndScrollItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.h index b0dfdcb03c6..c4136bbebb2 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_display_item.h @@ -23,8 +23,8 @@ class PLATFORM_EXPORT BeginScrollDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; const IntSize& CurrentOffset() const { return current_offset_; } @@ -49,8 +49,8 @@ class PLATFORM_EXPORT EndScrollDisplayItem final : public PairedEndDisplayItem { } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc index 468952c4a0d..8426d1f928c 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.cc @@ -28,9 +28,9 @@ void ScrollHitTestDisplayItem::Replay(GraphicsContext&) const { NOTREACHED(); } -void ScrollHitTestDisplayItem::AppendToWebDisplayItemList( +void ScrollHitTestDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList*) const { + cc::DisplayItemList&) const { NOTREACHED(); } @@ -57,8 +57,8 @@ void ScrollHitTestDisplayItem::Record( // The scroll hit test should be in the non-scrolled transform space and // therefore should not be scrolled by the associated scroll offset. - DCHECK(paint_controller.CurrentPaintChunkProperties() - .property_tree_state.Transform() != scroll_offset_node); + DCHECK_NE(paint_controller.CurrentPaintChunkProperties().Transform(), + scroll_offset_node.get()); if (paint_controller.DisplayItemConstructionIsDisabled()) return; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h index 234b1b33932..fb9b5cd7a02 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_hit_test_display_item.h @@ -28,7 +28,7 @@ class PLATFORM_EXPORT ScrollHitTestDisplayItem final : public DisplayItem { const DisplayItemClient&, Type, scoped_refptr<const TransformPaintPropertyNode> scroll_offset_node); - ~ScrollHitTestDisplayItem(); + ~ScrollHitTestDisplayItem() override; const TransformPaintPropertyNode& scroll_offset_node() const { return *scroll_offset_node_; @@ -36,8 +36,8 @@ class PLATFORM_EXPORT ScrollHitTestDisplayItem final : public DisplayItem { // DisplayItem void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; bool Equals(const DisplayItem&) const override; #if DCHECK_IS_ON() void PropertiesAsJSON(JSONObject&) const override; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc index 9acec3301c5..0329c33a0f4 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.cc @@ -8,10 +8,7 @@ namespace blink { ScrollPaintPropertyNode* ScrollPaintPropertyNode::Root() { DEFINE_STATIC_REF(ScrollPaintPropertyNode, root, - (ScrollPaintPropertyNode::Create( - nullptr, IntRect(), IntRect(), false, false, - MainThreadScrollingReason::kNotScrollingOnMain, - CompositorElementId()))); + (ScrollPaintPropertyNode::Create(nullptr, State{}))); return root; } @@ -19,25 +16,26 @@ std::unique_ptr<JSONObject> ScrollPaintPropertyNode::ToJSON() const { auto json = JSONObject::Create(); if (Parent()) json->SetString("parent", String::Format("%p", Parent())); - if (container_rect_ != IntRect()) - json->SetString("containerRect", container_rect_.ToString()); - if (contents_rect_ != IntRect()) - json->SetString("contentsRect", contents_rect_.ToString()); - if (user_scrollable_horizontal_ || user_scrollable_vertical_) { - json->SetString("userScrollable", - user_scrollable_horizontal_ - ? (user_scrollable_vertical_ ? "both" : "horizontal") - : "vertical"); + if (state_.container_rect != IntRect()) + json->SetString("containerRect", state_.container_rect.ToString()); + if (state_.contents_rect != IntRect()) + json->SetString("contentsRect", state_.contents_rect.ToString()); + if (state_.user_scrollable_horizontal || state_.user_scrollable_vertical) { + json->SetString( + "userScrollable", + state_.user_scrollable_horizontal + ? (state_.user_scrollable_vertical ? "both" : "horizontal") + : "vertical"); } - if (main_thread_scrolling_reasons_) { - json->SetString("mainThreadReasons", - MainThreadScrollingReason::mainThreadScrollingReasonsAsText( - main_thread_scrolling_reasons_) - .c_str()); + if (state_.main_thread_scrolling_reasons) { + json->SetString( + "mainThreadReasons", + MainThreadScrollingReason::AsText(state_.main_thread_scrolling_reasons) + .c_str()); } - if (compositor_element_id_) { + if (state_.compositor_element_id) { json->SetString("compositorElementId", - compositor_element_id_.ToString().c_str()); + state_.compositor_element_id.ToString().c_str()); } return json; } diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h index 72ead3e6a20..80bdd359d10 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h @@ -12,9 +12,6 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -#include <iosfwd> namespace blink { @@ -35,47 +32,48 @@ using MainThreadScrollingReasons = uint32_t; class PLATFORM_EXPORT ScrollPaintPropertyNode : public PaintPropertyNode<ScrollPaintPropertyNode> { public: + // To make it less verbose and more readable to construct and update a node, + // a struct with default values is used to represent the state. + struct State { + IntRect container_rect; + IntRect contents_rect; + bool user_scrollable_horizontal = false; + bool user_scrollable_vertical = false; + MainThreadScrollingReasons main_thread_scrolling_reasons = + MainThreadScrollingReason::kNotScrollingOnMain; + // The scrolling element id is stored directly on the scroll node and not on + // the associated TransformPaintPropertyNode used for scroll offset. + CompositorElementId compositor_element_id; + + bool operator==(const State& o) const { + return container_rect == o.container_rect && + contents_rect == o.contents_rect && + user_scrollable_horizontal == o.user_scrollable_horizontal && + user_scrollable_vertical == o.user_scrollable_vertical && + main_thread_scrolling_reasons == o.main_thread_scrolling_reasons && + compositor_element_id == o.compositor_element_id; + } + }; + // This node is really a sentinel, and does not represent a real scroll. static ScrollPaintPropertyNode* Root(); static scoped_refptr<ScrollPaintPropertyNode> Create( scoped_refptr<const ScrollPaintPropertyNode> parent, - const IntRect& container_rect, - const IntRect& contents_rect, - bool user_scrollable_horizontal, - bool user_scrollable_vertical, - MainThreadScrollingReasons main_thread_scrolling_reasons, - CompositorElementId compositor_element_id) { - return base::AdoptRef(new ScrollPaintPropertyNode( - std::move(parent), container_rect, contents_rect, - user_scrollable_horizontal, user_scrollable_vertical, - main_thread_scrolling_reasons, compositor_element_id)); + State&& state) { + return base::AdoptRef( + new ScrollPaintPropertyNode(std::move(parent), std::move(state))); } bool Update(scoped_refptr<const ScrollPaintPropertyNode> parent, - const IntRect& container_rect, - const IntRect& contents_rect, - bool user_scrollable_horizontal, - bool user_scrollable_vertical, - MainThreadScrollingReasons main_thread_scrolling_reasons, - CompositorElementId compositor_element_id) { - bool parent_changed = PaintPropertyNode::Update(std::move(parent)); - - if (container_rect == container_rect_ && contents_rect == contents_rect_ && - user_scrollable_horizontal == user_scrollable_horizontal_ && - user_scrollable_vertical == user_scrollable_vertical_ && - main_thread_scrolling_reasons == main_thread_scrolling_reasons_ && - compositor_element_id_ == compositor_element_id) + State&& state) { + bool parent_changed = SetParent(parent); + if (state == state_) return parent_changed; SetChanged(); - container_rect_ = container_rect; - contents_rect_ = contents_rect; - user_scrollable_horizontal_ = user_scrollable_horizontal; - user_scrollable_vertical_ = user_scrollable_vertical; - main_thread_scrolling_reasons_ = main_thread_scrolling_reasons; - compositor_element_id_ = compositor_element_id; - DCHECK(ElementIdNamespaceIsForScrolling()); + state_ = std::move(state); + Validate(); return true; } @@ -83,97 +81,72 @@ class PLATFORM_EXPORT ScrollPaintPropertyNode // the parent of the associated transform node (ScrollTranslation). // It doesn't include non-overlay scrollbars. Overlay scrollbars do not affect // the rect. - const IntRect& ContainerRect() const { return container_rect_; } + const IntRect& ContainerRect() const { return state_.container_rect; } // Rect of the contents that is scrolled within the container rect, in the // space of the associated transform node (ScrollTranslation). - const IntRect& ContentsRect() const { return contents_rect_; } + const IntRect& ContentsRect() const { return state_.contents_rect; } - bool UserScrollableHorizontal() const { return user_scrollable_horizontal_; } - bool UserScrollableVertical() const { return user_scrollable_vertical_; } + bool UserScrollableHorizontal() const { + return state_.user_scrollable_horizontal; + } + bool UserScrollableVertical() const { + return state_.user_scrollable_vertical; + } // Return reason bitfield with values from cc::MainThreadScrollingReason. MainThreadScrollingReasons GetMainThreadScrollingReasons() const { - return main_thread_scrolling_reasons_; + return state_.main_thread_scrolling_reasons; } // Main thread scrolling reason for the threaded scrolling disabled setting. bool ThreadedScrollingDisabled() const { - return main_thread_scrolling_reasons_ & + return state_.main_thread_scrolling_reasons & MainThreadScrollingReason::kThreadedScrollingDisabled; } // Main thread scrolling reason for background attachment fixed descendants. bool HasBackgroundAttachmentFixedDescendants() const { - return main_thread_scrolling_reasons_ & + return state_.main_thread_scrolling_reasons & MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; } const CompositorElementId& GetCompositorElementId() const { - return compositor_element_id_; + return state_.compositor_element_id; } #if DCHECK_IS_ON() // The clone function is used by FindPropertiesNeedingUpdate.h for recording // a scroll node before it has been updated, to later detect changes. scoped_refptr<ScrollPaintPropertyNode> Clone() const { - scoped_refptr<ScrollPaintPropertyNode> cloned = - base::AdoptRef(new ScrollPaintPropertyNode( - Parent(), container_rect_, contents_rect_, - user_scrollable_horizontal_, user_scrollable_vertical_, - main_thread_scrolling_reasons_, compositor_element_id_)); - return cloned; + return base::AdoptRef(new ScrollPaintPropertyNode(Parent(), State(state_))); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking // if a scroll node has changed. bool operator==(const ScrollPaintPropertyNode& o) const { - return Parent() == o.Parent() && container_rect_ == o.container_rect_ && - contents_rect_ == o.contents_rect_ && - user_scrollable_horizontal_ == o.user_scrollable_horizontal_ && - user_scrollable_vertical_ == o.user_scrollable_vertical_ && - main_thread_scrolling_reasons_ == o.main_thread_scrolling_reasons_ && - compositor_element_id_ == o.compositor_element_id_; + return Parent() == o.Parent() && state_ == o.state_; } #endif std::unique_ptr<JSONObject> ToJSON() const; private: - ScrollPaintPropertyNode( - scoped_refptr<const ScrollPaintPropertyNode> parent, - const IntRect& container_rect, - const IntRect& contents_rect, - bool user_scrollable_horizontal, - bool user_scrollable_vertical, - MainThreadScrollingReasons main_thread_scrolling_reasons, - CompositorElementId compositor_element_id) - : PaintPropertyNode(std::move(parent)), - container_rect_(container_rect), - contents_rect_(contents_rect), - user_scrollable_horizontal_(user_scrollable_horizontal), - user_scrollable_vertical_(user_scrollable_vertical), - main_thread_scrolling_reasons_(main_thread_scrolling_reasons), - compositor_element_id_(compositor_element_id) { -#if DCHECK_IS_ON() - DCHECK(ElementIdNamespaceIsForScrolling()); -#endif + ScrollPaintPropertyNode(scoped_refptr<const ScrollPaintPropertyNode> parent, + State&& state) + : PaintPropertyNode(std::move(parent)), state_(std::move(state)) { + Validate(); } - bool ElementIdNamespaceIsForScrolling() const { - return !compositor_element_id_ || - NamespaceFromCompositorElementId(compositor_element_id_) == - CompositorElementIdNamespace::kScroll; + void Validate() const { +#if DCHECK_IS_ON() + DCHECK(!state_.compositor_element_id || + NamespaceFromCompositorElementId(state_.compositor_element_id) == + CompositorElementIdNamespace::kScroll); +#endif } - IntRect container_rect_; - IntRect contents_rect_; - bool user_scrollable_horizontal_ : 1; - bool user_scrollable_vertical_ : 1; - MainThreadScrollingReasons main_thread_scrolling_reasons_; - // The scrolling element id is stored directly on the scroll node and not on - // the associated TransformPaintPropertyNode used for scroll offset. - CompositorElementId compositor_element_id_; + State state_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.cc index dcce1a0c662..91f9a1e2525 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -17,13 +17,20 @@ void BeginTransform3DDisplayItem::Replay(GraphicsContext& context) const { context.ConcatCTM(transform.ToAffineTransform()); } -void BeginTransform3DDisplayItem::AppendToWebDisplayItemList( +void BeginTransform3DDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { + cc::DisplayItemList& list) const { // TODO(jbroman): The compositor will need the transform origin separately. TransformationMatrix transform(transform_); transform.ApplyTransformOrigin(transform_origin_); - list->AppendTransformItem(TransformationMatrix::ToSkMatrix44(transform)); + + list.StartPaint(); + list.push<cc::SaveOp>(); + if (!transform.IsIdentity()) { + list.push<cc::ConcatOp>( + static_cast<SkMatrix>(TransformationMatrix::ToSkMatrix44(transform))); + } + list.EndPaintOfPairedBegin(); } #if DCHECK_IS_ON() @@ -38,10 +45,12 @@ void EndTransform3DDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndTransform3DDisplayItem::AppendToWebDisplayItemList( +void EndTransform3DDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndTransformItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.h index 1c7e75f92af..df63b22f978 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_3d_display_item.h @@ -26,8 +26,8 @@ class PLATFORM_EXPORT BeginTransform3DDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; const TransformationMatrix& Transform() const { return transform_; } const FloatPoint3D& TransformOrigin() const { return transform_origin_; } @@ -58,8 +58,8 @@ class PLATFORM_EXPORT EndTransform3DDisplayItem final } void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.cc index 662db9aff26..e0d45085f61 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/transform_display_item.h" -#include "third_party/blink/public/platform/web_display_item_list.h" +#include "cc/paint/display_item_list.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" @@ -15,10 +15,14 @@ void BeginTransformDisplayItem::Replay(GraphicsContext& context) const { context.ConcatCTM(transform_); } -void BeginTransformDisplayItem::AppendToWebDisplayItemList( +void BeginTransformDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendTransformItem(AffineTransformToSkMatrix(transform_)); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::SaveOp>(); + if (!transform_.IsIdentity()) + list.push<cc::ConcatOp>(AffineTransformToSkMatrix(transform_)); + list.EndPaintOfPairedBegin(); } #if DCHECK_IS_ON() @@ -32,10 +36,12 @@ void EndTransformDisplayItem::Replay(GraphicsContext& context) const { context.Restore(); } -void EndTransformDisplayItem::AppendToWebDisplayItemList( +void EndTransformDisplayItem::AppendToDisplayItemList( const FloatSize&, - WebDisplayItemList* list) const { - list->AppendEndTransformItem(); + cc::DisplayItemList& list) const { + list.StartPaint(); + list.push<cc::RestoreOp>(); + list.EndPaintOfPairedEnd(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.h b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.h index 88a7865a662..a684f7b7f10 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_display_item.h @@ -19,8 +19,8 @@ class PLATFORM_EXPORT BeginTransformDisplayItem final transform_(transform) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; const AffineTransform& Transform() const { return transform_; } @@ -44,8 +44,8 @@ class PLATFORM_EXPORT EndTransformDisplayItem final : PairedEndDisplayItem(client, kEndTransform, sizeof(*this)) {} void Replay(GraphicsContext&) const override; - void AppendToWebDisplayItemList(const FloatSize&, - WebDisplayItemList*) const override; + void AppendToDisplayItemList(const FloatSize&, + cc::DisplayItemList&) const override; private: #if DCHECK_IS_ON() diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc index 6c6e321349a..cc75a09fe68 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.cc @@ -9,11 +9,13 @@ namespace blink { // The root of the transform tree. The root transform node references the root // scroll node. TransformPaintPropertyNode* TransformPaintPropertyNode::Root() { - DEFINE_STATIC_REF(TransformPaintPropertyNode, root, - base::AdoptRef(new TransformPaintPropertyNode( - nullptr, TransformationMatrix(), FloatPoint3D(), false, - 0, CompositingReason::kNone, CompositorElementId(), - ScrollPaintPropertyNode::Root()))); + DEFINE_STATIC_REF( + TransformPaintPropertyNode, root, + base::AdoptRef(new TransformPaintPropertyNode( + nullptr, + State{TransformationMatrix(), FloatPoint3D(), false, + BackfaceVisibility::kVisible, 0, CompositingReason::kNone, + CompositorElementId(), ScrollPaintPropertyNode::Root()}))); return root; } @@ -33,27 +35,43 @@ std::unique_ptr<JSONObject> TransformPaintPropertyNode::ToJSON() const { auto json = JSONObject::Create(); if (Parent()) json->SetString("parent", String::Format("%p", Parent())); - if (!matrix_.IsIdentity()) - json->SetString("matrix", matrix_.ToString()); - if (!matrix_.IsIdentityOrTranslation()) - json->SetString("origin", origin_.ToString()); - if (!flattens_inherited_transform_) + if (!state_.matrix.IsIdentity()) + json->SetString("matrix", state_.matrix.ToString()); + if (!state_.matrix.IsIdentityOrTranslation()) + json->SetString("origin", state_.origin.ToString()); + if (!state_.flattens_inherited_transform) json->SetBoolean("flattensInheritedTransform", false); - if (rendering_context_id_) { + if (state_.backface_visibility != BackfaceVisibility::kInherited) { + json->SetString("backface", + state_.backface_visibility == BackfaceVisibility::kVisible + ? "visible" + : "hidden"); + } + if (state_.rendering_context_id) { json->SetString("renderingContextId", - String::Format("%x", rendering_context_id_)); + String::Format("%x", state_.rendering_context_id)); } - if (direct_compositing_reasons_ != CompositingReason::kNone) { - json->SetString("directCompositingReasons", - CompositingReason::ToString(direct_compositing_reasons_)); + if (state_.direct_compositing_reasons != CompositingReason::kNone) { + json->SetString( + "directCompositingReasons", + CompositingReason::ToString(state_.direct_compositing_reasons)); } - if (compositor_element_id_) { + if (state_.compositor_element_id) { json->SetString("compositorElementId", - compositor_element_id_.ToString().c_str()); + state_.compositor_element_id.ToString().c_str()); } - if (scroll_) - json->SetString("scroll", String::Format("%p", scroll_.get())); + if (state_.scroll) + json->SetString("scroll", String::Format("%p", state_.scroll.get())); return json; } +size_t TransformPaintPropertyNode::CacheMemoryUsageInBytes() const { + size_t total_bytes = sizeof(*this); + if (transform_cache_) + total_bytes += sizeof(*transform_cache_); + if (Parent()) + total_bytes += Parent()->CacheMemoryUsageInBytes(); + return total_bytes; +} + } // namespace blink 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 8b4279a52dc..9e33f591430 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 @@ -12,11 +12,7 @@ #include "third_party/blink/renderer/platform/graphics/paint/paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/scroll_paint_property_node.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h" -#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" - -#include <iosfwd> namespace blink { @@ -31,76 +27,70 @@ namespace blink { class PLATFORM_EXPORT TransformPaintPropertyNode : public PaintPropertyNode<TransformPaintPropertyNode> { public: + enum class BackfaceVisibility : unsigned char { + // backface-visibility is not inherited per the css spec. However, for an + // element that don't create a new plane, for now we let the element + // inherit the parent backface-visibility. + kInherited, + // backface-visibility: hidden for the new plane. + kHidden, + // backface-visibility: visible for the new plane. + kVisible, + }; + + // To make it less verbose and more readable to construct and update a node, + // a struct with default values is used to represent the state. + struct State { + TransformationMatrix matrix; + FloatPoint3D origin; + bool flattens_inherited_transform = false; + BackfaceVisibility backface_visibility = BackfaceVisibility::kInherited; + unsigned rendering_context_id = 0; + CompositingReasons direct_compositing_reasons = CompositingReason::kNone; + CompositorElementId compositor_element_id; + scoped_refptr<const ScrollPaintPropertyNode> scroll; + + bool operator==(const State& o) const { + return matrix == o.matrix && origin == o.origin && + flattens_inherited_transform == o.flattens_inherited_transform && + backface_visibility == o.backface_visibility && + rendering_context_id == o.rendering_context_id && + direct_compositing_reasons == o.direct_compositing_reasons && + compositor_element_id == o.compositor_element_id && + scroll == o.scroll; + } + }; + // This node is really a sentinel, and does not represent a real transform // space. static TransformPaintPropertyNode* Root(); static scoped_refptr<TransformPaintPropertyNode> Create( scoped_refptr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - bool flattens_inherited_transform = false, - unsigned rendering_context_id = 0, - CompositingReasons direct_compositing_reasons = CompositingReason::kNone, - const CompositorElementId& compositor_element_id = CompositorElementId(), - scoped_refptr<const ScrollPaintPropertyNode> scroll = nullptr) { - if (scroll) { - // If there is an associated scroll node, this can only be a 2d - // translation for scroll offset. - DCHECK(matrix.IsIdentityOr2DTranslation()); - // The scroll compositor element id should be stored on the scroll node. - DCHECK(!compositor_element_id); - } - return base::AdoptRef(new TransformPaintPropertyNode( - std::move(parent), matrix, origin, flattens_inherited_transform, - rendering_context_id, direct_compositing_reasons, compositor_element_id, - std::move(scroll))); + State&& state) { + return base::AdoptRef( + new TransformPaintPropertyNode(std::move(parent), std::move(state))); } - bool Update( - scoped_refptr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - bool flattens_inherited_transform = false, - unsigned rendering_context_id = 0, - CompositingReasons direct_compositing_reasons = CompositingReason::kNone, - CompositorElementId compositor_element_id = CompositorElementId(), - scoped_refptr<const ScrollPaintPropertyNode> scroll = nullptr) { - bool parent_changed = PaintPropertyNode::Update(std::move(parent)); - - if (scroll) { - // If there is an associated scroll node, this can only be a 2d - // translation for scroll offset. - DCHECK(matrix.IsIdentityOr2DTranslation()); - // The scroll compositor element id should be stored on the scroll node. - DCHECK(!compositor_element_id); - } - - if (matrix == matrix_ && origin == origin_ && - flattens_inherited_transform == flattens_inherited_transform_ && - (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || - (rendering_context_id == rendering_context_id_ && - direct_compositing_reasons == direct_compositing_reasons_ && - compositor_element_id == compositor_element_id_)) && - scroll == scroll_) + bool Update(scoped_refptr<const TransformPaintPropertyNode> parent, + State&& state) { + bool parent_changed = SetParent(parent); + if (state == state_) return parent_changed; SetChanged(); - matrix_ = matrix; - origin_ = origin; - flattens_inherited_transform_ = flattens_inherited_transform; - rendering_context_id_ = rendering_context_id; - direct_compositing_reasons_ = direct_compositing_reasons; - compositor_element_id_ = compositor_element_id; - scroll_ = std::move(scroll); + state_ = std::move(state); + Validate(); return true; } - const TransformationMatrix& Matrix() const { return matrix_; } - const FloatPoint3D& Origin() const { return origin_; } + const TransformationMatrix& Matrix() const { return state_.matrix; } + const FloatPoint3D& Origin() const { return state_.origin; } // The associated scroll node, or nullptr otherwise. - const ScrollPaintPropertyNode* ScrollNode() const { return scroll_.get(); } + const ScrollPaintPropertyNode* ScrollNode() const { + return state_.scroll.get(); + } // If this is a scroll offset translation (i.e., has an associated scroll // node), returns this. Otherwise, returns the transform node that this node @@ -111,71 +101,70 @@ class PLATFORM_EXPORT TransformPaintPropertyNode // the plane of its parent. This is implemented by flattening the total // accumulated transform from its ancestors. bool FlattensInheritedTransform() const { - return flattens_inherited_transform_; + return state_.flattens_inherited_transform; + } + + BackfaceVisibility GetBackfaceVisibility() const { + return state_.backface_visibility; } bool HasDirectCompositingReasons() const { - return direct_compositing_reasons_ != CompositingReason::kNone; + return state_.direct_compositing_reasons != CompositingReason::kNone; } bool RequiresCompositingForAnimation() const { - return direct_compositing_reasons_ & + return state_.direct_compositing_reasons & CompositingReason::kComboActiveAnimation; } const CompositorElementId& GetCompositorElementId() const { - return compositor_element_id_; + return state_.compositor_element_id; } // Content whose transform nodes have a common rendering context ID are 3D // sorted. If this is 0, content will not be 3D sorted. - unsigned RenderingContextId() const { return rendering_context_id_; } - bool HasRenderingContext() const { return rendering_context_id_; } + unsigned RenderingContextId() const { return state_.rendering_context_id; } + bool HasRenderingContext() const { return state_.rendering_context_id; } #if DCHECK_IS_ON() // The clone function is used by FindPropertiesNeedingUpdate.h for recording // a transform node before it has been updated, to later detect changes. scoped_refptr<TransformPaintPropertyNode> Clone() const { - return base::AdoptRef(new TransformPaintPropertyNode( - Parent(), matrix_, origin_, flattens_inherited_transform_, - rendering_context_id_, direct_compositing_reasons_, - compositor_element_id_, scroll_)); + return base::AdoptRef( + new TransformPaintPropertyNode(Parent(), State(state_))); } // The equality operator is used by FindPropertiesNeedingUpdate.h for checking // if a transform node has changed. bool operator==(const TransformPaintPropertyNode& o) const { - return Parent() == o.Parent() && matrix_ == o.matrix_ && - origin_ == o.origin_ && - flattens_inherited_transform_ == o.flattens_inherited_transform_ && - (!RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || - (rendering_context_id_ == o.rendering_context_id_ && - direct_compositing_reasons_ == o.direct_compositing_reasons_ && - compositor_element_id_ == o.compositor_element_id_)) && - scroll_ == o.scroll_; + return Parent() == o.Parent() && state_ == o.state_; } #endif std::unique_ptr<JSONObject> ToJSON() const; + // Returns memory usage of the transform cache of this node plus ancestors. + size_t CacheMemoryUsageInBytes() const; + private: TransformPaintPropertyNode( scoped_refptr<const TransformPaintPropertyNode> parent, - const TransformationMatrix& matrix, - const FloatPoint3D& origin, - bool flattens_inherited_transform, - unsigned rendering_context_id, - CompositingReasons direct_compositing_reasons, - CompositorElementId compositor_element_id, - scoped_refptr<const ScrollPaintPropertyNode> scroll = nullptr) - : PaintPropertyNode(std::move(parent)), - matrix_(matrix), - origin_(origin), - flattens_inherited_transform_(flattens_inherited_transform), - rendering_context_id_(rendering_context_id), - direct_compositing_reasons_(direct_compositing_reasons), - compositor_element_id_(compositor_element_id), - scroll_(std::move(scroll)) {} + State&& state) + : PaintPropertyNode(std::move(parent)), state_(std::move(state)) { + Validate(); + } + + void Validate() const { +#if DCHECK_IS_ON() + if (state_.scroll) { + // If there is an associated scroll node, this can only be a 2d + // translation for scroll offset. + DCHECK(state_.matrix.IsIdentityOr2DTranslation()); + // The scroll compositor element id should be stored on the scroll node. + DCHECK(!state_.compositor_element_id); + } +#endif + } // For access to getTransformCache() and setCachedTransform. friend class GeometryMapper; @@ -189,14 +178,7 @@ class PLATFORM_EXPORT TransformPaintPropertyNode return *transform_cache_; } - TransformationMatrix matrix_; - FloatPoint3D origin_; - bool flattens_inherited_transform_; - unsigned rendering_context_id_; - CompositingReasons direct_compositing_reasons_; - CompositorElementId compositor_element_id_; - scoped_refptr<const ScrollPaintPropertyNode> scroll_; - + State state_; mutable std::unique_ptr<GeometryMapperTransformCache> transform_cache_; }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc index 4b2381e686b..e2d2623ab27 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.cc @@ -50,6 +50,10 @@ const char* PaintInvalidationReasonToString(PaintInvalidationReason reason) { return "DocumentMarker change"; case PaintInvalidationReason::kImage: return "image"; + case PaintInvalidationReason::kChunkAppeared: + return "chunk appeared"; + case PaintInvalidationReason::kChunkDisappeared: + return "chunk disappeared"; case PaintInvalidationReason::kChunkUncacheable: return "chunk uncacheable"; case PaintInvalidationReason::kChunkReordered: diff --git a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h index c1a324d0260..43b9c79d6aa 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h +++ b/chromium/third_party/blink/renderer/platform/graphics/paint_invalidation_reason.h @@ -32,6 +32,8 @@ enum class PaintInvalidationReason : unsigned { kCaret, kDocumentMarker, kImage, + kChunkAppeared, + kChunkDisappeared, kChunkUncacheable, kChunkReordered, kPaintProperty, diff --git a/chromium/third_party/blink/renderer/platform/graphics/path.cc b/chromium/third_party/blink/renderer/platform/graphics/path.cc index 361de3fac5c..3a90e063342 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/path.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/path.cc @@ -198,19 +198,19 @@ FloatPoint Path::PointAtLength(float length) const { return point; } -static bool CalculatePointAndNormalOnPath( - SkPathMeasure& measure, - SkScalar length, - FloatPoint& point, - float& normal_angle, - SkScalar* accumulated_length = nullptr) { +static bool CalculatePointAndNormalOnPath(SkPathMeasure& measure, + SkScalar& contour_start, + SkScalar length, + FloatPoint& point, + float& normal_angle) { do { - SkScalar contour_length = measure.getLength(); - if (length <= contour_length) { + SkScalar contour_end = contour_start + measure.getLength(); + if (length <= contour_end) { SkVector tangent; SkPoint position; - if (measure.getPosTan(length, &position, &tangent)) { + SkScalar pos_in_contour = length - contour_start; + if (measure.getPosTan(pos_in_contour, &position, &tangent)) { normal_angle = rad2deg(SkScalarToFloat(SkScalarATan2(tangent.fY, tangent.fX))); point = FloatPoint(SkScalarToFloat(position.fX), @@ -218,9 +218,7 @@ static bool CalculatePointAndNormalOnPath( return true; } } - length -= contour_length; - if (accumulated_length) - *accumulated_length += contour_length; + contour_start = contour_end; } while (measure.nextContour()); return false; } @@ -229,8 +227,9 @@ void Path::PointAndNormalAtLength(float length, FloatPoint& point, float& normal) const { SkPathMeasure measure(path_, false); - if (CalculatePointAndNormalOnPath(measure, WebCoreFloatToSkScalar(length), - point, normal)) + SkScalar start = 0; + if (CalculatePointAndNormalOnPath( + measure, start, WebCoreFloatToSkScalar(length), point, normal)) return; SkPoint position = path_.getPoint(0); @@ -253,12 +252,10 @@ void Path::PositionCalculator::PointAndNormalAtLength(float length, // Reset path measurer to rewind (and restart from 0). path_measure_.setPath(&path_, false); accumulated_length_ = 0; - } else { - sk_length -= accumulated_length_; } - if (CalculatePointAndNormalOnPath(path_measure_, sk_length, point, - normal_angle, &accumulated_length_)) + if (CalculatePointAndNormalOnPath(path_measure_, accumulated_length_, + sk_length, point, normal_angle)) return; } @@ -266,7 +263,6 @@ void Path::PositionCalculator::PointAndNormalAtLength(float length, point = FloatPoint(SkScalarToFloat(position.fX), SkScalarToFloat(position.fY)); normal_angle = 0; - return; } void Path::Clear() { @@ -309,25 +305,27 @@ void Path::SetWindRule(const WindRule rule) { } void Path::MoveTo(const FloatPoint& point) { - path_.moveTo(point.Data()); + path_.moveTo(FloatPointToSkPoint(point)); } void Path::AddLineTo(const FloatPoint& point) { - path_.lineTo(point.Data()); + path_.lineTo(FloatPointToSkPoint(point)); } void Path::AddQuadCurveTo(const FloatPoint& cp, const FloatPoint& ep) { - path_.quadTo(cp.Data(), ep.Data()); + path_.quadTo(FloatPointToSkPoint(cp), FloatPointToSkPoint(ep)); } void Path::AddBezierCurveTo(const FloatPoint& p1, const FloatPoint& p2, const FloatPoint& ep) { - path_.cubicTo(p1.Data(), p2.Data(), ep.Data()); + path_.cubicTo(FloatPointToSkPoint(p1), FloatPointToSkPoint(p2), + FloatPointToSkPoint(ep)); } void Path::AddArcTo(const FloatPoint& p1, const FloatPoint& p2, float radius) { - path_.arcTo(p1.Data(), p2.Data(), WebCoreFloatToSkScalar(radius)); + path_.arcTo(FloatPointToSkPoint(p1), FloatPointToSkPoint(p2), + WebCoreFloatToSkScalar(radius)); } void Path::AddArcTo(const FloatPoint& p, diff --git a/chromium/third_party/blink/renderer/platform/graphics/path_test.cc b/chromium/third_party/blink/renderer/platform/graphics/path_test.cc new file mode 100644 index 00000000000..fbf1af623c8 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/path_test.cc @@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/path.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(PathTest, PointAtEndOfPath) { + Path path; + path.MoveTo(FloatPoint(70, -48)); + path.AddBezierCurveTo(FloatPoint(70, -48), FloatPoint(136, 136), + FloatPoint(230, 166)); + path.MoveTo(FloatPoint(230, 166)); + path.AddBezierCurveTo(FloatPoint(324, 196), FloatPoint(472, 370), + FloatPoint(460, 470)); + + FloatPoint point; + float angle; + path.PointAndNormalAtLength(path.length(), point, angle); + EXPECT_EQ(point, FloatPoint(460, 470)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc index bce17741869..904e6231373 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/platform/fonts/font_description.h" #include "third_party/blink/renderer/platform/fonts/font_family.h" #include "third_party/blink/renderer/platform/fonts/font_selection_types.h" +#include "third_party/blink/renderer/platform/fonts/text_run_paint_info.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/int_point.h" diff --git a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h index e3398f05e31..00dd9ee06d5 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h +++ b/chromium/third_party/blink/renderer/platform/graphics/placeholder_image.h @@ -8,10 +8,10 @@ #include <stdint.h> #include "base/memory/scoped_refptr.h" +#include "base/optional.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" #include "third_party/blink/renderer/platform/graphics/image.h" #include "third_party/blink/renderer/platform/graphics/image_orientation.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -84,7 +84,7 @@ class PLATFORM_EXPORT PlaceholderImage final : public Image { scoped_refptr<SharedFont> shared_font_; // Lazily initialized. - Optional<float> cached_text_width_; + base::Optional<float> cached_text_width_; sk_sp<PaintRecord> paint_record_for_current_frame_; PaintImage::ContentId paint_record_content_id_; }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/profiling_canvas.cc b/chromium/third_party/blink/renderer/platform/graphics/profiling_canvas.cc index fbadaa0964e..694ef3108f1 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/profiling_canvas.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/profiling_canvas.cc @@ -43,7 +43,7 @@ CanvasInterceptor<ProfilingCanvas>::~CanvasInterceptor() { if (!TopLevelCall()) return; double delta = WTF::CurrentTimeTicksInSeconds() - start_time_; - if (auto timings = Canvas()->timings_) { + if (auto* timings = Canvas()->timings_) { DCHECK_EQ(timings->size(), Canvas()->CallCount()); timings->push_back(delta); } diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc index 8d412e39318..efa048b0b98 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils.cc @@ -34,13 +34,17 @@ #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/paint/paint_flags.h" #include "third_party/skia/include/effects/SkCornerPathEffect.h" +#include "ui/gfx/icc_profile.h" + +#include <algorithm> +#include <cmath> namespace blink { -static const struct CompositOpToXfermodeMode { +static const struct CompositOpToSkBlendMode { CompositeOperator composit_op; SkBlendMode xfermode_mode; -} kGMapCompositOpsToXfermodeModes[] = { +} kGMapCompositOpsToSkBlendMode[] = { {kCompositeClear, SkBlendMode::kClear}, {kCompositeCopy, SkBlendMode::kSrc}, {kCompositeSourceOver, SkBlendMode::kSrcOver}, @@ -54,45 +58,45 @@ static const struct CompositOpToXfermodeMode { {kCompositeXOR, SkBlendMode::kXor}, {kCompositePlusLighter, SkBlendMode::kPlus}}; -// Keep this array in sync with the WebBlendMode enum in -// public/platform/WebBlendMode.h. -static const SkBlendMode kGMapBlendOpsToXfermodeModes[] = { - SkBlendMode::kSrcOver, // WebBlendModeNormal - SkBlendMode::kMultiply, // WebBlendModeMultiply - SkBlendMode::kScreen, // WebBlendModeScreen - SkBlendMode::kOverlay, // WebBlendModeOverlay - SkBlendMode::kDarken, // WebBlendModeDarken - SkBlendMode::kLighten, // WebBlendModeLighten - SkBlendMode::kColorDodge, // WebBlendModeColorDodge - SkBlendMode::kColorBurn, // WebBlendModeColorBurn - SkBlendMode::kHardLight, // WebBlendModeHardLight - SkBlendMode::kSoftLight, // WebBlendModeSoftLight - SkBlendMode::kDifference, // WebBlendModeDifference - SkBlendMode::kExclusion, // WebBlendModeExclusion - SkBlendMode::kHue, // WebBlendModeHue - SkBlendMode::kSaturation, // WebBlendModeSaturation - SkBlendMode::kColor, // WebBlendModeColor - SkBlendMode::kLuminosity // WebBlendModeLuminosity +// Keep this array in sync with the BlendMode enum in +// platform/graphics/graphics_types.h. +static const SkBlendMode kGMapBlendOpsToSkBlendMode[] = { + SkBlendMode::kSrcOver, // BlendMode::kNormal + SkBlendMode::kMultiply, // BlendMode::kMultiply + SkBlendMode::kScreen, // BlendMode::kScreen + SkBlendMode::kOverlay, // BlendMode::kOverlay + SkBlendMode::kDarken, // BlendMode::kDarken + SkBlendMode::kLighten, // BlendMode::kLighten + SkBlendMode::kColorDodge, // BlendMode::kColorDodge + SkBlendMode::kColorBurn, // BlendMode::kColorBurn + SkBlendMode::kHardLight, // BlendMode::kHardLight + SkBlendMode::kSoftLight, // BlendMode::kSoftLight + SkBlendMode::kDifference, // BlendMode::kDifference + SkBlendMode::kExclusion, // BlendMode::kExclusion + SkBlendMode::kHue, // BlendMode::kHue + SkBlendMode::kSaturation, // BlendMode::kSaturation + SkBlendMode::kColor, // BlendMode::kColor + SkBlendMode::kLuminosity // BlendMode::kLuminosity }; SkBlendMode WebCoreCompositeToSkiaComposite(CompositeOperator op, - WebBlendMode blend_mode) { - DCHECK(op == kCompositeSourceOver || blend_mode == WebBlendMode::kNormal); - if (blend_mode != WebBlendMode::kNormal) { + BlendMode blend_mode) { + DCHECK(op == kCompositeSourceOver || blend_mode == BlendMode::kNormal); + if (blend_mode != BlendMode::kNormal) { if (static_cast<uint8_t>(blend_mode) >= - SK_ARRAY_COUNT(kGMapBlendOpsToXfermodeModes)) { + SK_ARRAY_COUNT(kGMapBlendOpsToSkBlendMode)) { SkDEBUGF( ("GraphicsContext::setPlatformCompositeOperation unknown " - "WebBlendMode %d\n", + "BlendMode %d\n", blend_mode)); return SkBlendMode::kSrcOver; } - return kGMapBlendOpsToXfermodeModes[static_cast<uint8_t>(blend_mode)]; + return kGMapBlendOpsToSkBlendMode[static_cast<uint8_t>(blend_mode)]; } - const CompositOpToXfermodeMode* table = kGMapCompositOpsToXfermodeModes; + const CompositOpToSkBlendMode* table = kGMapCompositOpsToSkBlendMode; if (static_cast<uint8_t>(op) >= - SK_ARRAY_COUNT(kGMapCompositOpsToXfermodeModes)) { + SK_ARRAY_COUNT(kGMapCompositOpsToSkBlendMode)) { SkDEBUGF( ("GraphicsContext::setPlatformCompositeOperation unknown " "CompositeOperator %d\n", @@ -103,8 +107,20 @@ SkBlendMode WebCoreCompositeToSkiaComposite(CompositeOperator op, return table[static_cast<uint8_t>(op)].xfermode_mode; } -CompositeOperator CompositeOperatorFromSkia(SkBlendMode xfer_mode) { - switch (xfer_mode) { +SkBlendMode WebCoreBlendModeToSkBlendMode(BlendMode blend_mode) { + if (static_cast<uint8_t>(blend_mode) >= + SK_ARRAY_COUNT(kGMapBlendOpsToSkBlendMode)) { + SkDEBUGF( + ("GraphicsContext::setPlatformCompositeOperation unknown " + "BlendMode %d\n", + blend_mode)); + return SkBlendMode::kSrcOver; + } + return kGMapBlendOpsToSkBlendMode[static_cast<uint8_t>(blend_mode)]; +} + +CompositeOperator CompositeOperatorFromSkBlendMode(SkBlendMode blend_mode) { + switch (blend_mode) { case SkBlendMode::kClear: return kCompositeClear; case SkBlendMode::kSrc: @@ -135,44 +151,44 @@ CompositeOperator CompositeOperatorFromSkia(SkBlendMode xfer_mode) { return kCompositeSourceOver; } -WebBlendMode BlendModeFromSkia(SkBlendMode xfer_mode) { - switch (xfer_mode) { +BlendMode BlendModeFromSkBlendMode(SkBlendMode blend_mode) { + switch (blend_mode) { case SkBlendMode::kSrcOver: - return WebBlendMode::kNormal; + return BlendMode::kNormal; case SkBlendMode::kMultiply: - return WebBlendMode::kMultiply; + return BlendMode::kMultiply; case SkBlendMode::kScreen: - return WebBlendMode::kScreen; + return BlendMode::kScreen; case SkBlendMode::kOverlay: - return WebBlendMode::kOverlay; + return BlendMode::kOverlay; case SkBlendMode::kDarken: - return WebBlendMode::kDarken; + return BlendMode::kDarken; case SkBlendMode::kLighten: - return WebBlendMode::kLighten; + return BlendMode::kLighten; case SkBlendMode::kColorDodge: - return WebBlendMode::kColorDodge; + return BlendMode::kColorDodge; case SkBlendMode::kColorBurn: - return WebBlendMode::kColorBurn; + return BlendMode::kColorBurn; case SkBlendMode::kHardLight: - return WebBlendMode::kHardLight; + return BlendMode::kHardLight; case SkBlendMode::kSoftLight: - return WebBlendMode::kSoftLight; + return BlendMode::kSoftLight; case SkBlendMode::kDifference: - return WebBlendMode::kDifference; + return BlendMode::kDifference; case SkBlendMode::kExclusion: - return WebBlendMode::kExclusion; + return BlendMode::kExclusion; case SkBlendMode::kHue: - return WebBlendMode::kHue; + return BlendMode::kHue; case SkBlendMode::kSaturation: - return WebBlendMode::kSaturation; + return BlendMode::kSaturation; case SkBlendMode::kColor: - return WebBlendMode::kColor; + return BlendMode::kColor; case SkBlendMode::kLuminosity: - return WebBlendMode::kLuminosity; + return BlendMode::kLuminosity; default: break; } - return WebBlendMode::kNormal; + return BlendMode::kNormal; } SkMatrix AffineTransformToSkMatrix(const AffineTransform& source) { @@ -295,22 +311,34 @@ InterpolationQuality ComputeInterpolationQuality(float src_width, return kInterpolationDefault; } -int ClampedAlphaForBlending(float alpha) { - if (alpha < 0) - return 0; - int rounded_alpha = roundf(alpha * 256); - if (rounded_alpha > 256) - rounded_alpha = 256; - return rounded_alpha; -} - SkColor ScaleAlpha(SkColor color, float alpha) { - return ScaleAlpha(color, ClampedAlphaForBlending(alpha)); + const auto clamped_alpha = std::max(0.0f, std::min(1.0f, alpha)); + const auto rounded_alpha = std::lround(SkColorGetA(color) * clamped_alpha); + + return SkColorSetA(color, rounded_alpha); } -SkColor ScaleAlpha(SkColor color, int alpha) { - int a = (SkColorGetA(color) * alpha) >> 8; - return (color & 0x00FFFFFF) | (a << 24); +gfx::ColorSpace SkColorSpaceToGfxColorSpace( + const sk_sp<SkColorSpace> color_space) { + if (!color_space) + return gfx::ColorSpace::CreateSRGB(); + + SkMatrix44 toXYZD50; + SkColorSpaceTransferFn transfer_fn; + if (color_space->toXYZD50(&toXYZD50) && + color_space->isNumericalTransferFn(&transfer_fn)) + return gfx::ColorSpace::CreateCustom(toXYZD50, transfer_fn); + + // Use an intermediate ICC profile to convert the color space data structure. + // If this fails, we fall back to sRGB. + sk_sp<SkData> sk_profile = color_space->serialize(); + if (sk_profile) { + gfx::ICCProfile icc_profile = + gfx::ICCProfile::FromData(sk_profile->data(), sk_profile->size()); + if (icc_profile.IsValid()) + return icc_profile.GetColorSpace(); + } + return gfx::ColorSpace::CreateSRGB(); } template <typename PrimitiveType> 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 9da9dd90ed2..d34ca3cac4e 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 @@ -41,6 +41,7 @@ #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkScalar.h" @@ -62,20 +63,18 @@ bool PLATFORM_EXPORT IsValidImageSize(const IntSize&); SkBlendMode PLATFORM_EXPORT WebCoreCompositeToSkiaComposite(CompositeOperator, - WebBlendMode = WebBlendMode::kNormal); -CompositeOperator PLATFORM_EXPORT CompositeOperatorFromSkia(SkBlendMode); -WebBlendMode PLATFORM_EXPORT BlendModeFromSkia(SkBlendMode); - -// Map alpha values from [0, 1] to [0, 256] for alpha blending. -int PLATFORM_EXPORT ClampedAlphaForBlending(float); + BlendMode = BlendMode::kNormal); +SkBlendMode PLATFORM_EXPORT WebCoreBlendModeToSkBlendMode(BlendMode); +CompositeOperator PLATFORM_EXPORT CompositeOperatorFromSkBlendMode(SkBlendMode); +BlendMode PLATFORM_EXPORT BlendModeFromSkBlendMode(SkBlendMode); // Multiply a color's alpha channel by an additional alpha factor where // alpha is in the range [0, 1]. SkColor PLATFORM_EXPORT ScaleAlpha(SkColor, float); -// Multiply a color's alpha channel by an additional alpha factor where -// alpha is in the range [0, 256]. -SkColor PLATFORM_EXPORT ScaleAlpha(SkColor, int); +// Convert a SkColorSpace to a gfx::ColorSpace +gfx::ColorSpace PLATFORM_EXPORT +SkColorSpaceToGfxColorSpace(const sk_sp<SkColorSpace>); // Skia has problems when passed infinite, etc floats, filter them to 0. inline SkScalar WebCoreFloatToSkScalar(float f) { @@ -107,6 +106,11 @@ inline WindRule SkFillTypeToWindRule(SkPath::FillType fill_type) { return RULE_NONZERO; } +inline SkPoint FloatPointToSkPoint(const FloatPoint& point) { + return SkPoint::Make(WebCoreFloatToSkScalar(point.X()), + WebCoreFloatToSkScalar(point.Y())); +} + SkMatrix PLATFORM_EXPORT AffineTransformToSkMatrix(const AffineTransform&); bool NearlyIntegral(float value); diff --git a/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc new file mode 100644 index 00000000000..7de98907099 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/skia/skia_utils_test.cc @@ -0,0 +1,44 @@ +// 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/graphics/skia/skia_utils.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class SkiaUtilsTest : public testing::Test {}; + +// Tests converting a SkColorSpace to a gfx::ColorSpace +TEST_F(SkiaUtilsTest, SkColorSpaceToGfxColorSpace) { + std::vector<sk_sp<SkColorSpace>> skia_color_spaces; + + SkColorSpace::RenderTargetGamma gammas[] = { + SkColorSpace::kLinear_RenderTargetGamma, + SkColorSpace::kSRGB_RenderTargetGamma}; + + SkColorSpace::Gamut gamuts[] = { + SkColorSpace::kSRGB_Gamut, SkColorSpace::kAdobeRGB_Gamut, + SkColorSpace::kDCIP3_D65_Gamut, SkColorSpace::kRec2020_Gamut, + }; + + skia_color_spaces.push_back((SkColorSpace::MakeSRGB())->makeColorSpin()); + + for (unsigned gamma_itr = 0; gamma_itr < 2; gamma_itr++) { + for (unsigned gamut_itr = 0; gamut_itr < 4; gamut_itr++) { + skia_color_spaces.push_back( + SkColorSpace::MakeRGB(gammas[gamma_itr], gamuts[gamut_itr])); + } + } + + std::vector<gfx::ColorSpace> gfx_color_spaces; + for (unsigned i = 0; i < skia_color_spaces.size(); i++) { + gfx::ColorSpace color_space = + SkColorSpaceToGfxColorSpace(skia_color_spaces[i]); + ASSERT_TRUE(SkColorSpace::Equals(color_space.ToSkColorSpace().get(), + skia_color_spaces[i].get())); + } +} + +} // namespace blink 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 7de82499da3..8f87d6b29fe 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 @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "skia/ext/texture_handle.h" #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h" #include "third_party/blink/renderer/platform/graphics/graphics_context.h" #include "third_party/blink/renderer/platform/graphics/image_observer.h" @@ -92,13 +91,21 @@ scoped_refptr<StaticBitmapImage> StaticBitmapImage::ConvertToColorSpace( if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get())) return this; + // crbug.com/844145: Remove this when GPU-backed SkImage supports color + // covnersion for kRespect TransferFnBehavior (skia:6553). + if (skia_image->isTextureBacked() && + transfer_function_behavior == SkTransferFunctionBehavior::kRespect) { + skia_image = skia_image->makeNonTextureImage(); + } sk_sp<SkImage> converted_skia_image = skia_image->makeColorSpace(dst_color_space, transfer_function_behavior); DCHECK(converted_skia_image.get()); DCHECK(skia_image.get() != converted_skia_image.get()); return StaticBitmapImage::Create(converted_skia_image, - ContextProviderWrapper()); + converted_skia_image->isTextureBacked() + ? ContextProviderWrapper() + : nullptr); } bool StaticBitmapImage::ConvertToArrayBufferContents( 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 ea20292876e..5a596f14221 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 @@ -49,7 +49,7 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image { bool IsStaticBitmapImage() const override { return true; } // Methods overridden by all sub-classes - virtual ~StaticBitmapImage() = default; + ~StaticBitmapImage() override = default; // Creates a gpu copy of the image using the given ContextProvider. Should // not be called if IsTextureBacked() is already true. May return null if the // conversion failed (for instance if the context had an error). @@ -58,7 +58,7 @@ class PLATFORM_EXPORT StaticBitmapImage : public Image { // Methods have common implementation for all sub-classes bool CurrentFrameIsComplete() override { return true; } - void DestroyDecodedData() {} + void DestroyDecodedData() override {} // Methods that have a default implementation, and overridden by only one // sub-class diff --git a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc index f46a7d111e2..f07c3a9c77f 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.cc @@ -12,10 +12,8 @@ #include "components/viz/common/surfaces/surface_info.h" #include "media/base/media_switches.h" #include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom-blink.h" +#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" -#include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" #include "third_party/blink/renderer/platform/mojo/mojo_helper.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -30,31 +28,44 @@ SurfaceLayerBridge::SurfaceLayerBridge(WebLayerTreeView* layer_tree_view, frame_sink_id_(Platform::Current()->GenerateFrameSinkId()), parent_frame_sink_id_(layer_tree_view ? layer_tree_view->GetFrameSinkId() : viz::FrameSinkId()) { - mojom::blink::OffscreenCanvasProviderPtr provider; + mojom::blink::EmbeddedFrameSinkProviderPtr provider; Platform::Current()->GetInterfaceProvider()->GetInterface( mojo::MakeRequest(&provider)); // TODO(xlai): Ensure OffscreenCanvas commit() is still functional when a // frame-less HTML canvas's document is reparenting under another frame. // See crbug.com/683172. - blink::mojom::blink::OffscreenCanvasSurfaceClientPtr client; + blink::mojom::blink::EmbeddedFrameSinkClientPtr client; binding_.Bind(mojo::MakeRequest(&client)); - provider->CreateOffscreenCanvasSurface(parent_frame_sink_id_, frame_sink_id_, - std::move(client)); + provider->RegisterEmbeddedFrameSink(parent_frame_sink_id_, frame_sink_id_, + std::move(client)); } SurfaceLayerBridge::~SurfaceLayerBridge() { observer_ = nullptr; } +void SurfaceLayerBridge::ClearSurfaceId() { + current_surface_id_ = viz::SurfaceId(); + cc::SurfaceLayer* surface_layer = + static_cast<cc::SurfaceLayer*>(cc_layer_.get()); + + if (!surface_layer) + return; + + // We reset the Ids if we lose the context_provider (case: GPU process ended) + // If we destroyed the surface_layer before that point, we need not update + // the ids. + surface_layer->SetPrimarySurfaceId(viz::SurfaceId(), + cc::DeadlinePolicy::UseDefaultDeadline()); + surface_layer->SetFallbackSurfaceId(viz::SurfaceId()); +} + void SurfaceLayerBridge::CreateSolidColorLayer() { cc_layer_ = cc::SolidColorLayer::Create(); cc_layer_->SetBackgroundColor(SK_ColorTRANSPARENT); - web_layer_ = Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( - cc_layer_.get()); - if (observer_) - observer_->RegisterContentsLayer(web_layer_.get()); + observer_->RegisterContentsLayer(cc_layer_.get()); } void SurfaceLayerBridge::OnFirstSurfaceActivation( @@ -62,10 +73,10 @@ void SurfaceLayerBridge::OnFirstSurfaceActivation( if (!current_surface_id_.is_valid() && surface_info.is_valid()) { // First time a SurfaceId is received. current_surface_id_ = surface_info.id(); - if (web_layer_) { + if (cc_layer_) { if (observer_) - observer_->UnregisterContentsLayer(web_layer_.get()); - web_layer_->RemoveFromParent(); + observer_->UnregisterContentsLayer(cc_layer_.get()); + cc_layer_->RemoveFromParent(); } scoped_refptr<cc::SurfaceLayer> surface_layer = cc::SurfaceLayer::Create(); @@ -76,11 +87,8 @@ void SurfaceLayerBridge::OnFirstSurfaceActivation( surface_layer->SetIsDrawable(true); cc_layer_ = surface_layer; - web_layer_ = - Platform::Current()->CompositorSupport()->CreateLayerFromCCLayer( - cc_layer_.get()); if (observer_) - observer_->RegisterContentsLayer(web_layer_.get()); + observer_->RegisterContentsLayer(cc_layer_.get()); } else if (current_surface_id_ != surface_info.id()) { // A different SurfaceId is received, prompting change to existing // SurfaceLayer. diff --git a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h index a2ad32b512b..e2c931c524d 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h +++ b/chromium/third_party/blink/renderer/platform/graphics/surface_layer_bridge.h @@ -6,10 +6,11 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_SURFACE_LAYER_BRIDGE_H_ #include <memory> + #include "base/memory/scoped_refptr.h" #include "components/viz/common/surfaces/surface_id.h" #include "mojo/public/cpp/bindings/binding.h" -#include "third_party/blink/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom-blink.h" +#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h" #include "third_party/blink/public/platform/web_surface_layer_bridge.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -23,25 +24,25 @@ class SurfaceInfo; namespace blink { -class WebLayer; class WebLayerTreeView; // The SurfaceLayerBridge facilitates communication about changes to a Surface // between the Render and Browser processes. class PLATFORM_EXPORT SurfaceLayerBridge - : public blink::mojom::blink::OffscreenCanvasSurfaceClient, + : public blink::mojom::blink::EmbeddedFrameSinkClient, public WebSurfaceLayerBridge { public: SurfaceLayerBridge(WebLayerTreeView*, WebSurfaceLayerBridgeObserver*); - virtual ~SurfaceLayerBridge(); + ~SurfaceLayerBridge() override; void CreateSolidColorLayer(); - // Implementation of blink::mojom::blink::OffscreenCanvasSurfaceClient + // Implementation of blink::mojom::blink::EmbeddedFrameSinkClient void OnFirstSurfaceActivation(const viz::SurfaceInfo&) override; // Implementation of WebSurfaceLayerBridge. - WebLayer* GetWebLayer() const override { return web_layer_.get(); } + cc::Layer* GetCcLayer() const override { return cc_layer_.get(); } + void ClearSurfaceId() override; const viz::FrameSinkId& GetFrameSinkId() const override { return frame_sink_id_; @@ -49,11 +50,10 @@ class PLATFORM_EXPORT SurfaceLayerBridge private: scoped_refptr<cc::Layer> cc_layer_; - std::unique_ptr<WebLayer> web_layer_; WebSurfaceLayerBridgeObserver* observer_; - mojo::Binding<blink::mojom::blink::OffscreenCanvasSurfaceClient> binding_; + mojo::Binding<blink::mojom::blink::EmbeddedFrameSinkClient> binding_; const viz::FrameSinkId frame_sink_id_; viz::SurfaceId current_surface_id_; diff --git a/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc new file mode 100644 index 00000000000..0b5fe7b1e80 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.cc @@ -0,0 +1,26 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/platform/graphics/touch_action_rect.h" + +#include "base/containers/flat_map.h" +#include "cc/base/region.h" +#include "cc/layers/touch_action_region.h" + +namespace blink { + +// static +cc::TouchActionRegion TouchActionRect::BuildRegion( + const Vector<TouchActionRect>& touch_action_rects) { + base::flat_map<TouchAction, cc::Region> region_map; + region_map.reserve(touch_action_rects.size()); + for (const TouchActionRect& touch_action_rect : touch_action_rects) { + TouchAction action = touch_action_rect.whitelisted_touch_action; + const LayoutRect& rect = touch_action_rect.rect; + region_map[action].Union(EnclosingIntRect(rect)); + } + return cc::TouchActionRegion(std::move(region_map)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h new file mode 100644 index 00000000000..d32bf452d02 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/graphics/touch_action_rect.h @@ -0,0 +1,44 @@ +// 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_GRAPHICS_TOUCH_ACTION_RECT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TOUCH_ACTION_RECT_H_ + +#include "third_party/blink/renderer/platform/geometry/layout_rect.h" +#include "third_party/blink/renderer/platform/graphics/touch_action.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/vector.h" + +namespace cc { +class TouchActionRegion; +} + +namespace blink { + +class PaintLayer; + +struct PLATFORM_EXPORT TouchActionRect { + LayoutRect rect; + TouchAction whitelisted_touch_action; + + TouchActionRect(const LayoutRect& layout_rect, TouchAction action) + : rect(layout_rect), whitelisted_touch_action(action) {} + + static cc::TouchActionRegion BuildRegion(const Vector<TouchActionRect>&); + + bool operator==(const TouchActionRect& rhs) const { + return rect == rhs.rect && + whitelisted_touch_action == rhs.whitelisted_touch_action; + } + + bool operator!=(const TouchActionRect& rhs) const { return !(*this == rhs); } +}; + +using LayerHitTestRects = + WTF::HashMap<const PaintLayer*, Vector<TouchActionRect>>; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TOUCH_ACTION_RECT_H_ diff --git a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc index bafffea5e9a..45048ff77db 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/unaccelerated_static_bitmap_image.cc @@ -60,10 +60,9 @@ UnacceleratedStaticBitmapImage::MakeAccelerated( if (!grcontext) return nullptr; // Can happen if the context is lost. - // TODO(crbug.com/782383): This can return a SkColorSpace, which should be - // passed along. + sk_sp<SkImage> sk_image = paint_image_.GetSkImage(); sk_sp<SkImage> gpu_skimage = - paint_image_.GetSkImage()->makeTextureImage(grcontext, nullptr); + sk_image->makeTextureImage(grcontext, sk_image->colorSpace()); if (!gpu_skimage) return nullptr; diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc index de63be8779d..76a6dd3c515 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.cc @@ -16,52 +16,41 @@ #include "components/viz/common/quads/yuv_video_draw_quad.h" #include "media/base/video_frame.h" -namespace cc { -class VideoFrameExternalResources; -} // namespace cc - namespace blink { VideoFrameResourceProvider::VideoFrameResourceProvider( - WebContextProviderCallback context_provider_callback, - viz::SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const cc::LayerTreeSettings& settings) - : context_provider_callback_(std::move(context_provider_callback)), - shared_bitmap_manager_(shared_bitmap_manager), - gpu_memory_buffer_manager_(gpu_memory_buffer_manager), - settings_(settings), - weak_ptr_factory_(this) {} + : settings_(settings) {} -VideoFrameResourceProvider::~VideoFrameResourceProvider() { - if (context_provider_) { - resource_updater_ = nullptr; - resource_provider_ = nullptr; - } -} - -void VideoFrameResourceProvider::ObtainContextProvider() { - context_provider_callback_.Run(base::BindOnce( - &VideoFrameResourceProvider::Initialize, weak_ptr_factory_.GetWeakPtr())); -} +VideoFrameResourceProvider::~VideoFrameResourceProvider() = default; void VideoFrameResourceProvider::Initialize( - viz::ContextProvider* media_context_provider) { - // TODO(lethalantidote): Need to handle null contexts. - // https://crbug/768565 - CHECK(media_context_provider); + viz::ContextProvider* media_context_provider, + viz::SharedBitmapReporter* shared_bitmap_reporter) { context_provider_ = media_context_provider; - resource_provider_ = std::make_unique<cc::LayerTreeResourceProvider>( - media_context_provider, shared_bitmap_manager_, - gpu_memory_buffer_manager_, true, settings_.resource_settings); + media_context_provider, true); + + int max_texture_size; + if (context_provider_) { + max_texture_size = + context_provider_->ContextCapabilities().max_texture_size; + } else { + // Pick an arbitrary limit here similar to what hardware might. + max_texture_size = 16 * 1024; + } - // TODO(kylechar): VideoResourceUpdater needs something it can notify about - // SharedBitmaps that isn't a LayerTreeFrameSink. https://crbug.com/730660#c88 resource_updater_ = std::make_unique<cc::VideoResourceUpdater>( - context_provider_, nullptr, resource_provider_.get(), + media_context_provider, shared_bitmap_reporter, resource_provider_.get(), settings_.use_stream_video_draw_quad, - settings_.resource_settings.use_gpu_memory_buffer_resources); + settings_.resource_settings.use_gpu_memory_buffer_resources, + settings_.resource_settings.use_r16_texture, max_texture_size); +} + +void VideoFrameResourceProvider::OnContextLost() { + resource_updater_ = nullptr; + resource_provider_ = nullptr; + context_provider_ = nullptr; } void VideoFrameResourceProvider::AppendQuads( @@ -69,6 +58,9 @@ void VideoFrameResourceProvider::AppendQuads( scoped_refptr<media::VideoFrame> frame, media::VideoRotation rotation) { TRACE_EVENT0("media", "VideoFrameResourceProvider::AppendQuads"); + DCHECK(resource_updater_); + DCHECK(resource_provider_); + gfx::Transform transform = gfx::Transform(); gfx::Size rotated_size = frame->coded_size(); @@ -115,9 +107,10 @@ void VideoFrameResourceProvider::ReleaseFrameResources() { } void VideoFrameResourceProvider::PrepareSendToParent( - const cc::LayerTreeResourceProvider::ResourceIdArray& resource_ids, + const std::vector<viz::ResourceId>& resource_ids, std::vector<viz::TransferableResource>* transferable_resources) { - resource_provider_->PrepareSendToParent(resource_ids, transferable_resources); + resource_provider_->PrepareSendToParent(resource_ids, transferable_resources, + context_provider_); } void VideoFrameResourceProvider::ReceiveReturnsFromParent( diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h index 9320146c2b2..8f785932895 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h +++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h @@ -9,17 +9,13 @@ #include "cc/resources/layer_tree_resource_provider.h" #include "cc/resources/video_resource_updater.h" #include "cc/trees/layer_tree_settings.h" +#include "components/viz/common/resources/shared_bitmap_reporter.h" #include "media/base/video_frame.h" #include "third_party/blink/public/platform/web_video_frame_submitter.h" #include "third_party/blink/renderer/platform/platform_export.h" -namespace gpu { -class GpuMemoryBufferManager; -} - namespace viz { class RenderPass; -class SharedBitmapManager; } namespace blink { @@ -31,35 +27,35 @@ namespace blink { // https://crbug.com/753605 class PLATFORM_EXPORT VideoFrameResourceProvider { public: - explicit VideoFrameResourceProvider(WebContextProviderCallback, - viz::SharedBitmapManager*, - gpu::GpuMemoryBufferManager*, - const cc::LayerTreeSettings&); + explicit VideoFrameResourceProvider(const cc::LayerTreeSettings&); virtual ~VideoFrameResourceProvider(); - virtual void ObtainContextProvider(); - virtual void Initialize(viz::ContextProvider*); + virtual void Initialize(viz::ContextProvider*, viz::SharedBitmapReporter*); virtual void AppendQuads(viz::RenderPass*, scoped_refptr<media::VideoFrame>, media::VideoRotation); virtual void ReleaseFrameResources(); + // Once the context is lost, we must call Initialize again before we can + // continue doing work. + void OnContextLost(); + + bool IsInitialized() { return resource_updater_.get(); } + virtual void PrepareSendToParent( - const cc::LayerTreeResourceProvider::ResourceIdArray& resource_ids, + const std::vector<viz::ResourceId>& resource_ids, std::vector<viz::TransferableResource>* transferable_resources); virtual void ReceiveReturnsFromParent( const std::vector<viz::ReturnedResource>& transferable_resources); private: + const cc::LayerTreeSettings settings_; + WebContextProviderCallback context_provider_callback_; - viz::SharedBitmapManager* shared_bitmap_manager_; - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; - cc::LayerTreeSettings settings_; - std::unique_ptr<cc::VideoResourceUpdater> resource_updater_; + viz::ContextProvider* context_provider_; std::unique_ptr<cc::LayerTreeResourceProvider> resource_provider_; - viz::ContextProvider* context_provider_ = nullptr; - base::WeakPtrFactory<VideoFrameResourceProvider> weak_ptr_factory_; + std::unique_ptr<cc::VideoResourceUpdater> resource_updater_; }; } // 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 a587c82470a..d72158a7300 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 @@ -4,32 +4,72 @@ #include "third_party/blink/renderer/platform/graphics/video_frame_submitter.h" +#include "base/task_runner.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "cc/paint/filter_operations.h" -#include "cc/resources/resource_provider.h" #include "cc/resources/video_resource_updater.h" #include "cc/scheduler/video_frame_controller.h" +#include "components/viz/common/resources/resource_id.h" +#include "components/viz/common/resources/returned_resource.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "media/base/video_frame.h" +#include "services/ui/public/cpp/gpu/context_provider_command_buffer.h" #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" #include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/modules/offscreencanvas/offscreen_canvas_surface.mojom-blink.h" +#include "third_party/blink/public/platform/modules/frame_sinks/embedded_frame_sink.mojom-blink.h" #include "third_party/blink/public/platform/platform.h" namespace blink { +namespace { + +// TODO(danakj): One day the gpu::mojom::Mailbox type should be shared with +// blink directly and we won't need to use gpu::mojom::blink::Mailbox, nor the +// conversion through WTF::Vector. +gpu::mojom::blink::MailboxPtr SharedBitmapIdToGpuMailboxPtr( + const viz::SharedBitmapId& id) { + WTF::Vector<int8_t> name(GL_MAILBOX_SIZE_CHROMIUM); + for (int i = 0; i < GL_MAILBOX_SIZE_CHROMIUM; ++i) + name[i] = id.name[i]; + return {base::in_place, name}; +} + +// Delay to retry getting the context_provider. +constexpr int kGetContextProviderRetryMS = 150; + +} // namespace + VideoFrameSubmitter::VideoFrameSubmitter( + WebContextProviderCallback context_provider_callback, std::unique_ptr<VideoFrameResourceProvider> resource_provider) : binding_(this), + context_provider_callback_(context_provider_callback), resource_provider_(std::move(resource_provider)), is_rendering_(false), weak_ptr_factory_(this) { - current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId(); DETACH_FROM_THREAD(media_thread_checker_); } -VideoFrameSubmitter::~VideoFrameSubmitter() = default; +VideoFrameSubmitter::~VideoFrameSubmitter() { + if (context_provider_) + context_provider_->RemoveObserver(this); +} + +void VideoFrameSubmitter::SetRotation(media::VideoRotation rotation) { + rotation_ = rotation; +} + +void VideoFrameSubmitter::EnableSubmission( + viz::FrameSinkId id, + WebFrameSinkDestroyedCallback frame_sink_destroyed_callback) { + // TODO(lethalantidote): Set these fields earlier in the constructor. Will + // need to construct VideoFrameSubmitter later in order to do this. + frame_sink_id_ = id; + frame_sink_destroyed_callback_ = frame_sink_destroyed_callback; + if (resource_provider_->IsInitialized()) + StartSubmitting(); +} void VideoFrameSubmitter::StopUsingProvider() { DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); @@ -43,14 +83,20 @@ void VideoFrameSubmitter::StopRendering() { DCHECK(is_rendering_); DCHECK(provider_); - // Push out final frame. - SubmitSingleFrame(); - + if (compositor_frame_sink_) { + // Push out final frame. + SubmitSingleFrame(); + compositor_frame_sink_->SetNeedsBeginFrame(false); + } is_rendering_ = false; - compositor_frame_sink_->SetNeedsBeginFrame(false); } void VideoFrameSubmitter::SubmitSingleFrame() { + // If we haven't gotten a valid result yet from |context_provider_callback_| + // |resource_provider_| will remain uninitalized. + if (!resource_provider_->IsInitialized()) + return; + viz::BeginFrameAck current_begin_frame_ack = viz::BeginFrameAck::CreateManualAckWithDamage(); scoped_refptr<media::VideoFrame> video_frame = provider_->GetCurrentFrame(); @@ -75,7 +121,8 @@ void VideoFrameSubmitter::DidReceiveFrame() { void VideoFrameSubmitter::StartRendering() { DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); DCHECK(!is_rendering_); - compositor_frame_sink_->SetNeedsBeginFrame(true); + if (compositor_frame_sink_) + compositor_frame_sink_->SetNeedsBeginFrame(true); is_rendering_ = true; } @@ -84,23 +131,55 @@ void VideoFrameSubmitter::Initialize(cc::VideoFrameProvider* provider) { if (provider) { DCHECK(!provider_); provider_ = provider; - resource_provider_->ObtainContextProvider(); + context_provider_callback_.Run( + base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider, + weak_ptr_factory_.GetWeakPtr())); } } -void VideoFrameSubmitter::StartSubmitting(const viz::FrameSinkId& id) { +void VideoFrameSubmitter::OnReceivedContextProvider( + bool use_gpu_compositing, + scoped_refptr<ui::ContextProviderCommandBuffer> context_provider) { + // We could get a null |context_provider| back if the context is still lost. + if (!context_provider && use_gpu_compositing) { + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + base::BindOnce( + context_provider_callback_, + base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider, + weak_ptr_factory_.GetWeakPtr())), + base::TimeDelta::FromMilliseconds(kGetContextProviderRetryMS)); + return; + } + + context_provider_ = std::move(context_provider); + if (use_gpu_compositing) { + context_provider_->AddObserver(this); + resource_provider_->Initialize(context_provider_.get(), nullptr); + } else { + resource_provider_->Initialize(nullptr, this); + } + + if (frame_sink_id_.is_valid()) + StartSubmitting(); +} + +void VideoFrameSubmitter::StartSubmitting() { DCHECK_CALLED_ON_VALID_THREAD(media_thread_checker_); - DCHECK(id.is_valid()); + DCHECK(frame_sink_id_.is_valid()); - // TODO(lethalantidote): Class to be renamed. - mojom::blink::OffscreenCanvasProviderPtr canvas_provider; + mojom::blink::EmbeddedFrameSinkProviderPtr provider; Platform::Current()->GetInterfaceProvider()->GetInterface( - mojo::MakeRequest(&canvas_provider)); + mojo::MakeRequest(&provider)); viz::mojom::blink::CompositorFrameSinkClientPtr client; binding_.Bind(mojo::MakeRequest(&client)); - canvas_provider->CreateCompositorFrameSink( - id, std::move(client), mojo::MakeRequest(&compositor_frame_sink_)); + provider->CreateCompositorFrameSink( + frame_sink_id_, std::move(client), + mojo::MakeRequest(&compositor_frame_sink_)); + + if (is_rendering_) + compositor_frame_sink_->SetNeedsBeginFrame(true); scoped_refptr<media::VideoFrame> video_frame = provider_->GetCurrentFrame(); if (video_frame) { @@ -132,7 +211,7 @@ void VideoFrameSubmitter::SubmitFrame( compositor_frame.metadata.device_scale_factor = 1; compositor_frame.metadata.may_contain_video = true; - cc::ResourceProvider::ResourceIdArray resources; + std::vector<viz::ResourceId> resources; for (auto* quad : render_pass->quad_list) { for (viz::ResourceId resource_id : quad->resources) { resources.push_back(resource_id); @@ -143,13 +222,14 @@ void VideoFrameSubmitter::SubmitFrame( compositor_frame.render_pass_list.push_back(std::move(render_pass)); if (compositor_frame.size_in_pixels() != current_size_in_pixels_) { - current_local_surface_id_ = parent_local_surface_id_allocator_.GenerateId(); + parent_local_surface_id_allocator_.GenerateId(); current_size_in_pixels_ = compositor_frame.size_in_pixels(); } // TODO(lethalantidote): Address third/fourth arg in SubmitCompositorFrame. compositor_frame_sink_->SubmitCompositorFrame( - current_local_surface_id_, std::move(compositor_frame), nullptr, 0); + parent_local_surface_id_allocator_.GetCurrentLocalSurfaceId(), + std::move(compositor_frame), nullptr, 0); resource_provider_->ReleaseFrameResources(); } @@ -180,8 +260,23 @@ void VideoFrameSubmitter::OnBeginFrame(const viz::BeginFrameArgs& args) { provider_->PutCurrentFrame(); } -void VideoFrameSubmitter::SetRotation(media::VideoRotation rotation) { - rotation_ = rotation; +void VideoFrameSubmitter::OnContextLost() { + // TODO(lethalantidote): This check will be obsolete once other TODO to move + // field initialization earlier is fulfilled. + if (frame_sink_destroyed_callback_) + frame_sink_destroyed_callback_.Run(); + + if (binding_.is_bound()) + binding_.Unbind(); + + compositor_frame_sink_.reset(); + context_provider_->RemoveObserver(this); + context_provider_ = nullptr; + + resource_provider_->OnContextLost(); + context_provider_callback_.Run( + base::BindOnce(&VideoFrameSubmitter::OnReceivedContextProvider, + weak_ptr_factory_.GetWeakPtr())); } void VideoFrameSubmitter::DidReceiveCompositorFrameAck( @@ -207,4 +302,19 @@ void VideoFrameSubmitter::DidPresentCompositorFrame( void VideoFrameSubmitter::DidDiscardCompositorFrame( uint32_t presentation_token) {} + +void VideoFrameSubmitter::DidAllocateSharedBitmap( + mojo::ScopedSharedBufferHandle buffer, + const viz::SharedBitmapId& id) { + DCHECK(compositor_frame_sink_); + compositor_frame_sink_->DidAllocateSharedBitmap( + std::move(buffer), SharedBitmapIdToGpuMailboxPtr(id)); +} + +void VideoFrameSubmitter::DidDeleteSharedBitmap(const viz::SharedBitmapId& id) { + DCHECK(compositor_frame_sink_); + compositor_frame_sink_->DidDeleteSharedBitmap( + SharedBitmapIdToGpuMailboxPtr(id)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h index 4797e36f45f..f6facc2a2a8 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h +++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter.h @@ -7,8 +7,12 @@ #include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" +#include "components/viz/common/gpu/context_provider.h" +#include "components/viz/common/quads/shared_bitmap.h" +#include "components/viz/common/resources/shared_bitmap_reporter.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/system/buffer.h" #include "services/viz/public/interfaces/compositing/compositor_frame_sink.mojom-blink.h" #include "third_party/blink/public/platform/web_video_frame_submitter.h" #include "third_party/blink/renderer/platform/graphics/video_frame_resource_provider.h" @@ -24,17 +28,15 @@ namespace blink { // should be consistently ran from the same media SingleThreadTaskRunner. class PLATFORM_EXPORT VideoFrameSubmitter : public WebVideoFrameSubmitter, + public viz::ContextLostObserver, + public viz::SharedBitmapReporter, public viz::mojom::blink::CompositorFrameSinkClient { public: - explicit VideoFrameSubmitter(std::unique_ptr<VideoFrameResourceProvider>); + explicit VideoFrameSubmitter(WebContextProviderCallback, + std::unique_ptr<VideoFrameResourceProvider>); ~VideoFrameSubmitter() override; - static void CreateCompositorFrameSink( - const viz::FrameSinkId, - mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient>*, - viz::mojom::blink::CompositorFrameSinkPtr*); - bool Rendering() { return is_rendering_; }; cc::VideoFrameProvider* Provider() { return provider_; } mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient>* Binding() { @@ -44,6 +46,10 @@ class PLATFORM_EXPORT VideoFrameSubmitter compositor_frame_sink_ = std::move(*sink); } + void OnReceivedContextProvider( + bool, + scoped_refptr<ui::ContextProviderCommandBuffer>); + // cc::VideoFrameProvider::Client implementation. void StopUsingProvider() override; void StartRendering() override; @@ -52,8 +58,12 @@ class PLATFORM_EXPORT VideoFrameSubmitter // WebVideoFrameSubmitter implementation. void Initialize(cc::VideoFrameProvider*) override; - void StartSubmitting(const viz::FrameSinkId&) override; void SetRotation(media::VideoRotation) override; + void EnableSubmission(viz::FrameSinkId, + WebFrameSinkDestroyedCallback) override; + + // viz::ContextLostObserver implementation. + void OnContextLost() override; // cc::mojom::CompositorFrameSinkClient implementation. void DidReceiveCompositorFrameAck( @@ -68,7 +78,13 @@ class PLATFORM_EXPORT VideoFrameSubmitter void ReclaimResources( const WTF::Vector<viz::ReturnedResource>& resources) override; + // viz::SharedBitmapReporter implementation. + void DidAllocateSharedBitmap(mojo::ScopedSharedBufferHandle, + const viz::SharedBitmapId&) override; + void DidDeleteSharedBitmap(const viz::SharedBitmapId&) override; + private: + void StartSubmitting(); void SubmitFrame(viz::BeginFrameAck, scoped_refptr<media::VideoFrame>); // Pulls frame and submits it to compositor. @@ -78,19 +94,23 @@ class PLATFORM_EXPORT VideoFrameSubmitter void SubmitSingleFrame(); cc::VideoFrameProvider* provider_ = nullptr; + scoped_refptr<ui::ContextProviderCommandBuffer> context_provider_; viz::mojom::blink::CompositorFrameSinkPtr compositor_frame_sink_; mojo::Binding<viz::mojom::blink::CompositorFrameSinkClient> binding_; viz::ParentLocalSurfaceIdAllocator parent_local_surface_id_allocator_; - viz::LocalSurfaceId current_local_surface_id_; + WebContextProviderCallback context_provider_callback_; std::unique_ptr<VideoFrameResourceProvider> resource_provider_; + WebFrameSinkDestroyedCallback frame_sink_destroyed_callback_; + viz::FrameSinkId frame_sink_id_; bool is_rendering_; media::VideoRotation rotation_; gfx::Size current_size_in_pixels_; - base::WeakPtrFactory<VideoFrameSubmitter> weak_ptr_factory_; THREAD_CHECKER(media_thread_checker_); + base::WeakPtrFactory<VideoFrameSubmitter> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(VideoFrameSubmitter); }; diff --git a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc index 53c51912273..674465d8bf8 100644 --- a/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc +++ b/chromium/third_party/blink/renderer/platform/graphics/video_frame_submitter_test.cc @@ -35,7 +35,7 @@ namespace { class MockVideoFrameProvider : public cc::VideoFrameProvider { public: MockVideoFrameProvider() = default; - ~MockVideoFrameProvider() = default; + ~MockVideoFrameProvider() override = default; MOCK_METHOD1(SetVideoFrameProviderClient, void(Client*)); MOCK_METHOD2(UpdateCurrentFrame, bool(base::TimeTicks, base::TimeTicks)); @@ -52,7 +52,7 @@ class MockCompositorFrameSink : public viz::mojom::blink::CompositorFrameSink { MockCompositorFrameSink( viz::mojom::blink::CompositorFrameSinkRequest* request) : binding_(this, std::move(*request)) {} - ~MockCompositorFrameSink() = default; + ~MockCompositorFrameSink() override = default; MOCK_METHOD1(SetNeedsBeginFrame, void(bool)); MOCK_METHOD0(SetWantsAnimateOnlyBeginFrames, void()); @@ -66,6 +66,14 @@ class MockCompositorFrameSink : public viz::mojom::blink::CompositorFrameSink { uint64_t submit_time) override { DoSubmitCompositorFrame(id, &frame); } + void SubmitCompositorFrameSync( + const viz::LocalSurfaceId& id, + viz::CompositorFrame frame, + viz::mojom::blink::HitTestRegionListPtr hit_test_region_list, + uint64_t submit_time, + const SubmitCompositorFrameSyncCallback callback) override { + DoSubmitCompositorFrame(id, &frame); + } MOCK_METHOD1(DidNotProduceFrame, void(const viz::BeginFrameAck&)); @@ -91,25 +99,24 @@ class MockCompositorFrameSink : public viz::mojom::blink::CompositorFrameSink { class MockVideoFrameResourceProvider : public blink::VideoFrameResourceProvider { public: - MockVideoFrameResourceProvider(viz::ContextProvider* context_provider) - : blink::VideoFrameResourceProvider( - base::BindRepeating( - [](base::OnceCallback<void(viz::ContextProvider*)>) {}), - nullptr, - nullptr, - cc::LayerTreeSettings()) { - blink::VideoFrameResourceProvider::Initialize(context_provider); + MockVideoFrameResourceProvider( + viz::ContextProvider* context_provider, + viz::SharedBitmapReporter* shared_bitmap_reporter) + : blink::VideoFrameResourceProvider(cc::LayerTreeSettings()) { + blink::VideoFrameResourceProvider::Initialize(context_provider, + shared_bitmap_reporter); } - ~MockVideoFrameResourceProvider() = default; + ~MockVideoFrameResourceProvider() override = default; - MOCK_METHOD1(Initialize, void(viz::ContextProvider*)); + MOCK_METHOD2(Initialize, + void(viz::ContextProvider*, viz::SharedBitmapReporter*)); MOCK_METHOD3(AppendQuads, void(viz::RenderPass*, scoped_refptr<media::VideoFrame>, media::VideoRotation)); MOCK_METHOD0(ReleaseFrameResources, void()); MOCK_METHOD2(PrepareSendToParent, - void(const cc::LayerTreeResourceProvider::ResourceIdArray&, + void(const std::vector<viz::ResourceId>&, std::vector<viz::TransferableResource>*)); MOCK_METHOD1( ReceiveReturnsFromParent, @@ -137,12 +144,14 @@ class VideoFrameSubmitterTest : public testing::Test { } void MakeSubmitter() { - resource_provider_ = - new StrictMock<MockVideoFrameResourceProvider>(context_provider_.get()); + resource_provider_ = new StrictMock<MockVideoFrameResourceProvider>( + context_provider_.get(), nullptr); submitter_ = std::make_unique<VideoFrameSubmitter>( + base::BindRepeating( + [](base::OnceCallback<void( + bool, scoped_refptr<ui::ContextProviderCommandBuffer>)>) {}), base::WrapUnique<MockVideoFrameResourceProvider>(resource_provider_)); - EXPECT_CALL(*resource_provider_, ObtainContextProvider()); submitter_->Initialize(provider_.get()); viz::mojom::blink::CompositorFrameSinkPtr submitter_sink; viz::mojom::blink::CompositorFrameSinkRequest request = diff --git a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn index 254b8b9d715..b889f9297d0 100644 --- a/chromium/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/chromium/third_party/blink/renderer/platform/heap/BUILD.gn @@ -8,16 +8,14 @@ import("//third_party/blink/renderer/platform/platform.gni") import("//testing/test.gni") declare_args() { - # Enables incremental marking in Oilpan. + # Build Blink with incremental marking infrastructure for Oilpan. # - # Note: Incremental marking is currently considered experimental and also - # enables 'enable_blink_heap_incremental_marking'. See default value below. - enable_blink_heap_incremental_marking = false -} + # To turn on incremental marking also use + # --enable-blink-features=HeapIncrementalMarking + enable_blink_heap_incremental_marking = true -declare_args() { # Enables heap verification. - enable_blink_heap_verification = enable_blink_heap_incremental_marking + enable_blink_heap_verification = false } buildflag_header("blink_heap_buildflags") { @@ -32,9 +30,12 @@ buildflag_header("blink_heap_buildflags") { blink_platform_sources("heap") { sources = [ + "address_cache.cc", + "address_cache.h", "blink_gc.h", "blink_gc_memory_dump_provider.cc", "blink_gc_memory_dump_provider.h", + "finalizer_traits.h", "garbage_collected.h", "gc_info.cc", "gc_info.h", @@ -49,6 +50,8 @@ blink_platform_sources("heap") { "heap_linked_stack.h", "heap_page.cc", "heap_page.h", + "heap_stats_collector.cc", + "heap_stats_collector.h", "heap_terminated_array.h", "heap_terminated_array_builder.h", "heap_traits.h", @@ -56,6 +59,7 @@ blink_platform_sources("heap") { "marking_visitor.cc", "marking_visitor.h", "member.h", + "name_traits.h", "page_memory.cc", "page_memory.h", "page_pool.cc", @@ -106,8 +110,11 @@ test("blink_heap_unittests") { jumbo_source_set("blink_heap_unittests_sources") { testonly = true sources = [ + "address_cache_test.cc", "blink_gc_memory_dump_provider_test.cc", + "gc_info_test.cc", "heap_compact_test.cc", + "heap_stats_collector_test.cc", "heap_test.cc", "heap_test_utilities.cc", "heap_test_utilities.h", diff --git a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md index ea23a2d9ebd..fe40df89450 100644 --- a/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md +++ b/chromium/third_party/blink/renderer/platform/heap/BlinkGCAPIReference.md @@ -472,7 +472,7 @@ class MyGarbageCollectedClass : public GarbageCollected<MyGarbageCollectedClass> }; ``` -When you want to add a heap collection as a member of a non-garbage-collected class, please use the persistent variants (just prefix the type with Persistent e.g. PersistentHeapVector, PersistentHeapHashMap, etc.). +When you want to add a heap collection as a member of a non-garbage-collected class (on the main thread), please use the persistent variants (just prefix the type with Persistent e.g. PersistentHeapVector, PersistentHeapHashMap, etc.). ```c++ class MyNotGarbageCollectedClass { @@ -481,6 +481,8 @@ class MyNotGarbageCollectedClass { }; ``` +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. + 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. ### Weak collections diff --git a/chromium/third_party/blink/renderer/platform/heap/DEPS b/chromium/third_party/blink/renderer/platform/heap/DEPS index 3600042e6a4..c5aa107a763 100644 --- a/chromium/third_party/blink/renderer/platform/heap/DEPS +++ b/chromium/third_party/blink/renderer/platform/heap/DEPS @@ -1,11 +1,28 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/heap", + + # Dependencies. "+base/atomicops.h", "+base/bits.h", "+base/compiler_specific.h", "+base/synchronization/lock.h", "+base/sys_info.h", + + "+third_party/blink/renderer/platform/bindings", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/memory_coordinator.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/heap/address_cache.cc b/chromium/third_party/blink/renderer/platform/heap/address_cache.cc new file mode 100644 index 00000000000..06c24e011f5 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/address_cache.cc @@ -0,0 +1,58 @@ +// 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 { + +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 new file mode 100644 index 00000000000..85c676cd6b2 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/address_cache.h @@ -0,0 +1,55 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef 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" + +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: + AddressCache() : enabled_(false), has_entries_(false), dirty_(false) { + // Start by flushing the cache in a non-empty state to initialize all the + // cache entries. + for (size_t i = 0; i < kNumberOfEntries; ++i) + entries_[i] = nullptr; + } + + void EnableLookup() { enabled_ = true; } + void DisableLookup() { enabled_ = false; } + + void MarkDirty() { dirty_ = true; } + void Flush(); + void FlushIfDirty(); + bool IsEmpty() { 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 new file mode 100644 index 00000000000..001b32ce553 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/address_cache_test.cc @@ -0,0 +1,74 @@ +// 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, 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 65d62de254f..887425e50cf 100644 --- a/chromium/third_party/blink/renderer/platform/heap/blink_gc.h +++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc.h @@ -28,7 +28,6 @@ using TraceCallback = VisitorCallback; using TraceWrappersCallback = void (*)(ScriptWrappableVisitor*, void*); using WeakCallback = VisitorCallback; using EphemeronCallback = VisitorCallback; -using MissedWriteBarrierCallback = void (*)(); using NameCallback = const char* (*)(const void* self); // Callback used for unit testing the marking of conservative pointers @@ -97,14 +96,15 @@ class PLATFORM_EXPORT BlinkGC final { }; enum GCReason { - kIdleGC, - kPreciseGC, - kConservativeGC, - kForcedGC, - kMemoryPressureGC, - kPageNavigationGC, - kThreadTerminationGC, - kLastGCReason = kThreadTerminationGC, + kIdleGC = 0, + kPreciseGC = 1, + kConservativeGC = 2, + kForcedGC = 3, + kMemoryPressureGC = 4, + kPageNavigationGC = 5, + kThreadTerminationGC = 6, + kTesting = 7, + kLastGCReason = kTesting, }; enum ArenaIndices { diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc index fb672d0bc11..53df6c751e6 100644 --- a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc +++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.cc @@ -6,10 +6,8 @@ #include <unordered_map> -#include "base/trace_event/heap_profiler_allocation_context_tracker.h" #include "base/trace_event/memory_allocator_dump.h" #include "base/trace_event/process_memory_dump.h" -#include "base/trace_event/trace_event_memory_overhead.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/web_memory_allocator_dump.h" @@ -35,14 +33,6 @@ void DumpMemoryTotals(base::trace_event::ProcessMemoryDump* memory_dump) { ProcessHeap::TotalMarkedObjectSize()); } -void ReportAllocation(Address address, size_t size, const char* type_name) { - BlinkGCMemoryDumpProvider::Instance()->insert(address, size, type_name); -} - -void ReportFree(Address address) { - BlinkGCMemoryDumpProvider::Instance()->Remove(address); -} - } // namespace BlinkGCMemoryDumpProvider* BlinkGCMemoryDumpProvider::Instance() { @@ -66,37 +56,12 @@ bool BlinkGCMemoryDumpProvider::OnMemoryDump( } DumpMemoryTotals(memory_dump); - if (allocation_register_.is_enabled()) { - // Overhead should always be reported, regardless of light vs. heavy. - base::trace_event::TraceEventMemoryOverhead overhead; - std::unordered_map<base::trace_event::AllocationContext, - base::trace_event::AllocationMetrics> - metrics_by_context; - if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { - allocation_register_.UpdateAndReturnsMetrics(metrics_by_context); - } - allocation_register_.EstimateTraceMemoryOverhead(&overhead); - memory_dump->DumpHeapUsage(metrics_by_context, overhead, "blink_gc"); - } - // Merge all dumps collected by ThreadHeap::collectGarbage. if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) memory_dump->TakeAllDumpsFrom(current_process_memory_dump_.get()); return true; } -void BlinkGCMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) { - if (enabled) { - allocation_register_.SetEnabled(); - HeapAllocHooks::SetAllocationHook(ReportAllocation); - HeapAllocHooks::SetFreeHook(ReportFree); - } else { - HeapAllocHooks::SetAllocationHook(nullptr); - HeapAllocHooks::SetFreeHook(nullptr); - allocation_register_.SetDisabled(); - } -} - base::trace_event::MemoryAllocatorDump* BlinkGCMemoryDumpProvider::CreateMemoryAllocatorDumpForCurrentGC( const String& absolute_name) { @@ -114,24 +79,4 @@ BlinkGCMemoryDumpProvider::BlinkGCMemoryDumpProvider() nullptr, {base::trace_event::MemoryDumpLevelOfDetail::DETAILED})) {} -void BlinkGCMemoryDumpProvider::insert(Address address, - size_t size, - const char* type_name) { - base::trace_event::AllocationContext context; - if (!base::trace_event::AllocationContextTracker:: - GetInstanceForCurrentThread() - ->GetContextSnapshot(&context)) - return; - context.type_name = type_name; - if (!allocation_register_.is_enabled()) - return; - allocation_register_.Insert(address, size, context); -} - -void BlinkGCMemoryDumpProvider::Remove(Address address) { - if (!allocation_register_.is_enabled()) - return; - allocation_register_.Remove(address); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h index 89bf8b5fcd6..16d905d659f 100644 --- a/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h +++ b/chromium/third_party/blink/renderer/platform/heap/blink_gc_memory_dump_provider.h @@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_BLINK_GC_MEMORY_DUMP_PROVIDER_H_ #include "base/trace_event/memory_dump_provider.h" -#include "base/trace_event/sharded_allocation_register.h" #include "third_party/blink/renderer/platform/heap/blink_gc.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -34,7 +33,6 @@ class PLATFORM_EXPORT BlinkGCMemoryDumpProvider final // MemoryDumpProvider implementation. bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&, base::trace_event::ProcessMemoryDump*) override; - void OnHeapProfilingEnabled(bool) override; // The returned WebMemoryAllocatorDump is owned by // BlinkGCMemoryDumpProvider, and should not be retained (just used to @@ -50,13 +48,9 @@ class PLATFORM_EXPORT BlinkGCMemoryDumpProvider final return current_process_memory_dump_.get(); } - void insert(Address, size_t, const char*); - void Remove(Address); - private: BlinkGCMemoryDumpProvider(); - base::trace_event::ShardedAllocationRegister allocation_register_; std::unique_ptr<base::trace_event::ProcessMemoryDump> current_process_memory_dump_; }; diff --git a/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h new file mode 100644 index 00000000000..c0b335cb874 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/finalizer_traits.h @@ -0,0 +1,132 @@ +// 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_FINALIZER_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_ + +#include "third_party/blink/renderer/platform/heap/garbage_collected.h" + +namespace WTF { + +template <typename ValueArg, typename Allocator> +class ListHashSetNode; + +} // namespace WTF + +namespace blink { + +// The FinalizerTraitImpl specifies how to finalize objects. Objects that +// inherit from GarbageCollectedFinalized are finalized by calling their +// |Finalize| method which by default will call the destructor on the object. +template <typename T, bool isGarbageCollectedFinalized> +struct FinalizerTraitImpl; + +template <typename T> +struct FinalizerTraitImpl<T, true> { + STATIC_ONLY(FinalizerTraitImpl); + static void Finalize(void* obj) { + static_assert(sizeof(T), "T must be fully defined"); + static_cast<T*>(obj)->FinalizeGarbageCollectedObject(); + }; +}; + +template <typename T> +struct FinalizerTraitImpl<T, false> { + STATIC_ONLY(FinalizerTraitImpl); + static void Finalize(void* obj) { + static_assert(sizeof(T), "T must be fully defined"); + }; +}; + +// The FinalizerTrait is used to determine if a type requires finalization and +// what finalization means. +// +// By default classes that inherit from GarbageCollectedFinalized need +// finalization and finalization means calling the |Finalize| method of the +// object. The FinalizerTrait can be specialized if the default behavior is not +// desired. +template <typename T> +struct FinalizerTrait { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = + WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type, + GarbageCollectedFinalized>::value; + static void Finalize(void* obj) { + FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj); + } +}; + +class HeapAllocator; +template <typename T, typename Traits> +class HeapVectorBacking; +template <typename Table> +class HeapHashTableBacking; + +template <typename T, typename U, typename V> +struct FinalizerTrait<LinkedHashSet<T, U, V, HeapAllocator>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = true; + static void Finalize(void* obj) { + FinalizerTraitImpl<LinkedHashSet<T, U, V, HeapAllocator>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +template <typename T, typename Allocator> +struct FinalizerTrait<WTF::ListHashSetNode<T, Allocator>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = + !WTF::IsTriviallyDestructible<T>::value; + static void Finalize(void* obj) { + FinalizerTraitImpl<WTF::ListHashSetNode<T, Allocator>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +template <typename T, size_t inlineCapacity> +struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = + inlineCapacity && VectorTraits<T>::kNeedsDestruction; + static void Finalize(void* obj) { + FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +template <typename T, size_t inlineCapacity> +struct FinalizerTrait<Deque<T, inlineCapacity, HeapAllocator>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = + inlineCapacity && VectorTraits<T>::kNeedsDestruction; + static void Finalize(void* obj) { + FinalizerTraitImpl<Deque<T, inlineCapacity, HeapAllocator>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +template <typename Table> +struct FinalizerTrait<HeapHashTableBacking<Table>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = + !WTF::IsTriviallyDestructible<typename Table::ValueType>::value; + static void Finalize(void* obj) { + FinalizerTraitImpl<HeapHashTableBacking<Table>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +template <typename T, typename Traits> +struct FinalizerTrait<HeapVectorBacking<T, Traits>> { + STATIC_ONLY(FinalizerTrait); + static const bool kNonTrivialFinalizer = Traits::kNeedsDestruction; + static void Finalize(void* obj) { + FinalizerTraitImpl<HeapVectorBacking<T, Traits>, + kNonTrivialFinalizer>::Finalize(obj); + } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_FINALIZER_TRAITS_H_ diff --git a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h index cac0ef4cea7..d7f66a87004 100644 --- a/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h +++ b/chromium/third_party/blink/renderer/platform/heap/garbage_collected.h @@ -58,8 +58,6 @@ struct TraceWrapperDescriptor { STACK_ALLOCATED(); void* base_object_payload; TraceWrappersCallback trace_wrappers_callback; - MissedWriteBarrierCallback missed_write_barrier_callback; - NameCallback name_callback; }; // The GarbageCollectedMixin interface and helper macro @@ -115,7 +113,7 @@ class PLATFORM_EXPORT GarbageCollectedMixin { return {BlinkGC::kNotFullyConstructedObject, nullptr, false}; } virtual TraceWrapperDescriptor GetTraceWrapperDescriptor() const { - return {BlinkGC::kNotFullyConstructedObject, nullptr, nullptr, nullptr}; + return {BlinkGC::kNotFullyConstructedObject, nullptr}; } }; @@ -136,9 +134,7 @@ class PLATFORM_EXPORT GarbageCollectedMixin { \ TraceWrapperDescriptor GetTraceWrapperDescriptor() const override { \ return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \ - TraceTrait<TYPE>::TraceWrappers, \ - ScriptWrappableVisitor::MissedWriteBarrier<TYPE>, \ - ScriptWrappableVisitor::NameCallback<TYPE>}; \ + TraceTrait<TYPE>::TraceWrappers}; \ } \ \ private: diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc b/chromium/third_party/blink/renderer/platform/heap/gc_info.cc index 10573e6dcde..1033c658f78 100644 --- a/chromium/third_party/blink/renderer/platform/heap/gc_info.cc +++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.cc @@ -4,25 +4,59 @@ #include "third_party/blink/renderer/platform/heap/gc_info.h" -#include "third_party/blink/renderer/platform/heap/handle.h" +#include "base/bits.h" #include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" namespace blink { -// GCInfo indices start from 1 for heap objects, with 0 being treated -// specially as the index for freelist entries and large heap objects. -size_t GCInfoTable::gc_info_index_ = 0; +namespace { -size_t GCInfoTable::gc_info_table_size_ = 0; -GCInfo const** g_gc_info_table = nullptr; +constexpr size_t kEntrySize = sizeof(GCInfo*); + +// Allocation and resizing are built around the following invariants. +static_assert(base::bits::IsPowerOfTwo(kEntrySize), + "GCInfoTable entries size must be power of " + "two"); +static_assert( + 0 == base::kPageAllocationGranularity % base::kSystemPageSize, + "System page size must be a multiple of page page allocation granularity"); + +constexpr size_t ComputeInitialTableLimit() { + // (Light) experimentation suggests that Blink doesn't need more than this + // while handling content on popular web properties. + constexpr size_t kInitialWantedLimit = 512; + + // Different OSes have different page sizes, so we have to choose the minimum + // of memory wanted and OS page size. + constexpr size_t memory_wanted = kInitialWantedLimit * kEntrySize; + return base::RoundUpToPageAllocationGranularity(memory_wanted) / kEntrySize; +} + +constexpr size_t MaxTableSize() { + constexpr size_t kMaxTableSize = base::RoundUpToPageAllocationGranularity( + GCInfoTable::kMaxIndex * kEntrySize); + return kMaxTableSize; +} + +} // namespace + +GCInfoTable* GCInfoTable::global_table_ = nullptr; + +void GCInfoTable::CreateGlobalTable() { + DEFINE_STATIC_LOCAL(GCInfoTable, table, ()); + global_table_ = &table; +} void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info, size_t* gc_info_index_slot) { DCHECK(gc_info); DCHECK(gc_info_index_slot); - // Keep a global GCInfoTable lock while allocating a new slot. - DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, mutex, ()); - MutexLocker locker(mutex); + + // Ensuring a new index involves current index adjustment as well + // as potentially resizing the table, both operations that require + // a lock. + MutexLocker locker(table_mutex_); // If more than one thread ends up allocating a slot for // the same GCInfo, have later threads reuse the slot @@ -30,37 +64,55 @@ void GCInfoTable::EnsureGCInfoIndex(const GCInfo* gc_info, if (*gc_info_index_slot) return; - int index = ++gc_info_index_; + int index = ++current_index_; size_t gc_info_index = static_cast<size_t>(index); CHECK(gc_info_index < GCInfoTable::kMaxIndex); - if (gc_info_index >= gc_info_table_size_) + if (current_index_ >= limit_) Resize(); - g_gc_info_table[gc_info_index] = gc_info; + table_[gc_info_index] = gc_info; ReleaseStore(reinterpret_cast<int*>(gc_info_index_slot), index); } void GCInfoTable::Resize() { - static const int kGcInfoZapValue = 0x33; - // (Light) experimentation suggests that Blink doesn't need - // more than this while handling content on popular web properties. - const size_t kInitialSize = 512; - - size_t new_size = - gc_info_table_size_ ? 2 * gc_info_table_size_ : kInitialSize; - DCHECK(new_size < GCInfoTable::kMaxIndex); - g_gc_info_table = - reinterpret_cast<GCInfo const**>(WTF::Partitions::FastRealloc( - g_gc_info_table, new_size * sizeof(GCInfo), "GCInfo")); - DCHECK(g_gc_info_table); - memset(reinterpret_cast<uint8_t*>(g_gc_info_table) + - gc_info_table_size_ * sizeof(GCInfo), - kGcInfoZapValue, (new_size - gc_info_table_size_) * sizeof(GCInfo)); - gc_info_table_size_ = new_size; + const size_t new_limit = (limit_) ? 2 * limit_ : ComputeInitialTableLimit(); + const size_t old_committed_size = limit_ * kEntrySize; + const size_t new_committed_size = new_limit * kEntrySize; + CHECK(table_); + CHECK_EQ(0u, new_committed_size % base::kPageAllocationGranularity); + CHECK_GE(MaxTableSize(), limit_ * kEntrySize); + + // Recommitting and zapping assumes byte-addressable storage. + uint8_t* const current_table_end = + reinterpret_cast<uint8_t*>(table_) + old_committed_size; + const size_t table_size_delta = new_committed_size - old_committed_size; + + // Commit the new size and allow read/write. + // TODO(ajwong): SetSystemPagesAccess should be part of RecommitSystemPages to + // avoid having two calls here. + bool ok = base::SetSystemPagesAccess(current_table_end, table_size_delta, + base::PageReadWrite); + CHECK(ok); + ok = base::RecommitSystemPages(current_table_end, table_size_delta, + base::PageReadWrite); + CHECK(ok); + +#if DCHECK_IS_ON() + // Check that newly-committed memory is zero-initialized. + for (size_t i = 0; i < (table_size_delta / sizeof(uintptr_t)); ++i) { + DCHECK(!reinterpret_cast<uintptr_t*>(current_table_end)[i]); + } +#endif // DCHECK_IS_ON() + + limit_ = new_limit; } -void GCInfoTable::Init() { - CHECK(!g_gc_info_table); +GCInfoTable::GCInfoTable() { + CHECK(!table_); + table_ = reinterpret_cast<GCInfo const**>(base::AllocPages( + nullptr, MaxTableSize(), base::kPageAllocationGranularity, + base::PageInaccessible)); + CHECK(table_); Resize(); } 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 adbbf23d6c7..c3290ff97e2 100644 --- a/chromium/third_party/blink/renderer/platform/heap/gc_info.h +++ b/chromium/third_party/blink/renderer/platform/heap/gc_info.h @@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GC_INFO_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_GC_INFO_H_ +#include "third_party/blink/renderer/platform/heap/finalizer_traits.h" +#include "third_party/blink/renderer/platform/heap/name_traits.h" #include "third_party/blink/renderer/platform/heap/visitor.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -21,119 +23,6 @@ namespace blink { -// The FinalizerTraitImpl specifies how to finalize objects. Objects that -// inherit from GarbageCollectedFinalized are finalized by calling their -// |Finalize| method which by default will call the destructor on the object. -template <typename T, bool isGarbageCollectedFinalized> -struct FinalizerTraitImpl; - -template <typename T> -struct FinalizerTraitImpl<T, true> { - STATIC_ONLY(FinalizerTraitImpl); - static void Finalize(void* obj) { - static_assert(sizeof(T), "T must be fully defined"); - static_cast<T*>(obj)->FinalizeGarbageCollectedObject(); - }; -}; - -template <typename T> -struct FinalizerTraitImpl<T, false> { - STATIC_ONLY(FinalizerTraitImpl); - static void Finalize(void* obj) { - static_assert(sizeof(T), "T must be fully defined"); - }; -}; - -// The FinalizerTrait is used to determine if a type requires finalization and -// what finalization means. -// -// By default classes that inherit from GarbageCollectedFinalized need -// finalization and finalization means calling the |Finalize| method of the -// object. The FinalizerTrait can be specialized if the default behavior is not -// desired. -template <typename T> -struct FinalizerTrait { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = - WTF::IsSubclassOfTemplate<typename std::remove_const<T>::type, - GarbageCollectedFinalized>::value; - static void Finalize(void* obj) { - FinalizerTraitImpl<T, kNonTrivialFinalizer>::Finalize(obj); - } -}; - -class HeapAllocator; -template <typename ValueArg, size_t inlineCapacity> -class HeapListHashSetAllocator; -template <typename T, typename Traits> -class HeapVectorBacking; -template <typename Table> -class HeapHashTableBacking; - -template <typename T, typename U, typename V> -struct FinalizerTrait<LinkedHashSet<T, U, V, HeapAllocator>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = true; - static void Finalize(void* obj) { - FinalizerTraitImpl<LinkedHashSet<T, U, V, HeapAllocator>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - -template <typename T, typename Allocator> -struct FinalizerTrait<WTF::ListHashSetNode<T, Allocator>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = - !WTF::IsTriviallyDestructible<T>::value; - static void Finalize(void* obj) { - FinalizerTraitImpl<WTF::ListHashSetNode<T, Allocator>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - -template <typename T, size_t inlineCapacity> -struct FinalizerTrait<Vector<T, inlineCapacity, HeapAllocator>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = - inlineCapacity && VectorTraits<T>::kNeedsDestruction; - static void Finalize(void* obj) { - FinalizerTraitImpl<Vector<T, inlineCapacity, HeapAllocator>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - -template <typename T, size_t inlineCapacity> -struct FinalizerTrait<Deque<T, inlineCapacity, HeapAllocator>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = - inlineCapacity && VectorTraits<T>::kNeedsDestruction; - static void Finalize(void* obj) { - FinalizerTraitImpl<Deque<T, inlineCapacity, HeapAllocator>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - -template <typename Table> -struct FinalizerTrait<HeapHashTableBacking<Table>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = - !WTF::IsTriviallyDestructible<typename Table::ValueType>::value; - static void Finalize(void* obj) { - FinalizerTraitImpl<HeapHashTableBacking<Table>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - -template <typename T, typename Traits> -struct FinalizerTrait<HeapVectorBacking<T, Traits>> { - STATIC_ONLY(FinalizerTrait); - static const bool kNonTrivialFinalizer = Traits::kNeedsDestruction; - static void Finalize(void* obj) { - FinalizerTraitImpl<HeapVectorBacking<T, Traits>, - kNonTrivialFinalizer>::Finalize(obj); - } -}; - // GCInfo contains meta-data associated with object classes allocated in the // Blink heap. This meta-data consists of a function pointer used to trace the // pointers in the class instance during garbage collection, an indication of @@ -145,44 +34,72 @@ struct FinalizerTrait<HeapVectorBacking<T, Traits>> { struct GCInfo { bool HasFinalizer() const { return non_trivial_finalizer_; } bool HasVTable() const { return has_v_table_; } + TraceCallback trace_; FinalizationCallback finalize_; + NameCallback name_; bool non_trivial_finalizer_; bool has_v_table_; }; -// s_gcInfoTable holds the per-class GCInfo descriptors; each HeapObjectHeader -// keeps an index into this table. -extern PLATFORM_EXPORT GCInfo const** g_gc_info_table; - #if DCHECK_IS_ON() PLATFORM_EXPORT void AssertObjectHasGCInfo(const void*, size_t gc_info_index); #endif -class GCInfoTable { - STATIC_ONLY(GCInfoTable); - +class PLATFORM_EXPORT GCInfoTable { public: - PLATFORM_EXPORT static void EnsureGCInfoIndex(const GCInfo*, size_t*); - - static void Init(); - - static size_t GcInfoIndex() { return gc_info_index_; } - - // The (max + 1) GCInfo index supported. + // At maximum |kMaxIndex - 1| indices are supported. // // We assume that 14 bits is enough to represent all possible types: during // telemetry runs, we see about 1,000 different types; looking at the output // of the Oilpan GC Clang plugin, there appear to be at most about 6,000 // types. Thus 14 bits should be more than twice as many bits as we will ever // need. - static const size_t kMaxIndex = 1 << 14; + static constexpr size_t kMaxIndex = 1 << 14; + + // Sets up a singleton table that can be acquired using Get(). + static void CreateGlobalTable(); + + static GCInfoTable& Get() { return *global_table_; } + + inline const GCInfo* GCInfoFromIndex(size_t index) { + DCHECK_GE(index, 1u); + DCHECK(index < kMaxIndex); + DCHECK(table_); + const GCInfo* info = table_[index]; + DCHECK(info); + return info; + } + + void EnsureGCInfoIndex(const GCInfo*, size_t*); + + size_t GcInfoIndex() { return current_index_; } private: - static void Resize(); + FRIEND_TEST_ALL_PREFIXES(GCInfoTest, InitialEmpty); + FRIEND_TEST_ALL_PREFIXES(GCInfoTest, ResizeToMaxIndex); + + // Use GCInfoTable::Get() for retrieving the global table outside of testing + // code. + GCInfoTable(); + + void Resize(); - static size_t gc_info_index_; - static size_t gc_info_table_size_; + // Singleton for each process. Retrieved through Get(). + static GCInfoTable* global_table_; + + // Holds the per-class GCInfo descriptors; each HeapObjectHeader keeps an + // index into this table. + const GCInfo** table_ = nullptr; + + // GCInfo indices start from 1 for heap objects, with 0 being treated + // specially as the index for freelist entries and large heap objects. + size_t current_index_ = 0; + + // The limit (exclusive) of the currently allocated table. + size_t limit_ = 0; + + Mutex table_mutex_; }; // GCInfoAtBaseType should be used when returning a unique 14 bit integer @@ -193,14 +110,13 @@ struct GCInfoAtBaseType { static size_t Index() { static_assert(sizeof(T), "T must be fully defined"); static const GCInfo kGcInfo = { - TraceTrait<T>::Trace, FinalizerTrait<T>::Finalize, - FinalizerTrait<T>::kNonTrivialFinalizer, std::is_polymorphic<T>::value, + TraceTrait<T>::Trace, FinalizerTrait<T>::Finalize, + NameTrait<T>::GetName, FinalizerTrait<T>::kNonTrivialFinalizer, + std::is_polymorphic<T>::value, }; - static size_t gc_info_index = 0; - DCHECK(g_gc_info_table); if (!AcquireLoad(&gc_info_index)) - GCInfoTable::EnsureGCInfoIndex(&kGcInfo, &gc_info_index); + GCInfoTable::Get().EnsureGCInfoIndex(&kGcInfo, &gc_info_index); DCHECK_GE(gc_info_index, 1u); DCHECK(gc_info_index < GCInfoTable::kMaxIndex); return gc_info_index; @@ -243,6 +159,8 @@ template <typename T, typename U, typename V> class HeapLinkedHashSet; template <typename T, size_t inlineCapacity, typename U> class HeapListHashSet; +template <typename ValueArg, size_t inlineCapacity> +class HeapListHashSetAllocator; template <typename T, size_t inlineCapacity> class HeapVector; template <typename T, size_t inlineCapacity> diff --git a/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc b/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc new file mode 100644 index 00000000000..d651be09c53 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/gc_info_test.cc @@ -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. + +#include "third_party/blink/renderer/platform/heap/gc_info.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +TEST(GCInfoTest, InitialEmpty) { + GCInfoTable table; + EXPECT_EQ(0u, table.GcInfoIndex()); +} + +TEST(GCInfoTest, ResizeToMaxIndex) { + GCInfoTable table; + GCInfo info = {nullptr, nullptr, nullptr, false, false}; + size_t slot = 0; + for (size_t i = 0; i < (GCInfoTable::kMaxIndex - 1); i++) { + slot = 0; + table.EnsureGCInfoIndex(&info, &slot); + EXPECT_LT(0u, slot); + EXPECT_EQ(&info, table.GCInfoFromIndex(slot)); + } +} + +} // namespace blink 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 b8d92cbc1a8..f825c13fc37 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 @@ -45,15 +45,15 @@ class GCTaskObserver final : public WebThread::TaskObserver { public: GCTaskObserver() : nesting_(0) {} - ~GCTaskObserver() { + ~GCTaskObserver() override { // m_nesting can be 1 if this was unregistered in a task and // didProcessTask was not called. DCHECK(!nesting_ || nesting_ == 1); } - virtual void WillProcessTask() { nesting_++; } + void WillProcessTask() override { nesting_++; } - virtual void DidProcessTask() { + void DidProcessTask() override { // In the production code WebKit::initialize is called from inside the // message loop so we can get didProcessTask() without corresponding // willProcessTask once. This is benign. diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.cc b/chromium/third_party/blink/renderer/platform/heap/heap.cc index f4509a7e93b..f71f7abc09a 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap.cc +++ b/chromium/third_party/blink/renderer/platform/heap/heap.cc @@ -37,8 +37,10 @@ #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_visitor.h" #include "third_party/blink/renderer/platform/heap/page_memory.h" #include "third_party/blink/renderer/platform/heap/page_pool.h" @@ -58,10 +60,6 @@ namespace blink { HeapAllocHooks::AllocationHook* HeapAllocHooks::allocation_hook_ = nullptr; HeapAllocHooks::FreeHook* HeapAllocHooks::free_hook_ = nullptr; -void ThreadHeap::FlushHeapDoesNotContainCache() { - heap_does_not_contain_cache_->Flush(); -} - ThreadHeapStats::ThreadHeapStats() : allocated_space_(0), allocated_object_size_(0), @@ -131,15 +129,15 @@ double ThreadHeapStats::LiveObjectRateSinceLastGC() const { ThreadHeap::ThreadHeap(ThreadState* thread_state) : thread_state_(thread_state), + heap_stats_collector_(std::make_unique<ThreadHeapStatsCollector>()), region_tree_(std::make_unique<RegionTree>()), - heap_does_not_contain_cache_(std::make_unique<HeapDoesNotContainCache>()), + address_cache_(std::make_unique<AddressCache>()), free_page_pool_(std::make_unique<PagePool>()), marking_worklist_(nullptr), not_fully_constructed_worklist_(nullptr), weak_callback_worklist_(nullptr), vector_backing_arena_index_(BlinkGC::kVector1ArenaIndex), - current_arena_ages_(0), - should_flush_heap_does_not_contain_cache_(false) { + current_arena_ages_(0) { if (ThreadState::Current()->IsMainThread()) main_thread_heap_ = this; @@ -164,7 +162,7 @@ Address ThreadHeap::CheckAndMarkPointer(MarkingVisitor* visitor, DCHECK(thread_state_->InAtomicMarkingPause()); #if !DCHECK_IS_ON() - if (heap_does_not_contain_cache_->Lookup(address)) + if (address_cache_->Lookup(address)) return nullptr; #endif @@ -172,17 +170,17 @@ Address ThreadHeap::CheckAndMarkPointer(MarkingVisitor* visitor, #if DCHECK_IS_ON() DCHECK(page->Contains(address)); #endif - DCHECK(!heap_does_not_contain_cache_->Lookup(address)); + DCHECK(!address_cache_->Lookup(address)); DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap()); visitor->ConservativelyMarkAddress(page, address); return address; } #if !DCHECK_IS_ON() - heap_does_not_contain_cache_->AddEntry(address); + address_cache_->AddEntry(address); #else - if (!heap_does_not_contain_cache_->Lookup(address)) - heap_does_not_contain_cache_->AddEntry(address); + if (!address_cache_->Lookup(address)) + address_cache_->AddEntry(address); #endif return nullptr; } @@ -199,13 +197,13 @@ Address ThreadHeap::CheckAndMarkPointer( if (BasePage* page = LookupPageForAddress(address)) { DCHECK(page->Contains(address)); - DCHECK(!heap_does_not_contain_cache_->Lookup(address)); + DCHECK(!address_cache_->Lookup(address)); DCHECK(&visitor->Heap() == &page->Arena()->GetThreadState()->Heap()); visitor->ConservativelyMarkAddress(page, address, callback); return address; } - if (!heap_does_not_contain_cache_->Lookup(address)) - heap_does_not_contain_cache_->AddEntry(address); + if (!address_cache_->Lookup(address)) + address_cache_->AddEntry(address); return nullptr; } #endif // DCHECK_IS_ON() @@ -449,26 +447,6 @@ size_t ThreadHeap::ObjectPayloadSizeForTesting() { return object_payload_size; } -void ThreadHeap::ShouldFlushHeapDoesNotContainCache() { - should_flush_heap_does_not_contain_cache_ = true; -} - -void ThreadHeap::FlushHeapDoesNotContainCacheIfNeeded() { - if (should_flush_heap_does_not_contain_cache_) { - FlushHeapDoesNotContainCache(); - should_flush_heap_does_not_contain_cache_ = false; - } -} - -bool ThreadHeap::IsAddressInHeapDoesNotContainCache(Address address) { - // If the cache has been marked as invalidated, it's cleared prior - // to performing the next GC. Hence, consider the cache as being - // effectively empty. - if (should_flush_heap_does_not_contain_cache_) - return false; - return heap_does_not_contain_cache_->Lookup(address); -} - void ThreadHeap::VisitPersistentRoots(Visitor* visitor) { DCHECK(thread_state_->InAtomicMarkingPause()); TRACE_EVENT0("blink_gc", "ThreadHeap::visitPersistentRoots"); @@ -478,7 +456,10 @@ void ThreadHeap::VisitPersistentRoots(Visitor* visitor) { void ThreadHeap::VisitStackRoots(MarkingVisitor* visitor) { DCHECK(thread_state_->InAtomicMarkingPause()); TRACE_EVENT0("blink_gc", "ThreadHeap::visitStackRoots"); + address_cache_->FlushIfDirty(); + address_cache_->EnableLookup(); thread_state_->VisitStack(visitor); + address_cache_->DisableLookup(); } BasePage* ThreadHeap::LookupPageForAddress(Address address) { @@ -646,7 +627,7 @@ void ThreadHeap::TakeSnapshot(SnapshotType type) { // 0 is used as index for freelist entries. Objects are indexed 1 to // gcInfoIndex. - ThreadState::GCSnapshotInfo info(GCInfoTable::GcInfoIndex() + 1); + ThreadState::GCSnapshotInfo info(GCInfoTable::Get().GcInfoIndex() + 1); String thread_dump_name = String::Format("blink_gc/thread_%lu", static_cast<unsigned long>(thread_state_->ThreadId())); @@ -696,8 +677,8 @@ void ThreadHeap::TakeSnapshot(SnapshotType type) { size_t total_dead_count = 0; size_t total_live_size = 0; size_t total_dead_size = 0; - for (size_t gc_info_index = 1; gc_info_index <= GCInfoTable::GcInfoIndex(); - ++gc_info_index) { + for (size_t gc_info_index = 1; + gc_info_index <= GCInfoTable::Get().GcInfoIndex(); ++gc_info_index) { total_live_count += info.live_count[gc_info_index]; total_dead_count += info.dead_count[gc_info_index]; total_live_size += info.live_size[gc_info_index]; @@ -757,7 +738,8 @@ void ThreadHeap::WriteBarrier(void* value) { header->Mark(); marking_worklist_->Push( WorklistTaskId::MainThread, - {header->Payload(), ThreadHeap::GcInfo(header->GcInfoIndex())->trace_}); + {header->Payload(), + GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex())->trace_}); } ThreadHeap* ThreadHeap::main_thread_heap_ = nullptr; diff --git a/chromium/third_party/blink/renderer/platform/heap/heap.h b/chromium/third_party/blink/renderer/platform/heap/heap.h index f18a6f951be..f4d3bfc9aef 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap.h +++ b/chromium/third_party/blink/renderer/platform/heap/heap.h @@ -55,6 +55,8 @@ namespace incremental_marking_test { class IncrementalMarkingScopeBase; } // namespace incremental_marking_test +class AddressCache; +class ThreadHeapStatsCollector; class PagePool; class RegionTree; @@ -358,10 +360,7 @@ class PLATFORM_EXPORT ThreadHeap { size_t ObjectPayloadSizeForTesting(); - void FlushHeapDoesNotContainCache(); - bool IsAddressInHeapDoesNotContainCache(Address); - void FlushHeapDoesNotContainCacheIfNeeded(); - void ShouldFlushHeapDoesNotContainCache(); + AddressCache* address_cache() { return address_cache_.get(); } PagePool* GetFreePagePool() { return free_page_pool_.get(); } @@ -370,15 +369,6 @@ class PLATFORM_EXPORT ThreadHeap { // heap-page if one exists. BasePage* LookupPageForAddress(Address); - static const GCInfo* GcInfo(size_t gc_info_index) { - DCHECK_GE(gc_info_index, 1u); - DCHECK(gc_info_index < GCInfoTable::kMaxIndex); - DCHECK(g_gc_info_table); - const GCInfo* info = g_gc_info_table[gc_info_index]; - DCHECK(info); - return info; - } - static void ReportMemoryUsageHistogram(); static void ReportMemoryUsageForTracing(); @@ -465,6 +455,10 @@ class PLATFORM_EXPORT ThreadHeap { enum SnapshotType { kHeapSnapshot, kFreelistSnapshot }; void TakeSnapshot(SnapshotType); + ThreadHeapStatsCollector* stats_collector() const { + return heap_stats_collector_.get(); + } + #if defined(ADDRESS_SANITIZER) void PoisonEagerArena(); void PoisonAllHeaps(); @@ -498,8 +492,9 @@ class PLATFORM_EXPORT ThreadHeap { ThreadState* thread_state_; ThreadHeapStats stats_; + std::unique_ptr<ThreadHeapStatsCollector> heap_stats_collector_; std::unique_ptr<RegionTree> region_tree_; - std::unique_ptr<HeapDoesNotContainCache> heap_does_not_contain_cache_; + std::unique_ptr<AddressCache> address_cache_; std::unique_ptr<PagePool> free_page_pool_; std::unique_ptr<MarkingWorklist> marking_worklist_; std::unique_ptr<NotFullyConstructedWorklist> not_fully_constructed_worklist_; @@ -515,7 +510,6 @@ class PLATFORM_EXPORT ThreadHeap { int vector_backing_arena_index_; size_t arena_ages_[BlinkGC::kNumberOfArenas]; size_t current_arena_ages_; - bool should_flush_heap_does_not_contain_cache_; // 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 @@ -716,7 +710,9 @@ Address ThreadHeap::Reallocate(void* previous, size_t size) { size_t gc_info_index = GCInfoTrait<T>::Index(); // TODO(haraken): We don't support reallocate() for finalizable objects. - DCHECK(!ThreadHeap::GcInfo(previous_header->GcInfoIndex())->HasFinalizer()); + DCHECK(!GCInfoTable::Get() + .GCInfoFromIndex(previous_header->GcInfoIndex()) + ->HasFinalizer()); DCHECK_EQ(previous_header->GcInfoIndex(), gc_info_index); HeapAllocHooks::FreeHookIfEnabled(static_cast<Address>(previous)); Address address; 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 58e6656ed96..814264b9de3 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h +++ b/chromium/third_party/blink/renderer/platform/heap/heap_allocator.h @@ -128,6 +128,10 @@ class PLATFORM_EXPORT HeapAllocator { static void FreeHashTableBacking(void* address, bool is_weak_table); static bool ExpandHashTableBacking(void*, size_t); + static void TraceMarkedBackingStore(void* address) { + MarkingVisitor::TraceMarkedBackingStore(address); + } + static void BackingWriteBarrier(void* address) { MarkingVisitor::WriteBarrier(address); } 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 b73e8281dcb..27ef4c5e141 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap_page.cc +++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.cc @@ -30,11 +30,14 @@ #include "third_party/blink/renderer/platform/heap/heap_page.h" +#include "base/auto_reset.h" #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_memory.h" #include "third_party/blink/renderer/platform/heap/page_pool.h" @@ -47,7 +50,6 @@ #include "third_party/blink/renderer/platform/memory_coordinator.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/container_annotations.h" #include "third_party/blink/renderer/platform/wtf/leak_annotations.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -96,7 +98,7 @@ void HeapObjectHeader::ZapMagic() { void HeapObjectHeader::Finalize(Address object, size_t object_size) { HeapAllocHooks::FreeHookIfEnabled(object); - const GCInfo* gc_info = ThreadHeap::GcInfo(GcInfoIndex()); + const GCInfo* gc_info = GCInfoTable::Get().GCInfoFromIndex(GcInfoIndex()); if (gc_info->HasFinalizer()) gc_info->finalize_(object); @@ -264,16 +266,16 @@ Address BaseArena::LazySweep(size_t allocation_size, size_t gc_info_index) { if (GetThreadState()->SweepForbidden()) return nullptr; - TRACE_EVENT0("blink_gc", "BaseArena::lazySweepPages"); - ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState()); - ScriptForbiddenScope script_forbidden; - - double start_time = WTF::CurrentTimeTicksInMilliseconds(); - Address result = LazySweepPages(allocation_size, gc_info_index); - GetThreadState()->AccumulateSweepingTime( - WTF::CurrentTimeTicksInMilliseconds() - start_time); + Address result = nullptr; + { + ThreadHeapStatsCollector::Scope stats_scope( + GetThreadState()->Heap().stats_collector(), + ThreadHeapStatsCollector::kLazySweepOnAllocation); + ThreadState::SweepForbiddenScope sweep_forbidden(GetThreadState()); + ScriptForbiddenScope script_forbidden; + result = LazySweepPages(allocation_size, gc_info_index); + } ThreadHeap::ReportMemoryUsageForTracing(); - return result; } @@ -659,7 +661,7 @@ void NormalPageArena::TakeFreelistSnapshot(const String& dump_name) { } void NormalPageArena::AllocatePage() { - GetThreadState()->Heap().ShouldFlushHeapDoesNotContainCache(); + GetThreadState()->Heap().address_cache()->MarkDirty(); PageMemory* page_memory = GetThreadState()->Heap().GetFreePagePool()->Take(ArenaIndex()); @@ -833,7 +835,7 @@ bool NormalPageArena::ShrinkObject(HeapObjectHeader* header, size_t new_size) { Address NormalPageArena::LazySweepPages(size_t allocation_size, size_t gc_info_index) { DCHECK(!HasCurrentAllocationArea()); - AutoReset<bool> is_lazy_sweeping(&is_lazy_sweeping_, true); + base::AutoReset<bool> is_lazy_sweeping(&is_lazy_sweeping_, true); Address result = nullptr; while (!SweepingCompleted()) { BasePage* page = first_unswept_page_; @@ -1014,7 +1016,7 @@ Address LargeObjectArena::DoAllocateLargeObjectPage(size_t allocation_size, large_object_size += kAllocationGranularity; #endif - GetThreadState()->Heap().ShouldFlushHeapDoesNotContainCache(); + GetThreadState()->Heap().address_cache()->MarkDirty(); PageMemory* page_memory = PageMemory::Allocate( large_object_size, GetThreadState()->Heap().GetRegionTree()); Address large_object_address = page_memory->WritableStart(); @@ -1775,44 +1777,4 @@ bool LargeObjectPage::Contains(Address object) { } #endif -void HeapDoesNotContainCache::Flush() { - if (has_entries_) { - for (size_t i = 0; i < kNumberOfEntries; ++i) - entries_[i] = nullptr; - has_entries_ = false; - } -} - -size_t HeapDoesNotContainCache::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 HeapDoesNotContainCache::Lookup(Address address) { - DCHECK(ThreadState::Current()->InAtomicMarkingPause()); - - 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 HeapDoesNotContainCache::AddEntry(Address address) { - DCHECK(ThreadState::Current()->InAtomicMarkingPause()); - - 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/heap_page.h b/chromium/third_party/blink/renderer/platform/heap/heap_page.h index 60f367ef845..f9e45bc4d7c 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap_page.h +++ b/chromium/third_party/blink/renderer/platform/heap/heap_page.h @@ -492,7 +492,7 @@ class PLATFORM_EXPORT ObjectStartBitmap { class PLATFORM_EXPORT NormalPage final : public BasePage { public: NormalPage(PageMemory*, BaseArena*); - ~NormalPage(); + ~NormalPage() override; Address Payload() { return GetAddress() + PageHeaderSize(); } size_t PayloadSize() { @@ -613,7 +613,7 @@ class LargeObjectPage final : public BasePage { // negative page cache. bool Contains(Address) override; #endif - virtual size_t size() { + size_t size() override { return PageHeaderSize() + sizeof(HeapObjectHeader) + payload_size_; } static size_t PageHeaderSize() { @@ -646,54 +646,6 @@ class LargeObjectPage final : public BasePage { #endif }; -// |HeapDoesNotContainCache| provides a fast way to determine whether an -// aribtrary pointer-sized word can be interpreted as a pointer to an area that -// is managed by the garbage collected Blink heap. This is a cache of 'pages' -// that have previously been determined to be wholly outside of the heap. The -// size of these pages must be smaller than the allocation alignment of the heap -// pages. We determine off-heap-ness by rounding down the pointer to the nearest -// page and looking up the page in the cache. If there is a miss in the cache we -// can determine the status of the pointer precisely using the heap -// |RegionTree|. -// -// This is a negative cache, so it must be flushed when memory is added to the -// heap. -class HeapDoesNotContainCache { - USING_FAST_MALLOC(HeapDoesNotContainCache); - - public: - HeapDoesNotContainCache() : has_entries_(false) { - // Start by flushing the cache in a non-empty state to initialize all the - // cache entries. - for (size_t i = 0; i < kNumberOfEntries; ++i) - entries_[i] = nullptr; - } - - void Flush(); - bool IsEmpty() { return !has_entries_; } - - // Perform a lookup in the cache. - // - // If lookup returns false, the argument address was not found in the cache - // and it is unknown if the address is in the Blink heap. - // - // If lookup returns true, the argument address was found in the cache which - // means the address is not in the heap. - PLATFORM_EXPORT bool Lookup(Address); - - // Add an entry to the cache. - PLATFORM_EXPORT 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 has_entries_; -}; - class FreeList { DISALLOW_NEW(); @@ -996,35 +948,40 @@ inline uint32_t GetRandomMagic() { #pragma warning(disable : 4319) #endif - static const uintptr_t random1 = ~(RotateLeft16(reinterpret_cast<uintptr_t>( + // 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(reinterpret_cast<uintptr_t>( base::trace_event::MemoryAllocatorDump::kNameSize))); #if defined(OS_WIN) - static const uintptr_t random2 = - ~(RotateLeft16(reinterpret_cast<uintptr_t>(::ReadFile))); -#elif defined(OS_POSIX) - static const uintptr_t random2 = - ~(RotateLeft16(reinterpret_cast<uintptr_t>(::read))); + 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 OS not supported +#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"); - static const uint32_t random = static_cast<uint32_t>( - (random1 & 0x0FFFFULL) | ((random2 >> 32) & 0x0FFFF0000ULL)); + // 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"); - static const uint32_t random = - (random1 & 0x0FFFFUL) | (random2 & 0xFFFF0000UL); #else #error architecture not supported #endif + random2 = ~(RotateLeft16(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 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 new file mode 100644 index 00000000000..b55da843c98 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.cc @@ -0,0 +1,51 @@ +// 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/heap_stats_collector.h" + +#include "base/logging.h" + +namespace blink { + +void ThreadHeapStatsCollector::IncreaseMarkedObjectSize(size_t size) { + DCHECK(is_started_); + current_.marked_object_size += size; +} + +void ThreadHeapStatsCollector::Start(BlinkGC::GCReason reason) { + DCHECK(!is_started_); + is_started_ = true; + current_.reason = reason; +} + +void ThreadHeapStatsCollector::Stop() { + is_started_ = false; + previous_ = std::move(current_); + current_.reset(); +} + +void ThreadHeapStatsCollector::Event::reset() { + marked_object_size = 0; + memset(scope_data, 0, sizeof(scope_data)); + reason = BlinkGC::kTesting; +} + +double ThreadHeapStatsCollector::Event::marking_time_in_ms() const { + return scope_data[kIncrementalMarkingStartMarking] + + scope_data[kIncrementalMarkingStep] + + scope_data[kIncrementalMarkingFinalizeMarking] + + scope_data[kAtomicPhaseMarking]; +} + +double ThreadHeapStatsCollector::Event::marking_time_per_byte_in_s() const { + return marked_object_size ? marking_time_in_ms() / 1000 / marked_object_size + : 0.0; +} + +double ThreadHeapStatsCollector::Event::sweeping_time_in_ms() const { + return scope_data[kCompleteSweep] + scope_data[kEagerSweep] + + scope_data[kLazySweepInIdle] + scope_data[kLazySweepOnAllocation]; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h new file mode 100644 index 00000000000..c94e8d9e14d --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector.h @@ -0,0 +1,160 @@ +// 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_HEAP_STATS_COLLECTOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_ + +#include <stddef.h> + +#include "third_party/blink/renderer/platform/heap/blink_gc.h" +#include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/time.h" + +namespace blink { + +// Manages counters and statistics across garbage collection cycles. +// +// Usage: +// ThreadHeapStatsCollector stats_collector; +// stats_collector.Start(<BlinkGC::GCReason>); +// // Use tracer. +// // Current event is available using stats_collector.current(). +// stats_collector.Stop(); +// // Previous event is available using stats_collector.previous(). +class PLATFORM_EXPORT ThreadHeapStatsCollector { + public: + // These ids will form human readable names when used in Scopes. + enum Id { + kCompleteSweep, + kEagerSweep, + kIncrementalMarkingStartMarking, + kIncrementalMarkingStep, + kIncrementalMarkingFinalize, + kIncrementalMarkingFinalizeMarking, + kInvokePreFinalizers, + kLazySweepInIdle, + kLazySweepOnAllocation, + kAtomicPhaseMarking, + kVisitDOMWrappers, + kNumScopeIds, + }; + + static const char* ToString(Id id) { + switch (id) { + case Id::kAtomicPhaseMarking: + return "BlinkGC.AtomicPhaseMarking"; + case Id::kCompleteSweep: + return "BlinkGC.CompleteSweep"; + case Id::kEagerSweep: + return "BlinkGC.EagerSweep"; + case Id::kIncrementalMarkingStartMarking: + return "BlinkGC.IncrementalMarkingStartMarking"; + case Id::kIncrementalMarkingStep: + return "BlinkGC.IncrementalMarkingStep"; + case Id::kIncrementalMarkingFinalize: + return "BlinkGC.IncrementalMarkingFinalize"; + case Id::kIncrementalMarkingFinalizeMarking: + return "BlinkGC.IncrementalMarkingFinalizeMarking"; + case Id::kInvokePreFinalizers: + return "BlinkGC.InvokePreFinalizers"; + case Id::kLazySweepInIdle: + return "BlinkGC.LazySweepInIdle"; + case Id::kLazySweepOnAllocation: + return "BlinkGC.LazySweepOnAllocation"; + case Id::kVisitDOMWrappers: + return "BlinkGC.VisitDOMWrappers"; + case Id::kNumScopeIds: + break; + } + CHECK(false); + return nullptr; + } + + enum TraceDefaultBehavior { + kEnabled, + kDisabled, + }; + + // Trace a particular scope. Will emit a trace event and record the time in + // the corresponding ThreadHeapStatsCollector. + template <TraceDefaultBehavior default_behavior = kDisabled> + class PLATFORM_EXPORT InternalScope { + public: + template <typename... Args> + InternalScope(ThreadHeapStatsCollector* tracer, Id id, Args... args) + : tracer_(tracer), + start_time_(WTF::CurrentTimeTicksInMilliseconds()), + id_(id) { + StartTrace(args...); + } + + ~InternalScope() { + TRACE_EVENT_END0(TraceCategory(), ToString(id_)); + tracer_->IncreaseScopeTime( + id_, WTF::CurrentTimeTicksInMilliseconds() - start_time_); + } + + private: + static const char* TraceCategory() { + return default_behavior == kEnabled + ? "blink_gc" + : TRACE_DISABLED_BY_DEFAULT("blink_gc"); + } + + void StartTrace() { TRACE_EVENT_BEGIN0(TraceCategory(), ToString(id_)); } + + template <typename Value1> + void StartTrace(const char* k1, Value1 v1) { + TRACE_EVENT_BEGIN1(TraceCategory(), ToString(id_), k1, v1); + } + + template <typename Value1, typename Value2> + void StartTrace(const char* k1, Value1 v1, const char* k2, Value2 v2) { + TRACE_EVENT_BEGIN2(TraceCategory(), ToString(id_), k1, v1, k2, v2); + } + + ThreadHeapStatsCollector* const tracer_; + const double start_time_; + const Id id_; + }; + + using Scope = InternalScope<kDisabled>; + using EnabledScope = InternalScope<kEnabled>; + + struct PLATFORM_EXPORT Event { + void reset(); + + double marking_time_in_ms() const; + double marking_time_per_byte_in_s() const; + double sweeping_time_in_ms() const; + + size_t marked_object_size = 0; + double scope_data[kNumScopeIds] = {0}; + BlinkGC::GCReason reason; + }; + + void Start(BlinkGC::GCReason); + void Stop(); + + void IncreaseScopeTime(Id id, double time) { + DCHECK(is_started_); + current_.scope_data[id] += time; + } + + void IncreaseMarkedObjectSize(size_t); + + bool is_started() const { return is_started_; } + const Event& current() const { return current_; } + const Event& previous() const { return previous_; } + + private: + Event current_; + Event previous_; + bool is_started_ = false; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_HEAP_STATS_COLLECTOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc new file mode 100644 index 00000000000..b85a3fb3f6f --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/heap_stats_collector_test.cc @@ -0,0 +1,136 @@ +// 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/heap_stats_collector.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +// ============================================================================= +// ThreadHeapStatsCollector. =================================================== +// ============================================================================= + +TEST(ThreadHeapStatsCollectorTest, InitialEmpty) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + for (int i = 0; i < ThreadHeapStatsCollector::Id::kNumScopeIds; i++) { + EXPECT_DOUBLE_EQ(0.0, stats_collector.current().scope_data[i]); + } + stats_collector.Stop(); +} + +TEST(ThreadHeapStatsCollectorTest, IncreaseScopeTime) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingStep, 1.0); + EXPECT_DOUBLE_EQ( + 1.0, stats_collector.current() + .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); +} + +TEST(ThreadHeapStatsCollectorTest, StopMovesCurrentToPrevious) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingStep, 1.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ( + 1.0, stats_collector.previous() + .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); +} + +TEST(ThreadHeapStatsCollectorTest, StopResetsCurrent) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingStep, 1.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ( + 0.0, stats_collector.current() + .scope_data[ThreadHeapStatsCollector::kIncrementalMarkingStep]); +} + +TEST(ThreadHeapStatsCollectorTest, StartStop) { + ThreadHeapStatsCollector stats_collector; + EXPECT_FALSE(stats_collector.is_started()); + stats_collector.Start(BlinkGC::kTesting); + EXPECT_TRUE(stats_collector.is_started()); + stats_collector.Stop(); + EXPECT_FALSE(stats_collector.is_started()); +} + +TEST(ThreadHeapStatsCollectorTest, ScopeToString) { + EXPECT_STREQ("BlinkGC.IncrementalMarkingStartMarking", + ThreadHeapStatsCollector::ToString( + ThreadHeapStatsCollector::kIncrementalMarkingStartMarking)); +} + +// ============================================================================= +// ThreadHeapStatsCollector::Event. ============================================ +// ============================================================================= + +TEST(ThreadHeapStatsCollectorTest, EventMarkedObjectSize) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseMarkedObjectSize(1024); + stats_collector.Stop(); + EXPECT_EQ(1024u, stats_collector.previous().marked_object_size); +} + +TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeInMsFromIncrementalGC) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingStartMarking, 7.0); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingStep, 2.0); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingFinalizeMarking, 1.0); + // Ignore the full finalization. + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kIncrementalMarkingFinalize, 3.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ(10.0, stats_collector.previous().marking_time_in_ms()); +} + +TEST(ThreadHeapStatsCollectorTest, EventMarkingTimeInMsFromFullGC) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kAtomicPhaseMarking, 11.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ(11.0, stats_collector.previous().marking_time_in_ms()); +} + +TEST(ThreadHeapStatsCollectorTest, EventMarkingTimePerByteInS) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseMarkedObjectSize(1000); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kAtomicPhaseMarking, 1000.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ(.001, + stats_collector.previous().marking_time_per_byte_in_s()); +} + +TEST(ThreadHeapStatsCollectorTest, SweepingTimeInMs) { + ThreadHeapStatsCollector stats_collector; + stats_collector.Start(BlinkGC::kTesting); + stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, + 1.0); + stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, + 2.0); + stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kLazySweepInIdle, + 3.0); + stats_collector.IncreaseScopeTime( + ThreadHeapStatsCollector::kLazySweepOnAllocation, 4.0); + stats_collector.IncreaseScopeTime(ThreadHeapStatsCollector::kCompleteSweep, + 5.0); + stats_collector.Stop(); + EXPECT_DOUBLE_EQ(15.0, stats_collector.previous().sweeping_time_in_ms()); +} + +} // namespace blink 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 974efd871b6..dc938b32d50 100644 --- a/chromium/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/chromium/third_party/blink/renderer/platform/heap/heap_test.cc @@ -38,9 +38,11 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/cross_thread_functional.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" +#include "third_party/blink/renderer/platform/heap/heap_stats_collector.h" #include "third_party/blink/renderer/platform/heap/heap_terminated_array_builder.h" #include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" #include "third_party/blink/renderer/platform/heap/marking_visitor.h" @@ -364,6 +366,7 @@ class TestGCMarkingScope : public TestGCCollectGarbageScope { : TestGCCollectGarbageScope(state), atomic_pause_scope_(ThreadState::Current()), persistent_lock_(ProcessHeap::CrossThreadPersistentMutex()) { + ThreadState::Current()->Heap().stats_collector()->Start(BlinkGC::kTesting); ThreadState::Current()->MarkPhasePrologue(state, BlinkGC::kAtomicMarking, BlinkGC::kPreciseGC); } @@ -631,11 +634,9 @@ class ThreadedWeaknessTester : public ThreadedTesterBase { { Persistent<HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>> weak_map = new HeapHashMap<ThreadMarker, WeakMember<IntWrapper>>; - PersistentHeapHashMap<ThreadMarker, WeakMember<IntWrapper>> weak_map2; for (int i = 0; i < kNumberOfAllocations; i++) { weak_map->insert(static_cast<unsigned>(i), IntWrapper::Create(0)); - weak_map2.insert(static_cast<unsigned>(i), IntWrapper::Create(0)); test::YieldCurrentThread(); } @@ -652,7 +653,6 @@ class ThreadedWeaknessTester : public ThreadedTesterBase { // BlinkGC::TakeSnapshot, BlinkGC::ForcedGC); PreciselyCollectGarbage(); EXPECT_TRUE(weak_map->IsEmpty()); - EXPECT_TRUE(weak_map2.IsEmpty()); } test::YieldCurrentThread(); } @@ -866,7 +866,7 @@ class Foo : public Bar { static Foo* Create(Foo* foo) { return new Foo(foo); } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { if (points_to_foo_) visitor->Trace(static_cast<Foo*>(bar_)); else @@ -888,7 +888,7 @@ class Bars : public Bar { public: static Bars* Create() { return new Bars(); } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { for (unsigned i = 0; i < width_; i++) visitor->Trace(bars_[i]); } @@ -1036,7 +1036,7 @@ class Weak : public Bar { public: static Weak* Create(Bar* strong, Bar* weak) { return new Weak(strong, weak); } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(strong_bar_); visitor->template RegisterWeakMembers<Weak, &Weak::ZapWeakMembers>(this); } @@ -1065,7 +1065,7 @@ class WithWeakMember : public Bar { return new WithWeakMember(strong, weak); } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(strong_bar_); visitor->Trace(weak_bar_); } @@ -1162,7 +1162,7 @@ class PreFinalizerMixin : public GarbageCollectedMixin { public: ~PreFinalizerMixin() { was_destructed_ = true; } - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} void Dispose() { EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base); EXPECT_TRUE(g_dispose_was_called_for_pre_finalizer_sub_class); @@ -1182,8 +1182,8 @@ class PreFinalizerSubClass : public PreFinalizerBase, public PreFinalizerMixin { public: static PreFinalizerSubClass* Create() { return new PreFinalizerSubClass(); } - ~PreFinalizerSubClass() { was_destructed_ = true; } - virtual void Trace(blink::Visitor* visitor) {} + ~PreFinalizerSubClass() override { was_destructed_ = true; } + void Trace(blink::Visitor* visitor) override {} void Dispose() { EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_base); EXPECT_FALSE(g_dispose_was_called_for_pre_finalizer_sub_class); @@ -1352,7 +1352,7 @@ class SubClass : public SuperClass { ~SubClass() override { --alive_count_; } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(data_); SuperClass::Trace(visitor); } @@ -1373,7 +1373,7 @@ int SubClass::alive_count_ = 0; class Mixin : public GarbageCollectedMixin { public: - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} virtual char GetPayload(int i) { return padding_[i]; } @@ -1387,7 +1387,7 @@ class UseMixin : public SimpleObject, public Mixin { static UseMixin* Create() { return new UseMixin(); } static int trace_count_; - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { SimpleObject::Trace(visitor); Mixin::Trace(visitor); ++trace_count_; @@ -2367,9 +2367,21 @@ TEST(HeapTest, LargeHeapObjects) { PreciselyCollectGarbage(); } -TEST(HeapTest, LargeHashMap) { +// This test often fails on Android (https://crbug.com/843032). +// We run out of memory on Android devices because ReserveCapacityForSize +// actually allocates a much larger backing than specified (in this case 400MB). +#if defined(OS_ANDROID) +#define MAYBE_LargeHashMap DISABLED_LargeHashMap +#else +#define MAYBE_LargeHashMap LargeHashMap +#endif +TEST(HeapTest, MAYBE_LargeHashMap) { ClearOutOldGarbage(); - size_t size = (1 << 27) / sizeof(Member<IntWrapper>); + + // Try to allocate a HashTable larger than kMaxHeapObjectSize + // (crbug.com/597953). + size_t size = kMaxHeapObjectSize / + sizeof(HeapHashMap<int, Member<IntWrapper>>::ValueType); Persistent<HeapHashMap<int, Member<IntWrapper>>> map = new HeapHashMap<int, Member<IntWrapper>>(); map->ReserveCapacityForSize(size); @@ -2379,7 +2391,9 @@ TEST(HeapTest, LargeHashMap) { TEST(HeapTest, LargeVector) { ClearOutOldGarbage(); - size_t size = (1 << 27) / sizeof(int); + // Try to allocate a HeapVectors larger than kMaxHeapObjectSize + // (crbug.com/597953). + size_t size = kMaxHeapObjectSize / sizeof(int); Persistent<HeapVector<int>> vector = new HeapVector<int>(size); EXPECT_LE(size, vector->capacity()); } @@ -4010,7 +4024,8 @@ TEST(HeapTest, CheckAndMarkPointer) { TestGCScope scope(BlinkGC::kHeapPointersOnStack); MarkingVisitor visitor(ThreadState::Current(), MarkingVisitor::kGlobalMarking); - heap.FlushHeapDoesNotContainCache(); + heap.address_cache()->EnableLookup(); + heap.address_cache()->Flush(); for (size_t i = 0; i < object_addresses.size(); i++) { EXPECT_TRUE(heap.CheckAndMarkPointer(&visitor, object_addresses[i], ReportMarkedPointer)); @@ -4034,7 +4049,8 @@ TEST(HeapTest, CheckAndMarkPointer) { TestGCScope scope(BlinkGC::kHeapPointersOnStack); MarkingVisitor visitor(ThreadState::Current(), MarkingVisitor::kGlobalMarking); - heap.FlushHeapDoesNotContainCache(); + heap.address_cache()->EnableLookup(); + heap.address_cache()->Flush(); for (size_t i = 0; i < object_addresses.size(); i++) { // We would like to assert that checkAndMarkPointer returned false // here because the pointers no longer point into a valid object @@ -4721,7 +4737,7 @@ TEST(HeapTest, DestructorsCalled) { class MixinA : public GarbageCollectedMixin { public: MixinA() : obj_(IntWrapper::Create(100)) {} - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { trace_count_++; visitor->Trace(obj_); } @@ -4736,7 +4752,7 @@ int MixinA::trace_count_ = 0; class MixinB : public GarbageCollectedMixin { public: MixinB() : obj_(IntWrapper::Create(101)) {} - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(obj_); } + void Trace(blink::Visitor* visitor) override { visitor->Trace(obj_); } Member<IntWrapper> obj_; }; @@ -4747,7 +4763,7 @@ class MultipleMixins : public GarbageCollected<MultipleMixins>, public: MultipleMixins() : obj_(IntWrapper::Create(102)) {} - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(obj_); MixinA::Trace(visitor); MixinB::Trace(visitor); @@ -4759,7 +4775,7 @@ class DerivedMultipleMixins : public MultipleMixins { public: DerivedMultipleMixins() : obj_(IntWrapper::Create(103)) {} - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { trace_called_++; visitor->Trace(obj_); MultipleMixins::Trace(visitor); @@ -5772,7 +5788,7 @@ class ClassWithGarbageCollectingMixinConstructor : trace_counter_(TraceCounter::Create()), wrapper_(IntWrapper::Create(32)) {} - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { trace_called_++; visitor->Trace(trace_counter_); visitor->Trace(wrapper_); @@ -6338,7 +6354,7 @@ class TestMixinAllocationA : public GarbageCollected<TestMixinAllocationA>, DCHECK(ThreadState::Current()->IsGCForbidden()); } - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; class TestMixinAllocationB : public TestMixinAllocationA { @@ -6354,7 +6370,7 @@ class TestMixinAllocationB : public TestMixinAllocationA { DCHECK(ThreadState::Current()->IsGCForbidden()); } - void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(a_); TestMixinAllocationA::Trace(visitor); } @@ -6369,7 +6385,9 @@ class TestMixinAllocationC final : public TestMixinAllocationB { public: TestMixinAllocationC() { DCHECK(!ThreadState::Current()->IsGCForbidden()); } - void Trace(blink::Visitor* visitor) { TestMixinAllocationB::Trace(visitor); } + void Trace(blink::Visitor* visitor) override { + TestMixinAllocationB::Trace(visitor); + } }; TEST(HeapTest, NestedMixinConstruction) { @@ -6405,7 +6423,7 @@ class TestMixinAllocatingObject final return new TestMixinAllocatingObject(member); } - void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(trace_counter_); TestMixinAllocationB::Trace(visitor); } @@ -6602,11 +6620,11 @@ class ThreadedClearOnShutdownTester : public ThreadedTesterBase { class HeapObject; friend class HeapObject; - using WeakHeapObjectSet = PersistentHeapHashSet<WeakMember<HeapObject>>; + using WeakHeapObjectSet = HeapHashSet<WeakMember<HeapObject>>; static WeakHeapObjectSet& GetWeakHeapObjectSet(); - using HeapObjectSet = PersistentHeapHashSet<Member<HeapObject>>; + using HeapObjectSet = HeapHashSet<Member<HeapObject>>; static HeapObjectSet& GetHeapObjectSet(); static IntWrapper& ThreadSpecificIntWrapper() { @@ -6655,21 +6673,26 @@ class ThreadedClearOnShutdownTester::HeapObject final ThreadedClearOnShutdownTester::WeakHeapObjectSet& ThreadedClearOnShutdownTester::GetWeakHeapObjectSet() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<WeakHeapObjectSet>, singleton, - ()); - if (!singleton.IsSet()) - singleton->RegisterAsStaticReference(); - - return *singleton; + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<WeakHeapObjectSet>>, + singleton, ()); + Persistent<WeakHeapObjectSet>& singleton_persistent = *singleton; + if (!singleton_persistent) { + singleton_persistent = new WeakHeapObjectSet(); + singleton_persistent.RegisterAsStaticReference(); + } + return *singleton_persistent; } ThreadedClearOnShutdownTester::HeapObjectSet& ThreadedClearOnShutdownTester::GetHeapObjectSet() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<HeapObjectSet>, singleton, ()); - if (!singleton.IsSet()) - singleton->RegisterAsStaticReference(); - - return *singleton; + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<Persistent<HeapObjectSet>>, + singleton, ()); + Persistent<HeapObjectSet>& singleton_persistent = *singleton; + if (!singleton_persistent) { + singleton_persistent = new HeapObjectSet(); + singleton_persistent.RegisterAsStaticReference(); + } + return *singleton_persistent; } void ThreadedClearOnShutdownTester::RunWhileAttached() { @@ -6848,4 +6871,13 @@ TEST(HeapTest, HeapDoublyLinkedList) { EXPECT_EQ(DoublyLinkedListNodeImpl::destructor_calls_, 2); } +TEST(HeapTest, PersistentHeapVectorCopyAssignment) { + PersistentHeapVector<Member<IntWrapper>> vector1; + { + PersistentHeapVector<Member<IntWrapper>> vector2; + vector1 = vector2; + } + PreciselyCollectGarbage(); +} + } // namespace blink 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 c1db0127070..49c4fa7f0a0 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 @@ -24,18 +24,19 @@ namespace incremental_marking_test { // Visitor that expects every directly reachable object from a given backing // store to be in the set of provided objects. -template <typename T> class BackingVisitor : public Visitor { public: - explicit BackingVisitor(ThreadState* state, std::vector<T*>* objects) + BackingVisitor(ThreadState* state, std::vector<void*>* objects) : Visitor(state), objects_(objects) {} - virtual ~BackingVisitor() {} + ~BackingVisitor() final {} void ProcessBackingStore(HeapObjectHeader* header) { EXPECT_TRUE(header->IsValid()); EXPECT_TRUE(header->IsMarked()); header->Unmark(); - ThreadHeap::GcInfo(header->GcInfoIndex())->trace_(this, header->Payload()); + GCInfoTable::Get() + .GCInfoFromIndex(header->GcInfoIndex()) + ->trace_(this, header->Payload()); } void Visit(void* obj, TraceDescriptor desc) final { @@ -68,15 +69,19 @@ class BackingVisitor : public Visitor { MovingObjectCallback, void* callback_data) final {} void RegisterWeakCallback(void* closure, WeakCallback) final {} + void Visit(const TraceWrapperV8Reference<v8::Value>&) final {} + void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) final {} + void Visit(void*, TraceWrapperDescriptor) final {} private: - std::vector<T*>* objects_; + std::vector<void*>* objects_; }; // Base class for initializing worklists. class IncrementalMarkingScopeBase { public: - IncrementalMarkingScopeBase(ThreadState* thread_state) + explicit IncrementalMarkingScopeBase(ThreadState* thread_state) : thread_state_(thread_state), heap_(thread_state_->Heap()) { heap_.CommitCallbackStacks(); } @@ -132,14 +137,15 @@ class IncrementalMarkingScope : public IncrementalMarkingScopeBase { // Expects that the write barrier fires for the objects passed to the // constructor. This requires that the objects are added to the marking stack // as well as headers being marked. -template <typename T> class ExpectWriteBarrierFires : public IncrementalMarkingScope { public: ExpectWriteBarrierFires(ThreadState* thread_state, - std::initializer_list<T*> objects) - : IncrementalMarkingScope(thread_state), objects_(objects) { + std::initializer_list<void*> objects) + : IncrementalMarkingScope(thread_state), + objects_(objects), + backing_visitor_(thread_state_, &objects_) { EXPECT_TRUE(marking_worklist_->IsGlobalEmpty()); - for (T* object : objects_) { + for (void* object : objects_) { // Ensure that the object is in the normal arena so we can ignore backing // objects on the marking stack. CHECK(ThreadHeap::IsNormalArenaIndex( @@ -155,16 +161,15 @@ class ExpectWriteBarrierFires : public IncrementalMarkingScope { MarkingItem item; // All objects watched should be on the marking stack. while (marking_worklist_->Pop(WorklistTaskId::MainThread, &item)) { - T* obj = reinterpret_cast<T*>(item.object); // Inspect backing stores to allow specifying objects that are only // reachable through a backing store. if (!ThreadHeap::IsNormalArenaIndex( - PageFromObject(obj)->Arena()->ArenaIndex())) { - BackingVisitor<T> visitor(thread_state_, &objects_); - visitor.ProcessBackingStore(HeapObjectHeader::FromPayload(obj)); + PageFromObject(item.object)->Arena()->ArenaIndex())) { + backing_visitor_.ProcessBackingStore( + HeapObjectHeader::FromPayload(item.object)); continue; } - auto pos = std::find(objects_.begin(), objects_.end(), obj); + auto pos = std::find(objects_.begin(), objects_.end(), item.object); if (objects_.end() != pos) objects_.erase(pos); } @@ -178,39 +183,37 @@ class ExpectWriteBarrierFires : public IncrementalMarkingScope { } private: - std::vector<T*> objects_; + std::vector<void*> objects_; std::vector<HeapObjectHeader*> headers_; + BackingVisitor backing_visitor_; }; // Expects that no write barrier fires for the objects passed to the // constructor. This requires that the marking stack stays empty and the marking // state of the object stays the same across the lifetime of the scope. -template <typename T> class ExpectNoWriteBarrierFires : public IncrementalMarkingScope { public: ExpectNoWriteBarrierFires(ThreadState* thread_state, - std::initializer_list<T*> objects) - : IncrementalMarkingScope(thread_state), objects_(objects) { + std::initializer_list<void*> objects) + : IncrementalMarkingScope(thread_state) { EXPECT_TRUE(marking_worklist_->IsGlobalEmpty()); - for (T* object : objects_) { + for (void* object : objects_) { HeapObjectHeader* header = HeapObjectHeader::FromPayload(object); - headers_.push_back(header); - was_marked_.push_back(header->IsMarked()); + headers_.push_back({header, header->IsMarked()}); } } ~ExpectNoWriteBarrierFires() { EXPECT_TRUE(marking_worklist_->IsGlobalEmpty()); - for (size_t i = 0; i < headers_.size(); i++) { - EXPECT_EQ(was_marked_[i], headers_[i]->IsMarked()); - headers_[i]->Unmark(); + for (const auto& pair : headers_) { + EXPECT_EQ(pair.second, pair.first->IsMarked()); + pair.first->Unmark(); } } private: - std::vector<T*> objects_; - std::vector<HeapObjectHeader*> headers_; - std::vector<bool> was_marked_; + std::vector<void*> objects_; + std::vector<std::pair<HeapObjectHeader*, bool /* was marked */>> headers_; }; class Object : public GarbageCollected<Object> { @@ -220,12 +223,12 @@ class Object : public GarbageCollected<Object> { void set_next(Object* next) { next_ = next; } - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(next_); } - bool IsMarked() const { return HeapObjectHeader::FromPayload(this)->IsMarked(); } + virtual void Trace(blink::Visitor* visitor) { visitor->Trace(next_); } + private: Object() : next_(nullptr) {} explicit Object(Object* next) : next_(next) {} @@ -254,7 +257,7 @@ TEST(IncrementalMarkingTest, StackFrameDepthDisabled) { TEST(IncrementalMarkingTest, ManualWriteBarrierTriggersWhenMarkingIsOn) { Object* object = Object::Create(); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {object}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {object}); EXPECT_FALSE(object->IsMarked()); MarkingVisitor::WriteBarrier(object); EXPECT_TRUE(object->IsMarked()); @@ -276,7 +279,7 @@ TEST(IncrementalMarkingTest, MemberSetUnmarkedObject) { Object* parent = Object::Create(); Object* child = Object::Create(); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {child}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {child}); EXPECT_FALSE(child->IsMarked()); parent->set_next(child); EXPECT_TRUE(child->IsMarked()); @@ -288,7 +291,7 @@ TEST(IncrementalMarkingTest, MemberSetMarkedObjectNoBarrier) { Object* child = Object::Create(); HeapObjectHeader::FromPayload(child)->Mark(); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {child}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child}); parent->set_next(child); } } @@ -312,7 +315,7 @@ TEST(IncrementalMarkingTest, MemberReferenceAssignMember) { Member<Object>& m2 = m1; Member<Object> m3(obj); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); m2 = m3; } } @@ -320,7 +323,7 @@ TEST(IncrementalMarkingTest, MemberReferenceAssignMember) { TEST(IncrementalMarkingTest, MemberSetDeletedValueNoBarrier) { Member<Object> m; { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {}); m = WTF::kHashTableDeletedValue; } } @@ -328,7 +331,7 @@ TEST(IncrementalMarkingTest, MemberSetDeletedValueNoBarrier) { TEST(IncrementalMarkingTest, MemberCopyDeletedValueNoBarrier) { Member<Object> m1(WTF::kHashTableDeletedValue); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {}); Member<Object> m2(m1); } } @@ -336,7 +339,7 @@ TEST(IncrementalMarkingTest, MemberCopyDeletedValueNoBarrier) { TEST(IncrementalMarkingTest, MemberHashTraitConstructDeletedValueNoBarrier) { Member<Object> m1; { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {}); HashTraits<Member<Object>>::ConstructDeletedValue(m1, false); } } @@ -344,7 +347,7 @@ TEST(IncrementalMarkingTest, MemberHashTraitConstructDeletedValueNoBarrier) { TEST(IncrementalMarkingTest, MemberHashTraitIsDeletedValueNoBarrier) { Member<Object> m1(Object::Create()); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {}); EXPECT_FALSE(HashTraits<Member<Object>>::IsDeletedValue(m1)); } } @@ -360,7 +363,7 @@ class Mixin : public GarbageCollectedMixin { Mixin() : next_(nullptr) {} virtual ~Mixin() {} - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(next_); } + void Trace(blink::Visitor* visitor) override { visitor->Trace(next_); } virtual void Bar() {} @@ -380,12 +383,12 @@ class Child : public GarbageCollected<Child>, public: static Child* Create() { return new Child(); } - virtual ~Child() {} + ~Child() override {} - virtual void Trace(blink::Visitor* visitor) { Mixin::Trace(visitor); } + void Trace(blink::Visitor* visitor) override { Mixin::Trace(visitor); } - virtual void Foo() {} - virtual void Bar() {} + void Foo() override {} + void Bar() override {} protected: Child() : ClassWithVirtual(), Mixin() {} @@ -415,7 +418,7 @@ TEST(IncrementalMarkingTest, WriteBarrierOnUnmarkedMixinApplication) { Mixin* mixin = static_cast<Mixin*>(child); EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin)); { - ExpectWriteBarrierFires<Child> scope(ThreadState::Current(), {child}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {child}); parent->set_mixin(mixin); } } @@ -427,7 +430,7 @@ TEST(IncrementalMarkingTest, NoWriteBarrierOnMarkedMixinApplication) { Mixin* mixin = static_cast<Mixin*>(child); EXPECT_NE(static_cast<void*>(child), static_cast<void*>(mixin)); { - ExpectNoWriteBarrierFires<Child> scope(ThreadState::Current(), {child}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {child}); parent->set_mixin(mixin); } } @@ -478,7 +481,7 @@ TEST(IncrementalMarkingTest, HeapVectorPushBackMember) { Object* obj = Object::Create(); HeapVector<Member<Object>> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); vec.push_back(obj); } } @@ -487,7 +490,7 @@ TEST(IncrementalMarkingTest, HeapVectorPushBackNonGCedContainer) { Object* obj = Object::Create(); HeapVector<NonGarbageCollectedContainer> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); vec.push_back(NonGarbageCollectedContainer(obj, 1)); } } @@ -497,7 +500,7 @@ TEST(IncrementalMarkingTest, HeapVectorPushBackStdPair) { Object* obj2 = Object::Create(); HeapVector<std::pair<Member<Object>, Member<Object>>> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); vec.push_back(std::make_pair(Member<Object>(obj1), Member<Object>(obj2))); } } @@ -506,7 +509,7 @@ TEST(IncrementalMarkingTest, HeapVectorEmplaceBackMember) { Object* obj = Object::Create(); HeapVector<Member<Object>> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); vec.emplace_back(obj); } } @@ -515,7 +518,7 @@ TEST(IncrementalMarkingTest, HeapVectorEmplaceBackNonGCedContainer) { Object* obj = Object::Create(); HeapVector<NonGarbageCollectedContainer> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); vec.emplace_back(obj, 1); } } @@ -525,7 +528,7 @@ TEST(IncrementalMarkingTest, HeapVectorEmplaceBackStdPair) { Object* obj2 = Object::Create(); HeapVector<std::pair<Member<Object>, Member<Object>>> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); vec.emplace_back(obj1, obj2); } } @@ -535,7 +538,7 @@ TEST(IncrementalMarkingTest, HeapVectorCopyMember) { HeapVector<Member<Object>> vec1; vec1.push_back(object); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {object}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {object}); HeapVector<Member<Object>> vec2(vec1); } } @@ -545,7 +548,7 @@ TEST(IncrementalMarkingTest, HeapVectorCopyNonGCedContainer) { HeapVector<NonGarbageCollectedContainer> vec1; vec1.emplace_back(obj, 1); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); HeapVector<NonGarbageCollectedContainer> vec2(vec1); } } @@ -556,7 +559,7 @@ TEST(IncrementalMarkingTest, HeapVectorCopyStdPair) { HeapVector<std::pair<Member<Object>, Member<Object>>> vec1; vec1.emplace_back(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapVector<std::pair<Member<Object>, Member<Object>>> vec2(vec1); } } @@ -566,7 +569,7 @@ TEST(IncrementalMarkingTest, HeapVectorMoveMember) { HeapVector<Member<Object>> vec1; vec1.push_back(obj); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); HeapVector<Member<Object>> vec2(std::move(vec1)); } } @@ -576,7 +579,7 @@ TEST(IncrementalMarkingTest, HeapVectorMoveNonGCedContainer) { HeapVector<NonGarbageCollectedContainer> vec1; vec1.emplace_back(obj, 1); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); HeapVector<NonGarbageCollectedContainer> vec2(std::move(vec1)); } } @@ -587,7 +590,7 @@ TEST(IncrementalMarkingTest, HeapVectorMoveStdPair) { HeapVector<std::pair<Member<Object>, Member<Object>>> vec1; vec1.emplace_back(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapVector<std::pair<Member<Object>, Member<Object>>> vec2(std::move(vec1)); } } @@ -600,7 +603,7 @@ TEST(IncrementalMarkingTest, HeapVectorSwapMember) { HeapVector<Member<Object>> vec2; vec2.push_back(obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(vec1, vec2); } } @@ -613,7 +616,7 @@ TEST(IncrementalMarkingTest, HeapVectorSwapNonGCedContainer) { HeapVector<NonGarbageCollectedContainer> vec2; vec2.emplace_back(obj2, 2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(vec1, vec2); } } @@ -626,7 +629,7 @@ TEST(IncrementalMarkingTest, HeapVectorSwapStdPair) { HeapVector<std::pair<Member<Object>, Member<Object>>> vec2; vec2.emplace_back(nullptr, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(vec1, vec2); } } @@ -637,7 +640,7 @@ TEST(IncrementalMarkingTest, HeapVectorSubscriptOperator) { HeapVector<Member<Object>> vec; vec.push_back(obj1); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj2}); EXPECT_EQ(1u, vec.size()); EXPECT_EQ(obj1, vec[0]); vec[0] = obj2; @@ -653,7 +656,7 @@ TEST(IncrementalMarkingTest, HeapVectorEagerTracingStopsAtMember) { obj1->set_next(obj3); HeapVector<NonGarbageCollectedContainerRoot> vec; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); vec.emplace_back(obj1, obj2, 3); // |obj3| is only reachable from |obj1| which is not eagerly traced. Only // objects without object headers are eagerly traced. @@ -693,8 +696,7 @@ TEST(IncrementalMarkingTest, HeapDoublyLinkedListPush) { ObjectNode* obj_node = new ObjectNode(obj); HeapDoublyLinkedList<ObjectNode> list; { - ExpectWriteBarrierFires<ObjectNode> scope(ThreadState::Current(), - {obj_node}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj_node}); list.Push(obj_node); // |obj| will be marked once |obj_node| gets processed. EXPECT_FALSE(obj->IsMarked()); @@ -706,8 +708,7 @@ TEST(IncrementalMarkingTest, HeapDoublyLinkedListAppend) { ObjectNode* obj_node = new ObjectNode(obj); HeapDoublyLinkedList<ObjectNode> list; { - ExpectWriteBarrierFires<ObjectNode> scope(ThreadState::Current(), - {obj_node}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj_node}); list.Append(obj_node); // |obj| will be marked once |obj_node| gets processed. EXPECT_FALSE(obj->IsMarked()); @@ -722,7 +723,7 @@ TEST(IncrementalMarkingTest, HeapDequePushBackMember) { Object* obj = Object::Create(); HeapDeque<Member<Object>> deq; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); deq.push_back(obj); } } @@ -731,7 +732,7 @@ TEST(IncrementalMarkingTest, HeapDequePushFrontMember) { Object* obj = Object::Create(); HeapDeque<Member<Object>> deq; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); deq.push_front(obj); } } @@ -740,7 +741,7 @@ TEST(IncrementalMarkingTest, HeapDequeEmplaceBackMember) { Object* obj = Object::Create(); HeapDeque<Member<Object>> deq; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); deq.emplace_back(obj); } } @@ -749,7 +750,7 @@ TEST(IncrementalMarkingTest, HeapDequeEmplaceFrontMember) { Object* obj = Object::Create(); HeapDeque<Member<Object>> deq; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); deq.emplace_front(obj); } } @@ -759,7 +760,7 @@ TEST(IncrementalMarkingTest, HeapDequeCopyMember) { HeapDeque<Member<Object>> deq1; deq1.push_back(object); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {object}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {object}); HeapDeque<Member<Object>> deq2(deq1); } } @@ -769,7 +770,7 @@ TEST(IncrementalMarkingTest, HeapDequeMoveMember) { HeapDeque<Member<Object>> deq1; deq1.push_back(object); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {object}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {object}); HeapDeque<Member<Object>> deq2(std::move(deq1)); } } @@ -782,7 +783,7 @@ TEST(IncrementalMarkingTest, HeapDequeSwapMember) { HeapDeque<Member<Object>> deq2; deq2.push_back(obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(deq1, deq2); } } @@ -798,7 +799,7 @@ void Insert() { Object* obj = Object::Create(); Container container; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); container.insert(obj); } } @@ -808,7 +809,7 @@ void InsertNoBarrier() { Object* obj = Object::Create(); Container container; { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj}); container.insert(obj); } } @@ -819,7 +820,7 @@ void Copy() { Container container1; container1.insert(obj); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); Container container2(container1); EXPECT_TRUE(container1.Contains(obj)); EXPECT_TRUE(container2.Contains(obj)); @@ -832,7 +833,7 @@ void CopyNoBarrier() { Container container1; container1.insert(obj); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj}); Container container2(container1); EXPECT_TRUE(container1.Contains(obj)); EXPECT_TRUE(container2.Contains(obj)); @@ -845,7 +846,7 @@ void Move() { Container container1; container1.insert(obj); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); Container container2(std::move(container1)); } } @@ -856,7 +857,7 @@ void MoveNoBarrier() { Container container1; container1.insert(obj); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj}); Container container2(std::move(container1)); } } @@ -870,7 +871,7 @@ void Swap() { Container container2; container2.insert(obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(container1, container2); } } @@ -884,8 +885,7 @@ void SwapNoBarrier() { Container container2; container2.insert(obj2); { - ExpectNoWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2}); + ExpectNoWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); std::swap(container1, container2); } } @@ -1015,7 +1015,7 @@ TEST(IncrementalMarkingTest, HeapHashSetStrongWeakPair) { { // Only the strong field in the StrongWeakPair should be hit by the // write barrier. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1}); set.insert(StrongWeakPair(obj1, obj2)); EXPECT_FALSE(obj2->IsMarked()); } @@ -1028,7 +1028,7 @@ TEST(IncrementalMarkingTest, HeapLinkedHashSetStrongWeakPair) { { // Only the strong field in the StrongWeakPair should be hit by the // write barrier. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1}); set.insert(StrongWeakPair(obj1, obj2)); EXPECT_FALSE(obj2->IsMarked()); } @@ -1084,8 +1084,7 @@ TEST(IncrementalMarkingTest, HeapHashCountedSetSwap) { HeapHashCountedSet<Member<Object>> container2; container2.insert(obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); container1.swap(container2); } } @@ -1098,8 +1097,7 @@ TEST(IncrementalMarkingTest, HeapHashCountedSetSwap) { container2.insert(obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); container1.swap(container2); } } @@ -1144,7 +1142,7 @@ TEST(IncrementalMarkingTest, HeapTerminatedArrayBuilder) { HeapTerminatedArrayBuilder<TerminatedArrayNode> builder(array); builder.Grow(1); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj}); builder.Append(TerminatedArrayNode(obj)); } array = builder.Release(); @@ -1160,7 +1158,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertMember) { Object* obj2 = Object::Create(); HeapHashMap<Member<Object>, Member<Object>> map; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.insert(obj1, obj2); } } @@ -1171,7 +1169,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertWeakMember) { HeapHashMap<WeakMember<Object>, WeakMember<Object>> map; { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.insert(obj1, obj2); } } @@ -1182,7 +1180,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertMemberWeakMember) { HeapHashMap<Member<Object>, WeakMember<Object>> map; { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.insert(obj1, obj2); } } @@ -1193,7 +1191,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertWeakMemberMember) { HeapHashMap<WeakMember<Object>, Member<Object>> map; { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.insert(obj1, obj2); } } @@ -1203,7 +1201,7 @@ TEST(IncrementalMarkingTest, HeapHashMapSetMember) { Object* obj2 = Object::Create(); HeapHashMap<Member<Object>, Member<Object>> map; { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.Set(obj1, obj2); } } @@ -1217,7 +1215,7 @@ TEST(IncrementalMarkingTest, HeapHashMapSetMemberUpdateValue) { { // Only |obj3| is newly added to |map|, so we only expect the barrier to // fire on this one. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3}); map.Set(obj1, obj3); EXPECT_FALSE(HeapObjectHeader::FromPayload(obj1)->IsMarked()); EXPECT_FALSE(HeapObjectHeader::FromPayload(obj2)->IsMarked()); @@ -1231,7 +1229,7 @@ TEST(IncrementalMarkingTest, HeapHashMapIteratorChangeKey) { HeapHashMap<Member<Object>, Member<Object>> map; map.insert(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3}); auto it = map.find(obj1); EXPECT_NE(map.end(), it); it->key = obj3; @@ -1245,7 +1243,7 @@ TEST(IncrementalMarkingTest, HeapHashMapIteratorChangeValue) { HeapHashMap<Member<Object>, Member<Object>> map; map.insert(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj3}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj3}); auto it = map.find(obj1); EXPECT_NE(map.end(), it); it->value = obj3; @@ -1258,7 +1256,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyMemberMember) { HeapHashMap<Member<Object>, Member<Object>> map1; map1.insert(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); EXPECT_TRUE(map1.Contains(obj1)); HeapHashMap<Member<Object>, Member<Object>> map2(map1); EXPECT_TRUE(map1.Contains(obj1)); @@ -1273,7 +1271,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyWeakMemberWeakMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); EXPECT_TRUE(map1.Contains(obj1)); HeapHashMap<WeakMember<Object>, WeakMember<Object>> map2(map1); EXPECT_TRUE(map1.Contains(obj1)); @@ -1288,7 +1286,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyMemberWeakMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); EXPECT_TRUE(map1.Contains(obj1)); HeapHashMap<Member<Object>, WeakMember<Object>> map2(map1); EXPECT_TRUE(map1.Contains(obj1)); @@ -1303,7 +1301,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyWeakMemberMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); EXPECT_TRUE(map1.Contains(obj1)); HeapHashMap<WeakMember<Object>, Member<Object>> map2(map1); EXPECT_TRUE(map1.Contains(obj1)); @@ -1317,7 +1315,7 @@ TEST(IncrementalMarkingTest, HeapHashMapMoveMember) { HeapHashMap<Member<Object>, Member<Object>> map1; map1.insert(obj1, obj2); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapHashMap<Member<Object>, Member<Object>> map2(std::move(map1)); } } @@ -1329,7 +1327,7 @@ TEST(IncrementalMarkingTest, HeapHashMapMoveWeakMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapHashMap<WeakMember<Object>, WeakMember<Object>> map2(std::move(map1)); } } @@ -1341,7 +1339,7 @@ TEST(IncrementalMarkingTest, HeapHashMapMoveMemberWeakMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapHashMap<Member<Object>, WeakMember<Object>> map2(std::move(map1)); } } @@ -1353,7 +1351,7 @@ TEST(IncrementalMarkingTest, HeapHashMapMoveWeakMemberMember) { map1.insert(obj1, obj2); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); HeapHashMap<WeakMember<Object>, Member<Object>> map2(std::move(map1)); } } @@ -1368,8 +1366,8 @@ TEST(IncrementalMarkingTest, HeapHashMapSwapMemberMember) { HeapHashMap<Member<Object>, Member<Object>> map2; map2.insert(obj3, obj4); { - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2, obj3, obj4}); + ExpectWriteBarrierFires scope(ThreadState::Current(), + {obj1, obj2, obj3, obj4}); std::swap(map1, map2); } } @@ -1385,8 +1383,8 @@ TEST(IncrementalMarkingTest, HeapHashMapSwapWeakMemberWeakMember) { map2.insert(obj3, obj4); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2, obj3, obj4}); + ExpectWriteBarrierFires scope(ThreadState::Current(), + {obj1, obj2, obj3, obj4}); std::swap(map1, map2); } } @@ -1402,8 +1400,8 @@ TEST(IncrementalMarkingTest, HeapHashMapSwapMemberWeakMember) { map2.insert(obj3, obj4); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2, obj3, obj4}); + ExpectWriteBarrierFires scope(ThreadState::Current(), + {obj1, obj2, obj3, obj4}); std::swap(map1, map2); } } @@ -1419,8 +1417,8 @@ TEST(IncrementalMarkingTest, HeapHashMapSwapWeakMemberMember) { map2.insert(obj3, obj4); { // Weak references are strongified for the current cycle. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), - {obj1, obj2, obj3, obj4}); + ExpectWriteBarrierFires scope(ThreadState::Current(), + {obj1, obj2, obj3, obj4}); std::swap(map1, map2); } } @@ -1433,7 +1431,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertStrongWeakPairMember) { { // Tests that the write barrier also fires for entities such as // StrongWeakPair that don't overload assignment operators in translators. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj3}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj3}); map.insert(StrongWeakPair(obj1, obj2), obj3); } } @@ -1446,7 +1444,7 @@ TEST(IncrementalMarkingTest, HeapHashMapInsertMemberStrongWeakPair) { { // Tests that the write barrier also fires for entities such as // StrongWeakPair that don't overload assignment operators in translators. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1, obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1, obj2}); map.insert(obj1, StrongWeakPair(obj2, obj3)); } } @@ -1460,7 +1458,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyKeysToVectorMember) { { // Only key should have its write barrier fired. A write barrier call for // value hints to an inefficient implementation. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj1}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj1}); CopyKeysToVector(map, vec); } } @@ -1474,7 +1472,7 @@ TEST(IncrementalMarkingTest, HeapHashMapCopyValuesToVectorMember) { { // Only value should have its write barrier fired. A write barrier call for // key hints to an inefficient implementation. - ExpectWriteBarrierFires<Object> scope(ThreadState::Current(), {obj2}); + ExpectWriteBarrierFires scope(ThreadState::Current(), {obj2}); CopyValuesToVector(map, vec); } } @@ -1548,30 +1546,35 @@ TEST(IncrementalMarkingTest, WriteBarrierDuringMixinConstruction) { IncrementalMarkingScope scope(ThreadState::Current()); ObjectRegistry registry; RegisteringObject* object = new RegisteringObject(®istry); + + // 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 item; - EXPECT_TRUE(scope.marking_worklist()->Pop(WorklistTaskId::MainThread, &item)); - RegisteringObject* recorded_object = - reinterpret_cast<RegisteringObject*>(item.object); - // In this case, the Member write barrier will also add the object to the - // regular marking stack. The not-fully-constructed object marking stack is - // only needed when going through custom off-heap data structures that require - // eager tracing. - EXPECT_EQ(object, recorded_object); - // In this example, there are two more objects on the callback stack: the - // backing store for which a write barrier triggers after rehashing, and - // a write barrier for the Member assignment (which might not always happen). - scope.marking_worklist()->Pop(WorklistTaskId::MainThread, &item); - scope.marking_worklist()->Pop(WorklistTaskId::MainThread, &item); - // The mixin object should be on the not-fully-constructed object marking - // stack. + MarkingItem marking_item; + while (scope.marking_worklist()->Pop(WorklistTaskId::MainThread, + &marking_item)) { + HeapObjectHeader* header = + HeapObjectHeader::FromPayload(marking_item.object); + if (header->IsMarked()) + header->Unmark(); + } + EXPECT_TRUE(scope.marking_worklist()->IsGlobalEmpty()); + EXPECT_FALSE(scope.not_fully_constructed_worklist()->IsGlobalEmpty()); - NotFullyConstructedItem item2; - EXPECT_TRUE(scope.not_fully_constructed_worklist()->Pop( - WorklistTaskId::MainThread, &item2)); - RegisteringObject* recorded_object2 = - reinterpret_cast<RegisteringObject*>(item2); - EXPECT_EQ(object, recorded_object2); + NotFullyConstructedItem partial_item; + bool found_mixin_object = false; + // The same object may be on the marking work list because of expanding + // and rehashing of the backing store in the registry. + while (scope.not_fully_constructed_worklist()->Pop(WorklistTaskId::MainThread, + &partial_item)) { + if (object == partial_item) + found_mixin_object = true; + HeapObjectHeader* header = HeapObjectHeader::FromPayload(partial_item); + if (header->IsMarked()) + header->Unmark(); + } + EXPECT_TRUE(found_mixin_object); + EXPECT_TRUE(scope.not_fully_constructed_worklist()->IsGlobalEmpty()); } TEST(IncrementalMarkingTest, OverrideAfterMixinConstruction) { 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 61c68bf4d0d..1d9d67a51a5 100644 --- a/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h +++ b/chromium/third_party/blink/renderer/platform/heap/marking_verifier.h @@ -15,14 +15,15 @@ namespace blink { class MarkingVerifier final : public Visitor { public: explicit MarkingVerifier(ThreadState* state) : Visitor(state) {} - virtual ~MarkingVerifier() {} + ~MarkingVerifier() override {} void VerifyObject(HeapObjectHeader* header) { // Verify only non-free marked objects. if (header->IsFree() || !header->IsMarked()) return; - const GCInfo* info = ThreadHeap::GcInfo(header->GcInfoIndex()); + const GCInfo* info = + GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex()); const bool can_verify = !info->HasVTable() || blink::VTableInitialized(header->Payload()); if (can_verify) { @@ -54,6 +55,10 @@ class MarkingVerifier final : public Visitor { void VisitBackingStoreOnly(void*, void**) final {} void RegisterBackingStoreCallback(void*, MovingObjectCallback, void*) final {} void RegisterWeakCallback(void*, WeakCallback) final {} + void Visit(const TraceWrapperV8Reference<v8::Value>&) final {} + void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) final {} + void Visit(void*, TraceWrapperDescriptor) final {} private: void VerifyChild(void* base_object_payload) { 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 ab2dc1f1fec..101f45e633a 100644 --- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc +++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.cc @@ -9,6 +9,14 @@ namespace blink { +namespace { + +ALWAYS_INLINE bool IsHashTableDeleteValue(const void* value) { + return value == reinterpret_cast<void*>(-1); +} + +} // namespace + std::unique_ptr<MarkingVisitor> MarkingVisitor::Create(ThreadState* state, MarkingMode mode) { return std::make_unique<MarkingVisitor>(state, mode); @@ -79,7 +87,8 @@ bool IsUninitializedMemory(void* object_pointer, size_t object_size) { } // namespace void MarkingVisitor::ConservativelyMarkHeader(HeapObjectHeader* header) { - const GCInfo* gc_info = ThreadHeap::GcInfo(header->GcInfoIndex()); + const GCInfo* gc_info = + GCInfoTable::Get().GCInfoFromIndex(header->GcInfoIndex()); if (gc_info->HasVTable() && !VTableInitialized(header->Payload())) { // We hit this branch when a GC strikes before GarbageCollected<>'s // constructor runs. @@ -131,4 +140,38 @@ bool MarkingVisitor::RegisterWeakTable(const void* closure, return true; } +void MarkingVisitor::WriteBarrierSlow(void* value) { + if (!value || IsHashTableDeleteValue(value)) + return; + + ThreadState* const thread_state = ThreadState::Current(); + if (!thread_state->IsIncrementalMarking()) + return; + + thread_state->Heap().WriteBarrier(value); +} + +void MarkingVisitor::TraceMarkedBackingStoreSlow(void* value) { + if (!value) + return; + + ThreadState* const thread_state = ThreadState::Current(); + if (!thread_state->IsIncrementalMarking()) + return; + + // |value| is pointing to the start of a backing store. + HeapObjectHeader* header = HeapObjectHeader::FromPayload(value); + CHECK(header->IsMarked()); + DCHECK(thread_state->CurrentVisitor()); + // This check ensures that the visitor will not eagerly recurse into children + // but rather push all blink::GarbageCollected objects and only eagerly trace + // non-managed objects. + DCHECK(!thread_state->Heap().GetStackFrameDepth().IsEnabled()); + // No weak handling for write barriers. Modifying weakly reachable objects + // strongifies them for the current cycle. + GCInfoTable::Get() + .GCInfoFromIndex(header->GcInfoIndex()) + ->trace_(thread_state->CurrentVisitor(), value); +} + } // namespace blink 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 ec072aca4bb..0c5c362d40d 100644 --- a/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h +++ b/chromium/third_party/blink/renderer/platform/heap/marking_visitor.h @@ -35,10 +35,19 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor { static std::unique_ptr<MarkingVisitor> Create(ThreadState*, MarkingMode); - inline static void WriteBarrier(void* value); + // 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. + ALWAYS_INLINE static void 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); MarkingVisitor(ThreadState*, MarkingMode); - virtual ~MarkingVisitor(); + ~MarkingVisitor() override; // Marking implementation. @@ -100,6 +109,10 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor { desc.callback); } + void Visit(void*, TraceWrapperDescriptor) final { + // Ignore as the object is also passed to Visit(void*, TraceDescriptor). + } + void VisitWeak(void* object, void** object_slot, TraceDescriptor desc, @@ -138,7 +151,16 @@ class PLATFORM_EXPORT MarkingVisitor final : public Visitor { EphemeronCallback iteration_callback) final; void RegisterWeakCallback(void* closure, WeakCallback) final; + // Unused cross-component visit methods. + void Visit(const TraceWrapperV8Reference<v8::Value>&) final {} + void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) final {} + private: + // Exact version of the marking write barriers. + static void WriteBarrierSlow(void*); + static void TraceMarkedBackingStoreSlow(void*); + void RegisterBackingStoreReference(void* slot); void ConservativelyMarkHeader(HeapObjectHeader*); @@ -173,16 +195,25 @@ inline void MarkingVisitor::MarkHeader(HeapObjectHeader* header, } } -inline void MarkingVisitor::WriteBarrier(void* value) { +ALWAYS_INLINE void MarkingVisitor::WriteBarrier(void* value) { #if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) - if (!ThreadState::IsAnyIncrementalMarking() || !value) + if (!ThreadState::IsAnyIncrementalMarking()) return; - ThreadState* const thread_state = ThreadState::Current(); - if (!thread_state->IsIncrementalMarking()) + // Avoid any further checks and dispatch to a call at this point. Aggressive + // inlining otherwise pollutes the regular execution paths. + WriteBarrierSlow(value); +#endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) +} + +ALWAYS_INLINE void MarkingVisitor::TraceMarkedBackingStore(void* value) { +#if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) + if (!ThreadState::IsAnyIncrementalMarking()) return; - thread_state->Heap().WriteBarrier(value); + // Avoid any further checks and dispatch to a call at this point. Aggressive + // inlining otherwise pollutes the regular execution paths. + TraceMarkedBackingStoreSlow(value); #endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) } diff --git a/chromium/third_party/blink/renderer/platform/heap/member.h b/chromium/third_party/blink/renderer/platform/heap/member.h index 10e22d4b10d..fc06523e713 100644 --- a/chromium/third_party/blink/renderer/platform/heap/member.h +++ b/chromium/third_party/blink/renderer/platform/heap/member.h @@ -216,47 +216,47 @@ class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> { } Member(WTF::HashTableDeletedValueType x) : Parent(x) {} - Member(const Member& other) : Parent(other) { WriteBarrier(this->raw_); } + Member(const Member& other) : Parent(other) { WriteBarrier(); } template <typename U> Member(const Member<U>& other) : Parent(other) { - WriteBarrier(this->raw_); + WriteBarrier(); } template <typename U> Member(const Persistent<U>& other) : Parent(other) { - WriteBarrier(this->raw_); + WriteBarrier(); } template <typename U> Member& operator=(const Persistent<U>& other) { Parent::operator=(other); - WriteBarrier(this->raw_); + WriteBarrier(); return *this; } Member& operator=(const Member& other) { Parent::operator=(other); - WriteBarrier(this->raw_); + WriteBarrier(); return *this; } template <typename U> Member& operator=(const Member<U>& other) { Parent::operator=(other); - WriteBarrier(this->raw_); + WriteBarrier(); return *this; } template <typename U> Member& operator=(const WeakMember<U>& other) { Parent::operator=(other); - WriteBarrier(this->raw_); + WriteBarrier(); return *this; } template <typename U> Member& operator=(U* other) { Parent::operator=(other); - WriteBarrier(this->raw_); + WriteBarrier(); return *this; } @@ -271,12 +271,10 @@ class Member : public MemberBase<T, TracenessMemberConfiguration::kTraced> { } protected: - ALWAYS_INLINE void WriteBarrier(T* value) const { + ALWAYS_INLINE void WriteBarrier() const { #if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) - if (LIKELY(!this->IsHashTableDeletedValue())) { - MarkingVisitor::WriteBarrier( - const_cast<typename std::remove_const<T>::type*>(value)); - } + MarkingVisitor::WriteBarrier( + const_cast<typename std::remove_const<T>::type*>(this->raw_)); #endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) } @@ -604,13 +602,13 @@ class ConstructTraits<blink::Member<T>, Traits, Allocator> { Args&&... args) { blink::Member<T>* object = new (NotNull, location) blink::Member<T>(std::forward<Args>(args)...); - object->WriteBarrier(object->raw_); + object->WriteBarrier(); return object; } static void NotifyNewElements(blink::Member<T>* array, size_t len) { while (len-- > 0) { - array->WriteBarrier(array->raw_); + array->WriteBarrier(); array++; } } diff --git a/chromium/third_party/blink/renderer/platform/heap/name_traits.h b/chromium/third_party/blink/renderer/platform/heap/name_traits.h new file mode 100644 index 00000000000..bb16f206efa --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/heap/name_traits.h @@ -0,0 +1,31 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_NAME_TRAITS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_NAME_TRAITS_H_ + +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_base.h" + +namespace blink { + +template <typename T> +class NameTrait { + STATIC_ONLY(NameTrait); + + public: + static const char* GetName(const void* obj) { + return GetNameFor(static_cast<const T*>(obj)); + } + + private: + static const char* GetNameFor(const TraceWrapperBase* wrapper_tracable) { + return wrapper_tracable->NameInHeapSnapshot(); + } + + static const char* GetNameFor(...) { return "InternalNode"; } +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_NAME_TRAITS_H_ 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 7f4ca6ef9f7..1fbed846fee 100644 --- a/chromium/third_party/blink/renderer/platform/heap/page_memory.h +++ b/chromium/third_party/blink/renderer/platform/heap/page_memory.h @@ -169,15 +169,6 @@ class PageMemory { WARN_UNUSED_RESULT bool Commit() { reserved_->MarkPageUsed(WritableStart()); - // Check that in-use page isn't also marked as being a non-heap page - // by the current heap's negative cache. That cache is invalidated - // when allocating new pages, but crbug.com/649485 suggests that - // we do get out of sync somehow. - // - // TODO(sof): consider removing check once bug has been diagnosed - // and addressed. - CHECK(!ThreadState::Current()->Heap().IsAddressInHeapDoesNotContainCache( - WritableStart())); return writable_.Commit(); } diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent.h b/chromium/third_party/blink/renderer/platform/heap/persistent.h index b7a40b82ce8..2d4eb64969c 100644 --- a/chromium/third_party/blink/renderer/platform/heap/persistent.h +++ b/chromium/third_party/blink/renderer/platform/heap/persistent.h @@ -581,6 +581,13 @@ class PersistentHeapCollectionBase : public Collection { ~PersistentHeapCollectionBase() { Uninitialize(); } + // Override so we don't copy persistent_node_. + PersistentHeapCollectionBase& operator=( + const PersistentHeapCollectionBase& other) { + Collection::operator=(other); + return *this; + } + // See PersistentBase::registerAsStaticReference() comment. PersistentHeapCollectionBase* RegisterAsStaticReference() { if (persistent_node_) { @@ -611,6 +618,9 @@ class PersistentHeapCollectionBase : public Collection { NO_SANITIZE_ADDRESS void Initialize() { + CHECK(IsMainThread()) << "Persistent heap collections are disabled on " + "non-main threads. Put the heap collection in a " + "Persistent instead."; // FIXME: Derive affinity based on the collection. ThreadState* state = ThreadState::Current(); DCHECK(state->CheckThread()); diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc b/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc index c79d85cc5fd..013939ad924 100644 --- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc +++ b/chromium/third_party/blink/renderer/platform/heap/persistent_node.cc @@ -126,6 +126,29 @@ void PersistentRegion::TracePersistentNodes(Visitor* visitor, #endif } +void PersistentRegion::PrepareForThreadStateTermination() { + DCHECK(!IsMainThread()); + PersistentNodeSlots* slots = slots_; + while (slots) { + for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { + PersistentNode* node = &slots->slot_[i]; + if (node->IsUnused()) + continue; + // It is safe to cast to Persistent<DummyGCBase> because persistent heap + // collections are banned in non-main threads. + Persistent<DummyGCBase>* persistent = + reinterpret_cast<Persistent<DummyGCBase>*>(node->Self()); + DCHECK(persistent); + persistent->Clear(); + DCHECK(node->IsUnused()); + } + slots = slots->next_; + } +#if DCHECK_IS_ON() + DCHECK_EQ(persistent_count_, 0); +#endif +} + bool CrossThreadPersistentRegion::ShouldTracePersistentNode( Visitor* visitor, PersistentNode* node) { @@ -146,9 +169,6 @@ void CrossThreadPersistentRegion::PrepareForThreadStateTermination( // out the underlying heap reference. RecursiveMutexLocker lock(ProcessHeap::CrossThreadPersistentMutex()); - // TODO(sof): consider ways of reducing overhead. (e.g., tracking number of - // active CrossThreadPersistent<>s pointing into the heaps of each ThreadState - // and use that count to bail out early.) PersistentNodeSlots* slots = persistent_region_->slots_; while (slots) { for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { diff --git a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h b/chromium/third_party/blink/renderer/platform/heap/persistent_node.h index a3eb2b117b2..666b81926b0 100644 --- a/chromium/third_party/blink/renderer/platform/heap/persistent_node.h +++ b/chromium/third_party/blink/renderer/platform/heap/persistent_node.h @@ -151,6 +151,7 @@ class PLATFORM_EXPORT PersistentRegion final { Visitor*, ShouldTraceCallback = PersistentRegion::ShouldTracePersistentNode); int NumberOfPersistents(); + void PrepareForThreadStateTermination(); private: friend CrossThreadPersistentRegion; diff --git a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc b/chromium/third_party/blink/renderer/platform/heap/process_heap.cc index 5890dea8cc2..6bf558e3acb 100644 --- a/chromium/third_party/blink/renderer/platform/heap/process_heap.cc +++ b/chromium/third_party/blink/renderer/platform/heap/process_heap.cc @@ -29,7 +29,7 @@ void ProcessHeap::Init() { total_allocated_object_size_ = 0; total_marked_object_size_ = 0; - GCInfoTable::Init(); + GCInfoTable::CreateGlobalTable(); base::SamplingHeapProfiler::SetHooksInstallCallback([]() { HeapAllocHooks::SetAllocationHook(&BlinkGCAllocHook); diff --git a/chromium/third_party/blink/renderer/platform/heap/process_heap.h b/chromium/third_party/blink/renderer/platform/heap/process_heap.h index e9f504e1ac9..70f42f2d287 100644 --- a/chromium/third_party/blink/renderer/platform/heap/process_heap.h +++ b/chromium/third_party/blink/renderer/platform/heap/process_heap.h @@ -23,7 +23,17 @@ class PLATFORM_EXPORT ProcessHeap { static CrossThreadPersistentRegion& GetCrossThreadPersistentRegion(); static CrossThreadPersistentRegion& GetCrossThreadWeakPersistentRegion(); - // Recursive as prepareForThreadStateTermination() clears a PersistentNode's + // Access to the CrossThreadPersistentRegion from multiple threads has to be + // prevented as allocation, freeing, and iteration of nodes may otherwise + // cause data races. + // + // Examples include: + // - Iteration of strong cross-thread Persistents. + // - Iteration and processing of weak cross-thread Persistents. The lock + // needs to span both operations as iteration of weak persistents only + // registers memory regions that are then processed afterwards. + // + // Recursive as PrepareForThreadStateTermination() clears a PersistentNode's // associated Persistent<> -- it in turn freeing the PersistentNode. And both // CrossThreadPersistentRegion operations need a lock on the region before // mutating. 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 7a7edae6823..6a8b96996f2 100644 --- a/chromium/third_party/blink/renderer/platform/heap/thread_state.cc +++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.cc @@ -49,6 +49,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap_buildflags.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_pool.h" #include "third_party/blink/renderer/platform/heap/safe_point.h" @@ -57,7 +58,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/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/stack_util.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" @@ -88,6 +89,8 @@ const size_t kDefaultAllocatedObjectSizeThreshold = 100 * 1024; // doesn't cause jank even though it is scheduled as a normal task. const double kIncrementalMarkingStepDurationInSeconds = 0.001; +constexpr size_t kMaxTerminationGCLoops = 20; + namespace { const char* GcReasonString(BlinkGC::GCReason reason) { @@ -106,6 +109,8 @@ const char* GcReasonString(BlinkGC::GCReason reason) { return "PageNavigationGC"; case BlinkGC::kThreadTerminationGC: return "ThreadTerminationGC"; + case BlinkGC::kTesting: + return "TestingGC"; } return "<Unknown>"; } @@ -155,7 +160,6 @@ ThreadState::ThreadState() no_allocation_count_(0), gc_forbidden_count_(0), mixins_being_constructed_count_(0), - accumulated_sweeping_time_(0), object_resurrection_forbidden_(false), in_atomic_pause_(false), gc_mixin_marker_(nullptr), @@ -165,7 +169,7 @@ ThreadState::ThreadState() trace_dom_wrappers_(nullptr), invalidate_dead_objects_in_wrappers_marking_deque_(nullptr), perform_cleanup_(nullptr), - wrapper_tracing_in_progress_(false), + wrapper_tracing_(false), incremental_marking_(false), #if defined(ADDRESS_SANITIZER) asan_fake_stack_(__asan_get_current_fake_stack()), @@ -234,9 +238,23 @@ void ThreadState::RunTerminationGC() { old_count = current_count; current_count = GetPersistentRegion()->NumberOfPersistents(); } + // We should not have any persistents left when getting to this point, - // if we have it is probably a bug so adding a debug ASSERT to catch this. - DCHECK(!current_count); + // if we have it is a bug, and we have a reference cycle or a missing + // RegisterAsStaticReference. Clearing out all the Persistents will avoid + // stale pointers and gets them reported as nullptr dereferences. + if (current_count) { + for (size_t i = 0; i < kMaxTerminationGCLoops && + GetPersistentRegion()->NumberOfPersistents(); + i++) { + GetPersistentRegion()->PrepareForThreadStateTermination(); + CollectGarbage(BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking, + BlinkGC::kEagerSweeping, BlinkGC::kThreadTerminationGC); + } + } + + CHECK(!GetPersistentRegion()->NumberOfPersistents()); + // All of pre-finalizers should be consumed. DCHECK(ordered_pre_finalizers_.IsEmpty()); CHECK_EQ(GcState(), kNoGCScheduled); @@ -319,10 +337,16 @@ void ThreadState::VisitStack(MarkingVisitor* visitor) { } void ThreadState::VisitPersistents(Visitor* visitor) { - ProcessHeap::GetCrossThreadPersistentRegion().TracePersistentNodes(visitor); + { + // See ProcessHeap::CrossThreadPersistentMutex(). + RecursiveMutexLocker persistent_lock( + ProcessHeap::CrossThreadPersistentMutex()); + ProcessHeap::GetCrossThreadPersistentRegion().TracePersistentNodes(visitor); + } persistent_region_->TracePersistentNodes(visitor); if (trace_dom_wrappers_) { - TRACE_EVENT0("blink_gc", "V8GCController::traceDOMWrappers"); + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), ThreadHeapStatsCollector::kVisitDOMWrappers); trace_dom_wrappers_(isolate_, visitor); } } @@ -421,10 +445,10 @@ bool ThreadState::JudgeGCThreshold(size_t allocated_object_size_threshold, bool ThreadState::ShouldScheduleIncrementalMarking() const { #if BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) - // TODO(mlippautz): For now immediately schedule incremental marking if - // the runtime flag is provided, basically exercising a stress test. + // TODO(mlippautz): For now only schedule incremental marking if + // the runtime stress flag is provided. return GcState() == kNoGCScheduled && - RuntimeEnabledFeatures::HeapIncrementalMarkingEnabled(); + RuntimeEnabledFeatures::HeapIncrementalMarkingStressEnabled(); #else return false; #endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) @@ -470,6 +494,7 @@ void ThreadState::ScheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType gc_type) { VLOG(2) << "[state:" << this << "] ScheduleV8FollowupGCIfNeeded: v8_gc_type=" << ((gc_type == BlinkGC::kV8MajorGC) ? "MajorGC" : "MinorGC"); DCHECK(CheckThread()); + DCHECK_EQ(BlinkGC::kV8MajorGC, gc_type); ThreadHeap::ReportMemoryUsageForTracing(); if (IsGCForbidden()) @@ -481,14 +506,13 @@ void ThreadState::ScheduleV8FollowupGCIfNeeded(BlinkGC::V8GCType gc_type) { DCHECK(!IsSweepingInProgress()); DCHECK(!SweepForbidden()); - if ((gc_type == BlinkGC::kV8MajorGC && ShouldForceMemoryPressureGC()) || - ShouldScheduleV8FollowupGC()) { + if (ShouldForceMemoryPressureGC() || ShouldScheduleV8FollowupGC()) { VLOG(2) << "[state:" << this << "] " << "ScheduleV8FollowupGCIfNeeded: Scheduled precise GC"; SchedulePreciseGC(); return; } - if (gc_type == BlinkGC::kV8MajorGC && ShouldScheduleIdleGC()) { + if (ShouldScheduleIdleGC()) { VLOG(2) << "[state:" << this << "] " << "ScheduleV8FollowupGCIfNeeded: Scheduled idle GC"; ScheduleIdleGC(); @@ -504,8 +528,8 @@ void ThreadState::WillStartV8GC(BlinkGC::V8GCType gc_type) { // completeSweep() here, because gcPrologue for a major GC is called // not at the point where the major GC started but at the point where // the major GC requests object grouping. - if (gc_type == BlinkGC::kV8MajorGC) - CompleteSweep(); + DCHECK_EQ(BlinkGC::kV8MajorGC, gc_type); + CompleteSweep(); } void ThreadState::SchedulePageNavigationGCIfNeeded( @@ -650,20 +674,19 @@ void ThreadState::PerformIdleLazySweep(double deadline_seconds) { RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS( GetIsolate(), RuntimeCallStats::CounterId::kPerformIdleLazySweep); - TRACE_EVENT1("blink_gc,devtools.timeline", - "ThreadState::performIdleLazySweep", "idleDeltaInSeconds", - deadline_seconds - CurrentTimeTicksInSeconds()); - - AtomicPauseScope atomic_pause_scope(this); - SweepForbiddenScope scope(this); - - double start_time = WTF::CurrentTimeTicksInMilliseconds(); - bool sweep_completed = Heap().AdvanceLazySweep(deadline_seconds); - // We couldn't finish the sweeping within the deadline. - // We request another idle task for the remaining sweeping. - if (!sweep_completed) - ScheduleIdleLazySweep(); - AccumulateSweepingTime(WTF::CurrentTimeTicksInMilliseconds() - start_time); + bool sweep_completed = false; + { + AtomicPauseScope atomic_pause_scope(this); + SweepForbiddenScope scope(this); + ThreadHeapStatsCollector::EnabledScope stats_scope( + Heap().stats_collector(), ThreadHeapStatsCollector::kLazySweepInIdle, + "idleDeltaInSeconds", deadline_seconds - CurrentTimeTicksInSeconds()); + sweep_completed = Heap().AdvanceLazySweep(deadline_seconds); + // We couldn't finish the sweeping within the deadline. + // We request another idle task for the remaining sweeping. + if (!sweep_completed) + ScheduleIdleLazySweep(); + } if (sweep_completed) PostSweep(); @@ -877,6 +900,7 @@ void ThreadState::PreSweep(BlinkGC::MarkingType marking_type, gc_state_ = kNoGCScheduled; SetGCPhase(GCPhase::kSweeping); SetGCPhase(GCPhase::kNone); + Heap().stats_collector()->Stop(); return; } @@ -889,8 +913,6 @@ void ThreadState::PreSweep(BlinkGC::MarkingType marking_type, // a dead object gets resurrected. InvokePreFinalizers(); - accumulated_sweeping_time_ = 0; - EagerSweep(); // Any sweep compaction must happen after pre-finalizers and eager @@ -920,12 +942,10 @@ void ThreadState::EagerSweep() { // by lazy sweeping. Keep those in a designated heap and sweep it // eagerly. DCHECK(IsSweepingInProgress()); - SweepForbiddenScope scope(this); - - double start_time = WTF::CurrentTimeTicksInMilliseconds(); + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), ThreadHeapStatsCollector::kEagerSweep); Heap().Arena(BlinkGC::kEagerSweepArenaIndex)->CompleteSweep(); - AccumulateSweepingTime(WTF::CurrentTimeTicksInMilliseconds() - start_time); } void ThreadState::CompleteSweep() { @@ -940,24 +960,13 @@ void ThreadState::CompleteSweep() { if (SweepForbidden()) return; - AtomicPauseScope atomic_pause_scope(this); - SweepForbiddenScope scope(this); - - TRACE_EVENT0("blink_gc,devtools.timeline", "ThreadState::completeSweep"); - double start_time = WTF::CurrentTimeTicksInMilliseconds(); - - Heap().CompleteSweep(); - - double time_for_complete_sweep = - WTF::CurrentTimeTicksInMilliseconds() - start_time; - AccumulateSweepingTime(time_for_complete_sweep); - - if (IsMainThread()) { - DEFINE_STATIC_LOCAL(CustomCountHistogram, complete_sweep_histogram, - ("BlinkGC.CompleteSweep", 1, 10 * 1000, 50)); - complete_sweep_histogram.Count(time_for_complete_sweep); + { + AtomicPauseScope atomic_pause_scope(this); + SweepForbiddenScope scope(this); + ThreadHeapStatsCollector::EnabledScope stats_scope( + Heap().stats_collector(), ThreadHeapStatsCollector::kCompleteSweep); + Heap().CompleteSweep(); } - PostSweep(); } @@ -970,13 +979,44 @@ BlinkGCObserver::~BlinkGCObserver() { thread_state_->RemoveObserver(this); } +namespace { + +void UpdateHistograms(const ThreadHeapStatsCollector::Event& event) { + DEFINE_THREAD_SAFE_STATIC_LOCAL( + EnumerationHistogram, gc_reason_histogram, + ("BlinkGC.GCReason", BlinkGC::kLastGCReason + 1)); + gc_reason_histogram.Count(event.reason); + + // TODO(mlippautz): Update name of this histogram. + DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, marking_time_histogram, + ("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); + marking_time_histogram.Count(event.marking_time_in_ms()); + + DEFINE_STATIC_LOCAL(CustomCountHistogram, complete_sweep_histogram, + ("BlinkGC.CompleteSweep", 1, 10 * 1000, 50)); + complete_sweep_histogram.Count( + event.scope_data[ThreadHeapStatsCollector::kCompleteSweep]); + + DEFINE_STATIC_LOCAL(CustomCountHistogram, time_for_sweep_histogram, + ("BlinkGC.TimeForSweepingAllObjects", 1, 10 * 1000, 50)); + time_for_sweep_histogram.Count(event.sweeping_time_in_ms()); + + DEFINE_STATIC_LOCAL( + CustomCountHistogram, pre_finalizers_histogram, + ("BlinkGC.TimeForInvokingPreFinalizers", 1, 10 * 1000, 50)); + pre_finalizers_histogram.Count( + event.scope_data[ThreadHeapStatsCollector::kInvokePreFinalizers]); +} + +} // namespace + void ThreadState::PostSweep() { DCHECK(CheckThread()); ThreadHeap::ReportMemoryUsageForTracing(); if (IsMainThread()) { - double collection_rate = - 1.0 - heap_->HeapStats().LiveObjectRateSinceLastGC(); + ThreadHeapStats& stats = heap_->HeapStats(); + double collection_rate = 1.0 - stats.LiveObjectRateSinceLastGC(); TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("blink_gc"), "ThreadState::collectionRate", static_cast<int>(100 * collection_rate)); @@ -985,26 +1025,23 @@ void ThreadState::PostSweep() { << " PostSweep: collection_rate: " << std::setprecision(2) << (100 * collection_rate) << "%"; - // ThreadHeap::markedObjectSize() may be underestimated here if any other - // thread has not yet finished lazy sweeping. - heap_->HeapStats().SetMarkedObjectSizeAtLastCompleteSweep( - heap_->HeapStats().MarkedObjectSize()); + stats.SetMarkedObjectSizeAtLastCompleteSweep(stats.MarkedObjectSize()); + + stats.SetEstimatedMarkingTimePerByte( + stats.MarkedObjectSize() + ? (current_gc_data_.marking_time_in_milliseconds / 1000 / + stats.MarkedObjectSize()) + : 0); DEFINE_STATIC_LOCAL(CustomCountHistogram, object_size_before_gc_histogram, ("BlinkGC.ObjectSizeBeforeGC", 1, 4 * 1024 * 1024, 50)); - object_size_before_gc_histogram.Count( - heap_->HeapStats().ObjectSizeAtLastGC() / 1024); + object_size_before_gc_histogram.Count(stats.ObjectSizeAtLastGC() / 1024); DEFINE_STATIC_LOCAL(CustomCountHistogram, object_size_after_gc_histogram, ("BlinkGC.ObjectSizeAfterGC", 1, 4 * 1024 * 1024, 50)); - object_size_after_gc_histogram.Count(heap_->HeapStats().MarkedObjectSize() / - 1024); + object_size_after_gc_histogram.Count(stats.MarkedObjectSize() / 1024); DEFINE_STATIC_LOCAL(CustomCountHistogram, collection_rate_histogram, ("BlinkGC.CollectionRate", 1, 100, 20)); collection_rate_histogram.Count(static_cast<int>(100 * collection_rate)); - DEFINE_STATIC_LOCAL( - CustomCountHistogram, time_for_sweep_histogram, - ("BlinkGC.TimeForSweepingAllObjects", 1, 10 * 1000, 50)); - time_for_sweep_histogram.Count(accumulated_sweeping_time_); #define COUNT_COLLECTION_RATE_HISTOGRAM_BY_GC_REASON(GCReason) \ case BlinkGC::k##GCReason: { \ @@ -1032,8 +1069,12 @@ void ThreadState::PostSweep() { gc_age_++; - for (const auto& observer : observers_) + for (auto* const observer : observers_) observer->OnCompleteSweepDone(); + + Heap().stats_collector()->Stop(); + if (IsMainThread()) + UpdateHistograms(Heap().stats_collector()->previous()); } void ThreadState::SafePoint(BlinkGC::StackState stack_state) { @@ -1198,15 +1239,14 @@ void ThreadState::leaveStaticReferenceRegistrationDisabledScope() { void ThreadState::InvokePreFinalizers() { DCHECK(CheckThread()); DCHECK(!SweepForbidden()); - TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), ThreadHeapStatsCollector::kInvokePreFinalizers); SweepForbiddenScope sweep_forbidden(this); // Pre finalizers may access unmarked objects but are forbidden from // ressurecting them. ObjectResurrectionForbiddenScope object_resurrection_forbidden(this); - double start_time = WTF::CurrentTimeTicksInMilliseconds(); - // Call the prefinalizers in the opposite order to their registration. // // LinkedHashSet does not support modification during iteration, so @@ -1224,19 +1264,14 @@ void ThreadState::InvokePreFinalizers() { if ((pre_finalizer.second)(pre_finalizer.first)) ordered_pre_finalizers_.erase(pre_finalizer); } - if (IsMainThread()) { - double time_for_invoking_pre_finalizers = - WTF::CurrentTimeTicksInMilliseconds() - start_time; - DEFINE_STATIC_LOCAL( - CustomCountHistogram, pre_finalizers_histogram, - ("BlinkGC.TimeForInvokingPreFinalizers", 1, 10 * 1000, 50)); - pre_finalizers_histogram.Count(time_for_invoking_pre_finalizers); - } } // static base::subtle::AtomicWord ThreadState::incremental_marking_counter_ = 0; +// static +base::subtle::AtomicWord ThreadState::wrapper_tracing_counter_ = 0; + void ThreadState::EnableIncrementalMarkingBarrier() { CHECK(!IsIncrementalMarking()); base::subtle::Barrier_AtomicIncrement(&incremental_marking_counter_, 1); @@ -1249,28 +1284,47 @@ void ThreadState::DisableIncrementalMarkingBarrier() { SetIncrementalMarking(false); } +void ThreadState::EnableWrapperTracingBarrier() { + CHECK(!IsWrapperTracing()); + base::subtle::Barrier_AtomicIncrement(&wrapper_tracing_counter_, 1); + SetWrapperTracing(true); +} + +void ThreadState::DisableWrapperTracingBarrier() { + CHECK(IsWrapperTracing()); + base::subtle::Barrier_AtomicIncrement(&wrapper_tracing_counter_, -1); + SetWrapperTracing(false); +} + void ThreadState::IncrementalMarkingStart() { VLOG(2) << "[state:" << this << "] " << "IncrementalMarking: Start"; CompleteSweep(); - AtomicPauseScope atomic_pause_scope(this); - RecursiveMutexLocker persistent_lock( - ProcessHeap::CrossThreadPersistentMutex()); - MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack, - BlinkGC::kIncrementalMarking, BlinkGC::kIdleGC); - MarkPhaseVisitRoots(); - EnableIncrementalMarkingBarrier(); - ScheduleIncrementalMarkingStep(); - DCHECK(IsMarkingInProgress()); + // TODO(mlippautz): Replace this with a proper reason once incremental marking + // is actually scheduled in production. + Heap().stats_collector()->Start(BlinkGC::kTesting); + { + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kIncrementalMarkingStartMarking); + AtomicPauseScope atomic_pause_scope(this); + MarkPhasePrologue(BlinkGC::kNoHeapPointersOnStack, + BlinkGC::kIncrementalMarking, BlinkGC::kTesting); + MarkPhaseVisitRoots(); + EnableIncrementalMarkingBarrier(); + ScheduleIncrementalMarkingStep(); + DCHECK(IsMarkingInProgress()); + } } void ThreadState::IncrementalMarkingStep() { + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kIncrementalMarkingStep); VLOG(2) << "[state:" << this << "] " << "IncrementalMarking: Step"; AtomicPauseScope atomic_pause_scope(this); DCHECK(IsMarkingInProgress()); - RecursiveMutexLocker persistent_lock( - ProcessHeap::CrossThreadPersistentMutex()); bool complete = MarkPhaseAdvanceMarking( CurrentTimeTicksInSeconds() + kIncrementalMarkingStepDurationInSeconds); if (complete) @@ -1281,22 +1335,30 @@ void ThreadState::IncrementalMarkingStep() { } void ThreadState::IncrementalMarkingFinalize() { - VLOG(2) << "[state:" << this << "] " - << "IncrementalMarking: Finalize"; - SetGCState(kNoGCScheduled); - DisableIncrementalMarkingBarrier(); - AtomicPauseScope atomic_pause_scope(this); - DCHECK(IsMarkingInProgress()); - RecursiveMutexLocker persistent_lock( - ProcessHeap::CrossThreadPersistentMutex()); - MarkPhaseVisitRoots(); - bool complete = - MarkPhaseAdvanceMarking(std::numeric_limits<double>::infinity()); - CHECK(complete); - MarkPhaseEpilogue(current_gc_data_.marking_type); - PreSweep(current_gc_data_.marking_type, BlinkGC::kLazySweeping); - DCHECK(IsSweepingInProgress()); - DCHECK_EQ(GcState(), kNoGCScheduled); + { + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kIncrementalMarkingFinalize); + VLOG(2) << "[state:" << this << "] " + << "IncrementalMarking: Finalize"; + SetGCState(kNoGCScheduled); + DisableIncrementalMarkingBarrier(); + AtomicPauseScope atomic_pause_scope(this); + DCHECK(IsMarkingInProgress()); + { + ThreadHeapStatsCollector::Scope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kIncrementalMarkingFinalizeMarking); + MarkPhaseVisitRoots(); + bool complete = + MarkPhaseAdvanceMarking(std::numeric_limits<double>::infinity()); + CHECK(complete); + MarkPhaseEpilogue(current_gc_data_.marking_type); + } + PreSweep(current_gc_data_.marking_type, BlinkGC::kLazySweeping); + DCHECK(IsSweepingInProgress()); + DCHECK_EQ(GcState(), kNoGCScheduled); + } } void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, @@ -1312,7 +1374,6 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, double start_total_collect_garbage_time = WTF::CurrentTimeTicksInMilliseconds(); - RUNTIME_CALL_TIMER_SCOPE_IF_ISOLATE_EXISTS( GetIsolate(), RuntimeCallStats::CounterId::kCollectGarbage); @@ -1326,8 +1387,8 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, } // We don't want floating garbage for the specific garbage collection types - // mentioned below. In this case we will follow up with a regular full garbage - // collection. + // mentioned below. In this case we will follow up with a regular full + // garbage collection. const bool should_do_full_gc = !was_incremental_marking || reason == BlinkGC::kForcedGC || reason == BlinkGC::kMemoryPressureGC || @@ -1335,19 +1396,14 @@ void ThreadState::CollectGarbage(BlinkGC::StackState stack_state, if (should_do_full_gc) { CompleteSweep(); SetGCState(kNoGCScheduled); + Heap().stats_collector()->Start(reason); AtomicPauseScope atomic_pause_scope(this); { - TRACE_EVENT2("blink_gc,devtools.timeline", "BlinkGCMarking", - "lazySweeping", sweeping_type == BlinkGC::kLazySweeping, - "gcReason", GcReasonString(reason)); - // Access to the CrossThreadPersistentRegion has to be prevented - // while in the marking phase because otherwise other threads may - // allocate or free PersistentNodes and we can't handle - // that. Grabbing this lock also prevents non-attached threads - // from accessing any GCed heap while a GC runs. - RecursiveMutexLocker persistent_lock( - ProcessHeap::CrossThreadPersistentMutex()); - + ThreadHeapStatsCollector::EnabledScope stats_scope( + Heap().stats_collector(), + ThreadHeapStatsCollector::kAtomicPhaseMarking, "lazySweeping", + sweeping_type == BlinkGC::kLazySweeping ? "yes" : "no", "gcReason", + GcReasonString(reason)); MarkPhasePrologue(stack_state, marking_type, reason); MarkPhaseVisitRoots(); CHECK(MarkPhaseAdvanceMarking(std::numeric_limits<double>::infinity())); @@ -1416,12 +1472,8 @@ void ThreadState::MarkPhasePrologue(BlinkGC::StackState stack_state, DCHECK(InAtomicMarkingPause()); Heap().MakeConsistentForGC(); - Heap().FlushHeapDoesNotContainCacheIfNeeded(); Heap().ClearArenaAges(); - current_gc_data_.marked_object_size = - Heap().HeapStats().AllocatedObjectSize() + - Heap().HeapStats().MarkedObjectSize(); if (marking_type != BlinkGC::kTakeSnapshot) Heap().ResetHeapCounters(); } @@ -1459,6 +1511,15 @@ bool ThreadState::MarkPhaseAdvanceMarking(double deadline_seconds) { return complete; } +bool ThreadState::ShouldVerifyMarking() const { + bool should_verify_marking = + RuntimeEnabledFeatures::HeapIncrementalMarkingStressEnabled(); +#if BUILDFLAG(BLINK_HEAP_VERIFICATION) + should_verify_marking = true; +#endif // BLINK_HEAP_VERIFICATION + return should_verify_marking; +} + void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) { Visitor* visitor = current_gc_data_.visitor.get(); // Finish marking of not-fully-constructed objects. @@ -1466,21 +1527,19 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) { CHECK(Heap().AdvanceMarkingStackProcessing( visitor, std::numeric_limits<double>::infinity())); - VisitWeakPersistents(visitor); - Heap().WeakProcessing(visitor); + { + // See ProcessHeap::CrossThreadPersistentMutex(). + RecursiveMutexLocker persistent_lock( + ProcessHeap::CrossThreadPersistentMutex()); + VisitWeakPersistents(visitor); + Heap().WeakProcessing(visitor); + } Heap().DecommitCallbackStacks(); current_gc_data_.visitor.reset(); -#if BUILDFLAG(BLINK_HEAP_VERIFICATION) - VerifyMarking(marking_type); -#endif // BLINK_HEAP_VERIFICATION - - Heap().HeapStats().SetEstimatedMarkingTimePerByte( - current_gc_data_.marked_object_size - ? (current_gc_data_.marking_time_in_milliseconds / 1000 / - current_gc_data_.marked_object_size) - : 0); + if (ShouldVerifyMarking()) + VerifyMarking(marking_type); ThreadHeap::ReportMemoryUsageHistogram(); WTF::Partitions::ReportMemoryUsageHistogram(); @@ -1488,9 +1547,6 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) { if (invalidate_dead_objects_in_wrappers_marking_deque_) invalidate_dead_objects_in_wrappers_marking_deque_(isolate_); - DEFINE_THREAD_SAFE_STATIC_LOCAL(CustomCountHistogram, marking_time_histogram, - ("BlinkGC.CollectGarbage", 0, 10 * 1000, 50)); - marking_time_histogram.Count(current_gc_data_.marking_time_in_milliseconds); DEFINE_THREAD_SAFE_STATIC_LOCAL( CustomCountHistogram, total_object_space_histogram, ("BlinkGC.TotalObjectSpace", 0, 4 * 1024 * 1024, 50)); @@ -1501,10 +1557,6 @@ void ThreadState::MarkPhaseEpilogue(BlinkGC::MarkingType marking_type) { ("BlinkGC.TotalAllocatedSpace", 0, 4 * 1024 * 1024, 50)); total_allocated_space_histogram.Count(ProcessHeap::TotalAllocatedSpace() / 1024); - DEFINE_THREAD_SAFE_STATIC_LOCAL( - EnumerationHistogram, gc_reason_histogram, - ("BlinkGC.GCReason", BlinkGC::kLastGCReason + 1)); - gc_reason_histogram.Count(current_gc_data_.reason); } void ThreadState::VerifyMarking(BlinkGC::MarkingType marking_type) { 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 6a01829c573..58949fd544d 100644 --- a/chromium/third_party/blink/renderer/platform/heap/thread_state.h +++ b/chromium/third_party/blink/renderer/platform/heap/thread_state.h @@ -220,11 +220,18 @@ class PLATFORM_EXPORT ThreadState { // Returns true if any thread is currently incremental marking its heap and // false otherwise. For an exact check use // ThreadState::IsIncrementalMarking(). - static bool IsAnyIncrementalMarking() { + ALWAYS_INLINE static bool IsAnyIncrementalMarking() { // Stores use full barrier to allow using the simplest relaxed load here. return base::subtle::NoBarrier_Load(&incremental_marking_counter_) > 0; } + // Returns true if any thread is currently incremental marking its heap and + // false otherwise. For an exact check use ThreadState::IsWrapperTracing(). + static bool IsAnyWrapperTracing() { + // Stores use full barrier to allow using the simplest relaxed load here. + return base::subtle::NoBarrier_Load(&wrapper_tracing_counter_) > 0; + } + static void AttachMainThread(); // Associate ThreadState object with the current thread. After this @@ -277,6 +284,9 @@ class PLATFORM_EXPORT ThreadState { bool IsMarkingInProgress() const { return gc_phase_ == GCPhase::kMarking; } bool IsSweepingInProgress() const { return gc_phase_ == GCPhase::kSweeping; } + void EnableWrapperTracingBarrier(); + void DisableWrapperTracingBarrier(); + // Incremental GC. void ScheduleIncrementalMarkingStart(); @@ -364,10 +374,8 @@ class PLATFORM_EXPORT ThreadState { return in_atomic_pause() && IsSweepingInProgress(); } - bool WrapperTracingInProgress() const { return wrapper_tracing_in_progress_; } - void SetWrapperTracingInProgress(bool value) { - wrapper_tracing_in_progress_ = value; - } + bool IsWrapperTracing() const { return wrapper_tracing_; } + void SetWrapperTracing(bool value) { wrapper_tracing_ = value; } bool IsIncrementalMarking() const { return incremental_marking_; } void SetIncrementalMarking(bool value) { incremental_marking_ = value; } @@ -522,10 +530,6 @@ class PLATFORM_EXPORT ThreadState { } } - void AccumulateSweepingTime(double time) { - accumulated_sweeping_time_ += time; - } - void FreePersistentNode(PersistentRegion*, PersistentNode*); using PersistentClearCallback = void (*)(void*); @@ -594,6 +598,9 @@ class PLATFORM_EXPORT ThreadState { // marking and decremented upon finishing. static base::subtle::AtomicWord incremental_marking_counter_; + // Same semantic as |incremental_marking_counter_|. + static base::subtle::AtomicWord wrapper_tracing_counter_; + ThreadState(); ~ThreadState(); @@ -602,6 +609,8 @@ class PLATFORM_EXPORT ThreadState { safe_point_scope_marker_ = nullptr; } + bool ShouldVerifyMarking() const; + // shouldScheduleIdleGC and shouldForceConservativeGC // implement the heuristics that are used to determine when to collect // garbage. @@ -687,7 +696,6 @@ class PLATFORM_EXPORT ThreadState { size_t no_allocation_count_; size_t gc_forbidden_count_; size_t mixins_being_constructed_count_; - double accumulated_sweeping_time_; bool object_resurrection_forbidden_; bool in_atomic_pause_; @@ -708,7 +716,7 @@ class PLATFORM_EXPORT ThreadState { void (*trace_dom_wrappers_)(v8::Isolate*, Visitor*); void (*invalidate_dead_objects_in_wrappers_marking_deque_)(v8::Isolate*); void (*perform_cleanup_)(v8::Isolate*); - bool wrapper_tracing_in_progress_; + bool wrapper_tracing_; bool incremental_marking_; #if defined(ADDRESS_SANITIZER) @@ -737,7 +745,6 @@ class PLATFORM_EXPORT ThreadState { BlinkGC::MarkingType marking_type; BlinkGC::GCReason reason; double marking_time_in_milliseconds; - size_t marked_object_size; std::unique_ptr<MarkingVisitor> visitor; }; GCData current_gc_data_; 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 a746a221aea..87c81a07824 100644 --- a/chromium/third_party/blink/renderer/platform/heap/trace_traits.h +++ b/chromium/third_party/blink/renderer/platform/heap/trace_traits.h @@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_HEAP_TRACE_TRAITS_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable_visitor.h" #include "third_party/blink/renderer/platform/heap/gc_info.h" #include "third_party/blink/renderer/platform/heap/heap.h" @@ -18,7 +19,6 @@ #include "third_party/blink/renderer/platform/wtf/hash_table.h" #include "third_party/blink/renderer/platform/wtf/linked_hash_set.h" #include "third_party/blink/renderer/platform/wtf/list_hash_set.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" namespace blink { @@ -55,9 +55,7 @@ class AdjustPointerTrait<T, false> { } static TraceWrapperDescriptor GetTraceWrapperDescriptor(void* self) { - return {self, TraceTrait<T>::TraceWrappers, - ScriptWrappableVisitor::MissedWriteBarrier<T>, - ScriptWrappableVisitor::NameCallback<T>}; + return {self, TraceTrait<T>::TraceWrappers}; } static HeapObjectHeader* GetHeapObjectHeader(void* self) { @@ -289,17 +287,18 @@ class TraceTrait<std::pair<T, U>> { } }; -// While using Optional<T> with garbage-collected types is generally disallowed -// by the OptionalGarbageCollected check in blink_gc_plugin, garbage-collected -// containers such as HeapVector are allowed and need to be traced. +// While using base::Optional<T> with garbage-collected types is generally +// disallowed by the OptionalGarbageCollected check in blink_gc_plugin, +// garbage-collected containers such as HeapVector are allowed and need to be +// traced. template <typename T> -class TraceTrait<WTF::Optional<T>> { +class TraceTrait<base::Optional<T>> { STATIC_ONLY(TraceTrait); public: template <typename VisitorDispatcher> - static void Trace(VisitorDispatcher visitor, WTF::Optional<T>* optional) { - if (*optional != WTF::nullopt) { + static void Trace(VisitorDispatcher visitor, base::Optional<T>* optional) { + if (*optional != base::nullopt) { TraceIfEnabled<T, WTF::IsTraceable<T>::value>::Trace(visitor, optional->value()); } diff --git a/chromium/third_party/blink/renderer/platform/heap/visitor.h b/chromium/third_party/blink/renderer/platform/heap/visitor.h index 159e40106f9..ee3ad9dc49a 100644 --- a/chromium/third_party/blink/renderer/platform/heap/visitor.h +++ b/chromium/third_party/blink/renderer/platform/heap/visitor.h @@ -39,19 +39,25 @@ #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/hash_traits.h" #include "third_party/blink/renderer/platform/wtf/type_traits.h" +#include "v8/include/v8.h" namespace blink { template <typename T> class GarbageCollected; template <typename T> +class DOMWrapperMap; +template <typename T> class TraceTrait; class ThreadState; class Visitor; template <typename T> class SameThreadCheckedMember; +class ScriptWrappable; template <typename T> class TraceWrapperMember; +template <typename T> +class TraceWrapperV8Reference; // The TraceMethodDelegate is used to convert a trace method for type T to a // TraceCallback. This allows us to pass a type's trace method as a parameter @@ -86,11 +92,6 @@ class PLATFORM_EXPORT Visitor { } template <typename T> - void Trace(const TraceWrapperMember<T>& t) { - Trace(*(static_cast<const Member<T>*>(&t))); - } - - template <typename T> void Trace(const SameThreadCheckedMember<T>& t) { Trace(*(static_cast<const Member<T>*>(&t))); } @@ -110,8 +111,7 @@ class PLATFORM_EXPORT Visitor { if (!t) return; Visit(const_cast<void*>(reinterpret_cast<const void*>(t)), - TraceTrait<T>::GetTraceDescriptor( - const_cast<void*>(reinterpret_cast<const void*>(t)))); + TraceDescriptorFor(t)); } template <typename T> @@ -124,8 +124,7 @@ class PLATFORM_EXPORT Visitor { return; VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store), reinterpret_cast<void**>(backing_store_slot), - TraceTrait<T>::GetTraceDescriptor( - reinterpret_cast<void*>(backing_store))); + TraceDescriptorFor(backing_store)); } template <typename T> @@ -208,10 +207,50 @@ class PLATFORM_EXPORT Visitor { &TraceMethodDelegate<T, method>::Trampoline); } + // Cross-component tracing interface. + + template <typename T> + void Trace(const TraceWrapperMember<T>& t) { + DCHECK(!t.IsHashTableDeletedValue()); + TraceWithWrappers(t.Get()); + } + + template <typename T> + void TraceWithWrappers(T* t) { + static_assert(sizeof(T), "T must be fully defined"); + static_assert(IsGarbageCollectedType<T>::value, + "T needs to be a garbage collected object"); + if (!t) + return; + + // Dispatch two both, the TraceDescritpor and the TraceWrapperDescriptor, + // versions of the visitor. This way the wrapper-tracing world can ignore + // the TraceDescriptor versions. + Visit(const_cast<void*>(reinterpret_cast<const void*>(t)), + TraceDescriptorFor(t)); + Visit(const_cast<void*>(reinterpret_cast<const void*>(t)), + TraceWrapperDescriptorFor(t)); + } + + void Trace(DOMWrapperMap<ScriptWrappable>* wrapper_map, + const ScriptWrappable* key) { + Visit(wrapper_map, key); + } + + template <typename V8Type> + void Trace(const TraceWrapperV8Reference<V8Type>& v8reference) { + Visit(v8reference.template Cast<v8::Value>()); + } + // Dynamic visitor interface. // Visits an object through a strong reference. virtual void Visit(void*, TraceDescriptor) = 0; + // Subgraph of objects that are interested in wrappers. Note that the same + // object is also passed to Visit(void*, TraceDescriptor). + // TODO(mlippautz): Remove this visit method once wrapper tracing also uses + // Trace() instead of TraceWrappers(). + virtual void Visit(void*, TraceWrapperDescriptor) = 0; // Visits an object through a weak reference. virtual void VisitWeak(void*, void**, TraceDescriptor, WeakCallback) = 0; @@ -225,6 +264,12 @@ class PLATFORM_EXPORT Visitor { void*) = 0; virtual void VisitBackingStoreOnly(void*, void**) = 0; + // Visits cross-component references to V8. + + virtual void Visit(const TraceWrapperV8Reference<v8::Value>&) = 0; + virtual void Visit(DOMWrapperMap<ScriptWrappable>*, + const ScriptWrappable* key) = 0; + // Registers backing store pointers so that they can be moved and properly // updated. virtual void RegisterBackingStoreCallback(void* backing_store, @@ -247,6 +292,18 @@ class PLATFORM_EXPORT Visitor { // WeakMember elements though. virtual void RegisterWeakCallback(void* closure, WeakCallback) = 0; + protected: + template <typename T> + static inline TraceDescriptor TraceDescriptorFor(const T* traceable) { + return TraceTrait<T>::GetTraceDescriptor(const_cast<T*>(traceable)); + } + + template <typename T> + static inline TraceWrapperDescriptor TraceWrapperDescriptorFor( + const T* traceable) { + return TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable)); + } + private: template <typename T> static void HandleWeakCell(Visitor* self, void*); diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/DEPS b/chromium/third_party/blink/renderer/platform/image-decoders/DEPS index 3c137cbce31..24c3c139d17 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/DEPS +++ b/chromium/third_party/blink/renderer/platform/image-decoders/DEPS @@ -1,3 +1,17 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/image-decoders", + + # Dependencies. "+cc/paint/image_animation_count.h", -]
\ No newline at end of file + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h index 504d556c1e9..c94f7eaae0e 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h +++ b/chromium/third_party/blink/renderer/platform/image-decoders/gif/gif_image_decoder.h @@ -73,7 +73,7 @@ class PLATFORM_EXPORT GIFImageDecoder final : public ImageDecoder { private: // ImageDecoder: void ClearFrameBuffer(size_t frame_index) override; - virtual void DecodeSize() { Parse(kGIFSizeQuery); } + void DecodeSize() override { Parse(kGIFSizeQuery); } size_t DecodeFrameCount() override; void InitializeNewFrame(size_t) override; void Decode(size_t) override; 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 c3da2e76b9f..b7730cabc07 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 @@ -147,7 +147,9 @@ ImageFrame* ImageDecoder::DecodeFrameBufferAtIndex(size_t index) { } if (!has_histogrammed_color_space_) { - BitmapImageMetrics::CountImageGammaAndGamut(embedded_color_space_.get()); + BitmapImageMetrics::CountImageGammaAndGamut( + embedded_color_profile_ ? embedded_color_profile_->GetProfile() + : nullptr); has_histogrammed_color_space_ = true; } @@ -487,15 +489,51 @@ size_t ImagePlanes::RowBytes(int i) const { return row_bytes_[i]; } -void ImageDecoder::SetEmbeddedColorSpace(sk_sp<SkColorSpace> color_space) { +ColorProfile::ColorProfile(const skcms_ICCProfile& profile, + std::unique_ptr<uint8_t[]> buffer) + : profile_(profile), buffer_(std::move(buffer)) {} + +std::unique_ptr<ColorProfile> ColorProfile::Create(const void* buffer, + size_t size) { + // After skcms_Parse, profile will have pointers into the passed buffer, + // so we need to copy first, then parse. + std::unique_ptr<uint8_t[]> owned_buffer(new uint8_t[size]); + memcpy(owned_buffer.get(), buffer, size); + skcms_ICCProfile profile; + if (skcms_Parse(owned_buffer.get(), size, &profile)) { + return std::make_unique<ColorProfile>(profile, std::move(owned_buffer)); + } + return nullptr; +} + +ColorProfileTransform::ColorProfileTransform( + const skcms_ICCProfile* src_profile, + const skcms_ICCProfile* dst_profile) { + DCHECK(src_profile); + DCHECK(dst_profile); + src_profile_ = src_profile; + dst_profile_ = *dst_profile; +} + +const skcms_ICCProfile* ColorProfileTransform::SrcProfile() const { + return src_profile_; +} + +const skcms_ICCProfile* ColorProfileTransform::DstProfile() const { + return &dst_profile_; +} + +void ImageDecoder::SetEmbeddedColorProfile( + std::unique_ptr<ColorProfile> profile) { DCHECK(!IgnoresColorSpace()); DCHECK(!has_histogrammed_color_space_); - embedded_color_space_ = color_space; + embedded_color_profile_ = std::move(profile); source_to_target_color_transform_needs_update_ = true; + color_space_for_sk_images_ = nullptr; } -SkColorSpaceXform* ImageDecoder::ColorTransform() { +ColorProfileTransform* ImageDecoder::ColorTransform() { if (!source_to_target_color_transform_needs_update_) return source_to_target_color_transform_.get(); source_to_target_color_transform_needs_update_ = false; @@ -505,60 +543,60 @@ SkColorSpaceXform* ImageDecoder::ColorTransform() { return nullptr; } - sk_sp<SkColorSpace> src_color_space = nullptr; - sk_sp<SkColorSpace> dst_color_space = nullptr; + const skcms_ICCProfile* src_profile = nullptr; + skcms_ICCProfile dst_profile; if (color_behavior_.IsTransformToSRGB()) { - if (!embedded_color_space_) { + if (!embedded_color_profile_) { return nullptr; } - src_color_space = embedded_color_space_; - dst_color_space = SkColorSpace::MakeSRGB(); + src_profile = embedded_color_profile_->GetProfile(); + dst_profile = *skcms_sRGB_profile(); } else { DCHECK(color_behavior_.IsTag()); - src_color_space = embedded_color_space_; - if (!src_color_space) { - src_color_space = SkColorSpace::MakeSRGB(); - } + src_profile = embedded_color_profile_ + ? embedded_color_profile_->GetProfile() + : skcms_sRGB_profile(); - // This will most likely be equal to the |src_color_space|. + // This will most likely be equal to the |src_profile|. // In that case, we skip the xform when we check for equality below. - dst_color_space = ColorSpaceForSkImages(); + ColorSpaceForSkImages()->toProfile(&dst_profile); } - if (SkColorSpace::Equals(src_color_space.get(), dst_color_space.get())) { + if (skcms_ApproximatelyEqualProfiles(src_profile, &dst_profile)) { return nullptr; } source_to_target_color_transform_ = - SkColorSpaceXform::New(src_color_space.get(), dst_color_space.get()); + std::make_unique<ColorProfileTransform>(src_profile, &dst_profile); return source_to_target_color_transform_.get(); } -sk_sp<SkColorSpace> ImageDecoder::ColorSpaceForSkImages() const { +sk_sp<SkColorSpace> ImageDecoder::ColorSpaceForSkImages() { + if (color_space_for_sk_images_) + return color_space_for_sk_images_; + if (!color_behavior_.IsTag()) return nullptr; - if (embedded_color_space_) { - SkColorSpaceTransferFn fn; - if (embedded_color_space_->isNumericalTransferFn(&fn)) { - // The embedded color space is supported by Skia. - return embedded_color_space_; - } + if (embedded_color_profile_) { + const skcms_ICCProfile* profile = embedded_color_profile_->GetProfile(); + color_space_for_sk_images_ = SkColorSpace::Make(*profile); - // In the rare case that the embedded color space is unsupported, xform at - // decode time. - SkMatrix44 to_xyz_d50(SkMatrix44::kUninitialized_Constructor); - if (embedded_color_space_->toXYZD50(&to_xyz_d50)) { + // If the embedded color space isn't supported by Skia, + // we xform at decode time. + if (!color_space_for_sk_images_ && profile->has_toXYZD50) { // Preserve the gamut, but convert to a standard transfer function. - return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, - to_xyz_d50); + skcms_ICCProfile with_srgb = *profile; + skcms_SetTransferFunction(&with_srgb, skcms_sRGB_TransferFunction()); + color_space_for_sk_images_ = SkColorSpace::Make(with_srgb); } - - // For color spaces without an identifiable gamut, just fall through to - // sRGB. } - return SkColorSpace::MakeSRGB(); + // For color spaces without an identifiable gamut, just fall through to sRGB. + if (!color_space_for_sk_images_) + color_space_for_sk_images_ = SkColorSpace::MakeSRGB(); + + return color_space_for_sk_images_; } } // namespace blink 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 bba85871cdf..8390adbb08c 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 @@ -42,16 +42,17 @@ #include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/skia/include/core/SkColorSpaceXform.h" +#include "third_party/skia/third_party/skcms/skcms.h" namespace blink { #if SK_B32_SHIFT -inline SkColorSpaceXform::ColorFormat XformColorFormat() { - return SkColorSpaceXform::kRGBA_8888_ColorFormat; +inline skcms_PixelFormat XformColorFormat() { + return skcms_PixelFormat_RGBA_8888; } #else -inline SkColorSpaceXform::ColorFormat XformColorFormat() { - return SkColorSpaceXform::kBGRA_8888_ColorFormat; +inline skcms_PixelFormat XformColorFormat() { + return skcms_PixelFormat_BGRA_8888; } #endif @@ -73,6 +74,37 @@ class PLATFORM_EXPORT ImagePlanes final { size_t row_bytes_[3]; }; +class PLATFORM_EXPORT ColorProfile final { + USING_FAST_MALLOC(ColorProfile); + WTF_MAKE_NONCOPYABLE(ColorProfile); + + public: + ColorProfile(const skcms_ICCProfile&, std::unique_ptr<uint8_t[]> = nullptr); + static std::unique_ptr<ColorProfile> Create(const void* buffer, size_t size); + + const skcms_ICCProfile* GetProfile() const { return &profile_; } + + private: + skcms_ICCProfile profile_; + std::unique_ptr<uint8_t[]> buffer_; +}; + +class PLATFORM_EXPORT ColorProfileTransform final { + USING_FAST_MALLOC(ColorProfileTransform); + WTF_MAKE_NONCOPYABLE(ColorProfileTransform); + + public: + ColorProfileTransform(const skcms_ICCProfile* src_profile, + const skcms_ICCProfile* dst_profile); + + const skcms_ICCProfile* SrcProfile() const; + const skcms_ICCProfile* DstProfile() const; + + private: + const skcms_ICCProfile* src_profile_; + skcms_ICCProfile dst_profile_; +}; + // ImageDecoder is a base for all format-specific decoders // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache. // @@ -218,17 +250,17 @@ class PLATFORM_EXPORT ImageDecoder { // This returns the color space that will be included in the SkImageInfo of // SkImages created from this decoder. This will be nullptr unless the // decoder was created with the option ColorSpaceTagged. - sk_sp<SkColorSpace> ColorSpaceForSkImages() const; + sk_sp<SkColorSpace> ColorSpaceForSkImages(); // This returns whether or not the image included a not-ignored embedded - // color space. This is independent of whether or not that space's transform - // has been baked into the pixel values. - bool HasEmbeddedColorSpace() const { return embedded_color_space_.get(); } + // color profile. This is independent of whether or not that profile's + // transform has been baked into the pixel values. + bool HasEmbeddedColorProfile() const { return embedded_color_profile_.get(); } - void SetEmbeddedColorSpace(sk_sp<SkColorSpace> src_space); + void SetEmbeddedColorProfile(std::unique_ptr<ColorProfile> profile); // Transformation from embedded color space to target color space. - SkColorSpaceXform* ColorTransform(); + ColorProfileTransform* ColorTransform(); AlphaOption GetAlphaOption() const { return premultiply_alpha_ ? kAlphaPremultiplied : kAlphaNotPremultiplied; @@ -427,9 +459,11 @@ class PLATFORM_EXPORT ImageDecoder { bool failed_ = false; bool has_histogrammed_color_space_ = false; - sk_sp<SkColorSpace> embedded_color_space_ = nullptr; + std::unique_ptr<ColorProfile> embedded_color_profile_; + sk_sp<SkColorSpace> color_space_for_sk_images_; + bool source_to_target_color_transform_needs_update_ = false; - std::unique_ptr<SkColorSpaceXform> source_to_target_color_transform_; + std::unique_ptr<ColorProfileTransform> source_to_target_color_transform_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc index c4d4c787890..25eb1ee6ad5 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc +++ b/chromium/third_party/blink/renderer/platform/image-decoders/image_decoder_test_helpers.cc @@ -244,14 +244,14 @@ static void TestByteByByteSizeAvailable(DecoderCreator create_decoder, if (length < frame_offset) { EXPECT_FALSE(decoder->IsSizeAvailable()); EXPECT_TRUE(decoder->Size().IsEmpty()); - EXPECT_FALSE(decoder->HasEmbeddedColorSpace()); + EXPECT_FALSE(decoder->HasEmbeddedColorProfile()); EXPECT_EQ(0u, decoder->FrameCount()); EXPECT_EQ(kAnimationLoopOnce, decoder->RepetitionCount()); EXPECT_FALSE(decoder->DecodeFrameBufferAtIndex(0)); } else { EXPECT_TRUE(decoder->IsSizeAvailable()); EXPECT_FALSE(decoder->Size().IsEmpty()); - EXPECT_EQ(decoder->HasEmbeddedColorSpace(), has_color_space); + EXPECT_EQ(decoder->HasEmbeddedColorProfile(), has_color_space); EXPECT_EQ(1u, decoder->FrameCount()); EXPECT_EQ(expected_repetition_count, decoder->RepetitionCount()); } 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 f3e4416d756..e3e3173bec4 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 @@ -466,34 +466,35 @@ class JPEGImageReader final { // Allow color management of the decoded RGBA pixels if possible. if (!decoder_->IgnoresColorSpace()) { - JOCTET* profile = nullptr; + JOCTET* profile_buf = nullptr; unsigned profile_length = 0; - if (read_icc_profile(Info(), &profile, &profile_length)) { - sk_sp<SkColorSpace> color_space = - SkColorSpace::MakeICC(profile, profile_length); - if (color_space) { - const SkColorSpace::Type type = color_space->type(); + if (read_icc_profile(Info(), &profile_buf, &profile_length)) { + std::unique_ptr<ColorProfile> profile = + ColorProfile::Create(profile_buf, profile_length); + if (profile) { + uint32_t data_color_space = + profile->GetProfile()->data_color_space; switch (info_.jpeg_color_space) { case JCS_CMYK: case JCS_YCCK: - if (type != SkColorSpace::kCMYK_Type) - color_space = nullptr; + if (data_color_space != skcms_Signature_CMYK) + profile = nullptr; break; case JCS_GRAYSCALE: - if (type != SkColorSpace::kGray_Type && - type != SkColorSpace::kRGB_Type) - color_space = nullptr; + if (data_color_space != skcms_Signature_Gray && + data_color_space != skcms_Signature_RGB) + profile = nullptr; break; default: - if (type != SkColorSpace::kRGB_Type) - color_space = nullptr; + if (data_color_space != skcms_Signature_RGB) + profile = nullptr; break; } - Decoder()->SetEmbeddedColorSpace(std::move(color_space)); + Decoder()->SetEmbeddedColorProfile(std::move(profile)); } else { DLOG(ERROR) << "Failed to parse image ICC profile"; } - free(profile); + free(profile_buf); } if (Decoder()->ColorTransform()) { override_color_space = JCS_UNKNOWN; @@ -902,13 +903,14 @@ bool OutputRows(JPEGImageReader* reader, ImageFrame& buffer) { for (int x = 0; x < width; ++pixel, ++x) SetPixel<colorSpace>(pixel, samples, x); - SkColorSpaceXform* xform = reader->Decoder()->ColorTransform(); + ColorProfileTransform* xform = reader->Decoder()->ColorTransform(); if (xform) { ImageFrame::PixelData* row = buffer.GetAddr(0, y); - bool color_converison_successful = - xform->apply(XformColorFormat(), row, XformColorFormat(), row, width, - kOpaque_SkAlphaType); - DCHECK(color_converison_successful); + skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; + bool color_conversion_successful = skcms_Transform( + row, XformColorFormat(), alpha_format, xform->SrcProfile(), row, + XformColorFormat(), alpha_format, xform->DstProfile(), width); + DCHECK(color_conversion_successful); } } @@ -1012,12 +1014,14 @@ bool JPEGImageDecoder::OutputScanlines() { if (jpeg_read_scanlines(info, &row, 1) != 1) return false; - SkColorSpaceXform* xform = ColorTransform(); + ColorProfileTransform* xform = ColorTransform(); if (xform) { - bool color_converison_successful = - xform->apply(XformColorFormat(), row, XformColorFormat(), row, - info->output_width, kOpaque_SkAlphaType); - DCHECK(color_converison_successful); + skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; + bool color_conversion_successful = skcms_Transform( + row, XformColorFormat(), alpha_format, xform->SrcProfile(), row, + XformColorFormat(), alpha_format, xform->DstProfile(), + info->output_width); + DCHECK(color_conversion_successful); } } buffer.SetPixelsChanged(true); diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc index cad2f68db51..e6f8d772540 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc +++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.cc @@ -146,16 +146,19 @@ void PNGImageDecoder::InitializeNewFrame(size_t index) { buffer.SetRequiredPreviousFrameIndex(previous_frame_index); } -inline sk_sp<SkColorSpace> ReadColorSpace(png_structp png, png_infop info) { - if (png_get_valid(png, info, PNG_INFO_sRGB)) - return SkColorSpace::MakeSRGB(); +inline std::unique_ptr<ColorProfile> ReadColorProfile(png_structp png, + png_infop info) { + if (png_get_valid(png, info, PNG_INFO_sRGB)) { + return std::make_unique<ColorProfile>(*skcms_sRGB_profile()); + } png_charp name; int compression; - png_bytep profile; + png_bytep buffer; png_uint_32 length; - if (png_get_iCCP(png, info, &name, &compression, &profile, &length)) - return SkColorSpace::MakeICC(profile, length); + if (png_get_iCCP(png, info, &name, &compression, &buffer, &length)) { + return ColorProfile::Create(buffer, length); + } png_fixed_point chrm[8]; if (!png_get_cHRM_fixed(png, info, &chrm[0], &chrm[1], &chrm[2], &chrm[3], @@ -178,26 +181,29 @@ inline sk_sp<SkColorSpace> ReadColorSpace(png_structp png, png_infop info) { float float_value; }; - SkColorSpacePrimaries primaries; - primaries.fRX = pngFixedToFloat(chrm[2]); - primaries.fRY = pngFixedToFloat(chrm[3]); - primaries.fGX = pngFixedToFloat(chrm[4]); - primaries.fGY = pngFixedToFloat(chrm[5]); - primaries.fBX = pngFixedToFloat(chrm[6]); - primaries.fBY = pngFixedToFloat(chrm[7]); - primaries.fWX = pngFixedToFloat(chrm[0]); - primaries.fWY = pngFixedToFloat(chrm[1]); - - SkMatrix44 to_xyzd50(SkMatrix44::kUninitialized_Constructor); - if (!primaries.toXYZD50(&to_xyzd50)) + float rx = pngFixedToFloat(chrm[2]); + float ry = pngFixedToFloat(chrm[3]); + float gx = pngFixedToFloat(chrm[4]); + float gy = pngFixedToFloat(chrm[5]); + float bx = pngFixedToFloat(chrm[6]); + float by = pngFixedToFloat(chrm[7]); + float wx = pngFixedToFloat(chrm[0]); + float wy = pngFixedToFloat(chrm[1]); + skcms_Matrix3x3 to_xyzd50; + if (!skcms_PrimariesToXYZD50(rx, ry, gx, gy, bx, by, wx, wy, &to_xyzd50)) return nullptr; - SkColorSpaceTransferFn fn; - fn.fG = 1.0f / pngFixedToFloat(inverse_gamma); - fn.fA = 1.0f; - fn.fB = fn.fC = fn.fD = fn.fE = fn.fF = 0.0f; + skcms_TransferFunction fn; + fn.g = 1.0f / pngFixedToFloat(inverse_gamma); + fn.a = 1.0f; + fn.b = fn.c = fn.d = fn.e = fn.f = 0.0f; + + skcms_ICCProfile profile; + skcms_Init(&profile); + skcms_SetTransferFunction(&profile, &fn); + skcms_SetXYZD50(&profile, &to_xyzd50); - return SkColorSpace::MakeRGB(fn, to_xyzd50); + return std::make_unique<ColorProfile>(profile); } void PNGImageDecoder::SetColorSpace() { @@ -210,9 +216,9 @@ void PNGImageDecoder::SetColorSpace() { return; // We only support color profiles for color PALETTE and RGB[A] PNG. // TODO(msarett): Add GRAY profile support, block CYMK? - sk_sp<SkColorSpace> color_space = ReadColorSpace(png, info); - if (color_space) - SetEmbeddedColorSpace(color_space); + if (auto profile = ReadColorProfile(png, info)) { + SetEmbeddedColorProfile(std::move(profile)); + } } bool PNGImageDecoder::SetSize(unsigned width, unsigned height) { @@ -251,7 +257,7 @@ void PNGImageDecoder::HeaderAvailable() { color_type == PNG_COLOR_TYPE_GRAY_ALPHA) png_set_gray_to_rgb(png); - if (!HasEmbeddedColorSpace()) { + if (!HasEmbeddedColorProfile()) { const double kInverseGamma = 0.45455; const double kDefaultGamma = 2.2; double gamma; @@ -579,14 +585,31 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer, // the premultiply, we will very likely end up with valid pixels // where R, G, and/or B are greater than A. The legacy drawing // pipeline does not know how to handle this. - if (SkColorSpaceXform* xform = ColorTransform()) { - SkColorSpaceXform::ColorFormat color_format = - SkColorSpaceXform::kRGBA_8888_ColorFormat; - bool color_converison_successful = - xform->apply(color_format, dst_row, color_format, src_ptr, width, - kUnpremul_SkAlphaType); - DCHECK(color_converison_successful); - src_ptr = png_bytep(dst_row); + if (ColorProfileTransform* xform = ColorTransform()) { + ImageFrame::PixelData* xform_dst = dst_row; + // If we're blending over the previous frame, we can't overwrite that + // when we do the color transform. So we allocate another row of pixels + // to hold the temporary result before blending. In all other cases, + // we can safely transform directly to the destination buffer, then do + // any operations in-place (premul, swizzle). + if (frame_buffer_cache_[current_frame_].GetAlphaBlendSource() == + ImageFrame::kBlendAtopPreviousFrame) { + if (!color_transform_scanline_) { + // This buffer may be wider than necessary for this frame, but by + // allocating the full width of the PNG, we know it will be able to + // hold temporary data for any subsequent frame. + color_transform_scanline_.reset( + new ImageFrame::PixelData[Size().Width()]); + } + xform_dst = color_transform_scanline_.get(); + } + skcms_PixelFormat color_format = skcms_PixelFormat_RGBA_8888; + skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; + bool color_conversion_successful = skcms_Transform( + src_ptr, color_format, alpha_format, xform->SrcProfile(), xform_dst, + color_format, alpha_format, xform->DstProfile(), width); + DCHECK(color_conversion_successful); + src_ptr = png_bytep(xform_dst); } unsigned alpha_mask = 255; @@ -651,13 +674,15 @@ void PNGImageDecoder::RowAvailable(unsigned char* row_buffer, } #endif // We'll apply the color space xform to opaque pixels after they have been - // written to the ImageFrame, purely because SkColorSpaceXform supports - // RGBA (and not RGB). - if (SkColorSpaceXform* xform = ColorTransform()) { - bool color_converison_successful = - xform->apply(XformColorFormat(), dst_row, XformColorFormat(), dst_row, - width, kOpaque_SkAlphaType); - DCHECK(color_converison_successful); + // written to the ImageFrame. + // TODO: Apply the xform to the RGB pixels, skipping second pass over data. + if (ColorProfileTransform* xform = ColorTransform()) { + skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Opaque; + bool color_conversion_successful = + skcms_Transform(dst_row, XformColorFormat(), alpha_format, + xform->SrcProfile(), dst_row, XformColorFormat(), + alpha_format, xform->DstProfile(), width); + DCHECK(color_conversion_successful); } } diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h index dc39091673b..26403d3585f 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h +++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder.h @@ -77,6 +77,7 @@ class PLATFORM_EXPORT PNGImageDecoder final : public ImageDecoder { int repetition_count_; bool has_alpha_channel_; bool current_buffer_saw_alpha_; + std::unique_ptr<ImageFrame::PixelData[]> color_transform_scanline_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc index 00daa8a2d8f..aa0310bad62 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc +++ b/chromium/third_party/blink/renderer/platform/image-decoders/png/png_image_decoder_test.cc @@ -1081,4 +1081,16 @@ TEST(PNGTests, truncated) { } } +TEST(PNGTests, crbug827754) { + const char* png_file = "/images/resources/crbug827754.png"; + scoped_refptr<SharedBuffer> data = ReadFile(png_file); + ASSERT_TRUE(data); + + auto decoder = CreatePNGDecoder(); + decoder->SetData(data.get(), true); + auto* frame = decoder->DecodeFrameBufferAtIndex(0); + ASSERT_TRUE(frame); + ASSERT_FALSE(decoder->Failed()); +} + }; // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc index 391da54bb27..e5da242e0ba 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc +++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.cc @@ -313,11 +313,10 @@ void WEBPImageDecoder::ReadColorProfile() { reinterpret_cast<const char*>(chunk_iterator.chunk.bytes); size_t profile_size = chunk_iterator.chunk.size; - sk_sp<SkColorSpace> color_space = - SkColorSpace::MakeICC(profile_data, profile_size); - if (color_space) { - if (color_space->type() == SkColorSpace::kRGB_Type) - SetEmbeddedColorSpace(std::move(color_space)); + if (auto profile = ColorProfile::Create(profile_data, profile_size)) { + if (profile->GetProfile()->data_color_space == skcms_Signature_RGB) { + SetEmbeddedColorProfile(std::move(profile)); + } } else { DLOG(ERROR) << "Failed to parse image ICC profile"; } @@ -346,18 +345,18 @@ void WEBPImageDecoder::ApplyPostProcessing(size_t frame_index) { // space and then immediately after, perform a linear premultiply // and linear blending. Can we find a way to perform the // premultiplication and blending in a linear space? - SkColorSpaceXform* xform = ColorTransform(); + ColorProfileTransform* xform = ColorTransform(); if (xform) { - const SkColorSpaceXform::ColorFormat kSrcFormat = - SkColorSpaceXform::kBGRA_8888_ColorFormat; - const SkColorSpaceXform::ColorFormat kDstFormat = - SkColorSpaceXform::kRGBA_8888_ColorFormat; + skcms_PixelFormat kSrcFormat = skcms_PixelFormat_BGRA_8888; + skcms_PixelFormat kDstFormat = skcms_PixelFormat_RGBA_8888; + skcms_AlphaFormat alpha_format = skcms_AlphaFormat_Unpremul; for (int y = decoded_height_; y < decoded_height; ++y) { const int canvas_y = top + y; uint8_t* row = reinterpret_cast<uint8_t*>(buffer.GetAddr(left, canvas_y)); - bool color_converison_successful = xform->apply( - kDstFormat, row, kSrcFormat, row, width, kUnpremul_SkAlphaType); - DCHECK(color_converison_successful); + bool color_conversion_successful = skcms_Transform( + row, kSrcFormat, alpha_format, xform->SrcProfile(), row, kDstFormat, + alpha_format, xform->DstProfile(), width); + DCHECK(color_conversion_successful); uint8_t* pixel = row; for (int x = 0; x < width; ++x, pixel += 4) { const int canvas_x = left + x; diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h index 651d35d0534..30a7971a15a 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h +++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder.h @@ -55,7 +55,7 @@ class PLATFORM_EXPORT WEBPImageDecoder final : public ImageDecoder { private: // ImageDecoder: - virtual void DecodeSize() { UpdateDemuxer(); } + void DecodeSize() override { UpdateDemuxer(); } size_t DecodeFrameCount() override; void InitializeNewFrame(size_t) override; void Decode(size_t) override; diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc index 975d3d1b84f..83bac77afde 100644 --- a/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc +++ b/chromium/third_party/blink/renderer/platform/image-decoders/webp/webp_image_decoder_test.cc @@ -127,7 +127,7 @@ TEST(AnimatedWebPTests, verifyAnimationParametersTransparentImage) { true}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kFrameParameters); ++i) { + for (size_t i = 0; i < arraysize(kFrameParameters); ++i) { const ImageFrame* const frame = decoder->DecodeFrameBufferAtIndex(i); EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus()); EXPECT_EQ(kCanvasWidth, frame->Bitmap().width()); @@ -143,7 +143,7 @@ TEST(AnimatedWebPTests, verifyAnimationParametersTransparentImage) { EXPECT_EQ(kFrameParameters[i].has_alpha, frame->HasAlpha()); } - EXPECT_EQ(WTF_ARRAY_LENGTH(kFrameParameters), decoder->FrameCount()); + EXPECT_EQ(arraysize(kFrameParameters), decoder->FrameCount()); EXPECT_EQ(kAnimationLoopInfinite, decoder->RepetitionCount()); } @@ -174,7 +174,7 @@ TEST(AnimatedWebPTests, true}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kFrameParameters); ++i) { + for (size_t i = 0; i < arraysize(kFrameParameters); ++i) { const ImageFrame* const frame = decoder->DecodeFrameBufferAtIndex(i); EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus()); EXPECT_EQ(kCanvasWidth, frame->Bitmap().width()); @@ -190,7 +190,7 @@ TEST(AnimatedWebPTests, EXPECT_EQ(kFrameParameters[i].has_alpha, frame->HasAlpha()); } - EXPECT_EQ(WTF_ARRAY_LENGTH(kFrameParameters), decoder->FrameCount()); + EXPECT_EQ(arraysize(kFrameParameters), decoder->FrameCount()); EXPECT_EQ(kAnimationLoopInfinite, decoder->RepetitionCount()); } @@ -216,7 +216,7 @@ TEST(AnimatedWebPTests, verifyAnimationParametersBlendOverwrite) { ImageFrame::kBlendAtopBgcolor, TimeDelta::FromMilliseconds(1000), true}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kFrameParameters); ++i) { + for (size_t i = 0; i < arraysize(kFrameParameters); ++i) { const ImageFrame* const frame = decoder->DecodeFrameBufferAtIndex(i); EXPECT_EQ(ImageFrame::kFrameComplete, frame->GetStatus()); EXPECT_EQ(kCanvasWidth, frame->Bitmap().width()); @@ -232,7 +232,7 @@ TEST(AnimatedWebPTests, verifyAnimationParametersBlendOverwrite) { EXPECT_EQ(kFrameParameters[i].has_alpha, frame->HasAlpha()); } - EXPECT_EQ(WTF_ARRAY_LENGTH(kFrameParameters), decoder->FrameCount()); + EXPECT_EQ(arraysize(kFrameParameters), decoder->FrameCount()); EXPECT_EQ(kAnimationLoopInfinite, decoder->RepetitionCount()); } diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/DEPS b/chromium/third_party/blink/renderer/platform/image-encoders/DEPS new file mode 100644 index 00000000000..5acbcd396c0 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/image-encoders/DEPS @@ -0,0 +1,18 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/image-encoders", + + # Dependencies. + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/network/mime/mime_type_registry.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc index 1236b897722..0c7f14c7c0e 100644 --- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc +++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.cc @@ -55,6 +55,20 @@ std::unique_ptr<ImageEncoder> ImageEncoder::Create( return image_encoder; } +int ImageEncoder::MaxDimension(MimeType mime_type) { + switch (mime_type) { + case kMimeTypePng: + return 65535; + case kMimeTypeJpeg: + return JPEG_MAX_DIMENSION; + case kMimeTypeWebp: + return WEBP_MAX_DIMENSION; + default: + NOTREACHED(); + } + return -1; +} + int ImageEncoder::ComputeJpegQuality(double quality) { int compression_quality = 92; // Default value if (0.0f <= quality && quality <= 1.0) diff --git a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h index 85ad21e03a8..0d1460f3482 100644 --- a/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h +++ b/chromium/third_party/blink/renderer/platform/image-encoders/image_encoder.h @@ -7,6 +7,8 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/libjpeg/jpeglib.h" // for JPEG_MAX_DIMENSION +#include "third_party/libwebp/src/webp/encode.h" // for WEBP_MAX_DIMENSION #include "third_party/skia/include/core/SkStream.h" #include "third_party/skia/include/encode/SkJpegEncoder.h" #include "third_party/skia/include/encode/SkPngEncoder.h" @@ -47,6 +49,15 @@ class PLATFORM_EXPORT ImageEncoder { const SkPixmap& src, const SkWebpEncoder::Options&); + enum MimeType { + kMimeTypePng, + kMimeTypeJpeg, + kMimeTypeWebp, + kNumberOfMimeTypeSupported + }; + + static int MaxDimension(MimeType mime_type); + static std::unique_ptr<ImageEncoder> Create(Vector<unsigned char>* dst, const SkPixmap& src, const SkJpegEncoder::Options&); diff --git a/chromium/third_party/blink/renderer/platform/instance_counters.h b/chromium/third_party/blink/renderer/platform/instance_counters.h index 9aa201902a9..137a40bd10a 100644 --- a/chromium/third_party/blink/renderer/platform/instance_counters.h +++ b/chromium/third_party/blink/renderer/platform/instance_counters.h @@ -53,7 +53,9 @@ namespace blink { V(WorkerGlobalScope) \ V(UACSSResource) \ V(RTCPeerConnection) \ - V(ResourceFetcher) + V(ResourceFetcher) \ + V(AdSubframe) \ + V(DetachedScriptState) class InstanceCounters { STATIC_ONLY(InstanceCounters); diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/DEPS b/chromium/third_party/blink/renderer/platform/instrumentation/DEPS index 18a8e5ed671..20dc455fb85 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/DEPS +++ b/chromium/third_party/blink/renderer/platform/instrumentation/DEPS @@ -1,4 +1,11 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/instrumentation", + + # Dependencies. "+base/gtest_prod_util.h", "+base/json", "+base/macros.h", @@ -8,4 +15,8 @@ include_rules = [ "+base/trace_event", "+base/values.h", "+skia/ext/skia_trace_memory_dump_impl.h", + + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc index ddaf7992cf5..95c99cf5794 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc +++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.cc @@ -27,6 +27,13 @@ void FrameResourceCoordinator::SetNetworkAlmostIdle(bool idle) { service_->SetNetworkAlmostIdle(idle); } +void FrameResourceCoordinator::SetLifecycleState( + resource_coordinator::mojom::LifecycleState state) { + if (!service_) + return; + service_->SetLifecycleState(state); +} + void FrameResourceCoordinator::OnNonPersistentNotificationCreated() { if (!service_) return; diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h index 13649425dce..a801a489300 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h +++ b/chromium/third_party/blink/renderer/platform/instrumentation/resource_coordinator/frame_resource_coordinator.h @@ -23,6 +23,7 @@ class PLATFORM_EXPORT FrameResourceCoordinator final ~FrameResourceCoordinator(); void SetNetworkAlmostIdle(bool); + void SetLifecycleState(resource_coordinator::mojom::LifecycleState); void OnNonPersistentNotificationCreated(); private: diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h index 9c4ea8d628c..822b8e79140 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h +++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/memory_cache_dump_provider.h @@ -21,7 +21,7 @@ class PLATFORM_EXPORT MemoryCacheDumpClient : public GarbageCollectedMixin { virtual bool OnMemoryDump(WebMemoryDumpLevelOfDetail, WebProcessMemoryDump*) = 0; - virtual void Trace(blink::Visitor*); + void Trace(blink::Visitor*) override; }; // This class is wrapper around MemoryCache to take memory snapshots. It dumps diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.cc index 04695c14f86..0a174cba59f 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.cc +++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.cc @@ -19,5 +19,16 @@ void DisableTracing() { base::trace_event::TraceLog::GetInstance()->SetDisabled(); } +void AddAsyncEnabledStateObserver( + base::WeakPtr<AsyncEnabledStateObserver> observer) { + base::trace_event::TraceLog::GetInstance()->AddAsyncEnabledStateObserver( + observer); +} + +void RemoveAsyncEnabledStateObserver(AsyncEnabledStateObserver* observer) { + base::trace_event::TraceLog::GetInstance()->RemoveAsyncEnabledStateObserver( + observer); +} + } // namespace TraceEvent } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h index d189d432d3d..1fbb622b565 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h +++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h @@ -29,6 +29,8 @@ namespace blink { namespace TraceEvent { using base::trace_event::TraceScopedTrackableObject; +using AsyncEnabledStateObserver = + base::trace_event::TraceLog::AsyncEnabledStateObserver; inline base::TimeTicks ToTraceTimestamp(double seconds) { return base::TimeTicks() + base::TimeDelta::FromSecondsD(seconds); @@ -40,6 +42,11 @@ void ToTraceTimestamp(int64_t); PLATFORM_EXPORT void EnableTracing(const String& category_filter); PLATFORM_EXPORT void DisableTracing(); +PLATFORM_EXPORT void AddAsyncEnabledStateObserver( + base::WeakPtr<AsyncEnabledStateObserver>); +PLATFORM_EXPORT void RemoveAsyncEnabledStateObserver( + AsyncEnabledStateObserver*); + } // namespace TraceEvent } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h index 6a0b4136452..6a25ad9876e 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h +++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h @@ -16,7 +16,7 @@ namespace blink { class PLATFORM_EXPORT TracedValue final : public base::trace_event::ConvertableToTraceFormat { public: - ~TracedValue(); + ~TracedValue() override; static std::unique_ptr<TracedValue> Create(); diff --git a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump_test.cc b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump_test.cc index 7bcfac8c98f..ac618b1cf1a 100644 --- a/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump_test.cc +++ b/chromium/third_party/blink/renderer/platform/instrumentation/tracing/web_process_memory_dump_test.cc @@ -29,8 +29,8 @@ TEST(WebProcessMemoryDumpTest, IntegrationTest) { new base::trace_event::TracedValue()); std::unique_ptr<WebProcessMemoryDump> wpmd1(new WebProcessMemoryDump()); - auto wmad1 = wpmd1->CreateMemoryAllocatorDump("1/1"); - auto wmad2 = wpmd1->CreateMemoryAllocatorDump("1/2"); + auto* wmad1 = wpmd1->CreateMemoryAllocatorDump("1/1"); + auto* wmad2 = wpmd1->CreateMemoryAllocatorDump("1/2"); ASSERT_EQ(wmad1, wpmd1->GetMemoryAllocatorDump("1/1")); ASSERT_EQ(wmad2, wpmd1->GetMemoryAllocatorDump("1/2")); @@ -48,10 +48,10 @@ TEST(WebProcessMemoryDumpTest, IntegrationTest) { ASSERT_TRUE(wpmd2->process_memory_dump()->allocator_dumps().empty()); // Make sure that wpmd2 is still usable after it has been emptied. - auto wmad = wpmd2->CreateMemoryAllocatorDump("2/new"); + auto* wmad = wpmd2->CreateMemoryAllocatorDump("2/new"); wmad->AddScalar("attr_name", "bytes", 42); ASSERT_EQ(1u, wpmd2->process_memory_dump()->allocator_dumps().size()); - auto mad = wpmd2->process_memory_dump()->GetAllocatorDump("2/new"); + auto* mad = wpmd2->process_memory_dump()->GetAllocatorDump("2/new"); ASSERT_NE(static_cast<MemoryAllocatorDump*>(nullptr), mad); ASSERT_EQ(wmad, wpmd2->GetMemoryAllocatorDump("2/new")); @@ -103,12 +103,12 @@ TEST(WebProcessMemoryDumpTest, IntegrationTest) { // Check if a WebMemoryAllocatorDump created with guid, has correct guid. blink::WebMemoryAllocatorDumpGuid guid = base::trace_event::MemoryAllocatorDumpGuid("id_1").ToUint64(); - auto wmad3 = wpmd1->CreateMemoryAllocatorDump("1/3", guid); + auto* wmad3 = wpmd1->CreateMemoryAllocatorDump("1/3", guid); ASSERT_EQ(wmad3->Guid(), guid); ASSERT_EQ(wmad3, wpmd1->GetMemoryAllocatorDump("1/3")); // Check that AddOwnershipEdge is propagated correctly. - auto wmad4 = wpmd1->CreateMemoryAllocatorDump("1/4"); + auto* wmad4 = wpmd1->CreateMemoryAllocatorDump("1/4"); wpmd1->AddOwnershipEdge(wmad4->Guid(), guid); auto allocator_dumps_edges = wpmd1->process_memory_dump()->allocator_dumps_edges(); @@ -119,7 +119,7 @@ TEST(WebProcessMemoryDumpTest, IntegrationTest) { ASSERT_EQ(guid, it->second.target.ToUint64()); // Check that createDumpAdapterForSkia() works. - auto skia_trace_memory_dump = wpmd1->CreateDumpAdapterForSkia("1/skia"); + auto* skia_trace_memory_dump = wpmd1->CreateDumpAdapterForSkia("1/skia"); ASSERT_TRUE(skia_trace_memory_dump); // Check that createDiscardableMemoryAllocatorDump() works. diff --git a/chromium/third_party/blink/renderer/platform/json/DEPS b/chromium/third_party/blink/renderer/platform/json/DEPS new file mode 100644 index 00000000000..ab2653f09b5 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/json/DEPS @@ -0,0 +1,13 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/json", + + # Dependencies. + "+third_party/blink/renderer/platform/decimal.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/json/json_parser_test.cc b/chromium/third_party/blink/renderer/platform/json/json_parser_test.cc index 443a218334b..32141dc5a83 100644 --- a/chromium/third_party/blink/renderer/platform/json/json_parser_test.cc +++ b/chromium/third_party/blink/renderer/platform/json/json_parser_test.cc @@ -447,14 +447,14 @@ TEST(JSONParserTest, Reading) { EXPECT_EQ(JSONValue::kTypeString, root->GetType()); EXPECT_TRUE(root->AsString(&str_val)); UChar tmp2[] = {0x20ac, 0x33, 0x2c, 0x31, 0x34}; - EXPECT_EQ(String(tmp2, WTF_ARRAY_LENGTH(tmp2)), str_val); + EXPECT_EQ(String(tmp2, arraysize(tmp2)), str_val); root = ParseJSON("\"\\ud83d\\udca9\\ud83d\\udc6c\""); ASSERT_TRUE(root.get()); EXPECT_EQ(JSONValue::kTypeString, root->GetType()); EXPECT_TRUE(root->AsString(&str_val)); UChar tmp3[] = {0xd83d, 0xdca9, 0xd83d, 0xdc6c}; - EXPECT_EQ(String(tmp3, WTF_ARRAY_LENGTH(tmp3)), str_val); + EXPECT_EQ(String(tmp3, arraysize(tmp3)), str_val); // Test literal root objects. root = ParseJSON("null"); @@ -481,7 +481,7 @@ TEST(JSONParserTest, InvalidSanity) { "/* test *", "{\"foo\"", "{\"foo\":", " [", "\"\\u123g\"", "{\n\"eh:\n}", "////", "*/**/", "/**/", "/*/", "//**/", "\"\\"}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kInvalidJson); ++i) { + for (size_t i = 0; i < arraysize(kInvalidJson); ++i) { std::unique_ptr<JSONValue> result = ParseJSON(kInvalidJson[i]); EXPECT_FALSE(result.get()); } diff --git a/chromium/third_party/blink/renderer/platform/layout_locale_test.cc b/chromium/third_party/blink/renderer/platform/layout_locale_test.cc index ea37d5539aa..2791c1144ae 100644 --- a/chromium/third_party/blink/renderer/platform/layout_locale_test.cc +++ b/chromium/third_party/blink/renderer/platform/layout_locale_test.cc @@ -145,7 +145,7 @@ TEST(LayoutLocaleTest, ExistingKeywordName) { const char* tests[] = { "en@x=", "en@lb=xyz", "en@ =", }; - for (const auto& test : tests) { + for (auto* const test : tests) { scoped_refptr<LayoutLocale> locale = LayoutLocale::CreateForTesting(test); EXPECT_EQ(test, locale->LocaleWithBreakKeyword(LineBreakIteratorMode::kNormal)); diff --git a/chromium/third_party/blink/renderer/platform/layout_unit.cc b/chromium/third_party/blink/renderer/platform/layout_unit.cc index 3a0936da9e1..e27c262080c 100644 --- a/chromium/third_party/blink/renderer/platform/layout_unit.cc +++ b/chromium/third_party/blink/renderer/platform/layout_unit.cc @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/platform/layout_unit.h" #include <ostream> +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -25,4 +26,8 @@ std::ostream& operator<<(std::ostream& stream, const LayoutUnit& value) { return stream << value.ToString(); } +WTF::TextStream& operator<<(WTF::TextStream& ts, const LayoutUnit& unit) { + return ts << WTF::TextStream::FormatNumberRespectingIntegers(unit.ToDouble()); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/layout_unit.h b/chromium/third_party/blink/renderer/platform/layout_unit.h index d9cd9b51509..7291a446f42 100644 --- a/chromium/third_party/blink/renderer/platform/layout_unit.h +++ b/chromium/third_party/blink/renderer/platform/layout_unit.h @@ -711,6 +711,8 @@ inline bool IsIntegerValue(const LayoutUnit value) { } PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const LayoutUnit&); +PLATFORM_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, + const LayoutUnit&); } // namespace blink 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 1bb2403a810..e14ba8373b8 100644 --- a/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc +++ b/chromium/third_party/blink/renderer/platform/lifecycle_context_test.cc @@ -41,7 +41,7 @@ class DummyContext final public: static DummyContext* Create() { return new DummyContext; } - void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { LifecycleNotifier<DummyContext, TestingObserver>::Trace(visitor); } }; @@ -64,7 +64,7 @@ class TestingObserver final context_destroyed_called_ = true; } - void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(observer_to_remove_on_destruct_); LifecycleObserver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h b/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h index 97ab7bc7616..c1f3b60b94d 100644 --- a/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h +++ b/chromium/third_party/blink/renderer/platform/lifecycle_notifier.h @@ -27,8 +27,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_NOTIFIER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LIFECYCLE_NOTIFIER_H_ +#include "base/auto_reset.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" namespace blink { @@ -50,7 +50,7 @@ class LifecycleNotifier : public GarbageCollectedMixin { // and safe to use while handling the notification. virtual void NotifyContextDestroyed(); - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(observers_); } + void Trace(blink::Visitor* visitor) override { visitor->Trace(observers_); } bool IsIteratingOverObservers() const { return iteration_state_ != kNotIterating; @@ -132,7 +132,7 @@ class ContextDestroyedNotifier<Observer, T, false> { template <typename T, typename Observer> inline void LifecycleNotifier<T, Observer>::NotifyContextDestroyed() { // Observer unregistration is allowed, but effectively a no-op. - AutoReset<IterationState> scope(&iteration_state_, kAllowingRemoval); + base::AutoReset<IterationState> scope(&iteration_state_, kAllowingRemoval); ObserverSet observers; observers_.swap(observers); for (Observer* observer : observers) { diff --git a/chromium/third_party/blink/renderer/platform/lifecycle_observer.h b/chromium/third_party/blink/renderer/platform/lifecycle_observer.h index 9b72fba6169..785bab5cfa3 100644 --- a/chromium/third_party/blink/renderer/platform/lifecycle_observer.h +++ b/chromium/third_party/blink/renderer/platform/lifecycle_observer.h @@ -37,7 +37,7 @@ class LifecycleNotifier; template <typename Context, typename Observer> class LifecycleObserver : public GarbageCollectedMixin { public: - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(lifecycle_context_); } diff --git a/chromium/third_party/blink/renderer/platform/loader/DEPS b/chromium/third_party/blink/renderer/platform/loader/DEPS index 3577746624c..ebdf6764fc2 100644 --- a/chromium/third_party/blink/renderer/platform/loader/DEPS +++ b/chromium/third_party/blink/renderer/platform/loader/DEPS @@ -1,9 +1,43 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/loader", + + # Dependencies. "+base/metrics/field_trial_params.h", # for fetch/ResourceLoadScheduler.cpp "+base/strings/string_number_conversions.h", # for fetch/ResourceLoadScheduler.cpp "+components/link_header_util", # for LinkHeader.cpp "+services/network/public", # for Fetch API and CORS - "+third_party/boringssl/src/include/openssl/curve25519.h" # for SubresourceIntegrity.cpp + "+third_party/blink/renderer/platform/bindings/script_forbidden_scope.h", + "+third_party/blink/renderer/platform/blob/blob_data.h", + "+third_party/blink/renderer/platform/cross_origin_attribute_value.h", + "+third_party/blink/renderer/platform/cross_thread_copier.h", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/crypto.h", + "+third_party/blink/renderer/platform/decimal.h", + "+third_party/blink/renderer/platform/exported", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instance_counters.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/language.h", + "+third_party/blink/renderer/platform/memory_coordinator.h", + "+third_party/blink/renderer/platform/mhtml", + "+third_party/blink/renderer/platform/network", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/PlatformProbeSink.h", + "+third_party/blink/renderer/platform/probe", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/timer.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", + "+third_party/boringssl/src/include/openssl/curve25519.h", # for SubresourceIntegrity.cpp ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc index 370971d02b8..ff219bdaad9 100644 --- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc +++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.cc @@ -68,7 +68,7 @@ std::unique_ptr<net::HttpRequestHeaders> CreateNetHttpRequestHeaders( namespace CORS { -WTF::Optional<network::mojom::CORSError> CheckAccess( +base::Optional<network::mojom::CORSError> CheckAccess( const KURL& response_url, const int response_status_code, const HTTPHeaderMap& response_header, @@ -85,7 +85,24 @@ WTF::Optional<network::mojom::CORSError> CheckAccess( !privilege->block_local_access_from_local_origin_); } -WTF::Optional<network::mojom::CORSError> CheckRedirectLocation( +base::Optional<network::mojom::CORSError> CheckPreflightAccess( + const KURL& response_url, + const int response_status_code, + const HTTPHeaderMap& response_header, + network::mojom::FetchCredentialsMode actual_credentials_mode, + const SecurityOrigin& origin) { + std::unique_ptr<SecurityOrigin::PrivilegeData> privilege = + origin.CreatePrivilegeData(); + return network::cors::CheckPreflightAccess( + response_url, response_status_code, + GetHeaderValue(response_header, HTTPNames::Access_Control_Allow_Origin), + GetHeaderValue(response_header, + HTTPNames::Access_Control_Allow_Credentials), + actual_credentials_mode, origin.ToUrlOrigin(), + !privilege->block_local_access_from_local_origin_); +} + +base::Optional<network::mojom::CORSError> CheckRedirectLocation( const KURL& url) { static const bool run_blink_side_scheme_check = !RuntimeEnabledFeatures::OutOfBlinkCORSEnabled(); @@ -99,12 +116,12 @@ WTF::Optional<network::mojom::CORSError> CheckRedirectLocation( return network::cors::CheckRedirectLocation(url, run_blink_side_scheme_check); } -WTF::Optional<network::mojom::CORSError> CheckPreflight( +base::Optional<network::mojom::CORSError> CheckPreflight( const int preflight_response_status_code) { return network::cors::CheckPreflight(preflight_response_status_code); } -WTF::Optional<network::mojom::CORSError> CheckExternalPreflight( +base::Optional<network::mojom::CORSError> CheckExternalPreflight( const HTTPHeaderMap& response_header) { return network::cors::CheckExternalPreflight(GetHeaderValue( response_header, HTTPNames::Access_Control_Allow_External)); @@ -210,6 +227,34 @@ bool IsCORSSafelistedHeader(const String& name, const String& value) { std::string(utf8_value.data(), utf8_value.length())); } +bool IsForbiddenHeaderName(const String& name) { + CString utf8_name = name.Utf8(); + return network::cors::IsForbiddenHeader( + std::string(utf8_name.data(), utf8_name.length())); +} + +bool ContainsOnlyCORSSafelistedHeaders(const HTTPHeaderMap& header_map) { + for (const auto& header : header_map) { + if (!IsCORSSafelistedHeader(header.key, header.value)) + return false; + } + return true; +} + +bool ContainsOnlyCORSSafelistedOrForbiddenHeaders( + const HTTPHeaderMap& header_map) { + for (const auto& header : header_map) { + if (!IsCORSSafelistedHeader(header.key, header.value) && + !IsForbiddenHeaderName(header.key)) + return false; + } + return true; +} + +bool IsOkStatus(int status) { + return network::cors::IsOkStatus(status); +} + } // namespace CORS } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors.h b/chromium/third_party/blink/renderer/platform/loader/cors/cors.h index 0ba71c770f7..e50bd9dcfd9 100644 --- a/chromium/third_party/blink/renderer/platform/loader/cors/cors.h +++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors.h @@ -5,10 +5,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_CORS_CORS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_CORS_CORS_H_ +#include "base/optional.h" #include "services/network/public/mojom/cors.mojom-shared.h" #include "services/network/public/mojom/fetch_api.mojom-shared.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -23,21 +23,28 @@ namespace CORS { // Thin wrapper functions below are for calling ::network::cors functions from // Blink core. Once Out-of-renderer CORS is enabled, following functions will // be removed. -PLATFORM_EXPORT WTF::Optional<network::mojom::CORSError> CheckAccess( +PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckAccess( const KURL&, const int response_status_code, const HTTPHeaderMap&, network::mojom::FetchCredentialsMode, const SecurityOrigin&); -PLATFORM_EXPORT WTF::Optional<network::mojom::CORSError> CheckRedirectLocation( +PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckPreflightAccess( + const KURL&, + const int response_status_code, + const HTTPHeaderMap&, + network::mojom::FetchCredentialsMode, + const SecurityOrigin&); + +PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckRedirectLocation( const KURL&); -PLATFORM_EXPORT WTF::Optional<network::mojom::CORSError> CheckPreflight( +PLATFORM_EXPORT base::Optional<network::mojom::CORSError> CheckPreflight( const int preflight_response_status_code); -PLATFORM_EXPORT WTF::Optional<network::mojom::CORSError> CheckExternalPreflight( - const HTTPHeaderMap&); +PLATFORM_EXPORT base::Optional<network::mojom::CORSError> +CheckExternalPreflight(const HTTPHeaderMap&); PLATFORM_EXPORT bool IsCORSEnabledRequestMode(network::mojom::FetchRequestMode); @@ -63,6 +70,12 @@ PLATFORM_EXPORT bool IsCORSSafelistedMethod(const String& method); PLATFORM_EXPORT bool IsCORSSafelistedContentType(const String&); PLATFORM_EXPORT bool IsCORSSafelistedHeader(const String& name, const String& value); +PLATFORM_EXPORT bool IsForbiddenHeaderName(const String& name); +PLATFORM_EXPORT bool ContainsOnlyCORSSafelistedHeaders(const HTTPHeaderMap&); +PLATFORM_EXPORT bool ContainsOnlyCORSSafelistedOrForbiddenHeaders( + const HTTPHeaderMap&); + +PLATFORM_EXPORT bool IsOkStatus(int status); } // namespace CORS diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc index e0d653ff462..03a485a9552 100644 --- a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc +++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.cc @@ -37,15 +37,25 @@ ErrorParameter CreateWrongParameter(network::mojom::CORSError error) { // static ErrorParameter ErrorParameter::Create( - const network::mojom::CORSError error, + const network::CORSErrorStatus& error_status, const KURL& first_url, const KURL& second_url, const int status_code, const HTTPHeaderMap& header_map, const SecurityOrigin& origin, const WebURLRequest::RequestContext context) { - return ErrorParameter(error, first_url, second_url, status_code, header_map, - origin, context, String(), false); + String hint; + switch (error_status.cors_error) { + case network::mojom::CORSError::kMethodDisallowedByPreflightResponse: + case network::mojom::CORSError::kHeaderDisallowedByPreflightResponse: + DCHECK(!error_status.failed_parameter.empty()); + hint = String(error_status.failed_parameter.c_str()); + break; + default: + break; + } + return ErrorParameter(error_status.cors_error, first_url, second_url, + status_code, header_map, origin, context, hint, false); } // static @@ -84,7 +94,13 @@ ErrorParameter ErrorParameter::CreateForAccessCheck( case network::mojom::CORSError::kMultipleAllowOriginValues: case network::mojom::CORSError::kInvalidAllowOriginValue: case network::mojom::CORSError::kAllowOriginMismatch: - case network::mojom::CORSError::kDisallowCredentialsNotSetToTrue: + case network::mojom::CORSError::kInvalidAllowCredentials: + case network::mojom::CORSError::kPreflightWildcardOriginNotAllowed: + case network::mojom::CORSError::kPreflightMissingAllowOriginHeader: + case network::mojom::CORSError::kPreflightMultipleAllowOriginValues: + case network::mojom::CORSError::kPreflightInvalidAllowOriginValue: + case network::mojom::CORSError::kPreflightAllowOriginMismatch: + case network::mojom::CORSError::kPreflightInvalidAllowCredentials: return ErrorParameter(error, request_url, redirect_url, response_status_code, response_header_map, origin, context, String(), false); @@ -105,6 +121,14 @@ ErrorParameter ErrorParameter::CreateForPreflightStatusCheck( } // static +ErrorParameter ErrorParameter::CreateForDisallowedRedirect() { + return ErrorParameter( + network::mojom::CORSError::kPreflightDisallowedRedirect, GetInvalidURL(), + GetInvalidURL(), 0, HTTPHeaderMap(), *SecurityOrigin::CreateUnique(), + WebURLRequest::kRequestContextUnspecified, String(), false); +} + +// static ErrorParameter ErrorParameter::CreateForExternalPreflightCheck( const network::mojom::CORSError error, const HTTPHeaderMap& response_header_map) { @@ -182,6 +206,8 @@ String GetErrorString(const ErrorParameter& param) { " Have the server send the header with a valid value, or, if an opaque " "response serves your needs, set the request's mode to 'no-cors' to " "fetch the resource with CORS disabled."; + static const char kPreflightInformation[] = + "Response to preflight request doesn't pass access control check: "; if (param.unknown) return String::Format("CORS error, code %d", static_cast<int>(param.error)); @@ -205,21 +231,31 @@ String GetErrorString(const ErrorParameter& param) { "%sInvalid response. Origin '%s' is therefore not allowed access.", redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data()); case network::mojom::CORSError::kWildcardOriginNotAllowed: + case network::mojom::CORSError::kPreflightWildcardOriginNotAllowed: return String::Format( - "%sThe value of the 'Access-Control-Allow-Origin' header in the " + "%s%sThe value of the 'Access-Control-Allow-Origin' header in the " "response must not be the wildcard '*' when the request's " "credentials mode is 'include'. Origin '%s' is therefore not allowed " "access.%s", + param.error == + network::mojom::CORSError::kPreflightWildcardOriginNotAllowed + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data(), param.context == WebURLRequest::kRequestContextXMLHttpRequest ? " The credentials mode of requests initiated by the " "XMLHttpRequest is controlled by the withCredentials attribute." : ""); case network::mojom::CORSError::kMissingAllowOriginHeader: + case network::mojom::CORSError::kPreflightMissingAllowOriginHeader: return String::Format( - "%sNo 'Access-Control-Allow-Origin' header is present on the " + "%s%sNo 'Access-Control-Allow-Origin' header is present on the " "requested resource. Origin '%s' is therefore not allowed access." "%s%s", + param.error == + network::mojom::CORSError::kPreflightMissingAllowOriginHeader + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.origin.ToString().Utf8().data(), IsInterestingStatusCode(param.status_code) ? String::Format(" The response had HTTP status code %d.", @@ -232,10 +268,15 @@ String GetErrorString(const ErrorParameter& param) { "mode to 'no-cors' to fetch the resource with CORS disabled." : ""); case network::mojom::CORSError::kMultipleAllowOriginValues: + case network::mojom::CORSError::kPreflightMultipleAllowOriginValues: return String::Format( - "%sThe 'Access-Control-Allow-Origin' header contains multiple values " - "'%s', but only one is allowed. Origin '%s' is therefore not allowed " - "access.%s", + "%s%sThe 'Access-Control-Allow-Origin' header contains multiple " + "values '%s', but only one is allowed. Origin '%s' is therefore not " + "allowed access.%s", + param.error == + network::mojom::CORSError::kPreflightMultipleAllowOriginValues + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.header_map.Get(HTTPNames::Access_Control_Allow_Origin) .Utf8() @@ -245,9 +286,14 @@ String GetErrorString(const ErrorParameter& param) { ? kNoCorsInformation : ""); case network::mojom::CORSError::kInvalidAllowOriginValue: + case network::mojom::CORSError::kPreflightInvalidAllowOriginValue: return String::Format( - "%sThe 'Access-Control-Allow-Origin' header contains the invalid " + "%s%sThe 'Access-Control-Allow-Origin' header contains the invalid " "value '%s'. Origin '%s' is therefore not allowed access.%s", + param.error == + network::mojom::CORSError::kPreflightInvalidAllowOriginValue + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.header_map.Get(HTTPNames::Access_Control_Allow_Origin) .Utf8() @@ -257,10 +303,15 @@ String GetErrorString(const ErrorParameter& param) { ? kNoCorsInformation : ""); case network::mojom::CORSError::kAllowOriginMismatch: + case network::mojom::CORSError::kPreflightAllowOriginMismatch: return String::Format( - "%sThe 'Access-Control-Allow-Origin' header has a value '%s' that is " - "not equal to the supplied origin. Origin '%s' is therefore not " + "%s%sThe 'Access-Control-Allow-Origin' header has a value '%s' that " + "is not equal to the supplied origin. Origin '%s' is therefore not " "allowed access.%s", + param.error == + network::mojom::CORSError::kPreflightAllowOriginMismatch + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.header_map.Get(HTTPNames::Access_Control_Allow_Origin) .Utf8() @@ -269,12 +320,17 @@ String GetErrorString(const ErrorParameter& param) { param.context == WebURLRequest::kRequestContextFetch ? kNoCorsInformation : ""); - case network::mojom::CORSError::kDisallowCredentialsNotSetToTrue: + case network::mojom::CORSError::kInvalidAllowCredentials: + case network::mojom::CORSError::kPreflightInvalidAllowCredentials: return String::Format( - "%sThe value of the 'Access-Control-Allow-Credentials' header in " + "%s%sThe value of the 'Access-Control-Allow-Credentials' header in " "the response is '%s' which must be 'true' when the request's " "credentials mode is 'include'. Origin '%s' is therefore not allowed " "access.%s", + param.error == + network::mojom::CORSError::kPreflightInvalidAllowCredentials + ? kPreflightInformation + : "", redirect_denied.Utf8().data(), param.header_map.Get(HTTPNames::Access_Control_Allow_Credentials) .Utf8() @@ -286,9 +342,9 @@ String GetErrorString(const ErrorParameter& param) { "attribute." : "")); case network::mojom::CORSError::kPreflightInvalidStatus: - return String::Format( - "Response for preflight has invalid HTTP status code %d.", - param.status_code); + return String("Response for preflight does not have HTTP ok status."); + case network::mojom::CORSError::kPreflightDisallowedRedirect: + return String("Response for preflight is invalid (redirect)"); case network::mojom::CORSError::kPreflightMissingAllowExternal: return String( "No 'Access-Control-Allow-External' header was present in the " diff --git a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h index 73bd0f9e07d..35dab0a940c 100644 --- a/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h +++ b/chromium/third_party/blink/renderer/platform/loader/cors/cors_error_string.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_CORS_CORS_ERROR_STRING_H_ #include "base/macros.h" +#include "services/network/public/cpp/cors/cors_error_status.h" #include "services/network/public/mojom/cors.mojom-shared.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -23,7 +24,7 @@ namespace CORS { struct PLATFORM_EXPORT ErrorParameter { // Creates an ErrorParameter for generic cases. Use this function if |error| // can contain any. - static ErrorParameter Create(const network::mojom::CORSError, + static ErrorParameter Create(const network::CORSErrorStatus&, const KURL& first_url, const KURL& second_url, const int status_code, @@ -54,6 +55,9 @@ struct PLATFORM_EXPORT ErrorParameter { // CORS::CheckPreflight() returns. static ErrorParameter CreateForPreflightStatusCheck(int response_status_code); + // Creates an ErrorParameter for kPreflightDisallowedRedirect. + static ErrorParameter CreateForDisallowedRedirect(); + // Creates an ErrorParameter for an error that CORS::CheckExternalPreflight() // returns. static ErrorParameter CreateForExternalPreflightCheck( diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_data_pipe_writer_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_data_pipe_writer_test.cc index 0788a286d23..0ce03bb6188 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_data_pipe_writer_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/buffering_data_pipe_writer_test.cc @@ -24,7 +24,7 @@ TEST(BufferingDataPipeWriterTest, WriteMany) { mojo::ScopedDataPipeConsumerHandle consumer; MojoCreateDataPipeOptions options; options.struct_size = sizeof(MojoCreateDataPipeOptions); - options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; + options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; options.element_num_bytes = 1; options.capacity_num_bytes = kCapacity; 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 ab5e1ae5900..345744206a4 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 @@ -31,7 +31,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/fetch_context.h" #include "third_party/blink/renderer/platform/PlatformProbeSink.h" -#include "third_party/blink/renderer/platform/probe/PlatformTraceEventsAgent.h" +#include "third_party/blink/renderer/platform/probe/platform_trace_events_agent.h" namespace blink { @@ -40,8 +40,7 @@ FetchContext& FetchContext::NullInstance() { } FetchContext::FetchContext() : platform_probe_sink_(new PlatformProbeSink) { - platform_probe_sink_->addPlatformTraceEventsAgent( - new PlatformTraceEventsAgent); + platform_probe_sink_->addPlatformTraceEvents(new PlatformTraceEventsAgent); } void FetchContext::Trace(blink::Visitor* visitor) { @@ -93,7 +92,7 @@ void FetchContext::DispatchDidDownloadToBlob(unsigned long identifier, BlobDataHandle*) {} void FetchContext::DispatchDidFinishLoading(unsigned long, - double, + TimeTicks, int64_t, int64_t, bool) {} 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 600b89d2900..5ed4a1b91eb 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 @@ -31,9 +31,12 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_FETCH_CONTEXT_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_FETCH_CONTEXT_H_ +#include "base/optional.h" +#include "base/single_thread_task_runner.h" #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" #include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/resource_request_blocked_reason.h" #include "third_party/blink/public/platform/web_application_cache_host.h" #include "third_party/blink/public/platform/web_url_loader.h" #include "third_party/blink/public/platform/web_url_request.h" @@ -151,7 +154,7 @@ class PLATFORM_EXPORT FetchContext virtual void DispatchDidDownloadToBlob(unsigned long identifier, BlobDataHandle*); virtual void DispatchDidFinishLoading(unsigned long identifier, - double finish_time, + TimeTicks finish_time, int64_t encoded_data_length, int64_t decoded_body_length, bool blocked_cross_site_document); @@ -173,7 +176,7 @@ class PLATFORM_EXPORT FetchContext virtual void AddResourceTiming(const ResourceTimingInfo&); virtual bool AllowImage(bool, const KURL&) const { return false; } - virtual ResourceRequestBlockedReason CanRequest( + virtual base::Optional<ResourceRequestBlockedReason> CanRequest( Resource::Type, const ResourceRequest&, const KURL&, @@ -183,7 +186,7 @@ class PLATFORM_EXPORT FetchContext ResourceRequest::RedirectStatus) const { return ResourceRequestBlockedReason::kOther; } - virtual ResourceRequestBlockedReason CheckCSPForRequest( + virtual base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( WebURLRequest::RequestContext, const KURL&, const ResourceLoaderOptions&, @@ -191,7 +194,7 @@ class PLATFORM_EXPORT FetchContext ResourceRequest::RedirectStatus) const { return ResourceRequestBlockedReason::kOther; } - virtual ResourceRequestBlockedReason CheckResponseNosniff( + virtual base::Optional<ResourceRequestBlockedReason> CheckResponseNosniff( WebURLRequest::RequestContext, const ResourceResponse&) const { return ResourceRequestBlockedReason::kOther; 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 7dd29cbbd58..970713f10d2 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 @@ -37,7 +37,6 @@ FetchParameters::FetchParameters(const ResourceRequest& resource_request) : resource_request_(resource_request), decoder_options_(TextResourceDecoderOptions::kPlainTextContent), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), - preload_discovery_time_(0.0), defer_(kNoDefer), origin_restriction_(kUseDefaultOriginRestrictionForType), placeholder_image_request_type_(kDisallowPlaceholder) {} @@ -48,7 +47,6 @@ FetchParameters::FetchParameters( decoder_options_(data->decoder_options), options_(data->options), speculative_preload_type_(data->speculative_preload_type), - preload_discovery_time_(data->preload_discovery_time), defer_(data->defer), origin_restriction_(data->origin_restriction), resource_width_(data->resource_width), @@ -61,7 +59,6 @@ FetchParameters::FetchParameters(const ResourceRequest& resource_request, decoder_options_(TextResourceDecoderOptions::kPlainTextContent), options_(options), speculative_preload_type_(SpeculativePreloadType::kNotSpeculative), - preload_discovery_time_(0.0), defer_(kNoDefer), origin_restriction_(kUseDefaultOriginRestrictionForType), placeholder_image_request_type_(kDisallowPlaceholder) {} @@ -115,18 +112,12 @@ void FetchParameters::SetSpeculativePreloadType( SpeculativePreloadType speculative_preload_type, double discovery_time) { speculative_preload_type_ = speculative_preload_type; - preload_discovery_time_ = discovery_time; } void FetchParameters::MakeSynchronous() { // Synchronous requests should always be max priority, lest they hang the // renderer. resource_request_.SetPriority(ResourceLoadPriority::kHighest); - if (resource_request_.TimeoutInterval() == INT_MAX) { - // This 1 day timeout is a temporary value to avoid the 100% CPU usage bug - // in stable (crbug/848210) and mitigate the timeout bug (crbug/844268). - resource_request_.SetTimeoutInterval(60 * 60 * 24); - } // Skip ServiceWorker for synchronous loads from the main thread to avoid // deadlocks. if (IsMainThread()) @@ -166,7 +157,6 @@ std::unique_ptr<CrossThreadFetchParametersData> FetchParameters::CopyData() data->decoder_options = decoder_options_; data->options = CrossThreadResourceLoaderOptionsData(options_); data->speculative_preload_type = speculative_preload_type_; - data->preload_discovery_time = preload_discovery_time_; data->defer = defer_; data->origin_restriction = origin_restriction_; data->resource_width = resource_width_; 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 4ed9aba1b11..3948868c91e 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 @@ -93,6 +93,10 @@ class PLATFORM_EXPORT FetchParameters { resource_request_.SetRequestContext(context); } + void SetFetchImportanceMode(mojom::FetchImportanceMode importance_mode) { + resource_request_.SetFetchImportanceMode(importance_mode); + } + const TextResourceDecoderOptions& DecoderOptions() const { return decoder_options_; } @@ -130,8 +134,6 @@ class PLATFORM_EXPORT FetchParameters { void SetSpeculativePreloadType(SpeculativePreloadType, double discovery_time = 0); - double PreloadDiscoveryTime() const { return preload_discovery_time_; } - bool IsLinkPreload() const { return options_.initiator_info.is_link_preload; } void SetLinkPreload(bool is_link_preload) { options_.initiator_info.is_link_preload = is_link_preload; @@ -199,7 +201,6 @@ class PLATFORM_EXPORT FetchParameters { TextResourceDecoderOptions decoder_options_; ResourceLoaderOptions options_; SpeculativePreloadType speculative_preload_type_; - double preload_discovery_time_; DeferOption defer_; OriginRestriction origin_restriction_; ResourceWidth resource_width_; @@ -228,7 +229,6 @@ struct CrossThreadFetchParametersData { TextResourceDecoderOptions decoder_options; CrossThreadResourceLoaderOptionsData options; FetchParameters::SpeculativePreloadType speculative_preload_type; - double preload_discovery_time; FetchParameters::DeferOption defer; FetchParameters::OriginRestriction origin_restriction; FetchParameters::ResourceWidth resource_width; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc index 643ed618ac3..89eee30c487 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.cc @@ -5,7 +5,6 @@ #include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h" #include "services/network/public/cpp/cors/cors.h" -#include "third_party/blink/renderer/platform/loader/cors/cors.h" #include "third_party/blink/renderer/platform/network/http_header_map.h" #include "third_party/blink/renderer/platform/network/http_names.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" @@ -33,12 +32,6 @@ bool FetchUtils::IsForbiddenMethod(const String& method) { EqualIgnoringASCIICase(method, "CONNECT"); } -bool FetchUtils::IsForbiddenHeaderName(const String& name) { - const CString utf8_name = name.Utf8(); - return network::cors::IsForbiddenHeader( - std::string(utf8_name.data(), utf8_name.length())); -} - bool FetchUtils::IsForbiddenResponseHeaderName(const String& name) { // http://fetch.spec.whatwg.org/#forbidden-response-header-name // "A forbidden response header name is a header name that is one of: @@ -75,23 +68,4 @@ String FetchUtils::NormalizeHeaderValue(const String& value) { return value.StripWhiteSpace(IsHTTPWhitespace); } -bool FetchUtils::ContainsOnlyCORSSafelistedHeaders( - const HTTPHeaderMap& header_map) { - for (const auto& header : header_map) { - if (!CORS::IsCORSSafelistedHeader(header.key, header.value)) - return false; - } - return true; -} - -bool FetchUtils::ContainsOnlyCORSSafelistedOrForbiddenHeaders( - const HTTPHeaderMap& header_map) { - for (const auto& header : header_map) { - if (!CORS::IsCORSSafelistedHeader(header.key, header.value) && - !IsForbiddenHeaderName(header.key)) - return false; - } - return true; -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h index 991ffcce318..f5ab97e7fbe 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/fetch_utils.h @@ -12,25 +12,14 @@ namespace blink { -class HTTPHeaderMap; - class PLATFORM_EXPORT FetchUtils { STATIC_ONLY(FetchUtils); public: static bool IsForbiddenMethod(const String& method); - static bool IsForbiddenHeaderName(const String& name); static bool IsForbiddenResponseHeaderName(const String& name); static AtomicString NormalizeMethod(const AtomicString& method); static String NormalizeHeaderValue(const String& value); - static bool ContainsOnlyCORSSafelistedHeaders(const HTTPHeaderMap&); - static bool ContainsOnlyCORSSafelistedOrForbiddenHeaders( - const HTTPHeaderMap&); - - // https://fetch.spec.whatwg.org/#ok-status aka a successful 2xx status - // code, https://tools.ietf.org/html/rfc7231#section-6.3 . We opt to use - // the Fetch term in naming the predicate. - static bool IsOkStatus(int status) { return status >= 200 && status < 300; } }; } // namespace blink 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 20be134ae12..c3d91db16b8 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 @@ -22,13 +22,13 @@ #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" +#include "base/auto_reset.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loading_log.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_origin_hash.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -416,7 +416,7 @@ void MemoryCache::PruneNow(double current_time, PruneStrategy strategy) { Platform::Current()->CurrentThread()->RemoveTaskObserver(this); } - AutoReset<bool> reentrancy_protector(&in_prune_resources_, true); + base::AutoReset<bool> reentrancy_protector(&in_prune_resources_, true); PruneResources(strategy); prune_frame_time_stamp_ = last_frame_paint_time_stamp_; 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 083f95fa3f8..309a75c3ef5 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 @@ -36,7 +36,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h" #include "third_party/blink/renderer/platform/network/http_names.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" namespace blink { @@ -300,7 +300,7 @@ bool RawResource::MatchPreload(const FetchParameters& params, mojo::ScopedDataPipeConsumerHandle consumer; MojoCreateDataPipeOptions options; options.struct_size = sizeof(MojoCreateDataPipeOptions); - options.flags = MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE; + options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE; options.element_num_bytes = 1; options.capacity_num_bytes = kCapacity; 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 88c232ccea0..25777998d67 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 @@ -25,13 +25,13 @@ #include <memory> +#include "base/optional.h" #include "third_party/blink/public/platform/web_data_consumer_handle.h" #include "third_party/blink/renderer/platform/loader/fetch/buffering_data_pipe_writer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { class WebDataConsumerHandle; @@ -91,7 +91,7 @@ class PLATFORM_EXPORT RawResource final : public Resource { // keyed by the source code of the script. SourceKeyedCachedMetadataHandler* CacheHandler(); - WTF::Optional<int64_t> DownloadedFileLength() const { + base::Optional<int64_t> DownloadedFileLength() const { return downloaded_file_length_; } scoped_refptr<BlobDataHandle> DownloadedBlob() const { @@ -134,7 +134,7 @@ class PLATFORM_EXPORT RawResource final : public Resource { base::SingleThreadTaskRunner*) override; void NotifyFinished() override; - WTF::Optional<int64_t> downloaded_file_length_; + base::Optional<int64_t> downloaded_file_length_; scoped_refptr<BlobDataHandle> downloaded_blob_; // Used for preload matching. diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc index 3a973b9476e..9d75c8fb7b4 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/raw_resource_test.cc @@ -40,7 +40,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_timing_info.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" 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 13a3f06f3d0..0dbbd999d45 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.cc @@ -49,7 +49,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_finish_observer.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h" #include "third_party/blink/renderer/platform/network/http_parsers.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -99,14 +99,13 @@ const char* const kHeaderPrefixesToIgnoreAfterRevalidation[] = { static inline bool ShouldUpdateHeaderAfterRevalidation( const AtomicString& header) { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kHeadersToIgnoreAfterRevalidation); - i++) { + for (size_t i = 0; i < arraysize(kHeadersToIgnoreAfterRevalidation); i++) { if (DeprecatedEqualIgnoringCase(header, kHeadersToIgnoreAfterRevalidation[i])) return false; } - for (size_t i = 0; - i < WTF_ARRAY_LENGTH(kHeaderPrefixesToIgnoreAfterRevalidation); i++) { + for (size_t i = 0; i < arraysize(kHeaderPrefixesToIgnoreAfterRevalidation); + i++) { if (header.StartsWithIgnoringASCIICase( kHeaderPrefixesToIgnoreAfterRevalidation[i])) return false; @@ -187,9 +186,7 @@ Resource::Resource(const ResourceRequest& request, const ResourceLoaderOptions& options) : type_(type), status_(ResourceStatus::kNotStarted), - load_finish_time_(0), identifier_(0), - preload_discovery_time_(0.0), encoded_size_(0), encoded_size_memory_usage_(0), decoded_size_(0), @@ -357,7 +354,7 @@ void Resource::FinishAsError(const ResourceError& error, NotifyFinished(); } -void Resource::Finish(double load_finish_time, +void Resource::Finish(TimeTicks load_finish_time, base::SingleThreadTaskRunner* task_runner) { DCHECK(!is_revalidating_); load_finish_time_ = load_finish_time; @@ -375,7 +372,7 @@ AtomicString Resource::HttpContentType() const { bool Resource::PassesAccessControlCheck( const SecurityOrigin& security_origin) const { - WTF::Optional<network::mojom::CORSError> cors_error = CORS::CheckAccess( + base::Optional<network::mojom::CORSError> cors_error = CORS::CheckAccess( GetResponse().Url(), GetResponse().HttpStatusCode(), GetResponse().HttpHeaderFields(), LastResourceRequest().GetFetchCredentialsMode(), security_origin); @@ -520,15 +517,6 @@ std::unique_ptr<CachedMetadataSender> Resource::CreateCachedMetadataSender() void Resource::ResponseReceived(const ResourceResponse& response, std::unique_ptr<WebDataConsumerHandle>) { response_timestamp_ = CurrentTime(); - if (preload_discovery_time_) { - int time_since_discovery = static_cast<int>( - 1000 * (CurrentTimeTicksInSeconds() - preload_discovery_time_)); - DEFINE_STATIC_LOCAL(CustomCountHistogram, - preload_discovery_to_first_byte_histogram, - ("PreloadScanner.TTFB", 0, 10000, 50)); - preload_discovery_to_first_byte_histogram.Count(time_since_discovery); - } - if (is_revalidating_) { if (response.HttpStatusCode() == 304) { RevalidationSucceeded(response); @@ -705,7 +693,7 @@ void Resource::DidRemoveClientOrObserver() { } void Resource::AllClientsAndObserversRemoved() { - if (loader_ && !detachable_) + if (loader_) loader_->ScheduleCancel(); } @@ -1024,14 +1012,6 @@ bool Resource::MatchPreload(const FetchParameters& params, base::SingleThreadTaskRunner*) { DCHECK(is_unused_preload_); is_unused_preload_ = false; - - if (preload_discovery_time_) { - int time_since_discovery = static_cast<int>( - 1000 * (CurrentTimeTicksInSeconds() - preload_discovery_time_)); - DEFINE_STATIC_LOCAL(CustomCountHistogram, preload_discovery_histogram, - ("PreloadScanner.ReferenceTime", 0, 10000, 50)); - preload_discovery_histogram.Count(time_since_discovery); - } return true; } 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 b68b9c5abb0..c6159e3d9d3 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource.h @@ -25,6 +25,8 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_H_ #include <memory> +#include "base/auto_reset.h" +#include "base/optional.h" #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_data_consumer_handle.h" #include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h" @@ -47,13 +49,12 @@ #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/web_task_runner.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/auto_reset.h" #include "third_party/blink/renderer/platform/wtf/hash_counted_set.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -127,10 +128,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, void SetLinkPreload(bool is_link_preload) { link_preload_ = is_link_preload; } bool IsLinkPreload() const { return link_preload_; } - void SetPreloadDiscoveryTime(double preload_discovery_time) { - preload_discovery_time_ = preload_discovery_time; - } - const ResourceError& GetResourceError() const { DCHECK(error_); return *error_; @@ -166,9 +163,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, // base::SingleThreadTaskRunner is unused. void AddClient(ResourceClient*, base::SingleThreadTaskRunner*); void RemoveClient(ResourceClient*); - // Once called, this resource will not be canceled until load finishes - // even if associated with no client. - void SetDetachable() { detachable_ = true; } // If this Resource is already finished when AddFinishObserver is called, the // ResourceFinishObserver will be notified asynchronously by a task scheduled @@ -218,8 +212,8 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, // Computes the status of an object after loading. Updates the expire date on // the cache entry file - virtual void Finish(double finish_time, base::SingleThreadTaskRunner*); - void FinishForTest() { Finish(0.0, nullptr); } + virtual void Finish(TimeTicks finish_time, base::SingleThreadTaskRunner*); + void FinishForTest() { Finish(TimeTicks(), nullptr); } bool PassesAccessControlCheck(const SecurityOrigin&) const; @@ -308,7 +302,7 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, virtual void DidDownloadData(int) {} virtual void DidDownloadToBlob(scoped_refptr<BlobDataHandle>) {} - double LoadFinishTime() const { return load_finish_time_; } + TimeTicks LoadFinishTime() const { return load_finish_time_; } void SetEncodedDataLength(int64_t value) { response_.SetEncodedDataLength(value); @@ -358,13 +352,13 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, Type, const AtomicString& fetch_initiator_name); - class ProhibitAddRemoveClientInScope : public AutoReset<bool> { + class ProhibitAddRemoveClientInScope : public base::AutoReset<bool> { public: ProhibitAddRemoveClientInScope(Resource* resource) : AutoReset(&resource->is_add_remove_client_prohibited_, true) {} }; - class RevalidationStartForbiddenScope : public AutoReset<bool> { + class RevalidationStartForbiddenScope : public base::AutoReset<bool> { public: RevalidationStartForbiddenScope(Resource* resource) : AutoReset(&resource->is_revalidation_start_forbidden_, true) {} @@ -495,14 +489,12 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, Member<CachedMetadataHandler> cache_handler_; - Optional<ResourceError> error_; + base::Optional<ResourceError> error_; - double load_finish_time_; + TimeTicks load_finish_time_; unsigned long identifier_; - double preload_discovery_time_; - size_t encoded_size_; size_t encoded_size_memory_usage_; size_t decoded_size_; @@ -521,7 +513,6 @@ class PLATFORM_EXPORT Resource : public GarbageCollectedFinalized<Resource>, bool is_add_remove_client_prohibited_; bool is_revalidation_start_forbidden_ = false; bool is_unused_preload_ = false; - bool detachable_ = false; ResourceIntegrityDisposition integrity_disposition_; SubresourceIntegrity::ReportInfo integrity_report_info_; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc index 4a4c0e1f55f..9a84d2c09d3 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.cc @@ -28,6 +28,7 @@ #include "net/base/net_errors.h" #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/resource_request_blocked_reason.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" @@ -46,7 +47,7 @@ int ResourceError::BlockedByXSSAuditorErrorCode() { } ResourceError ResourceError::CancelledError(const KURL& url) { - return ResourceError(net::ERR_ABORTED, url, WTF::nullopt); + return ResourceError(net::ERR_ABORTED, url, base::nullopt); } ResourceError ResourceError::CancelledDueToAccessCheckError( @@ -69,21 +70,21 @@ ResourceError ResourceError::CancelledDueToAccessCheckError( } ResourceError ResourceError::CacheMissError(const KURL& url) { - return ResourceError(net::ERR_CACHE_MISS, url, WTF::nullopt); + return ResourceError(net::ERR_CACHE_MISS, url, base::nullopt); } ResourceError ResourceError::TimeoutError(const KURL& url) { - return ResourceError(net::ERR_TIMED_OUT, url, WTF::nullopt); + return ResourceError(net::ERR_TIMED_OUT, url, base::nullopt); } ResourceError ResourceError::Failure(const KURL& url) { - return ResourceError(net::ERR_FAILED, url, WTF::nullopt); + return ResourceError(net::ERR_FAILED, url, base::nullopt); } ResourceError::ResourceError( int error_code, const KURL& url, - WTF::Optional<network::CORSErrorStatus> cors_error_status) + base::Optional<network::CORSErrorStatus> cors_error_status) : error_code_(error_code), failing_url_(url), cors_error_status_(cors_error_status) { @@ -148,6 +149,9 @@ bool ResourceError::Compare(const ResourceError& a, const ResourceError& b) { if (a.CORSErrorStatus() != b.CORSErrorStatus()) return false; + if (a.extended_error_code_ != b.extended_error_code_) + return false; + return true; } @@ -167,9 +171,54 @@ bool ResourceError::WasBlockedByResponse() const { return error_code_ == net::ERR_BLOCKED_BY_RESPONSE; } +base::Optional<ResourceRequestBlockedReason> +ResourceError::GetResourceRequestBlockedReason() const { + if (error_code_ != net::ERR_BLOCKED_BY_CLIENT && + error_code_ != net::ERR_BLOCKED_BY_RESPONSE) { + return base::nullopt; + } + return static_cast<ResourceRequestBlockedReason>(extended_error_code_); +} + +namespace { +String DescriptionForBlockedByClientOrResponse(int error, int extended_error) { + if (extended_error == 0) + return WebString::FromASCII(net::ErrorToString(error)); + std::string detail; + switch (static_cast<ResourceRequestBlockedReason>(extended_error)) { + case ResourceRequestBlockedReason::kOther: + NOTREACHED(); // extended_error == 0, handled above + break; + case ResourceRequestBlockedReason::kCSP: + detail = "CSP"; + break; + case ResourceRequestBlockedReason::kMixedContent: + detail = "MixedContent"; + break; + case ResourceRequestBlockedReason::kOrigin: + detail = "Origin"; + break; + case ResourceRequestBlockedReason::kInspector: + detail = "Inspector"; + break; + case ResourceRequestBlockedReason::kSubresourceFilter: + detail = "SubresourceFilter"; + break; + case ResourceRequestBlockedReason::kContentType: + detail = "ContentType"; + break; + } + return WebString::FromASCII(net::ErrorToString(error) + "." + detail); +} +} // namespace + void ResourceError::InitializeDescription() { if (error_code_ == net::ERR_TEMPORARILY_THROTTLED) { localized_description_ = WebString::FromASCII(kThrottledErrorDescription); + } else if (error_code_ == net::ERR_BLOCKED_BY_CLIENT || + error_code_ == net::ERR_BLOCKED_BY_RESPONSE) { + localized_description_ = DescriptionForBlockedByClientOrResponse( + error_code_, extended_error_code_); } else { localized_description_ = WebString::FromASCII( net::ExtendedErrorToString(error_code_, extended_error_code_)); diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h index ea6e0f6acb2..894622598b3 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_error.h @@ -28,12 +28,12 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_ERROR_H_ #include <iosfwd> +#include "base/optional.h" #include "services/network/public/cpp/cors/cors_error_status.h" #include "third_party/blink/public/platform/web_url_error.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.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -63,7 +63,7 @@ class PLATFORM_EXPORT ResourceError final { // |error_code| must not be 0. ResourceError(int error_code, const KURL& failing_url, - WTF::Optional<network::CORSErrorStatus>); + base::Optional<network::CORSErrorStatus>); ResourceError(const WebURLError&); // Makes a deep copy. Useful for when you need to use a ResourceError on @@ -81,8 +81,10 @@ class PLATFORM_EXPORT ResourceError final { bool IsCacheMiss() const; bool WasBlockedByResponse() const; bool ShouldCollapseInitiator() const { return should_collapse_initiator_; } + base::Optional<ResourceRequestBlockedReason> GetResourceRequestBlockedReason() + const; - WTF::Optional<network::CORSErrorStatus> CORSErrorStatus() const { + base::Optional<network::CORSErrorStatus> CORSErrorStatus() const { return cors_error_status_; } @@ -97,13 +99,13 @@ class PLATFORM_EXPORT ResourceError final { void InitializeDescription(); int error_code_; - int extended_error_code_; + int extended_error_code_ = 0; KURL failing_url_; String localized_description_; bool is_access_check_ = false; bool has_copy_in_cache_ = false; bool should_collapse_initiator_ = false; - WTF::Optional<network::CORSErrorStatus> cors_error_status_; + base::Optional<network::CORSErrorStatus> cors_error_status_; }; inline bool operator==(const ResourceError& a, const ResourceError& b) { 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 7a5b12a467f..8bd77ea2f64 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 @@ -55,7 +55,7 @@ #include "third_party/blink/renderer/platform/network/network_utils.h" #include "third_party/blink/renderer/platform/probe/platform_probes.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/weborigin/known_ports.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" @@ -63,6 +63,7 @@ #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/wtf.h" using blink::WebURLRequest; @@ -162,6 +163,61 @@ bool ShouldResourceBeAddedToMemoryCache(const FetchParameters& params, return true; } +static ResourceFetcher::ResourceFetcherSet& MainThreadFetchersSet() { + DEFINE_STATIC_LOCAL(ResourceFetcher::ResourceFetcherSet, fetchers, ()); + return fetchers; +} + +ResourceLoadPriority AdjustPriorityWithPriorityHint( + ResourceLoadPriority priority_so_far, + Resource::Type type, + const ResourceRequest& resource_request, + FetchParameters::DeferOption defer_option, + bool is_link_preload) { + mojom::FetchImportanceMode importance_mode = + resource_request.GetFetchImportanceMode(); + + ResourceLoadPriority new_priority = priority_so_far; + + switch (importance_mode) { + case mojom::FetchImportanceMode::kImportanceAuto: + break; + case mojom::FetchImportanceMode::kImportanceHigh: + // Boost priority of + // - Late and async scripts + // - Images + // - Prefetch + if ((type == Resource::kScript && + (FetchParameters::kLazyLoad == defer_option)) || + type == Resource::kImage || type == Resource::kLinkPrefetch) { + new_priority = ResourceLoadPriority::kHigh; + } + + DCHECK_LE(priority_so_far, new_priority); + break; + case mojom::FetchImportanceMode::kImportanceLow: + // Demote priority of: + // - Images + // Note: this will only have a real effect on in-viewport images since + // 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 + if (type == Resource::kImage || + resource_request.GetRequestContext() == + WebURLRequest::RequestContext::kRequestContextFetch || + is_link_preload) { + new_priority = ResourceLoadPriority::kLow; + } + + DCHECK_LE(new_priority, priority_so_far); + break; + } + + return new_priority; +} + } // namespace ResourceLoadPriority ResourceFetcher::ComputeLoadPriority( @@ -218,6 +274,11 @@ ResourceLoadPriority ResourceFetcher::ComputeLoadPriority( priority = ResourceLoadPriority::kVeryLow; } + if (RuntimeEnabledFeatures::PriorityHintsEnabled()) { + priority = AdjustPriorityWithPriorityHint(priority, type, resource_request, + defer_option, is_link_preload); + } + // A manually set priority acts as a floor. This is used to ensure that // synchronous requests are always given the highest possible priority, as // well as to ensure that there isn't priority churn if images move in and out @@ -297,6 +358,8 @@ ResourceFetcher::ResourceFetcher(FetchContext* new_context) allow_stale_resources_(false), image_fetched_(false) { InstanceCounters::IncrementCounter(InstanceCounters::kResourceFetcherCounter); + if (IsMainThread()) + MainThreadFetchersSet().insert(this); } ResourceFetcher::~ResourceFetcher() { @@ -365,7 +428,7 @@ void ResourceFetcher::RequestLoadStarted(unsigned long identifier, // Resources loaded from memory cache should be reported the first time // they're used. scoped_refptr<ResourceTimingInfo> info = ResourceTimingInfo::Create( - params.Options().initiator_info.name, CurrentTimeTicksInSeconds(), + params.Options().initiator_info.name, CurrentTimeTicks(), resource->GetType() == Resource::kMainResource); PopulateTimingInfo(info.get(), resource); info->ClearLoadTimings(); @@ -403,7 +466,8 @@ void ResourceFetcher::DidLoadResourceFromMemoryCache( } Context().DispatchDidFinishLoading( - identifier, 0, 0, resource->GetResponse().DecodedBodyLength(), false); + identifier, TimeTicks(), 0, resource->GetResponse().DecodedBodyLength(), + false); } static std::unique_ptr<TracedValue> UrlForTraceEvent(const KURL& url) { @@ -431,13 +495,17 @@ Resource* ResourceFetcher::ResourceForStaticData( return nullptr; const String cache_identifier = GetCacheIdentifier(); - if (Resource* old_resource = - GetMemoryCache()->ResourceForURL(url, cache_identifier)) { - // There's no reason to re-parse if we saved the data from the previous - // parse. - if (params.Options().data_buffering_policy != kDoNotBufferData) - return old_resource; - GetMemoryCache()->Remove(old_resource); + // Most off-main-thread resource fetches use Resource::kRaw and don't reach + // this point, but off-main-thread module fetches might. + if (IsMainThread()) { + if (Resource* old_resource = + GetMemoryCache()->ResourceForURL(url, cache_identifier)) { + // There's no reason to re-parse if we saved the data from the previous + // parse. + if (params.Options().data_buffering_policy != kDoNotBufferData) + return old_resource; + GetMemoryCache()->Remove(old_resource); + } } ResourceResponse response; @@ -479,7 +547,7 @@ Resource* ResourceFetcher::ResourceForStaticData( resource->SetIdentifier(CreateUniqueIdentifier()); resource->SetCacheIdentifier(cache_identifier); resource->SetSourceOrigin(GetSourceOrigin(params.Options())); - resource->Finish(0.0, Context().GetLoadingTaskRunner().get()); + resource->Finish(TimeTicks(), Context().GetLoadingTaskRunner().get()); if (!substitute_data.IsValid()) AddToMemoryCacheIfNeeded(params, resource); @@ -552,7 +620,7 @@ void ResourceFetcher::RemovePreload(Resource* resource) { preloads_.erase(it); } -ResourceRequestBlockedReason ResourceFetcher::PrepareRequest( +base::Optional<ResourceRequestBlockedReason> ResourceFetcher::PrepareRequest( FetchParameters& params, const ResourceFactory& factory, const SubstituteData& substitute_data, @@ -619,16 +687,17 @@ ResourceRequestBlockedReason ResourceFetcher::PrepareRequest( resource_request.Priority()); KURL url = MemoryCache::RemoveFragmentIdentifierIfNeeded(params.Url()); - ResourceRequestBlockedReason blocked_reason = Context().CanRequest( - resource_type, resource_request, url, options, reporting_policy, - params.GetOriginRestriction(), resource_request.GetRedirectStatus()); + base::Optional<ResourceRequestBlockedReason> blocked_reason = + Context().CanRequest(resource_type, resource_request, url, options, + reporting_policy, params.GetOriginRestriction(), + resource_request.GetRedirectStatus()); if (Context().IsAdResource(url, resource_type, resource_request.GetRequestContext())) { resource_request.SetIsAdResource(); } - if (blocked_reason != ResourceRequestBlockedReason::kNone) + if (blocked_reason) return blocked_reason; const scoped_refptr<const SecurityOrigin>& origin = options.security_origin; @@ -672,7 +741,7 @@ ResourceRequestBlockedReason ResourceFetcher::PrepareRequest( resource_request.SetAllowStoredCredentials(allow_stored_credentials); } - return ResourceRequestBlockedReason::kNone; + return base::nullopt; } Resource* ResourceFetcher::RequestResource( @@ -718,10 +787,10 @@ Resource* ResourceFetcher::RequestResourceInternal( } } - ResourceRequestBlockedReason blocked_reason = + base::Optional<ResourceRequestBlockedReason> blocked_reason = PrepareRequest(params, factory, substitute_data, identifier); - if (blocked_reason != ResourceRequestBlockedReason::kNone) - return ResourceForBlockedRequest(params, factory, blocked_reason); + if (blocked_reason) + return ResourceForBlockedRequest(params, factory, blocked_reason.value()); Resource::Type resource_type = factory.GetType(); @@ -906,9 +975,6 @@ Resource* ResourceFetcher::CreateResourceForLoading( Resource* resource = factory.Create( params.GetResourceRequest(), params.Options(), params.DecoderOptions()); resource->SetLinkPreload(params.IsLinkPreload()); - if (params.IsSpeculativePreload()) { - resource->SetPreloadDiscoveryTime(params.PreloadDiscoveryTime()); - } resource->SetCacheIdentifier(cache_identifier); resource->SetSourceOrigin(GetSourceOrigin(params.Options())); @@ -926,9 +992,10 @@ void ResourceFetcher::StorePerformanceTimingInitiatorInformation( // The request can already be fetched in a previous navigation. Thus // startTime must be set accordingly. - double start_time = resource->GetResourceRequest().NavigationStartTime() - ? resource->GetResourceRequest().NavigationStartTime() - : CurrentTimeTicksInSeconds(); + TimeTicks start_time = + !resource->GetResourceRequest().NavigationStartTime().is_null() + ? resource->GetResourceRequest().NavigationStartTime() + : CurrentTimeTicks(); // This buffer is created and populated for providing transferSize // and redirect timing opt-in information. @@ -1389,7 +1456,7 @@ void ResourceFetcher::HandleLoadCompletion(Resource* resource) { } void ResourceFetcher::HandleLoaderFinish(Resource* resource, - double finish_time, + TimeTicks finish_time, LoaderFinishType type, uint32_t inflight_keepalive_bytes, bool blocked_cross_site_document) { @@ -1484,8 +1551,7 @@ void ResourceFetcher::HandleLoaderError(Resource* resource, void ResourceFetcher::MoveResourceLoaderToNonBlocking(ResourceLoader* loader) { DCHECK(loader); - // TODO(yoav): Convert CHECK to DCHECK if no crash reports come in. - CHECK(loaders_.Contains(loader)); + DCHECK(loaders_.Contains(loader)); non_blocking_loaders_.insert(loader); loaders_.erase(loader); } @@ -1697,4 +1763,10 @@ void ResourceFetcher::Trace(blink::Visitor* visitor) { visitor->Trace(resource_timing_info_map_); } +// static +const ResourceFetcher::ResourceFetcherSet& +ResourceFetcher::MainThreadFetchers() { + return MainThreadFetchersSet(); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h index 134349299fb..872bf01d629 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h @@ -42,6 +42,7 @@ #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -133,7 +134,7 @@ class PLATFORM_EXPORT ResourceFetcher enum LoaderFinishType { kDidFinishLoading, kDidFinishFirstPartInMultipart }; void HandleLoaderFinish(Resource*, - double finish_time, + TimeTicks finish_time, LoaderFinishType, uint32_t inflight_keepalive_bytes, bool blocked_cross_site_document); @@ -176,6 +177,9 @@ class PLATFORM_EXPORT ResourceFetcher // counting. void PrepareForLeakDetection(); + using ResourceFetcherSet = PersistentHeapHashSet<WeakMember<ResourceFetcher>>; + static const ResourceFetcherSet& MainThreadFetchers(); + private: friend class ResourceCacheValidationSuppressor; enum class StopFetchingTarget { @@ -206,10 +210,11 @@ class PLATFORM_EXPORT ResourceFetcher Resource* RequestResourceInternal(FetchParameters&, const ResourceFactory&, const SubstituteData&); - ResourceRequestBlockedReason PrepareRequest(FetchParameters&, - const ResourceFactory&, - const SubstituteData&, - unsigned long identifier); + base::Optional<ResourceRequestBlockedReason> PrepareRequest( + FetchParameters&, + const ResourceFactory&, + const SubstituteData&, + unsigned long identifier); Resource* ResourceForStaticData(const FetchParameters&, const ResourceFactory&, 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 679e35ddf20..c39486b7e6c 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 @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include <memory> +#include "base/optional.h" #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" @@ -63,7 +64,7 @@ #include "third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -176,7 +177,7 @@ TEST_F(ResourceFetcherTest, WillSendRequestAdBit) { Resource* new_resource = RawResource::Fetch(fetch_params, fetcher, nullptr); EXPECT_EQ(resource, new_resource); - WTF::Optional<ResourceRequest> new_request = + base::Optional<ResourceRequest> new_request = Context()->RequestFromWillSendRequest(); EXPECT_TRUE(new_request.has_value()); EXPECT_TRUE(new_request.value().IsAdResource()); @@ -230,7 +231,8 @@ TEST_F(ResourceFetcherTest, NavigationTimingInfo) { fetcher->GetNavigationTimingInfo(); ASSERT_TRUE(navigation_timing_info); long long encoded_data_length = 123; - resource->Loader()->DidFinishLoading(0.0, encoded_data_length, 0, 0, false); + resource->Loader()->DidFinishLoading(TimeTicks(), encoded_data_length, 0, 0, + false); EXPECT_EQ(navigation_timing_info->TransferSize(), encoded_data_length); // When there are redirects. diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc index 5e0f33f2aa3..e0ca9c25153 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.cc @@ -225,6 +225,7 @@ void ResourceLoadScheduler::TrafficMonitor::Report( switch (current_state_) { case FrameScheduler::ThrottlingState::kThrottled: + case FrameScheduler::ThrottlingState::kHidden: if (is_main_frame_) { request_count_by_circumstance.Count( ToSample(ReportCircumstance::kMainframeThrottled)); @@ -602,7 +603,8 @@ bool ResourceLoadScheduler::IsThrottablePriority( // If this scheduler is throttled by the associated FrameScheduler, // consider every prioritiy as throttlable. const auto state = frame_scheduler_throttling_state_; - if (state == FrameScheduler::ThrottlingState::kThrottled || + if (state == FrameScheduler::ThrottlingState::kHidden || + state == FrameScheduler::ThrottlingState::kThrottled || state == FrameScheduler::ThrottlingState::kStopped) { return true; } @@ -613,12 +615,16 @@ bool ResourceLoadScheduler::IsThrottablePriority( void ResourceLoadScheduler::OnThrottlingStateChanged( FrameScheduler::ThrottlingState state) { + if (frame_scheduler_throttling_state_ == state) + return; + if (traffic_monitor_) traffic_monitor_->OnThrottlingStateChanged(state); frame_scheduler_throttling_state_ = state; switch (state) { + case FrameScheduler::ThrottlingState::kHidden: case FrameScheduler::ThrottlingState::kThrottled: if (throttling_history_ == ThrottlingHistory::kInitial) throttling_history_ = ThrottlingHistory::kThrottled; @@ -651,22 +657,8 @@ void ResourceLoadScheduler::MaybeRun() { return; while (!pending_requests_.empty()) { - // TODO(yhirano): Consider using a unified value. - const auto num_requests = - frame_scheduler_throttling_state_ == - FrameScheduler::ThrottlingState::kNotThrottled - ? running_throttlable_requests_.size() - : running_requests_.size(); - - const bool has_enough_running_requets = - num_requests >= GetOutstandingLimit(); - - if (IsThrottablePriority(pending_requests_.begin()->priority) && - has_enough_running_requets) { - break; - } if (IsThrottablePriority(pending_requests_.begin()->priority) && - has_enough_running_requets) { + running_throttlable_requests_.size() >= GetOutstandingLimit()) { break; } @@ -697,6 +689,7 @@ size_t ResourceLoadScheduler::GetOutstandingLimit() const { size_t limit = kOutstandingUnlimited; switch (frame_scheduler_throttling_state_) { + case FrameScheduler::ThrottlingState::kHidden: case FrameScheduler::ThrottlingState::kThrottled: limit = std::min(limit, outstanding_limit_for_throttled_frame_scheduler_); break; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h index 403276a26e4..c7c0553d382 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_load_scheduler.h @@ -143,7 +143,7 @@ class PLATFORM_EXPORT ResourceLoadScheduler final std::numeric_limits<size_t>::max(); static ResourceLoadScheduler* Create(FetchContext* = nullptr); - ~ResourceLoadScheduler(); + ~ResourceLoadScheduler() override; void Trace(blink::Visitor*); 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 7800884770f..218972f8b0c 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 @@ -46,7 +46,7 @@ #include "third_party/blink/renderer/platform/loader/fetch/resource_error.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/network/network_instrumentation.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -55,6 +55,16 @@ namespace blink { +namespace { + +bool IsThrottlableRequestContext(WebURLRequest::RequestContext context) { + return context != WebURLRequest::kRequestContextEventSource && + context != WebURLRequest::kRequestContextFetch && + context != WebURLRequest::kRequestContextXMLHttpRequest; +} + +} // namespace + ResourceLoader* ResourceLoader::Create(ResourceFetcher* fetcher, ResourceLoadScheduler* scheduler, Resource* resource, @@ -100,11 +110,12 @@ void ResourceLoader::Start() { DCHECK_EQ(ResourceLoadScheduler::kInvalidClientId, scheduler_client_id_); auto throttle_option = ResourceLoadScheduler::ThrottleOption::kCanBeThrottled; - // Synchronous requests should not work with a throttling. Also, tentatively - // disables throttling for fetch requests that could keep on holding an active - // connection until data is read by JavaScript. + // Synchronous requests should not work with a throttling. Also, disables + // throttling for the case that can be used for aka long-polling requests. + // We also disable throttling for non-http[s] requests. if (resource_->Options().synchronous_policy == kRequestSynchronously || - request.GetRequestContext() == WebURLRequest::kRequestContextFetch) { + !IsThrottlableRequestContext(request.GetRequestContext()) || + !request.Url().ProtocolIsInHTTPFamily()) { throttle_option = ResourceLoadScheduler::ThrottleOption::kCanNotBeThrottled; } @@ -275,18 +286,19 @@ bool ResourceLoader::WillFollowRedirect( request_context, new_url, options, reporting_policy, ResourceRequest::RedirectStatus::kFollowedRedirect); - ResourceRequestBlockedReason blocked_reason = Context().CanRequest( - resource_type, *new_request, new_url, options, reporting_policy, - FetchParameters::kUseDefaultOriginRestrictionForType, - ResourceRequest::RedirectStatus::kFollowedRedirect); + base::Optional<ResourceRequestBlockedReason> blocked_reason = + Context().CanRequest( + resource_type, *new_request, new_url, options, reporting_policy, + FetchParameters::kUseDefaultOriginRestrictionForType, + ResourceRequest::RedirectStatus::kFollowedRedirect); if (Context().IsAdResource(new_url, resource_type, new_request->GetRequestContext())) { new_request->SetIsAdResource(); } - if (blocked_reason != ResourceRequestBlockedReason::kNone) { - CancelForRedirectAccessCheckError(new_url, blocked_reason); + if (blocked_reason) { + CancelForRedirectAccessCheckError(new_url, blocked_reason.value()); return false; } @@ -296,7 +308,7 @@ bool ResourceLoader::WillFollowRedirect( scoped_refptr<const SecurityOrigin> source_origin = GetSourceOrigin(); WebSecurityOrigin source_web_origin(source_origin.get()); WrappedResourceRequest new_request_wrapper(*new_request); - WTF::Optional<network::mojom::CORSError> cors_error = + base::Optional<network::mojom::CORSError> cors_error = WebCORS::HandleRedirect( source_web_origin, new_request_wrapper, redirect_response.Url(), redirect_response.HttpStatusCode(), @@ -308,7 +320,8 @@ bool ResourceLoader::WillFollowRedirect( if (!unused_preload) { Context().AddErrorConsoleMessage( CORS::GetErrorString(CORS::ErrorParameter::Create( - *cors_error, redirect_response.Url(), new_url, + network::CORSErrorStatus(*cors_error), + redirect_response.Url(), new_url, redirect_response.HttpStatusCode(), redirect_response.HttpHeaderFields(), *source_origin.get(), resource_->LastResourceRequest().GetRequestContext())), @@ -487,7 +500,7 @@ CORSStatus ResourceLoader::DetermineCORSStatus(const ResourceResponse& response, error_msg.Append(source_origin->ToString()); error_msg.Append("' has been blocked by CORS policy: "); error_msg.Append(CORS::GetErrorString(CORS::ErrorParameter::Create( - *cors_error, initial_request.Url(), KURL(), + network::CORSErrorStatus(*cors_error), initial_request.Url(), KURL(), response_for_access_control.HttpStatusCode(), response_for_access_control.HttpHeaderFields(), *source_origin, initial_request.GetRequestContext()))); @@ -531,11 +544,11 @@ void ResourceLoader::DidReceiveResponse( (resource_->IsCacheValidator() && response.HttpStatusCode() == 304) ? resource_->GetResponse() : response; - ResourceRequestBlockedReason blocked_reason = + base::Optional<ResourceRequestBlockedReason> blocked_reason = Context().CheckResponseNosniff(request_context, nosniffed_response); - if (blocked_reason != ResourceRequestBlockedReason::kNone) { - HandleError(ResourceError::CancelledDueToAccessCheckError(response.Url(), - blocked_reason)); + if (blocked_reason) { + HandleError(ResourceError::CancelledDueToAccessCheckError( + response.Url(), blocked_reason.value())); return; } @@ -571,14 +584,15 @@ void ResourceLoader::DidReceiveResponse( SecurityViolationReportingPolicy::kReport, ResourceRequest::RedirectStatus::kFollowedRedirect); - ResourceRequestBlockedReason blocked_reason = Context().CanRequest( - resource_type, initial_request, original_url, options, - SecurityViolationReportingPolicy::kReport, - FetchParameters::kUseDefaultOriginRestrictionForType, - ResourceRequest::RedirectStatus::kFollowedRedirect); - if (blocked_reason != ResourceRequestBlockedReason::kNone) { + base::Optional<ResourceRequestBlockedReason> blocked_reason = + Context().CanRequest( + resource_type, initial_request, original_url, options, + SecurityViolationReportingPolicy::kReport, + FetchParameters::kUseDefaultOriginRestrictionForType, + ResourceRequest::RedirectStatus::kFollowedRedirect); + if (blocked_reason) { HandleError(ResourceError::CancelledDueToAccessCheckError( - original_url, blocked_reason)); + original_url, blocked_reason.value())); return; } } @@ -663,12 +677,12 @@ void ResourceLoader::DidFinishLoadingFirstPartInMultipart() { resource_->Identifier(), network_instrumentation::RequestOutcome::kSuccess); - fetcher_->HandleLoaderFinish(resource_.Get(), 0, + fetcher_->HandleLoaderFinish(resource_.Get(), TimeTicks(), ResourceFetcher::kDidFinishFirstPartInMultipart, 0, false); } -void ResourceLoader::DidFinishLoading(double finish_time, +void ResourceLoader::DidFinishLoading(TimeTicks finish_time, int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length, @@ -733,14 +747,14 @@ void ResourceLoader::RequestSynchronously(const ResourceRequest& request) { WrappedResourceRequest request_in(request); WebURLResponse response_out; - WTF::Optional<WebURLError> error_out; + base::Optional<WebURLError> error_out; WebData data_out; int64_t encoded_data_length = WebURLLoaderClient::kUnknownEncodedDataLength; int64_t encoded_body_length = 0; base::Optional<int64_t> downloaded_file_length; WebBlobInfo downloaded_blob; - loader_->LoadSynchronously(request_in, response_out, error_out, data_out, - encoded_data_length, encoded_body_length, + loader_->LoadSynchronously(request_in, this, response_out, error_out, + data_out, encoded_data_length, encoded_body_length, downloaded_file_length, downloaded_blob); // A message dispatched while synchronously fetching the resource @@ -786,8 +800,8 @@ void ResourceLoader::RequestSynchronously(const ResourceRequest& request) { Context().DispatchDidDownloadToBlob(resource_->Identifier(), blob.get()); resource_->DidDownloadToBlob(blob); } - DidFinishLoading(CurrentTimeTicksInSeconds(), encoded_data_length, - encoded_body_length, decoded_body_length, false); + DidFinishLoading(CurrentTimeTicks(), encoded_data_length, encoded_body_length, + decoded_body_length, false); } void ResourceLoader::Dispose() { diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h index cc8c44ea9a6..db929e18b96 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/resource_loader.h @@ -31,6 +31,7 @@ #include <memory> #include "base/gtest_prod_util.h" +#include "base/single_thread_task_runner.h" #include "mojo/public/cpp/bindings/associated_binding.h" #include "third_party/blink/public/mojom/blob/blob_registry.mojom-blink.h" #include "third_party/blink/public/platform/web_url_loader.h" @@ -119,7 +120,7 @@ class PLATFORM_EXPORT ResourceLoader final void DidStartLoadingResponseBody( mojo::ScopedDataPipeConsumerHandle body) override; void DidDownloadData(int, int) override; - void DidFinishLoading(double finish_time, + void DidFinishLoading(TimeTicks finish_time, int64_t encoded_data_length, int64_t encoded_body_length, int64_t decoded_body_length, @@ -192,10 +193,10 @@ class PLATFORM_EXPORT ResourceLoader final // struct is used to store the information needed to refire DidFinishLoading // when the blob is finished too. struct DeferedFinishLoadingInfo { - double finish_time; + TimeTicks finish_time; bool blocked_cross_site_document; }; - Optional<DeferedFinishLoadingInfo> load_did_finish_before_blob_; + base::Optional<DeferedFinishLoadingInfo> load_did_finish_before_blob_; TaskRunnerTimer<ResourceLoader> cancel_timer_; }; 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 fab47ed61e5..875d723b823 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 @@ -68,6 +68,7 @@ ResourceRequest::ResourceRequest(const KURL& url) request_context_(WebURLRequest::kRequestContextUnspecified), frame_type_(network::mojom::RequestContextFrameType::kNone), fetch_request_mode_(network::mojom::FetchRequestMode::kNoCORS), + fetch_importance_mode_(mojom::FetchImportanceMode::kImportanceAuto), fetch_credentials_mode_(network::mojom::FetchCredentialsMode::kInclude), fetch_redirect_mode_(network::mojom::FetchRedirectMode::kFollow), referrer_policy_(kReferrerPolicyDefault), @@ -111,6 +112,7 @@ ResourceRequest::ResourceRequest(CrossThreadResourceRequestData* data) SetRequestContext(data->request_context_); SetFrameType(data->frame_type_); SetFetchRequestMode(data->fetch_request_mode_); + SetFetchImportanceMode(data->fetch_importance_mode_); SetFetchCredentialsMode(data->fetch_credentials_mode_); SetFetchRedirectMode(data->fetch_redirect_mode_); SetFetchIntegrity(data->fetch_integrity_.IsolatedCopy()); @@ -124,6 +126,7 @@ ResourceRequest::ResourceRequest(CrossThreadResourceRequestData* data) redirect_status_ = data->redirect_status_; suggested_filename_ = data->suggested_filename_; is_ad_resource_ = data->is_ad_resource_; + SetInitiatorCSP(data->navigation_csp_); } ResourceRequest::ResourceRequest(const ResourceRequest&) = default; @@ -167,6 +170,7 @@ std::unique_ptr<ResourceRequest> ResourceRequest::CreateRedirectRequest( request->SetCORSPreflightPolicy(CORSPreflightPolicy()); if (IsAdResource()) request->SetIsAdResource(); + request->SetInitiatorCSP(GetInitiatorCSP()); return request; } @@ -204,6 +208,7 @@ std::unique_ptr<CrossThreadResourceRequestData> ResourceRequest::CopyData() data->request_context_ = request_context_; data->frame_type_ = frame_type_; data->fetch_request_mode_ = fetch_request_mode_; + data->fetch_importance_mode_ = fetch_importance_mode_; data->fetch_credentials_mode_ = fetch_credentials_mode_; data->fetch_redirect_mode_ = fetch_redirect_mode_; data->fetch_integrity_ = fetch_integrity_.IsolatedCopy(); @@ -217,6 +222,8 @@ std::unique_ptr<CrossThreadResourceRequestData> ResourceRequest::CopyData() data->redirect_status_ = redirect_status_; data->suggested_filename_ = suggested_filename_; data->is_ad_resource_ = is_ad_resource_; + data->navigation_csp_ = initiator_csp_; + return data; } @@ -410,7 +417,7 @@ void ResourceRequest::SetExternalRequestStateFromRequestorAddressSpace( is_external_request_ = requestor_space > target_space; } -void ResourceRequest::SetNavigationStartTime(double navigation_start) { +void ResourceRequest::SetNavigationStartTime(TimeTicks navigation_start) { navigation_start_ = navigation_start; } 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 194138f38f3..d71f7802808 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 @@ -29,11 +29,14 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_FETCH_RESOURCE_REQUEST_H_ #include <memory> +#include "base/optional.h" #include "services/network/public/mojom/cors.mojom-blink.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "services/network/public/mojom/request_context_frame_type.mojom-shared.h" #include "third_party/blink/public/mojom/net/ip_address_space.mojom-blink.h" #include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" +#include "third_party/blink/public/platform/resource_request_blocked_reason.h" +#include "third_party/blink/public/platform/web_content_security_policy_struct.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" @@ -43,22 +46,10 @@ #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/referrer.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" namespace blink { -enum class ResourceRequestBlockedReason { - kCSP, - kMixedContent, - kOrigin, - kInspector, - kSubresourceFilter, - kOther, - kContentType, - kNone -}; - enum InputToLoadPerfMetricReportPolicy : uint8_t { kNoReport, // Don't report metrics for this ResourceRequest. kReportLink, // Report metrics for this request as initiated by a link click. @@ -283,6 +274,21 @@ class PLATFORM_EXPORT ResourceRequest final { fetch_request_mode_ = mode; } + // A resource request's fetch_importance_mode_ is a developer-set priority + // hint that differs from priority_. It is used in + // ResourceFetcher::ComputeLoadPriority to possibly influence the resolved + // priority of a resource request. + // This member exists both here and in FetchParameters, as opposed just in + // the latter because the fetch() API creates a ResourceRequest object long + // before its associaed FetchParameters, so this makes it easier to + // communicate an importance value down to the lower-level fetching code. + mojom::FetchImportanceMode GetFetchImportanceMode() const { + return fetch_importance_mode_; + } + void SetFetchImportanceMode(mojom::FetchImportanceMode mode) { + fetch_importance_mode_ = mode; + } + network::mojom::FetchCredentialsMode GetFetchCredentialsMode() const { return fetch_credentials_mode_; } @@ -350,15 +356,15 @@ class PLATFORM_EXPORT ResourceRequest final { void SetRedirectStatus(RedirectStatus status) { redirect_status_ = status; } RedirectStatus GetRedirectStatus() const { return redirect_status_; } - void SetSuggestedFilename(const WTF::Optional<String>& suggested_filename) { + void SetSuggestedFilename(const base::Optional<String>& suggested_filename) { suggested_filename_ = suggested_filename; } - const WTF::Optional<String>& GetSuggestedFilename() const { + const base::Optional<String>& GetSuggestedFilename() const { return suggested_filename_; } - void SetNavigationStartTime(double); - double NavigationStartTime() const { return navigation_start_; } + void SetNavigationStartTime(TimeTicks); + TimeTicks NavigationStartTime() const { return navigation_start_; } void SetIsSameDocumentNavigation(bool is_same_document) { is_same_document_navigation_ = is_same_document; @@ -368,6 +374,13 @@ class PLATFORM_EXPORT ResourceRequest final { void SetIsAdResource() { is_ad_resource_ = true; } bool IsAdResource() const { return is_ad_resource_; } + void SetInitiatorCSP(const WebContentSecurityPolicyList& initiator_csp) { + initiator_csp_ = initiator_csp; + } + const WebContentSecurityPolicyList& GetInitiatorCSP() const { + return initiator_csp_; + } + private: using SharableExtraData = base::RefCountedData<std::unique_ptr<WebURLRequest::ExtraData>>; @@ -412,6 +425,7 @@ class PLATFORM_EXPORT ResourceRequest final { WebURLRequest::RequestContext request_context_; network::mojom::RequestContextFrameType frame_type_; network::mojom::FetchRequestMode fetch_request_mode_; + mojom::FetchImportanceMode fetch_importance_mode_; network::mojom::FetchCredentialsMode fetch_credentials_mode_; network::mojom::FetchRedirectMode fetch_redirect_mode_; String fetch_integrity_; @@ -425,15 +439,16 @@ class PLATFORM_EXPORT ResourceRequest final { bool is_same_document_navigation_; InputToLoadPerfMetricReportPolicy input_perf_metric_report_policy_; RedirectStatus redirect_status_; - WTF::Optional<String> suggested_filename_; + base::Optional<String> suggested_filename_; mutable CacheControlHeader cache_control_header_cache_; static double default_timeout_interval_; - double navigation_start_ = 0; + TimeTicks navigation_start_; bool is_ad_resource_ = false; + WebContentSecurityPolicyList initiator_csp_; }; // This class is needed to copy a ResourceRequest across threads, because it @@ -477,6 +492,7 @@ struct CrossThreadResourceRequestData { WebURLRequest::RequestContext request_context_; network::mojom::RequestContextFrameType frame_type_; network::mojom::FetchRequestMode fetch_request_mode_; + mojom::FetchImportanceMode fetch_importance_mode_; network::mojom::FetchCredentialsMode fetch_credentials_mode_; network::mojom::FetchRedirectMode fetch_redirect_mode_; String fetch_integrity_; @@ -491,6 +507,7 @@ struct CrossThreadResourceRequestData { ResourceRequest::RedirectStatus redirect_status_; base::Optional<String> suggested_filename_; bool is_ad_resource_; + WebContentSecurityPolicyList navigation_csp_; }; } // namespace blink 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 dd964d8be55..afff3bffdc2 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 @@ -39,6 +39,7 @@ #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -51,7 +52,7 @@ class PLATFORM_EXPORT ResourceTimingInfo public: static scoped_refptr<ResourceTimingInfo> Create(const AtomicString& type, - const double time, + const TimeTicks time, bool is_main_resource) { return base::AdoptRef(new ResourceTimingInfo(type, time, is_main_resource)); } @@ -61,7 +62,7 @@ class PLATFORM_EXPORT ResourceTimingInfo // Gets a copy of the data suitable for passing to another thread. std::unique_ptr<CrossThreadResourceTimingInfoData> CopyData() const; - double InitialTime() const { return initial_time_; } + TimeTicks InitialTime() const { return initial_time_; } bool IsMainResource() const { return is_main_resource_; } const AtomicString& InitiatorType() const { return type_; } @@ -74,8 +75,8 @@ class PLATFORM_EXPORT ResourceTimingInfo return original_timing_allow_origin_; } - void SetLoadFinishTime(double time) { load_finish_time_ = time; } - double LoadFinishTime() const { return load_finish_time_; } + void SetLoadFinishTime(TimeTicks time) { load_finish_time_ = time; } + TimeTicks LoadFinishTime() const { return load_finish_time_; } void SetInitialURL(const KURL& url) { initial_url_ = url; } const KURL& InitialURL() const { return initial_url_; } @@ -115,14 +116,14 @@ class PLATFORM_EXPORT ResourceTimingInfo private: ResourceTimingInfo(const AtomicString& type, - const double time, + const TimeTicks time, bool is_main_resource) : type_(type), initial_time_(time), is_main_resource_(is_main_resource) {} AtomicString type_; AtomicString original_timing_allow_origin_; - double initial_time_; - double load_finish_time_; + TimeTicks initial_time_; + TimeTicks load_finish_time_; KURL initial_url_; ResourceResponse final_response_; Vector<ResourceResponse> redirect_chain_; @@ -141,8 +142,8 @@ struct CrossThreadResourceTimingInfoData { String type_; String original_timing_allow_origin_; - double initial_time_; - double load_finish_time_; + TimeTicks initial_time_; + TimeTicks load_finish_time_; KURL initial_url_; std::unique_ptr<CrossThreadResourceResponseData> final_response_; Vector<std::unique_ptr<CrossThreadResourceResponseData>> redirect_chain_; diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc index 7fca9edf686..ed49f458a6a 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/script_fetch_options.cc @@ -23,6 +23,7 @@ FetchParameters ScriptFetchOptions::CreateFetchParameters( ResourceLoaderOptions resource_loader_options; resource_loader_options.initiator_info.name = "script"; FetchParameters params(resource_request, resource_loader_options); + params.SetRequestContext(WebURLRequest::kRequestContextScript); // Step 1. ... and CORS setting. [spec text] // diff --git a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc index b30c1769416..c67276f2457 100644 --- a/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler_test.cc @@ -16,7 +16,7 @@ namespace { class MockSha256WebCryptoDigestor : public WebCryptoDigestor { public: - virtual bool Consume(const unsigned char* data, unsigned data_size) { + bool Consume(const unsigned char* data, unsigned data_size) override { String key(data, data_size); auto it = kMapOfHashes.find(key); @@ -29,7 +29,8 @@ class MockSha256WebCryptoDigestor : public WebCryptoDigestor { return hash_exists_; } - virtual bool Finish(unsigned char*& result_data, unsigned& result_data_size) { + bool Finish(unsigned char*& result_data, + unsigned& result_data_size) override { if (hash_exists_) { result_data = hash_.data(); result_data_size = hash_.size(); @@ -123,7 +124,7 @@ class MockCachedMetadataSender final : public CachedMetadataSender { public: MockCachedMetadataSender(KURL response_url) : response_url_(response_url) {} - void Send(const char* data, size_t size) { + void Send(const char* data, size_t size) override { Platform::Current()->CacheMetadata(response_url_, response_time_, data, size); } diff --git a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity.cc b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity.cc index 7d6141afa47..8d823a30264 100644 --- a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity.cc +++ b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity.cc @@ -318,7 +318,7 @@ SubresourceIntegrity::ParseAttributeAlgorithm(const UChar*& begin, // The last algorithm prefix is the ed25519 signature algorithm, which should // only be enabled if kSignatures is requested. We'll implement this by // adjusting the last_prefix index into the array. - size_t last_prefix = WTF_ARRAY_LENGTH(kPrefixes); + size_t last_prefix = arraysize(kPrefixes); if (features != IntegrityFeatures::kSignatures) last_prefix--; @@ -332,8 +332,8 @@ SubresourceIntegrity::ParseIntegrityHeaderAlgorithm( IntegrityAlgorithm& algorithm) { static const AlgorithmPrefixPair kPrefixes[] = { {"ed25519", IntegrityAlgorithm::kEd25519}}; - return ParseAlgorithmPrefix(begin, end, kPrefixes, - WTF_ARRAY_LENGTH(kPrefixes), algorithm); + return ParseAlgorithmPrefix(begin, end, kPrefixes, arraysize(kPrefixes), + algorithm); } SubresourceIntegrity::AlgorithmParseResult diff --git a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc index e0c92673a0a..929caf2ff7d 100644 --- a/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc +++ b/chromium/third_party/blink/renderer/platform/loader/subresource_integrity_test.cc @@ -470,7 +470,7 @@ TEST_F(SubresourceIntegrityTest, Parsing) { "sha384-XVVXBGoYw6AJOh9J+Z8pBDMVVPfkBpngexkA7JqZu8d5GENND6TEIup/tA1v5GPr " "sha512-tbUPioKbVBplr0b1ucnWB57SJWt4x9dOE0Vy2mzCXvH3FepqDZ+" "07yMK81ytlg0MPaIrPAjcHqba5csorDWtKg==", - valid_sha384_and_sha512, WTF_ARRAY_LENGTH(valid_sha384_and_sha512)); + valid_sha384_and_sha512, arraysize(valid_sha384_and_sha512)); const IntegrityMetadata valid_sha256_and_sha256[] = { IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", @@ -479,7 +479,7 @@ TEST_F(SubresourceIntegrityTest, Parsing) { }; ExpectParseMultipleHashes( "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-deadbeef", - valid_sha256_and_sha256, WTF_ARRAY_LENGTH(valid_sha256_and_sha256)); + valid_sha256_and_sha256, arraysize(valid_sha256_and_sha256)); const IntegrityMetadata valid_sha256_and_invalid_sha256[] = { IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", @@ -488,7 +488,7 @@ TEST_F(SubresourceIntegrityTest, Parsing) { ExpectParseMultipleHashes( "sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE= sha256-!!!!", valid_sha256_and_invalid_sha256, - WTF_ARRAY_LENGTH(valid_sha256_and_invalid_sha256)); + arraysize(valid_sha256_and_invalid_sha256)); const IntegrityMetadata invalid_sha256_and_valid_sha256[] = { IntegrityMetadata("BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", @@ -497,7 +497,7 @@ TEST_F(SubresourceIntegrityTest, Parsing) { ExpectParseMultipleHashes( "sha256-!!! sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", invalid_sha256_and_valid_sha256, - WTF_ARRAY_LENGTH(invalid_sha256_and_valid_sha256)); + arraysize(invalid_sha256_and_valid_sha256)); ExpectParse("sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=?foo=bar", "BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=", diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h b/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h index e5f3adb730f..b22a12df81a 100644 --- a/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h +++ b/chromium/third_party/blink/renderer/platform/loader/testing/mock_fetch_context.h @@ -5,6 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_TESTING_MOCK_FETCH_CONTEXT_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_LOADER_TESTING_MOCK_FETCH_CONTEXT_H_ +#include "base/optional.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_url_loader_factory.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_request.h" @@ -14,7 +16,6 @@ #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include <memory> @@ -51,7 +52,7 @@ class MockFetchContext : public FetchContext { } // The last ResourceRequest passed to DispatchWillSendRequest. - WTF::Optional<ResourceRequest> RequestFromWillSendRequest() const { + base::Optional<ResourceRequest> RequestFromWillSendRequest() const { return will_send_request_; } @@ -67,7 +68,7 @@ class MockFetchContext : public FetchContext { bool AllowImage(bool images_enabled, const KURL&) const override { return true; } - ResourceRequestBlockedReason CanRequest( + base::Optional<ResourceRequestBlockedReason> CanRequest( Resource::Type, const ResourceRequest&, const KURL&, @@ -75,20 +76,20 @@ class MockFetchContext : public FetchContext { SecurityViolationReportingPolicy, FetchParameters::OriginRestriction, ResourceRequest::RedirectStatus redirect_status) const override { - return ResourceRequestBlockedReason::kNone; + return base::nullopt; } - ResourceRequestBlockedReason CheckCSPForRequest( + base::Optional<ResourceRequestBlockedReason> CheckCSPForRequest( WebURLRequest::RequestContext, const KURL& url, const ResourceLoaderOptions& options, SecurityViolationReportingPolicy reporting_policy, ResourceRequest::RedirectStatus redirect_status) const override { - return ResourceRequestBlockedReason::kNone; + return base::nullopt; } - virtual ResourceRequestBlockedReason CheckResponseNosniff( + base::Optional<ResourceRequestBlockedReason> CheckResponseNosniff( WebURLRequest::RequestContext, - const ResourceResponse&) const { - return ResourceRequestBlockedReason::kNone; + const ResourceResponse&) const override { + return base::nullopt; } bool ShouldLoadNewResource(Resource::Type) const override { return load_policy_ == kShouldLoadNewResource; @@ -158,7 +159,7 @@ class MockFetchContext : public FetchContext { std::unique_ptr<WebURLLoaderFactory> url_loader_factory_; bool complete_; long long transfer_size_; - WTF::Optional<ResourceRequest> will_send_request_; + base::Optional<ResourceRequest> will_send_request_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/loader/testing/web_url_loader_factory_with_mock.h b/chromium/third_party/blink/renderer/platform/loader/testing/web_url_loader_factory_with_mock.h index c66ba9ff8fd..3949dfb1182 100644 --- a/chromium/third_party/blink/renderer/platform/loader/testing/web_url_loader_factory_with_mock.h +++ b/chromium/third_party/blink/renderer/platform/loader/testing/web_url_loader_factory_with_mock.h @@ -7,6 +7,7 @@ #include <memory> +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_url_loader_factory.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector.cc b/chromium/third_party/blink/renderer/platform/long_task_detector.cc index d56839cee1c..57ee22627ff 100644 --- a/chromium/third_party/blink/renderer/platform/long_task_detector.cc +++ b/chromium/third_party/blink/renderer/platform/long_task_detector.cc @@ -22,8 +22,7 @@ LongTaskDetector::LongTaskDetector() = default; void LongTaskDetector::RegisterObserver(LongTaskObserver* observer) { DCHECK(IsMainThread()); DCHECK(observer); - observers_.insert(observer); - if (observers_.size() == 1) { + if (observers_.insert(observer).is_new_entry && observers_.size() == 1) { // Number of observers just became non-zero. Platform::Current()->CurrentThread()->AddTaskTimeObserver(this); } diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector.h b/chromium/third_party/blink/renderer/platform/long_task_detector.h index d465cf6c481..d4ecc9af7a3 100644 --- a/chromium/third_party/blink/renderer/platform/long_task_detector.h +++ b/chromium/third_party/blink/renderer/platform/long_task_detector.h @@ -28,7 +28,7 @@ class PLATFORM_EXPORT LongTaskObserver : public GarbageCollectedMixin { // TaskTimeObserver. class PLATFORM_EXPORT LongTaskDetector final : public GarbageCollectedFinalized<LongTaskDetector>, - public scheduler::TaskTimeObserver { + public base::sequence_manager::TaskTimeObserver { WTF_MAKE_NONCOPYABLE(LongTaskDetector); public: diff --git a/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc b/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc index ef75642bf52..0758c7c07a8 100644 --- a/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc +++ b/chromium/third_party/blink/renderer/platform/long_task_detector_test.cc @@ -42,7 +42,7 @@ class LongTaskDetectorTest : public testing::Test { } protected: - void SetUp() { + void SetUp() override { // For some reason, platform needs to run for non-zero seconds before we // start posting tasks to it. Otherwise TaskTimeObservers don't get notified // of tasks. @@ -96,5 +96,27 @@ TEST_F(LongTaskDetectorTest, DoesNotGetNotifiedOfShortTasks) { SimulateTask(LongTaskDetector::kLongTaskThresholdSeconds + 0.01); EXPECT_EQ(long_task_observer->last_long_task_end, DummyTaskEndTime()); + LongTaskDetector::Instance().UnregisterObserver(long_task_observer); } + +TEST_F(LongTaskDetectorTest, RegisterSameObserverTwice) { + TestLongTaskObserver* long_task_observer = new TestLongTaskObserver(); + LongTaskDetector::Instance().RegisterObserver(long_task_observer); + LongTaskDetector::Instance().RegisterObserver(long_task_observer); + + SimulateTask(LongTaskDetector::kLongTaskThresholdSeconds + 0.01); + TimeTicks long_task_end_when_registered = DummyTaskEndTime(); + EXPECT_EQ(long_task_observer->last_long_task_start, DummyTaskStartTime()); + EXPECT_EQ(long_task_observer->last_long_task_end, + long_task_end_when_registered); + + LongTaskDetector::Instance().UnregisterObserver(long_task_observer); + // Should only need to unregister once even after we called RegisterObserver + // twice. + SimulateTask(LongTaskDetector::kLongTaskThresholdSeconds + 0.01); + ASSERT_FALSE(long_task_end_when_registered == DummyTaskEndTime()); + EXPECT_EQ(long_task_observer->last_long_task_end, + long_task_end_when_registered); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mac/DEPS b/chromium/third_party/blink/renderer/platform/mac/DEPS new file mode 100644 index 00000000000..5047015afce --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mac/DEPS @@ -0,0 +1,22 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/mac", + + # Dependencies. + "+third_party/blink/renderer/platform/animation/timing_function.h", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/kill_ring.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/scroll", + "+third_party/blink/renderer/platform/theme.h", + "+third_party/blink/renderer/platform/timer.h", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h b/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h index 9cc37379c42..289c2c0cdcd 100644 --- a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h +++ b/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.h @@ -113,7 +113,7 @@ class PLATFORM_EXPORT ScrollAnimatorMac : public ScrollAnimatorBase { void SendContentAreaScrolledSoon(const ScrollOffset& scroll_delta); - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { ScrollAnimatorBase::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm b/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm index 5ad7c8a2aaf..4b87883d49f 100644 --- a/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm +++ b/chromium/third_party/blink/renderer/platform/mac/scroll_animator_mac.mm @@ -34,7 +34,7 @@ #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/mac/block_exceptions.h" #include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h" @@ -897,10 +897,10 @@ void ScrollAnimatorMac::DidAddVerticalScrollbar(Scrollbar& scrollbar) { void ScrollAnimatorMac::WillRemoveVerticalScrollbar(Scrollbar& scrollbar) { ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); DCHECK_EQ([scrollbar_painter_controller_.Get() verticalScrollerImp], painter); + if (!painter) - return; + DCHECK(!vertical_scrollbar_painter_delegate_); - DCHECK(vertical_scrollbar_painter_delegate_); [painter setDelegate:nil]; [vertical_scrollbar_painter_delegate_.Get() invalidate]; vertical_scrollbar_painter_delegate_ = nullptr; @@ -924,10 +924,10 @@ void ScrollAnimatorMac::WillRemoveHorizontalScrollbar(Scrollbar& scrollbar) { ScrollbarPainter painter = ScrollbarPainterForScrollbar(scrollbar); DCHECK_EQ([scrollbar_painter_controller_.Get() horizontalScrollerImp], painter); + if (!painter) - return; + DCHECK(!horizontal_scrollbar_painter_delegate_); - DCHECK(horizontal_scrollbar_painter_delegate_); [painter setDelegate:nil]; [horizontal_scrollbar_painter_delegate_.Get() invalidate]; horizontal_scrollbar_painter_delegate_ = nullptr; diff --git a/chromium/third_party/blink/renderer/platform/mac/theme_mac.h b/chromium/third_party/blink/renderer/platform/mac/theme_mac.h index 3a974d308ee..ac60fc68067 100644 --- a/chromium/third_party/blink/renderer/platform/mac/theme_mac.h +++ b/chromium/third_party/blink/renderer/platform/mac/theme_mac.h @@ -37,40 +37,40 @@ class ThemeMac : public Theme { ThemeMac() {} ~ThemeMac() override {} - virtual int BaselinePositionAdjustment(ControlPart) const; - - virtual FontDescription ControlFont(ControlPart, - const FontDescription&, - float zoom_factor) const; - - virtual LengthSize GetControlSize(ControlPart, - const FontDescription&, - const LengthSize&, - float zoom_factor) const; - virtual LengthSize MinimumControlSize(ControlPart, - const FontDescription&, - float zoom_factor) const; - - virtual LengthBox ControlPadding(ControlPart, - const FontDescription&, - const Length& zoomed_box_top, - const Length& zoomed_box_right, - const Length& zoomed_box_bottom, - const Length& zoomed_box_left, - float zoom_factor) const; - virtual LengthBox ControlBorder(ControlPart, - const FontDescription&, - const LengthBox& zoomed_box, - float zoom_factor) const; - - virtual bool ControlRequiresPreWhiteSpace(ControlPart part) const { + int BaselinePositionAdjustment(ControlPart) const override; + + FontDescription ControlFont(ControlPart, + const FontDescription&, + float zoom_factor) const override; + + LengthSize GetControlSize(ControlPart, + const FontDescription&, + const LengthSize&, + float zoom_factor) const override; + LengthSize MinimumControlSize(ControlPart, + const FontDescription&, + float zoom_factor) const override; + + LengthBox ControlPadding(ControlPart, + const FontDescription&, + const Length& zoomed_box_top, + const Length& zoomed_box_right, + const Length& zoomed_box_bottom, + const Length& zoomed_box_left, + float zoom_factor) const override; + LengthBox ControlBorder(ControlPart, + const FontDescription&, + const LengthBox& zoomed_box, + float zoom_factor) const override; + + bool ControlRequiresPreWhiteSpace(ControlPart part) const override { return part == kPushButtonPart; } - virtual void AddVisualOverflow(ControlPart, - ControlStates, - float zoom_factor, - IntRect& border_box) const; + void AddVisualOverflow(ControlPart, + ControlStates, + float zoom_factor, + IntRect& border_box) const override; // Inflate an IntRect to accout for specific padding around margins. enum { kTopMargin = 0, kRightMargin = 1, kBottomMargin = 2, kLeftMargin = 3 }; diff --git a/chromium/third_party/blink/renderer/platform/mac/version_util_mac.h b/chromium/third_party/blink/renderer/platform/mac/version_util_mac.h index ea3bcbc3446..063cf5bdbc0 100644 --- a/chromium/third_party/blink/renderer/platform/mac/version_util_mac.h +++ b/chromium/third_party/blink/renderer/platform/mac/version_util_mac.h @@ -22,7 +22,6 @@ constexpr bool IsOS() { } // namespace internal -const auto IsOS10_9 = internal::IsOS<9, 1090>; const auto IsOS10_10 = internal::IsOS<10, 101000>; const auto IsOS10_11 = internal::IsOS<11, 101100>; const auto IsOS10_12 = internal::IsOS<12, 101200>; diff --git a/chromium/third_party/blink/renderer/platform/mac/version_util_mac_test.mm b/chromium/third_party/blink/renderer/platform/mac/version_util_mac_test.mm index 581a9e3b4ca..1fd3d7eb721 100644 --- a/chromium/third_party/blink/renderer/platform/mac/version_util_mac_test.mm +++ b/chromium/third_party/blink/renderer/platform/mac/version_util_mac_test.mm @@ -7,10 +7,6 @@ #include <AppKit/AppKit.h> #include <gtest/gtest.h> -#ifndef NSAppKitVersionNumber10_9 -#define NSAppKitVersionNumber10_9 1265 -#endif - #ifndef NSAppKitVersionNumber10_10 #define NSAppKitVersionNumber10_10 1343 #endif @@ -27,23 +23,14 @@ // sanity check in unit tests, though we don't want to rely on it in production // code. TEST(VersionUtilMac, AppKitVersions) { - if (floor(NSAppKitVersionNumber) == NSAppKitVersionNumber10_9) { - EXPECT_TRUE(blink::IsOS10_9()); - EXPECT_FALSE(blink::IsOS10_10()); - EXPECT_FALSE(blink::IsOS10_11()); - return; - } - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_10Max && floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_10) { - EXPECT_FALSE(blink::IsOS10_9()); EXPECT_TRUE(blink::IsOS10_10()); EXPECT_FALSE(blink::IsOS10_11()); return; } if (floor(NSAppKitVersionNumber) == NSAppKitVersionNumber10_11Max) { - EXPECT_FALSE(blink::IsOS10_9()); EXPECT_FALSE(blink::IsOS10_10()); EXPECT_TRUE(blink::IsOS10_11()); return; diff --git a/chromium/third_party/blink/renderer/platform/media/DEPS b/chromium/third_party/blink/renderer/platform/media/DEPS index dae35ae2f9c..d34ec436d8f 100644 --- a/chromium/third_party/blink/renderer/platform/media/DEPS +++ b/chromium/third_party/blink/renderer/platform/media/DEPS @@ -1,4 +1,13 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/media", + + # Dependencies. + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/wtf", "+third_party/zlib/google/compression_utils.h", "+ui/base/resource", ] diff --git a/chromium/third_party/blink/renderer/platform/mediastream/DEPS b/chromium/third_party/blink/renderer/platform/mediastream/DEPS new file mode 100644 index 00000000000..f0b36146bad --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mediastream/DEPS @@ -0,0 +1,14 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/mediastream", + + # Dependencies. + "+third_party/blink/renderer/platform/audio", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/uuid.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc index b327c63e9ed..d2373f3638b 100644 --- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc +++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.cc @@ -80,9 +80,10 @@ void MediaStreamDescriptor::AddComponent(MediaStreamComponent* component) { break; } - for (auto& observer : observers_) { + // Iterate over a copy of |observers_| to avoid re-entrancy issues. + Vector<WebMediaStreamObserver*> observers = observers_; + for (auto*& observer : observers) observer->TrackAdded(component); - } } void MediaStreamDescriptor::RemoveComponent(MediaStreamComponent* component) { @@ -100,9 +101,10 @@ void MediaStreamDescriptor::RemoveComponent(MediaStreamComponent* component) { break; } - for (auto& observer : observers_) { + // Iterate over a copy of |observers_| to avoid re-entrancy issues. + Vector<WebMediaStreamObserver*> observers = observers_; + for (auto*& observer : observers) observer->TrackRemoved(component); - } } void MediaStreamDescriptor::AddRemoteTrack(MediaStreamComponent* component) { @@ -119,6 +121,17 @@ void MediaStreamDescriptor::RemoveRemoteTrack(MediaStreamComponent* component) { RemoveComponent(component); } +void MediaStreamDescriptor::SetActive(bool active) { + if (active == active_) + return; + + active_ = active; + // Iterate over a copy of |observers_| to avoid re-entrancy issues. + Vector<WebMediaStreamObserver*> observers = observers_; + for (auto*& observer : observers) + observer->ActiveStateChanged(active_); +} + void MediaStreamDescriptor::AddObserver(WebMediaStreamObserver* observer) { DCHECK_EQ(observers_.Find(observer), kNotFound); observers_.push_back(observer); diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h index 41060ba217e..7f12f285f9c 100644 --- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h +++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_descriptor.h @@ -51,7 +51,7 @@ class PLATFORM_EXPORT MediaStreamDescriptorClient virtual void StreamEnded() = 0; virtual void AddTrackByComponent(MediaStreamComponent*) = 0; virtual void RemoveTrackByComponent(MediaStreamComponent*) = 0; - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; class PLATFORM_EXPORT MediaStreamDescriptor final @@ -102,7 +102,7 @@ class PLATFORM_EXPORT MediaStreamDescriptor final void RemoveRemoteTrack(MediaStreamComponent*); bool Active() const { return active_; } - void SetActive(bool active) { active_ = active; } + void SetActive(bool active); void AddObserver(WebMediaStreamObserver*); void RemoveObserver(WebMediaStreamObserver*); 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 282cf749ea6..816dfda39ab 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 @@ -56,6 +56,10 @@ MediaStreamSource::MediaStreamSource(const String& id, ready_state_(ready_state), requires_consumer_(requires_consumer) {} +void MediaStreamSource::SetGroupId(const String& group_id) { + group_id_ = group_id; +} + void MediaStreamSource::SetReadyState(ReadyState ready_state) { if (ready_state_ != kReadyStateEnded && ready_state_ != ready_state) { ready_state_ = ready_state; @@ -90,10 +94,11 @@ void MediaStreamSource::AddObserver(MediaStreamSource::Observer* observer) { observers_.insert(observer); } -void MediaStreamSource::SetAudioProcessingProperties(bool echo_cancellation, - bool auto_gain_control, - bool noise_supression) { - echo_cancellation_ = echo_cancellation; +void MediaStreamSource::SetAudioProcessingProperties( + EchoCancellationMode echo_cancellation_mode, + bool auto_gain_control, + bool noise_supression) { + echo_cancellation_mode_ = echo_cancellation_mode; auto_gain_control_ = auto_gain_control; noise_supression_ = noise_supression; } @@ -117,9 +122,26 @@ bool MediaStreamSource::RemoveAudioConsumer( void MediaStreamSource::GetSettings(WebMediaStreamTrack::Settings& settings) { settings.device_id = Id(); - - if (echo_cancellation_) - settings.echo_cancellation = *echo_cancellation_; + settings.group_id = GroupId(); + + if (echo_cancellation_mode_) { + switch (*echo_cancellation_mode_) { + case EchoCancellationMode::kDisabled: + settings.echo_cancellation = false; + settings.echo_cancellation_type.Reset(); + break; + case EchoCancellationMode::kSoftware: + settings.echo_cancellation = true; + settings.echo_cancellation_type = + WebString::FromASCII(blink::kEchoCancellationTypeBrowser); + break; + case EchoCancellationMode::kHardware: + settings.echo_cancellation = true; + settings.echo_cancellation_type = + WebString::FromASCII(blink::kEchoCancellationTypeSystem); + break; + } + } if (auto_gain_control_) settings.auto_gain_control = *auto_gain_control_; if (noise_supression_) @@ -155,5 +177,11 @@ STATIC_ASSERT_ENUM(WebMediaStreamSource::kReadyStateMuted, MediaStreamSource::kReadyStateMuted); STATIC_ASSERT_ENUM(WebMediaStreamSource::kReadyStateEnded, MediaStreamSource::kReadyStateEnded); +STATIC_ASSERT_ENUM(WebMediaStreamSource::EchoCancellationMode::kDisabled, + MediaStreamSource::EchoCancellationMode::kDisabled); +STATIC_ASSERT_ENUM(WebMediaStreamSource::EchoCancellationMode::kSoftware, + MediaStreamSource::EchoCancellationMode::kSoftware); +STATIC_ASSERT_ENUM(WebMediaStreamSource::EchoCancellationMode::kHardware, + MediaStreamSource::EchoCancellationMode::kHardware); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h index 1a72cd9acf5..9d9d40fc693 100644 --- a/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h +++ b/chromium/third_party/blink/renderer/platform/mediastream/media_stream_source.h @@ -35,13 +35,13 @@ #include <memory> #include <utility> +#include "base/optional.h" #include "third_party/blink/public/platform/web_media_constraints.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/audio/audio_destination_consumer.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -72,6 +72,8 @@ class PLATFORM_EXPORT MediaStreamSource final kReadyStateEnded = 2 }; + enum class EchoCancellationMode { kDisabled, kSoftware, kHardware }; + static MediaStreamSource* Create(const String& id, StreamType, const String& name, @@ -84,6 +86,9 @@ class PLATFORM_EXPORT MediaStreamSource final const String& GetName() const { return name_; } bool Remote() const { return remote_; } + void SetGroupId(const String& group_id); + const String& GroupId() { return group_id_; } + void SetReadyState(ReadyState); ReadyState GetReadyState() const { return ready_state_; } @@ -94,7 +99,7 @@ class PLATFORM_EXPORT MediaStreamSource final extra_data_ = std::move(extra_data); } - void SetAudioProcessingProperties(bool echo_cancellation, + void SetAudioProcessingProperties(EchoCancellationMode echo_cancellation_mode, bool auto_gain_control, bool noise_supression); @@ -138,6 +143,7 @@ class PLATFORM_EXPORT MediaStreamSource final String id_; StreamType type_; String name_; + String group_id_; bool remote_; ReadyState ready_state_; bool requires_consumer_; @@ -147,9 +153,9 @@ class PLATFORM_EXPORT MediaStreamSource final std::unique_ptr<ExtraData> extra_data_; WebMediaConstraints constraints_; WebMediaStreamSource::Capabilities capabilities_; - Optional<bool> echo_cancellation_; - Optional<bool> auto_gain_control_; - Optional<bool> noise_supression_; + base::Optional<EchoCancellationMode> echo_cancellation_mode_; + base::Optional<bool> auto_gain_control_; + base::Optional<bool> noise_supression_; }; typedef HeapVector<Member<MediaStreamSource>> MediaStreamSourceVector; diff --git a/chromium/third_party/blink/renderer/platform/memory_coordinator.cc b/chromium/third_party/blink/renderer/platform/memory_coordinator.cc index 67f9647adf1..33ebadea200 100644 --- a/chromium/third_party/blink/renderer/platform/memory_coordinator.cc +++ b/chromium/third_party/blink/renderer/platform/memory_coordinator.cc @@ -57,18 +57,19 @@ void MemoryCoordinator::SetIsLowEndDeviceForTesting(bool is_low_end_device) { // static MemoryCoordinator& MemoryCoordinator::Instance() { - DEFINE_STATIC_LOCAL(Persistent<MemoryCoordinator>, external, - (new MemoryCoordinator)); - DCHECK(IsMainThread()); + DEFINE_THREAD_SAFE_STATIC_LOCAL(CrossThreadPersistent<MemoryCoordinator>, + external, (new MemoryCoordinator)); return *external.Get(); } void MemoryCoordinator::RegisterThread(WebThread* thread) { - MemoryCoordinator::Instance().web_threads_.insert(thread); + MutexLocker lock(web_threads_mutex_); + web_threads_.insert(thread); } void MemoryCoordinator::UnregisterThread(WebThread* thread) { - MemoryCoordinator::Instance().web_threads_.erase(thread); + MutexLocker lock(web_threads_mutex_); + web_threads_.erase(thread); } MemoryCoordinator::MemoryCoordinator() = default; @@ -110,7 +111,8 @@ void MemoryCoordinator::OnPurgeMemory() { WTF::Partitions::DecommitFreeableMemory(); // Thread-specific data never issues a layout, so we are safe here. - for (auto thread : web_threads_) { + MutexLocker lock(web_threads_mutex_); + for (auto* thread : web_threads_) { if (!thread->GetTaskRunner()) continue; diff --git a/chromium/third_party/blink/renderer/platform/memory_coordinator.h b/chromium/third_party/blink/renderer/platform/memory_coordinator.h index 7e0bbf2ccdd..29d0b515ed2 100644 --- a/chromium/third_party/blink/renderer/platform/memory_coordinator.h +++ b/chromium/third_party/blink/renderer/platform/memory_coordinator.h @@ -11,6 +11,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/wtf/noncopyable.h" +#include "third_party/blink/renderer/platform/wtf/threading_primitives.h" namespace blink { @@ -51,8 +52,8 @@ class PLATFORM_EXPORT MemoryCoordinator final // the heap size. static void Initialize(); - static void RegisterThread(WebThread*); - static void UnregisterThread(WebThread*); + void RegisterThread(WebThread*) LOCKS_EXCLUDED(web_threads_mutex_); + void UnregisterThread(WebThread*) LOCKS_EXCLUDED(web_threads_mutex_); void RegisterClient(MemoryCoordinatorClient*); void UnregisterClient(MemoryCoordinatorClient*); @@ -81,6 +82,7 @@ class PLATFORM_EXPORT MemoryCoordinator final HeapHashSet<WeakMember<MemoryCoordinatorClient>> clients_; HashSet<WebThread*> web_threads_; + Mutex web_threads_mutex_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mhtml/DEPS b/chromium/third_party/blink/renderer/platform/mhtml/DEPS new file mode 100644 index 00000000000..85ca52ba41f --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/mhtml/DEPS @@ -0,0 +1,19 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/mhtml", + + # Dependencies. + "+third_party/blink/renderer/platform/date_components.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/network", + "+third_party/blink/renderer/platform/serialized_resource.h", + "+third_party/blink/renderer/platform/shared_buffer_chunk_reader.h", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/text", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc index 5d3cc087814..94fd391718c 100644 --- a/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc +++ b/chromium/third_party/blink/renderer/platform/mhtml/mhtml_archive.cc @@ -40,7 +40,6 @@ #include "third_party/blink/renderer/platform/text/quoted_printable.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/cryptographically_random_number.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -222,14 +221,7 @@ void MHTMLArchive::GenerateMHTMLHeader(const String& boundary, DCHECK(!boundary.IsEmpty()); DCHECK(!mime_type.IsEmpty()); - // TODO(lukasza): Passing individual date/time components seems fragile. - base::Time::Exploded date_components; - date.UTCExplode(&date_components); - String date_string = MakeRFC2822DateString( - date_components.day_of_week, date_components.day_of_month, - // |month| is 1-based in Exploded, but 0-based in MakeRFC2822DateString. - date_components.month - 1, date_components.year, date_components.hour, - date_components.minute, date_components.second, 0); + String date_string = MakeRFC2822DateString(date, 0); StringBuilder string_builder; string_builder.Append("From: <Saved by Blink>\r\n"); diff --git a/chromium/third_party/blink/renderer/platform/mojo/DEPS b/chromium/third_party/blink/renderer/platform/mojo/DEPS index 9278750b675..de0e119d9dc 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/DEPS +++ b/chromium/third_party/blink/renderer/platform/mojo/DEPS @@ -1,16 +1,25 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/mojo", + + # Dependencies. "+base/callback.h", "+base/containers/span.h", - "+base/message_loop/message_loop.h", + "+base/message_loop/message_loop_current.h", "+base/observer_list.h", "+base/strings/string16.h", - "+mojo/common/big_string.mojom-blink.h", - "+mojo/common/test_common_custom_types.mojom-blink.h", "+mojo/public/cpp/base/time_mojom_traits.h", "+mojo/public/cpp/bindings/binding.h", "+mojo/public/mojom/base/string16.mojom-blink.h", "+services/network/public/mojom/fetch_api.mojom-blink.h", - "+skia/public/interfaces/bitmap_skbitmap_struct_traits.h" + "+skia/public/interfaces/bitmap_skbitmap_struct_traits.h", + + "+third_party/blink/renderer/platform/blob/blob_data.h", + "+third_party/blink/renderer/platform/blob/serialized_blob_struct_traits.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc index 4253e2fd899..6548da748c0 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc +++ b/chromium/third_party/blink/renderer/platform/mojo/big_string_mojom_traits_test.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include "base/rand_util.h" -#include "mojo/common/test_common_custom_types.mojom-blink.h" #include "mojo/public/cpp/base/big_buffer_mojom_traits.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "mojo/public/mojom/base/big_string.mojom-blink.h" 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 6ae19f26328..7312847bb4f 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni +++ b/chromium/third_party/blink/renderer/platform/mojo/blink_typemaps.gni @@ -3,8 +3,9 @@ # found in the LICENSE file. typemaps = [ + "//mojo/public/cpp/base/file_info.typemap", "//mojo/public/cpp/base/file_path.typemap", - "//mojo/common/values.typemap", + "//mojo/public/cpp/base/shared_memory.typemap", "//third_party/blink/renderer/core/messaging/blink_cloneable_message.typemap", "//third_party/blink/renderer/core/messaging/blink_transferable_message.typemap", "//third_party/blink/renderer/platform/blob/serialized_blob.typemap", @@ -20,4 +21,6 @@ typemaps = [ "//third_party/blink/public/platform/modules/bluetooth/bluetooth.typemap", "//third_party/blink/public/platform/modules/fetch/fetch_api_request.typemap", "//third_party/blink/public/platform/modules/notifications/notification_types.typemap", + "//third_party/blink/public/common/manifest/display_mode.typemap", + "//third_party/blink/public/common/screen_orientation/screen_orientation_lock_types.typemap", ] diff --git a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc index 1614f4f0b4a..2d2ee6b8d27 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc +++ b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.cc @@ -8,7 +8,7 @@ #include "mojo/public/cpp/bindings/string_traits_wtf.h" #include "services/network/public/mojom/fetch_api.mojom-blink.h" #include "third_party/blink/public/platform/web_referrer_policy.h" -#include "third_party/blink/renderer/platform/blob/blob_data.h" +#include "third_party/blink/renderer/platform/blob/serialized_blob_struct_traits.h" #include "third_party/blink/renderer/platform/mojo/kurl_struct_traits.h" #include "third_party/blink/renderer/platform/mojo/referrer_struct_traits.h" #include "third_party/blink/renderer/platform/weborigin/referrer.h" @@ -239,36 +239,11 @@ const blink::Referrer& StructTraits<blink::mojom::FetchAPIRequestDataView, } // static -WTF::String StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - blob_uuid(const blink::WebServiceWorkerRequest& request) { - if (request.GetBlobDataHandle()) - return request.GetBlobDataHandle()->Uuid(); - - return WTF::String(); -} - -// static -uint64_t StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - blob_size(const blink::WebServiceWorkerRequest& request) { - if (request.GetBlobDataHandle()) - return request.GetBlobDataHandle()->size(); - - return 0; -} - -// static -blink::mojom::blink::BlobPtr StructTraits<blink::mojom::FetchAPIRequestDataView, - blink::WebServiceWorkerRequest>:: - blob(const blink::WebServiceWorkerRequest& request) { - if (request.GetBlobDataHandle()) { - blink::mojom::blink::BlobPtr result = - request.GetBlobDataHandle()->CloneBlobPtr(); - return result; - } - - return nullptr; +scoped_refptr<blink::BlobDataHandle> StructTraits< + blink::mojom::FetchAPIRequestDataView, + blink::WebServiceWorkerRequest>::blob(const blink::WebServiceWorkerRequest& + request) { + return request.GetBlobDataHandle(); } // static @@ -296,8 +271,7 @@ bool StructTraits<blink::mojom::FetchAPIRequestDataView, blink::KURL url; WTF::String method; WTF::HashMap<WTF::String, WTF::String> headers; - WTF::String blobUuid; - blink::mojom::blink::BlobPtr blob; + scoped_refptr<blink::BlobDataHandle> blob; blink::Referrer referrer; network::mojom::FetchCredentialsMode credentialsMode; network::mojom::FetchRedirectMode redirectMode; @@ -307,7 +281,7 @@ bool StructTraits<blink::mojom::FetchAPIRequestDataView, if (!data.ReadMode(&mode) || !data.ReadRequestContextType(&requestContext) || !data.ReadFrameType(&frameType) || !data.ReadUrl(&url) || !data.ReadMethod(&method) || !data.ReadHeaders(&headers) || - !data.ReadBlobUuid(&blobUuid) || !data.ReadReferrer(&referrer) || + !data.ReadBlob(&blob) || !data.ReadReferrer(&referrer) || !data.ReadCredentialsMode(&credentialsMode) || !data.ReadRedirectMode(&redirectMode) || !data.ReadClientId(&clientId) || !data.ReadIntegrity(&integrity)) { @@ -322,8 +296,7 @@ bool StructTraits<blink::mojom::FetchAPIRequestDataView, out->SetMethod(method); for (const auto& pair : headers) out->SetHeader(pair.key, pair.value); - out->SetBlob(blobUuid, static_cast<long long>(data.blob_size()), - data.TakeBlob<blink::mojom::blink::BlobPtr>().PassInterface()); + out->SetBlobDataHandle(blob); out->SetReferrer(referrer.referrer, static_cast<blink::WebReferrerPolicy>( referrer.referrer_policy)); out->SetCredentialsMode(credentialsMode); diff --git a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h index 0bfcd453764..108156cc814 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h +++ b/chromium/third_party/blink/renderer/platform/mojo/fetch_api_request_struct_traits.h @@ -55,11 +55,7 @@ struct StructTraits<::blink::mojom::FetchAPIRequestDataView, static WTF::HashMap<WTF::String, WTF::String> headers( const ::blink::WebServiceWorkerRequest&); - static WTF::String blob_uuid(const ::blink::WebServiceWorkerRequest&); - - static uint64_t blob_size(const ::blink::WebServiceWorkerRequest&); - - static blink::mojom::blink::BlobPtr blob( + static scoped_refptr<::blink::BlobDataHandle> blob( const ::blink::WebServiceWorkerRequest&); static const ::blink::Referrer& referrer( diff --git a/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h b/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h index 03f2d40ecea..826e676919f 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h +++ b/chromium/third_party/blink/renderer/platform/mojo/mojo_helper.h @@ -5,7 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_HELPER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_MOJO_MOJO_HELPER_H_ -#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" namespace blink { @@ -14,7 +14,7 @@ namespace blink { // TODO(leonhsl): http://crbug.com/660274 Remove this API by ensuring // a message loop before calling blink::initialize(). inline bool CanInitializeMojo() { - return base::MessageLoop::current(); + return base::MessageLoopCurrent::IsSet(); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc index 6f02d86a1e4..e61ef3efb7d 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc +++ b/chromium/third_party/blink/renderer/platform/mojo/notification_struct_traits_test.cc @@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/strings/stringprintf.h" +#include "mojo/public/cpp/test_support/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/modules/notifications/notification.mojom-blink.h" #include "third_party/blink/public/platform/modules/notifications/web_notification_data.h" @@ -144,9 +145,9 @@ TEST(NotificationStructTraitsTest, NotificationResourcesRoundtrip) { WebNotificationResources roundtrip_resources; - ASSERT_TRUE(mojom::blink::NotificationResources::Deserialize( - mojom::blink::NotificationResources::Serialize(&resources), - &roundtrip_resources)); + ASSERT_TRUE( + mojo::test::SerializeAndDeserialize<mojom::blink::NotificationResources>( + &resources, &roundtrip_resources)); ASSERT_FALSE(roundtrip_resources.image.empty()); EXPECT_TRUE(ImagesShareDimensionsAndColor(resources.image, diff --git a/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h b/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h index fa898aa3df1..6ae5f2dccc1 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h +++ b/chromium/third_party/blink/renderer/platform/mojo/referrer_struct_traits.h @@ -35,7 +35,10 @@ struct StructTraits<blink::mojom::ReferrerDataView, blink::Referrer> { out->referrer_policy = static_cast<blink::ReferrerPolicy>(webReferrerPolicy); - out->referrer = AtomicString(referrer.GetString()); + if (referrer.GetString().IsEmpty()) + out->referrer = g_null_atom; + else + out->referrer = AtomicString(referrer.GetString()); // Mimics the DCHECK() done in the blink::Referrer constructor. return referrer.IsValid() || out->referrer == blink::Referrer::NoReferrer(); diff --git a/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h b/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h index 32101602afd..ba5e0f303b4 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h +++ b/chromium/third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h @@ -56,7 +56,7 @@ class RevocableInterfacePtr : public InterfaceInvalidator::Observer { // message pipe already bound to this pointer. RevocableInterfacePtr& operator=(RevocableInterfacePtr&& other) { reset(); - interface_ptr_ = std::move(other.interface_ptr); + interface_ptr_ = std::move(other.interface_ptr_); SetInvalidator(other.invalidator_.get()); // Reset the other interface ptr to remove it as an observer of the // invalidator. diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc index ca4d5c3190a..ca71ff99633 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc +++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits.cc @@ -38,7 +38,7 @@ base::span<const uint16_t> StructTraits<mojo_base::mojom::String16DataView, WTF::String>::data( const WTF::String& input, void* context) { - auto contextObject = static_cast<base::string16*>(context); + auto* contextObject = static_cast<base::string16*>(context); DCHECK_EQ(input.Is8Bit(), !!contextObject); if (contextObject) { diff --git a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc index 8aa308d79c2..07be8469c2d 100644 --- a/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc +++ b/chromium/third_party/blink/renderer/platform/mojo/string16_mojom_traits_test.cc @@ -5,9 +5,7 @@ #include <cstdint> #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/rand_util.h" -#include "mojo/common/test_common_custom_types.mojom-blink.h" #include "mojo/public/cpp/base/big_buffer_mojom_traits.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/test_support/test_utils.h" diff --git a/chromium/third_party/blink/renderer/platform/network/DEPS b/chromium/third_party/blink/renderer/platform/network/DEPS index 531bbba099f..77af399ae9c 100644 --- a/chromium/third_party/blink/renderer/platform/network/DEPS +++ b/chromium/third_party/blink/renderer/platform/network/DEPS @@ -1,4 +1,11 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/network", + + # Dependencies. "+media", "-media/blink", # net/ includes should be allowed only in a limited set of directories, @@ -8,4 +15,23 @@ include_rules = [ "+net/nqe", # For URLRequestDataJob::BuildResponse(). "+net/url_request/url_request_data_job.h", + + "+third_party/blink/renderer/platform/blob/blob_data.h", + "+third_party/blink/renderer/platform/cross_origin_attribute_value.h", + "+third_party/blink/renderer/platform/cross_thread_copier.h", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/crypto.h", + "+third_party/blink/renderer/platform/file_metadata.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/loader", + "+third_party/blink/renderer/platform/loader", + "+third_party/blink/renderer/platform/loader", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/network/form_data_encoder.cc b/chromium/third_party/blink/renderer/platform/network/form_data_encoder.cc index 401ea3591c1..57116306536 100644 --- a/chromium/third_party/blink/renderer/platform/network/form_data_encoder.cc +++ b/chromium/third_party/blink/renderer/platform/network/form_data_encoder.cc @@ -26,7 +26,7 @@ #include "third_party/blink/renderer/platform/network/form_data_encoder.h" #include <limits> -#include "third_party/blink/renderer/platform/wtf/cryptographically_random_number.h" +#include "base/rand_util.h" #include "third_party/blink/renderer/platform/wtf/hex_number.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" @@ -120,17 +120,12 @@ Vector<char> FormDataEncoder::GenerateUniqueBoundaryString() { Append(boundary, "----WebKitFormBoundary"); // Append 16 random 7bit ascii AlphaNumeric characters. - Vector<char> random_bytes; - - for (unsigned i = 0; i < 4; ++i) { - uint32_t randomness = CryptographicallyRandomNumber(); - random_bytes.push_back(kAlphaNumericEncodingMap[(randomness >> 24) & 0x3F]); - random_bytes.push_back(kAlphaNumericEncodingMap[(randomness >> 16) & 0x3F]); - random_bytes.push_back(kAlphaNumericEncodingMap[(randomness >> 8) & 0x3F]); - random_bytes.push_back(kAlphaNumericEncodingMap[randomness & 0x3F]); - } + char random_bytes[16]; + base::RandBytes(random_bytes, sizeof(random_bytes)); + for (char& c : random_bytes) + c = kAlphaNumericEncodingMap[c & 0x3F]; + boundary.Append(random_bytes, sizeof(random_bytes)); - boundary.AppendVector(random_bytes); boundary.push_back( 0); // Add a 0 at the end so we can use this as a C-style string. return boundary; 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 a15991773c2..1951a112128 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 @@ -284,7 +284,7 @@ TEST(HTTPParsersTest, ParseMultipartHeadersResult) { {"Foo: bar\r\nBaz:\n", false, 0}, {"\r\n", true, 2}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { + for (size_t i = 0; i < arraysize(tests); ++i) { ResourceResponse response; size_t end = 0; bool result = ParseMultipartHeadersFromBody( 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 4b669292989..e024e3609bb 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 @@ -104,12 +104,17 @@ bool MIMETypeRegistry::IsSupportedImagePrefixedMIMEType( bool MIMETypeRegistry::IsSupportedImageMIMETypeForEncoding( const String& mime_type) { - if (DeprecatedEqualIgnoringCase(mime_type, "image/jpeg") || - DeprecatedEqualIgnoringCase(mime_type, "image/png")) - return true; - if (DeprecatedEqualIgnoringCase(mime_type, "image/webp")) - return true; - return false; + return (EqualIgnoringASCIICase(mime_type, "image/jpeg") || + EqualIgnoringASCIICase(mime_type, "image/png") || + EqualIgnoringASCIICase(mime_type, "image/webp")); +} + +bool MIMETypeRegistry::IsModernImageMIMEType(const String& mime_type) { + return (EqualIgnoringASCIICase(mime_type, "image/gif") || + EqualIgnoringASCIICase(mime_type, "image/jpeg") || + EqualIgnoringASCIICase(mime_type, "image/png") || + EqualIgnoringASCIICase(mime_type, "image/svg+xml") || + EqualIgnoringASCIICase(mime_type, "image/webp")); } bool MIMETypeRegistry::IsSupportedJavaScriptMIMEType(const String& mime_type) { @@ -184,7 +189,7 @@ bool MIMETypeRegistry::IsJavaAppletMIMEType(const String& mime_type) { } bool MIMETypeRegistry::IsSupportedStyleSheetMIMEType(const String& mime_type) { - return DeprecatedEqualIgnoringCase(mime_type, "text/css"); + return EqualIgnoringASCIICase(mime_type, "text/css"); } bool MIMETypeRegistry::IsSupportedFontMIMEType(const String& mime_type) { @@ -197,7 +202,7 @@ bool MIMETypeRegistry::IsSupportedFontMIMEType(const String& mime_type) { } bool MIMETypeRegistry::IsSupportedTextTrackMIMEType(const String& mime_type) { - return DeprecatedEqualIgnoringCase(mime_type, "text/vtt"); + return EqualIgnoringASCIICase(mime_type, "text/vtt"); } } // namespace blink 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 c487cec6891..94629bc6f44 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 @@ -64,6 +64,10 @@ class PLATFORM_EXPORT MIMETypeRegistry { // Checks to see if a mime type is suitable for being encoded. static bool IsSupportedImageMIMETypeForEncoding(const String& mime_type); + // Checks to see if a mime type is one of the default modern formats supported + // when the 'legacy-image-formats' feature is disabled. + static bool IsModernImageMIMEType(const String& mime_type); + // Checks to see if a mime type is suitable for being loaded as a JavaScript // resource. static bool IsSupportedJavaScriptMIMEType(const String& mime_type); diff --git a/chromium/third_party/blink/renderer/platform/network/mime/mock_mime_registry.h b/chromium/third_party/blink/renderer/platform/network/mime/mock_mime_registry.h index 0316b92bfe0..eb99eeb6b93 100644 --- a/chromium/third_party/blink/renderer/platform/network/mime/mock_mime_registry.h +++ b/chromium/third_party/blink/renderer/platform/network/mime/mock_mime_registry.h @@ -15,7 +15,7 @@ namespace blink { class MockMimeRegistry : public mojom::blink::MimeRegistry { public: MockMimeRegistry() = default; - ~MockMimeRegistry() = default; + ~MockMimeRegistry() override = default; void GetMimeTypeFromExtension( const String& ext, diff --git a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc index 6a36df128fe..e14b462091f 100644 --- a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc +++ b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.cc @@ -173,7 +173,7 @@ NetworkStateNotifier::AddOnLineObserver( void NetworkStateNotifier::SetNetworkConnectionInfoOverride( bool on_line, WebConnectionType type, - Optional<WebEffectiveConnectionType> effective_type, + base::Optional<WebEffectiveConnectionType> effective_type, unsigned long http_rtt_msec, double max_bandwidth_mbps) { DCHECK(IsMainThread()); @@ -396,7 +396,7 @@ double NetworkStateNotifier::GetRandomMultiplier(const String& host) const { unsigned long NetworkStateNotifier::RoundRtt( const String& host, - const Optional<TimeDelta>& rtt) const { + const base::Optional<TimeDelta>& rtt) const { // Limit the size of the buckets and the maximum reported value to reduce // fingerprinting. static const size_t kBucketSize = 50; @@ -420,7 +420,7 @@ unsigned long NetworkStateNotifier::RoundRtt( double NetworkStateNotifier::RoundMbps( const String& host, - const Optional<double>& downlink_mbps) const { + const base::Optional<double>& downlink_mbps) const { // Limit the size of the buckets and the maximum reported value to reduce // fingerprinting. static const size_t kBucketSize = 50; diff --git a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.h b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.h index f5ccbb9054c..dd02480e88a 100644 --- a/chromium/third_party/blink/renderer/platform/network/network_state_notifier.h +++ b/chromium/third_party/blink/renderer/platform/network/network_state_notifier.h @@ -28,6 +28,7 @@ #include <memory> +#include "base/optional.h" #include "base/rand_util.h" #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/web_connection_type.h" @@ -37,7 +38,6 @@ #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "third_party/blink/renderer/platform/wtf/time.h" @@ -59,9 +59,9 @@ class PLATFORM_EXPORT NetworkStateNotifier { double max_bandwidth_mbps = kInvalidMaxBandwidth; WebEffectiveConnectionType effective_type = WebEffectiveConnectionType::kTypeUnknown; - Optional<TimeDelta> http_rtt; - Optional<TimeDelta> transport_rtt; - Optional<double> downlink_throughput_mbps; + base::Optional<TimeDelta> http_rtt; + base::Optional<TimeDelta> transport_rtt; + base::Optional<double> downlink_throughput_mbps; bool save_data = false; }; @@ -72,9 +72,9 @@ class PLATFORM_EXPORT NetworkStateNotifier { WebConnectionType, double max_bandwidth_mbps, WebEffectiveConnectionType, - const Optional<TimeDelta>& http_rtt, - const Optional<TimeDelta>& transport_rtt, - const Optional<double>& downlink_throughput_mbps, + const base::Optional<TimeDelta>& http_rtt, + const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<double>& downlink_throughput_mbps, bool save_data) {} virtual void OnLineStateChange(bool on_line) {} }; @@ -131,7 +131,7 @@ class PLATFORM_EXPORT NetworkStateNotifier { // Returns the current HTTP RTT estimate. If the estimate is unavailable, the // returned optional value is null. - Optional<TimeDelta> HttpRtt() const { + base::Optional<TimeDelta> HttpRtt() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is @@ -141,7 +141,7 @@ class PLATFORM_EXPORT NetworkStateNotifier { // Returns the current transport RTT estimate. If the estimate is unavailable, // the returned optional value is null. - Optional<TimeDelta> TransportRtt() const { + base::Optional<TimeDelta> TransportRtt() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; DCHECK(state.on_line_initialized); @@ -150,7 +150,7 @@ class PLATFORM_EXPORT NetworkStateNotifier { // Returns the current throughput estimate (in megabits per second). If the // estimate is unavailable, the returned optional value is null. - Optional<double> DownlinkThroughputMbps() const { + base::Optional<double> DownlinkThroughputMbps() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; // TODO (tbansal): Add a DCHECK to check that |state.on_line_initialized| is @@ -158,6 +158,9 @@ class PLATFORM_EXPORT NetworkStateNotifier { return state.downlink_throughput_mbps; } + // Returns if the save data functionality has been enabled by the user. + // The returned value does not account for any holdback experiments that may + // be enabled. bool SaveDataEnabled() const { MutexLocker locker(mutex_); const NetworkState& state = has_override_ ? override_ : state_; @@ -224,7 +227,7 @@ class PLATFORM_EXPORT NetworkStateNotifier { void SetNetworkConnectionInfoOverride( bool on_line, WebConnectionType, - Optional<WebEffectiveConnectionType> effective_type, + base::Optional<WebEffectiveConnectionType> effective_type, unsigned long http_rtt_msec, double max_bandwidth_mbps); void SetSaveDataEnabledOverride(bool enabled); @@ -247,12 +250,12 @@ class PLATFORM_EXPORT NetworkStateNotifier { // Returns |rtt| after adding host-specific random noise, and rounding it as // per the NetInfo spec to improve privacy. unsigned long RoundRtt(const String& host, - const Optional<TimeDelta>& rtt) const; + const base::Optional<TimeDelta>& rtt) const; // Returns |downlink_mbps| after adding host-specific random noise, and // rounding it as per the NetInfo spec and to improve privacy. double RoundMbps(const String& host, - const Optional<double>& downlink_mbps) const; + const base::Optional<double>& downlink_mbps) const; // Returns the randomization salt (weak and insecure) that should be used when // adding noise to the network quality metrics. This is known only to the diff --git a/chromium/third_party/blink/renderer/platform/network/network_state_notifier_test.cc b/chromium/third_party/blink/renderer/platform/network/network_state_notifier_test.cc index a059d747ce5..d77df97ec99 100644 --- a/chromium/third_party/blink/renderer/platform/network/network_state_notifier_test.cc +++ b/chromium/third_party/blink/renderer/platform/network/network_state_notifier_test.cc @@ -30,6 +30,8 @@ #include "third_party/blink/renderer/platform/network/network_state_notifier.h" +#include "base/optional.h" +#include "base/single_thread_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_connection_type.h" @@ -38,7 +40,6 @@ #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" #include "third_party/blink/renderer/platform/wtf/functional.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -49,12 +50,13 @@ namespace { const double kNoneMaxBandwidthMbps = 0.0; const double kBluetoothMaxBandwidthMbps = 1.0; const double kEthernetMaxBandwidthMbps = 2.0; -const Optional<TimeDelta> kEthernetHttpRtt(TimeDelta::FromMilliseconds(50)); -const Optional<TimeDelta> kEthernetTransportRtt( +const base::Optional<TimeDelta> kEthernetHttpRtt( + TimeDelta::FromMilliseconds(50)); +const base::Optional<TimeDelta> kEthernetTransportRtt( TimeDelta::FromMilliseconds(25)); -const Optional<double> kEthernetThroughputMbps(75.0); -const Optional<TimeDelta> kUnknownRtt; -const Optional<double> kUnknownThroughputMbps; +const base::Optional<double> kEthernetThroughputMbps(75.0); +const base::Optional<TimeDelta> kUnknownRtt; +const base::Optional<double> kUnknownThroughputMbps; enum class SaveData { kOff = 0, @@ -76,14 +78,13 @@ class StateObserver : public NetworkStateNotifier::NetworkStateObserver { observed_save_data_(SaveData::kOff), callback_count_(0) {} - virtual void ConnectionChange( - WebConnectionType type, - double max_bandwidth_mbps, - WebEffectiveConnectionType effective_type, - const Optional<TimeDelta>& http_rtt, - const Optional<TimeDelta>& transport_rtt, - const Optional<double>& downlink_throughput_mbps, - bool save_data) { + void ConnectionChange(WebConnectionType type, + double max_bandwidth_mbps, + WebEffectiveConnectionType effective_type, + const base::Optional<TimeDelta>& http_rtt, + const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<double>& downlink_throughput_mbps, + bool save_data) override { observed_type_ = type; observed_max_bandwidth_mbps_ = max_bandwidth_mbps; observed_effective_type_ = effective_type; @@ -97,7 +98,7 @@ class StateObserver : public NetworkStateNotifier::NetworkStateObserver { std::move(closure_).Run(); } - virtual void OnLineStateChange(bool on_line) { + void OnLineStateChange(bool on_line) override { observed_on_line_state_ = on_line; callback_count_ += 1; @@ -110,11 +111,13 @@ class StateObserver : public NetworkStateNotifier::NetworkStateObserver { WebEffectiveConnectionType ObservedEffectiveType() const { return observed_effective_type_; } - Optional<TimeDelta> ObservedHttpRtt() const { return observed_http_rtt_; } - Optional<TimeDelta> ObservedTransportRtt() const { + base::Optional<TimeDelta> ObservedHttpRtt() const { + return observed_http_rtt_; + } + base::Optional<TimeDelta> ObservedTransportRtt() const { return observed_transport_rtt_; } - Optional<double> ObservedDownlinkThroughputMbps() const { + base::Optional<double> ObservedDownlinkThroughputMbps() const { return observed_downlink_throughput_mbps_; } bool ObservedOnLineState() const { return observed_on_line_state_; } @@ -150,9 +153,9 @@ class StateObserver : public NetworkStateNotifier::NetworkStateObserver { WebConnectionType observed_type_; double observed_max_bandwidth_mbps_; WebEffectiveConnectionType observed_effective_type_; - Optional<TimeDelta> observed_http_rtt_; - Optional<TimeDelta> observed_transport_rtt_; - Optional<double> observed_downlink_throughput_mbps_; + base::Optional<TimeDelta> observed_http_rtt_; + base::Optional<TimeDelta> observed_transport_rtt_; + base::Optional<double> observed_downlink_throughput_mbps_; bool observed_on_line_state_; SaveData observed_save_data_; int callback_count_; @@ -192,9 +195,9 @@ class NetworkStateNotifierTest : public testing::Test { void SetConnection(WebConnectionType type, double max_bandwidth_mbps, WebEffectiveConnectionType effective_type, - const Optional<TimeDelta>& http_rtt, - const Optional<TimeDelta>& transport_rtt, - const Optional<double>& downlink_throughput_mbps, + const base::Optional<TimeDelta>& http_rtt, + const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<double>& downlink_throughput_mbps, SaveData save_data) { notifier_.SetWebConnection(type, max_bandwidth_mbps); notifier_.SetNetworkQuality( @@ -214,14 +217,15 @@ class NetworkStateNotifierTest : public testing::Test { RunPendingTasks(); } - bool VerifyObservations(const StateObserver& observer, - WebConnectionType type, - double max_bandwidth_mbps, - WebEffectiveConnectionType effective_type, - const Optional<TimeDelta>& http_rtt, - const Optional<TimeDelta>& transport_rtt, - const Optional<double>& downlink_throughput_mbps, - SaveData save_data) const { + bool VerifyObservations( + const StateObserver& observer, + WebConnectionType type, + double max_bandwidth_mbps, + WebEffectiveConnectionType effective_type, + const base::Optional<TimeDelta>& http_rtt, + const base::Optional<TimeDelta>& transport_rtt, + const base::Optional<double>& downlink_throughput_mbps, + SaveData save_data) const { EXPECT_EQ(type, observer.ObservedType()); EXPECT_EQ(max_bandwidth_mbps, observer.ObservedMaxBandwidth()); EXPECT_EQ(effective_type, observer.ObservedEffectiveType()); @@ -937,7 +941,7 @@ TEST_F(NetworkStateNotifierTest, SetNetworkConnectionInfoOverrideGenerateECTs) { kNoneMaxBandwidthMbps, SaveData::kOff)); const struct { - Optional<TimeDelta> rtt; + base::Optional<TimeDelta> rtt; WebEffectiveConnectionType expected_effective_connection_type; } tests[] = { {TimeDelta::FromMilliseconds(100), WebEffectiveConnectionType::kType4G}, 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 3ac8421c7fe..3a5bce276ca 100644 --- a/chromium/third_party/blink/renderer/platform/network/network_utils.cc +++ b/chromium/third_party/blink/renderer/platform/network/network_utils.cc @@ -49,7 +49,7 @@ bool IsReservedIPAddress(const String& host) { StringUTF8Adaptor utf8(host); if (!net::ParseURLHostnameToAddress(utf8.AsStringPiece(), &address)) return false; - return address.IsReserved(); + return !address.IsPubliclyRoutable(); } bool IsLocalHostname(const String& host, bool* is_local6) { diff --git a/chromium/third_party/blink/renderer/platform/network/network_utils_test.cc b/chromium/third_party/blink/renderer/platform/network/network_utils_test.cc index 75ab7cc8651..bb493108ca6 100644 --- a/chromium/third_party/blink/renderer/platform/network/network_utils_test.cc +++ b/chromium/third_party/blink/renderer/platform/network/network_utils_test.cc @@ -32,10 +32,13 @@ TEST(NetworkUtilsTest, IsReservedIPAddress) { "[FFC0:ba98:7654:3210:FEDC:BA98:7654:3210]")); EXPECT_FALSE(NetworkUtils::IsReservedIPAddress( "[2000:ba98:7654:2301:EFCD:BA98:7654:3210]")); + // IPv4-mapped to IPv6 + EXPECT_FALSE(NetworkUtils::IsReservedIPAddress("[::ffff:8.8.8.8]")); // Reserved IPv6 addresses. EXPECT_TRUE(NetworkUtils::IsReservedIPAddress("[::1]")); EXPECT_TRUE(NetworkUtils::IsReservedIPAddress("[::192.9.5.5]")); + EXPECT_TRUE(NetworkUtils::IsReservedIPAddress("[::ffff:192.168.1.1]")); EXPECT_TRUE(NetworkUtils::IsReservedIPAddress("[FEED::BEEF]")); EXPECT_TRUE(NetworkUtils::IsReservedIPAddress( "[FEC0:ba98:7654:3210:FEDC:BA98:7654:3210]")); diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_disposition.h b/chromium/third_party/blink/renderer/platform/network/parsed_content_disposition.h index 46eb0cd5ca9..895da334c67 100644 --- a/chromium/third_party/blink/renderer/platform/network/parsed_content_disposition.h +++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_disposition.h @@ -5,11 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_DISPOSITION_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_DISPOSITION_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -36,7 +36,7 @@ class PLATFORM_EXPORT ParsedContentDisposition final { private: String type_; - WTF::Optional<ParsedContentHeaderFieldParameters> parameters_; + base::Optional<ParsedContentHeaderFieldParameters> parameters_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.cc b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.cc index d1153ab4a3a..bda672d3713 100644 --- a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.cc +++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.cc @@ -32,14 +32,14 @@ namespace blink { // "/" / "[" / "]" / "?" / "=" // ; Must be in quoted-string, // ; to use within parameter values -WTF::Optional<ParsedContentHeaderFieldParameters> +base::Optional<ParsedContentHeaderFieldParameters> ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer tokenizer, Mode mode) { NameValuePairs parameters; while (!tokenizer.IsConsumed()) { if (!tokenizer.Consume(';')) { DVLOG(1) << "Failed to find ';'"; - return WTF::nullopt; + return base::nullopt; } StringView key; @@ -47,16 +47,16 @@ ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer tokenizer, if (!tokenizer.ConsumeToken(Mode::kNormal, key)) { DVLOG(1) << "Invalid content parameter name. (at " << tokenizer.Index() << ")"; - return WTF::nullopt; + return base::nullopt; } if (!tokenizer.Consume('=')) { DVLOG(1) << "Failed to find '='"; - return WTF::nullopt; + return base::nullopt; } if (!tokenizer.ConsumeTokenOrQuotedString(mode, value)) { DVLOG(1) << "Invalid content parameter value (at " << tokenizer.Index() << ", for '" << key.ToString() << "')."; - return WTF::nullopt; + return base::nullopt; } parameters.emplace_back(key.ToString(), value); } diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h index 24a4b160510..99f1cc9bea8 100644 --- a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h +++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h @@ -5,9 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_HEADER_FIELD_PARAMETERS_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_HEADER_FIELD_PARAMETERS_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/vector.h" diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc index 889d0d972af..d1ea6bb6fbe 100644 --- a/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc +++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_header_field_parameters_test.cc @@ -68,7 +68,7 @@ TEST(ParsedContentHeaderFieldParametersTest, ParameterName) { CheckValidity(true, input); - WTF::Optional<ParsedContentHeaderFieldParameters> t = + base::Optional<ParsedContentHeaderFieldParameters> t = ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer(input), Mode::kNormal); ASSERT_TRUE(t); @@ -93,7 +93,7 @@ TEST(ParsedContentHeaderFieldParametersTest, RelaxedParameterName) { CheckValidity(true, input, Mode::kRelaxed); - WTF::Optional<ParsedContentHeaderFieldParameters> t = + base::Optional<ParsedContentHeaderFieldParameters> t = ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer(input), Mode::kRelaxed); ASSERT_TRUE(t); @@ -106,14 +106,14 @@ TEST(ParsedContentHeaderFieldParametersTest, RelaxedParameterName) { TEST(ParsedContentHeaderFieldParametersTest, BeginEnd) { String input = "; a=b; a=c; b=d"; - WTF::Optional<ParsedContentHeaderFieldParameters> t = + base::Optional<ParsedContentHeaderFieldParameters> t = ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer(input), Mode::kNormal); ASSERT_TRUE(t); EXPECT_TRUE(t->HasDuplicatedNames()); EXPECT_EQ(3u, t->ParameterCount()); - auto i = t->begin(); + auto* i = t->begin(); ASSERT_NE(i, t->end()); EXPECT_EQ(i->name, "a"); EXPECT_EQ(i->value, "b"); @@ -135,7 +135,7 @@ TEST(ParsedContentHeaderFieldParametersTest, BeginEnd) { TEST(ParsedContentHeaderFieldParametersTest, RBeginEnd) { String input = "; a=B; A=c; b=d"; - WTF::Optional<ParsedContentHeaderFieldParameters> t = + base::Optional<ParsedContentHeaderFieldParameters> t = ParsedContentHeaderFieldParameters::Parse(HeaderFieldTokenizer(input), Mode::kNormal); ASSERT_TRUE(t); diff --git a/chromium/third_party/blink/renderer/platform/network/parsed_content_type.h b/chromium/third_party/blink/renderer/platform/network/parsed_content_type.h index 1dc43fc8662..f8850926fe2 100644 --- a/chromium/third_party/blink/renderer/platform/network/parsed_content_type.h +++ b/chromium/third_party/blink/renderer/platform/network/parsed_content_type.h @@ -32,10 +32,10 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_TYPE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_NETWORK_PARSED_CONTENT_TYPE_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/network/parsed_content_header_field_parameters.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -68,7 +68,7 @@ class PLATFORM_EXPORT ParsedContentType final { private: String mime_type_; - WTF::Optional<ParsedContentHeaderFieldParameters> parameters_; + base::Optional<ParsedContentHeaderFieldParameters> parameters_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.cc b/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.cc index 0bb965c7bc1..276b9f0d165 100644 --- a/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.cc +++ b/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.cc @@ -7,10 +7,7 @@ #include <unordered_map> #include "base/strings/stringprintf.h" -#include "base/trace_event/heap_profiler_allocation_context_tracker.h" -#include "base/trace_event/heap_profiler_allocation_register.h" #include "base/trace_event/process_memory_dump.h" -#include "base/trace_event/trace_event_memory_overhead.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -18,15 +15,6 @@ namespace blink { namespace { -void ReportAllocation(void* address, size_t size, const char* type_name) { - PartitionAllocMemoryDumpProvider::Instance()->insert(address, size, - type_name); -} - -void ReportFree(void* address) { - PartitionAllocMemoryDumpProvider::Instance()->Remove(address); -} - const char kPartitionAllocDumpName[] = "partition_alloc"; const char kPartitionsDumpName[] = "partitions"; @@ -132,20 +120,6 @@ bool PartitionAllocMemoryDumpProvider::OnMemoryDump( using base::trace_event::MemoryDumpLevelOfDetail; MemoryDumpLevelOfDetail level_of_detail = args.level_of_detail; - if (allocation_register_.is_enabled()) { - // Overhead should always be reported, regardless of light vs. heavy. - base::trace_event::TraceEventMemoryOverhead overhead; - std::unordered_map<base::trace_event::AllocationContext, - base::trace_event::AllocationMetrics> - metrics_by_context; - // Dump only the overhead estimation in non-detailed dumps. - if (level_of_detail == MemoryDumpLevelOfDetail::DETAILED) { - allocation_register_.UpdateAndReturnsMetrics(metrics_by_context); - } - allocation_register_.EstimateTraceMemoryOverhead(&overhead); - memory_dump->DumpHeapUsage(metrics_by_context, overhead, "partition_alloc"); - } - PartitionStatsDumperImpl partition_stats_dumper(memory_dump, level_of_detail); base::trace_event::MemoryAllocatorDump* partitions_dump = @@ -169,43 +143,7 @@ bool PartitionAllocMemoryDumpProvider::OnMemoryDump( return true; } -// |m_allocationRegister| should be initialized only when necessary to avoid -// waste of memory. PartitionAllocMemoryDumpProvider::PartitionAllocMemoryDumpProvider() = default; - PartitionAllocMemoryDumpProvider::~PartitionAllocMemoryDumpProvider() = default; -void PartitionAllocMemoryDumpProvider::OnHeapProfilingEnabled(bool enabled) { - if (enabled) { - allocation_register_.SetEnabled(); - WTF::PartitionAllocHooks::SetAllocationHook(ReportAllocation); - WTF::PartitionAllocHooks::SetFreeHook(ReportFree); - } else { - WTF::PartitionAllocHooks::SetAllocationHook(nullptr); - WTF::PartitionAllocHooks::SetFreeHook(nullptr); - allocation_register_.SetDisabled(); - } -} - -void PartitionAllocMemoryDumpProvider::insert(void* address, - size_t size, - const char* type_name) { - base::trace_event::AllocationContext context; - if (!base::trace_event::AllocationContextTracker:: - GetInstanceForCurrentThread() - ->GetContextSnapshot(&context)) - return; - - context.type_name = type_name; - if (!allocation_register_.is_enabled()) - return; - allocation_register_.Insert(address, size, context); -} - -void PartitionAllocMemoryDumpProvider::Remove(void* address) { - if (!allocation_register_.is_enabled()) - return; - allocation_register_.Remove(address); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h b/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h index 75a8397f7bb..09450b8e996 100644 --- a/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h +++ b/chromium/third_party/blink/renderer/platform/partition_alloc_memory_dump_provider.h @@ -6,7 +6,6 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PARTITION_ALLOC_MEMORY_DUMP_PROVIDER_H_ #include "base/trace_event/memory_dump_provider.h" -#include "base/trace_event/sharded_allocation_register.h" #include "third_party/blink/public/platform/web_common.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" @@ -25,16 +24,9 @@ class BLINK_PLATFORM_EXPORT PartitionAllocMemoryDumpProvider final // MemoryDumpProvider implementation. bool OnMemoryDump(const base::trace_event::MemoryDumpArgs&, base::trace_event::ProcessMemoryDump*) override; - void OnHeapProfilingEnabled(bool) override; - - // These methods are called only from PartitionAllocHooks' callbacks. - void insert(void*, size_t, const char*); - void Remove(void*); private: PartitionAllocMemoryDumpProvider(); - - base::trace_event::ShardedAllocationRegister allocation_register_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/DEPS b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS new file mode 100644 index 00000000000..27fb621260e --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/peerconnection/DEPS @@ -0,0 +1,12 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/peerconnection", + + # Dependencies. + "+third_party/blink/renderer/platform/bindings/script_wrappable.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/wtf", +] 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 f29d0ade191..0b7258484f4 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 @@ -34,6 +34,10 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +namespace webrtc { +class RTCError; +} + namespace blink { class WebRTCSessionDescription; @@ -43,7 +47,7 @@ class RTCSessionDescriptionRequest virtual ~RTCSessionDescriptionRequest() = default; virtual void RequestSucceeded(const WebRTCSessionDescription&) = 0; - virtual void RequestFailed(const String& error) = 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_response_base.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_stats_response_base.h index 7e12d5d69b4..113d1454164 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 @@ -33,7 +33,7 @@ namespace blink { class RTCStatsResponseBase : public ScriptWrappable { public: - virtual ~RTCStatsResponseBase() = default; + ~RTCStatsResponseBase() override = default; virtual void AddStats(const WebRTCLegacyStats&) = 0; }; diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h index d6bac8af610..597cb1e7326 100644 --- a/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h +++ b/chromium/third_party/blink/renderer/platform/peerconnection/rtc_void_request.h @@ -31,9 +31,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VOID_REQUEST_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PEERCONNECTION_RTC_VOID_REQUEST_H_ -#include "third_party/blink/public/platform/web_rtc_error.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/wtf/forward.h" +#include "third_party/webrtc/api/rtcerror.h" namespace blink { @@ -42,7 +42,7 @@ class RTCVoidRequest : public GarbageCollectedFinalized<RTCVoidRequest> { virtual ~RTCVoidRequest() = default; virtual void RequestSucceeded() = 0; - virtual void RequestFailed(const WebRTCError&) = 0; + virtual void RequestFailed(const webrtc::RTCError&) = 0; virtual void Trace(blink::Visitor* visitor) {} diff --git a/chromium/third_party/blink/renderer/platform/platform_chrome_client.h b/chromium/third_party/blink/renderer/platform/platform_chrome_client.h index 7e5695cd79a..4626ea6d008 100644 --- a/chromium/third_party/blink/renderer/platform/platform_chrome_client.h +++ b/chromium/third_party/blink/renderer/platform/platform_chrome_client.h @@ -28,14 +28,11 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/platform_frame_view.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" namespace blink { -class IntRect; - class PLATFORM_EXPORT PlatformChromeClient : public GarbageCollectedFinalized<PlatformChromeClient> { WTF_MAKE_NONCOPYABLE(PlatformChromeClient); @@ -45,19 +42,10 @@ class PLATFORM_EXPORT PlatformChromeClient virtual ~PlatformChromeClient() = default; virtual void Trace(blink::Visitor* visitor) {} - // Requests the host invalidate the contents. - virtual void InvalidateRect(const IntRect& update_rect) = 0; - - // Converts the rect from the viewport coordinates to screen coordinates. - virtual IntRect ViewportToScreen(const IntRect&, - const PlatformFrameView*) const = 0; - // Converts the scalar value from the window coordinates to the viewport // scale. virtual float WindowToViewportScalar(const float) const = 0; - virtual void ScheduleAnimation(const PlatformFrameView*) = 0; - virtual bool IsPopup() { return false; } }; diff --git a/chromium/third_party/blink/renderer/platform/platform_frame_view.h b/chromium/third_party/blink/renderer/platform/platform_frame_view.h deleted file mode 100644 index 78a4136569d..00000000000 --- a/chromium/third_party/blink/renderer/platform/platform_frame_view.h +++ /dev/null @@ -1,25 +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_PLATFORM_FRAME_VIEW_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PLATFORM_FRAME_VIEW_H_ - -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace blink { - -// PlatformFrameView is a base class for core/frame/LocalFrameView. -// PlatformFrameView is needed to let the platform/ layer access functionalities -// of LocalFrameView. -class PLATFORM_EXPORT PlatformFrameView { - public: - PlatformFrameView() = default; - virtual ~PlatformFrameView() = default; - - virtual bool IsLocalFrameView() const { return false; } -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PLATFORM_FRAME_VIEW_H_ diff --git a/chromium/third_party/blink/renderer/platform/plugins/DEPS b/chromium/third_party/blink/renderer/platform/plugins/DEPS new file mode 100644 index 00000000000..ad511e473b0 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/plugins/DEPS @@ -0,0 +1,14 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/plugins", + + # Dependencies. + "+third_party/blink/renderer/platform/graphics/color.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.cc b/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.cc index 26d6f01a055..806586e6cf3 100644 --- a/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.cc +++ b/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.cc @@ -37,7 +37,7 @@ namespace blink { void PluginListBuilder::AddPlugin(const WebString& name, const WebString& description, const WebString& file_name, - WebColor background_color) { + SkColor background_color) { if (results_) { results_->push_back( new PluginInfo(name, file_name, description, background_color)); diff --git a/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.h b/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.h index 4578ae8742c..c4d181a8c37 100644 --- a/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.h +++ b/chromium/third_party/blink/renderer/platform/plugins/plugin_list_builder.h @@ -49,7 +49,7 @@ class PluginListBuilder final : public WebPluginListBuilder { void AddPlugin(const WebString& name, const WebString& description, const WebString& file_name, - WebColor background_color) override; + SkColor background_color) override; void AddMediaTypeToLastPlugin(const WebString& name, const WebString& description) override; void AddFileExtensionToLastMediaType(const WebString& extension) override; diff --git a/chromium/third_party/blink/renderer/platform/png_fuzzer.cc b/chromium/third_party/blink/renderer/platform/png_fuzzer.cc index 8428ae133c0..9d3f7d779eb 100644 --- a/chromium/third_party/blink/renderer/platform/png_fuzzer.cc +++ b/chromium/third_party/blink/renderer/platform/png_fuzzer.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. // TODO (scroggo): Move this to -// third_party/WebKit/Source/platform/image-decoders ? +// third_party/blink/renderer/platform/image-decoders ? // Compile with: // gn gen out/Fuzz '--args=use_libfuzzer=true is_asan=true diff --git a/chromium/third_party/blink/renderer/platform/pod_red_black_tree.h b/chromium/third_party/blink/renderer/platform/pod_red_black_tree.h index b03309aa1f6..873cb0fef8b 100644 --- a/chromium/third_party/blink/renderer/platform/pod_red_black_tree.h +++ b/chromium/third_party/blink/renderer/platform/pod_red_black_tree.h @@ -709,7 +709,7 @@ class PODRedBlackTree { public: Counter() : count_(0) {} - virtual void Visit(const T&) { ++count_; } + void Visit(const T&) override { ++count_; } int Count() const { return count_; } private: diff --git a/chromium/third_party/blink/renderer/platform/precompile_platform.h b/chromium/third_party/blink/renderer/platform/precompile_platform.h index 432604ee6e0..bbd15745717 100644 --- a/chromium/third_party/blink/renderer/platform/precompile_platform.h +++ b/chromium/third_party/blink/renderer/platform/precompile_platform.h @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#if defined(PrecompilePlatform_h_) +#ifdef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRECOMPILE_PLATFORM_H_ #error You shouldn't include the precompiled header file more than once. #endif -#define PrecompilePlatform_h_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PRECOMPILE_PLATFORM_H_ #if defined(_MSC_VER) -#include "build/win/precompile.h" +#include "third_party/blink/renderer/build/win/precompile.h" #elif defined(__APPLE__) -#include "build/mac/prefix.h" +#include "third_party/blink/renderer/build/mac/prefix.h" #else #error implement #endif -// Include Oilpan's Handle.h by default, as it is included by a significant +// Include Oilpan's handle.h by default, as it is included by a significant // portion of platform/ source files. #include "third_party/blink/renderer/platform/heap/handle.h" diff --git a/chromium/third_party/blink/renderer/platform/prerender_client.h b/chromium/third_party/blink/renderer/platform/prerender_client.h index 81108f88b12..0d56cf628c9 100644 --- a/chromium/third_party/blink/renderer/platform/prerender_client.h +++ b/chromium/third_party/blink/renderer/platform/prerender_client.h @@ -46,7 +46,7 @@ class PLATFORM_EXPORT PrerenderClient : public GarbageCollectedMixin { virtual void DidSendLoadForPrerender() = 0; virtual void DidSendDOMContentLoadedForPrerender() = 0; - virtual void Trace(blink::Visitor* visitor) {} + void Trace(blink::Visitor* visitor) override {} }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/probe/DEPS b/chromium/third_party/blink/renderer/platform/probe/DEPS new file mode 100644 index 00000000000..723fe7874d8 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/probe/DEPS @@ -0,0 +1,15 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/probe", + + # Dependencies. + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/loader/fetch/fetch_context.h", + "+third_party/blink/renderer/platform/PlatformProbesInl.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/probe/PlatformProbes.json5 b/chromium/third_party/blink/renderer/platform/probe/PlatformProbes.json5 index 5bef0f3daea..9643fb64623 100644 --- a/chromium/third_party/blink/renderer/platform/probe/PlatformProbes.json5 +++ b/chromium/third_party/blink/renderer/platform/probe/PlatformProbes.json5 @@ -1,11 +1,11 @@ { settings: { - export_header: "platform/platform_export.h", + export_header: "third_party/blink/renderer/platform/platform_export.h", export_symbol: "PLATFORM_EXPORT", - include_path: "platform/probe", + include_path: "third_party/blink/renderer/platform/probe", includes: [ - "platform/PlatformProbeSink.h", - "platform/probe/platform_probes.h", + "third_party/blink/renderer/platform/PlatformProbeSink.h", + "third_party/blink/renderer/platform/probe/platform_probes.h", ] }, observers: { diff --git a/chromium/third_party/blink/renderer/platform/probe/PlatformTraceEventsAgent.cpp b/chromium/third_party/blink/renderer/platform/probe/platform_trace_events_agent.cc index a5ac31a4dd8..da2a3d23c8e 100644 --- a/chromium/third_party/blink/renderer/platform/probe/PlatformTraceEventsAgent.cpp +++ b/chromium/third_party/blink/renderer/platform/probe/platform_trace_events_agent.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/renderer/platform/probe/PlatformTraceEventsAgent.h" +#include "third_party/blink/renderer/platform/probe/platform_trace_events_agent.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" diff --git a/chromium/third_party/blink/renderer/platform/probe/PlatformTraceEventsAgent.h b/chromium/third_party/blink/renderer/platform/probe/platform_trace_events_agent.h index 1332a584992..94811c6e42f 100644 --- a/chromium/third_party/blink/renderer/platform/probe/PlatformTraceEventsAgent.h +++ b/chromium/third_party/blink/renderer/platform/probe/platform_trace_events_agent.h @@ -2,8 +2,8 @@ // 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_PROBE_PLATFORMTRACEEVENTSAGENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PROBE_PLATFORMTRACEEVENTSAGENT_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_PROBE_PLATFORM_TRACE_EVENTS_AGENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_PROBE_PLATFORM_TRACE_EVENTS_AGENT_H_ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -25,4 +25,4 @@ class PLATFORM_EXPORT PlatformTraceEventsAgent } // namespace blink -#endif // !defined(PlatformTraceEventsAgent_h) +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_PROBE_PLATFORM_TRACE_EVENTS_AGENT_H_ 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 bd7e3cabb87..86a111ef2db 100644 --- a/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/chromium/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -113,6 +113,10 @@ settable_from_internals: true, }, { + // Flag set by the media::kAutoplayIgnoreWebAudio feature flag. + name: "AutoplayIgnoresWebAudio", + }, + { name: "AutoplayMutedVideos", settable_from_internals: true, }, @@ -125,9 +129,16 @@ status: "stable", }, { + name: "BlinkGenPropertyTrees", + }, + { name: "BlinkRuntimeCallStats", }, { + name: "BloatedRendererDetection", + status: "experimental", + }, + { name: "BlockCredentialedSubresources", status: "stable", }, @@ -182,10 +193,6 @@ status: "experimental", }, { - name: "CanvasTransformations", - status: "experimental", - }, - { name: "ClickRetargetting", status: "experimental", }, @@ -197,9 +204,6 @@ name: "ClientPlaceholdersForServerLoFi", }, { - name: "CodeCacheAfterExecute" - }, - { name: "CompositedSelectionUpdate", }, { @@ -316,7 +320,11 @@ }, { name: "CSSPartPseudoElement", - status: "test", + status: "experimental", + }, + { + name: "CSSPseudoIS", + status: "experimental", }, { name: "CSSScrollSnapPoints", @@ -350,6 +358,12 @@ name: "CustomElementsBuiltin", status: "stable", }, + // Introduced this flag as stable so web developers can test their sites + // without native Custom Elements v0 support. + { + name: "CustomElementsV0", + status: "stable", + }, { name: "CustomUserTiming", }, @@ -385,6 +399,10 @@ name: "DisableRasterInvalidation", }, { + name: "DisplayCutoutViewportFit", + settable_from_internals: true, + }, + { name: "DisplayNoneIFrameCreatesNoLayoutObject", status: "stable", }, @@ -406,6 +424,11 @@ status: "test", }, { + name: "EventTiming", + origin_trial_feature_name: "EventTiming", + status: "experimental", + }, + { name: "ExecCommandInJavaScript", status: "test", }, @@ -419,9 +442,17 @@ }, { name: "ExperimentalHardwareEchoCancellation", - origin_trial_feature_name: "ExperimentalHardwareEchoCancellation", + origin_trial_feature_name: "ExperimentalHardwareEchoCancellation2", status: "experimental", }, + // Enables a set of features intended to help improve web developer + // productivity, by restricting the use of potentially problematic web- + // platform behaviors, as well as adding new high-level APIs for common + // development patterns. + { + name: "ExperimentalProductivityFeatures", + status: "experimental" + }, { name: "ExperimentalV8Extras", status: "experimental", @@ -508,13 +539,17 @@ { name: "FramebustingNeedsSameOriginOrUserGesture", settable_from_internals: true, - status: "experimental", + status: "stable", }, { name: "FramesTimingFunction", status: "experimental", }, { + name: "FullscreenOptions", + status: "experimental", + }, + { name: "FullscreenUnprefixed", settable_from_internals: true, status: "experimental", @@ -525,11 +560,8 @@ status: "experimental", }, { - name: "GeometryInterfaces", - status: "stable", - }, - { - name: "GetMatchedCSSRules", + name: "GamepadVibration", + status: "experimental", }, { name: "HeapCompaction", @@ -538,6 +570,9 @@ { name: "HeapIncrementalMarking", }, + { + name: "HeapIncrementalMarkingStress" + }, // https://crbug.com/766694 for testing disabling the feature. { name: "HTMLImports", @@ -554,7 +589,7 @@ }, { name: "IdleTimeColdModeSpellChecking", - status: "test", + status: "experimental", }, { name: "ImageDecodingAttribute", @@ -571,16 +606,13 @@ }, { name: "IncrementalShadowDOM", + status: "experimental", }, { name: "InertAttribute", status: "experimental", }, { - name: "InputModeAttribute", - status: "stable", - }, - { name: "InputMultipleFieldsUI", status: "stable", }, @@ -590,17 +622,37 @@ status: "experimental", }, { + name: "IntersectionObserverGeometryMapper", + }, + { + name: "IntersectionObserverV2", + }, + { + // Tracks "jank" from layout objects changing their visual location + // between animation frames (see crbug.com/581518). + name: "JankTracking", + status: "experimental", + }, + { name: "JSImageDecode", status: "stable", }, { name: "KeyboardLock", - status: "test", + status: "stable", + }, + { + name: "KeyboardMap", + status: "experimental", }, { name: "LangAttributeAwareFormControlUI", }, { + name: "LayeredAPI", + implied_by: ["ExperimentalProductivityFeatures"], + }, + { name: "LayoutNG", implied_by: ["LayoutNGBlockFragmentation", "LayoutNGFlexBox"], }, @@ -808,9 +860,6 @@ status: "stable", }, { - name: "NotificationsWithMojo", - }, - { name: "NullableDocumentDomain", status: "experimental", }, @@ -869,7 +918,7 @@ }, { name: "PageLifecycle", - status: "experimental", + status: "stable", }, { name: "PagePopup", @@ -932,7 +981,9 @@ }, { name: "PictureInPictureAPI", - status: "test", + origin_trial_feature_name: "PictureInPictureAPI", + origin_trial_os: ["chromeos", "linux", "macosx", "win"], + status: "experimental", }, { name: "PreciseMemoryInfo", @@ -963,6 +1014,10 @@ name: "PrintBrowser", }, { + name: "PriorityHints", + status: "experimental", + }, + { name: "PushMessaging", status: "stable", }, @@ -1025,8 +1080,6 @@ }, // Handles frame scrolling via the root PaintLayer instead of the FrameView. // The master bug for the root layer scrolling project is crbug.com/417782. - // This REF is enabled iff features::kRootLayerScrolling is on or - // experimental web platform features are enabled. { name: "RootLayerScrolling", status: "stable", @@ -1038,13 +1091,13 @@ }, { name: "RTCRtpSenderParameters", - status: "experimental", + status: "stable", }, // Enables the use of |RTCConfiguration::sdpSemantics| to override the // default SDP semantics at RTCPeerConnection construction. { name: "RTCUnifiedPlan", - status: "experimental", + status: "stable", }, // Overrides the default SDP semantics to be Unified Plan at // RTCPeerConnection construction (unless otherwise specified). @@ -1055,12 +1108,6 @@ name: "ScriptedSpeech", status: "stable", }, - // Scrolls to compensate for layout movements (bit.ly/scroll-anchoring). - { - name: "ScrollAnchoring", - settable_from_internals: true, - status: "experimental", - }, // Serialize and restore scroll anchors. { name: "ScrollAnchorSerialization", @@ -1075,6 +1122,10 @@ status: "stable", }, { + name: "SecMetadata", + status: "experimental" + }, + { name: "SendBeaconThrowForBlobWithNonSimpleType", status: "stable", }, @@ -1101,7 +1152,7 @@ }, { name: "ServiceWorkerUpdateViaCache", - status: "experimental", + status: "stable", }, { name: "SetRootScroller", @@ -1137,7 +1188,7 @@ { name: "SlimmingPaintV175", status: "stable", - implied_by: ["SlimmingPaintV2", "LayoutNG"], + implied_by: ["BlinkGenPropertyTrees", "SlimmingPaintV2", "LayoutNG"], }, { name: "SlimmingPaintV2", @@ -1185,10 +1236,6 @@ name: "TimerThrottlingForHiddenFrames", status: "stable", }, - { - name: "TopNavByUserActivationInSandbox", - status: "stable", - }, // Many websites disable mouse support when touch APIs are available. We'd // like to enable this always but can't until more websites fix this bug. // Chromium sets this conditionally (eg. based on the presence of a @@ -1219,18 +1266,11 @@ status: "stable", }, { - name: "TurnOff2DAndOpacityCompositorAnimations", - }, - { name: "UnclosedFormControlIsInvalid", status: "experimental", }, { name: "UnifiedTouchAdjustment", - status: "experimental", - }, - { - name: "UpdateHoverPostLayout", status: "stable", }, { @@ -1309,6 +1349,12 @@ name: "WebNFC", status: "experimental", }, + { + name: "WebRtcVaapiHWVP8Encoding", + origin_trial_feature_name: "WebRtcVaapiHWVP8Encoding", + origin_trial_os: ["chromeos"], + status: "experimental", + }, // WebShare is enabled by default on Android. { name: "WebShare", @@ -1319,6 +1365,11 @@ status: "stable", }, { + name: "WebUSBOnDedicatedAndSharedWorkers", + status: "test", + depends_on: ["WebUSB"], + }, + { name: "WebVR", origin_trial_feature_name: "WebVR1.1M62", status: "experimental", @@ -1342,6 +1393,9 @@ status: "experimental", }, { + name: "WebXRHitTest", + }, + { name: "WorkerNosniffBlock", status: "test", }, diff --git a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn index c8ee15c3a53..6b3edf24340 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn +++ b/chromium/third_party/blink/renderer/platform/scheduler/BUILD.gn @@ -12,12 +12,9 @@ blink_platform_sources("scheduler") { "base/graceful_queue_shutdown_helper.cc", "base/graceful_queue_shutdown_helper.h", "base/intrusive_heap.h", - "base/lazy_now.cc", - "base/lazy_now.h", "base/moveable_auto_lock.h", "base/real_time_domain.cc", "base/real_time_domain.h", - "base/sequenced_task_source.h", "base/task_queue.cc", "base/task_queue.h", "base/task_queue_impl.cc", @@ -29,7 +26,6 @@ blink_platform_sources("scheduler") { "base/task_queue_selector.h", "base/task_queue_selector_logic.h", "base/task_time_observer.h", - "base/thread_controller.h", "base/thread_controller_impl.cc", "base/thread_controller_impl.h", "base/time_domain.cc", @@ -58,27 +54,23 @@ blink_platform_sources("scheduler") { "child/pollable_thread_safe_flag.h", "child/process_state.cc", "child/process_state.h", - "common/scheduler_helper.cc", - "common/scheduler_helper.h", "child/single_thread_idle_task_runner.cc", - "child/task_runner_impl.cc", - "child/task_runner_impl.h", - "child/web_scheduler.h", - "child/web_scheduler_impl.cc", - "child/web_scheduler_impl.h", + "child/task_queue_with_task_type.cc", + "child/task_queue_with_task_type.h", "child/webthread_base.cc", "child/webthread_impl_for_worker_scheduler.cc", "child/webthread_impl_for_worker_scheduler.h", - "child/worker_global_scope_scheduler.cc", - "child/worker_global_scope_scheduler.h", "child/worker_metrics_helper.cc", "child/worker_metrics_helper.h", - "worker/worker_scheduler_helper.cc", - "worker/worker_scheduler_helper.h", + "child/worker_scheduler.cc", + "child/worker_scheduler.h", "child/worker_scheduler_proxy.cc", "child/worker_scheduler_proxy.h", "child/worker_task_queue.cc", "child/worker_task_queue.h", + "common/scheduler_helper.cc", + "common/scheduler_helper.h", + "common/thread_scheduler.cc", "common/throttling/budget_pool.cc", "common/throttling/budget_pool.h", "common/throttling/cpu_time_budget_pool.cc", @@ -89,45 +81,46 @@ blink_platform_sources("scheduler") { "common/throttling/throttled_time_domain.h", "common/throttling/wake_up_budget_pool.cc", "common/throttling/wake_up_budget_pool.h", + "common/web_thread_scheduler.cc", + "main_thread/auto_advancing_virtual_time_domain.cc", + "main_thread/auto_advancing_virtual_time_domain.h", + "main_thread/deadline_task_runner.cc", + "main_thread/deadline_task_runner.h", "main_thread/frame_origin_type.cc", "main_thread/frame_origin_type.h", "main_thread/frame_scheduler_impl.cc", "main_thread/frame_scheduler_impl.h", + "main_thread/idle_time_estimator.cc", + "main_thread/idle_time_estimator.h", + "main_thread/main_thread_metrics_helper.cc", + "main_thread/main_thread_metrics_helper.h", + "main_thread/main_thread_scheduler_helper.cc", + "main_thread/main_thread_scheduler_helper.h", "main_thread/main_thread_scheduler_impl.cc", "main_thread/main_thread_scheduler_impl.h", + "main_thread/main_thread_task_queue.cc", + "main_thread/main_thread_task_queue.h", "main_thread/page_scheduler_impl.cc", "main_thread/page_scheduler_impl.h", + "main_thread/queueing_time_estimator.cc", + "main_thread/queueing_time_estimator.h", + "main_thread/render_widget_signals.cc", + "main_thread/render_widget_signals.h", + "main_thread/task_cost_estimator.cc", + "main_thread/task_cost_estimator.h", + "main_thread/use_case.h", + "main_thread/user_model.cc", + "main_thread/user_model.h", "main_thread/web_main_thread_scheduler.cc", "main_thread/web_render_widget_scheduling_state.cc", - "public/frame_or_worker_global_scope_scheduler.h", + "public/frame_or_worker_scheduler.h", "public/frame_scheduler.h", "public/non_main_thread_scheduler.h", "public/page_scheduler.h", + "public/thread_scheduler.h", "public/web_main_thread_scheduler.h", - "renderer/auto_advancing_virtual_time_domain.cc", - "renderer/auto_advancing_virtual_time_domain.h", - "renderer/deadline_task_runner.cc", - "renderer/deadline_task_runner.h", "renderer/frame_status.cc", "renderer/frame_status.h", - "renderer/idle_time_estimator.cc", - "renderer/idle_time_estimator.h", - "main_thread/main_thread_scheduler_helper.cc", - "main_thread/main_thread_scheduler_helper.h", - "renderer/main_thread_task_queue.cc", - "renderer/main_thread_task_queue.h", - "renderer/queueing_time_estimator.cc", - "renderer/queueing_time_estimator.h", - "renderer/render_widget_signals.cc", - "renderer/render_widget_signals.h", - "renderer/renderer_metrics_helper.cc", - "renderer/renderer_metrics_helper.h", - "renderer/renderer_web_scheduler_impl.cc", - "renderer/renderer_web_scheduler_impl.h", - "renderer/task_cost_estimator.cc", - "renderer/task_cost_estimator.h", - "renderer/user_model.cc", - "renderer/user_model.h", "renderer/web_scoped_virtual_time_pauser.cc", "renderer/webthread_impl_for_renderer_scheduler.cc", "renderer/webthread_impl_for_renderer_scheduler.h", @@ -146,6 +139,8 @@ blink_platform_sources("scheduler") { "worker/compositor_thread_scheduler.cc", "worker/compositor_thread_scheduler.h", "worker/non_main_thread_scheduler.cc", + "worker/non_main_thread_scheduler_helper.cc", + "worker/non_main_thread_scheduler_helper.h", "worker/worker_thread_scheduler.cc", "worker/worker_thread_scheduler.h", ] @@ -164,7 +159,13 @@ jumbo_source_set("test_support") { testonly = true sources = [ - "base/test_task_time_observer.h", + "base/test/task_queue_manager_for_test.cc", + "base/test/task_queue_manager_for_test.h", + "base/test/test_count_uses_time_source.cc", + "base/test/test_count_uses_time_source.h", + "base/test/test_task_queue.cc", + "base/test/test_task_queue.h", + "base/test/test_task_time_observer.h", "test/fake_frame_scheduler.h", "test/fake_page_scheduler.h", "test/fake_renderer_scheduler.cc", @@ -173,10 +174,6 @@ jumbo_source_set("test_support") { "test/lazy_thread_controller_for_test.cc", "test/lazy_thread_controller_for_test.h", "test/renderer_scheduler_test_support.cc", - "test/task_queue_manager_for_test.cc", - "test/task_queue_manager_for_test.h", - "test/test_task_queue.cc", - "test/test_task_queue.h", ] deps = [ @@ -194,31 +191,29 @@ jumbo_source_set("unit_tests") { "base/intrusive_heap_unittest.cc", "base/task_queue_manager_impl_unittest.cc", "base/task_queue_selector_unittest.cc", - "base/test_count_uses_time_source.cc", - "base/test_count_uses_time_source.h", "base/time_domain_unittest.cc", "base/work_queue_sets_unittest.cc", "base/work_queue_unittest.cc", "child/idle_canceled_delayed_task_sweeper_unittest.cc", "child/idle_helper_unittest.cc", "child/metrics_helper_unittest.cc", - "common/scheduler_helper_unittest.cc", "child/webthread_impl_for_worker_scheduler_unittest.cc", - "child/worker_global_scope_scheduler_unittest.cc", "child/worker_scheduler_proxy_unittest.cc", + "child/worker_scheduler_unittest.cc", + "common/scheduler_helper_unittest.cc", "common/throttling/budget_pool_unittest.cc", "common/throttling/task_queue_throttler_unittest.cc", + "main_thread/auto_advancing_virtual_time_domain_unittest.cc", + "main_thread/deadline_task_runner_unittest.cc", "main_thread/frame_scheduler_impl_unittest.cc", + "main_thread/idle_time_estimator_unittest.cc", + "main_thread/main_thread_metrics_helper_unittest.cc", "main_thread/main_thread_scheduler_impl_unittest.cc", "main_thread/page_scheduler_impl_unittest.cc", - "renderer/auto_advancing_virtual_time_domain_unittest.cc", - "renderer/deadline_task_runner_unittest.cc", - "renderer/idle_time_estimator_unittest.cc", - "renderer/queueing_time_estimator_unittest.cc", - "renderer/render_widget_signals_unittest.cc", - "renderer/renderer_metrics_helper_unittest.cc", - "renderer/task_cost_estimator_unittest.cc", - "renderer/user_model_unittest.cc", + "main_thread/queueing_time_estimator_unittest.cc", + "main_thread/render_widget_signals_unittest.cc", + "main_thread/task_cost_estimator_unittest.cc", + "main_thread/user_model_unittest.cc", "renderer/webthread_impl_for_renderer_scheduler_unittest.cc", "util/task_duration_metric_reporter_unittest.cc", "util/thread_load_tracker_unittest.cc", diff --git a/chromium/third_party/blink/renderer/platform/scheduler/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/DEPS index a011b9d769a..872751e234f 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/DEPS +++ b/chromium/third_party/blink/renderer/platform/scheduler/DEPS @@ -1,4 +1,11 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/scheduler", + + # Dependencies. "+base/atomic_sequence_num.h", "+base/atomicops.h", "+base/bind_helpers.h", @@ -6,12 +13,14 @@ include_rules = [ "+base/cancelable_callback.h", "+base/command_line.h", "+base/compiler_specific.h", + "+base/containers/circular_deque.h", "+base/containers/small_map.h", "+base/feature_list.h", "+base/format_macros.h", "+base/gtest_prod_util.h", "+base/logging.h", "+base/message_loop/message_loop.h", + "+base/message_loop/message_loop_current.h", "+base/metrics/field_trial.h", "+base/metrics/field_trial_params.h", "+base/metrics/histogram_functions.h", @@ -26,11 +35,22 @@ include_rules = [ "+base/synchronization/atomic_flag.h", "+base/synchronization/cancellation_flag.h", "+base/synchronization/lock.h", + "+base/task/sequence_manager", "+base/threading/platform_thread.h", "+base/threading/sequenced_task_runner_handle.h", "+base/threading/thread.h", "+base/threading/thread_checker.h", "+services/metrics", + + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/waitable_event.h", + "+third_party/blink/renderer/platform/web_task_runner.h", + "+third_party/blink/renderer/platform/wtf", ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS b/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS index 53701134c2e..2b191979763 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/DEPS @@ -1,5 +1,8 @@ -specific_include_rules = { - ".*test\.cc": [ - "+components/viz/test", - ], -} +include_rules = [ + "-services", + "-third_party", + + "+third_party/blink/renderer/platform/scheduler/base", + "+third_party/blink/renderer/platform/platform_export.h", + "+base", +] diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/README.md b/chromium/third_party/blink/renderer/platform/scheduler/base/README.md new file mode 100644 index 00000000000..50246536821 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/README.md @@ -0,0 +1,8 @@ +Please refrain from submitting a new code in this directory. +It' going to be moved to //base/sequence_manager. + +Temporary base::sequence_manager namespace in Blink code will disappear soon. +In the meantime it's possible that the code is spread between scheduler/base +and //base/sequence_manager directories. + +See https://crbug.com/783309 for details. diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.cc index 5d262f4956a..0baabcbaf15 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.cc @@ -4,8 +4,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/enqueue_order.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { // Note we set the first |enqueue_order_| to a specific non-zero value, because @@ -16,10 +16,10 @@ EnqueueOrderGenerator::EnqueueOrderGenerator() EnqueueOrderGenerator::~EnqueueOrderGenerator() = default; EnqueueOrder EnqueueOrderGenerator::GenerateNext() { - base::AutoLock lock(lock_); + AutoLock lock(lock_); return enqueue_order_++; } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h b/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h index 9caea897ade..ae5f480feae 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/enqueue_order.h @@ -9,8 +9,8 @@ #include "base/synchronization/lock.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { using EnqueueOrder = uint64_t; @@ -41,12 +41,12 @@ class EnqueueOrderGenerator { } private: - base::Lock lock_; + Lock lock_; EnqueueOrder enqueue_order_; }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_ENQUEUE_ORDER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.cc index c2fc97aafdf..6ea076b1c71 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.cc @@ -4,8 +4,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { GracefulQueueShutdownHelper::GracefulQueueShutdownHelper() @@ -15,26 +15,26 @@ GracefulQueueShutdownHelper::~GracefulQueueShutdownHelper() = default; void GracefulQueueShutdownHelper::GracefullyShutdownTaskQueue( std::unique_ptr<internal::TaskQueueImpl> task_queue) { - base::AutoLock lock(lock_); + AutoLock lock(lock_); if (task_queue_manager_deleted_) return; queues_.push_back(std::move(task_queue)); } void GracefulQueueShutdownHelper::OnTaskQueueManagerDeleted() { - base::AutoLock lock(lock_); + AutoLock lock(lock_); task_queue_manager_deleted_ = true; queues_.clear(); } std::vector<std::unique_ptr<internal::TaskQueueImpl>> GracefulQueueShutdownHelper::TakeQueues() { - base::AutoLock lock(lock_); + AutoLock lock(lock_); std::vector<std::unique_ptr<internal::TaskQueueImpl>> result; result.swap(queues_); return result; } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h index 976feb1ae5d..79d0b1b6890 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h @@ -12,15 +12,15 @@ #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { class TaskQueueImpl; // Thread-safe helper to shutdown queues from any thread. class GracefulQueueShutdownHelper - : public base::RefCountedThreadSafe<GracefulQueueShutdownHelper> { + : public RefCountedThreadSafe<GracefulQueueShutdownHelper> { public: GracefulQueueShutdownHelper(); ~GracefulQueueShutdownHelper(); @@ -33,7 +33,7 @@ class GracefulQueueShutdownHelper std::vector<std::unique_ptr<internal::TaskQueueImpl>> TakeQueues(); private: - base::Lock lock_; + Lock lock_; bool task_queue_manager_deleted_; std::vector<std::unique_ptr<internal::TaskQueueImpl>> queues_; @@ -41,7 +41,7 @@ class GracefulQueueShutdownHelper }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_GRACEFUL_QUEUE_SHUTDOWN_HELPER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h b/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h index 5d5acabdcc5..0b2aa9ff95a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h @@ -10,8 +10,8 @@ #include "base/logging.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { template <typename T> class IntrusiveHeap; @@ -221,7 +221,7 @@ class IntrusiveHeap { size_t size_; }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_INTRUSIVE_HEAP_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap_unittest.cc index d64250ffaf7..c20412c8a78 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/intrusive_heap_unittest.cc @@ -6,8 +6,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace { struct TestElement { @@ -370,5 +370,5 @@ TEST_F(IntrusiveHeapTest, CompareNodes) { EXPECT_TRUE(IntrusiveHeapTest::CompareNodes(six, five)); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.cc deleted file mode 100644 index 4ac96989417..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.cc +++ /dev/null @@ -1,18 +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/base/lazy_now.h" - -#include "base/time/tick_clock.h" - -namespace blink { -namespace scheduler { -base::TimeTicks LazyNow::Now() { - if (!now_) - now_ = tick_clock_->NowTicks(); - return now_.value(); -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.h b/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.h deleted file mode 100644 index c841f20c78a..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/lazy_now.h +++ /dev/null @@ -1,40 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_LAZY_NOW_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_LAZY_NOW_H_ - -#include "base/optional.h" -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace base { -class TickClock; -} - -namespace blink { -namespace scheduler { - -// Now() is somewhat expensive so it makes sense not to call Now() unless we -// really need to. -class PLATFORM_EXPORT LazyNow { - public: - explicit LazyNow(base::TimeTicks now) : tick_clock_(nullptr), now_(now) { - } - - explicit LazyNow(const base::TickClock* tick_clock) - : tick_clock_(tick_clock) {} - - // Result will not be updated on any subsesequent calls. - base::TimeTicks Now(); - - private: - const base::TickClock* tick_clock_; // NOT OWNED - base::Optional<base::TimeTicks> now_; -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_LAZY_NOW_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/moveable_auto_lock.h b/chromium/third_party/blink/renderer/platform/scheduler/base/moveable_auto_lock.h index 60412fbcf25..4065ebe46f8 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/moveable_auto_lock.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/moveable_auto_lock.h @@ -7,12 +7,12 @@ #include "base/synchronization/lock.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class MoveableAutoLock { public: - explicit MoveableAutoLock(base::Lock& lock) : lock_(lock), moved_(false) { + explicit MoveableAutoLock(Lock& lock) : lock_(lock), moved_(false) { lock_.Acquire(); } @@ -30,12 +30,12 @@ class MoveableAutoLock { } private: - base::Lock& lock_; + Lock& lock_; bool moved_; DISALLOW_COPY_AND_ASSIGN(MoveableAutoLock); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_MOVEABLE_AUTO_LOCK_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc index ccdce6fabf1..a30dc11e16b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.cc @@ -8,8 +8,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { RealTimeDomain::RealTimeDomain() : task_queue_manager_(nullptr) {} @@ -25,34 +25,32 @@ LazyNow RealTimeDomain::CreateLazyNow() const { return task_queue_manager_->CreateLazyNow(); } -base::TimeTicks RealTimeDomain::Now() const { +TimeTicks RealTimeDomain::Now() const { return task_queue_manager_->NowTicks(); } -void RealTimeDomain::RequestWakeUpAt(base::TimeTicks now, - base::TimeTicks run_time) { +void RealTimeDomain::RequestWakeUpAt(TimeTicks now, TimeTicks run_time) { // NOTE this is only called if the scheduled runtime is sooner than any // previously scheduled runtime, or there is no (outstanding) previously // scheduled runtime. task_queue_manager_->MaybeScheduleDelayedWork(FROM_HERE, this, now, run_time); } -void RealTimeDomain::CancelWakeUpAt(base::TimeTicks run_time) { +void RealTimeDomain::CancelWakeUpAt(TimeTicks run_time) { task_queue_manager_->CancelDelayedWork(this, run_time); } -base::Optional<base::TimeDelta> RealTimeDomain::DelayTillNextTask( - LazyNow* lazy_now) { - base::TimeTicks next_run_time; +Optional<TimeDelta> RealTimeDomain::DelayTillNextTask(LazyNow* lazy_now) { + TimeTicks next_run_time; if (!NextScheduledRunTime(&next_run_time)) - return base::nullopt; + return nullopt; - base::TimeTicks now = lazy_now->Now(); + TimeTicks now = lazy_now->Now(); if (now >= next_run_time) - return base::TimeDelta(); // Makes DoWork post an immediate continuation. + return TimeDelta(); // Makes DoWork post an immediate continuation. - base::TimeDelta delay = next_run_time - now; - TRACE_EVENT1("renderer.scheduler", "RealTimeDomain::DelayTillNextTask", + TimeDelta delay = next_run_time - now; + TRACE_EVENT1("sequence_manager", "RealTimeDomain::DelayTillNextTask", "delay_ms", delay.InMillisecondsF()); // The next task is sometime in the future. DoWork will make sure it gets @@ -61,10 +59,10 @@ base::Optional<base::TimeDelta> RealTimeDomain::DelayTillNextTask( } void RealTimeDomain::AsValueIntoInternal( - base::trace_event::TracedValue* state) const {} + trace_event::TracedValue* state) const {} const char* RealTimeDomain::GetName() const { return "RealTimeDomain"; } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h index 57e079c2d71..f89191d4627 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/real_time_domain.h @@ -11,8 +11,8 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class PLATFORM_EXPORT RealTimeDomain : public TimeDomain { public: @@ -21,17 +21,16 @@ class PLATFORM_EXPORT RealTimeDomain : public TimeDomain { // TimeDomain implementation: LazyNow CreateLazyNow() const override; - base::TimeTicks Now() const override; - base::Optional<base::TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; + TimeTicks Now() const override; + Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; const char* GetName() const override; protected: void OnRegisterWithTaskQueueManager( TaskQueueManagerImpl* task_queue_manager) override; - void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override; - void CancelWakeUpAt(base::TimeTicks run_time) override; - void AsValueIntoInternal( - base::trace_event::TracedValue* state) const override; + void RequestWakeUpAt(TimeTicks now, TimeTicks run_time) override; + void CancelWakeUpAt(TimeTicks run_time) override; + void AsValueIntoInternal(trace_event::TracedValue* state) const override; private: TaskQueueManagerImpl* task_queue_manager_; // NOT OWNED @@ -39,7 +38,7 @@ class PLATFORM_EXPORT RealTimeDomain : public TimeDomain { DISALLOW_COPY_AND_ASSIGN(RealTimeDomain); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_REAL_TIME_DOMAIN_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h b/chromium/third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h deleted file mode 100644 index 323e0868988..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h +++ /dev/null @@ -1,40 +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_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_ - -#include "base/optional.h" -#include "base/pending_task.h" - -namespace blink { -namespace scheduler { -class LazyNow; - -namespace internal { - -// This is temporary interface for ThreadController to be able to run tasks -// from TaskQueueManager. -class SequencedTaskSource { - public: - // TODO(alexclarke): Move this enum elsewhere. - enum class WorkType { kImmediate, kDelayed }; - - // Take a next task to run from a sequence. - // TODO(altimin): Do not pass |work_type| here. - virtual base::Optional<base::PendingTask> TakeTask() = 0; - - // Notify a sequence that a taken task has been completed. - virtual void DidRunTask() = 0; - - // Returns the delay till the next task, or base::TimeDelta::Max() if there - // isn't one. - virtual base::TimeDelta DelayTillNextTask(LazyNow* lazy_now) = 0; -}; - -} // namespace internal -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.cc index d1dd378e3a8..2f450e4cd54 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.cc @@ -5,16 +5,17 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "base/bind_helpers.h" +#include "base/optional.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { TaskQueue::TaskQueue(std::unique_ptr<internal::TaskQueueImpl> impl, const TaskQueue::Spec& spec) : impl_(std::move(impl)), - thread_id_(base::PlatformThread::CurrentId()), + thread_id_(PlatformThread::CurrentId()), task_queue_manager_(impl_ ? impl_->GetTaskQueueManagerWeakPtr() : nullptr), graceful_queue_shutdown_helper_( @@ -30,18 +31,17 @@ TaskQueue::~TaskQueue() { TakeTaskQueueImpl()); } -TaskQueue::Task::Task(TaskQueue::PostedTask task, - base::TimeTicks desired_run_time) +TaskQueue::Task::Task(TaskQueue::PostedTask task, TimeTicks desired_run_time) : PendingTask(task.posted_from, std::move(task.callback), desired_run_time, task.nestable), task_type_(task.task_type) {} -TaskQueue::PostedTask::PostedTask(base::OnceClosure callback, - base::Location posted_from, - base::TimeDelta delay, - base::Nestable nestable, +TaskQueue::PostedTask::PostedTask(OnceClosure callback, + Location posted_from, + TimeDelta delay, + Nestable nestable, int task_type) : callback(std::move(callback)), posted_from(posted_from), @@ -49,9 +49,18 @@ TaskQueue::PostedTask::PostedTask(base::OnceClosure callback, nestable(nestable), task_type(task_type) {} +TaskQueue::PostedTask::PostedTask(PostedTask&& move_from) + : callback(std::move(move_from.callback)), + posted_from(move_from.posted_from), + delay(move_from.delay), + nestable(move_from.nestable), + task_type(move_from.task_type) {} + +TaskQueue::PostedTask::~PostedTask() = default; + void TaskQueue::ShutdownTaskQueue() { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); - base::AutoLock lock(impl_lock_); + AutoLock lock(impl_lock_); if (!impl_) return; if (!task_queue_manager_) { @@ -70,43 +79,33 @@ bool TaskQueue::RunsTasksInCurrentSequence() const { return IsOnMainThread(); } -bool TaskQueue::PostDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) { - internal::TaskQueueImpl::PostTaskResult result; - { - auto lock = AcquireImplReadLockIfNeeded(); - if (!impl_) - return false; - result = impl_->PostDelayedTask(PostedTask( - std::move(task), from_here, delay, base::Nestable::kNestable)); - } - return result.success; +bool TaskQueue::PostDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) { + return PostTaskWithMetadata( + PostedTask(std::move(task), from_here, delay, Nestable::kNestable)); } -bool TaskQueue::PostNonNestableDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) { - internal::TaskQueueImpl::PostTaskResult result; - { - auto lock = AcquireImplReadLockIfNeeded(); - if (!impl_) - return false; - result = impl_->PostDelayedTask(PostedTask( - std::move(task), from_here, delay, base::Nestable::kNonNestable)); - } - return result.success; +bool TaskQueue::PostNonNestableDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) { + return PostTaskWithMetadata( + PostedTask(std::move(task), from_here, delay, Nestable::kNonNestable)); } bool TaskQueue::PostTaskWithMetadata(PostedTask task) { - internal::TaskQueueImpl::PostTaskResult result; - { - auto lock = AcquireImplReadLockIfNeeded(); - if (!impl_) - return false; - result = impl_->PostDelayedTask(std::move(task)); - } - return result.success; + Optional<MoveableAutoLock> lock = AcquireImplReadLockIfNeeded(); + if (!impl_) + return false; + internal::TaskQueueImpl::PostTaskResult result( + impl_->PostDelayedTask(std::move(task))); + if (result.success) + return true; + // If posting task was unsuccessful then |result| will contain + // the original task which should be destructed outside of the lock. + lock = nullopt; + // Task gets implicitly destructed here. + return false; } std::unique_ptr<TaskQueue::QueueEnabledVoter> @@ -145,10 +144,10 @@ bool TaskQueue::HasTaskToRunImmediately() const { return impl_->HasTaskToRunImmediately(); } -base::Optional<base::TimeTicks> TaskQueue::GetNextScheduledWakeUp() { +Optional<TimeTicks> TaskQueue::GetNextScheduledWakeUp() { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (!impl_) - return base::nullopt; + return nullopt; return impl_->GetNextScheduledWakeUp(); } @@ -166,16 +165,14 @@ TaskQueue::QueuePriority TaskQueue::GetQueuePriority() const { return impl_->GetQueuePriority(); } -void TaskQueue::AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { +void TaskQueue::AddTaskObserver(MessageLoop::TaskObserver* task_observer) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (!impl_) return; impl_->AddTaskObserver(task_observer); } -void TaskQueue::RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { +void TaskQueue::RemoveTaskObserver(MessageLoop::TaskObserver* task_observer) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (!impl_) return; @@ -196,8 +193,7 @@ TimeDomain* TaskQueue::GetTimeDomain() const { return impl_->GetTimeDomain(); } -void TaskQueue::SetBlameContext( - base::trace_event::BlameContext* blame_context) { +void TaskQueue::SetBlameContext(trace_event::BlameContext* blame_context) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); if (!impl_) return; @@ -211,7 +207,7 @@ void TaskQueue::InsertFence(InsertFencePosition position) { impl_->InsertFence(position); } -void TaskQueue::InsertFenceAt(base::TimeTicks time) { +void TaskQueue::InsertFenceAt(TimeTicks time) { impl_->InsertFenceAt(time); } @@ -250,23 +246,21 @@ void TaskQueue::SetObserver(Observer* observer) { if (observer) { // Observer is guaranteed to outlive TaskQueue and TaskQueueImpl lifecycle // is controlled by |this|. - impl_->SetOnNextWakeUpChangedCallback(base::BindRepeating( - &TaskQueue::Observer::OnQueueNextWakeUpChanged, - base::Unretained(observer), base::Unretained(this))); - } else { impl_->SetOnNextWakeUpChangedCallback( - base::RepeatingCallback<void(base::TimeTicks)>()); + BindRepeating(&TaskQueue::Observer::OnQueueNextWakeUpChanged, + Unretained(observer), Unretained(this))); + } else { + impl_->SetOnNextWakeUpChangedCallback(RepeatingCallback<void(TimeTicks)>()); } } bool TaskQueue::IsOnMainThread() const { - return thread_id_ == base::PlatformThread::CurrentId(); + return thread_id_ == PlatformThread::CurrentId(); } -base::Optional<MoveableAutoLock> TaskQueue::AcquireImplReadLockIfNeeded() - const { +Optional<MoveableAutoLock> TaskQueue::AcquireImplReadLockIfNeeded() const { if (IsOnMainThread()) - return base::nullopt; + return nullopt; return MoveableAutoLock(impl_lock_); } @@ -275,5 +269,5 @@ std::unique_ptr<internal::TaskQueueImpl> TaskQueue::TakeTaskQueueImpl() { return std::move(impl_); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.h index 031204f5581..187a9c15af3 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue.h @@ -23,11 +23,9 @@ class BlameContext; } } // namespace base -namespace blink { -namespace scheduler { -namespace task_queue_throttler_unittest { -class TaskQueueThrottlerTest; -} +namespace base { +namespace sequence_manager { + namespace internal { class TaskQueueImpl; } @@ -35,7 +33,7 @@ class TaskQueueImpl; class TimeDomain; class TaskQueueManagerImpl; -class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { +class PLATFORM_EXPORT TaskQueue : public SingleThreadTaskRunner { public: class PLATFORM_EXPORT Observer { public: @@ -43,30 +41,33 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { // Notify observer that the time at which this queue wants to run // the next task has changed. |next_wakeup| can be in the past - // (e.g. base::TimeTicks() can be used to notify about immediate work). + // (e.g. TimeTicks() can be used to notify about immediate work). // Can be called on any thread // All methods but SetObserver, SetTimeDomain and GetTimeDomain can be // called on |queue|. // - // TODO(altimin): Make it base::Optional<base::TimeTicks> to tell + // TODO(altimin): Make it Optional<TimeTicks> to tell // observer about cancellations. virtual void OnQueueNextWakeUpChanged(TaskQueue* queue, - base::TimeTicks next_wake_up) = 0; + TimeTicks next_wake_up) = 0; }; - // A wrapper around base::OnceClosure with additional metadata to be passed + // A wrapper around OnceClosure with additional metadata to be passed // to PostTask and plumbed until PendingTask is created. struct PLATFORM_EXPORT PostedTask { - PostedTask(base::OnceClosure callback, - base::Location posted_from, - base::TimeDelta delay = base::TimeDelta(), - base::Nestable nestable = base::Nestable::kNestable, + PostedTask(OnceClosure callback, + Location posted_from, + TimeDelta delay = TimeDelta(), + Nestable nestable = Nestable::kNestable, int task_type = 0); - - base::OnceClosure callback; - base::Location posted_from; - base::TimeDelta delay; - base::Nestable nestable; + PostedTask(PostedTask&& move_from); + PostedTask(const PostedTask& copy_from) = delete; + ~PostedTask(); + + OnceClosure callback; + Location posted_from; + TimeDelta delay; + Nestable nestable; int task_type; }; @@ -134,9 +135,9 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { }; // Interface to pass per-task metadata to RendererScheduler. - class PLATFORM_EXPORT Task : public base::PendingTask { + class PLATFORM_EXPORT Task : public PendingTask { public: - Task(PostedTask posted_task, base::TimeTicks desired_run_time); + Task(PostedTask posted_task, TimeTicks desired_run_time); int task_type() const { return task_type_; } @@ -183,9 +184,9 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { // Returns requested run time of next scheduled wake-up for a delayed task // which is not ready to run. If there are no such tasks or the queue is - // disabled (by a QueueEnabledVoter) it returns base::nullopt. + // disabled (by a QueueEnabledVoter) it returns nullopt. // NOTE: this must be called on the thread this TaskQueue was created by. - base::Optional<base::TimeTicks> GetNextScheduledWakeUp(); + Optional<TimeTicks> GetNextScheduledWakeUp(); // Can be called on any thread. virtual const char* GetName() const; @@ -199,13 +200,13 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { // These functions can only be called on the same thread that the task queue // manager executes its tasks on. - void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); - void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer); + void AddTaskObserver(MessageLoop::TaskObserver* task_observer); + void RemoveTaskObserver(MessageLoop::TaskObserver* task_observer); // Set the blame context which is entered and left while executing tasks from // this task queue. |blame_context| must be null or outlive this task queue. // Must be called on the thread this TaskQueue was created by. - void SetBlameContext(base::trace_event::BlameContext* blame_context); + void SetBlameContext(trace_event::BlameContext* blame_context); // Removes the task queue from the previous TimeDomain and adds it to // |domain|. This is a moderately expensive operation. @@ -237,7 +238,7 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { // Only one fence can be scheduled at a time. Inserting a new fence // will automatically remove the previous one, regardless of fence type. void InsertFence(InsertFencePosition position); - void InsertFenceAt(base::TimeTicks time); + void InsertFenceAt(TimeTicks time); // Removes any previously added fence and unblocks execution of any tasks // blocked by it. @@ -250,33 +251,32 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { void SetObserver(Observer* observer); - // base::SingleThreadTaskRunner implementation + // SingleThreadTaskRunner implementation bool RunsTasksInCurrentSequence() const override; - bool PostDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override; - bool PostNonNestableDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override; + bool PostDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) override; + bool PostNonNestableDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) override; bool PostTaskWithMetadata(PostedTask task); + // TODO(kraynov): Make protected. + internal::TaskQueueImpl* GetTaskQueueImpl() const { return impl_.get(); } + protected: TaskQueue(std::unique_ptr<internal::TaskQueueImpl> impl, const TaskQueue::Spec& spec); ~TaskQueue() override; - internal::TaskQueueImpl* GetTaskQueueImpl() const { return impl_.get(); } - private: friend class internal::TaskQueueImpl; friend class TaskQueueManagerImpl; - friend class task_queue_throttler_unittest::TaskQueueThrottlerTest; - bool IsOnMainThread() const; - base::Optional<MoveableAutoLock> AcquireImplReadLockIfNeeded() const; + Optional<MoveableAutoLock> AcquireImplReadLockIfNeeded() const; // Take |impl_| and untie it from the enclosing task queue. std::unique_ptr<internal::TaskQueueImpl> TakeTaskQueueImpl(); @@ -286,12 +286,12 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { // |impl_lock_| must be acquired when writing to |impl_| or when accessing // it from non-main thread. Reading from the main thread does not require // a lock. - mutable base::Lock impl_lock_; + mutable Lock impl_lock_; std::unique_ptr<internal::TaskQueueImpl> impl_; - const base::PlatformThreadId thread_id_; + const PlatformThreadId thread_id_; - const base::WeakPtr<TaskQueueManagerImpl> task_queue_manager_; + const WeakPtr<TaskQueueManagerImpl> task_queue_manager_; const scoped_refptr<internal::GracefulQueueShutdownHelper> graceful_queue_shutdown_helper_; @@ -301,7 +301,7 @@ class PLATFORM_EXPORT TaskQueue : public base::SingleThreadTaskRunner { DISALLOW_COPY_AND_ASSIGN(TaskQueue); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc index d53960530ce..a3356141268 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.cc @@ -7,15 +7,15 @@ #include <memory> #include <utility> +#include "base/strings/stringprintf.h" #include "base/time/time.h" #include "base/trace_event/blame_context.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { // static const char* TaskQueue::PriorityToString(TaskQueue::QueuePriority priority) { @@ -44,7 +44,7 @@ TaskQueueImpl::TaskQueueImpl(TaskQueueManagerImpl* task_queue_manager, TimeDomain* time_domain, const TaskQueue::Spec& spec) : name_(spec.name), - thread_id_(base::PlatformThread::CurrentId()), + thread_id_(PlatformThread::CurrentId()), any_thread_(task_queue_manager, time_domain), main_thread_only_(task_queue_manager, this, time_domain), should_monitor_quiescence_(spec.should_monitor_quiescence), @@ -55,7 +55,7 @@ TaskQueueImpl::TaskQueueImpl(TaskQueueManagerImpl* task_queue_manager, TaskQueueImpl::~TaskQueueImpl() { #if DCHECK_IS_ON() - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); // NOTE this check shouldn't fire because |TaskQueueManagerImpl::queues_| // contains a strong reference to this TaskQueueImpl and the // TaskQueueManagerImpl destructor calls UnregisterTaskQueue on all task @@ -66,15 +66,19 @@ TaskQueueImpl::~TaskQueueImpl() { } TaskQueueImpl::PostTaskResult::PostTaskResult() - : task(base::OnceClosure(), base::Location()) {} + : success(false), task(OnceClosure(), Location()) {} TaskQueueImpl::PostTaskResult::PostTaskResult(bool success, TaskQueue::PostedTask task) : success(success), task(std::move(task)) {} +TaskQueueImpl::PostTaskResult::PostTaskResult(PostTaskResult&& move_from) + : success(move_from.success), task(std::move(move_from.task)) {} + +TaskQueueImpl::PostTaskResult::~PostTaskResult() = default; + TaskQueueImpl::PostTaskResult TaskQueueImpl::PostTaskResult::Success() { - return PostTaskResult( - true, TaskQueue::PostedTask(base::OnceClosure(), base::Location())); + return PostTaskResult(true, TaskQueue::PostedTask(OnceClosure(), Location())); } TaskQueueImpl::PostTaskResult TaskQueueImpl::PostTaskResult::Fail( @@ -83,7 +87,7 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostTaskResult::Fail( } TaskQueueImpl::Task::Task(TaskQueue::PostedTask task, - base::TimeTicks desired_run_time, + TimeTicks desired_run_time, EnqueueOrder sequence_number) : TaskQueue::Task(std::move(task), desired_run_time), #ifndef NDEBUG @@ -94,7 +98,7 @@ TaskQueueImpl::Task::Task(TaskQueue::PostedTask task, } TaskQueueImpl::Task::Task(TaskQueue::PostedTask task, - base::TimeTicks desired_run_time, + TimeTicks desired_run_time, EnqueueOrder sequence_number, EnqueueOrder enqueue_order) : TaskQueue::Task(std::move(task), desired_run_time), @@ -135,9 +139,8 @@ void TaskQueueImpl::UnregisterTaskQueue() { TaskDeque immediate_incoming_queue; { - base::AutoLock lock(any_thread_lock_); - base::AutoLock immediate_incoming_queue_lock( - immediate_incoming_queue_lock_); + AutoLock lock(any_thread_lock_); + AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); if (main_thread_only().time_domain) main_thread_only().time_domain->UnregisterQueue(this); @@ -155,7 +158,7 @@ void TaskQueueImpl::UnregisterTaskQueue() { OnNextWakeUpChangedCallback(); main_thread_only().on_next_wake_up_changed_callback = OnNextWakeUpChangedCallback(); - immediate_incoming_queue.Swap(immediate_incoming_queue_); + immediate_incoming_queue.swap(immediate_incoming_queue_); } // It is possible for a task to hold a scoped_refptr to this, which @@ -184,7 +187,7 @@ const char* TaskQueueImpl::GetName() const { } bool TaskQueueImpl::RunsTasksInCurrentSequence() const { - return base::PlatformThread::CurrentId() == thread_id_; + return PlatformThread::CurrentId() == thread_id_; } TaskQueueImpl::PostTaskResult TaskQueueImpl::PostDelayedTask( @@ -200,7 +203,7 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostImmediateTaskImpl( // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 // for details. CHECK(task.callback); - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); if (!any_thread().task_queue_manager) return PostTaskResult::Fail(std::move(task)); @@ -218,8 +221,8 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostDelayedTaskImpl( // Use CHECK instead of DCHECK to crash earlier. See http://crbug.com/711167 // for details. CHECK(task.callback); - DCHECK_GT(task.delay, base::TimeDelta()); - if (base::PlatformThread::CurrentId() == thread_id_) { + DCHECK_GT(task.delay, TimeDelta()); + if (PlatformThread::CurrentId() == thread_id_) { // Lock-free fast path for delayed tasks posted from the main thread. if (!main_thread_only().task_queue_manager) return PostTaskResult::Fail(std::move(task)); @@ -227,8 +230,8 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostDelayedTaskImpl( EnqueueOrder sequence_number = main_thread_only().task_queue_manager->GetNextSequenceNumber(); - base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); - base::TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; + TimeTicks time_domain_now = main_thread_only().time_domain->Now(); + TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; PushOntoDelayedIncomingQueueFromMainThread( Task(std::move(task), time_domain_delayed_run_time, sequence_number), time_domain_now); @@ -237,15 +240,15 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostDelayedTaskImpl( // be common. This pathway is less optimal than perhaps it could be // because it causes two main thread tasks to be run. Should this // assumption prove to be false in future, we may need to revisit this. - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); if (!any_thread().task_queue_manager) return PostTaskResult::Fail(std::move(task)); EnqueueOrder sequence_number = any_thread().task_queue_manager->GetNextSequenceNumber(); - base::TimeTicks time_domain_now = any_thread().time_domain->Now(); - base::TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; + TimeTicks time_domain_now = any_thread().time_domain->Now(); + TimeTicks time_domain_delayed_run_time = time_domain_now + task.delay; PushOntoDelayedIncomingQueueLocked( Task(std::move(task), time_domain_delayed_run_time, sequence_number)); } @@ -254,7 +257,7 @@ TaskQueueImpl::PostTaskResult TaskQueueImpl::PostDelayedTaskImpl( void TaskQueueImpl::PushOntoDelayedIncomingQueueFromMainThread( Task pending_task, - base::TimeTicks now) { + TimeTicks now) { main_thread_only().task_queue_manager->DidQueueTask(pending_task); main_thread_only().delayed_incoming_queue.push(std::move(pending_task)); @@ -270,20 +273,19 @@ void TaskQueueImpl::PushOntoDelayedIncomingQueueLocked(Task pending_task) { int thread_hop_task_sequence_number = any_thread().task_queue_manager->GetNextSequenceNumber(); // TODO(altimin): Add a copy method to Task to capture metadata here. - PushOntoImmediateIncomingQueueLocked( - Task(TaskQueue::PostedTask( - base::BindOnce(&TaskQueueImpl::ScheduleDelayedWorkTask, - base::Unretained(this), std::move(pending_task)), - FROM_HERE, base::TimeDelta(), base::Nestable::kNonNestable, - pending_task.task_type()), - base::TimeTicks(), thread_hop_task_sequence_number, - thread_hop_task_sequence_number)); + PushOntoImmediateIncomingQueueLocked(Task( + TaskQueue::PostedTask(BindOnce(&TaskQueueImpl::ScheduleDelayedWorkTask, + Unretained(this), std::move(pending_task)), + FROM_HERE, TimeDelta(), Nestable::kNonNestable, + pending_task.task_type()), + TimeTicks(), thread_hop_task_sequence_number, + thread_hop_task_sequence_number)); } void TaskQueueImpl::ScheduleDelayedWorkTask(Task pending_task) { DCHECK(main_thread_checker_.CalledOnValidThread()); - base::TimeTicks delayed_run_time = pending_task.delayed_run_time; - base::TimeTicks time_domain_now = main_thread_only().time_domain->Now(); + TimeTicks delayed_run_time = pending_task.delayed_run_time; + TimeTicks time_domain_now = main_thread_only().time_domain->Now(); if (delayed_run_time <= time_domain_now) { // If |delayed_run_time| is in the past then push it onto the work queue // immediately. To ensure the right task ordering we need to temporarily @@ -307,10 +309,10 @@ void TaskQueueImpl::PushOntoImmediateIncomingQueueLocked(Task task) { bool was_immediate_incoming_queue_empty; EnqueueOrder sequence_number = task.sequence_num; - base::TimeTicks desired_run_time = task.delayed_run_time; + TimeTicks desired_run_time = task.delayed_run_time; { - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); was_immediate_incoming_queue_empty = immediate_incoming_queue().empty(); immediate_incoming_queue().push_back(std::move(task)); any_thread().task_queue_manager->DidQueueTask( @@ -340,9 +342,9 @@ void TaskQueueImpl::ReloadImmediateWorkQueueIfEmpty() { } TaskQueueImpl::TaskDeque TaskQueueImpl::TakeImmediateIncomingQueue() { - base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); + AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); TaskQueueImpl::TaskDeque queue; - queue.Swap(immediate_incoming_queue()); + queue.swap(immediate_incoming_queue()); // Activate delayed fence if necessary. This is ideologically similar to // ActivateDelayedFenceIfNeeded, but due to immediate tasks being posted @@ -352,7 +354,7 @@ TaskQueueImpl::TaskDeque TaskQueueImpl::TakeImmediateIncomingQueue() { if (main_thread_only().delayed_fence) { for (const Task& task : queue) { if (task.delayed_run_time >= main_thread_only().delayed_fence.value()) { - main_thread_only().delayed_fence = base::nullopt; + main_thread_only().delayed_fence = nullopt; DCHECK_EQ(main_thread_only().current_fence, static_cast<EnqueueOrder>(EnqueueOrderValues::kNone)); main_thread_only().current_fence = task.enqueue_order(); @@ -377,7 +379,7 @@ bool TaskQueueImpl::IsEmpty() const { return false; } - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); return immediate_incoming_queue().empty(); } @@ -387,7 +389,7 @@ size_t TaskQueueImpl::GetNumberOfPendingTasks() const { task_count += main_thread_only().delayed_incoming_queue.size(); task_count += main_thread_only().immediate_work_queue->Size(); - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); task_count += immediate_incoming_queue().size(); return task_count; } @@ -408,23 +410,23 @@ bool TaskQueueImpl::HasTaskToRunImmediately() const { } // Finally tasks on |immediate_incoming_queue| count as immediate work. - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); return !immediate_incoming_queue().empty(); } -base::Optional<TaskQueueImpl::DelayedWakeUp> +Optional<TaskQueueImpl::DelayedWakeUp> TaskQueueImpl::GetNextScheduledWakeUpImpl() { // Note we don't scheduled a wake-up for disabled queues. if (main_thread_only().delayed_incoming_queue.empty() || !IsQueueEnabled()) - return base::nullopt; + return nullopt; return main_thread_only().delayed_incoming_queue.top().delayed_wake_up(); } -base::Optional<base::TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { - base::Optional<DelayedWakeUp> wake_up = GetNextScheduledWakeUpImpl(); +Optional<TimeTicks> TaskQueueImpl::GetNextScheduledWakeUp() { + Optional<DelayedWakeUp> wake_up = GetNextScheduledWakeUpImpl(); if (!wake_up) - return base::nullopt; + return nullopt; return wake_up->time; } @@ -462,17 +464,17 @@ void TaskQueueImpl::WakeUpForDelayedWork(LazyNow* lazy_now) { void TaskQueueImpl::TraceQueueSize() const { bool is_tracing; TRACE_EVENT_CATEGORY_GROUP_ENABLED( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), &is_tracing); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), &is_tracing); if (!is_tracing) return; // It's only safe to access the work queues from the main thread. // TODO(alexclarke): We should find another way of tracing this - if (base::PlatformThread::CurrentId() != thread_id_) + if (PlatformThread::CurrentId() != thread_id_) return; - base::AutoLock lock(immediate_incoming_queue_lock_); - TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), GetName(), + AutoLock lock(immediate_incoming_queue_lock_); + TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), GetName(), immediate_incoming_queue().size() + main_thread_only().immediate_work_queue->Size() + main_thread_only().delayed_work_queue->Size() + @@ -493,10 +495,10 @@ TaskQueue::QueuePriority TaskQueueImpl::GetQueuePriority() const { return static_cast<TaskQueue::QueuePriority>(set_index); } -void TaskQueueImpl::AsValueInto(base::TimeTicks now, - base::trace_event::TracedValue* state) const { - base::AutoLock lock(any_thread_lock_); - base::AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); +void TaskQueueImpl::AsValueInto(TimeTicks now, + trace_event::TracedValue* state) const { + AutoLock lock(any_thread_lock_); + AutoLock immediate_incoming_queue_lock(immediate_incoming_queue_lock_); state->BeginDictionary(); state->SetString("name", GetName()); if (!main_thread_only().task_queue_manager) { @@ -508,7 +510,10 @@ void TaskQueueImpl::AsValueInto(base::TimeTicks now, DCHECK(main_thread_only().delayed_work_queue); DCHECK(main_thread_only().immediate_work_queue); - state->SetString("task_queue_id", PointerToString(this)); + state->SetString( + "task_queue_id", + StringPrintf("0x%" PRIx64, + static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this)))); state->SetBoolean("enabled", IsQueueEnabled()); state->SetString("time_domain_name", main_thread_only().time_domain->GetName()); @@ -521,7 +526,7 @@ void TaskQueueImpl::AsValueInto(base::TimeTicks now, state->SetInteger("delayed_work_queue_size", main_thread_only().delayed_work_queue->Size()); if (!main_thread_only().delayed_incoming_queue.empty()) { - base::TimeDelta delay_to_next_task = + TimeDelta delay_to_next_task = (main_thread_only().delayed_incoming_queue.top().delayed_run_time - main_thread_only().time_domain->CreateLazyNow().Now()); state->SetDouble("delay_to_next_task_ms", @@ -534,7 +539,13 @@ void TaskQueueImpl::AsValueInto(base::TimeTicks now, "delayed_fence_seconds_from_now", (main_thread_only().delayed_fence.value() - now).InSecondsF()); } - if (AreVerboseSnapshotsEnabled()) { + + bool verbose = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.verbose_snapshots"), + &verbose); + + if (verbose) { state->BeginArray("immediate_incoming_queue"); QueueAsValueInto(immediate_incoming_queue(), now, state); state->EndArray(); @@ -552,18 +563,16 @@ void TaskQueueImpl::AsValueInto(base::TimeTicks now, state->EndDictionary(); } -void TaskQueueImpl::AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { +void TaskQueueImpl::AddTaskObserver(MessageLoop::TaskObserver* task_observer) { main_thread_only().task_observers.AddObserver(task_observer); } void TaskQueueImpl::RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { + MessageLoop::TaskObserver* task_observer) { main_thread_only().task_observers.RemoveObserver(task_observer); } -void TaskQueueImpl::NotifyWillProcessTask( - const base::PendingTask& pending_task) { +void TaskQueueImpl::NotifyWillProcessTask(const PendingTask& pending_task) { DCHECK(should_notify_observers_); if (main_thread_only().blame_context) main_thread_only().blame_context->Enter(); @@ -571,8 +580,7 @@ void TaskQueueImpl::NotifyWillProcessTask( observer.WillProcessTask(pending_task); } -void TaskQueueImpl::NotifyDidProcessTask( - const base::PendingTask& pending_task) { +void TaskQueueImpl::NotifyDidProcessTask(const PendingTask& pending_task) { DCHECK(should_notify_observers_); for (auto& observer : main_thread_only().task_observers) observer.DidProcessTask(pending_task); @@ -582,7 +590,7 @@ void TaskQueueImpl::NotifyDidProcessTask( void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) { { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); DCHECK(time_domain); // NOTE this is similar to checking |any_thread().task_queue_manager| but // the TaskQueueSelectorTests constructs TaskQueueImpl directly with a null @@ -607,20 +615,19 @@ void TaskQueueImpl::SetTimeDomain(TimeDomain* time_domain) { // correctly. // TODO(altimin): Remove this when we won't have to support changing time // domains. - main_thread_only().scheduled_wake_up = base::nullopt; + main_thread_only().scheduled_wake_up = nullopt; UpdateDelayedWakeUp(&lazy_now); } TimeDomain* TaskQueueImpl::GetTimeDomain() const { - if (base::PlatformThread::CurrentId() == thread_id_) + if (PlatformThread::CurrentId() == thread_id_) return main_thread_only().time_domain; - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); return any_thread().time_domain; } -void TaskQueueImpl::SetBlameContext( - base::trace_event::BlameContext* blame_context) { +void TaskQueueImpl::SetBlameContext(trace_event::BlameContext* blame_context) { main_thread_only().blame_context = blame_context; } @@ -629,7 +636,7 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { return; // Only one fence may be present at a time. - main_thread_only().delayed_fence = base::nullopt; + main_thread_only().delayed_fence = nullopt; EnqueueOrder previous_fence = main_thread_only().current_fence; EnqueueOrder current_fence = @@ -646,7 +653,7 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { main_thread_only().delayed_work_queue->InsertFence(current_fence); if (!task_unblocked && previous_fence && previous_fence < current_fence) { - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); if (!immediate_incoming_queue().empty() && immediate_incoming_queue().front().enqueue_order() > previous_fence && immediate_incoming_queue().front().enqueue_order() < current_fence) { @@ -660,7 +667,7 @@ void TaskQueueImpl::InsertFence(TaskQueue::InsertFencePosition position) { } } -void TaskQueueImpl::InsertFenceAt(base::TimeTicks time) { +void TaskQueueImpl::InsertFenceAt(TimeTicks time) { // Task queue can have only one fence, delayed or not. RemoveFence(); main_thread_only().delayed_fence = time; @@ -672,13 +679,13 @@ void TaskQueueImpl::RemoveFence() { EnqueueOrder previous_fence = main_thread_only().current_fence; main_thread_only().current_fence = 0; - main_thread_only().delayed_fence = base::nullopt; + main_thread_only().delayed_fence = nullopt; bool task_unblocked = main_thread_only().immediate_work_queue->RemoveFence(); task_unblocked |= main_thread_only().delayed_work_queue->RemoveFence(); if (!task_unblocked && previous_fence) { - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); if (!immediate_incoming_queue().empty() && immediate_incoming_queue().front().enqueue_order() > previous_fence) { task_unblocked = true; @@ -700,7 +707,7 @@ bool TaskQueueImpl::BlockedByFence() const { return false; } - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); if (immediate_incoming_queue().empty()) return true; @@ -733,8 +740,8 @@ EnqueueOrder TaskQueueImpl::GetFenceForTest() const { // static void TaskQueueImpl::QueueAsValueInto(const TaskDeque& queue, - base::TimeTicks now, - base::trace_event::TracedValue* state) { + TimeTicks now, + trace_event::TracedValue* state) { for (const Task& task : queue) { TaskAsValueInto(task, now, state); } @@ -742,8 +749,8 @@ void TaskQueueImpl::QueueAsValueInto(const TaskDeque& queue, // static void TaskQueueImpl::QueueAsValueInto(const std::priority_queue<Task>& queue, - base::TimeTicks now, - base::trace_event::TracedValue* state) { + TimeTicks now, + trace_event::TracedValue* state) { // Remove const to search |queue| in the destructive manner. Restore the // content from |visited| later. std::priority_queue<Task>* mutable_queue = @@ -759,8 +766,8 @@ void TaskQueueImpl::QueueAsValueInto(const std::priority_queue<Task>& queue, // static void TaskQueueImpl::TaskAsValueInto(const Task& task, - base::TimeTicks now, - base::trace_event::TracedValue* state) { + TimeTicks now, + trace_event::TracedValue* state) { state->BeginDictionary(); state->SetString("posted_from", task.posted_from.ToString()); #ifndef NDEBUG @@ -770,12 +777,11 @@ void TaskQueueImpl::TaskAsValueInto(const Task& task, state->SetInteger("enqueue_order", task.enqueue_order()); #endif state->SetInteger("sequence_num", task.sequence_num); - state->SetBoolean("nestable", task.nestable == base::Nestable::kNestable); + state->SetBoolean("nestable", task.nestable == Nestable::kNestable); state->SetBoolean("is_high_res", task.is_high_res); state->SetBoolean("is_cancelled", task.task.IsCancelled()); - state->SetDouble( - "delayed_run_time", - (task.delayed_run_time - base::TimeTicks()).InMillisecondsF()); + state->SetDouble("delayed_run_time", + (task.delayed_run_time - TimeTicks()).InMillisecondsF()); state->SetDouble("delayed_run_time_milliseconds_from_now", (task.delayed_run_time - now).InMillisecondsF()); state->EndDictionary(); @@ -852,8 +858,7 @@ void TaskQueueImpl::EnableOrDisableWithSelector(bool enable) { if (HasPendingImmediateWork() && !main_thread_only().on_next_wake_up_changed_callback.is_null()) { // Delayed work notification will be issued via time domain. - main_thread_only().on_next_wake_up_changed_callback.Run( - base::TimeTicks()); + main_thread_only().on_next_wake_up_changed_callback.Run(TimeTicks()); } // Note the selector calls TaskQueueManager::OnTaskQueueEnabled which posts @@ -876,7 +881,7 @@ TaskQueueImpl::CreateQueueEnabledVoter(scoped_refptr<TaskQueue> task_queue) { return std::make_unique<QueueEnabledVoterImpl>(task_queue); } -void TaskQueueImpl::SweepCanceledDelayedTasks(base::TimeTicks now) { +void TaskQueueImpl::SweepCanceledDelayedTasks(TimeTicks now) { if (main_thread_only().delayed_incoming_queue.empty()) return; @@ -898,24 +903,23 @@ void TaskQueueImpl::SweepCanceledDelayedTasks(base::TimeTicks now) { void TaskQueueImpl::PushImmediateIncomingTaskForTest( TaskQueueImpl::Task&& task) { - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); immediate_incoming_queue().push_back(std::move(task)); } void TaskQueueImpl::RequeueDeferredNonNestableTask( - TaskQueueImpl::Task&& task, - SequencedTaskSource::WorkType work_type) { - DCHECK(task.nestable == base::Nestable::kNonNestable); + DeferredNonNestableTask task) { + DCHECK(task.task.nestable == Nestable::kNonNestable); // The re-queued tasks have to be pushed onto the front because we'd otherwise // violate the strict monotonically increasing enqueue order within the // WorkQueue. We can't assign them a new enqueue order here because that will // not behave correctly with fences and things will break (e.g Idle TQ). - if (work_type == SequencedTaskSource::WorkType::kDelayed) { + if (task.work_queue_type == WorkQueueType::kDelayed) { main_thread_only().delayed_work_queue->PushNonNestableTaskToFront( - std::move(task)); + std::move(task.task)); } else { main_thread_only().immediate_work_queue->PushNonNestableTaskToFront( - std::move(task)); + std::move(task.task)); } } @@ -928,7 +932,7 @@ void TaskQueueImpl::SetOnNextWakeUpChangedCallback( "blink::scheduler::TaskQueue"; } #endif - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); any_thread().on_next_wake_up_changed_callback = callback; main_thread_only().on_next_wake_up_changed_callback = callback; } @@ -939,7 +943,7 @@ void TaskQueueImpl::UpdateDelayedWakeUp(LazyNow* lazy_now) { void TaskQueueImpl::UpdateDelayedWakeUpImpl( LazyNow* lazy_now, - base::Optional<TaskQueueImpl::DelayedWakeUp> wake_up) { + Optional<TaskQueueImpl::DelayedWakeUp> wake_up) { if (main_thread_only().scheduled_wake_up == wake_up) return; main_thread_only().scheduled_wake_up = wake_up; @@ -955,7 +959,7 @@ void TaskQueueImpl::UpdateDelayedWakeUpImpl( } void TaskQueueImpl::SetDelayedWakeUpForTesting( - base::Optional<TaskQueueImpl::DelayedWakeUp> wake_up) { + Optional<TaskQueueImpl::DelayedWakeUp> wake_up) { LazyNow lazy_now = main_thread_only().time_domain->CreateLazyNow(); UpdateDelayedWakeUpImpl(&lazy_now, wake_up); } @@ -968,7 +972,7 @@ bool TaskQueueImpl::HasPendingImmediateWork() { } // Finally tasks on |immediate_incoming_queue| count as immediate work. - base::AutoLock lock(immediate_incoming_queue_lock_); + AutoLock lock(immediate_incoming_queue_lock_); return !immediate_incoming_queue().empty(); } @@ -978,7 +982,7 @@ void TaskQueueImpl::SetOnTaskStartedHandler( } void TaskQueueImpl::OnTaskStarted(const TaskQueue::Task& task, - base::TimeTicks start) { + TimeTicks start) { if (!main_thread_only().on_task_started_handler.is_null()) main_thread_only().on_task_started_handler.Run(task, start); } @@ -988,11 +992,10 @@ void TaskQueueImpl::SetOnTaskCompletedHandler( main_thread_only().on_task_completed_handler = std::move(handler); } -void TaskQueueImpl::OnTaskCompleted( - const TaskQueue::Task& task, - base::TimeTicks start, - base::TimeTicks end, - base::Optional<base::TimeDelta> thread_time) { +void TaskQueueImpl::OnTaskCompleted(const TaskQueue::Task& task, + TimeTicks start, + TimeTicks end, + Optional<TimeDelta> thread_time) { if (!main_thread_only().on_task_completed_handler.is_null()) { main_thread_only().on_task_completed_handler.Run(task, start, end, thread_time); @@ -1005,12 +1008,11 @@ bool TaskQueueImpl::RequiresTaskTiming() const { } bool TaskQueueImpl::IsUnregistered() const { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); return !any_thread().task_queue_manager; } -base::WeakPtr<TaskQueueManagerImpl> -TaskQueueImpl::GetTaskQueueManagerWeakPtr() { +WeakPtr<TaskQueueManagerImpl> TaskQueueImpl::GetTaskQueueManagerWeakPtr() { return main_thread_only().task_queue_manager->GetWeakPtr(); } @@ -1025,15 +1027,15 @@ void TaskQueueImpl::SetQueueEnabledForTest(bool enabled) { EnableOrDisableWithSelector(IsQueueEnabled()); } -void TaskQueueImpl::ActivateDelayedFenceIfNeeded(base::TimeTicks now) { +void TaskQueueImpl::ActivateDelayedFenceIfNeeded(TimeTicks now) { if (!main_thread_only().delayed_fence) return; if (main_thread_only().delayed_fence.value() > now) return; InsertFence(TaskQueue::InsertFencePosition::kNow); - main_thread_only().delayed_fence = base::nullopt; + main_thread_only().delayed_fence = nullopt; } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h index 0e1a62c1a9d..471e60bec22 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h @@ -11,22 +11,22 @@ #include <set> #include "base/callback.h" +#include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" #include "base/pending_task.h" +#include "base/task/sequence_manager/sequenced_task_source.h" #include "base/threading/thread_checker.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "third_party/blink/renderer/platform/scheduler/base/enqueue_order.h" #include "third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h" #include "third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/wtf/deque.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class LazyNow; class TimeDomain; class TaskQueueManagerImpl; @@ -72,7 +72,7 @@ class PLATFORM_EXPORT TaskQueueImpl { // Represents a time at which a task wants to run. Tasks scheduled for the // same point in time will be ordered by their sequence numbers. struct DelayedWakeUp { - base::TimeTicks time; + TimeTicks time; int sequence_num; bool operator!=(const DelayedWakeUp& other) const { @@ -96,11 +96,11 @@ class PLATFORM_EXPORT TaskQueueImpl { class PLATFORM_EXPORT Task : public TaskQueue::Task { public: Task(TaskQueue::PostedTask task, - base::TimeTicks desired_run_time, + TimeTicks desired_run_time, EnqueueOrder sequence_number); Task(TaskQueue::PostedTask task, - base::TimeTicks desired_run_time, + TimeTicks desired_run_time, EnqueueOrder sequence_number, EnqueueOrder enqueue_order); @@ -144,23 +144,33 @@ class PLATFORM_EXPORT TaskQueueImpl { struct PostTaskResult { PostTaskResult(); PostTaskResult(bool success, TaskQueue::PostedTask task); + PostTaskResult(PostTaskResult&& move_from); + PostTaskResult(const PostTaskResult& copy_from) = delete; + ~PostTaskResult(); static PostTaskResult Success(); static PostTaskResult Fail(TaskQueue::PostedTask task); - bool success = false; + bool success; TaskQueue::PostedTask task; }; - using OnNextWakeUpChangedCallback = - base::RepeatingCallback<void(base::TimeTicks)>; + // Types of queues TaskQueueImpl is maintaining internally. + enum class WorkQueueType { kImmediate, kDelayed }; + + // Non-nestable tasks may get deferred but such queue is being maintained on + // TaskQueueManager side, so we need to keep information how to requeue it. + struct DeferredNonNestableTask { + internal::TaskQueueImpl::Task task; + internal::TaskQueueImpl* task_queue; + WorkQueueType work_queue_type; + }; + + using OnNextWakeUpChangedCallback = RepeatingCallback<void(TimeTicks)>; using OnTaskStartedHandler = - base::RepeatingCallback<void(const TaskQueue::Task&, base::TimeTicks)>; - using OnTaskCompletedHandler = - base::RepeatingCallback<void(const TaskQueue::Task&, - base::TimeTicks, - base::TimeTicks, - base::Optional<base::TimeDelta>)>; + RepeatingCallback<void(const TaskQueue::Task&, TimeTicks)>; + using OnTaskCompletedHandler = RepeatingCallback< + void(const TaskQueue::Task&, TimeTicks, TimeTicks, Optional<TimeDelta>)>; // TaskQueue implementation. const char* GetName() const; @@ -173,17 +183,17 @@ class PLATFORM_EXPORT TaskQueueImpl { bool IsEmpty() const; size_t GetNumberOfPendingTasks() const; bool HasTaskToRunImmediately() const; - base::Optional<base::TimeTicks> GetNextScheduledWakeUp(); - base::Optional<DelayedWakeUp> GetNextScheduledWakeUpImpl(); + Optional<TimeTicks> GetNextScheduledWakeUp(); + Optional<DelayedWakeUp> GetNextScheduledWakeUpImpl(); void SetQueuePriority(TaskQueue::QueuePriority priority); TaskQueue::QueuePriority GetQueuePriority() const; - void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); - void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer); + void AddTaskObserver(MessageLoop::TaskObserver* task_observer); + void RemoveTaskObserver(MessageLoop::TaskObserver* task_observer); void SetTimeDomain(TimeDomain* time_domain); TimeDomain* GetTimeDomain() const; - void SetBlameContext(base::trace_event::BlameContext* blame_context); + void SetBlameContext(trace_event::BlameContext* blame_context); void InsertFence(TaskQueue::InsertFencePosition position); - void InsertFenceAt(base::TimeTicks time); + void InsertFenceAt(TimeTicks time); void RemoveFence(); bool HasActiveFence(); bool BlockedByFence() const; @@ -200,14 +210,13 @@ class PLATFORM_EXPORT TaskQueueImpl { // Must only be called from the thread this task queue was created on. void ReloadImmediateWorkQueueIfEmpty(); - void AsValueInto(base::TimeTicks now, - base::trace_event::TracedValue* state) const; + void AsValueInto(TimeTicks now, trace_event::TracedValue* state) const; bool GetQuiescenceMonitored() const { return should_monitor_quiescence_; } bool GetShouldNotifyObservers() const { return should_notify_observers_; } - void NotifyWillProcessTask(const base::PendingTask& pending_task); - void NotifyDidProcessTask(const base::PendingTask& pending_task); + void NotifyWillProcessTask(const PendingTask& pending_task); + void NotifyDidProcessTask(const PendingTask& pending_task); // Check for available tasks in immediate work queues. // Used to check if we need to generate notifications about delayed work. @@ -242,8 +251,8 @@ class PLATFORM_EXPORT TaskQueueImpl { // Pushes |task| onto the front of the specified work queue. Caution must be // taken with this API because you could easily starve out other work. - void RequeueDeferredNonNestableTask(TaskQueueImpl::Task&& task, - SequencedTaskSource::WorkType work_type); + // TODO(kraynov): Simplify non-nestable task logic https://crbug.com/845437. + void RequeueDeferredNonNestableTask(DeferredNonNestableTask task); void PushImmediateIncomingTaskForTest(TaskQueueImpl::Task&& task); EnqueueOrder GetFenceForTest() const; @@ -268,20 +277,20 @@ class PLATFORM_EXPORT TaskQueueImpl { }; // Iterates over |delayed_incoming_queue| removing canceled tasks. - void SweepCanceledDelayedTasks(base::TimeTicks now); + void SweepCanceledDelayedTasks(TimeTicks now); // Allows wrapping TaskQueue to set a handler to subscribe for notifications // about started and completed tasks. void SetOnTaskStartedHandler(OnTaskStartedHandler handler); - void OnTaskStarted(const TaskQueue::Task& task, base::TimeTicks start); + void OnTaskStarted(const TaskQueue::Task& task, TimeTicks start); void SetOnTaskCompletedHandler(OnTaskCompletedHandler handler); void OnTaskCompleted(const TaskQueue::Task& task, - base::TimeTicks start, - base::TimeTicks end, - base::Optional<base::TimeDelta> thread_time); + TimeTicks start, + TimeTicks end, + Optional<TimeDelta> thread_time); bool RequiresTaskTiming() const; - base::WeakPtr<TaskQueueManagerImpl> GetTaskQueueManagerWeakPtr(); + WeakPtr<TaskQueueManagerImpl> GetTaskQueueManagerWeakPtr(); scoped_refptr<GracefulQueueShutdownHelper> GetGracefulQueueShutdownHelper(); @@ -294,7 +303,7 @@ class PLATFORM_EXPORT TaskQueueImpl { void SetQueueEnabledForTest(bool enabled); protected: - void SetDelayedWakeUpForTesting(base::Optional<DelayedWakeUp> wake_up); + void SetDelayedWakeUpForTesting(Optional<DelayedWakeUp> wake_up); private: friend class WorkQueue; @@ -332,19 +341,19 @@ class PLATFORM_EXPORT TaskQueueImpl { std::unique_ptr<WorkQueue> delayed_work_queue; std::unique_ptr<WorkQueue> immediate_work_queue; std::priority_queue<Task> delayed_incoming_queue; - base::ObserverList<base::MessageLoop::TaskObserver> task_observers; + ObserverList<MessageLoop::TaskObserver> task_observers; size_t set_index; HeapHandle heap_handle; int is_enabled_refcount; int voter_refcount; - base::trace_event::BlameContext* blame_context; // Not owned. + trace_event::BlameContext* blame_context; // Not owned. EnqueueOrder current_fence; - base::Optional<base::TimeTicks> delayed_fence; + Optional<TimeTicks> delayed_fence; OnTaskStartedHandler on_task_started_handler; OnTaskCompletedHandler on_task_completed_handler; // Last reported wake up, used only in UpdateWakeUp to avoid // excessive calls. - base::Optional<DelayedWakeUp> scheduled_wake_up; + Optional<DelayedWakeUp> scheduled_wake_up; // If false, queue will be disabled. Used only for tests. bool is_enabled_for_test; }; @@ -355,7 +364,7 @@ class PLATFORM_EXPORT TaskQueueImpl { // Push the task onto the |delayed_incoming_queue|. Lock-free main thread // only fast path. void PushOntoDelayedIncomingQueueFromMainThread(Task pending_task, - base::TimeTicks now); + TimeTicks now); // Push the task onto the |delayed_incoming_queue|. Slow path from other // threads. @@ -372,7 +381,7 @@ class PLATFORM_EXPORT TaskQueueImpl { // We reserve an inline capacity of 8 tasks to try and reduce the load on // PartitionAlloc. - using TaskDeque = WTF::Deque<Task, 8>; + using TaskDeque = circular_deque<Task>; // Extracts all the tasks from the immediate incoming queue and clears it. // Can be called from any thread. @@ -380,14 +389,14 @@ class PLATFORM_EXPORT TaskQueueImpl { void TraceQueueSize() const; static void QueueAsValueInto(const TaskDeque& queue, - base::TimeTicks now, - base::trace_event::TracedValue* state); + TimeTicks now, + trace_event::TracedValue* state); static void QueueAsValueInto(const std::priority_queue<Task>& queue, - base::TimeTicks now, - base::trace_event::TracedValue* state); + TimeTicks now, + trace_event::TracedValue* state); static void TaskAsValueInto(const Task& task, - base::TimeTicks now, - base::trace_event::TracedValue* state); + TimeTicks now, + trace_event::TracedValue* state); void RemoveQueueEnabledVoter(const QueueEnabledVoterImpl* voter); void OnQueueEnabledVoteChanged(bool enabled); @@ -396,16 +405,16 @@ class PLATFORM_EXPORT TaskQueueImpl { // Schedules delayed work on time domain and calls the observer. void UpdateDelayedWakeUp(LazyNow* lazy_now); void UpdateDelayedWakeUpImpl(LazyNow* lazy_now, - base::Optional<DelayedWakeUp> wake_up); + Optional<DelayedWakeUp> wake_up); // Activate a delayed fence if a time has come. - void ActivateDelayedFenceIfNeeded(base::TimeTicks now); + void ActivateDelayedFenceIfNeeded(TimeTicks now); const char* name_; - const base::PlatformThreadId thread_id_; + const PlatformThreadId thread_id_; - mutable base::Lock any_thread_lock_; + mutable Lock any_thread_lock_; AnyThread any_thread_; struct AnyThread& any_thread() { any_thread_lock_.AssertAcquired(); @@ -416,7 +425,7 @@ class PLATFORM_EXPORT TaskQueueImpl { return any_thread_; } - base::ThreadChecker main_thread_checker_; + ThreadChecker main_thread_checker_; MainThreadOnly main_thread_only_; MainThreadOnly& main_thread_only() { DCHECK(main_thread_checker_.CalledOnValidThread()); @@ -427,7 +436,7 @@ class PLATFORM_EXPORT TaskQueueImpl { return main_thread_only_; } - mutable base::Lock immediate_incoming_queue_lock_; + mutable Lock immediate_incoming_queue_lock_; TaskDeque immediate_incoming_queue_; TaskDeque& immediate_incoming_queue() { immediate_incoming_queue_lock_.AssertAcquired(); @@ -445,7 +454,7 @@ class PLATFORM_EXPORT TaskQueueImpl { }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h index 77fecacb9b4..988194589d0 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h @@ -5,6 +5,9 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ +#include <memory> +#include <utility> + #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -13,8 +16,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_time_observer.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class PLATFORM_EXPORT TaskQueueManager { public: @@ -44,10 +47,8 @@ class PLATFORM_EXPORT TaskQueueManager { // These functions can only be called on the same thread that the task queue // manager executes its tasks on. - virtual void AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) = 0; - virtual void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) = 0; + virtual void AddTaskObserver(MessageLoop::TaskObserver* task_observer) = 0; + virtual void RemoveTaskObserver(MessageLoop::TaskObserver* task_observer) = 0; virtual void AddTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; virtual void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer) = 0; @@ -56,14 +57,14 @@ class PLATFORM_EXPORT TaskQueueManager { virtual void UnregisterTimeDomain(TimeDomain* time_domain) = 0; virtual RealTimeDomain* GetRealTimeDomain() const = 0; - virtual const base::TickClock* GetClock() const = 0; - virtual base::TimeTicks NowTicks() const = 0; + virtual const TickClock* GetClock() const = 0; + virtual TimeTicks NowTicks() const = 0; // Sets the SingleThreadTaskRunner that will be returned by - // ThreadTaskRunnerHandle::Get and MessageLoop::current().task_runner() on the - // thread associated with this TaskQueueManager. + // ThreadTaskRunnerHandle::Get on the thread associated with this + // TaskQueueManager. virtual void SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) = 0; + scoped_refptr<SingleThreadTaskRunner> task_runner) = 0; // Removes all canceled delayed tasks. virtual void SweepCanceledDelayedTasks() = 0; @@ -81,6 +82,10 @@ class PLATFORM_EXPORT TaskQueueManager { virtual void EnableCrashKeys(const char* file_name_crash_key, const char* function_name_crash_key) = 0; + // Returns the portion of tasks for which CPU time is recorded or 0 if not + // sampled. + virtual double GetSamplingRateForRecordingCPUTime() const = 0; + // Creates a task queue with the given type, |spec| and args. Must be called // on the thread this class was created on. // TODO(altimin): TaskQueueManager should not create TaskQueues. @@ -97,7 +102,7 @@ class PLATFORM_EXPORT TaskQueueManager { const TaskQueue::Spec& spec) = 0; }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.cc index e24c8827fdb..371180047c7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.cc @@ -9,36 +9,35 @@ #include "base/bind.h" #include "base/bind_helpers.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { // static scoped_refptr<TaskQueueManagerDelegateForTest> TaskQueueManagerDelegateForTest::Create( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source) { - return base::WrapRefCounted( + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source) { + return WrapRefCounted( new TaskQueueManagerDelegateForTest(task_runner, time_source)); } TaskQueueManagerDelegateForTest::TaskQueueManagerDelegateForTest( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source) + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source) : task_runner_(task_runner), time_source_(time_source) {} TaskQueueManagerDelegateForTest::~TaskQueueManagerDelegateForTest() {} -bool TaskQueueManagerDelegateForTest::PostDelayedTask( - const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) { +bool TaskQueueManagerDelegateForTest::PostDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) { return task_runner_->PostDelayedTask(from_here, std::move(task), delay); } bool TaskQueueManagerDelegateForTest::PostNonNestableDelayedTask( - const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) { + const Location& from_here, + OnceClosure task, + TimeDelta delay) { return task_runner_->PostNonNestableDelayedTask(from_here, std::move(task), delay); } @@ -52,14 +51,14 @@ bool TaskQueueManagerDelegateForTest::IsNested() const { } void TaskQueueManagerDelegateForTest::AddNestingObserver( - base::RunLoop::NestingObserver* observer) {} + RunLoop::NestingObserver* observer) {} void TaskQueueManagerDelegateForTest::RemoveNestingObserver( - base::RunLoop::NestingObserver* observer) {} + RunLoop::NestingObserver* observer) {} -base::TimeTicks TaskQueueManagerDelegateForTest::NowTicks() const { +TimeTicks TaskQueueManagerDelegateForTest::NowTicks() const { return time_source_->NowTicks(); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.h index d448f792c3e..b0c5f574af7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate_for_test.h @@ -14,46 +14,46 @@ #include "base/time/tick_clock.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_delegate.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class TaskQueueManagerDelegateForTest : public TaskQueueManagerDelegate { public: static scoped_refptr<TaskQueueManagerDelegateForTest> Create( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source); + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source); // SingleThreadTaskRunner: - bool PostDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override; - bool PostNonNestableDelayedTask(const base::Location& from_here, - base::OnceClosure task, - base::TimeDelta delay) override; + bool PostDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) override; + bool PostNonNestableDelayedTask(const Location& from_here, + OnceClosure task, + TimeDelta delay) override; bool RunsTasksInCurrentSequence() const override; // TaskQueueManagerDelegate: bool IsNested() const override; - void AddNestingObserver(base::RunLoop::NestingObserver* observer) override; - void RemoveNestingObserver(base::RunLoop::NestingObserver* observer) override; + void AddNestingObserver(RunLoop::NestingObserver* observer) override; + void RemoveNestingObserver(RunLoop::NestingObserver* observer) override; // TickClock: - base::TimeTicks NowTicks() const override; + TimeTicks NowTicks() const override; protected: ~TaskQueueManagerDelegateForTest() override; TaskQueueManagerDelegateForTest( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source); + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source); private: - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; - const base::TickClock* time_source_; + scoped_refptr<SingleThreadTaskRunner> task_runner_; + const TickClock* time_source_; DISALLOW_COPY_AND_ASSIGN(TaskQueueManagerDelegateForTest); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_DELEGATE_FOR_TEST_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc index 5c7b2968477..78f006450dc 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.cc @@ -4,9 +4,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" -#include <memory> #include <queue> -#include <set> +#include <vector> #include "base/bind.h" #include "base/bit_cast.h" @@ -20,21 +19,20 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" #include "third_party/blink/renderer/platform/scheduler/base/task_time_observer.h" -#include "third_party/blink/renderer/platform/scheduler/base/thread_controller.h" #include "third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace { const double kLongTaskTraceEventThreshold = 0.05; const double kSamplingRateForRecordingCPUTime = 0.01; -double MonotonicTimeInSeconds(base::TimeTicks time_ticks) { - return (time_ticks - base::TimeTicks()).InSecondsF(); +double MonotonicTimeInSeconds(TimeTicks time_ticks) { + return (time_ticks - TimeTicks()).InSecondsF(); } // Magic value to protect against memory corruption and bail out @@ -43,7 +41,7 @@ constexpr int kMemoryCorruptionSentinelValue = 0xdeadbeef; void SweepCanceledDelayedTasksInQueue( internal::TaskQueueImpl* queue, - std::map<TimeDomain*, base::TimeTicks>* time_domain_now) { + std::map<TimeDomain*, TimeTicks>* time_domain_now) { TimeDomain* time_domain = queue->GetTimeDomain(); if (time_domain_now->find(time_domain) == time_domain_now->end()) time_domain_now->insert(std::make_pair(time_domain, time_domain->Now())); @@ -65,9 +63,16 @@ TaskQueueManagerImpl::TaskQueueManagerImpl( weak_factory_(this) { // TODO(altimin): Create a sequence checker here. DCHECK(controller_->RunsTasksInCurrentSequence()); + + TRACE_EVENT_WARMUP_CATEGORY("sequence_manager"); + TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("sequence_manager")); + TRACE_EVENT_WARMUP_CATEGORY( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.debug")); + TRACE_EVENT_WARMUP_CATEGORY( + TRACE_DISABLED_BY_DEFAULT("sequence_manager.verbose_snapshots")); + TRACE_EVENT_OBJECT_CREATED_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", - this); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager", this); main_thread_only().selector.SetTaskQueueSelectorObserver(this); RegisterTimeDomain(main_thread_only().real_time_domain.get()); @@ -78,8 +83,7 @@ TaskQueueManagerImpl::TaskQueueManagerImpl( TaskQueueManagerImpl::~TaskQueueManagerImpl() { TRACE_EVENT_OBJECT_DELETED_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "TaskQueueManager", - this); + TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager", this); // TODO(altimin): restore default task runner automatically when // ThreadController is destroyed. @@ -99,17 +103,22 @@ TaskQueueManagerImpl::~TaskQueueManagerImpl() { controller_->RemoveNestingObserver(this); } +TaskQueueManagerImpl::AnyThread::AnyThread() = default; + +TaskQueueManagerImpl::AnyThread::~AnyThread() = default; + TaskQueueManagerImpl::MainThreadOnly::MainThreadOnly() - : random_generator(base::RandUint64()), + : random_generator(RandUint64()), uniform_distribution(0.0, 1.0), real_time_domain(new RealTimeDomain()) {} +TaskQueueManagerImpl::MainThreadOnly::~MainThreadOnly() = default; + std::unique_ptr<TaskQueueManagerImpl> TaskQueueManagerImpl::TakeOverCurrentThread() { return std::unique_ptr<TaskQueueManagerImpl>( new TaskQueueManagerImpl(internal::ThreadControllerImpl::Create( - base::MessageLoop::current(), - base::DefaultTickClock::GetInstance()))); + MessageLoop::current(), DefaultTickClock::GetInstance()))); } void TaskQueueManagerImpl::RegisterTimeDomain(TimeDomain* time_domain) { @@ -146,15 +155,14 @@ void TaskQueueManagerImpl::SetObserver(Observer* observer) { void TaskQueueManagerImpl::UnregisterTaskQueueImpl( std::unique_ptr<internal::TaskQueueImpl> task_queue) { - TRACE_EVENT1("renderer.scheduler", - "TaskQueueManagerImpl::UnregisterTaskQueue", "queue_name", - task_queue->GetName()); + TRACE_EVENT1("sequence_manager", "TaskQueueManagerImpl::UnregisterTaskQueue", + "queue_name", task_queue->GetName()); DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); main_thread_only().selector.RemoveQueue(task_queue.get()); { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); any_thread().has_incoming_immediate_work.erase(task_queue.get()); } @@ -179,7 +187,7 @@ void TaskQueueManagerImpl::ReloadEmptyWorkQueues( } void TaskQueueManagerImpl::WakeUpReadyDelayedQueues(LazyNow* lazy_now) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::WakeUpReadyDelayedQueues"); for (TimeDomain* time_domain : main_thread_only().time_domains) { @@ -207,10 +215,10 @@ void TaskQueueManagerImpl::OnExitNestedRunLoop() { // While we were nested some non-nestable tasks may have become eligible to // run. We push them back onto the front of their original work queues. while (!main_thread_only().non_nestable_task_queue.empty()) { - NonNestableTask& non_nestable_task = + internal::TaskQueueImpl::DeferredNonNestableTask& non_nestable_task = *main_thread_only().non_nestable_task_queue.begin(); non_nestable_task.task_queue->RequeueDeferredNonNestableTask( - std::move(non_nestable_task.task), non_nestable_task.work_type); + std::move(non_nestable_task)); main_thread_only().non_nestable_task_queue.pop_front(); } if (main_thread_only().observer) @@ -223,7 +231,7 @@ void TaskQueueManagerImpl::OnQueueHasIncomingImmediateWork( internal::EnqueueOrder enqueue_order, bool queue_is_blocked) { { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); any_thread().has_incoming_immediate_work.insert( std::make_pair(queue, enqueue_order)); } @@ -233,33 +241,36 @@ void TaskQueueManagerImpl::OnQueueHasIncomingImmediateWork( } void TaskQueueManagerImpl::MaybeScheduleImmediateWork( - const base::Location& from_here) { + const Location& from_here) { controller_->ScheduleWork(); } void TaskQueueManagerImpl::MaybeScheduleDelayedWork( - const base::Location& from_here, + const Location& from_here, TimeDomain* requesting_time_domain, - base::TimeTicks now, - base::TimeTicks run_time) { - controller_->ScheduleDelayedWork(now, run_time); + TimeTicks now, + TimeTicks run_time) { + // TODO(kraynov): Convert time domains to use LazyNow. + LazyNow lazy_now(now); + controller_->SetNextDelayedDoWork(&lazy_now, run_time); } +// TODO(kraynov): Remove after simplifying TimeDomain. void TaskQueueManagerImpl::CancelDelayedWork(TimeDomain* requesting_time_domain, - base::TimeTicks run_time) { - controller_->CancelDelayedWork(run_time); + TimeTicks run_time) { + controller_->SetNextDelayedDoWork(nullptr, TimeTicks::Max()); } -base::Optional<base::PendingTask> TaskQueueManagerImpl::TakeTask() { +Optional<PendingTask> TaskQueueManagerImpl::TakeTask() { CHECK(Validate()); DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); - TRACE_EVENT0("renderer.scheduler", "TaskQueueManagerImpl::TakeTask"); + TRACE_EVENT0("sequence_manager", "TaskQueueManagerImpl::TakeTask"); IncomingImmediateWorkMap queues_to_reload; { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); std::swap(queues_to_reload, any_thread().has_incoming_immediate_work); } @@ -274,26 +285,25 @@ base::Optional<base::PendingTask> TaskQueueManagerImpl::TakeTask() { bool should_run = main_thread_only().selector.SelectWorkQueueToService(&work_queue); TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"), - "TaskQueueManager", this, - AsValueWithSelectorResult(should_run, work_queue)); + TRACE_DISABLED_BY_DEFAULT("sequence_manager.debug"), "TaskQueueManager", + this, AsValueWithSelectorResult(should_run, work_queue)); if (!should_run) - return base::nullopt; + return nullopt; // If the head task was canceled, remove it and run the selector again. if (work_queue->RemoveAllCanceledTasksFromFront()) continue; - if (work_queue->GetFrontTask()->nestable == base::Nestable::kNonNestable && + if (work_queue->GetFrontTask()->nestable == Nestable::kNonNestable && main_thread_only().nesting_depth > 0) { // Defer non-nestable work. NOTE these tasks can be arbitrarily delayed so // the additional delay should not be a problem. // Note because we don't delete queues while nested, it's perfectly OK to // store the raw pointer for |queue| here. - NonNestableTask deferred_task{work_queue->TakeTaskFromWorkQueue(), - work_queue->task_queue(), - work_queue->queue_type()}; + internal::TaskQueueImpl::DeferredNonNestableTask deferred_task{ + work_queue->TakeTaskFromWorkQueue(), work_queue->task_queue(), + work_queue->queue_type()}; // We push these tasks onto the front to make sure that when requeued they // are pushed in the right order. main_thread_only().non_nestable_task_queue.push_front( @@ -324,31 +334,30 @@ void TaskQueueManagerImpl::DidRunTask() { CleanUpQueues(); } -base::TimeDelta TaskQueueManagerImpl::DelayTillNextTask(LazyNow* lazy_now) { +TimeDelta TaskQueueManagerImpl::DelayTillNextTask(LazyNow* lazy_now) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); // If the selector has non-empty queues we trivially know there is immediate // work to be done. if (!main_thread_only().selector.AllEnabledWorkQueuesAreEmpty()) - return base::TimeDelta(); + return TimeDelta(); // Its possible the selectors state is dirty because ReloadEmptyWorkQueues // hasn't been called yet. This check catches the case of fresh incoming work. { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); for (const auto& pair : any_thread().has_incoming_immediate_work) { if (pair.first->CouldTaskRun(pair.second)) - return base::TimeDelta(); + return TimeDelta(); } } // Otherwise we need to find the shortest delay, if any. NB we don't need to // call WakeUpReadyDelayedQueues because it's assumed DelayTillNextTask will - // return base::TimeDelta>() if the delayed task is due to run now. - base::TimeDelta delay_till_next_task = base::TimeDelta::Max(); + // return TimeDelta>() if the delayed task is due to run now. + TimeDelta delay_till_next_task = TimeDelta::Max(); for (TimeDomain* time_domain : main_thread_only().time_domains) { - base::Optional<base::TimeDelta> delay = - time_domain->DelayTillNextTask(lazy_now); + Optional<TimeDelta> delay = time_domain->DelayTillNextTask(lazy_now); if (!delay) continue; @@ -365,28 +374,28 @@ void TaskQueueManagerImpl::DidQueueTask( void TaskQueueManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, LazyNow* time_before_task) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::NotifyWillProcessTaskObservers"); if (executing_task->task_queue->GetQuiescenceMonitored()) main_thread_only().task_was_run_on_quiescence_monitored_queue = true; - base::debug::SetCrashKeyString( + debug::SetCrashKeyString( main_thread_only().file_name_crash_key, executing_task->pending_task.posted_from.file_name()); - base::debug::SetCrashKeyString( + debug::SetCrashKeyString( main_thread_only().function_name_crash_key, executing_task->pending_task.posted_from.function_name()); if (executing_task->task_queue->GetShouldNotifyObservers()) { { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.WillProcessTaskObservers"); for (auto& observer : main_thread_only().task_observers) observer.WillProcessTask(executing_task->pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueNotifyWillProcessTask"); executing_task->task_queue->NotifyWillProcessTask( executing_task->pending_task); @@ -402,14 +411,14 @@ void TaskQueueManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, MonotonicTimeInSeconds(executing_task->task_start_time); { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.WillProcessTaskTimeObservers"); for (auto& observer : main_thread_only().task_time_observers) observer.WillProcessTask(task_start_time_sec); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueOnTaskStarted"); executing_task->task_queue->OnTaskStarted( executing_task->pending_task, executing_task->task_start_time); @@ -419,18 +428,20 @@ void TaskQueueManagerImpl::NotifyWillProcessTask(ExecutingTask* executing_task, executing_task->should_record_thread_time = ShouldRecordCPUTimeForTask(); if (executing_task->should_record_thread_time) - executing_task->task_start_thread_time = base::ThreadTicks::Now(); + executing_task->task_start_thread_time = ThreadTicks::Now(); } void TaskQueueManagerImpl::NotifyDidProcessTask( const ExecutingTask& executing_task, LazyNow* time_after_task) { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManagerImpl::NotifyDidProcessTaskObservers"); - base::ThreadTicks task_end_thread_time; - if (executing_task.should_record_thread_time) - task_end_thread_time = base::ThreadTicks::Now(); + Optional<TimeDelta> thread_time; + if (executing_task.should_record_thread_time) { + auto task_end_thread_time = ThreadTicks::Now(); + thread_time = task_end_thread_time - executing_task.task_start_thread_time; + } if (!executing_task.task_queue->GetShouldNotifyObservers()) return; @@ -442,34 +453,33 @@ void TaskQueueManagerImpl::NotifyDidProcessTask( if (task_start_time_sec) { task_end_time_sec = MonotonicTimeInSeconds(time_after_task->Now()); - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.DidProcessTaskTimeObservers"); for (auto& observer : main_thread_only().task_time_observers) observer.DidProcessTask(task_start_time_sec, task_end_time_sec); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.DidProcessTaskObservers"); for (auto& observer : main_thread_only().task_observers) observer.DidProcessTask(executing_task.pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueNotifyDidProcessTask"); executing_task.task_queue->NotifyDidProcessTask( executing_task.pending_task); } { - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "TaskQueueManager.QueueOnTaskCompleted"); if (task_start_time_sec && task_end_time_sec) { executing_task.task_queue->OnTaskCompleted( executing_task.pending_task, executing_task.task_start_time, - time_after_task->Now(), - task_end_thread_time - executing_task.task_start_thread_time); + time_after_task->Now(), thread_time); } } @@ -487,13 +497,13 @@ void TaskQueueManagerImpl::SetWorkBatchSize(int work_batch_size) { } void TaskQueueManagerImpl::AddTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { + MessageLoop::TaskObserver* task_observer) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); main_thread_only().task_observers.AddObserver(task_observer); } void TaskQueueManagerImpl::RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) { + MessageLoop::TaskObserver* task_observer) { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); main_thread_only().task_observers.RemoveObserver(task_observer); } @@ -525,17 +535,16 @@ LazyNow TaskQueueManagerImpl::CreateLazyNow() const { return LazyNow(controller_->GetClock()); } -std::unique_ptr<base::trace_event::ConvertableToTraceFormat> +std::unique_ptr<trace_event::ConvertableToTraceFormat> TaskQueueManagerImpl::AsValueWithSelectorResult( bool should_run, internal::WorkQueue* selected_work_queue) const { DCHECK_CALLED_ON_VALID_THREAD(main_thread_checker_); - std::unique_ptr<base::trace_event::TracedValue> state( - new base::trace_event::TracedValue()); - base::TimeTicks now = - main_thread_only().real_time_domain->CreateLazyNow().Now(); + std::unique_ptr<trace_event::TracedValue> state( + new trace_event::TracedValue()); + TimeTicks now = main_thread_only().real_time_domain->CreateLazyNow().Now(); state->BeginArray("active_queues"); - for (auto& queue : main_thread_only().active_queues) + for (auto* const queue : main_thread_only().active_queues) queue->AsValueInto(now, state.get()); state->EndArray(); state->BeginArray("queues_to_gracefully_shutdown"); @@ -560,7 +569,7 @@ TaskQueueManagerImpl::AsValueWithSelectorResult( time_domain->AsValueInto(state.get()); state->EndArray(); { - base::AutoLock lock(any_thread_lock_); + AutoLock lock(any_thread_lock_); state->BeginArray("has_incoming_immediate_work"); for (const auto& pair : any_thread().has_incoming_immediate_work) { state->AppendString(pair.first->GetName()); @@ -579,8 +588,8 @@ void TaskQueueManagerImpl::OnTaskQueueEnabled(internal::TaskQueueImpl* queue) { } void TaskQueueManagerImpl::SweepCanceledDelayedTasks() { - std::map<TimeDomain*, base::TimeTicks> time_domain_now; - for (const auto& queue : main_thread_only().active_queues) + std::map<TimeDomain*, TimeTicks> time_domain_now; + for (auto* const queue : main_thread_only().active_queues) SweepCanceledDelayedTasksInQueue(queue, &time_domain_now); for (const auto& pair : main_thread_only().queues_to_gracefully_shutdown) SweepCanceledDelayedTasksInQueue(pair.first, &time_domain_now); @@ -616,30 +625,36 @@ TaskQueueManagerImpl::GetGracefulQueueShutdownHelper() const { return graceful_shutdown_helper_; } -base::WeakPtr<TaskQueueManagerImpl> TaskQueueManagerImpl::GetWeakPtr() { +WeakPtr<TaskQueueManagerImpl> TaskQueueManagerImpl::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } void TaskQueueManagerImpl::SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + scoped_refptr<SingleThreadTaskRunner> task_runner) { controller_->SetDefaultTaskRunner(task_runner); } -const base::TickClock* TaskQueueManagerImpl::GetClock() const { +const TickClock* TaskQueueManagerImpl::GetClock() const { return controller_->GetClock(); } -base::TimeTicks TaskQueueManagerImpl::NowTicks() const { +TimeTicks TaskQueueManagerImpl::NowTicks() const { return controller_->GetClock()->NowTicks(); } bool TaskQueueManagerImpl::ShouldRecordCPUTimeForTask() { - return base::ThreadTicks::IsSupported() && + return ThreadTicks::IsSupported() && main_thread_only().uniform_distribution( main_thread_only().random_generator) < kSamplingRateForRecordingCPUTime; } +double TaskQueueManagerImpl::GetSamplingRateForRecordingCPUTime() const { + if (!ThreadTicks::IsSupported()) + return 0; + return kSamplingRateForRecordingCPUTime; +} + MSVC_DISABLE_OPTIMIZE() bool TaskQueueManagerImpl::Validate() { return memory_corruption_sentinel_ == kMemoryCorruptionSentinelValue; @@ -651,11 +666,10 @@ void TaskQueueManagerImpl::EnableCrashKeys( const char* function_name_crash_key_name) { DCHECK(!main_thread_only().file_name_crash_key); DCHECK(!main_thread_only().function_name_crash_key); - main_thread_only().file_name_crash_key = base::debug::AllocateCrashKeyString( - file_name_crash_key_name, base::debug::CrashKeySize::Size64); - main_thread_only().function_name_crash_key = - base::debug::AllocateCrashKeyString(function_name_crash_key_name, - base::debug::CrashKeySize::Size64); + main_thread_only().file_name_crash_key = debug::AllocateCrashKeyString( + file_name_crash_key_name, debug::CrashKeySize::Size64); + main_thread_only().function_name_crash_key = debug::AllocateCrashKeyString( + function_name_crash_key_name, debug::CrashKeySize::Size64); } internal::TaskQueueImpl* TaskQueueManagerImpl::currently_executing_task_queue() @@ -665,5 +679,5 @@ internal::TaskQueueImpl* TaskQueueManagerImpl::currently_executing_task_queue() return main_thread_only().task_execution_stack.rbegin()->task_queue; } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h index dde60bee6b7..ba348f20b03 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h @@ -5,11 +5,17 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_IMPL_H_ +#include <list> #include <map> +#include <memory> #include <random> +#include <set> +#include <unordered_map> +#include <utility> #include "base/atomic_sequence_num.h" #include "base/cancelable_callback.h" +#include "base/containers/circular_deque.h" #include "base/debug/task_annotator.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" @@ -17,12 +23,13 @@ #include "base/message_loop/message_loop.h" #include "base/pending_task.h" #include "base/run_loop.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" +#include "base/task/sequence_manager/thread_controller.h" #include "base/threading/thread_checker.h" #include "third_party/blink/renderer/platform/scheduler/base/enqueue_order.h" #include "third_party/blink/renderer/platform/scheduler/base/graceful_queue_shutdown_helper.h" #include "third_party/blink/renderer/platform/scheduler/base/moveable_auto_lock.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" @@ -37,15 +44,13 @@ class ConvertableToTraceFormat; } // namespace trace_event } // namespace base -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { class TaskQueueImpl; -class ThreadController; } // namespace internal -class LazyNow; class RealTimeDomain; class TaskQueue; class TaskTimeObserver; @@ -67,7 +72,7 @@ class PLATFORM_EXPORT TaskQueueManagerImpl : public TaskQueueManager, public internal::SequencedTaskSource, public internal::TaskQueueSelector::Observer, - public base::RunLoop::NestingObserver { + public RunLoop::NestingObserver { public: // Keep public methods in sync with TaskQueueManager interface. // The general rule is to keep methods only used in scheduler/base just here @@ -85,47 +90,47 @@ class PLATFORM_EXPORT TaskQueueManagerImpl // TaskQueueManager implementation: void SetObserver(Observer* observer) override; - void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer) override; - void RemoveTaskObserver( - base::MessageLoop::TaskObserver* task_observer) override; + void AddTaskObserver(MessageLoop::TaskObserver* task_observer) override; + void RemoveTaskObserver(MessageLoop::TaskObserver* task_observer) override; void AddTaskTimeObserver(TaskTimeObserver* task_time_observer) override; void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer) override; void RegisterTimeDomain(TimeDomain* time_domain) override; void UnregisterTimeDomain(TimeDomain* time_domain) override; RealTimeDomain* GetRealTimeDomain() const override; - const base::TickClock* GetClock() const override; - base::TimeTicks NowTicks() const override; + const TickClock* GetClock() const override; + TimeTicks NowTicks() const override; void SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) override; + scoped_refptr<SingleThreadTaskRunner> task_runner) override; void SweepCanceledDelayedTasks() override; bool GetAndClearSystemIsQuiescentBit() override; void SetWorkBatchSize(int work_batch_size) override; void EnableCrashKeys(const char* file_name_crash_key, const char* function_name_crash_key) override; + double GetSamplingRateForRecordingCPUTime() const override; // Implementation of SequencedTaskSource: - base::Optional<base::PendingTask> TakeTask() override; + Optional<PendingTask> TakeTask() override; void DidRunTask() override; - base::TimeDelta DelayTillNextTask(LazyNow* lazy_now) override; + TimeDelta DelayTillNextTask(LazyNow* lazy_now) override; // Requests that a task to process work is posted on the main task runner. // These tasks are de-duplicated in two buckets: main-thread and all other // threads. This distinction is done to reduce the overhead from locks, we // assume the main-thread path will be hot. - void MaybeScheduleImmediateWork(const base::Location& from_here); + void MaybeScheduleImmediateWork(const Location& from_here); // Requests that a delayed task to process work is posted on the main task // runner. These delayed tasks are de-duplicated. Must be called on the thread // this class was created on. - void MaybeScheduleDelayedWork(const base::Location& from_here, + void MaybeScheduleDelayedWork(const Location& from_here, TimeDomain* requesting_time_domain, - base::TimeTicks now, - base::TimeTicks run_time); + TimeTicks now, + TimeTicks run_time); // Cancels a delayed task to process work at |run_time|, previously requested // with MaybeScheduleDelayedWork. void CancelDelayedWork(TimeDomain* requesting_time_domain, - base::TimeTicks run_time); + TimeTicks run_time); LazyNow CreateLazyNow() const; @@ -141,7 +146,7 @@ class PLATFORM_EXPORT TaskQueueManagerImpl scoped_refptr<internal::GracefulQueueShutdownHelper> GetGracefulQueueShutdownHelper() const; - base::WeakPtr<TaskQueueManagerImpl> GetWeakPtr(); + WeakPtr<TaskQueueManagerImpl> GetWeakPtr(); protected: // Create a task queue manager where |controller| controls the thread @@ -163,29 +168,26 @@ class PLATFORM_EXPORT TaskQueueManagerImpl std::unordered_map<internal::TaskQueueImpl*, internal::EnqueueOrder>; struct AnyThread { - AnyThread() = default; + AnyThread(); + ~AnyThread(); // Task queues with newly available work on the incoming queue. IncomingImmediateWorkMap has_incoming_immediate_work; }; - // TODO(scheduler-dev): Review if we really need non-nestable tasks at all. - struct NonNestableTask { - internal::TaskQueueImpl::Task task; - internal::TaskQueueImpl* task_queue; - WorkType work_type; - }; - using NonNestableTaskDeque = WTF::Deque<NonNestableTask, 8>; + // TaskQueueManager maintains a queue of non-nestable tasks since they're + // uncommon and allocating an extra deque per TaskQueue will waste the memory. + using NonNestableTaskDeque = + circular_deque<internal::TaskQueueImpl::DeferredNonNestableTask>; // We have to track rentrancy because we support nested runloops but the // selector interface is unaware of those. This struct keeps track off all // task related state needed to make pairs of TakeTask() / DidRunTask() work. struct ExecutingTask { ExecutingTask() - : pending_task( - TaskQueue::PostedTask(base::OnceClosure(), base::Location()), - base::TimeTicks(), - 0) {} + : pending_task(TaskQueue::PostedTask(OnceClosure(), Location()), + TimeTicks(), + 0) {} ExecutingTask(internal::TaskQueueImpl::Task&& pending_task, internal::TaskQueueImpl* task_queue) @@ -193,27 +195,28 @@ class PLATFORM_EXPORT TaskQueueManagerImpl internal::TaskQueueImpl::Task pending_task; internal::TaskQueueImpl* task_queue = nullptr; - base::TimeTicks task_start_time; - base::ThreadTicks task_start_thread_time; + TimeTicks task_start_time; + ThreadTicks task_start_thread_time; bool should_record_thread_time = false; }; struct MainThreadOnly { MainThreadOnly(); + ~MainThreadOnly(); int nesting_depth = 0; NonNestableTaskDeque non_nestable_task_queue; // TODO(altimin): Switch to instruction pointer crash key when it's // available. - base::debug::CrashKeyString* file_name_crash_key = nullptr; - base::debug::CrashKeyString* function_name_crash_key = nullptr; + debug::CrashKeyString* file_name_crash_key = nullptr; + debug::CrashKeyString* function_name_crash_key = nullptr; std::mt19937_64 random_generator; std::uniform_real_distribution<double> uniform_distribution; internal::TaskQueueSelector selector; - base::ObserverList<base::MessageLoop::TaskObserver> task_observers; - base::ObserverList<TaskTimeObserver> task_time_observers; + ObserverList<MessageLoop::TaskObserver> task_observers; + ObserverList<TaskTimeObserver> task_time_observers; std::set<TimeDomain*> time_domains; std::unique_ptr<RealTimeDomain> real_time_domain; @@ -244,7 +247,7 @@ class PLATFORM_EXPORT TaskQueueManagerImpl // TaskQueueSelector::Observer: void OnTaskQueueEnabled(internal::TaskQueueImpl* queue) override; - // base::RunLoop::NestingObserver: + // RunLoop::NestingObserver: void OnBeginNestedRunLoop() override; void OnExitNestedRunLoop() override; @@ -261,7 +264,7 @@ class PLATFORM_EXPORT TaskQueueManagerImpl internal::EnqueueOrder GetNextSequenceNumber(); - std::unique_ptr<base::trace_event::ConvertableToTraceFormat> + std::unique_ptr<trace_event::ConvertableToTraceFormat> AsValueWithSelectorResult(bool should_run, internal::WorkQueue* selected_work_queue) const; @@ -294,7 +297,7 @@ class PLATFORM_EXPORT TaskQueueManagerImpl std::unique_ptr<internal::ThreadController> controller_; - mutable base::Lock any_thread_lock_; + mutable Lock any_thread_lock_; AnyThread any_thread_; struct AnyThread& any_thread() { @@ -323,12 +326,12 @@ class PLATFORM_EXPORT TaskQueueManagerImpl return main_thread_only_; } - base::WeakPtrFactory<TaskQueueManagerImpl> weak_factory_; + WeakPtrFactory<TaskQueueManagerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(TaskQueueManagerImpl); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_MANAGER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl_unittest.cc index 303dc435830..f4c8561873a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl_unittest.cc @@ -11,28 +11,30 @@ #include "base/location.h" #include "base/memory/ref_counted_memory.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/test/simple_test_tick_clock.h" +#include "base/test/test_mock_time_task_runner.h" +#include "base/test/test_simple_task_runner.h" #include "base/test/trace_event_analyzer.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/blame_context.h" -#include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" -#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" -#include "third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.h" -#include "third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_count_uses_time_source.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h" #include "third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" -#include "third_party/blink/renderer/platform/scheduler/test/test_task_queue.h" using testing::AnyNumber; using testing::Contains; @@ -41,149 +43,163 @@ using testing::ElementsAreArray; using testing::Mock; using testing::Not; using testing::_; -using blink::scheduler::internal::EnqueueOrder; +using base::sequence_manager::internal::EnqueueOrder; -namespace blink { -namespace scheduler { - -class TaskQueueManagerTest : public testing::Test { - public: - TaskQueueManagerTest() = default; - void DeleteTaskQueueManager() { manager_.reset(); } +namespace base { +namespace sequence_manager { +class TaskQueueManagerTestBase : public testing::Test { protected: - void TearDown() { manager_.reset(); } - - scoped_refptr<TestTaskQueue> CreateTaskQueueWithSpec(TaskQueue::Spec spec) { - return manager_->CreateTaskQueue<TestTaskQueue>(spec); + void TearDown() override { + // TaskQueueManager should be deleted before an underlying task runner. + manager_.reset(); } - scoped_refptr<TestTaskQueue> CreateTaskQueue() { - return CreateTaskQueueWithSpec(TaskQueue::Spec("test")); - } - - scoped_refptr<TestTaskQueue> CreateTaskQueueWithMonitoredQuiescence() { - return CreateTaskQueueWithSpec( - TaskQueue::Spec("test").SetShouldMonitorQuiescence(true)); + scoped_refptr<TestTaskQueue> CreateTaskQueue( + TaskQueue::Spec spec = TaskQueue::Spec("test")) { + return manager_->CreateTaskQueue<TestTaskQueue>(spec); } - void Initialize(size_t num_queues) { - now_src_.Advance(base::TimeDelta::FromMicroseconds(1000)); - - test_task_runner_ = - base::WrapRefCounted(new cc::OrderedSimpleTaskRunner(&now_src_, false)); - - manager_ = TaskQueueManagerForTest::Create(nullptr, test_task_runner_.get(), - &now_src_); - + void CreateTaskQueues(size_t num_queues) { for (size_t i = 0; i < num_queues; i++) runners_.push_back(CreateTaskQueue()); } - void InitializeWithRealMessageLoop(size_t num_queues) { - message_loop_.reset(new base::MessageLoop()); - original_message_loop_task_runner_ = message_loop_->task_runner(); - // A null clock triggers some assertions. - now_src_.Advance(base::TimeDelta::FromMicroseconds(1000)); - manager_ = TaskQueueManagerForTest::Create( - message_loop_.get(), GetSingleThreadTaskRunnerForTesting(), &now_src_); + std::unique_ptr<TaskQueueManagerForTest> manager_; + std::vector<scoped_refptr<TestTaskQueue>> runners_; + TimeTicks start_time_; + TestTaskTimeObserver test_task_time_observer_; +}; - for (size_t i = 0; i < num_queues; i++) - runners_.push_back(CreateTaskQueue()); - } +// TaskQueueManagerImpl uses TestMockTimeTaskRunner which controls +// both task execution and mock clock. +class TaskQueueManagerTest : public TaskQueueManagerTestBase { + public: + void DeleteTaskQueueManagerTask() { manager_.reset(); } - void WakeUpReadyDelayedQueues(LazyNow lazy_now) { - manager_->WakeUpReadyDelayedQueues(&lazy_now); + protected: + void SetUp() override { + test_task_runner_ = WrapRefCounted(new TestMockTimeTaskRunner( + TestMockTimeTaskRunner::Type::kBoundToThread)); + // A null clock triggers some assertions. + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(1)); + start_time_ = GetTickClock()->NowTicks(); + + manager_ = + TaskQueueManagerForTest::Create(nullptr, ThreadTaskRunnerHandle::Get(), + test_task_runner_->GetMockTickClock()); } - EnqueueOrder GetNextSequenceNumber() const { - return manager_->GetNextSequenceNumber(); + const TickClock* GetTickClock() { + return test_task_runner_->GetMockTickClock(); } - void MaybeScheduleImmediateWork(const base::Location& from_here) { - manager_->MaybeScheduleImmediateWork(from_here); + void RunPendingTasks() { + // We should only run tasks already posted by that moment. + RunLoop run_loop; + test_task_runner_->PostTask(FROM_HERE, run_loop.QuitClosure()); + // TestMockTimeTaskRunner will fast-forward mock clock if necessary. + run_loop.Run(); } // Runs all immediate tasks until there is no more work to do and advances // time if there is a pending delayed task. |per_run_time_callback| is called // when the clock advances. - void RunUntilIdle(base::RepeatingClosure per_run_time_callback) { + // The only difference to FastForwardUntilNoTasksRemain is that time + // advancing isn't driven by the test task runner, but uses time domain's + // next scheduled run time instead. It allows us to double-check consistency + // and allows to count such bursts of doing work, which is a test subject. + void RunUntilManagerIsIdle(RepeatingClosure per_run_time_callback) { for (;;) { // Advance time if we've run out of immediate work to do. if (!manager_->HasImmediateWork()) { - base::TimeTicks run_time; + TimeTicks run_time; if (manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)) { - now_src_.SetNowTicks(run_time); + test_task_runner_->AdvanceMockTickClock(run_time - + GetTickClock()->NowTicks()); per_run_time_callback.Run(); } else { break; } } - - test_task_runner_->RunPendingTasks(); + RunPendingTasks(); } } - base::TimeTicks Now() { return now_src_.NowTicks(); } + scoped_refptr<TestMockTimeTaskRunner> test_task_runner_; +}; - std::unique_ptr<base::MessageLoop> message_loop_; - scoped_refptr<base::SingleThreadTaskRunner> - original_message_loop_task_runner_; - base::SimpleTestTickClock now_src_; - scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner_; - std::unique_ptr<TaskQueueManagerForTest> manager_; - std::vector<scoped_refptr<TestTaskQueue>> runners_; - TestTaskTimeObserver test_task_time_observer_; +// TaskQueueManagerImpl is being initialized with real MessageLoop +// at cost of less control over a task runner. +class TaskQueueManagerTestWithMessageLoop : public TaskQueueManagerTestBase { + protected: + void SetUp() override { + message_loop_.reset(new MessageLoop()); + // A null clock triggers some assertions. + mock_clock_.Advance(TimeDelta::FromMilliseconds(1)); + start_time_ = mock_clock_.NowTicks(); + + manager_ = TaskQueueManagerForTest::Create( + message_loop_.get(), ThreadTaskRunnerHandle::Get(), &mock_clock_); + } + + const TickClock* GetTickClock() { return &mock_clock_; } + + std::unique_ptr<MessageLoop> message_loop_; + SimpleTestTickClock mock_clock_; +}; + +class TaskQueueManagerTestWithCustomInitialization + : public TaskQueueManagerTestWithMessageLoop { + protected: + void SetUp() override {} }; -void PostFromNestedRunloop( - base::MessageLoop* message_loop, - base::SingleThreadTaskRunner* runner, - std::vector<std::pair<base::OnceClosure, bool>>* tasks) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); - for (std::pair<base::OnceClosure, bool>& pair : *tasks) { +void PostFromNestedRunloop(SingleThreadTaskRunner* runner, + std::vector<std::pair<OnceClosure, bool>>* tasks) { + for (std::pair<OnceClosure, bool>& pair : *tasks) { if (pair.second) { runner->PostTask(FROM_HERE, std::move(pair.first)); } else { runner->PostNonNestableTask(FROM_HERE, std::move(pair.first)); } } - base::RunLoop().RunUntilIdle(); + RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); } void NopTask() {} -TEST_F(TaskQueueManagerTest, +TEST_F(TaskQueueManagerTestWithCustomInitialization, NowCalledMinimumNumberOfTimesToComputeTaskDurations) { - message_loop_.reset(new base::MessageLoop()); + message_loop_.reset(new MessageLoop()); // This memory is managed by the TaskQueueManager, but we need to hold a // pointer to this object to read out how many times Now was called. TestCountUsesTimeSource test_count_uses_time_source; manager_ = TaskQueueManagerForTest::Create( - nullptr, GetSingleThreadTaskRunnerForTesting(), - &test_count_uses_time_source); + nullptr, ThreadTaskRunnerHandle::Get(), &test_count_uses_time_source); manager_->SetWorkBatchSize(6); manager_->AddTaskTimeObserver(&test_task_time_observer_); for (size_t i = 0; i < 3; i++) runners_.push_back(CreateTaskQueue()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - runners_[2]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - runners_[2]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&NopTask)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&NopTask)); + runners_[2]->PostTask(FROM_HERE, BindOnce(&NopTask)); + runners_[2]->PostTask(FROM_HERE, BindOnce(&NopTask)); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); // Now is called each time a task is queued, when first task is started // running, and when a task is completed. 6 * 3 = 18 calls. EXPECT_EQ(18, test_count_uses_time_source.now_calls_count()); } -TEST_F(TaskQueueManagerTest, NowNotCalledForNestedTasks) { - message_loop_.reset(new base::MessageLoop()); +TEST_F(TaskQueueManagerTestWithCustomInitialization, + NowNotCalledForNestedTasks) { + message_loop_.reset(new MessageLoop()); // This memory is managed by the TaskQueueManager, but we need to hold a // pointer to this object to read out how many times Now was called. TestCountUsesTimeSource test_count_uses_time_source; @@ -195,20 +211,17 @@ TEST_F(TaskQueueManagerTest, NowNotCalledForNestedTasks) { runners_.push_back(CreateTaskQueue()); - std::vector<std::pair<base::OnceClosure, bool>> - tasks_to_post_from_nested_loop; + std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop; for (int i = 0; i < 7; ++i) { tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&NopTask), true)); + std::make_pair(BindOnce(&NopTask), true)); } runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostFromNestedRunloop, message_loop_.get(), - base::RetainedRef(runners_[0]), - base::Unretained(&tasks_to_post_from_nested_loop))); + FROM_HERE, BindOnce(&PostFromNestedRunloop, RetainedRef(runners_[0]), + Unretained(&tasks_to_post_from_nested_loop))); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); // We need to call Now twice, to measure the start and end of the outermost // task. We shouldn't call it for any of the nested tasks. // Also Now is called when a task is scheduled (8 times). @@ -230,83 +243,82 @@ void DisableQueueTestTask(EnqueueOrder value, } TEST_F(TaskQueueManagerTest, SingleQueuePosting) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); } TEST_F(TaskQueueManagerTest, MultiQueuePosting) { - Initialize(3u); + CreateTaskQueues(3u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); - runners_[2]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 5, &run_order)); - runners_[2]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 6, &run_order)); - - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); + runners_[2]->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order)); + runners_[2]->PostTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6)); } -TEST_F(TaskQueueManagerTest, NonNestableTaskPosting) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, NonNestableTaskPosting) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; runners_[0]->PostNonNestableTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order)); + BindOnce(&TestTask, 1, &run_order)); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } -TEST_F(TaskQueueManagerTest, NonNestableTaskExecutesInExpectedOrder) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, + NonNestableTaskExecutesInExpectedOrder) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); runners_[0]->PostNonNestableTask(FROM_HERE, - base::BindOnce(&TestTask, 5, &run_order)); + BindOnce(&TestTask, 5, &run_order)); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5)); } -TEST_F(TaskQueueManagerTest, NonNestableTasksDoesntExecuteInNestedLoop) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, + NonNestableTasksDoesntExecuteInNestedLoop) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); - std::vector<std::pair<base::OnceClosure, bool>> - tasks_to_post_from_nested_loop; + std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 3, &run_order), false)); + std::make_pair(BindOnce(&TestTask, 3, &run_order), false)); tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 4, &run_order), false)); + std::make_pair(BindOnce(&TestTask, 4, &run_order), false)); tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 5, &run_order), true)); + std::make_pair(BindOnce(&TestTask, 5, &run_order), true)); tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 6, &run_order), true)); + std::make_pair(BindOnce(&TestTask, 6, &run_order), true)); runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostFromNestedRunloop, message_loop_.get(), - base::RetainedRef(runners_[0]), - base::Unretained(&tasks_to_post_from_nested_loop))); + FROM_HERE, BindOnce(&PostFromNestedRunloop, RetainedRef(runners_[0]), + Unretained(&tasks_to_post_from_nested_loop))); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); // Note we expect tasks 3 & 4 to run last because they're non-nestable. EXPECT_THAT(run_order, ElementsAre(1, 2, 5, 6, 3, 4)); } @@ -318,7 +330,7 @@ void InsertFenceAndPostTestTask(EnqueueOrder id, scoped_refptr<TestTaskQueue> task_queue) { run_order->push_back(id); task_queue->InsertFence(TaskQueue::InsertFencePosition::kNow); - task_queue->PostTask(FROM_HERE, base::BindOnce(&TestTask, id + 1, run_order)); + task_queue->PostTask(FROM_HERE, BindOnce(&TestTask, id + 1, run_order)); // Force reload of immediate work queue. In real life the same effect can be // achieved with cross-thread posting. @@ -327,25 +339,21 @@ void InsertFenceAndPostTestTask(EnqueueOrder id, } // namespace -TEST_F(TaskQueueManagerTest, TaskQueueDisabledFromNestedLoop) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, TaskQueueDisabledFromNestedLoop) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - std::vector<std::pair<base::OnceClosure, bool>> - tasks_to_post_from_nested_loop; + std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 1, &run_order), false)); + std::make_pair(BindOnce(&TestTask, 1, &run_order), false)); tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::BindOnce(&InsertFenceAndPostTestTask, 2, &run_order, runners_[0]), - true)); + BindOnce(&InsertFenceAndPostTestTask, 2, &run_order, runners_[0]), true)); runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostFromNestedRunloop, message_loop_.get(), - base::RetainedRef(runners_[0]), - base::Unretained(&tasks_to_post_from_nested_loop))); - base::RunLoop().RunUntilIdle(); + FROM_HERE, BindOnce(&PostFromNestedRunloop, RetainedRef(runners_[0]), + Unretained(&tasks_to_post_from_nested_loop))); + RunLoop().RunUntilIdle(); // Task 1 shouldn't run first due to it being non-nestable and queue gets // blocked after task 2. Task 1 runs after existing nested message loop @@ -355,16 +363,16 @@ TEST_F(TaskQueueManagerTest, TaskQueueDisabledFromNestedLoop) { EXPECT_THAT(run_order, ElementsAre(2, 1)); runners_[0]->RemoveFence(); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(2, 1, 3)); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_ImmediateTask) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Move the task into the |immediate_work_queue|. @@ -372,155 +380,145 @@ TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_ImmediateTask) { std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE( runners_[0]->GetTaskQueueImpl()->immediate_work_queue()->Empty()); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Run the task, making the queue empty. voter->SetQueueEnabled(true); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_DelayedTask) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); - now_src_.Advance(delay); + test_task_runner_->AdvanceMockTickClock(delay); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Move the task into the |delayed_work_queue|. - WakeUpReadyDelayedQueues(LazyNow(&now_src_)); + LazyNow lazy_now(GetTickClock()); + manager_->WakeUpReadyDelayedQueues(&lazy_now); EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->delayed_work_queue()->Empty()); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // Run the task, making the queue empty. - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, DelayedTaskPosting) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); - EXPECT_EQ(delay, test_task_runner_->DelayToNextTaskTime()); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); + EXPECT_EQ(TimeDelta::FromMilliseconds(10), + test_task_runner_->NextPendingTaskDelay()); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); EXPECT_TRUE(run_order.empty()); // The task doesn't run before the delay has completed. - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(9)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(9)); EXPECT_TRUE(run_order.empty()); // After the delay has completed, the task runs normally. - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(1)); EXPECT_THAT(run_order, ElementsAre(1)); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } -bool MessageLoopTaskCounter(size_t* count) { - *count = *count + 1; - return true; -} - TEST_F(TaskQueueManagerTest, DelayedTaskExecutedInOneMessageLoopTask) { - Initialize(1u); - - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay); + CreateTaskQueues(1u); - size_t task_count = 0; - test_task_runner_->RunTasksWhile( - base::BindRepeating(&MessageLoopTaskCounter, &task_count)); - EXPECT_EQ(1u, task_count); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(10)); + RunLoop().RunUntilIdle(); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + test_task_runner_->FastForwardUntilNoTasksRemain(); + EXPECT_EQ(0u, test_task_runner_->GetPendingTaskCount()); } TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_DecendingOrder) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(8)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(8)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(5)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(5)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(5), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(5)); EXPECT_THAT(run_order, ElementsAre(3)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(3), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(3), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(3)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(3)); EXPECT_THAT(run_order, ElementsAre(3, 2)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(2), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(2), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(2)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(2)); EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); } TEST_F(TaskQueueManagerTest, DelayedTaskPosting_MultipleTasks_AscendingOrder) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(1)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(1)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(5)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(5)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(10)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(1), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(1)); EXPECT_THAT(run_order, ElementsAre(1)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(4), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(4), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(4)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(4)); EXPECT_THAT(run_order, ElementsAre(1, 2)); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(5), - test_task_runner_->DelayToNextTaskTime()); + EXPECT_EQ(TimeDelta::FromMilliseconds(5), + test_task_runner_->NextPendingTaskDelay()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(5)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(5)); EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); } TEST_F(TaskQueueManagerTest, PostDelayedTask_SharesUnderlyingDelayedTasks) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), delay); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), delay); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + delay); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + delay); - EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); } class TestObject { @@ -535,17 +533,15 @@ class TestObject { int TestObject::destructor_count__ = 0; TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) { - Initialize(1u); + CreateTaskQueues(1u); TestObject::destructor_count__ = 0; - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); runners_[0]->PostDelayedTask( - FROM_HERE, - base::BindOnce(&TestObject::Run, base::Owned(new TestObject())), delay); - runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&TestObject::Run, base::Owned(new TestObject()))); + FROM_HERE, BindOnce(&TestObject::Run, Owned(new TestObject())), delay); + runners_[0]->PostTask(FROM_HERE, + BindOnce(&TestObject::Run, Owned(new TestObject()))); manager_.reset(); @@ -553,229 +549,230 @@ TEST_F(TaskQueueManagerTest, PendingDelayedTasksRemovedOnShutdown) { } TEST_F(TaskQueueManagerTest, InsertAndRemoveFence) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; // Posting a task when pumping is disabled doesn't result in work getting // posted. - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); // However polling still works. EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); // After removing the fence the task runs normally. runners_[0]->RemoveFence(); - EXPECT_TRUE(test_task_runner_->HasPendingTasks()); - test_task_runner_->RunUntilIdle(); + EXPECT_TRUE(test_task_runner_->HasPendingTask()); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, RemovingFenceForDisabledQueueDoesNotPostDoWork) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); runners_[0]->RemoveFence(); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); } TEST_F(TaskQueueManagerTest, EnablingFencedQueueDoesNotPostDoWork) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); voter->SetQueueEnabled(true); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); } TEST_F(TaskQueueManagerTest, DenyRunning_BeforePosting) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_TRUE(run_order.empty()); voter->SetQueueEnabled(true); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, DenyRunning_AfterPosting) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); - EXPECT_TRUE(test_task_runner_->HasPendingTasks()); + EXPECT_TRUE(test_task_runner_->HasPendingTask()); voter->SetQueueEnabled(false); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_TRUE(run_order.empty()); voter->SetQueueEnabled(true); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, DenyRunning_AfterRemovingFence) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_TRUE(run_order.empty()); runners_[0]->RemoveFence(); voter->SetQueueEnabled(true); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, RemovingFenceWithDelayedTask) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; // Posting a delayed task when fenced will apply the delay, but won't cause // work to executed afterwards. - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); // The task does not run even though it's delay is up. - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(run_order.empty()); // Removing the fence causes the task to run. runners_[0]->RemoveFence(); - EXPECT_TRUE(test_task_runner_->HasPendingTasks()); - test_task_runner_->RunPendingTasks(); + EXPECT_TRUE(test_task_runner_->HasPendingTask()); + RunPendingTasks(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, RemovingFenceWithMultipleDelayedTasks) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; // Posting a delayed task when fenced will apply the delay, but won't cause // work to executed afterwards. - base::TimeDelta delay1(base::TimeDelta::FromMilliseconds(1)); - base::TimeDelta delay2(base::TimeDelta::FromMilliseconds(10)); - base::TimeDelta delay3(base::TimeDelta::FromMilliseconds(20)); - runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&TestTask, 1, &run_order), delay1); - runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&TestTask, 2, &run_order), delay2); - runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&TestTask, 3, &run_order), delay3); - - now_src_.Advance(base::TimeDelta::FromMilliseconds(15)); - test_task_runner_->RunUntilIdle(); + TimeDelta delay1(TimeDelta::FromMilliseconds(1)); + TimeDelta delay2(TimeDelta::FromMilliseconds(10)); + TimeDelta delay3(TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay1); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + delay2); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + delay3); + + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(15)); + RunLoop().RunUntilIdle(); EXPECT_TRUE(run_order.empty()); // Removing the fence causes the ready tasks to run. runners_[0]->RemoveFence(); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); } TEST_F(TaskQueueManagerTest, InsertFencePreventsDelayedTasksFromRunning) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay(base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); + TimeDelta delay(TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(10)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(10)); EXPECT_TRUE(run_order.empty()); } TEST_F(TaskQueueManagerTest, MultipleFences) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); // Subsequent tasks should be blocked. - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); } TEST_F(TaskQueueManagerTest, InsertFenceThenImmediatlyRemoveDoesNotBlock) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); runners_[0]->RemoveFence(); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); } TEST_F(TaskQueueManagerTest, InsertFencePostThenRemoveDoesNotBlock) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); runners_[0]->RemoveFence(); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); } TEST_F(TaskQueueManagerTest, MultipleFencesWithInitiallyEmptyQueue) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } TEST_F(TaskQueueManagerTest, BlockedByFence) { - Initialize(1u); + CreateTaskQueues(1u); EXPECT_FALSE(runners_[0]->BlockedByFence()); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); @@ -784,11 +781,11 @@ TEST_F(TaskQueueManagerTest, BlockedByFence) { runners_[0]->RemoveFence(); EXPECT_FALSE(runners_[0]->BlockedByFence()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); EXPECT_FALSE(runners_[0]->BlockedByFence()); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_TRUE(runners_[0]->BlockedByFence()); runners_[0]->RemoveFence(); @@ -796,9 +793,9 @@ TEST_F(TaskQueueManagerTest, BlockedByFence) { } TEST_F(TaskQueueManagerTest, BlockedByFence_BothTypesOfFence) { - Initialize(1u); + CreateTaskQueues(1u); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); EXPECT_FALSE(runners_[0]->BlockedByFence()); @@ -809,67 +806,65 @@ TEST_F(TaskQueueManagerTest, BlockedByFence_BothTypesOfFence) { namespace { -void RecordTimeTask(std::vector<base::TimeTicks>* run_times, - base::SimpleTestTickClock* clock) { +void RecordTimeTask(std::vector<TimeTicks>* run_times, const TickClock* clock) { run_times->push_back(clock->NowTicks()); } void RecordTimeAndQueueTask( - std::vector<std::pair<scoped_refptr<TestTaskQueue>, base::TimeTicks>>* - run_times, + std::vector<std::pair<scoped_refptr<TestTaskQueue>, TimeTicks>>* run_times, scoped_refptr<TestTaskQueue> task_queue, - base::SimpleTestTickClock* clock) { + const TickClock* clock) { run_times->emplace_back(task_queue, clock->NowTicks()); } } // namespace TEST_F(TaskQueueManagerTest, DelayedFence_DelayedTasks) { - Initialize(1u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + CreateTaskQueues(1u); - std::vector<base::TimeTicks> run_times; + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(100)); runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(200)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(200)); runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(300)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(300)); - runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250)); + runners_[0]->InsertFenceAt(GetTickClock()->NowTicks() + + TimeDelta::FromMilliseconds(250)); EXPECT_FALSE(runners_[0]->HasActiveFence()); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_TRUE(runners_[0]->HasActiveFence()); - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200))); run_times.clear(); runners_[0]->RemoveFence(); - test_task_runner_->RunUntilIdle(); + + test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_FALSE(runners_[0]->HasActiveFence()); - EXPECT_THAT(run_times, ElementsAre(base::TimeTicks() + - base::TimeDelta::FromMilliseconds(301))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(300))); } TEST_F(TaskQueueManagerTest, DelayedFence_ImmediateTasks) { - Initialize(1u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + CreateTaskQueues(1u); - std::vector<base::TimeTicks> run_times; - runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250)); + std::vector<TimeTicks> run_times; + runners_[0]->InsertFenceAt(GetTickClock()->NowTicks() + + TimeDelta::FromMilliseconds(250)); for (int i = 0; i < 5; ++i) { runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_)); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock())); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(100)); if (i < 2) { EXPECT_FALSE(runners_[0]->HasActiveFence()); } else { @@ -879,32 +874,30 @@ TEST_F(TaskQueueManagerTest, DelayedFence_ImmediateTasks) { EXPECT_THAT( run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201))); + ElementsAre(start_time_, start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200))); run_times.clear(); runners_[0]->RemoveFence(); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(501), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(501))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(500), + start_time_ + TimeDelta::FromMilliseconds(500))); } TEST_F(TaskQueueManagerTest, DelayedFence_RemovedFenceDoesNotActivate) { - Initialize(1u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + CreateTaskQueues(1u); - std::vector<base::TimeTicks> run_times; - runners_[0]->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250)); + std::vector<TimeTicks> run_times; + runners_[0]->InsertFenceAt(GetTickClock()->NowTicks() + + TimeDelta::FromMilliseconds(250)); for (int i = 0; i < 3; ++i) { runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock())); EXPECT_FALSE(runners_[0]->HasActiveFence()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(100)); } EXPECT_TRUE(runners_[0]->HasActiveFence()); @@ -912,67 +905,64 @@ TEST_F(TaskQueueManagerTest, DelayedFence_RemovedFenceDoesNotActivate) { for (int i = 0; i < 2; ++i) { runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_)); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock())); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(100)); EXPECT_FALSE(runners_[0]->HasActiveFence()); } EXPECT_THAT( run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(301), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(401))); + ElementsAre(start_time_, start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200), + start_time_ + TimeDelta::FromMilliseconds(300), + start_time_ + TimeDelta::FromMilliseconds(400))); } TEST_F(TaskQueueManagerTest, DelayedFence_TakeIncomingImmediateQueue) { // This test checks that everything works correctly when a work queue // is swapped with an immediate incoming queue and a delayed fence // is activated, forcing a different queue to become active. - Initialize(2u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); + CreateTaskQueues(2u); scoped_refptr<TestTaskQueue> queue1 = runners_[0]; scoped_refptr<TestTaskQueue> queue2 = runners_[1]; - std::vector<std::pair<scoped_refptr<TestTaskQueue>, base::TimeTicks>> - run_times; + std::vector<std::pair<scoped_refptr<TestTaskQueue>, TimeTicks>> run_times; // Fence ensures that the task posted after advancing time is blocked. - queue1->InsertFenceAt(Now() + base::TimeDelta::FromMilliseconds(250)); + queue1->InsertFenceAt(GetTickClock()->NowTicks() + + TimeDelta::FromMilliseconds(250)); // This task should not be blocked and should run immediately after // advancing time at 301ms. - queue1->PostTask(FROM_HERE, base::BindOnce(&RecordTimeAndQueueTask, - &run_times, queue1, &now_src_)); + queue1->PostTask(FROM_HERE, BindOnce(&RecordTimeAndQueueTask, &run_times, + queue1, GetTickClock())); // Force reload of immediate work queue. In real life the same effect can be // achieved with cross-thread posting. queue1->GetTaskQueueImpl()->ReloadImmediateWorkQueueIfEmpty(); - now_src_.Advance(base::TimeDelta::FromMilliseconds(300)); + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(300)); // This task should be blocked. - queue1->PostTask(FROM_HERE, base::BindOnce(&RecordTimeAndQueueTask, - &run_times, queue1, &now_src_)); + queue1->PostTask(FROM_HERE, BindOnce(&RecordTimeAndQueueTask, &run_times, + queue1, GetTickClock())); // This task on a different runner should run as expected. - queue2->PostTask(FROM_HERE, base::BindOnce(&RecordTimeAndQueueTask, - &run_times, queue2, &now_src_)); + queue2->PostTask(FROM_HERE, BindOnce(&RecordTimeAndQueueTask, &run_times, + queue2, GetTickClock())); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); EXPECT_THAT( run_times, - ElementsAre( - std::make_pair(queue1, base::TimeTicks() + - base::TimeDelta::FromMilliseconds(301)), - std::make_pair(queue2, base::TimeTicks() + - base::TimeDelta::FromMilliseconds(301)))); + ElementsAre(std::make_pair( + queue1, start_time_ + TimeDelta::FromMilliseconds(300)), + std::make_pair( + queue2, start_time_ + TimeDelta::FromMilliseconds(300)))); } namespace { -void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, +void ReentrantTestTask(scoped_refptr<SingleThreadTaskRunner> runner, int countdown, std::vector<EnqueueOrder>* out_result) { out_result->push_back(countdown); @@ -985,391 +975,385 @@ void ReentrantTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, } // namespace TEST_F(TaskQueueManagerTest, ReentrantPosting) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; runners_[0]->PostTask( FROM_HERE, BindOnce(&ReentrantTestTask, runners_[0], 3, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); } TEST_F(TaskQueueManagerTest, NoTasksAfterShutdown) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); manager_.reset(); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_TRUE(run_order.empty()); } -void PostTaskToRunner(scoped_refptr<base::SingleThreadTaskRunner> runner, +void PostTaskToRunner(scoped_refptr<SingleThreadTaskRunner> runner, std::vector<EnqueueOrder>* run_order) { - runner->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, run_order)); + runner->PostTask(FROM_HERE, BindOnce(&TestTask, 1, run_order)); } -TEST_F(TaskQueueManagerTest, PostFromThread) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, PostFromThread) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::Thread thread("TestThread"); + Thread thread("TestThread"); thread.Start(); thread.task_runner()->PostTask( - FROM_HERE, base::BindOnce(&PostTaskToRunner, runners_[0], &run_order)); + FROM_HERE, BindOnce(&PostTaskToRunner, runners_[0], &run_order)); thread.Stop(); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); } -void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, +void RePostingTestTask(scoped_refptr<SingleThreadTaskRunner> runner, int* run_count) { (*run_count)++; - runner->PostTask( - FROM_HERE, - BindOnce(&RePostingTestTask, base::Unretained(runner.get()), run_count)); + runner->PostTask(FROM_HERE, BindOnce(&RePostingTestTask, + Unretained(runner.get()), run_count)); } TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { - Initialize(1u); + CreateTaskQueues(1u); int run_count = 0; - runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&RePostingTestTask, runners_[0], &run_count)); + runners_[0]->PostTask(FROM_HERE, + BindOnce(&RePostingTestTask, runners_[0], &run_count)); - test_task_runner_->RunPendingTasks(); - // NOTE without the executing_task_ check in MaybeScheduleDoWork there - // will be two tasks here. - EXPECT_EQ(1u, test_task_runner_->NumPendingTasks()); + RunPendingTasks(); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); EXPECT_EQ(1, run_count); } -TEST_F(TaskQueueManagerTest, PostFromNestedRunloop) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, PostFromNestedRunloop) { + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - std::vector<std::pair<base::OnceClosure, bool>> - tasks_to_post_from_nested_loop; + std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TestTask, 1, &run_order), true)); + std::make_pair(BindOnce(&TestTask, 1, &run_order), true)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 0, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 0, &run_order)); runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostFromNestedRunloop, message_loop_.get(), - base::RetainedRef(runners_[0]), - base::Unretained(&tasks_to_post_from_nested_loop))); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + FROM_HERE, BindOnce(&PostFromNestedRunloop, RetainedRef(runners_[0]), + Unretained(&tasks_to_post_from_nested_loop))); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(0, 2, 1)); } TEST_F(TaskQueueManagerTest, WorkBatching) { - Initialize(1u); + CreateTaskQueues(1u); manager_->SetWorkBatchSize(2); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); // Running one task in the host message loop should cause two posted tasks to // get executed. - EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); - test_task_runner_->RunPendingTasks(); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + RunPendingTasks(); EXPECT_THAT(run_order, ElementsAre(1, 2)); // The second task runs the remaining two posted tasks. - EXPECT_EQ(test_task_runner_->NumPendingTasks(), 1u); - test_task_runner_->RunPendingTasks(); + EXPECT_EQ(1u, test_task_runner_->GetPendingTaskCount()); + RunPendingTasks(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); } -class MockTaskObserver : public base::MessageLoop::TaskObserver { +class MockTaskObserver : public MessageLoop::TaskObserver { public: - MOCK_METHOD1(DidProcessTask, void(const base::PendingTask& task)); - MOCK_METHOD1(WillProcessTask, void(const base::PendingTask& task)); + MOCK_METHOD1(DidProcessTask, void(const PendingTask& task)); + MOCK_METHOD1(WillProcessTask, void(const PendingTask& task)); }; -TEST_F(TaskQueueManagerTest, TaskObserverAdding) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, TaskObserverAdding) { + CreateTaskQueues(1u); MockTaskObserver observer; manager_->SetWorkBatchSize(2); manager_->AddTaskObserver(&observer); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); EXPECT_CALL(observer, WillProcessTask(_)).Times(2); EXPECT_CALL(observer, DidProcessTask(_)).Times(2); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } -TEST_F(TaskQueueManagerTest, TaskObserverRemoving) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, TaskObserverRemoving) { + CreateTaskQueues(1u); MockTaskObserver observer; manager_->SetWorkBatchSize(2); manager_->AddTaskObserver(&observer); manager_->RemoveTaskObserver(&observer); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); EXPECT_CALL(observer, WillProcessTask(_)).Times(0); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } void RemoveObserverTask(TaskQueueManagerImpl* manager, - base::MessageLoop::TaskObserver* observer) { + MessageLoop::TaskObserver* observer) { manager->RemoveTaskObserver(observer); } -TEST_F(TaskQueueManagerTest, TaskObserverRemovingInsideTask) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, TaskObserverRemovingInsideTask) { + CreateTaskQueues(1u); MockTaskObserver observer; manager_->SetWorkBatchSize(3); manager_->AddTaskObserver(&observer); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&RemoveObserverTask, - manager_.get(), &observer)); + runners_[0]->PostTask( + FROM_HERE, BindOnce(&RemoveObserverTask, manager_.get(), &observer)); EXPECT_CALL(observer, WillProcessTask(_)).Times(1); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } -TEST_F(TaskQueueManagerTest, QueueTaskObserverAdding) { - InitializeWithRealMessageLoop(2u); +TEST_F(TaskQueueManagerTestWithMessageLoop, QueueTaskObserverAdding) { + CreateTaskQueues(2u); MockTaskObserver observer; manager_->SetWorkBatchSize(2); runners_[0]->AddTaskObserver(&observer); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); EXPECT_CALL(observer, WillProcessTask(_)).Times(1); EXPECT_CALL(observer, DidProcessTask(_)).Times(1); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } -TEST_F(TaskQueueManagerTest, QueueTaskObserverRemoving) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, QueueTaskObserverRemoving) { + CreateTaskQueues(1u); MockTaskObserver observer; manager_->SetWorkBatchSize(2); runners_[0]->AddTaskObserver(&observer); runners_[0]->RemoveTaskObserver(&observer); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); EXPECT_CALL(observer, WillProcessTask(_)).Times(0); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } void RemoveQueueObserverTask(scoped_refptr<TaskQueue> queue, - base::MessageLoop::TaskObserver* observer) { + MessageLoop::TaskObserver* observer) { queue->RemoveTaskObserver(observer); } -TEST_F(TaskQueueManagerTest, QueueTaskObserverRemovingInsideTask) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, + QueueTaskObserverRemovingInsideTask) { + CreateTaskQueues(1u); MockTaskObserver observer; runners_[0]->AddTaskObserver(&observer); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&RemoveQueueObserverTask, - runners_[0], &observer)); + runners_[0]->PostTask( + FROM_HERE, BindOnce(&RemoveQueueObserverTask, runners_[0], &observer)); EXPECT_CALL(observer, WillProcessTask(_)).Times(1); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); } TEST_F(TaskQueueManagerTest, ThreadCheckAfterTermination) { - Initialize(1u); + CreateTaskQueues(1u); EXPECT_TRUE(runners_[0]->RunsTasksInCurrentSequence()); manager_.reset(); EXPECT_TRUE(runners_[0]->RunsTasksInCurrentSequence()); } TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime) { - Initialize(2u); - now_src_.Advance(base::TimeDelta::FromMicroseconds(10000)); + CreateTaskQueues(2u); + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMicroseconds(10000)); // With no delayed tasks. - base::TimeTicks run_time; + TimeTicks run_time; EXPECT_FALSE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); // With a non-delayed task. - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); EXPECT_FALSE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); // With a delayed task. - base::TimeDelta expected_delay = base::TimeDelta::FromMilliseconds(50); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - expected_delay); + TimeDelta expected_delay = TimeDelta::FromMilliseconds(50); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), expected_delay); EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time); + EXPECT_EQ(GetTickClock()->NowTicks() + expected_delay, run_time); // With another delayed task in the same queue with a longer delay. - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(100)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(100)); EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time); + EXPECT_EQ(GetTickClock()->NowTicks() + expected_delay, run_time); // With another delayed task in the same queue with a shorter delay. - expected_delay = base::TimeDelta::FromMilliseconds(20); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - expected_delay); + expected_delay = TimeDelta::FromMilliseconds(20); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), expected_delay); EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time); + EXPECT_EQ(GetTickClock()->NowTicks() + expected_delay, run_time); // With another delayed task in a different queue with a shorter delay. - expected_delay = base::TimeDelta::FromMilliseconds(10); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - expected_delay); + expected_delay = TimeDelta::FromMilliseconds(10); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), expected_delay); EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks() + expected_delay, run_time); + EXPECT_EQ(GetTickClock()->NowTicks() + expected_delay, run_time); // Test it updates as time progresses - now_src_.Advance(expected_delay); + test_task_runner_->AdvanceMockTickClock(expected_delay); EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks(), run_time); + EXPECT_EQ(GetTickClock()->NowTicks(), run_time); } TEST_F(TaskQueueManagerTest, TimeDomain_NextScheduledRunTime_MultipleQueues) { - Initialize(3u); + CreateTaskQueues(3u); - base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(50); - base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); - base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(10); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay1); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay2); - runners_[2]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay3); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + TimeDelta delay1 = TimeDelta::FromMilliseconds(50); + TimeDelta delay2 = TimeDelta::FromMilliseconds(5); + TimeDelta delay3 = TimeDelta::FromMilliseconds(10); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay2); + runners_[2]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay3); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); - base::TimeTicks run_time; + TimeTicks run_time; EXPECT_TRUE(manager_->GetRealTimeDomain()->NextScheduledRunTime(&run_time)); - EXPECT_EQ(now_src_.NowTicks() + delay2, run_time); + EXPECT_EQ(GetTickClock()->NowTicks() + delay2, run_time); } TEST_F(TaskQueueManagerTest, DeleteTaskQueueManagerInsideATask) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&TaskQueueManagerTest::DeleteTaskQueueManager, - base::Unretained(this))); + FROM_HERE, BindOnce(&TaskQueueManagerTest::DeleteTaskQueueManagerTask, + Unretained(this))); // This should not crash, assuming DoWork detects the TaskQueueManager has // been deleted. - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); } TEST_F(TaskQueueManagerTest, GetAndClearSystemIsQuiescentBit) { - Initialize(3u); + CreateTaskQueues(3u); - scoped_refptr<TaskQueue> queue0 = CreateTaskQueueWithMonitoredQuiescence(); - scoped_refptr<TaskQueue> queue1 = CreateTaskQueueWithMonitoredQuiescence(); + scoped_refptr<TaskQueue> queue0 = + CreateTaskQueue(TaskQueue::Spec("test").SetShouldMonitorQuiescence(true)); + scoped_refptr<TaskQueue> queue1 = + CreateTaskQueue(TaskQueue::Spec("test").SetShouldMonitorQuiescence(true)); scoped_refptr<TaskQueue> queue2 = CreateTaskQueue(); EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); - queue0->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - test_task_runner_->RunUntilIdle(); + queue0->PostTask(FROM_HERE, BindOnce(&NopTask)); + RunLoop().RunUntilIdle(); EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); - queue1->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - test_task_runner_->RunUntilIdle(); + queue1->PostTask(FROM_HERE, BindOnce(&NopTask)); + RunLoop().RunUntilIdle(); EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); - queue2->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - test_task_runner_->RunUntilIdle(); + queue2->PostTask(FROM_HERE, BindOnce(&NopTask)); + RunLoop().RunUntilIdle(); EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); - queue0->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - queue1->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - test_task_runner_->RunUntilIdle(); + queue0->PostTask(FROM_HERE, BindOnce(&NopTask)); + queue1->PostTask(FROM_HERE, BindOnce(&NopTask)); + RunLoop().RunUntilIdle(); EXPECT_FALSE(manager_->GetAndClearSystemIsQuiescentBit()); EXPECT_TRUE(manager_->GetAndClearSystemIsQuiescentBit()); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork) { - Initialize(1u); + CreateTaskQueues(1u); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(NullTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(NullTask)); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } TEST_F(TaskQueueManagerTest, HasPendingImmediateWork_DelayedTasks) { - Initialize(1u); + CreateTaskQueues(1u); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(NullTask), - base::TimeDelta::FromMilliseconds(12)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(NullTask), + TimeDelta::FromMilliseconds(12)); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); // Move time forwards until just before the delayed task should run. - now_src_.Advance(base::TimeDelta::FromMilliseconds(10)); - WakeUpReadyDelayedQueues(LazyNow(&now_src_)); + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(10)); + LazyNow lazy_now_1(GetTickClock()); + manager_->WakeUpReadyDelayedQueues(&lazy_now_1); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); // Force the delayed task onto the work queue. - now_src_.Advance(base::TimeDelta::FromMilliseconds(2)); - WakeUpReadyDelayedQueues(LazyNow(&now_src_)); + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromMilliseconds(2)); + LazyNow lazy_now_2(GetTickClock()); + manager_->WakeUpReadyDelayedQueues(&lazy_now_2); EXPECT_TRUE(runners_[0]->HasTaskToRunImmediately()); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE(runners_[0]->HasTaskToRunImmediately()); } void ExpensiveTestTask(int value, - base::SimpleTestTickClock* clock, + scoped_refptr<TestMockTimeTaskRunner> test_task_runner, std::vector<EnqueueOrder>* out_result) { out_result->push_back(value); - clock->Advance(base::TimeDelta::FromMilliseconds(1)); + test_task_runner->FastForwardBy(TimeDelta::FromMilliseconds(1)); } TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskInterleaving) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); + TimeDelta delay = TimeDelta::FromMilliseconds(10); for (int i = 10; i < 19; i++) { runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&ExpensiveTestTask, i, &now_src_, &run_order), - delay); + FROM_HERE, + BindOnce(&ExpensiveTestTask, i, test_task_runner_, &run_order), delay); } - test_task_runner_->RunForPeriod(delay); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(10)); for (int i = 0; i < 9; i++) { - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&ExpensiveTestTask, i, - &now_src_, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&ExpensiveTestTask, i, + test_task_runner_, &run_order)); } - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); // Delayed tasks are not allowed to starve out immediate work which is why // some of the immediate tasks run out of order. @@ -1380,93 +1364,88 @@ TEST_F(TaskQueueManagerTest, ImmediateAndDelayedTaskInterleaving) { TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_SameQueue) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); + TimeDelta delay = TimeDelta::FromMilliseconds(10); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); - now_src_.Advance(delay * 2); - test_task_runner_->RunUntilIdle(); + test_task_runner_->AdvanceMockTickClock(delay * 2); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); } TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfNonDelayedTask_DifferentQueues) { - Initialize(2u); + CreateTaskQueues(2u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), delay); + TimeDelta delay = TimeDelta::FromMilliseconds(10); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay); - now_src_.Advance(delay * 2); - test_task_runner_->RunUntilIdle(); + test_task_runner_->AdvanceMockTickClock(delay * 2); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(2, 3, 1)); } TEST_F(TaskQueueManagerTest, DelayedTaskDoesNotSkipAHeadOfShorterDelayedTask) { - Initialize(2u); + CreateTaskQueues(2u); std::vector<EnqueueOrder> run_order; - base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); - base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(5); - runners_[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&TestTask, 1, &run_order), delay1); - runners_[1]->PostDelayedTask( - FROM_HERE, base::BindOnce(&TestTask, 2, &run_order), delay2); + TimeDelta delay1 = TimeDelta::FromMilliseconds(10); + TimeDelta delay2 = TimeDelta::FromMilliseconds(5); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + delay1); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + delay2); - now_src_.Advance(delay1 * 2); - test_task_runner_->RunUntilIdle(); + test_task_runner_->AdvanceMockTickClock(delay1 * 2); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(2, 1)); } void CheckIsNested(bool* is_nested) { - *is_nested = base::RunLoop::IsNestedOnCurrentThread(); + *is_nested = RunLoop::IsNestedOnCurrentThread(); } -void PostAndQuitFromNestedRunloop(base::RunLoop* run_loop, - base::SingleThreadTaskRunner* runner, +void PostAndQuitFromNestedRunloop(RunLoop* run_loop, + SingleThreadTaskRunner* runner, bool* was_nested) { - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); runner->PostTask(FROM_HERE, run_loop->QuitClosure()); - runner->PostTask(FROM_HERE, base::BindOnce(&CheckIsNested, was_nested)); + runner->PostTask(FROM_HERE, BindOnce(&CheckIsNested, was_nested)); run_loop->Run(); } -TEST_F(TaskQueueManagerTest, QuitWhileNested) { +TEST_F(TaskQueueManagerTestWithMessageLoop, QuitWhileNested) { // This test makes sure we don't continue running a work batch after a nested // run loop has been exited in the middle of the batch. - InitializeWithRealMessageLoop(1u); + CreateTaskQueues(1u); manager_->SetWorkBatchSize(2); bool was_nested = true; - base::RunLoop run_loop; + RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed); runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostAndQuitFromNestedRunloop, base::Unretained(&run_loop), - base::RetainedRef(runners_[0]), - base::Unretained(&was_nested))); + FROM_HERE, BindOnce(&PostAndQuitFromNestedRunloop, Unretained(&run_loop), + RetainedRef(runners_[0]), Unretained(&was_nested))); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_FALSE(was_nested); } -class SequenceNumberCapturingTaskObserver - : public base::MessageLoop::TaskObserver { +class SequenceNumberCapturingTaskObserver : public MessageLoop::TaskObserver { public: // MessageLoop::TaskObserver overrides. - void WillProcessTask(const base::PendingTask& pending_task) override {} - void DidProcessTask(const base::PendingTask& pending_task) override { + void WillProcessTask(const PendingTask& pending_task) override {} + void DidProcessTask(const PendingTask& pending_task) override { sequence_numbers_.push_back(pending_task.sequence_num); } @@ -1479,25 +1458,22 @@ class SequenceNumberCapturingTaskObserver }; TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) { - Initialize(1u); + CreateTaskQueues(1u); SequenceNumberCapturingTaskObserver observer; manager_->AddTaskObserver(&observer); // Register four tasks that will run in reverse order. std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(30)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(20)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); - - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(30)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(10)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); + + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(40)); ASSERT_THAT(run_order, ElementsAre(4, 3, 2, 1)); // The sequence numbers are a one-based monotonically incrememting counter @@ -1509,7 +1485,7 @@ TEST_F(TaskQueueManagerTest, SequenceNumSetWhenTaskIsPosted) { } TEST_F(TaskQueueManagerTest, NewTaskQueues) { - Initialize(1u); + CreateTaskQueues(1u); scoped_refptr<TaskQueue> queue1 = CreateTaskQueue(); scoped_refptr<TaskQueue> queue2 = CreateTaskQueue(); @@ -1520,16 +1496,16 @@ TEST_F(TaskQueueManagerTest, NewTaskQueues) { ASSERT_NE(queue2, queue3); std::vector<EnqueueOrder> run_order; - queue1->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - queue2->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - queue3->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - test_task_runner_->RunUntilIdle(); + queue1->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + queue2->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + queue3->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); } TEST_F(TaskQueueManagerTest, ShutdownTaskQueue) { - Initialize(1u); + CreateTaskQueues(1u); scoped_refptr<TaskQueue> queue1 = CreateTaskQueue(); scoped_refptr<TaskQueue> queue2 = CreateTaskQueue(); @@ -1540,35 +1516,32 @@ TEST_F(TaskQueueManagerTest, ShutdownTaskQueue) { ASSERT_NE(queue2, queue3); std::vector<EnqueueOrder> run_order; - queue1->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - queue2->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - queue3->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); + queue1->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + queue2->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + queue3->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); queue2->ShutdownTaskQueue(); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 3)); } TEST_F(TaskQueueManagerTest, ShutdownTaskQueue_WithDelayedTasks) { - Initialize(2u); + CreateTaskQueues(2u); // Register three delayed tasks std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(10)); - runners_[1]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(20)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(30)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(10)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(30)); runners_[1]->ShutdownTaskQueue(); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(40)); ASSERT_THAT(run_order, ElementsAre(1, 3)); } @@ -1579,16 +1552,16 @@ void ShutdownQueue(scoped_refptr<TaskQueue> queue) { } // namespace TEST_F(TaskQueueManagerTest, ShutdownTaskQueue_InTasks) { - Initialize(3u); + CreateTaskQueues(3u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&ShutdownQueue, runners_[1])); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&ShutdownQueue, runners_[2])); - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[2]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&ShutdownQueue, runners_[1])); + runners_[0]->PostTask(FROM_HERE, BindOnce(&ShutdownQueue, runners_[2])); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[2]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); ASSERT_THAT(run_order, ElementsAre(1)); } @@ -1603,43 +1576,39 @@ class MockObserver : public TaskQueueManager::Observer { } // namespace -TEST_F(TaskQueueManagerTest, ShutdownTaskQueueInNestedLoop) { - InitializeWithRealMessageLoop(1u); +TEST_F(TaskQueueManagerTestWithMessageLoop, ShutdownTaskQueueInNestedLoop) { + CreateTaskQueues(1u); // We retain a reference to the task queue even when the manager has deleted // its reference. scoped_refptr<TaskQueue> task_queue = CreateTaskQueue(); std::vector<bool> log; - std::vector<std::pair<base::OnceClosure, bool>> - tasks_to_post_from_nested_loop; + std::vector<std::pair<OnceClosure, bool>> tasks_to_post_from_nested_loop; // Inside a nested run loop, call task_queue->ShutdownTaskQueue, bookended // by calls to HasOneRefTask to make sure the manager doesn't release its // reference until the nested run loop exits. // NB: This first HasOneRefTask is a sanity check. tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&NopTask), true)); - tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&TaskQueue::ShutdownTaskQueue, - base::Unretained(task_queue.get())), - true)); + std::make_pair(BindOnce(&NopTask), true)); + tasks_to_post_from_nested_loop.push_back(std::make_pair( + BindOnce(&TaskQueue::ShutdownTaskQueue, Unretained(task_queue.get())), + true)); tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&NopTask), true)); + std::make_pair(BindOnce(&NopTask), true)); runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&PostFromNestedRunloop, message_loop_.get(), - base::RetainedRef(runners_[0]), - base::Unretained(&tasks_to_post_from_nested_loop))); - base::RunLoop().RunUntilIdle(); + FROM_HERE, BindOnce(&PostFromNestedRunloop, RetainedRef(runners_[0]), + Unretained(&tasks_to_post_from_nested_loop))); + RunLoop().RunUntilIdle(); // Just make sure that we don't crash. } TEST_F(TaskQueueManagerTest, TimeDomainsAreIndependant) { - Initialize(2u); + CreateTaskQueues(2u); - base::TimeTicks start_time_ticks = manager_->NowTicks(); + TimeTicks start_time_ticks = manager_->NowTicks(); std::unique_ptr<VirtualTimeDomain> domain_a( new VirtualTimeDomain(start_time_ticks)); std::unique_ptr<VirtualTimeDomain> domain_b( @@ -1650,38 +1619,30 @@ TEST_F(TaskQueueManagerTest, TimeDomainsAreIndependant) { runners_[1]->SetTimeDomain(domain_b.get()); std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(20)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(30)); - - runners_[1]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 4, &run_order), - base::TimeDelta::FromMilliseconds(10)); - runners_[1]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 5, &run_order), - base::TimeDelta::FromMilliseconds(20)); - runners_[1]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 6, &run_order), - base::TimeDelta::FromMilliseconds(30)); - - domain_b->AdvanceNowTo(start_time_ticks + - base::TimeDelta::FromMilliseconds(50)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(30)); + + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order), + TimeDelta::FromMilliseconds(10)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order), + TimeDelta::FromMilliseconds(20)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order), + TimeDelta::FromMilliseconds(30)); + + domain_b->AdvanceNowTo(start_time_ticks + TimeDelta::FromMilliseconds(50)); manager_->MaybeScheduleImmediateWork(FROM_HERE); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(4, 5, 6)); - domain_a->AdvanceNowTo(start_time_ticks + - base::TimeDelta::FromMilliseconds(50)); + domain_a->AdvanceNowTo(start_time_ticks + TimeDelta::FromMilliseconds(50)); manager_->MaybeScheduleImmediateWork(FROM_HERE); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(4, 5, 6, 1, 2, 3)); runners_[0]->ShutdownTaskQueue(); @@ -1692,32 +1653,27 @@ TEST_F(TaskQueueManagerTest, TimeDomainsAreIndependant) { } TEST_F(TaskQueueManagerTest, TimeDomainMigration) { - Initialize(1u); + CreateTaskQueues(1u); - base::TimeTicks start_time_ticks = manager_->NowTicks(); + TimeTicks start_time_ticks = manager_->NowTicks(); std::unique_ptr<VirtualTimeDomain> domain_a( new VirtualTimeDomain(start_time_ticks)); manager_->RegisterTimeDomain(domain_a.get()); runners_[0]->SetTimeDomain(domain_a.get()); std::vector<EnqueueOrder> run_order; - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(10)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(20)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(30)); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 4, &run_order), - base::TimeDelta::FromMilliseconds(40)); - - domain_a->AdvanceNowTo(start_time_ticks + - base::TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(30)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order), + TimeDelta::FromMilliseconds(40)); + + domain_a->AdvanceNowTo(start_time_ticks + TimeDelta::FromMilliseconds(20)); manager_->MaybeScheduleImmediateWork(FROM_HERE); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); std::unique_ptr<VirtualTimeDomain> domain_b( @@ -1725,11 +1681,10 @@ TEST_F(TaskQueueManagerTest, TimeDomainMigration) { manager_->RegisterTimeDomain(domain_b.get()); runners_[0]->SetTimeDomain(domain_b.get()); - domain_b->AdvanceNowTo(start_time_ticks + - base::TimeDelta::FromMilliseconds(50)); + domain_b->AdvanceNowTo(start_time_ticks + TimeDelta::FromMilliseconds(50)); manager_->MaybeScheduleImmediateWork(FROM_HERE); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); runners_[0]->ShutdownTaskQueue(); @@ -1739,9 +1694,9 @@ TEST_F(TaskQueueManagerTest, TimeDomainMigration) { } TEST_F(TaskQueueManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) { - Initialize(1u); + CreateTaskQueues(1u); - base::TimeTicks start_time_ticks = manager_->NowTicks(); + TimeTicks start_time_ticks = manager_->NowTicks(); std::unique_ptr<VirtualTimeDomain> domain_a( new VirtualTimeDomain(start_time_ticks)); std::unique_ptr<VirtualTimeDomain> domain_b( @@ -1751,10 +1706,10 @@ TEST_F(TaskQueueManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) { runners_[0]->SetTimeDomain(domain_a.get()); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); runners_[0]->SetTimeDomain(domain_b.get()); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1)); runners_[0]->ShutdownTaskQueue(); @@ -1765,7 +1720,7 @@ TEST_F(TaskQueueManagerTest, TimeDomainMigrationWithIncomingImmediateTasks) { TEST_F(TaskQueueManagerTest, PostDelayedTasksReverseOrderAlternatingTimeDomains) { - Initialize(1u); + CreateTaskQueues(1u); std::vector<EnqueueOrder> run_order; @@ -1775,26 +1730,22 @@ TEST_F(TaskQueueManagerTest, manager_->RegisterTimeDomain(domain_b.get()); runners_[0]->SetTimeDomain(domain_a.get()); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 1, &run_order), - base::TimeDelta::FromMilliseconds(40)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order), + TimeDelta::FromMilliseconds(40)); runners_[0]->SetTimeDomain(domain_b.get()); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 2, &run_order), - base::TimeDelta::FromMilliseconds(30)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order), + TimeDelta::FromMilliseconds(30)); runners_[0]->SetTimeDomain(domain_a.get()); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 3, &run_order), - base::TimeDelta::FromMilliseconds(20)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order), + TimeDelta::FromMilliseconds(20)); runners_[0]->SetTimeDomain(domain_b.get()); - runners_[0]->PostDelayedTask(FROM_HERE, - base::BindOnce(&TestTask, 4, &run_order), - base::TimeDelta::FromMilliseconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order), + TimeDelta::FromMilliseconds(10)); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(40)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(40)); EXPECT_THAT(run_order, ElementsAre(4, 3, 2, 1)); runners_[0]->ShutdownTaskQueue(); @@ -1809,43 +1760,43 @@ class MockTaskQueueObserver : public TaskQueue::Observer { public: ~MockTaskQueueObserver() override = default; - MOCK_METHOD2(OnQueueNextWakeUpChanged, void(TaskQueue*, base::TimeTicks)); + MOCK_METHOD2(OnQueueNextWakeUpChanged, void(TaskQueue*, TimeTicks)); }; } // namespace TEST_F(TaskQueueManagerTest, TaskQueueObserver_ImmediateTask) { - Initialize(1u); + CreateTaskQueues(1u); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); // We should get a notification when a task is posted on an empty queue. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), _)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); Mock::VerifyAndClearExpectations(&observer); // But not subsequently. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)).Times(0); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); Mock::VerifyAndClearExpectations(&observer); // Unless the immediate work queue is emptied. runners_[0]->GetTaskQueueImpl()->ReloadImmediateWorkQueueIfEmpty(); EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), _)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); // Tidy up. runners_[0]->ShutdownTaskQueue(); } TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedTask) { - Initialize(1u); + CreateTaskQueues(1u); - base::TimeTicks start_time = manager_->NowTicks(); - base::TimeDelta delay10s(base::TimeDelta::FromSeconds(10)); - base::TimeDelta delay100s(base::TimeDelta::FromSeconds(100)); - base::TimeDelta delay1s(base::TimeDelta::FromSeconds(1)); + TimeTicks start_time = manager_->NowTicks(); + TimeDelta delay10s(TimeDelta::FromSeconds(10)); + TimeDelta delay100s(TimeDelta::FromSeconds(100)); + TimeDelta delay1s(TimeDelta::FromSeconds(1)); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); @@ -1854,18 +1805,18 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedTask) { // queue. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay10s)); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay10s); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay10s); Mock::VerifyAndClearExpectations(&observer); // We should not get a notification for a longer delay. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)).Times(0); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay100s); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay100s); Mock::VerifyAndClearExpectations(&observer); // We should get a notification for a shorter delay. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay1s)); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay1s); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s); Mock::VerifyAndClearExpectations(&observer); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = @@ -1885,15 +1836,15 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedTask) { } TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedTaskMultipleQueues) { - Initialize(2u); + CreateTaskQueues(2u); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); runners_[1]->SetObserver(&observer); - base::TimeTicks start_time = manager_->NowTicks(); - base::TimeDelta delay1s(base::TimeDelta::FromSeconds(1)); - base::TimeDelta delay10s(base::TimeDelta::FromSeconds(10)); + TimeTicks start_time = manager_->NowTicks(); + TimeDelta delay1s(TimeDelta::FromSeconds(1)); + TimeDelta delay10s(TimeDelta::FromSeconds(10)); EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay1s)) @@ -1901,8 +1852,8 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedTaskMultipleQueues) { EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[1].get(), start_time + delay10s)) .Times(1); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay1s); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay10s); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay10s); testing::Mock::VerifyAndClearExpectations(&observer); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter0 = @@ -1946,10 +1897,10 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) { // is the same in all conditions and just change a time domain to // trigger notification. - Initialize(1u); + CreateTaskQueues(1u); - base::TimeDelta delay1s(base::TimeDelta::FromSeconds(1)); - base::TimeDelta delay10s(base::TimeDelta::FromSeconds(10)); + TimeDelta delay1s(TimeDelta::FromSeconds(1)); + TimeDelta delay10s(TimeDelta::FromSeconds(10)); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); @@ -1957,14 +1908,14 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) { // We should get a notification when a delayed task is posted on an empty // queue. EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay1s); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1s); Mock::VerifyAndClearExpectations(&observer); std::unique_ptr<TimeDomain> mock_time_domain = std::make_unique<RealTimeDomain>(); manager_->RegisterTimeDomain(mock_time_domain.get()); - now_src_.Advance(delay10s); + test_task_runner_->AdvanceMockTickClock(delay10s); EXPECT_CALL(observer, OnQueueNextWakeUpChanged(_, _)); runners_[0]->SetTimeDomain(mock_time_domain.get()); @@ -1976,43 +1927,43 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_DelayedWorkWhichCanRunNow) { class CancelableTask { public: - explicit CancelableTask(const base::TickClock* clock) + explicit CancelableTask(const TickClock* clock) : clock_(clock), weak_factory_(this) {} - void RecordTimeTask(std::vector<base::TimeTicks>* run_times) { + void RecordTimeTask(std::vector<TimeTicks>* run_times) { run_times->push_back(clock_->NowTicks()); } - const base::TickClock* clock_; - base::WeakPtrFactory<CancelableTask> weak_factory_; + const TickClock* clock_; + WeakPtrFactory<CancelableTask> weak_factory_; }; TEST_F(TaskQueueManagerTest, TaskQueueObserver_SweepCanceledDelayedTasks) { - Initialize(1u); + CreateTaskQueues(1u); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); - base::TimeTicks start_time = manager_->NowTicks(); - base::TimeDelta delay1(base::TimeDelta::FromSeconds(5)); - base::TimeDelta delay2(base::TimeDelta::FromSeconds(10)); + TimeTicks start_time = manager_->NowTicks(); + TimeDelta delay1(TimeDelta::FromSeconds(5)); + TimeDelta delay2(TimeDelta::FromSeconds(10)); EXPECT_CALL(observer, OnQueueNextWakeUpChanged(runners_[0].get(), start_time + delay1)) .Times(1); - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - std::vector<base::TimeTicks> run_times; + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times), delay1); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times), delay2); task1.weak_factory_.InvalidateWeakPtrs(); @@ -2026,26 +1977,25 @@ TEST_F(TaskQueueManagerTest, TaskQueueObserver_SweepCanceledDelayedTasks) { namespace { void ChromiumRunloopInspectionTask( - scoped_refptr<cc::OrderedSimpleTaskRunner> test_task_runner) { - EXPECT_EQ(1u, test_task_runner->NumPendingTasks()); + scoped_refptr<TestMockTimeTaskRunner> test_task_runner) { + // We don't expect more than 1 pending task at any time. + EXPECT_GE(1u, test_task_runner->GetPendingTaskCount()); } } // namespace TEST_F(TaskQueueManagerTest, NumberOfPendingTasksOnChromiumRunLoop) { - Initialize(1u); + CreateTaskQueues(1u); // NOTE because tasks posted to the chromiumrun loop are not cancellable, we // will end up with a lot more tasks posted if the delayed tasks were posted // in the reverse order. // TODO(alexclarke): Consider talking to the message pump directly. - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); for (int i = 1; i < 100; i++) { runners_[0]->PostDelayedTask( - FROM_HERE, - base::BindOnce(&ChromiumRunloopInspectionTask, test_task_runner_), - base::TimeDelta::FromMilliseconds(i)); + FROM_HERE, BindOnce(&ChromiumRunloopInspectionTask, test_task_runner_), + TimeDelta::FromMilliseconds(i)); } - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); } namespace { @@ -2053,11 +2003,14 @@ namespace { class QuadraticTask { public: QuadraticTask(scoped_refptr<TaskQueue> task_queue, - base::TimeDelta delay, - base::SimpleTestTickClock* now_src) - : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {} - - void SetShouldExit(base::RepeatingCallback<bool()> should_exit) { + TimeDelta delay, + scoped_refptr<TestMockTimeTaskRunner> test_task_runner) + : count_(0), + task_queue_(task_queue), + delay_(delay), + test_task_runner_(test_task_runner) {} + + void SetShouldExit(RepeatingCallback<bool()> should_exit) { should_exit_ = should_exit; } @@ -2066,12 +2019,10 @@ class QuadraticTask { return; count_++; task_queue_->PostDelayedTask( - FROM_HERE, base::BindOnce(&QuadraticTask::Run, base::Unretained(this)), - delay_); + FROM_HERE, BindOnce(&QuadraticTask::Run, Unretained(this)), delay_); task_queue_->PostDelayedTask( - FROM_HERE, base::BindOnce(&QuadraticTask::Run, base::Unretained(this)), - delay_); - now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); + FROM_HERE, BindOnce(&QuadraticTask::Run, Unretained(this)), delay_); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(5)); } int Count() const { return count_; } @@ -2079,19 +2030,22 @@ class QuadraticTask { private: int count_; scoped_refptr<TaskQueue> task_queue_; - base::TimeDelta delay_; - base::RepeatingCallback<bool()> should_exit_; - base::SimpleTestTickClock* now_src_; + TimeDelta delay_; + RepeatingCallback<bool()> should_exit_; + scoped_refptr<TestMockTimeTaskRunner> test_task_runner_; }; class LinearTask { public: LinearTask(scoped_refptr<TaskQueue> task_queue, - base::TimeDelta delay, - base::SimpleTestTickClock* now_src) - : count_(0), task_queue_(task_queue), delay_(delay), now_src_(now_src) {} - - void SetShouldExit(base::RepeatingCallback<bool()> should_exit) { + TimeDelta delay, + scoped_refptr<TestMockTimeTaskRunner> test_task_runner) + : count_(0), + task_queue_(task_queue), + delay_(delay), + test_task_runner_(test_task_runner) {} + + void SetShouldExit(RepeatingCallback<bool()> should_exit) { should_exit_ = should_exit; } @@ -2100,9 +2054,8 @@ class LinearTask { return; count_++; task_queue_->PostDelayedTask( - FROM_HERE, base::BindOnce(&LinearTask::Run, base::Unretained(this)), - delay_); - now_src_->Advance(base::TimeDelta::FromMilliseconds(5)); + FROM_HERE, BindOnce(&LinearTask::Run, Unretained(this)), delay_); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(5)); } int Count() const { return count_; } @@ -2110,9 +2063,9 @@ class LinearTask { private: int count_; scoped_refptr<TaskQueue> task_queue_; - base::TimeDelta delay_; - base::RepeatingCallback<bool()> should_exit_; - base::SimpleTestTickClock* now_src_; + TimeDelta delay_; + RepeatingCallback<bool()> should_exit_; + scoped_refptr<TestMockTimeTaskRunner> test_task_runner_; }; bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) { @@ -2123,12 +2076,12 @@ bool ShouldExit(QuadraticTask* quadratic_task, LinearTask* linear_task) { TEST_F(TaskQueueManagerTest, DelayedTasksDontBadlyStarveNonDelayedWork_SameQueue) { - Initialize(1u); + CreateTaskQueues(1u); QuadraticTask quadratic_delayed_task( - runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_); - LinearTask linear_immediate_task(runners_[0], base::TimeDelta(), &now_src_); - base::RepeatingCallback<bool()> should_exit = base::BindRepeating( + runners_[0], TimeDelta::FromMilliseconds(10), test_task_runner_); + LinearTask linear_immediate_task(runners_[0], TimeDelta(), test_task_runner_); + RepeatingCallback<bool()> should_exit = BindRepeating( ShouldExit, &quadratic_delayed_task, &linear_immediate_task); quadratic_delayed_task.SetShouldExit(should_exit); linear_immediate_task.SetShouldExit(should_exit); @@ -2136,8 +2089,7 @@ TEST_F(TaskQueueManagerTest, quadratic_delayed_task.Run(); linear_immediate_task.Run(); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); double ratio = static_cast<double>(linear_immediate_task.Count()) / static_cast<double>(quadratic_delayed_task.Count()); @@ -2147,13 +2099,13 @@ TEST_F(TaskQueueManagerTest, } TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) { - Initialize(1u); + CreateTaskQueues(1u); - QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), - &now_src_); - LinearTask linear_delayed_task( - runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_); - base::RepeatingCallback<bool()> should_exit = base::BindRepeating( + QuadraticTask quadratic_immediate_task(runners_[0], TimeDelta(), + test_task_runner_); + LinearTask linear_delayed_task(runners_[0], TimeDelta::FromMilliseconds(10), + test_task_runner_); + RepeatingCallback<bool()> should_exit = BindRepeating( &ShouldExit, &quadratic_immediate_task, &linear_delayed_task); quadratic_immediate_task.SetShouldExit(should_exit); @@ -2162,8 +2114,7 @@ TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) { quadratic_immediate_task.Run(); linear_delayed_task.Run(); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); double ratio = static_cast<double>(linear_delayed_task.Count()) / static_cast<double>(quadratic_immediate_task.Count()); @@ -2176,12 +2127,12 @@ TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_SameQueue) { TEST_F(TaskQueueManagerTest, DelayedTasksDontBadlyStarveNonDelayedWork_DifferentQueue) { - Initialize(2u); + CreateTaskQueues(2u); QuadraticTask quadratic_delayed_task( - runners_[0], base::TimeDelta::FromMilliseconds(10), &now_src_); - LinearTask linear_immediate_task(runners_[1], base::TimeDelta(), &now_src_); - base::RepeatingCallback<bool()> should_exit = base::BindRepeating( + runners_[0], TimeDelta::FromMilliseconds(10), test_task_runner_); + LinearTask linear_immediate_task(runners_[1], TimeDelta(), test_task_runner_); + RepeatingCallback<bool()> should_exit = BindRepeating( ShouldExit, &quadratic_delayed_task, &linear_immediate_task); quadratic_delayed_task.SetShouldExit(should_exit); linear_immediate_task.SetShouldExit(should_exit); @@ -2189,8 +2140,7 @@ TEST_F(TaskQueueManagerTest, quadratic_delayed_task.Run(); linear_immediate_task.Run(); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); double ratio = static_cast<double>(linear_immediate_task.Count()) / static_cast<double>(quadratic_delayed_task.Count()); @@ -2201,13 +2151,13 @@ TEST_F(TaskQueueManagerTest, TEST_F(TaskQueueManagerTest, ImmediateWorkCanStarveDelayedTasks_DifferentQueue) { - Initialize(2u); + CreateTaskQueues(2u); - QuadraticTask quadratic_immediate_task(runners_[0], base::TimeDelta(), - &now_src_); - LinearTask linear_delayed_task( - runners_[1], base::TimeDelta::FromMilliseconds(10), &now_src_); - base::RepeatingCallback<bool()> should_exit = base::BindRepeating( + QuadraticTask quadratic_immediate_task(runners_[0], TimeDelta(), + test_task_runner_); + LinearTask linear_delayed_task(runners_[1], TimeDelta::FromMilliseconds(10), + test_task_runner_); + RepeatingCallback<bool()> should_exit = BindRepeating( &ShouldExit, &quadratic_immediate_task, &linear_delayed_task); quadratic_immediate_task.SetShouldExit(should_exit); @@ -2216,8 +2166,7 @@ TEST_F(TaskQueueManagerTest, quadratic_immediate_task.Run(); linear_delayed_task.Run(); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); double ratio = static_cast<double>(linear_delayed_task.Count()) / static_cast<double>(quadratic_immediate_task.Count()); @@ -2229,7 +2178,7 @@ TEST_F(TaskQueueManagerTest, } TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NoTaskRunning) { - Initialize(1u); + CreateTaskQueues(1u); EXPECT_EQ(nullptr, manager_->currently_executing_task_queue()); } @@ -2243,19 +2192,17 @@ void CurrentlyExecutingTaskQueueTestTask( } // namespace TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) { - Initialize(2u); + CreateTaskQueues(2u); TestTaskQueue* queue0 = runners_[0].get(); TestTaskQueue* queue1 = runners_[1].get(); std::vector<internal::TaskQueueImpl*> task_sources; - queue0->PostTask(FROM_HERE, - base::BindOnce(&CurrentlyExecutingTaskQueueTestTask, - manager_.get(), &task_sources)); - queue1->PostTask(FROM_HERE, - base::BindOnce(&CurrentlyExecutingTaskQueueTestTask, - manager_.get(), &task_sources)); - test_task_runner_->RunUntilIdle(); + queue0->PostTask(FROM_HERE, BindOnce(&CurrentlyExecutingTaskQueueTestTask, + manager_.get(), &task_sources)); + queue1->PostTask(FROM_HERE, BindOnce(&CurrentlyExecutingTaskQueueTestTask, + manager_.get(), &task_sources)); + RunLoop().RunUntilIdle(); EXPECT_THAT(task_sources, ElementsAre(queue0->GetTaskQueueImpl(), queue1->GetTaskQueueImpl())); @@ -2264,48 +2211,46 @@ TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_TaskRunning) { namespace { void RunloopCurrentlyExecutingTaskQueueTestTask( - base::MessageLoop* message_loop, TaskQueueManagerImpl* task_queue_manager, std::vector<internal::TaskQueueImpl*>* task_sources, - std::vector<std::pair<base::OnceClosure, TestTaskQueue*>>* tasks) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); + std::vector<std::pair<OnceClosure, TestTaskQueue*>>* tasks) { task_sources->push_back(task_queue_manager->currently_executing_task_queue()); - for (std::pair<base::OnceClosure, TestTaskQueue*>& pair : *tasks) { + for (std::pair<OnceClosure, TestTaskQueue*>& pair : *tasks) { pair.second->PostTask(FROM_HERE, std::move(pair.first)); } - base::RunLoop().RunUntilIdle(); + RunLoop(RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); task_sources->push_back(task_queue_manager->currently_executing_task_queue()); } } // namespace -TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NestedLoop) { - InitializeWithRealMessageLoop(3u); +TEST_F(TaskQueueManagerTestWithMessageLoop, + CurrentlyExecutingTaskQueue_NestedLoop) { + CreateTaskQueues(3u); TestTaskQueue* queue0 = runners_[0].get(); TestTaskQueue* queue1 = runners_[1].get(); TestTaskQueue* queue2 = runners_[2].get(); std::vector<internal::TaskQueueImpl*> task_sources; - std::vector<std::pair<base::OnceClosure, TestTaskQueue*>> + std::vector<std::pair<OnceClosure, TestTaskQueue*>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&CurrentlyExecutingTaskQueueTestTask, - manager_.get(), &task_sources), + std::make_pair(BindOnce(&CurrentlyExecutingTaskQueueTestTask, + manager_.get(), &task_sources), queue1)); tasks_to_post_from_nested_loop.push_back( - std::make_pair(base::BindOnce(&CurrentlyExecutingTaskQueueTestTask, - manager_.get(), &task_sources), + std::make_pair(BindOnce(&CurrentlyExecutingTaskQueueTestTask, + manager_.get(), &task_sources), queue2)); queue0->PostTask( FROM_HERE, - base::BindOnce(&RunloopCurrentlyExecutingTaskQueueTestTask, - message_loop_.get(), manager_.get(), &task_sources, - &tasks_to_post_from_nested_loop)); + BindOnce(&RunloopCurrentlyExecutingTaskQueueTestTask, manager_.get(), + &task_sources, &tasks_to_post_from_nested_loop)); - base::RunLoop().RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT( task_sources, ElementsAre(queue0->GetTaskQueueImpl(), queue1->GetTaskQueueImpl(), @@ -2313,20 +2258,20 @@ TEST_F(TaskQueueManagerTest, CurrentlyExecutingTaskQueue_NestedLoop) { EXPECT_EQ(nullptr, manager_->currently_executing_task_queue()); } -TEST_F(TaskQueueManagerTest, BlameContextAttribution) { +TEST_F(TaskQueueManagerTestWithMessageLoop, BlameContextAttribution) { using trace_analyzer::Query; - InitializeWithRealMessageLoop(1u); + CreateTaskQueues(1u); TestTaskQueue* queue = runners_[0].get(); trace_analyzer::Start("*"); { - base::trace_event::BlameContext blame_context("cat", "name", "type", - "scope", 0, nullptr); + trace_event::BlameContext blame_context("cat", "name", "type", "scope", 0, + nullptr); blame_context.Initialize(); queue->SetBlameContext(&blame_context); - queue->PostTask(FROM_HERE, base::BindOnce(&NopTask)); - base::RunLoop().RunUntilIdle(); + queue->PostTask(FROM_HERE, BindOnce(&NopTask)); + RunLoop().RunUntilIdle(); } auto analyzer = trace_analyzer::Stop(); @@ -2339,51 +2284,50 @@ TEST_F(TaskQueueManagerTest, BlameContextAttribution) { } TEST_F(TaskQueueManagerTest, NoWakeUpsForCanceledDelayedTasks) { - Initialize(1u); - - base::TimeTicks start_time = manager_->NowTicks(); - - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - CancelableTask task3(&now_src_); - CancelableTask task4(&now_src_); - base::TimeDelta delay1(base::TimeDelta::FromSeconds(5)); - base::TimeDelta delay2(base::TimeDelta::FromSeconds(10)); - base::TimeDelta delay3(base::TimeDelta::FromSeconds(15)); - base::TimeDelta delay4(base::TimeDelta::FromSeconds(30)); - std::vector<base::TimeTicks> run_times; + CreateTaskQueues(1u); + + TimeTicks start_time = manager_->NowTicks(); + + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + CancelableTask task3(GetTickClock()); + CancelableTask task4(GetTickClock()); + TimeDelta delay1(TimeDelta::FromSeconds(5)); + TimeDelta delay2(TimeDelta::FromSeconds(10)); + TimeDelta delay3(TimeDelta::FromSeconds(15)); + TimeDelta delay4(TimeDelta::FromSeconds(30)); + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times), delay1); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times), delay2); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task3.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task3.weak_factory_.GetWeakPtr(), &run_times), delay3); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task4.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task4.weak_factory_.GetWeakPtr(), &run_times), delay4); task2.weak_factory_.InvalidateWeakPtrs(); task3.weak_factory_.InvalidateWeakPtrs(); - std::set<base::TimeTicks> wake_up_times; + std::set<TimeTicks> wake_up_times; - RunUntilIdle(base::BindRepeating( - [](std::set<base::TimeTicks>* wake_up_times, - base::SimpleTestTickClock* clock) { + RunUntilManagerIsIdle(BindRepeating( + [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) { wake_up_times->insert(clock->NowTicks()); }, - &wake_up_times, &now_src_)); + &wake_up_times, GetTickClock())); EXPECT_THAT(wake_up_times, ElementsAre(start_time + delay1, start_time + delay4)); @@ -2391,51 +2335,50 @@ TEST_F(TaskQueueManagerTest, NoWakeUpsForCanceledDelayedTasks) { } TEST_F(TaskQueueManagerTest, NoWakeUpsForCanceledDelayedTasksReversePostOrder) { - Initialize(1u); - - base::TimeTicks start_time = manager_->NowTicks(); - - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - CancelableTask task3(&now_src_); - CancelableTask task4(&now_src_); - base::TimeDelta delay1(base::TimeDelta::FromSeconds(5)); - base::TimeDelta delay2(base::TimeDelta::FromSeconds(10)); - base::TimeDelta delay3(base::TimeDelta::FromSeconds(15)); - base::TimeDelta delay4(base::TimeDelta::FromSeconds(30)); - std::vector<base::TimeTicks> run_times; + CreateTaskQueues(1u); + + TimeTicks start_time = manager_->NowTicks(); + + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + CancelableTask task3(GetTickClock()); + CancelableTask task4(GetTickClock()); + TimeDelta delay1(TimeDelta::FromSeconds(5)); + TimeDelta delay2(TimeDelta::FromSeconds(10)); + TimeDelta delay3(TimeDelta::FromSeconds(15)); + TimeDelta delay4(TimeDelta::FromSeconds(30)); + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task4.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task4.weak_factory_.GetWeakPtr(), &run_times), delay4); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task3.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task3.weak_factory_.GetWeakPtr(), &run_times), delay3); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times), delay2); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times), delay1); task2.weak_factory_.InvalidateWeakPtrs(); task3.weak_factory_.InvalidateWeakPtrs(); - std::set<base::TimeTicks> wake_up_times; + std::set<TimeTicks> wake_up_times; - RunUntilIdle(base::BindRepeating( - [](std::set<base::TimeTicks>* wake_up_times, - base::SimpleTestTickClock* clock) { + RunUntilManagerIsIdle(BindRepeating( + [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) { wake_up_times->insert(clock->NowTicks()); }, - &wake_up_times, &now_src_)); + &wake_up_times, GetTickClock())); EXPECT_THAT(wake_up_times, ElementsAre(start_time + delay1, start_time + delay4)); @@ -2443,60 +2386,58 @@ TEST_F(TaskQueueManagerTest, NoWakeUpsForCanceledDelayedTasksReversePostOrder) { } TEST_F(TaskQueueManagerTest, TimeDomainWakeUpOnlyCancelledIfAllUsesCancelled) { - Initialize(1u); - - base::TimeTicks start_time = manager_->NowTicks(); - - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - CancelableTask task3(&now_src_); - CancelableTask task4(&now_src_); - base::TimeDelta delay1(base::TimeDelta::FromSeconds(5)); - base::TimeDelta delay2(base::TimeDelta::FromSeconds(10)); - base::TimeDelta delay3(base::TimeDelta::FromSeconds(15)); - base::TimeDelta delay4(base::TimeDelta::FromSeconds(30)); - std::vector<base::TimeTicks> run_times; + CreateTaskQueues(1u); + + TimeTicks start_time = manager_->NowTicks(); + + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + CancelableTask task3(GetTickClock()); + CancelableTask task4(GetTickClock()); + TimeDelta delay1(TimeDelta::FromSeconds(5)); + TimeDelta delay2(TimeDelta::FromSeconds(10)); + TimeDelta delay3(TimeDelta::FromSeconds(15)); + TimeDelta delay4(TimeDelta::FromSeconds(30)); + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times), delay1); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times), delay2); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task3.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task3.weak_factory_.GetWeakPtr(), &run_times), delay3); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task4.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task4.weak_factory_.GetWeakPtr(), &run_times), delay4); // Post a non-canceled task with |delay3|. So we should still get a wake-up at // |delay3| even though we cancel |task3|. runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, base::Unretained(&task3), - &run_times), + BindOnce(&CancelableTask::RecordTimeTask, Unretained(&task3), &run_times), delay3); task2.weak_factory_.InvalidateWeakPtrs(); task3.weak_factory_.InvalidateWeakPtrs(); task1.weak_factory_.InvalidateWeakPtrs(); - std::set<base::TimeTicks> wake_up_times; + std::set<TimeTicks> wake_up_times; - RunUntilIdle(base::BindRepeating( - [](std::set<base::TimeTicks>* wake_up_times, - base::SimpleTestTickClock* clock) { + RunUntilManagerIsIdle(BindRepeating( + [](std::set<TimeTicks>* wake_up_times, const TickClock* clock) { wake_up_times->insert(clock->NowTicks()); }, - &wake_up_times, &now_src_)); + &wake_up_times, GetTickClock())); EXPECT_THAT(wake_up_times, ElementsAre(start_time + delay1, start_time + delay3, @@ -2506,7 +2447,7 @@ TEST_F(TaskQueueManagerTest, TimeDomainWakeUpOnlyCancelledIfAllUsesCancelled) { } TEST_F(TaskQueueManagerTest, TaskQueueVoters) { - Initialize(1u); + CreateTaskQueues(1u); // The task queue should be initially enabled. EXPECT_TRUE(runners_[0]->IsQueueEnabled()); @@ -2552,7 +2493,7 @@ TEST_F(TaskQueueManagerTest, TaskQueueVoters) { } TEST_F(TaskQueueManagerTest, ShutdownQueueBeforeEnabledVoterDeleted) { - Initialize(1u); + CreateTaskQueues(1u); scoped_refptr<TaskQueue> queue = CreateTaskQueue(); @@ -2567,7 +2508,7 @@ TEST_F(TaskQueueManagerTest, ShutdownQueueBeforeEnabledVoterDeleted) { } TEST_F(TaskQueueManagerTest, ShutdownQueueBeforeDisabledVoterDeleted) { - Initialize(1u); + CreateTaskQueues(1u); scoped_refptr<TaskQueue> queue = CreateTaskQueue(); @@ -2582,36 +2523,36 @@ TEST_F(TaskQueueManagerTest, ShutdownQueueBeforeDisabledVoterDeleted) { } TEST_F(TaskQueueManagerTest, SweepCanceledDelayedTasks) { - Initialize(1u); - - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - CancelableTask task3(&now_src_); - CancelableTask task4(&now_src_); - base::TimeDelta delay1(base::TimeDelta::FromSeconds(5)); - base::TimeDelta delay2(base::TimeDelta::FromSeconds(10)); - base::TimeDelta delay3(base::TimeDelta::FromSeconds(15)); - base::TimeDelta delay4(base::TimeDelta::FromSeconds(30)); - std::vector<base::TimeTicks> run_times; + CreateTaskQueues(1u); + + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + CancelableTask task3(GetTickClock()); + CancelableTask task4(GetTickClock()); + TimeDelta delay1(TimeDelta::FromSeconds(5)); + TimeDelta delay2(TimeDelta::FromSeconds(10)); + TimeDelta delay3(TimeDelta::FromSeconds(15)); + TimeDelta delay4(TimeDelta::FromSeconds(30)); + std::vector<TimeTicks> run_times; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times), delay1); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times), delay2); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task3.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task3.weak_factory_.GetWeakPtr(), &run_times), delay3); runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&CancelableTask::RecordTimeTask, - task4.weak_factory_.GetWeakPtr(), &run_times), + BindOnce(&CancelableTask::RecordTimeTask, + task4.weak_factory_.GetWeakPtr(), &run_times), delay4); EXPECT_EQ(4u, runners_[0]->GetNumberOfPendingTasks()); @@ -2630,136 +2571,128 @@ TEST_F(TaskQueueManagerTest, SweepCanceledDelayedTasks) { } TEST_F(TaskQueueManagerTest, DelayTillNextTask) { - Initialize(2u); + CreateTaskQueues(2u); - LazyNow lazy_now(&now_src_); - EXPECT_EQ(base::TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); + LazyNow lazy_now(GetTickClock()); + EXPECT_EQ(TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromSeconds(10)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromSeconds(10)); - EXPECT_EQ(base::TimeDelta::FromSeconds(10), - manager_->DelayTillNextTask(&lazy_now)); + EXPECT_EQ(TimeDelta::FromSeconds(10), manager_->DelayTillNextTask(&lazy_now)); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromSeconds(15)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromSeconds(15)); - EXPECT_EQ(base::TimeDelta::FromSeconds(10), - manager_->DelayTillNextTask(&lazy_now)); + EXPECT_EQ(TimeDelta::FromSeconds(10), manager_->DelayTillNextTask(&lazy_now)); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromSeconds(5)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromSeconds(5)); - EXPECT_EQ(base::TimeDelta::FromSeconds(5), - manager_->DelayTillNextTask(&lazy_now)); + EXPECT_EQ(TimeDelta::FromSeconds(5), manager_->DelayTillNextTask(&lazy_now)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); - EXPECT_EQ(base::TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); + EXPECT_EQ(TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); } TEST_F(TaskQueueManagerTest, DelayTillNextTask_Disabled) { - Initialize(1u); + CreateTaskQueues(1u); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); - LazyNow lazy_now(&now_src_); - EXPECT_EQ(base::TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); + LazyNow lazy_now(GetTickClock()); + EXPECT_EQ(TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); } TEST_F(TaskQueueManagerTest, DelayTillNextTask_Fence) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); - LazyNow lazy_now(&now_src_); - EXPECT_EQ(base::TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); + LazyNow lazy_now(GetTickClock()); + EXPECT_EQ(TimeDelta::Max(), manager_->DelayTillNextTask(&lazy_now)); } TEST_F(TaskQueueManagerTest, DelayTillNextTask_FenceUnblocking) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - LazyNow lazy_now(&now_src_); - EXPECT_EQ(base::TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); + LazyNow lazy_now(GetTickClock()); + EXPECT_EQ(TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); } TEST_F(TaskQueueManagerTest, DelayTillNextTask_DelayedTaskReady) { - Initialize(1u); + CreateTaskQueues(1u); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromSeconds(1)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromSeconds(1)); - now_src_.Advance(base::TimeDelta::FromSeconds(10)); + test_task_runner_->AdvanceMockTickClock(TimeDelta::FromSeconds(10)); - LazyNow lazy_now(&now_src_); - EXPECT_EQ(base::TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); + LazyNow lazy_now(GetTickClock()); + EXPECT_EQ(TimeDelta(), manager_->DelayTillNextTask(&lazy_now)); } namespace { -void MessageLoopTaskWithDelayedQuit(base::MessageLoop* message_loop, - base::SimpleTestTickClock* now_src, +void MessageLoopTaskWithDelayedQuit(SimpleTestTickClock* now_src, scoped_refptr<TaskQueue> task_queue) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); - base::RunLoop run_loop; + RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed); task_queue->PostDelayedTask(FROM_HERE, run_loop.QuitClosure(), - base::TimeDelta::FromMilliseconds(100)); - now_src->Advance(base::TimeDelta::FromMilliseconds(200)); + TimeDelta::FromMilliseconds(100)); + now_src->Advance(TimeDelta::FromMilliseconds(200)); run_loop.Run(); } } // namespace -TEST_F(TaskQueueManagerTest, DelayedTaskRunsInNestedMessageLoop) { - InitializeWithRealMessageLoop(1u); - base::RunLoop run_loop; - runners_[0]->PostTask( - FROM_HERE, - base::BindOnce(&MessageLoopTaskWithDelayedQuit, message_loop_.get(), - &now_src_, base::RetainedRef(runners_[0]))); +TEST_F(TaskQueueManagerTestWithMessageLoop, + DelayedTaskRunsInNestedMessageLoop) { + CreateTaskQueues(1u); + RunLoop run_loop; + runners_[0]->PostTask(FROM_HERE, + BindOnce(&MessageLoopTaskWithDelayedQuit, &mock_clock_, + RetainedRef(runners_[0]))); run_loop.RunUntilIdle(); } namespace { -void MessageLoopTaskWithImmediateQuit(base::MessageLoop* message_loop, - base::OnceClosure non_nested_quit_closure, +void MessageLoopTaskWithImmediateQuit(OnceClosure non_nested_quit_closure, scoped_refptr<TaskQueue> task_queue) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop); - - base::RunLoop run_loop; + RunLoop run_loop(RunLoop::Type::kNestableTasksAllowed); // Needed because entering the nested run loop causes a DoWork to get // posted. - task_queue->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + task_queue->PostTask(FROM_HERE, BindOnce(&NopTask)); task_queue->PostTask(FROM_HERE, run_loop.QuitClosure()); run_loop.Run(); std::move(non_nested_quit_closure).Run(); } } // namespace -TEST_F(TaskQueueManagerTest, +TEST_F(TaskQueueManagerTestWithMessageLoop, DelayedNestedMessageLoopDoesntPreventTasksRunning) { - InitializeWithRealMessageLoop(1u); - base::RunLoop run_loop; + CreateTaskQueues(1u); + RunLoop run_loop; runners_[0]->PostDelayedTask( FROM_HERE, - base::BindOnce(&MessageLoopTaskWithImmediateQuit, message_loop_.get(), - run_loop.QuitClosure(), base::RetainedRef(runners_[0])), - base::TimeDelta::FromMilliseconds(100)); + BindOnce(&MessageLoopTaskWithImmediateQuit, run_loop.QuitClosure(), + RetainedRef(runners_[0])), + TimeDelta::FromMilliseconds(100)); - now_src_.Advance(base::TimeDelta::FromMilliseconds(200)); + mock_clock_.Advance(TimeDelta::FromMilliseconds(200)); run_loop.Run(); } TEST_F(TaskQueueManagerTest, CouldTaskRun_DisableAndReenable) { - Initialize(1u); + CreateTaskQueues(1u); - EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EnqueueOrder enqueue_order = manager_->GetNextSequenceNumber(); EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = @@ -2772,9 +2705,9 @@ TEST_F(TaskQueueManagerTest, CouldTaskRun_DisableAndReenable) { } TEST_F(TaskQueueManagerTest, CouldTaskRun_Fence) { - Initialize(1u); + CreateTaskQueues(1u); - EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EnqueueOrder enqueue_order = manager_->GetNextSequenceNumber(); EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); @@ -2788,11 +2721,11 @@ TEST_F(TaskQueueManagerTest, CouldTaskRun_Fence) { } TEST_F(TaskQueueManagerTest, CouldTaskRun_FenceBeforeThenAfter) { - Initialize(1u); + CreateTaskQueues(1u); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); - EnqueueOrder enqueue_order = GetNextSequenceNumber(); + EnqueueOrder enqueue_order = manager_->GetNextSequenceNumber(); EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->CouldTaskRun(enqueue_order)); runners_[0]->InsertFence(TaskQueue::InsertFencePosition::kNow); @@ -2800,36 +2733,33 @@ TEST_F(TaskQueueManagerTest, CouldTaskRun_FenceBeforeThenAfter) { } TEST_F(TaskQueueManagerTest, DelayedDoWorkNotPostedForDisabledQueue) { - Initialize(1u); + CreateTaskQueues(1u); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(1)); - ASSERT_TRUE(test_task_runner_->HasPendingTasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), - test_task_runner_->DelayToNextTaskTime()); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(1)); + ASSERT_TRUE(test_task_runner_->HasPendingTask()); + EXPECT_EQ(TimeDelta::FromMilliseconds(1), + test_task_runner_->NextPendingTaskDelay()); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - - EXPECT_TRUE(test_task_runner_->HasPendingTasks()); - test_task_runner_->RemoveCancelledTasks(); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); voter->SetQueueEnabled(true); - ASSERT_TRUE(test_task_runner_->HasPendingTasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), - test_task_runner_->DelayToNextTaskTime()); + ASSERT_TRUE(test_task_runner_->HasPendingTask()); + EXPECT_EQ(TimeDelta::FromMilliseconds(1), + test_task_runner_->NextPendingTaskDelay()); } TEST_F(TaskQueueManagerTest, DisablingQueuesChangesDelayTillNextDoWork) { - Initialize(3u); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(1)); - runners_[1]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(10)); - runners_[2]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(100)); + CreateTaskQueues(3u); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(1)); + runners_[1]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(10)); + runners_[2]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(100)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter0 = runners_[0]->CreateQueueEnabledVoter(); @@ -2838,53 +2768,50 @@ TEST_F(TaskQueueManagerTest, DisablingQueuesChangesDelayTillNextDoWork) { std::unique_ptr<TaskQueue::QueueEnabledVoter> voter2 = runners_[2]->CreateQueueEnabledVoter(); - ASSERT_TRUE(test_task_runner_->HasPendingTasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(1), - test_task_runner_->DelayToNextTaskTime()); + ASSERT_TRUE(test_task_runner_->HasPendingTask()); + EXPECT_EQ(TimeDelta::FromMilliseconds(1), + test_task_runner_->NextPendingTaskDelay()); voter0->SetQueueEnabled(false); - test_task_runner_->RemoveCancelledTasks(); - ASSERT_TRUE(test_task_runner_->HasPendingTasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(10), - test_task_runner_->DelayToNextTaskTime()); + ASSERT_TRUE(test_task_runner_->HasPendingTask()); + EXPECT_EQ(TimeDelta::FromMilliseconds(10), + test_task_runner_->NextPendingTaskDelay()); voter1->SetQueueEnabled(false); - test_task_runner_->RemoveCancelledTasks(); - ASSERT_TRUE(test_task_runner_->HasPendingTasks()); - EXPECT_EQ(base::TimeDelta::FromMilliseconds(100), - test_task_runner_->DelayToNextTaskTime()); + ASSERT_TRUE(test_task_runner_->HasPendingTask()); + EXPECT_EQ(TimeDelta::FromMilliseconds(100), + test_task_runner_->NextPendingTaskDelay()); voter2->SetQueueEnabled(false); - test_task_runner_->RemoveCancelledTasks(); - EXPECT_FALSE(test_task_runner_->HasPendingTasks()); + EXPECT_FALSE(test_task_runner_->HasPendingTask()); } TEST_F(TaskQueueManagerTest, GetNextScheduledWakeUp) { - Initialize(1u); + CreateTaskQueues(1u); - EXPECT_EQ(base::nullopt, runners_[0]->GetNextScheduledWakeUp()); + EXPECT_EQ(nullopt, runners_[0]->GetNextScheduledWakeUp()); - base::TimeTicks start_time = manager_->NowTicks(); - base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); - base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(2); + TimeTicks start_time = manager_->NowTicks(); + TimeDelta delay1 = TimeDelta::FromMilliseconds(10); + TimeDelta delay2 = TimeDelta::FromMilliseconds(2); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay1); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay1); EXPECT_EQ(start_time + delay1, runners_[0]->GetNextScheduledWakeUp()); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), delay2); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), delay2); EXPECT_EQ(start_time + delay2, runners_[0]->GetNextScheduledWakeUp()); // We don't have wake-ups scheduled for disabled queues. std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); voter->SetQueueEnabled(false); - EXPECT_EQ(base::nullopt, runners_[0]->GetNextScheduledWakeUp()); + EXPECT_EQ(nullopt, runners_[0]->GetNextScheduledWakeUp()); voter->SetQueueEnabled(true); EXPECT_EQ(start_time + delay2, runners_[0]->GetNextScheduledWakeUp()); // Immediate tasks shouldn't make any difference. - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&NopTask)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&NopTask)); EXPECT_EQ(start_time + delay2, runners_[0]->GetNextScheduledWakeUp()); // Neither should fences. @@ -2893,13 +2820,13 @@ TEST_F(TaskQueueManagerTest, GetNextScheduledWakeUp) { } TEST_F(TaskQueueManagerTest, SetTimeDomainForDisabledQueue) { - Initialize(1u); + CreateTaskQueues(1u); MockTaskQueueObserver observer; runners_[0]->SetObserver(&observer); - runners_[0]->PostDelayedTask(FROM_HERE, base::BindOnce(&NopTask), - base::TimeDelta::FromMilliseconds(1)); + runners_[0]->PostDelayedTask(FROM_HERE, BindOnce(&NopTask), + TimeDelta::FromMilliseconds(1)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter = runners_[0]->CreateQueueEnabledVoter(); @@ -2923,55 +2850,55 @@ void SetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue, int* start_counter, int* complete_counter) { task_queue->GetTaskQueueImpl()->SetOnTaskStartedHandler( - base::BindRepeating([](int* counter, const TaskQueue::Task& task, - base::TimeTicks start) { ++(*counter); }, - start_counter)); - task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::BindRepeating( - [](int* counter, const TaskQueue::Task& task, base::TimeTicks start, - base::TimeTicks end, - base::Optional<base::TimeDelta> thread_time) { ++(*counter); }, + BindRepeating([](int* counter, const TaskQueue::Task& task, + TimeTicks start) { ++(*counter); }, + start_counter)); + task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler(BindRepeating( + [](int* counter, const TaskQueue::Task& task, TimeTicks start, + TimeTicks end, Optional<TimeDelta> thread_time) { ++(*counter); }, complete_counter)); } void UnsetOnTaskHandlers(scoped_refptr<TestTaskQueue> task_queue) { task_queue->GetTaskQueueImpl()->SetOnTaskStartedHandler( - base::RepeatingCallback<void(const TaskQueue::Task& task, - base::TimeTicks start)>()); + RepeatingCallback<void(const TaskQueue::Task& task, TimeTicks start)>()); task_queue->GetTaskQueueImpl()->SetOnTaskCompletedHandler( - base::RepeatingCallback<void( - const TaskQueue::Task& task, base::TimeTicks start, - base::TimeTicks end, base::Optional<base::TimeDelta> thread_time)>()); + RepeatingCallback<void(const TaskQueue::Task& task, TimeTicks start, + TimeTicks end, + Optional<TimeDelta> thread_time)>()); } } // namespace TEST_F(TaskQueueManagerTest, ProcessTasksWithoutTaskTimeObservers) { - Initialize(1u); + CreateTaskQueues(1u); int start_counter = 0; int complete_counter = 0; std::vector<EnqueueOrder> run_order; SetOnTaskHandlers(runners_[0], &start_counter, &complete_counter); EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 3); EXPECT_EQ(complete_counter, 3); EXPECT_THAT(run_order, ElementsAre(1, 2, 3)); UnsetOnTaskHandlers(runners_[0]); EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 5, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 6, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 3); EXPECT_EQ(complete_counter, 3); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6)); } TEST_F(TaskQueueManagerTest, ProcessTasksWithTaskTimeObservers) { - Initialize(1u); + CreateTaskQueues(1u); int start_counter = 0; int complete_counter = 0; @@ -2979,35 +2906,39 @@ TEST_F(TaskQueueManagerTest, ProcessTasksWithTaskTimeObservers) { SetOnTaskHandlers(runners_[0], &start_counter, &complete_counter); EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 2); EXPECT_EQ(complete_counter, 2); EXPECT_THAT(run_order, ElementsAre(1, 2)); UnsetOnTaskHandlers(runners_[0]); EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 3, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 4, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 3, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 4, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 2); EXPECT_EQ(complete_counter, 2); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4)); manager_->RemoveTaskTimeObserver(&test_task_time_observer_); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 5, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 6, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 5, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 6, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 2); EXPECT_EQ(complete_counter, 2); EXPECT_FALSE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); EXPECT_THAT(run_order, ElementsAre(1, 2, 3, 4, 5, 6)); SetOnTaskHandlers(runners_[0], &start_counter, &complete_counter); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 7, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 8, &run_order)); - test_task_runner_->RunUntilIdle(); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 7, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 8, &run_order)); + + RunLoop().RunUntilIdle(); EXPECT_EQ(start_counter, 4); EXPECT_EQ(complete_counter, 4); EXPECT_TRUE(runners_[0]->GetTaskQueueImpl()->RequiresTaskTiming()); @@ -3016,12 +2947,9 @@ TEST_F(TaskQueueManagerTest, ProcessTasksWithTaskTimeObservers) { } TEST_F(TaskQueueManagerTest, GracefulShutdown) { - Initialize(0u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - - std::vector<base::TimeTicks> run_times; + std::vector<TimeTicks> run_times; scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); - base::WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr(); + WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr(); EXPECT_EQ(1u, manager_->ActiveQueuesCount()); EXPECT_EQ(0u, manager_->QueuesToShutdownCount()); @@ -3029,31 +2957,30 @@ TEST_F(TaskQueueManagerTest, GracefulShutdown) { for (int i = 1; i <= 5; ++i) { main_tq->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(i * 100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(i * 100)); } - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(250)); main_tq = nullptr; // Ensure that task queue went away. EXPECT_FALSE(main_tq_weak_ptr.get()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(1)); EXPECT_EQ(1u, manager_->ActiveQueuesCount()); EXPECT_EQ(1u, manager_->QueuesToShutdownCount()); EXPECT_EQ(0u, manager_->QueuesToDeleteCount()); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); // Even with TaskQueue gone, tasks are executed. - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(301), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(401), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(501))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200), + start_time_ + TimeDelta::FromMilliseconds(300), + start_time_ + TimeDelta::FromMilliseconds(400), + start_time_ + TimeDelta::FromMilliseconds(500))); EXPECT_EQ(0u, manager_->ActiveQueuesCount()); EXPECT_EQ(0u, manager_->QueuesToShutdownCount()); @@ -3061,13 +2988,10 @@ TEST_F(TaskQueueManagerTest, GracefulShutdown) { } TEST_F(TaskQueueManagerTest, GracefulShutdown_ManagerDeletedInFlight) { - Initialize(0u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - - std::vector<base::TimeTicks> run_times; + std::vector<TimeTicks> run_times; scoped_refptr<TestTaskQueue> control_tq = CreateTaskQueue(); std::vector<scoped_refptr<TestTaskQueue>> main_tqs; - std::vector<base::WeakPtr<TestTaskQueue>> main_tq_weak_ptrs; + std::vector<WeakPtr<TestTaskQueue>> main_tq_weak_ptrs; // There might be a race condition - async task queues should be unregistered // first. Increase the number of task queues to surely detect that. @@ -3084,10 +3008,10 @@ TEST_F(TaskQueueManagerTest, GracefulShutdown_ManagerDeletedInFlight) { for (int i = 1; i <= 5; ++i) { main_tqs[0]->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(i * 100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(i * 100)); } - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(250)); main_tqs.clear(); // Ensure that task queues went away. @@ -3100,22 +3024,18 @@ TEST_F(TaskQueueManagerTest, GracefulShutdown_ManagerDeletedInFlight) { // thread. manager_.reset(); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200))); } TEST_F(TaskQueueManagerTest, GracefulShutdown_ManagerDeletedWithQueuesToShutdown) { - Initialize(0u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - - std::vector<base::TimeTicks> run_times; + std::vector<TimeTicks> run_times; scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); - base::WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr(); + WeakPtr<TestTaskQueue> main_tq_weak_ptr = main_tq->GetWeakPtr(); EXPECT_EQ(1u, manager_->ActiveQueuesCount()); EXPECT_EQ(0u, manager_->QueuesToShutdownCount()); @@ -3123,16 +3043,16 @@ TEST_F(TaskQueueManagerTest, for (int i = 1; i <= 5; ++i) { main_tq->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(i * 100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(i * 100)); } - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(250)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(250)); main_tq = nullptr; // Ensure that task queue went away. EXPECT_FALSE(main_tq_weak_ptr.get()); - test_task_runner_->RunForPeriod(base::TimeDelta::FromMilliseconds(1)); + test_task_runner_->FastForwardBy(TimeDelta::FromMilliseconds(1)); EXPECT_EQ(1u, manager_->ActiveQueuesCount()); EXPECT_EQ(1u, manager_->QueuesToShutdownCount()); @@ -3141,20 +3061,19 @@ TEST_F(TaskQueueManagerTest, // Ensure that all queues-to-gracefully-shutdown are properly unregistered. manager_.reset(); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200))); } -TEST_F(TaskQueueManagerTest, DefaultTaskRunnerSupport) { - base::MessageLoop message_loop; - scoped_refptr<base::SingleThreadTaskRunner> original_task_runner = +TEST_F(TaskQueueManagerTestWithCustomInitialization, DefaultTaskRunnerSupport) { + MessageLoop message_loop; + scoped_refptr<SingleThreadTaskRunner> original_task_runner = message_loop.task_runner(); - scoped_refptr<base::SingleThreadTaskRunner> custom_task_runner = - base::MakeRefCounted<base::TestSimpleTaskRunner>(); + scoped_refptr<SingleThreadTaskRunner> custom_task_runner = + MakeRefCounted<TestSimpleTaskRunner>(); { std::unique_ptr<TaskQueueManagerForTest> manager = TaskQueueManagerForTest::Create(&message_loop, @@ -3166,36 +3085,33 @@ TEST_F(TaskQueueManagerTest, DefaultTaskRunnerSupport) { } TEST_F(TaskQueueManagerTest, CanceledTasksInQueueCantMakeOtherTasksSkipAhead) { - Initialize(2u); + CreateTaskQueues(2u); - CancelableTask task1(&now_src_); - CancelableTask task2(&now_src_); - std::vector<base::TimeTicks> run_times; + CancelableTask task1(GetTickClock()); + CancelableTask task2(GetTickClock()); + std::vector<TimeTicks> run_times; - runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&CancelableTask::RecordTimeTask, - task1.weak_factory_.GetWeakPtr(), &run_times)); - runners_[0]->PostTask( - FROM_HERE, base::BindOnce(&CancelableTask::RecordTimeTask, - task2.weak_factory_.GetWeakPtr(), &run_times)); + runners_[0]->PostTask(FROM_HERE, + BindOnce(&CancelableTask::RecordTimeTask, + task1.weak_factory_.GetWeakPtr(), &run_times)); + runners_[0]->PostTask(FROM_HERE, + BindOnce(&CancelableTask::RecordTimeTask, + task2.weak_factory_.GetWeakPtr(), &run_times)); std::vector<EnqueueOrder> run_order; - runners_[1]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 1, &run_order)); + runners_[1]->PostTask(FROM_HERE, BindOnce(&TestTask, 1, &run_order)); - runners_[0]->PostTask(FROM_HERE, base::BindOnce(&TestTask, 2, &run_order)); + runners_[0]->PostTask(FROM_HERE, BindOnce(&TestTask, 2, &run_order)); task1.weak_factory_.InvalidateWeakPtrs(); task2.weak_factory_.InvalidateWeakPtrs(); - test_task_runner_->RunUntilIdle(); + RunLoop().RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(1, 2)); } TEST_F(TaskQueueManagerTest, TaskQueueDeletedOnAnotherThread) { - Initialize(0u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - - std::vector<base::TimeTicks> run_times; + std::vector<TimeTicks> run_times; scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); int start_counter = 0; @@ -3208,25 +3124,23 @@ TEST_F(TaskQueueManagerTest, TaskQueueDeletedOnAnotherThread) { for (int i = 1; i <= 5; ++i) { main_tq->PostDelayedTask( - FROM_HERE, base::BindOnce(&RecordTimeTask, &run_times, &now_src_), - base::TimeDelta::FromMilliseconds(i * 100)); + FROM_HERE, BindOnce(&RecordTimeTask, &run_times, GetTickClock()), + TimeDelta::FromMilliseconds(i * 100)); } // TODO(altimin): do not do this after switching to weak pointer-based // task handlers. UnsetOnTaskHandlers(main_tq); - base::WaitableEvent task_queue_deleted( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - std::unique_ptr<base::Thread> thread = - std::make_unique<base::Thread>("test thread"); + WaitableEvent task_queue_deleted(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + std::unique_ptr<Thread> thread = std::make_unique<Thread>("test thread"); thread->StartAndWaitForTesting(); thread->task_runner()->PostTask( - FROM_HERE, base::BindOnce( - [](scoped_refptr<base::SingleThreadTaskRunner> task_queue, - base::WaitableEvent* task_queue_deleted) { + FROM_HERE, BindOnce( + [](scoped_refptr<SingleThreadTaskRunner> task_queue, + WaitableEvent* task_queue_deleted) { task_queue = nullptr; task_queue_deleted->Signal(); }, @@ -3237,16 +3151,15 @@ TEST_F(TaskQueueManagerTest, TaskQueueDeletedOnAnotherThread) { EXPECT_EQ(1u, manager_->QueuesToShutdownCount()); EXPECT_EQ(0u, manager_->QueuesToDeleteCount()); - test_task_runner_->RunUntilIdle(); + test_task_runner_->FastForwardUntilNoTasksRemain(); // Even with TaskQueue gone, tasks are executed. - EXPECT_THAT( - run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromMilliseconds(101), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(201), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(301), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(401), - base::TimeTicks() + base::TimeDelta::FromMilliseconds(501))); + EXPECT_THAT(run_times, + ElementsAre(start_time_ + TimeDelta::FromMilliseconds(100), + start_time_ + TimeDelta::FromMilliseconds(200), + start_time_ + TimeDelta::FromMilliseconds(300), + start_time_ + TimeDelta::FromMilliseconds(400), + start_time_ + TimeDelta::FromMilliseconds(500))); EXPECT_EQ(0u, manager_->ActiveQueuesCount()); EXPECT_EQ(0u, manager_->QueuesToShutdownCount()); @@ -3265,7 +3178,7 @@ class PostTaskInDestructor { : task_queue_(task_queue) {} ~PostTaskInDestructor() { - task_queue_->PostTask(FROM_HERE, base::BindOnce(&DoNothing)); + task_queue_->PostTask(FROM_HERE, BindOnce(&DoNothing)); } void Do() {} @@ -3279,27 +3192,22 @@ class PostTaskInDestructor { TEST_F(TaskQueueManagerTest, TaskQueueUsedInTaskDestructorAfterShutdown) { // This test checks that when a task is posted to a shutdown queue and // destroyed, it can try to post a task to the same queue without deadlocks. - Initialize(0u); - test_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - scoped_refptr<TestTaskQueue> main_tq = CreateTaskQueue(); - base::WaitableEvent test_executed( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - std::unique_ptr<base::Thread> thread = - std::make_unique<base::Thread>("test thread"); + WaitableEvent test_executed(WaitableEvent::ResetPolicy::MANUAL, + WaitableEvent::InitialState::NOT_SIGNALED); + std::unique_ptr<Thread> thread = std::make_unique<Thread>("test thread"); thread->StartAndWaitForTesting(); manager_.reset(); thread->task_runner()->PostTask( - FROM_HERE, base::BindOnce( - [](scoped_refptr<base::SingleThreadTaskRunner> task_queue, + FROM_HERE, BindOnce( + [](scoped_refptr<SingleThreadTaskRunner> task_queue, std::unique_ptr<PostTaskInDestructor> test_object, - base::WaitableEvent* test_executed) { - task_queue->PostTask( - FROM_HERE, base::BindOnce(&PostTaskInDestructor::Do, + WaitableEvent* test_executed) { + task_queue->PostTask(FROM_HERE, + BindOnce(&PostTaskInDestructor::Do, std::move(test_object))); test_executed->Signal(); }, @@ -3308,5 +3216,5 @@ TEST_F(TaskQueueManagerTest, TaskQueueUsedInTaskDestructorAfterShutdown) { test_executed.Wait(); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc index acaf725976b..a80845f7e00 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_manager_perftest.cc @@ -19,39 +19,38 @@ #include "testing/perf/perf_test.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" -#include "third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h" #include "third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" -#include "third_party/blink/renderer/platform/scheduler/test/test_task_queue.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { // To reduce noise related to the OS timer, we use a virtual time domain to // fast forward the timers. class PerfTestTimeDomain : public VirtualTimeDomain { public: - PerfTestTimeDomain() : VirtualTimeDomain(base::TimeTicks::Now()) {} + PerfTestTimeDomain() : VirtualTimeDomain(TimeTicks::Now()) {} ~PerfTestTimeDomain() override = default; - base::Optional<base::TimeDelta> DelayTillNextTask( - LazyNow* lazy_now) override { - base::TimeTicks run_time; + Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override { + TimeTicks run_time; if (!NextScheduledRunTime(&run_time)) - return base::Optional<base::TimeDelta>(); + return Optional<TimeDelta>(); AdvanceNowTo(run_time); - return base::TimeDelta(); // Makes DoWork post an immediate continuation. + return TimeDelta(); // Makes DoWork post an immediate continuation. } - void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override { + void RequestWakeUpAt(TimeTicks now, TimeTicks run_time) override { // De-dupe DoWorks. if (NumberOfScheduledWakeUps() == 1u) RequestDoWork(); } - void CancelWakeUpAt(base::TimeTicks run_time) override { + void CancelWakeUpAt(TimeTicks run_time) override { // We didn't post a delayed task in RequestWakeUpAt so there's no need to do // anything here. } @@ -71,8 +70,8 @@ class TaskQueueManagerPerfTest : public testing::Test { num_tasks_to_run_(0) {} void SetUp() override { - if (base::ThreadTicks::IsSupported()) - base::ThreadTicks::WaitUntilInitialized(); + if (ThreadTicks::IsSupported()) + ThreadTicks::WaitUntilInitialized(); } void TearDown() override { @@ -83,10 +82,10 @@ class TaskQueueManagerPerfTest : public testing::Test { void Initialize(size_t num_queues) { num_queues_ = num_queues; - message_loop_.reset(new base::MessageLoop()); - manager_ = TaskQueueManagerForTest::Create( - message_loop_.get(), message_loop_->task_runner(), - base::DefaultTickClock::GetInstance()); + message_loop_.reset(new MessageLoop()); + manager_ = TaskQueueManagerForTest::Create(message_loop_.get(), + message_loop_->task_runner(), + DefaultTickClock::GetInstance()); manager_->AddTaskTimeObserver(&test_task_time_observer_); virtual_time_domain_.reset(new PerfTestTimeDomain()); @@ -96,6 +95,12 @@ class TaskQueueManagerPerfTest : public testing::Test { queues_.push_back(manager_->CreateTaskQueue<TestTaskQueue>( TaskQueue::Spec("test").SetTimeDomain(virtual_time_domain_.get()))); } + + delayed_task_closure_ = BindRepeating( + &TaskQueueManagerPerfTest::TestDelayedTask, Unretained(this)); + + immediate_task_closure_ = BindRepeating( + &TaskQueueManagerPerfTest::TestImmediateTask, Unretained(this)); } void TestDelayedTask() { @@ -125,11 +130,38 @@ class TaskQueueManagerPerfTest : public testing::Test { // Simulate a mix of short and longer delays. unsigned int delay = num_tasks_to_post_ % 2 ? 1 : (10 + num_tasks_to_post_ % 10); - queues_[queue]->PostDelayedTask( - FROM_HERE, - base::BindOnce(&TaskQueueManagerPerfTest::TestDelayedTask, - base::Unretained(this)), - base::TimeDelta::FromMilliseconds(delay)); + queues_[queue]->PostDelayedTask(FROM_HERE, delayed_task_closure_, + TimeDelta::FromMilliseconds(delay)); + num_tasks_in_flight_++; + num_tasks_to_post_--; + } + } + + void TestImmediateTask() { + if (--num_tasks_to_run_ == 0) { + run_loop_->QuitWhenIdle(); + return; + } + + num_tasks_in_flight_--; + // NOTE there are only up to max_tasks_in_flight_ pending delayed tasks at + // any one time. Thanks to the lower_num_tasks_to_post going to zero if + // there are a lot of tasks in flight, the total number of task in flight at + // any one time is very variable. + unsigned int lower_num_tasks_to_post = + num_tasks_in_flight_ < (max_tasks_in_flight_ / 2) ? 1 : 0; + unsigned int max_tasks_to_post = + num_tasks_to_post_ % 2 ? lower_num_tasks_to_post : 10; + for (unsigned int i = 0; + i < max_tasks_to_post && num_tasks_in_flight_ < max_tasks_in_flight_ && + num_tasks_to_post_ > 0; + i++) { + // Choose a queue weighted towards queue 0. + unsigned int queue = num_tasks_to_post_ % (num_queues_ + 1); + if (queue == num_queues_) { + queue = 0; + } + queues_[queue]->PostTask(FROM_HERE, immediate_task_closure_); num_tasks_in_flight_++; num_tasks_to_post_--; } @@ -142,18 +174,24 @@ class TaskQueueManagerPerfTest : public testing::Test { TestDelayedTask(); } - void Benchmark(const std::string& trace, - const base::RepeatingClosure& test_task) { - base::ThreadTicks start = base::ThreadTicks::Now(); - base::ThreadTicks now; + void ResetAndCallTestImmediateTask(unsigned int num_tasks_to_run) { + num_tasks_in_flight_ = 1; + num_tasks_to_post_ = num_tasks_to_run; + num_tasks_to_run_ = num_tasks_to_run; + TestImmediateTask(); + } + + void Benchmark(const std::string& trace, const RepeatingClosure& test_task) { + ThreadTicks start = ThreadTicks::Now(); + ThreadTicks now; unsigned long long num_iterations = 0; do { test_task.Run(); - run_loop_.reset(new base::RunLoop()); + run_loop_.reset(new RunLoop()); run_loop_->Run(); - now = base::ThreadTicks::Now(); + now = ThreadTicks::Now(); num_iterations++; - } while (now - start < base::TimeDelta::FromSeconds(5)); + } while (now - start < TimeDelta::FromSeconds(5)); perf_test::PrintResult( "task", "", trace, (now - start).InMicroseconds() / static_cast<double>(num_iterations), @@ -165,66 +203,116 @@ class TaskQueueManagerPerfTest : public testing::Test { unsigned int num_tasks_in_flight_; unsigned int num_tasks_to_post_; unsigned int num_tasks_to_run_; - std::unique_ptr<base::MessageLoop> message_loop_; + std::unique_ptr<MessageLoop> message_loop_; std::unique_ptr<TaskQueueManager> manager_; - std::unique_ptr<base::RunLoop> run_loop_; + std::unique_ptr<RunLoop> run_loop_; std::unique_ptr<VirtualTimeDomain> virtual_time_domain_; - std::vector<scoped_refptr<base::SingleThreadTaskRunner>> queues_; + std::vector<scoped_refptr<SingleThreadTaskRunner>> queues_; + RepeatingClosure delayed_task_closure_; + RepeatingClosure immediate_task_closure_; // TODO(alexclarke): parameterize so we can measure with and without a // TaskTimeObserver. TestTaskTimeObserver test_task_time_observer_; }; TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_OneQueue) { - if (!base::ThreadTicks::IsSupported()) + if (!ThreadTicks::IsSupported()) return; Initialize(1u); max_tasks_in_flight_ = 200; - Benchmark("run 10000 delayed tasks with one queue", - base::BindRepeating( - &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + Benchmark( + "run 10000 delayed tasks with one queue", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_FourQueues) { - if (!base::ThreadTicks::IsSupported()) + if (!ThreadTicks::IsSupported()) return; Initialize(4u); max_tasks_in_flight_ = 200; - Benchmark("run 10000 delayed tasks with four queues", - base::BindRepeating( - &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + Benchmark( + "run 10000 delayed tasks with four queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_EightQueues) { - if (!base::ThreadTicks::IsSupported()) + if (!ThreadTicks::IsSupported()) return; Initialize(8u); max_tasks_in_flight_ = 200; - Benchmark("run 10000 delayed tasks with eight queues", - base::BindRepeating( - &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + Benchmark( + "run 10000 delayed tasks with eight queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_ThirtyTwoQueues) { - if (!base::ThreadTicks::IsSupported()) + if (!ThreadTicks::IsSupported()) + return; + Initialize(32u); + + max_tasks_in_flight_ = 200; + Benchmark( + "run 10000 delayed tasks with eight queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + Unretained(this), 10000)); +} + +TEST_F(TaskQueueManagerPerfTest, RunTenThousandImmediateTasks_OneQueue) { + if (!ThreadTicks::IsSupported()) + return; + Initialize(1u); + + max_tasks_in_flight_ = 200; + Benchmark( + "run 10000 immediate tasks with one queue", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestImmediateTask, + Unretained(this), 10000)); +} + +TEST_F(TaskQueueManagerPerfTest, RunTenThousandImmediateTasks_FourQueues) { + if (!ThreadTicks::IsSupported()) + return; + Initialize(4u); + + max_tasks_in_flight_ = 200; + Benchmark( + "run 10000 immediate tasks with four queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestImmediateTask, + Unretained(this), 10000)); +} + +TEST_F(TaskQueueManagerPerfTest, RunTenThousandImmediateTasks_EightQueues) { + if (!ThreadTicks::IsSupported()) + return; + Initialize(8u); + + max_tasks_in_flight_ = 200; + Benchmark( + "run 10000 immediate tasks with eight queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestImmediateTask, + Unretained(this), 10000)); +} + +TEST_F(TaskQueueManagerPerfTest, RunTenThousandImmediateTasks_ThirtyTwoQueues) { + if (!ThreadTicks::IsSupported()) return; Initialize(32u); max_tasks_in_flight_ = 200; - Benchmark("run 10000 delayed tasks with eight queues", - base::BindRepeating( - &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + Benchmark( + "run 10000 immediate tasks with eight queues", + BindRepeating(&TaskQueueManagerPerfTest::ResetAndCallTestImmediateTask, + Unretained(this), 10000)); } // TODO(alexclarke): Add additional tests with different mixes of non-delayed vs // delayed tasks. -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc index 46883b04c24..40c610654c1 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.cc @@ -10,8 +10,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { namespace { @@ -313,22 +313,34 @@ void TaskQueueSelector::DidSelectQueueWithPriority( break; case TaskQueue::kHighestPriority: low_priority_starvation_score_ += - kSmallScoreIncrementForLowPriorityStarvation; + HasTasksWithPriority(TaskQueue::kLowPriority) + ? kSmallScoreIncrementForLowPriorityStarvation + : 0; normal_priority_starvation_score_ += - kSmallScoreIncrementForNormalPriorityStarvation; + HasTasksWithPriority(TaskQueue::kNormalPriority) + ? kSmallScoreIncrementForNormalPriorityStarvation + : 0; high_priority_starvation_score_ += - kSmallScoreIncrementForHighPriorityStarvation; + HasTasksWithPriority(TaskQueue::kHighPriority) + ? kSmallScoreIncrementForHighPriorityStarvation + : 0; break; case TaskQueue::kHighPriority: low_priority_starvation_score_ += - kLargeScoreIncrementForLowPriorityStarvation; + HasTasksWithPriority(TaskQueue::kLowPriority) + ? kLargeScoreIncrementForLowPriorityStarvation + : 0; normal_priority_starvation_score_ += - kLargeScoreIncrementForNormalPriorityStarvation; + HasTasksWithPriority(TaskQueue::kNormalPriority) + ? kLargeScoreIncrementForNormalPriorityStarvation + : 0; high_priority_starvation_score_ = 0; break; case TaskQueue::kNormalPriority: low_priority_starvation_score_ += - kLargeScoreIncrementForLowPriorityStarvation; + HasTasksWithPriority(TaskQueue::kLowPriority) + ? kLargeScoreIncrementForLowPriorityStarvation + : 0; normal_priority_starvation_score_ = 0; break; case TaskQueue::kLowPriority: @@ -347,8 +359,7 @@ void TaskQueueSelector::DidSelectQueueWithPriority( } } -void TaskQueueSelector::AsValueInto( - base::trace_event::TracedValue* state) const { +void TaskQueueSelector::AsValueInto(trace_event::TracedValue* state) const { DCHECK(main_thread_checker_.CalledOnValidThread()); state->SetInteger("high_priority_starvation_score", high_priority_starvation_score_); @@ -383,6 +394,14 @@ void TaskQueueSelector::SetImmediateStarvationCountForTest( immediate_starvation_count_ = immediate_starvation_count; } +bool TaskQueueSelector::HasTasksWithPriority( + TaskQueue::QueuePriority priority) { + return !prioritizing_selector_.delayed_work_queue_sets()->IsSetEmpty( + priority) || + !prioritizing_selector_.immediate_work_queue_sets()->IsSetEmpty( + priority); +} + } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h index 8f39be19b6c..9cb7c114be9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h @@ -16,8 +16,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { // TaskQueueSelector is used by the SchedulerHelper to enable prioritization @@ -54,7 +54,7 @@ class PLATFORM_EXPORT TaskQueueSelector { bool SelectWorkQueueToService(WorkQueue** out_work_queue); // Serialize the selector state for tracing. - void AsValueInto(base::trace_event::TracedValue* state) const; + void AsValueInto(trace_event::TracedValue* state) const; class PLATFORM_EXPORT Observer { public: @@ -147,18 +147,6 @@ class PLATFORM_EXPORT TaskQueueSelector { return &prioritizing_selector_; } - private: - // Returns the priority which is next after |priority|. - static TaskQueue::QueuePriority NextPriority( - TaskQueue::QueuePriority priority); - - bool SelectWorkQueueToServiceInternal(WorkQueue** out_work_queue); - - // Called whenever the selector chooses a task queue for execution with the - // priority |priority|. - void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority, - bool chose_delayed_over_immediate); - // Maximum score to accumulate before high priority tasks are run even in // the presence of highest priority tasks. static const size_t kMaxHighPriorityStarvationScore = 3; @@ -206,7 +194,21 @@ class PLATFORM_EXPORT TaskQueueSelector { static const size_t kMaxDelayedStarvationTasks = 3; private: - base::ThreadChecker main_thread_checker_; + // Returns the priority which is next after |priority|. + static TaskQueue::QueuePriority NextPriority( + TaskQueue::QueuePriority priority); + + bool SelectWorkQueueToServiceInternal(WorkQueue** out_work_queue); + + // Called whenever the selector chooses a task queue for execution with the + // priority |priority|. + void DidSelectQueueWithPriority(TaskQueue::QueuePriority priority, + bool chose_delayed_over_immediate); + + // Returns true if there are pending tasks with priority |priority|. + bool HasTasksWithPriority(TaskQueue::QueuePriority priority); + + ThreadChecker main_thread_checker_; PrioritizingSelector prioritizing_selector_; size_t immediate_starvation_count_; @@ -219,7 +221,7 @@ class PLATFORM_EXPORT TaskQueueSelector { }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h index e29f25788f3..0e85d67bfe2 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_logic.h @@ -5,8 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_LOGIC_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_QUEUE_SELECTOR_LOGIC_H_ -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { // Used to describe the logic trigerred when a task queue is selected to // service. @@ -29,7 +29,7 @@ enum class TaskQueueSelectorLogic { kCount = 9, }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc index 46a59f25aa5..2638d8b342e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_queue_selector_unittest.cc @@ -22,8 +22,8 @@ using testing::_; -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { // To avoid symbol collisions in jumbo builds. namespace task_queue_selector_unittest { @@ -31,7 +31,7 @@ namespace task_queue_selector_unittest { class MockObserver : public TaskQueueSelector::Observer { public: MockObserver() = default; - virtual ~MockObserver() = default; + ~MockObserver() override = default; MOCK_METHOD1(OnTaskQueueEnabled, void(internal::TaskQueueImpl*)); @@ -44,13 +44,52 @@ class TaskQueueSelectorForTest : public TaskQueueSelector { using TaskQueueSelector::prioritizing_selector_for_test; using TaskQueueSelector::PrioritizingSelector; using TaskQueueSelector::SetImmediateStarvationCountForTest; + + // Returns the number of highest priority tasks needed to starve high priority + // task. + static constexpr size_t NumberOfHighestPriorityToStarveHighPriority() { + return (kMaxHighPriorityStarvationScore + + kSmallScoreIncrementForHighPriorityStarvation - 1) / + kSmallScoreIncrementForHighPriorityStarvation; + } + + // Returns the number of highest priority tasks needed to starve normal + // priority tasks. + static constexpr size_t NumberOfHighestPriorityToStarveNormalPriority() { + return (kMaxNormalPriorityStarvationScore + + kSmallScoreIncrementForNormalPriorityStarvation - 1) / + kSmallScoreIncrementForNormalPriorityStarvation; + } + + // Returns the number of high priority tasks needed to starve normal priority + // tasks. + static constexpr size_t NumberOfHighPriorityToStarveNormalPriority() { + return (kMaxNormalPriorityStarvationScore + + kLargeScoreIncrementForNormalPriorityStarvation - 1) / + kLargeScoreIncrementForNormalPriorityStarvation; + } + + // Returns the number of highest priority tasks needed to starve low priority + // ones. + static constexpr size_t NumberOfHighestPriorityToStarveLowPriority() { + return (kMaxLowPriorityStarvationScore + + kSmallScoreIncrementForLowPriorityStarvation - 1) / + kSmallScoreIncrementForLowPriorityStarvation; + } + + // Returns the number of high/normal priority tasks needed to starve low + // priority ones. + static constexpr size_t NumberOfHighAndNormalPriorityToStarveLowPriority() { + return (kMaxLowPriorityStarvationScore + + kLargeScoreIncrementForLowPriorityStarvation - 1) / + kLargeScoreIncrementForLowPriorityStarvation; + } }; class TaskQueueSelectorTest : public testing::Test { public: TaskQueueSelectorTest() - : test_closure_( - base::BindRepeating(&TaskQueueSelectorTest::TestFunction)) {} + : test_closure_(BindRepeating(&TaskQueueSelectorTest::TestFunction)) {} ~TaskQueueSelectorTest() override = default; TaskQueueSelectorForTest::PrioritizingSelector* prioritizing_selector() { @@ -70,7 +109,7 @@ class TaskQueueSelectorTest : public testing::Test { changed_queue_set.insert(queue_indices[i]); task_queues_[queue_indices[i]]->immediate_work_queue()->Push( TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0, i)); + TimeTicks(), 0, i)); } } @@ -82,7 +121,7 @@ class TaskQueueSelectorTest : public testing::Test { changed_queue_set.insert(queue_indices[i]); task_queues_[queue_indices[i]]->immediate_work_queue()->Push( TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0, enqueue_orders[i])); + TimeTicks(), 0, enqueue_orders[i])); } } @@ -103,8 +142,8 @@ class TaskQueueSelectorTest : public testing::Test { protected: void SetUp() final { - virtual_time_domain_ = base::WrapUnique<VirtualTimeDomain>( - new VirtualTimeDomain(base::TimeTicks())); + virtual_time_domain_ = std::make_unique<VirtualTimeDomain>( + TimeTicks() + TimeDelta::FromSeconds(1)); for (size_t i = 0; i < kTaskQueueCount; i++) { std::unique_ptr<TaskQueueImpl> task_queue = std::make_unique<TaskQueueImpl>(nullptr, virtual_time_domain_.get(), @@ -117,7 +156,7 @@ class TaskQueueSelectorTest : public testing::Test { << i; queue_to_index_map_.insert(std::make_pair(task_queues_[i].get(), i)); } - histogram_tester_.reset(new base::HistogramTester()); + histogram_tester_.reset(new HistogramTester()); } void TearDown() final { @@ -136,12 +175,12 @@ class TaskQueueSelectorTest : public testing::Test { } const size_t kTaskQueueCount = 5; - base::RepeatingClosure test_closure_; + RepeatingClosure test_closure_; TaskQueueSelectorForTest selector_; std::unique_ptr<VirtualTimeDomain> virtual_time_domain_; std::vector<std::unique_ptr<TaskQueueImpl>> task_queues_; std::map<TaskQueueImpl*, size_t> queue_to_index_map_; - std::unique_ptr<base::HistogramTester> histogram_tester_; + std::unique_ptr<HistogramTester> histogram_tester_; }; TEST_F(TaskQueueSelectorTest, TestDefaultPriority) { @@ -530,6 +569,133 @@ TEST_F(TaskQueueSelectorTest, TestBestEffortGetsStarved) { } } +TEST_F(TaskQueueSelectorTest, + TestHighPriorityStarvationScoreIncreasedOnlyWhenTasksArePresent) { + size_t queue_order[] = {0, 1}; + PushTasks(queue_order, 2); + selector_.SetQueuePriority(task_queues_[0].get(), + TaskQueue::kHighestPriority); + selector_.SetQueuePriority(task_queues_[1].get(), + TaskQueue::kHighestPriority); + + // Run a number of highest priority tasks needed to starve high priority + // tasks (when present). + for (size_t num_tasks = 0; + num_tasks <= + TaskQueueSelectorForTest::NumberOfHighestPriorityToStarveHighPriority(); + num_tasks++) { + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + // Don't remove task from queue to simulate the queue is still full. + } + + // Post a high priority task. + selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority); + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + + // Check that the high priority task is not considered starved, and thus isn't + // processed. + EXPECT_NE( + static_cast<int>( + queue_to_index_map_.find(chosen_work_queue->task_queue())->second), + 1); +} + +TEST_F(TaskQueueSelectorTest, + TestNormalPriorityStarvationScoreIncreasedOnllWhenTasksArePresent) { + size_t queue_order[] = {0, 1}; + PushTasks(queue_order, 2); + selector_.SetQueuePriority(task_queues_[0].get(), + TaskQueue::kHighestPriority); + selector_.SetQueuePriority(task_queues_[1].get(), + TaskQueue::kHighestPriority); + + // Run a number of highest priority tasks needed to starve normal priority + // tasks (when present). + for (size_t num_tasks = 0; + num_tasks <= TaskQueueSelectorForTest:: + NumberOfHighestPriorityToStarveNormalPriority(); + num_tasks++) { + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + // Don't remove task from queue to simulate the queue is still full. + } + + selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::kHighPriority); + selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kHighPriority); + + // Run a number of high priority tasks needed to starve normal priority + // tasks (when present). + for (size_t num_tasks = 0; + num_tasks <= + TaskQueueSelectorForTest::NumberOfHighPriorityToStarveNormalPriority(); + num_tasks++) { + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + // Don't remove task from queue to simulate the queue is still full. + } + + // Post a normal priority task. + selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kNormalPriority); + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + + // Check that the normal priority task is not considered starved, and thus + // isn't processed. + EXPECT_NE( + static_cast<int>( + queue_to_index_map_.find(chosen_work_queue->task_queue())->second), + 1); +} + +TEST_F(TaskQueueSelectorTest, + TestLowPriorityTaskStarvationOnlyIncreasedWhenTasksArePresent) { + size_t queue_order[] = {0, 1}; + PushTasks(queue_order, 2); + selector_.SetQueuePriority(task_queues_[0].get(), + TaskQueue::kHighestPriority); + selector_.SetQueuePriority(task_queues_[1].get(), + TaskQueue::kHighestPriority); + + // Run a number of highest priority tasks needed to starve low priority + // tasks (when present). + for (size_t num_tasks = 0; + num_tasks <= + TaskQueueSelectorForTest::NumberOfHighestPriorityToStarveLowPriority(); + num_tasks++) { + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + // Don't remove task from queue to simulate the queue is still full. + } + + selector_.SetQueuePriority(task_queues_[0].get(), TaskQueue::kHighPriority); + selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kNormalPriority); + + // Run a number of high/normal priority tasks needed to starve low priority + // tasks (when present). + for (size_t num_tasks = 0; + num_tasks <= TaskQueueSelectorForTest:: + NumberOfHighAndNormalPriorityToStarveLowPriority(); + num_tasks++) { + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + // Don't remove task from queue to simulate the queue is still full. + } + + // Post a low priority task. + selector_.SetQueuePriority(task_queues_[1].get(), TaskQueue::kLowPriority); + WorkQueue* chosen_work_queue = nullptr; + ASSERT_TRUE(selector_.SelectWorkQueueToService(&chosen_work_queue)); + + // Check that the low priority task is not considered starved, and thus + // isn't processed. + EXPECT_NE( + static_cast<int>( + queue_to_index_map_.find(chosen_work_queue->task_queue())->second), + 1); +} + TEST_F(TaskQueueSelectorTest, AllEnabledWorkQueuesAreEmpty) { EXPECT_TRUE(selector_.AllEnabledWorkQueuesAreEmpty()); size_t queue_order[] = {0, 1}; @@ -560,9 +726,8 @@ TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_Empty) { } TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) { - task_queues_[0]->delayed_work_queue()->Push( - TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0, 0)); + task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task( + TaskQueue::PostedTask(test_closure_, FROM_HERE), TimeTicks(), 0, 0)); WorkQueue* chosen_work_queue = nullptr; bool chose_delayed_over_immediate = false; @@ -574,9 +739,8 @@ TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyDelayed) { } TEST_F(TaskQueueSelectorTest, ChooseOldestWithPriority_OnlyImmediate) { - task_queues_[0]->immediate_work_queue()->Push( - TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0, 0)); + task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task( + TaskQueue::PostedTask(test_closure_, FROM_HERE), TimeTicks(), 0, 0)); WorkQueue* chosen_work_queue = nullptr; bool chose_delayed_over_immediate = false; @@ -601,7 +765,7 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithOneBlockedQueue) { selector.DisableQueue(task_queue.get()); TaskQueueImpl::Task task(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0); + TimeTicks(), 0); task.set_enqueue_order(0); task_queue->immediate_work_queue()->Push(std::move(task)); @@ -632,9 +796,9 @@ TEST_F(TaskQueueSelectorTest, TestObserverWithTwoBlockedQueues) { selector.SetQueuePriority(task_queue2.get(), TaskQueue::kControlPriority); TaskQueueImpl::Task task1(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 0); + TimeTicks(), 0); TaskQueueImpl::Task task2(TaskQueue::PostedTask(test_closure_, FROM_HERE), - base::TimeTicks(), 1); + TimeTicks(), 1); task1.set_enqueue_order(0); task2.set_enqueue_order(1); task_queue->immediate_work_queue()->Push(std::move(task1)); @@ -680,15 +844,15 @@ class ChooseOldestWithPriorityTest public testing::WithParamInterface<ChooseOldestWithPriorityTestParam> {}; TEST_P(ChooseOldestWithPriorityTest, RoundRobinTest) { - task_queues_[0]->immediate_work_queue()->Push(TaskQueueImpl::Task( - TaskQueue::PostedTask(test_closure_, FROM_HERE), base::TimeTicks(), - GetParam().immediate_task_enqueue_order, - GetParam().immediate_task_enqueue_order)); + task_queues_[0]->immediate_work_queue()->Push( + TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), + TimeTicks(), GetParam().immediate_task_enqueue_order, + GetParam().immediate_task_enqueue_order)); - task_queues_[0]->delayed_work_queue()->Push(TaskQueueImpl::Task( - TaskQueue::PostedTask(test_closure_, FROM_HERE), base::TimeTicks(), - GetParam().delayed_task_enqueue_order, - GetParam().delayed_task_enqueue_order)); + task_queues_[0]->delayed_work_queue()->Push( + TaskQueueImpl::Task(TaskQueue::PostedTask(test_closure_, FROM_HERE), + TimeTicks(), GetParam().delayed_task_enqueue_order, + GetParam().delayed_task_enqueue_order)); selector_.SetImmediateStarvationCountForTest( GetParam().immediate_starvation_count); @@ -710,5 +874,5 @@ INSTANTIATE_TEST_CASE_P(ChooseOldestWithPriorityTest, } // namespace task_queue_selector_unittest } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/task_time_observer.h b/chromium/third_party/blink/renderer/platform/scheduler/base/task_time_observer.h index cde2e569708..9704c222488 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/task_time_observer.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/task_time_observer.h @@ -8,8 +8,8 @@ #include "base/time/time.h" #include "third_party/blink/renderer/platform/platform_export.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { // TaskTimeObserver provides an API for observing completion of renderer tasks. class PLATFORM_EXPORT TaskTimeObserver { @@ -30,7 +30,7 @@ class PLATFORM_EXPORT TaskTimeObserver { DISALLOW_COPY_AND_ASSIGN(TaskTimeObserver); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TASK_TIME_OBSERVER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.cc deleted file mode 100644 index 9b6e17ad504..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.cc +++ /dev/null @@ -1,22 +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/base/test_count_uses_time_source.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace blink { -namespace scheduler { - -TestCountUsesTimeSource::TestCountUsesTimeSource() : now_calls_count_(0) {} - -TestCountUsesTimeSource::~TestCountUsesTimeSource() = default; - -base::TimeTicks TestCountUsesTimeSource::NowTicks() const { - now_calls_count_++; - // Don't return 0, as it triggers some assertions. - return base::TimeTicks() + base::TimeDelta::FromSeconds(1); -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.h b/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.h deleted file mode 100644 index c953ab16c55..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/test_count_uses_time_source.h +++ /dev/null @@ -1,31 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_COUNT_USES_TIME_SOURCE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_COUNT_USES_TIME_SOURCE_H_ - -#include "base/macros.h" -#include "base/time/tick_clock.h" - -namespace blink { -namespace scheduler { - -class TestCountUsesTimeSource : public base::TickClock { - public: - explicit TestCountUsesTimeSource(); - ~TestCountUsesTimeSource() override; - - base::TimeTicks NowTicks() const override; - int now_calls_count() const { return now_calls_count_; } - - private: - DISALLOW_COPY_AND_ASSIGN(TestCountUsesTimeSource); - - mutable int now_calls_count_; -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_COUNT_USES_TIME_SOURCE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h b/chromium/third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h deleted file mode 100644 index 62a4db3b58f..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_TASK_TIME_OBSERVER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_TASK_TIME_OBSERVER_H_ - -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_time_observer.h" - -namespace blink { -namespace scheduler { - -class TestTaskTimeObserver : public TaskTimeObserver { - public: - void WillProcessTask(double start_time) override {} - void DidProcessTask(double start_time, double end_time) override {} -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TEST_TASK_TIME_OBSERVER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller.h b/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller.h deleted file mode 100644 index cfae477eb76..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller.h +++ /dev/null @@ -1,94 +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_SCHEDULER_BASE_THREAD_CONTROLLER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_CONTROLLER_H_ - -#include "base/location.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/platform_export.h" - -namespace base { -class TickClock; -struct PendingTask; -}; - -namespace blink { -namespace scheduler { -namespace internal { - -class SequencedTaskSource; - -// Interface for TaskQueueManager to schedule work to be run. -class PLATFORM_EXPORT ThreadController { - public: - virtual ~ThreadController() = default; - - // Set the number of tasks executed in a single invocation of DoWork. - // Increasing the batch size can reduce the overhead of yielding back to the - // main message loop. The batch size is 1 by default. - virtual void SetWorkBatchSize(int work_batch_size) = 0; - - // Notifies that |pending_task| was enqueued. Needed for tracing purposes. - virtual void DidQueueTask(const base::PendingTask& pending_task) = 0; - - // Notify the controller that its associated sequence has immediate work - // to run. Shortly after this is called, the thread associated with this - // controller will run a task returned by sequence->TakeTask(). Can be called - // from any sequence. - // - // TODO(altimin): Change this to "the thread associated with this - // controller will run tasks returned by sequence->TakeTask() until it - // returns null or sequence->DidRunTask() returns false" once the - // code is changed to work that way. - virtual void ScheduleWork() = 0; - - // Notify the controller that its associated sequence will have - // delayed work to run at |run_time|. The thread associated with this - // controller will run a task returned by sequence->TakeTask() at that time. - // This call cancels any previously scheduled delayed work. Will be called - // from the main sequence. - // - // TODO(altimin): Change this to "the thread associated with this - // controller will run tasks returned by sequence->TakeTask() until - // it returns null or sequence->DidRunTask() returns false" once the - // code is changed to work that way. - virtual void ScheduleDelayedWork(base::TimeTicks now, - base::TimeTicks run_time) = 0; - - // Notify thread controller that sequence no longer has delayed work at - // |run_time| and previously scheduled callbacks should be cancelled. - virtual void CancelDelayedWork(base::TimeTicks run_time) = 0; - - // Sets the sequenced task source from which to take tasks after - // a Schedule*Work() call is made. - // Must be called before the first call to Schedule*Work(). - virtual void SetSequencedTaskSource(SequencedTaskSource*) = 0; - - // TODO(altimin): Get rid of the methods below. - // These methods exist due to current integration of TaskQueueManager - // with MessageLoop. - - virtual bool RunsTasksInCurrentSequence() = 0; - - virtual const base::TickClock* GetClock() = 0; - - virtual void SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner>) = 0; - - virtual void RestoreDefaultTaskRunner() = 0; - - virtual void AddNestingObserver(base::RunLoop::NestingObserver* observer) = 0; - - virtual void RemoveNestingObserver( - base::RunLoop::NestingObserver* observer) = 0; -}; - -} // namespace internal -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_CONTROLLER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc index 196cd5c5312..e108f455f21 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.cc @@ -8,38 +8,46 @@ #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/run_loop.h" -#include "base/time/tick_clock.h" +#include "base/task/sequence_manager/lazy_now.h" +#include "base/task/sequence_manager/sequenced_task_source.h" #include "base/trace_event/trace_event.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { ThreadControllerImpl::ThreadControllerImpl( - base::MessageLoop* message_loop, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source) + MessageLoop* message_loop, + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source) : message_loop_(message_loop), task_runner_(task_runner), message_loop_task_runner_(message_loop ? message_loop->task_runner() : nullptr), time_source_(time_source), weak_factory_(this) { - immediate_do_work_closure_ = base::BindRepeating( - &ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), - SequencedTaskSource::WorkType::kImmediate); - delayed_do_work_closure_ = base::BindRepeating( - &ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), - SequencedTaskSource::WorkType::kDelayed); + immediate_do_work_closure_ = + BindRepeating(&ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), + WorkType::kImmediate); + delayed_do_work_closure_ = + BindRepeating(&ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), + WorkType::kDelayed); } ThreadControllerImpl::~ThreadControllerImpl() = default; +ThreadControllerImpl::AnySequence::AnySequence() = default; + +ThreadControllerImpl::AnySequence::~AnySequence() = default; + +ThreadControllerImpl::MainSequenceOnly::MainSequenceOnly() = default; + +ThreadControllerImpl::MainSequenceOnly::~MainSequenceOnly() = default; + std::unique_ptr<ThreadControllerImpl> ThreadControllerImpl::Create( - base::MessageLoop* message_loop, - const base::TickClock* time_source) { - return base::WrapUnique(new ThreadControllerImpl( + MessageLoop* message_loop, + const TickClock* time_source) { + return WrapUnique(new ThreadControllerImpl( message_loop, message_loop->task_runner(), time_source)); } @@ -53,7 +61,7 @@ void ThreadControllerImpl::SetSequencedTaskSource( void ThreadControllerImpl::ScheduleWork() { DCHECK(sequence_); - base::AutoLock lock(any_sequence_lock_); + AutoLock lock(any_sequence_lock_); // Don't post a DoWork if there's an immediate DoWork in flight or if we're // inside a top level DoWork. We can rely on a continuation being posted as // needed. @@ -63,21 +71,26 @@ void ThreadControllerImpl::ScheduleWork() { } any_sequence().immediate_do_work_posted = true; - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "ThreadControllerImpl::ScheduleWork::PostTask"); task_runner_->PostTask(FROM_HERE, immediate_do_work_closure_); } -void ThreadControllerImpl::ScheduleDelayedWork(base::TimeTicks now, - base::TimeTicks run_time) { +void ThreadControllerImpl::SetNextDelayedDoWork(LazyNow* lazy_now, + TimeTicks run_time) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(sequence_); - // If there's a delayed DoWork scheduled to run sooner, we don't need to do - // anything because a delayed continuation will be posted as needed. - if (main_sequence_only().next_delayed_do_work <= run_time) + if (main_sequence_only().next_delayed_do_work == run_time) return; + // Cancel DoWork if it was scheduled and we set an "infinite" delay now. + if (run_time == TimeTicks::Max()) { + cancelable_delayed_do_work_closure_.Cancel(); + main_sequence_only().next_delayed_do_work = TimeTicks::Max(); + return; + } + // If DoWork is running then we don't need to do anything because it will post // a continuation as needed. Bailing out here is by far the most common case. if (main_sequence_only().do_work_running_count > @@ -87,42 +100,33 @@ void ThreadControllerImpl::ScheduleDelayedWork(base::TimeTicks now, // If DoWork is about to run then we also don't need to do anything. { - base::AutoLock lock(any_sequence_lock_); + AutoLock lock(any_sequence_lock_); if (any_sequence().immediate_do_work_posted) return; } - base::TimeDelta delay = std::max(base::TimeDelta(), run_time - now); - TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), - "ThreadControllerImpl::ScheduleDelayedWork::PostDelayedTask", + base::TimeDelta delay = std::max(TimeDelta(), run_time - lazy_now->Now()); + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), + "ThreadControllerImpl::SetNextDelayedDoWork::PostDelayedTask", "delay_ms", delay.InMillisecondsF()); main_sequence_only().next_delayed_do_work = run_time; + // Reset also causes cancellation of the previous DoWork task. cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_); task_runner_->PostDelayedTask( FROM_HERE, cancelable_delayed_do_work_closure_.callback(), delay); } -void ThreadControllerImpl::CancelDelayedWork(base::TimeTicks run_time) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(sequence_); - if (main_sequence_only().next_delayed_do_work != run_time) - return; - - cancelable_delayed_do_work_closure_.Cancel(); - main_sequence_only().next_delayed_do_work = base::TimeTicks::Max(); -} - bool ThreadControllerImpl::RunsTasksInCurrentSequence() { return task_runner_->RunsTasksInCurrentSequence(); } -const base::TickClock* ThreadControllerImpl::GetClock() { +const TickClock* ThreadControllerImpl::GetClock() { return time_source_; } void ThreadControllerImpl::SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + scoped_refptr<SingleThreadTaskRunner> task_runner) { if (!message_loop_) return; message_loop_->SetTaskRunner(task_runner); @@ -134,27 +138,27 @@ void ThreadControllerImpl::RestoreDefaultTaskRunner() { message_loop_->SetTaskRunner(message_loop_task_runner_); } -void ThreadControllerImpl::DidQueueTask(const base::PendingTask& pending_task) { +void ThreadControllerImpl::DidQueueTask(const PendingTask& pending_task) { task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); } -void ThreadControllerImpl::DoWork(SequencedTaskSource::WorkType work_type) { +void ThreadControllerImpl::DoWork(WorkType work_type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(sequence_); { - base::AutoLock lock(any_sequence_lock_); - if (work_type == SequencedTaskSource::WorkType::kImmediate) + AutoLock lock(any_sequence_lock_); + if (work_type == WorkType::kImmediate) any_sequence().immediate_do_work_posted = false; any_sequence().do_work_running_count++; } main_sequence_only().do_work_running_count++; - base::WeakPtr<ThreadControllerImpl> weak_ptr = weak_factory_.GetWeakPtr(); + WeakPtr<ThreadControllerImpl> weak_ptr = weak_factory_.GetWeakPtr(); // TODO(scheduler-dev): Consider moving to a time based work batch instead. for (int i = 0; i < main_sequence_only().work_batch_size_; i++) { - base::Optional<base::PendingTask> task = sequence_->TakeTask(); + Optional<PendingTask> task = sequence_->TakeTask(); if (!task) break; @@ -174,22 +178,21 @@ void ThreadControllerImpl::DoWork(SequencedTaskSource::WorkType work_type) { main_sequence_only().do_work_running_count--; { - base::AutoLock lock(any_sequence_lock_); + AutoLock lock(any_sequence_lock_); any_sequence().do_work_running_count--; DCHECK_GE(any_sequence().do_work_running_count, 0); LazyNow lazy_now(time_source_); - base::TimeDelta delay_till_next_task = - sequence_->DelayTillNextTask(&lazy_now); - if (delay_till_next_task <= base::TimeDelta()) { + TimeDelta delay_till_next_task = sequence_->DelayTillNextTask(&lazy_now); + if (delay_till_next_task <= TimeDelta()) { // The next task needs to run immediately, post a continuation if needed. if (!any_sequence().immediate_do_work_posted) { any_sequence().immediate_do_work_posted = true; task_runner_->PostTask(FROM_HERE, immediate_do_work_closure_); } - } else if (delay_till_next_task < base::TimeDelta::Max()) { + } else if (delay_till_next_task < TimeDelta::Max()) { // The next task needs to run after a delay, post a continuation if // needed. - base::TimeTicks next_task_at = lazy_now.Now() + delay_till_next_task; + TimeTicks next_task_at = lazy_now.Now() + delay_till_next_task; if (next_task_at != main_sequence_only().next_delayed_do_work) { main_sequence_only().next_delayed_do_work = next_task_at; cancelable_delayed_do_work_closure_.Reset(delayed_do_work_closure_); @@ -199,34 +202,34 @@ void ThreadControllerImpl::DoWork(SequencedTaskSource::WorkType work_type) { } } else { // There is no next task scheduled. - main_sequence_only().next_delayed_do_work = base::TimeTicks::Max(); + main_sequence_only().next_delayed_do_work = TimeTicks::Max(); } } } void ThreadControllerImpl::AddNestingObserver( - base::RunLoop::NestingObserver* observer) { + RunLoop::NestingObserver* observer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); nesting_observer_ = observer; - base::RunLoop::AddNestingObserverOnCurrentThread(this); + RunLoop::AddNestingObserverOnCurrentThread(this); } void ThreadControllerImpl::RemoveNestingObserver( - base::RunLoop::NestingObserver* observer) { + RunLoop::NestingObserver* observer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(observer, nesting_observer_); nesting_observer_ = nullptr; - base::RunLoop::RemoveNestingObserverOnCurrentThread(this); + RunLoop::RemoveNestingObserverOnCurrentThread(this); } void ThreadControllerImpl::OnBeginNestedRunLoop() { main_sequence_only().nesting_depth++; { - base::AutoLock lock(any_sequence_lock_); + AutoLock lock(any_sequence_lock_); any_sequence().nesting_depth++; if (!any_sequence().immediate_do_work_posted) { any_sequence().immediate_do_work_posted = true; - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("sequence_manager"), "ThreadControllerImpl::OnBeginNestedRunLoop::PostTask"); task_runner_->PostTask(FROM_HERE, immediate_do_work_closure_); } @@ -238,7 +241,7 @@ void ThreadControllerImpl::OnBeginNestedRunLoop() { void ThreadControllerImpl::OnExitNestedRunLoop() { main_sequence_only().nesting_depth--; { - base::AutoLock lock(any_sequence_lock_); + AutoLock lock(any_sequence_lock_); any_sequence().nesting_depth--; DCHECK_GE(any_sequence().nesting_depth, 0); } @@ -251,5 +254,5 @@ void ThreadControllerImpl::SetWorkBatchSize(int work_batch_size) { } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h index bff48060c17..e6473caf68b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/thread_controller_impl.h @@ -5,8 +5,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_CONTROLLER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_CONTROLLER_IMPL_H_ -#include "third_party/blink/renderer/platform/scheduler/base/thread_controller.h" - #include "base/cancelable_callback.h" #include "base/debug/task_annotator.h" #include "base/macros.h" @@ -14,72 +12,69 @@ #include "base/run_loop.h" #include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" +#include "base/task/sequence_manager/thread_controller.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h" namespace base { + class MessageLoop; -class TickClock; -} // namespace base -namespace blink { -namespace scheduler { +namespace sequence_manager { namespace internal { -class PLATFORM_EXPORT ThreadControllerImpl - : public ThreadController, - public base::RunLoop::NestingObserver { +class PLATFORM_EXPORT ThreadControllerImpl : public ThreadController, + public RunLoop::NestingObserver { public: ~ThreadControllerImpl() override; static std::unique_ptr<ThreadControllerImpl> Create( - base::MessageLoop* message_loop, - const base::TickClock* time_source); + MessageLoop* message_loop, + const TickClock* time_source); // ThreadController: void SetWorkBatchSize(int work_batch_size) override; - void DidQueueTask(const base::PendingTask& pending_task) override; + void DidQueueTask(const PendingTask& pending_task) override; void ScheduleWork() override; - void ScheduleDelayedWork(base::TimeTicks now, - base::TimeTicks run_timy) override; - void CancelDelayedWork(base::TimeTicks run_time) override; + void SetNextDelayedDoWork(LazyNow* lazy_now, TimeTicks run_time) override; void SetSequencedTaskSource(SequencedTaskSource* sequence) override; bool RunsTasksInCurrentSequence() override; - const base::TickClock* GetClock() override; - void SetDefaultTaskRunner( - scoped_refptr<base::SingleThreadTaskRunner>) override; + const TickClock* GetClock() override; + void SetDefaultTaskRunner(scoped_refptr<SingleThreadTaskRunner>) override; void RestoreDefaultTaskRunner() override; - void AddNestingObserver(base::RunLoop::NestingObserver* observer) override; - void RemoveNestingObserver(base::RunLoop::NestingObserver* observer) override; + void AddNestingObserver(RunLoop::NestingObserver* observer) override; + void RemoveNestingObserver(RunLoop::NestingObserver* observer) override; - // base::RunLoop::NestingObserver: + // RunLoop::NestingObserver: void OnBeginNestedRunLoop() override; void OnExitNestedRunLoop() override; protected: - ThreadControllerImpl(base::MessageLoop* message_loop, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - const base::TickClock* time_source); + ThreadControllerImpl(MessageLoop* message_loop, + scoped_refptr<SingleThreadTaskRunner> task_runner, + const TickClock* time_source); // TODO(altimin): Make these const. Blocked on removing // lazy initialisation support. - base::MessageLoop* message_loop_; - scoped_refptr<base::SingleThreadTaskRunner> task_runner_; + MessageLoop* message_loop_; + scoped_refptr<SingleThreadTaskRunner> task_runner_; - base::RunLoop::NestingObserver* nesting_observer_ = nullptr; + RunLoop::NestingObserver* nesting_observer_ = nullptr; private: - void DoWork(SequencedTaskSource::WorkType work_type); + enum class WorkType { kImmediate, kDelayed }; + + void DoWork(WorkType work_type); struct AnySequence { - AnySequence() = default; + AnySequence(); + ~AnySequence(); int do_work_running_count = 0; int nesting_depth = 0; bool immediate_do_work_posted = false; }; - mutable base::Lock any_sequence_lock_; + mutable Lock any_sequence_lock_; AnySequence any_sequence_; struct AnySequence& any_sequence() { @@ -92,13 +87,14 @@ class PLATFORM_EXPORT ThreadControllerImpl } struct MainSequenceOnly { - MainSequenceOnly() = default; + MainSequenceOnly(); + ~MainSequenceOnly(); int do_work_running_count = 0; int nesting_depth = 0; int work_batch_size_ = 1; - base::TimeTicks next_delayed_do_work = base::TimeTicks::Max(); + TimeTicks next_delayed_do_work = TimeTicks::Max(); }; SEQUENCE_CHECKER(sequence_checker_); @@ -112,21 +108,21 @@ class PLATFORM_EXPORT ThreadControllerImpl return main_sequence_only_; } - scoped_refptr<base::SingleThreadTaskRunner> message_loop_task_runner_; - const base::TickClock* time_source_; - base::RepeatingClosure immediate_do_work_closure_; - base::RepeatingClosure delayed_do_work_closure_; - base::CancelableClosure cancelable_delayed_do_work_closure_; + scoped_refptr<SingleThreadTaskRunner> message_loop_task_runner_; + const TickClock* time_source_; + RepeatingClosure immediate_do_work_closure_; + RepeatingClosure delayed_do_work_closure_; + CancelableClosure cancelable_delayed_do_work_closure_; SequencedTaskSource* sequence_ = nullptr; // NOT OWNED - base::debug::TaskAnnotator task_annotator_; + debug::TaskAnnotator task_annotator_; - base::WeakPtrFactory<ThreadControllerImpl> weak_factory_; + WeakPtrFactory<ThreadControllerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ThreadControllerImpl); }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_THREAD_CONTROLLER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.cc index b835c150451..4fa86036ffb 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.cc @@ -9,8 +9,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { TimeDomain::TimeDomain() = default; @@ -28,18 +28,18 @@ void TimeDomain::UnregisterQueue(internal::TaskQueueImpl* queue) { DCHECK_EQ(queue->GetTimeDomain(), this); LazyNow lazy_now = CreateLazyNow(); - ScheduleWakeUpForQueue(queue, base::nullopt, &lazy_now); + ScheduleWakeUpForQueue(queue, nullopt, &lazy_now); } void TimeDomain::ScheduleWakeUpForQueue( internal::TaskQueueImpl* queue, - base::Optional<internal::TaskQueueImpl::DelayedWakeUp> wake_up, + Optional<internal::TaskQueueImpl::DelayedWakeUp> wake_up, LazyNow* lazy_now) { DCHECK(main_thread_checker_.CalledOnValidThread()); DCHECK_EQ(queue->GetTimeDomain(), this); DCHECK(queue->IsQueueEnabled() || !wake_up); - base::Optional<base::TimeTicks> previous_wake_up; + Optional<TimeTicks> previous_wake_up; if (!delayed_wake_up_queue_.empty()) previous_wake_up = delayed_wake_up_queue_.Min().wake_up.time; @@ -59,7 +59,7 @@ void TimeDomain::ScheduleWakeUpForQueue( delayed_wake_up_queue_.erase(queue->heap_handle()); } - base::Optional<base::TimeTicks> new_wake_up; + Optional<TimeTicks> new_wake_up; if (!delayed_wake_up_queue_.empty()) new_wake_up = delayed_wake_up_queue_.Min().wake_up.time; @@ -84,7 +84,7 @@ void TimeDomain::WakeUpReadyDelayedQueues(LazyNow* lazy_now) { } } -bool TimeDomain::NextScheduledRunTime(base::TimeTicks* out_time) const { +bool TimeDomain::NextScheduledRunTime(TimeTicks* out_time) const { DCHECK(main_thread_checker_.CalledOnValidThread()); if (delayed_wake_up_queue_.empty()) return false; @@ -103,17 +103,17 @@ bool TimeDomain::NextScheduledTaskQueue( return true; } -void TimeDomain::AsValueInto(base::trace_event::TracedValue* state) const { +void TimeDomain::AsValueInto(trace_event::TracedValue* state) const { state->BeginDictionary(); state->SetString("name", GetName()); state->SetInteger("registered_delay_count", delayed_wake_up_queue_.size()); if (!delayed_wake_up_queue_.empty()) { - base::TimeDelta delay = delayed_wake_up_queue_.Min().wake_up.time - Now(); + TimeDelta delay = delayed_wake_up_queue_.Min().wake_up.time - Now(); state->SetDouble("next_delay_ms", delay.InMillisecondsF()); } AsValueIntoInternal(state); state->EndDictionary(); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.h index 5ee0d850ea6..4770dc307dc 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain.h @@ -10,13 +10,13 @@ #include "base/callback.h" #include "base/logging.h" #include "base/macros.h" +#include "base/task/sequence_manager/lazy_now.h" #include "base/time/time.h" #include "third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { class TaskQueueImpl; } // internal @@ -26,7 +26,7 @@ class TaskQueueManager; // are due to fire. TaskQueues request a wake up via ScheduleDelayedWork, when // the wake up is due the TimeDomain calls TaskQueue::WakeUpForDelayedWork. // The TimeDomain communicates with the TaskQueueManager to actually schedule -// the wake-ups on the underlying base::MessageLoop. Various levels of de-duping +// the wake-ups on the underlying MessageLoop. Various levels of de-duping // are employed to prevent unnecessary posting of TaskQueueManager::DoWork. // // Note the TimeDomain only knows about the first wake-up per queue, it's the @@ -43,27 +43,26 @@ class PLATFORM_EXPORT TimeDomain { virtual LazyNow CreateLazyNow() const = 0; // Evaluate this TimeDomain's Now. Can be called from any thread. - virtual base::TimeTicks Now() const = 0; + virtual TimeTicks Now() const = 0; // Computes the delay until the next task the TimeDomain is aware of, if any. - // Note virtual time domains may return base::TimeDelta() if they have any + // Note virtual time domains may return TimeDelta() if they have any // delayed tasks they deem eligible to run. Virtual time domains are allowed // to advance their internal clock when this method is called. - virtual base::Optional<base::TimeDelta> DelayTillNextTask( - LazyNow* lazy_now) = 0; + virtual Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) = 0; // Returns the name of this time domain for tracing. virtual const char* GetName() const = 0; // If there is a scheduled delayed task, |out_time| is set to the scheduled // runtime for the next one and it returns true. Returns false otherwise. - bool NextScheduledRunTime(base::TimeTicks* out_time) const; + bool NextScheduledRunTime(TimeTicks* out_time) const; protected: friend class internal::TaskQueueImpl; friend class TaskQueueManagerImpl; - void AsValueInto(base::trace_event::TracedValue* state) const; + void AsValueInto(trace_event::TracedValue* state) const; // If there is a scheduled delayed task, |out_task_queue| is set to the queue // the next task was posted to and it returns true. Returns false otherwise. @@ -71,7 +70,7 @@ class PLATFORM_EXPORT TimeDomain { void ScheduleWakeUpForQueue( internal::TaskQueueImpl* queue, - base::Optional<internal::TaskQueueImpl::DelayedWakeUp> wake_up, + Optional<internal::TaskQueueImpl::DelayedWakeUp> wake_up, LazyNow* lazy_now); // Registers the |queue|. @@ -89,17 +88,15 @@ class PLATFORM_EXPORT TimeDomain { // NOTE this is only called by ScheduleDelayedWork if the scheduled runtime // is sooner than any previously sheduled work or if there is no other // scheduled work. - virtual void RequestWakeUpAt(base::TimeTicks now, - base::TimeTicks run_time) = 0; + virtual void RequestWakeUpAt(TimeTicks now, TimeTicks run_time) = 0; // The implementation will cancel a wake up previously requested by // RequestWakeUpAt. It's expected this will be a NOP for most virtual time // domains. - virtual void CancelWakeUpAt(base::TimeTicks run_time) = 0; + virtual void CancelWakeUpAt(TimeTicks run_time) = 0; // For implementation specific tracing. - virtual void AsValueIntoInternal( - base::trace_event::TracedValue* state) const = 0; + virtual void AsValueIntoInternal(trace_event::TracedValue* state) const = 0; // Call TaskQueueImpl::UpdateDelayedWorkQueue for each queue where the delay // has elapsed. @@ -131,12 +128,12 @@ class PLATFORM_EXPORT TimeDomain { IntrusiveHeap<ScheduledDelayedWakeUp> delayed_wake_up_queue_; - base::ThreadChecker main_thread_checker_; + ThreadChecker main_thread_checker_; DISALLOW_COPY_AND_ASSIGN(TimeDomain); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_TIME_DOMAIN_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc index a16adba9f08..b86a866d297 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/time_domain_unittest.cc @@ -8,7 +8,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" @@ -18,8 +17,8 @@ using testing::_; using testing::AnyNumber; using testing::Mock; -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class TaskQueueImplForTest : public internal::TaskQueueImpl { public: @@ -34,8 +33,7 @@ class TaskQueueImplForTest : public internal::TaskQueueImpl { class MockTimeDomain : public TimeDomain { public: - MockTimeDomain() - : now_(base::TimeTicks() + base::TimeDelta::FromSeconds(1)) {} + MockTimeDomain() : now_(TimeTicks() + TimeDelta::FromSeconds(1)) {} ~MockTimeDomain() override = default; @@ -46,28 +44,25 @@ class MockTimeDomain : public TimeDomain { // TimeSource implementation: LazyNow CreateLazyNow() const override { return LazyNow(now_); } - base::TimeTicks Now() const override { return now_; } + TimeTicks Now() const override { return now_; } - void AsValueIntoInternal( - base::trace_event::TracedValue* state) const override {} + void AsValueIntoInternal(trace_event::TracedValue* state) const override {} - base::Optional<base::TimeDelta> DelayTillNextTask( - LazyNow* lazy_now) override { - return base::Optional<base::TimeDelta>(); + Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override { + return Optional<TimeDelta>(); } const char* GetName() const override { return "Test"; } void OnRegisterWithTaskQueueManager( TaskQueueManagerImpl* task_queue_manager) override {} - MOCK_METHOD2(RequestWakeUpAt, - void(base::TimeTicks now, base::TimeTicks run_time)); + MOCK_METHOD2(RequestWakeUpAt, void(TimeTicks now, TimeTicks run_time)); - MOCK_METHOD1(CancelWakeUpAt, void(base::TimeTicks run_time)); + MOCK_METHOD1(CancelWakeUpAt, void(TimeTicks run_time)); - void SetNow(base::TimeTicks now) { now_ = now; } + void SetNow(TimeTicks now) { now_ = now; } private: - base::TimeTicks now_; + TimeTicks now_; DISALLOW_COPY_AND_ASSIGN(MockTimeDomain); }; @@ -75,7 +70,7 @@ class MockTimeDomain : public TimeDomain { class TimeDomainTest : public testing::Test { public: void SetUp() final { - time_domain_ = base::WrapUnique(CreateMockTimeDomain()); + time_domain_ = WrapUnique(CreateMockTimeDomain()); task_queue_ = std::make_unique<TaskQueueImplForTest>( nullptr, time_domain_.get(), TaskQueue::Spec("test")); } @@ -94,15 +89,15 @@ class TimeDomainTest : public testing::Test { }; TEST_F(TimeDomainTest, ScheduleWakeUpForQueue) { - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); - base::TimeTicks delayed_runtime = time_domain_->Now() + delay; + TimeDelta delay = TimeDelta::FromMilliseconds(10); + TimeTicks delayed_runtime = time_domain_->Now() + delay; EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, delayed_runtime)); - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); task_queue_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{now + delay, 0}); - base::TimeTicks next_scheduled_runtime; + TimeTicks next_scheduled_runtime; EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); EXPECT_EQ(delayed_runtime, next_scheduled_runtime); @@ -115,17 +110,17 @@ TEST_F(TimeDomainTest, ScheduleWakeUpForQueue) { } TEST_F(TimeDomainTest, ScheduleWakeUpForQueueSupersedesPreviousWakeUp) { - base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); - base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(100); - base::TimeTicks delayed_runtime1 = time_domain_->Now() + delay1; - base::TimeTicks delayed_runtime2 = time_domain_->Now() + delay2; + TimeDelta delay1 = TimeDelta::FromMilliseconds(10); + TimeDelta delay2 = TimeDelta::FromMilliseconds(100); + TimeTicks delayed_runtime1 = time_domain_->Now() + delay1; + TimeTicks delayed_runtime2 = time_domain_->Now() + delay2; EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, delayed_runtime1)); - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); task_queue_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{delayed_runtime1, 0}); - base::TimeTicks next_scheduled_runtime; + TimeTicks next_scheduled_runtime; EXPECT_TRUE(time_domain_->NextScheduledRunTime(&next_scheduled_runtime)); EXPECT_EQ(delayed_runtime1, next_scheduled_runtime); @@ -157,13 +152,13 @@ TEST_F(TimeDomainTest, RequestWakeUpAt_OnlyCalledForEarlierTasks) { std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(), TaskQueue::Spec("test")); - base::TimeDelta delay1 = base::TimeDelta::FromMilliseconds(10); - base::TimeDelta delay2 = base::TimeDelta::FromMilliseconds(20); - base::TimeDelta delay3 = base::TimeDelta::FromMilliseconds(30); - base::TimeDelta delay4 = base::TimeDelta::FromMilliseconds(1); + TimeDelta delay1 = TimeDelta::FromMilliseconds(10); + TimeDelta delay2 = TimeDelta::FromMilliseconds(20); + TimeDelta delay3 = TimeDelta::FromMilliseconds(30); + TimeDelta delay4 = TimeDelta::FromMilliseconds(1); // RequestWakeUpAt should always be called if there are no other wake-ups. - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, now + delay1)); task_queue_->SetDelayedWakeUpForTesting( @@ -198,13 +193,13 @@ TEST_F(TimeDomainTest, UnregisterQueue) { std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(), TaskQueue::Spec("test")); - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); - base::TimeTicks wake_up1 = now + base::TimeDelta::FromMilliseconds(10); + TimeTicks wake_up1 = now + TimeDelta::FromMilliseconds(10); EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, wake_up1)).Times(1); task_queue_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{wake_up1, 0}); - base::TimeTicks wake_up2 = now + base::TimeDelta::FromMilliseconds(100); + TimeTicks wake_up2 = now + TimeDelta::FromMilliseconds(100); task_queue2_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{wake_up2, 0}); @@ -231,34 +226,34 @@ TEST_F(TimeDomainTest, UnregisterQueue) { } TEST_F(TimeDomainTest, WakeUpReadyDelayedQueues) { - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); - base::TimeTicks now = time_domain_->Now(); - LazyNow lazy_now(now); - base::TimeTicks delayed_runtime = now + delay; + TimeDelta delay = TimeDelta::FromMilliseconds(50); + TimeTicks now = time_domain_->Now(); + LazyNow lazy_now_1(now); + TimeTicks delayed_runtime = now + delay; EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, delayed_runtime)); task_queue_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{delayed_runtime, 0}); - base::TimeTicks next_run_time; + TimeTicks next_run_time; ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); EXPECT_EQ(delayed_runtime, next_run_time); - time_domain_->WakeUpReadyDelayedQueues(&lazy_now); + time_domain_->WakeUpReadyDelayedQueues(&lazy_now_1); ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); EXPECT_EQ(delayed_runtime, next_run_time); time_domain_->SetNow(delayed_runtime); - lazy_now = time_domain_->CreateLazyNow(); - time_domain_->WakeUpReadyDelayedQueues(&lazy_now); + LazyNow lazy_now_2(time_domain_->CreateLazyNow()); + time_domain_->WakeUpReadyDelayedQueues(&lazy_now_2); ASSERT_FALSE(time_domain_->NextScheduledRunTime(&next_run_time)); } TEST_F(TimeDomainTest, WakeUpReadyDelayedQueuesWithIdenticalRuntimes) { int sequence_num = 0; - base::TimeDelta delay = base::TimeDelta::FromMilliseconds(50); - base::TimeTicks now = time_domain_->Now(); + TimeDelta delay = TimeDelta::FromMilliseconds(50); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); - base::TimeTicks delayed_runtime = now + delay; + TimeTicks delayed_runtime = now + delay; EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, delayed_runtime)); EXPECT_CALL(*time_domain_.get(), CancelWakeUpAt(delayed_runtime)); @@ -283,9 +278,9 @@ TEST_F(TimeDomainTest, WakeUpReadyDelayedQueuesWithIdenticalRuntimes) { } TEST_F(TimeDomainTest, CancelDelayedWork) { - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); - base::TimeTicks run_time = now + base::TimeDelta::FromMilliseconds(20); + TimeTicks run_time = now + TimeDelta::FromMilliseconds(20); EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, run_time)); task_queue_->SetDelayedWakeUpForTesting( @@ -296,7 +291,7 @@ TEST_F(TimeDomainTest, CancelDelayedWork) { EXPECT_EQ(task_queue_.get(), next_task_queue); EXPECT_CALL(*time_domain_.get(), CancelWakeUpAt(run_time)); - task_queue_->SetDelayedWakeUpForTesting(base::nullopt); + task_queue_->SetDelayedWakeUpForTesting(nullopt); EXPECT_FALSE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); } @@ -305,10 +300,10 @@ TEST_F(TimeDomainTest, CancelDelayedWork_TwoQueues) { std::make_unique<TaskQueueImplForTest>(nullptr, time_domain_.get(), TaskQueue::Spec("test")); - base::TimeTicks now = time_domain_->Now(); + TimeTicks now = time_domain_->Now(); LazyNow lazy_now(now); - base::TimeTicks run_time1 = now + base::TimeDelta::FromMilliseconds(20); - base::TimeTicks run_time2 = now + base::TimeDelta::FromMilliseconds(40); + TimeTicks run_time1 = now + TimeDelta::FromMilliseconds(20); + TimeTicks run_time2 = now + TimeDelta::FromMilliseconds(40); EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, run_time1)); task_queue_->SetDelayedWakeUpForTesting( internal::TaskQueueImpl::DelayedWakeUp{run_time1, 0}); @@ -323,13 +318,13 @@ TEST_F(TimeDomainTest, CancelDelayedWork_TwoQueues) { EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); EXPECT_EQ(task_queue_.get(), next_task_queue); - base::TimeTicks next_run_time; + TimeTicks next_run_time; ASSERT_TRUE(time_domain_->NextScheduledRunTime(&next_run_time)); EXPECT_EQ(run_time1, next_run_time); EXPECT_CALL(*time_domain_.get(), CancelWakeUpAt(run_time1)); EXPECT_CALL(*time_domain_.get(), RequestWakeUpAt(_, run_time2)); - task_queue_->SetDelayedWakeUpForTesting(base::nullopt); + task_queue_->SetDelayedWakeUpForTesting(nullopt); EXPECT_TRUE(time_domain_->NextScheduledTaskQueue(&next_task_queue)); EXPECT_EQ(task_queue2.get(), next_task_queue); @@ -344,5 +339,5 @@ TEST_F(TimeDomainTest, CancelDelayedWork_TwoQueues) { task_queue2->UnregisterTaskQueue(); } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.cc index 55d425b4dde..ba3252ab83a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.cc @@ -8,10 +8,10 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { -VirtualTimeDomain::VirtualTimeDomain(base::TimeTicks initial_time_ticks) +VirtualTimeDomain::VirtualTimeDomain(TimeTicks initial_time_ticks) : now_ticks_(initial_time_ticks), task_queue_manager_(nullptr) {} VirtualTimeDomain::~VirtualTimeDomain() = default; @@ -23,36 +23,34 @@ void VirtualTimeDomain::OnRegisterWithTaskQueueManager( } LazyNow VirtualTimeDomain::CreateLazyNow() const { - base::AutoLock lock(lock_); + AutoLock lock(lock_); return LazyNow(now_ticks_); } -base::TimeTicks VirtualTimeDomain::Now() const { - base::AutoLock lock(lock_); +TimeTicks VirtualTimeDomain::Now() const { + AutoLock lock(lock_); return now_ticks_; } -void VirtualTimeDomain::RequestWakeUpAt(base::TimeTicks now, - base::TimeTicks run_time) { +void VirtualTimeDomain::RequestWakeUpAt(TimeTicks now, TimeTicks run_time) { // We don't need to do anything here because the caller of AdvanceTo is // responsible for calling TaskQueueManagerImpl::MaybeScheduleImmediateWork if // needed. } -void VirtualTimeDomain::CancelWakeUpAt(base::TimeTicks run_time) { +void VirtualTimeDomain::CancelWakeUpAt(TimeTicks run_time) { // We ignore this because RequestWakeUpAt is a NOP. } -base::Optional<base::TimeDelta> VirtualTimeDomain::DelayTillNextTask( - LazyNow* lazy_now) { - return base::nullopt; +Optional<TimeDelta> VirtualTimeDomain::DelayTillNextTask(LazyNow* lazy_now) { + return nullopt; } void VirtualTimeDomain::AsValueIntoInternal( - base::trace_event::TracedValue* state) const {} + trace_event::TracedValue* state) const {} -void VirtualTimeDomain::AdvanceNowTo(base::TimeTicks now) { - base::AutoLock lock(lock_); +void VirtualTimeDomain::AdvanceNowTo(TimeTicks now) { + AutoLock lock(lock_); DCHECK_GE(now, now_ticks_); now_ticks_ = now; } @@ -65,5 +63,5 @@ const char* VirtualTimeDomain::GetName() const { return "VirtualTimeDomain"; } -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h index c4f37699830..6a4ca9de6a3 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h @@ -10,46 +10,45 @@ #include "base/threading/thread_checker.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class PLATFORM_EXPORT VirtualTimeDomain : public TimeDomain { public: - explicit VirtualTimeDomain(base::TimeTicks initial_time_ticks); + explicit VirtualTimeDomain(TimeTicks initial_time_ticks); ~VirtualTimeDomain() override; // TimeDomain implementation: LazyNow CreateLazyNow() const override; - base::TimeTicks Now() const override; - base::Optional<base::TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; + TimeTicks Now() const override; + Optional<TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; const char* GetName() const override; // Advances this time domain to |now|. NOTE |now| is supposed to be // monotonically increasing. NOTE it's the responsibility of the caller to // call TaskQueueManager::MaybeScheduleImmediateWork if needed. - void AdvanceNowTo(base::TimeTicks now); + void AdvanceNowTo(TimeTicks now); protected: void OnRegisterWithTaskQueueManager( TaskQueueManagerImpl* task_queue_manager) override; - void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override; - void CancelWakeUpAt(base::TimeTicks run_time) override; - void AsValueIntoInternal( - base::trace_event::TracedValue* state) const override; + void RequestWakeUpAt(TimeTicks now, TimeTicks run_time) override; + void CancelWakeUpAt(TimeTicks run_time) override; + void AsValueIntoInternal(trace_event::TracedValue* state) const override; void RequestDoWork(); private: - mutable base::Lock lock_; // Protects |now_ticks_| - base::TimeTicks now_ticks_; + mutable Lock lock_; // Protects |now_ticks_| + TimeTicks now_ticks_; TaskQueueManagerImpl* task_queue_manager_; // NOT OWNED - base::Closure do_work_closure_; + Closure do_work_closure_; DISALLOW_COPY_AND_ASSIGN(VirtualTimeDomain); }; -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_VIRTUAL_TIME_DOMAIN_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.cc index 462d5c07eb2..f2319bc5b1d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.cc @@ -6,8 +6,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { WorkQueue::WorkQueue(TaskQueueImpl* task_queue, @@ -15,8 +15,8 @@ WorkQueue::WorkQueue(TaskQueueImpl* task_queue, QueueType queue_type) : task_queue_(task_queue), name_(name), queue_type_(queue_type) {} -void WorkQueue::AsValueInto(base::TimeTicks now, - base::trace_event::TracedValue* state) const { +void WorkQueue::AsValueInto(TimeTicks now, + trace_event::TracedValue* state) const { for (const TaskQueueImpl::Task& task : tasks_) { TaskQueueImpl::TaskAsValueInto(task, now, state); } @@ -81,7 +81,7 @@ void WorkQueue::Push(TaskQueueImpl::Task task) { } void WorkQueue::PushNonNestableTaskToFront(TaskQueueImpl::Task task) { - DCHECK(task.nestable == base::Nestable::kNonNestable); + DCHECK(task.nestable == Nestable::kNonNestable); bool was_empty = tasks_.empty(); bool was_blocked = BlockedByFence(); @@ -130,7 +130,8 @@ TaskQueueImpl::Task WorkQueue::TakeTaskFromWorkQueue() { DCHECK(work_queue_sets_); DCHECK(!tasks_.empty()); - TaskQueueImpl::Task pending_task = tasks_.TakeFirst(); + TaskQueueImpl::Task pending_task = std::move(tasks_.front()); + tasks_.pop_front(); // NB immediate tasks have a different pipeline to delayed ones. if (queue_type_ == QueueType::kImmediate && tasks_.empty()) { // Short-circuit the queue reload so that OnPopQueue does the right thing. @@ -230,5 +231,5 @@ void WorkQueue::PopTaskForTesting() { } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.h index 9b3b8010aec..b94b660474c 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue.h @@ -9,15 +9,15 @@ #include <set> +#include "base/task/sequence_manager/sequenced_task_source.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "third_party/blink/renderer/platform/scheduler/base/enqueue_order.h" #include "third_party/blink/renderer/platform/scheduler/base/intrusive_heap.h" -#include "third_party/blink/renderer/platform/scheduler/base/sequenced_task_source.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { class WorkQueueSets; @@ -33,7 +33,7 @@ class WorkQueueSets; // throttling mechanisms. class PLATFORM_EXPORT WorkQueue { public: - using QueueType = SequencedTaskSource::WorkType; + using QueueType = internal::TaskQueueImpl::WorkQueueType; // Note |task_queue| can be null if queue_type is kNonNestable. WorkQueue(TaskQueueImpl* task_queue, const char* name, QueueType queue_type); @@ -46,8 +46,7 @@ class PLATFORM_EXPORT WorkQueue { // Assigns the current set index. void AssignSetIndex(size_t work_queue_set_index); - void AsValueInto(base::TimeTicks now, - base::trace_event::TracedValue* state) const; + void AsValueInto(TimeTicks now, trace_event::TracedValue* state) const; // Returns true if the |tasks_| is empty. This method ignores any fences. bool Empty() const { return tasks_.empty(); } @@ -150,7 +149,7 @@ class PLATFORM_EXPORT WorkQueue { }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc index 04f64aaa021..0d34d146ba1 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.cc @@ -6,8 +6,8 @@ #include "base/logging.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { WorkQueueSets::WorkQueueSets(size_t num_sets, const char* name) @@ -168,5 +168,5 @@ bool WorkQueueSets::ContainsWorkQueueForTest( #endif } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h index aa51cacf170..9244a691b10 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h @@ -18,8 +18,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { // There is a WorkQueueSet for each scheduler priority and each WorkQueueSet @@ -98,7 +98,7 @@ class PLATFORM_EXPORT WorkQueueSets { }; } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_BASE_WORK_QUEUE_SETS_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets_unittest.cc index fe4794da7b9..237f719d33b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_sets_unittest.cc @@ -10,8 +10,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { class TimeDomain; namespace internal { @@ -37,25 +37,23 @@ class WorkQueueSetsTest : public testing::Test { WorkQueue* NewTaskQueue(const char* queue_name) { WorkQueue* queue = new WorkQueue(nullptr, "test", WorkQueue::QueueType::kImmediate); - work_queues_.push_back(base::WrapUnique(queue)); + work_queues_.push_back(WrapUnique(queue)); work_queue_sets_->AddQueue(queue, TaskQueue::kControlPriority); return queue; } TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) { TaskQueueImpl::Task fake_task( - TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE), - base::TimeTicks(), 0); + TaskQueue::PostedTask(BindOnce([] {}), FROM_HERE), TimeTicks(), 0); fake_task.set_enqueue_order(enqueue_order); return fake_task; } TaskQueueImpl::Task FakeNonNestableTaskWithEnqueueOrder(int enqueue_order) { TaskQueueImpl::Task fake_task( - TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE), - base::TimeTicks(), 0); + TaskQueue::PostedTask(BindOnce([] {}), FROM_HERE), TimeTicks(), 0); fake_task.set_enqueue_order(enqueue_order); - fake_task.nestable = base::Nestable::kNonNestable; + fake_task.nestable = Nestable::kNonNestable; return fake_task; } @@ -325,5 +323,5 @@ TEST_F(WorkQueueSetsTest, PushNonNestableTaskToFront) { } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_unittest.cc index 91624b2a65b..552662fd7f3 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/base/work_queue_unittest.cc @@ -13,8 +13,8 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/work_queue_sets.h" -namespace blink { -namespace scheduler { +namespace base { +namespace sequence_manager { namespace internal { namespace { void NopTask() {} @@ -24,7 +24,7 @@ struct Cancelable { void NopTask() {} - base::WeakPtrFactory<Cancelable> weak_ptr_factory; + WeakPtrFactory<Cancelable> weak_ptr_factory; }; } // namespace @@ -46,29 +46,27 @@ class WorkQueueTest : public testing::Test { protected: TaskQueueImpl::Task FakeCancelableTaskWithEnqueueOrder( int enqueue_order, - base::WeakPtr<Cancelable> weak_ptr) { + WeakPtr<Cancelable> weak_ptr) { TaskQueueImpl::Task fake_task( - TaskQueue::PostedTask(base::BindOnce(&Cancelable::NopTask, weak_ptr), + TaskQueue::PostedTask(BindOnce(&Cancelable::NopTask, weak_ptr), FROM_HERE), - base::TimeTicks(), 0); + TimeTicks(), 0); fake_task.set_enqueue_order(enqueue_order); return fake_task; } TaskQueueImpl::Task FakeTaskWithEnqueueOrder(int enqueue_order) { TaskQueueImpl::Task fake_task( - TaskQueue::PostedTask(base::BindOnce(&NopTask), FROM_HERE), - base::TimeTicks(), 0); + TaskQueue::PostedTask(BindOnce(&NopTask), FROM_HERE), TimeTicks(), 0); fake_task.set_enqueue_order(enqueue_order); return fake_task; } TaskQueueImpl::Task FakeNonNestableTaskWithEnqueueOrder(int enqueue_order) { TaskQueueImpl::Task fake_task( - TaskQueue::PostedTask(base::BindOnce(&NopTask), FROM_HERE), - base::TimeTicks(), 0); + TaskQueue::PostedTask(BindOnce(&NopTask), FROM_HERE), TimeTicks(), 0); fake_task.set_enqueue_order(enqueue_order); - fake_task.nestable = base::Nestable::kNonNestable; + fake_task.nestable = Nestable::kNonNestable; return fake_task; } @@ -470,5 +468,5 @@ TEST_F(WorkQueueTest, RemoveAllCanceledTasksFromFrontTasksNotCanceled) { } } // namespace internal -} // namespace scheduler -} // namespace blink +} // namespace sequence_manager +} // namespace base diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.cc index 37757604c31..1f221201b89 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.cc @@ -14,7 +14,7 @@ CompositorMetricsHelper::~CompositorMetricsHelper() {} void CompositorMetricsHelper::RecordTaskMetrics( WorkerTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.h index a758e587cfd..f1e07b28d20 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/compositor_metrics_helper.h @@ -17,7 +17,7 @@ class PLATFORM_EXPORT CompositorMetricsHelper : public MetricsHelper { ~CompositorMetricsHelper(); void RecordTaskMetrics(WorkerTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/features.h b/chromium/third_party/blink/renderer/platform/scheduler/child/features.h index a2951a685a7..05ddbce5a92 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/features.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/features.h @@ -13,6 +13,9 @@ namespace scheduler { const base::Feature kHighPriorityInput{"BlinkSchedulerHighPriorityInput", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kDedicatedWorkerThrottling{ + "kBlinkSchedulerWorkerThrottling", base::FEATURE_DISABLED_BY_DEFAULT}; + } // namespace scheduler } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc index 776ca644891..00779dfa5c9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc @@ -4,15 +4,15 @@ #include "third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper.h" +#include "base/task/sequence_manager/lazy_now.h" #include "base/test/simple_test_tick_clock.h" #include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/child/idle_helper.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" namespace blink { namespace scheduler { @@ -32,9 +32,10 @@ class IdleCanceledDelayedTaskSweeperTest : public testing::Test, IdleCanceledDelayedTaskSweeperTest() : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)), scheduler_helper_(new MainThreadSchedulerHelper( - TaskQueueManagerForTest::Create(nullptr, - mock_task_runner_, - &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, + mock_task_runner_, + &clock_), nullptr)), idle_helper_( new IdleHelper(scheduler_helper_.get(), @@ -69,7 +70,7 @@ class IdleCanceledDelayedTaskSweeperTest : public testing::Test, void IsNotQuiescent() override {} void OnIdlePeriodStarted() override {} void OnIdlePeriodEnded() override {} - void OnPendingTasksChanged(bool has_tasks) {} + void OnPendingTasksChanged(bool has_tasks) override {} protected: base::SimpleTestTickClock clock_; @@ -79,7 +80,7 @@ class IdleCanceledDelayedTaskSweeperTest : public testing::Test, std::unique_ptr<IdleHelper> idle_helper_; std::unique_ptr<IdleCanceledDelayedTaskSweeper> idle_canceled_delayed_taks_sweeper_; - scoped_refptr<TaskQueue> default_task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue_; DISALLOW_COPY_AND_ASSIGN(IdleCanceledDelayedTaskSweeperTest); }; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.cc index 56025c7c53f..11947de63d4 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.cc @@ -10,11 +10,14 @@ #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + IdleHelper::IdleHelper( SchedulerHelper* helper, Delegate* delegate, @@ -35,8 +38,10 @@ IdleHelper::IdleHelper( on_idle_task_posted_closure_.Reset(base::BindRepeating( &IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_)); - idle_task_runner_ = - base::MakeRefCounted<SingleThreadIdleTaskRunner>(idle_queue_, this); + idle_task_runner_ = base::MakeRefCounted<SingleThreadIdleTaskRunner>( + TaskQueueWithTaskType::Create(idle_queue_, + TaskType::kMainThreadTaskQueueIdle), + this); // This fence will block any idle tasks from running. idle_queue_->InsertFence(TaskQueue::InsertFencePosition::kBeginningOfTime); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.h index 8f0ec9a79c5..ea5ac0a58d5 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper.h @@ -97,7 +97,7 @@ class PLATFORM_EXPORT IdleHelper : public base::MessageLoop::TaskObserver, Delegate* delegate, const char* idle_period_tracing_name, base::TimeDelta required_quiescence_duration_before_long_idle_period, - scoped_refptr<TaskQueue> idle_queue); + scoped_refptr<base::sequence_manager::TaskQueue> idle_queue); ~IdleHelper() override; // Prevents any further idle tasks from running. @@ -157,7 +157,9 @@ class PLATFORM_EXPORT IdleHelper : public base::MessageLoop::TaskObserver, friend class idle_helper_unittest::BaseIdleHelperTest; friend class idle_helper_unittest::IdleHelperTest; - const scoped_refptr<TaskQueue>& idle_queue() const { return idle_queue_; } + const scoped_refptr<base::sequence_manager::TaskQueue>& idle_queue() const { + return idle_queue_; + } class State { public: @@ -225,7 +227,7 @@ class PLATFORM_EXPORT IdleHelper : public base::MessageLoop::TaskObserver, SchedulerHelper* helper_; // NOT OWNED Delegate* delegate_; // NOT OWNED - scoped_refptr<TaskQueue> idle_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> idle_queue_; scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; CancelableClosureHolder enable_next_long_idle_period_closure_; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper_unittest.cc index 98b4c60d9cc..2e7b506202d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/idle_helper_unittest.cc @@ -18,9 +18,9 @@ #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" using testing::_; using testing::AnyNumber; @@ -31,6 +31,10 @@ using testing::Return; namespace blink { namespace scheduler { + +using base::sequence_manager::TaskQueue; +using base::sequence_manager::TaskQueueManager; + // To avoid symbol collisions in jumbo builds. namespace idle_helper_unittest { @@ -197,13 +201,13 @@ class BaseIdleHelperTest : public testing::Test { : new cc::OrderedSimpleTaskRunner(&clock_, false)), message_loop_(message_loop) { std::unique_ptr<TaskQueueManager> task_queue_manager = - TaskQueueManagerForTest::Create( + base::sequence_manager::TaskQueueManagerForTest::Create( message_loop, message_loop ? message_loop->task_runner() : mock_task_runner_, &clock_); task_queue_manager_ = task_queue_manager.get(); - scheduler_helper_ = std::make_unique<WorkerSchedulerHelper>( - std::move(task_queue_manager), nullptr); + scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>( + std::move(task_queue_manager), nullptr, TaskType::kInternalTest); idle_helper_ = std::make_unique<IdleHelperForTest>( scheduler_helper_.get(), required_quiescence_duration_before_long_idle_period, @@ -306,7 +310,7 @@ class BaseIdleHelperTest : public testing::Test { scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<base::MessageLoop> message_loop_; - std::unique_ptr<WorkerSchedulerHelper> scheduler_helper_; + std::unique_ptr<NonMainThreadSchedulerHelper> scheduler_helper_; TaskQueueManager* task_queue_manager_; // Owned by scheduler_helper_. std::unique_ptr<IdleHelperForTest> idle_helper_; scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; @@ -476,7 +480,6 @@ class IdleHelperWithMessageLoopTest : public BaseIdleHelperTest { void PostFromNestedRunloop( std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get()); for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) { if (pair.second) { idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first)); @@ -488,7 +491,7 @@ class IdleHelperWithMessageLoopTest : public BaseIdleHelperTest { idle_helper_->StartIdlePeriod( IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(), clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10)); - base::RunLoop().RunUntilIdle(); + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); } void SetUp() override { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.cc index de044878b78..2cccc61835d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.cc @@ -37,8 +37,8 @@ MetricsHelper::MetricsHelper(WebThreadType thread_type) MetricsHelper::~MetricsHelper() {} bool MetricsHelper::ShouldDiscardTask( - TaskQueue* queue, - const TaskQueue::Task& task, + base::sequence_manager::TaskQueue* queue, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { @@ -48,8 +48,8 @@ bool MetricsHelper::ShouldDiscardTask( } void MetricsHelper::RecordCommonTaskMetrics( - TaskQueue* queue, - const TaskQueue::Task& task, + base::sequence_manager::TaskQueue* queue, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.h index 83794f48527..e22f12a07bd 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper.h @@ -11,17 +11,21 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h" +namespace base { +namespace sequence_manager { +class TaskQueue; +} +} // namespace base + namespace blink { namespace scheduler { -class TaskQueue; - // Helper class to take care of task metrics shared between main thread // and worker threads of the renderer process, including per-thread // task metrics. // // Each thread-specific scheduler should have its own subclass of MetricsHelper -// (RendererMetricsHelper, WorkerMetricsHelper, etc) and should call +// (MainThreadMetricsHelper, WorkerMetricsHelper, etc) and should call // RecordCommonTaskMetrics manually. // Note that this is code reuse, not data reuse -- each thread should have its // own instantiation of this class. @@ -31,18 +35,19 @@ class PLATFORM_EXPORT MetricsHelper { ~MetricsHelper(); protected: - bool ShouldDiscardTask(TaskQueue* queue, - const TaskQueue::Task& task, + bool ShouldDiscardTask(base::sequence_manager::TaskQueue* queue, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time); // Record task metrics which are shared between threads. - void RecordCommonTaskMetrics(TaskQueue* queue, - const TaskQueue::Task& task, - base::TimeTicks start_time, - base::TimeTicks end_time, - base::Optional<base::TimeDelta> thread_time); + void RecordCommonTaskMetrics( + base::sequence_manager::TaskQueue* queue, + const base::sequence_manager::TaskQueue::Task& task, + base::TimeTicks start_time, + base::TimeTicks end_time, + base::Optional<base::TimeDelta> thread_time); protected: WebThreadType thread_type_; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper_unittest.cc index f232dc424ce..a1d54dc539c 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/metrics_helper_unittest.cc @@ -7,6 +7,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using base::sequence_manager::TaskQueue; + namespace blink { namespace scheduler { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc new file mode 100644 index 00000000000..409682767e7 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.cc @@ -0,0 +1,54 @@ +// 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/child/task_queue_with_task_type.h" + +#include <utility> + +#include "base/bind.h" +#include "base/location.h" +#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" + +namespace blink { +namespace scheduler { + +scoped_refptr<TaskQueueWithTaskType> TaskQueueWithTaskType::Create( + scoped_refptr<base::sequence_manager::TaskQueue> task_queue, + TaskType task_type) { + return base::WrapRefCounted( + new TaskQueueWithTaskType(std::move(task_queue), task_type)); +} + +bool TaskQueueWithTaskType::RunsTasksInCurrentSequence() const { + return task_queue_->RunsTasksInCurrentSequence(); +} + +TaskQueueWithTaskType::TaskQueueWithTaskType( + scoped_refptr<base::sequence_manager::TaskQueue> task_queue, + TaskType task_type) + : task_queue_(std::move(task_queue)), task_type_(task_type) {} + +TaskQueueWithTaskType::~TaskQueueWithTaskType() = default; + +bool TaskQueueWithTaskType::PostDelayedTask(const base::Location& location, + base::OnceClosure task, + base::TimeDelta delay) { + return task_queue_->PostTaskWithMetadata( + base::sequence_manager::TaskQueue::PostedTask( + std::move(task), location, delay, base::Nestable::kNestable, + static_cast<int>(task_type_))); +} + +bool TaskQueueWithTaskType::PostNonNestableDelayedTask( + const base::Location& location, + base::OnceClosure task, + base::TimeDelta delay) { + return task_queue_->PostTaskWithMetadata( + base::sequence_manager::TaskQueue::PostedTask( + std::move(task), location, delay, base::Nestable::kNonNestable, + static_cast<int>(task_type_))); +} + +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h index e7025d30388..4232da92248 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h @@ -2,8 +2,8 @@ // 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_CHILD_TASK_RUNNER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_TASK_RUNNER_IMPL_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_TASK_QUEUE_WITH_TASK_TYPE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_TASK_QUEUE_WITH_TASK_TYPE_H_ #include <memory> @@ -15,21 +15,25 @@ #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/platform_export.h" +namespace base { +namespace sequence_manager { +class TaskQueue; +} +} // namespace base + namespace blink { namespace scheduler { -class TaskQueue; -class PLATFORM_EXPORT TaskRunnerImpl : public base::SingleThreadTaskRunner { +class PLATFORM_EXPORT TaskQueueWithTaskType + : public base::SingleThreadTaskRunner { public: - static scoped_refptr<TaskRunnerImpl> Create( - scoped_refptr<TaskQueue> task_queue, + static scoped_refptr<TaskQueueWithTaskType> Create( + scoped_refptr<base::sequence_manager::TaskQueue> task_queue, TaskType task_type); // base::SingleThreadTaskRunner implementation: bool RunsTasksInCurrentSequence() const override; - TaskQueue* GetTaskQueue() const { return task_queue_.get(); } - protected: bool PostDelayedTask(const base::Location&, base::OnceClosure, @@ -39,13 +43,15 @@ class PLATFORM_EXPORT TaskRunnerImpl : public base::SingleThreadTaskRunner { base::TimeDelta) override; private: - TaskRunnerImpl(scoped_refptr<TaskQueue> task_queue, TaskType task_type); - ~TaskRunnerImpl() override; + TaskQueueWithTaskType( + scoped_refptr<base::sequence_manager::TaskQueue> task_queue, + TaskType task_type); + ~TaskQueueWithTaskType() override; - scoped_refptr<TaskQueue> task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> task_queue_; TaskType task_type_; - DISALLOW_COPY_AND_ASSIGN(TaskRunnerImpl); + DISALLOW_COPY_AND_ASSIGN(TaskQueueWithTaskType); }; } // namespace scheduler diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.cc deleted file mode 100644 index 56ec26c2728..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/task_runner_impl.cc +++ /dev/null @@ -1,50 +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/child/task_runner_impl.h" - -#include <utility> - -#include "base/bind.h" -#include "base/location.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" - -namespace blink { -namespace scheduler { - -scoped_refptr<TaskRunnerImpl> TaskRunnerImpl::Create( - scoped_refptr<TaskQueue> task_queue, - TaskType task_type) { - return base::WrapRefCounted( - new TaskRunnerImpl(std::move(task_queue), task_type)); -} - -bool TaskRunnerImpl::RunsTasksInCurrentSequence() const { - return task_queue_->RunsTasksInCurrentSequence(); -} - -TaskRunnerImpl::TaskRunnerImpl(scoped_refptr<TaskQueue> task_queue, - TaskType task_type) - : task_queue_(std::move(task_queue)), task_type_(task_type) {} - -TaskRunnerImpl::~TaskRunnerImpl() = default; - -bool TaskRunnerImpl::PostDelayedTask(const base::Location& location, - base::OnceClosure task, - base::TimeDelta delay) { - return task_queue_->PostTaskWithMetadata(TaskQueue::PostedTask( - std::move(task), location, delay, base::Nestable::kNestable, - static_cast<int>(task_type_))); -} - -bool TaskRunnerImpl::PostNonNestableDelayedTask(const base::Location& location, - base::OnceClosure task, - base::TimeDelta delay) { - return task_queue_->PostTaskWithMetadata(TaskQueue::PostedTask( - std::move(task), location, delay, base::Nestable::kNonNestable, - static_cast<int>(task_type_))); -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc deleted file mode 100644 index eb441b529bc..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.cc +++ /dev/null @@ -1,87 +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/child/web_scheduler_impl.h" - -#include "base/bind.h" -#include "base/location.h" -#include "base/single_thread_task_runner.h" -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" -#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" - -namespace blink { -namespace scheduler { - -// TODO(kraynov): Ditch kDeprecatedNone here. -WebSchedulerImpl::WebSchedulerImpl( - WebThreadScheduler* thread_scheduler, - scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, - scoped_refptr<TaskQueue> v8_task_runner) - : thread_scheduler_(thread_scheduler), - idle_task_runner_(idle_task_runner), - v8_task_runner_(TaskRunnerImpl::Create(std::move(v8_task_runner), - TaskType::kDeprecatedNone)) {} - -WebSchedulerImpl::~WebSchedulerImpl() = default; - -void WebSchedulerImpl::Shutdown() { - thread_scheduler_->Shutdown(); -} - -bool WebSchedulerImpl::ShouldYieldForHighPriorityWork() { - return thread_scheduler_->ShouldYieldForHighPriorityWork(); -} - -bool WebSchedulerImpl::CanExceedIdleDeadlineIfRequired() { - return thread_scheduler_->CanExceedIdleDeadlineIfRequired(); -} - -void WebSchedulerImpl::RunIdleTask(blink::WebThread::IdleTask task, - base::TimeTicks deadline) { - std::move(task).Run((deadline - base::TimeTicks()).InSecondsF()); -} - -void WebSchedulerImpl::PostIdleTask(const base::Location& location, - blink::WebThread::IdleTask task) { - DCHECK(idle_task_runner_); - idle_task_runner_->PostIdleTask( - location, - base::BindOnce(&WebSchedulerImpl::RunIdleTask, std::move(task))); -} - -void WebSchedulerImpl::PostNonNestableIdleTask( - const base::Location& location, - blink::WebThread::IdleTask task) { - DCHECK(idle_task_runner_); - idle_task_runner_->PostNonNestableIdleTask( - location, - base::BindOnce(&WebSchedulerImpl::RunIdleTask, std::move(task))); -} - -base::SingleThreadTaskRunner* WebSchedulerImpl::V8TaskRunner() { - return v8_task_runner_.get(); -} - -base::SingleThreadTaskRunner* WebSchedulerImpl::CompositorTaskRunner() { - return nullptr; -} - -std::unique_ptr<blink::PageScheduler> WebSchedulerImpl::CreatePageScheduler( - PageScheduler::Delegate* delegate) { - NOTREACHED(); - return nullptr; -} - -std::unique_ptr<WebSchedulerImpl::RendererPauseHandle> -WebSchedulerImpl::PauseScheduler() { - return nullptr; -} - -base::TimeTicks WebSchedulerImpl::MonotonicallyIncreasingVirtualTime() const { - return base::TimeTicks::Now(); -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h deleted file mode 100644 index 174b7174821..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h +++ /dev/null @@ -1,67 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEB_SCHEDULER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEB_SCHEDULER_IMPL_H_ - -#include <memory> - -#include "base/macros.h" -#include "base/memory/scoped_refptr.h" -#include "base/time/time.h" -#include "third_party/blink/public/platform/web_thread.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" - -namespace blink { -namespace scheduler { - -class SingleThreadIdleTaskRunner; -class TaskRunnerImpl; -class WebThreadScheduler; - -class PLATFORM_EXPORT WebSchedulerImpl : public WebScheduler { - public: - WebSchedulerImpl(WebThreadScheduler* thread_scheduler, - scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, - scoped_refptr<TaskQueue> v8_task_runner); - ~WebSchedulerImpl() override; - - // WebScheduler implementation: - void Shutdown() override; - bool ShouldYieldForHighPriorityWork() override; - bool CanExceedIdleDeadlineIfRequired() override; - void PostIdleTask(const base::Location& location, - WebThread::IdleTask task) override; - void PostNonNestableIdleTask(const base::Location& location, - WebThread::IdleTask task) override; - base::SingleThreadTaskRunner* V8TaskRunner() override; - base::SingleThreadTaskRunner* CompositorTaskRunner() override; - std::unique_ptr<PageScheduler> CreatePageScheduler( - PageScheduler::Delegate*) override; - std::unique_ptr<RendererPauseHandle> PauseScheduler() override - WARN_UNUSED_RESULT; - void AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType type) override {} - void RemovePendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType type) override {} - - // Returns TimeTicks::Now() by default. - base::TimeTicks MonotonicallyIncreasingVirtualTime() const override; - - private: - static void RunIdleTask(WebThread::IdleTask task, base::TimeTicks deadline); - - WebThreadScheduler* thread_scheduler_; // NOT OWNED - scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; - scoped_refptr<TaskRunnerImpl> v8_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(WebSchedulerImpl); -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEB_SCHEDULER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc index ad1ce16ce72..8b0a45fa229 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_base.cc @@ -12,6 +12,7 @@ #include "base/bind_helpers.h" #include "base/location.h" #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" #include "base/pending_task.h" #include "base/threading/platform_thread.h" #include "third_party/blink/public/platform/scheduler/single_thread_idle_task_runner.h" @@ -67,23 +68,24 @@ void WebThreadBase::RemoveTaskObserver(TaskObserver* observer) { task_observer_map_.erase(iter); } -void WebThreadBase::AddTaskTimeObserver(TaskTimeObserver* task_time_observer) { +void WebThreadBase::AddTaskTimeObserver( + base::sequence_manager::TaskTimeObserver* task_time_observer) { AddTaskTimeObserverInternal(task_time_observer); } void WebThreadBase::RemoveTaskTimeObserver( - TaskTimeObserver* task_time_observer) { + base::sequence_manager::TaskTimeObserver* task_time_observer) { RemoveTaskTimeObserverInternal(task_time_observer); } void WebThreadBase::AddTaskObserverInternal( base::MessageLoop::TaskObserver* observer) { - base::MessageLoop::current()->AddTaskObserver(observer); + base::MessageLoopCurrent::Get()->AddTaskObserver(observer); } void WebThreadBase::RemoveTaskObserverInternal( base::MessageLoop::TaskObserver* observer) { - base::MessageLoop::current()->RemoveTaskObserver(observer); + base::MessageLoopCurrent::Get()->RemoveTaskObserver(observer); } // static @@ -118,7 +120,8 @@ class WebThreadForCompositor : public WebThreadImplForWorkerScheduler { std::unique_ptr<blink::scheduler::NonMainThreadScheduler> CreateNonMainThreadScheduler() override { return std::make_unique<CompositorThreadScheduler>( - GetThread(), TaskQueueManager::TakeOverCurrentThread()); + GetThread(), + base::sequence_manager::TaskQueueManager::TakeOverCurrentThread()); } DISALLOW_COPY_AND_ASSIGN(WebThreadForCompositor); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc index 8b1777f7f69..55583882fcd 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc @@ -10,8 +10,9 @@ #include "base/single_thread_task_runner.h" #include "base/synchronization/waitable_event.h" #include "base/time/default_tick_clock.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" @@ -64,12 +65,10 @@ void WebThreadImplForWorkerScheduler::InitOnThread( non_main_thread_scheduler_ = CreateNonMainThreadScheduler(); non_main_thread_scheduler_->Init(); task_queue_ = non_main_thread_scheduler_->DefaultTaskQueue(); + task_runner_ = TaskQueueWithTaskType::Create( + task_queue_, TaskType::kWorkerThreadTaskQueueDefault); idle_task_runner_ = non_main_thread_scheduler_->IdleTaskRunner(); - web_scheduler_.reset( - new WebSchedulerImpl(non_main_thread_scheduler_.get(), - non_main_thread_scheduler_->IdleTaskRunner(), - non_main_thread_scheduler_->DefaultTaskQueue())); - base::MessageLoop::current()->AddDestructionObserver(this); + base::MessageLoopCurrent::Get()->AddDestructionObserver(this); completion->Signal(); } @@ -78,8 +77,8 @@ void WebThreadImplForWorkerScheduler::ShutdownOnThread( was_shutdown_on_thread_.Set(); task_queue_ = nullptr; + task_runner_ = nullptr; idle_task_runner_ = nullptr; - web_scheduler_ = nullptr; non_main_thread_scheduler_ = nullptr; if (completion) @@ -100,8 +99,8 @@ blink::PlatformThreadId WebThreadImplForWorkerScheduler::ThreadId() const { return thread_->GetThreadId(); } -blink::WebScheduler* WebThreadImplForWorkerScheduler::Scheduler() const { - return web_scheduler_.get(); +blink::ThreadScheduler* WebThreadImplForWorkerScheduler::Scheduler() const { + return non_main_thread_scheduler_.get(); } SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::GetIdleTaskRunner() @@ -111,7 +110,7 @@ SingleThreadIdleTaskRunner* WebThreadImplForWorkerScheduler::GetIdleTaskRunner() scoped_refptr<base::SingleThreadTaskRunner> WebThreadImplForWorkerScheduler::GetTaskRunner() const { - return task_queue_; + return task_runner_; } void WebThreadImplForWorkerScheduler::AddTaskObserverInternal( diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h index 3643ac566c5..e68d0a8e68b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.h @@ -6,37 +6,41 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEBTHREAD_IMPL_FOR_WORKER_SCHEDULER_H_ #include "base/message_loop/message_loop.h" +#include "base/message_loop/message_loop_current.h" +#include "base/single_thread_task_runner.h" #include "base/synchronization/atomic_flag.h" #include "base/threading/thread.h" #include "third_party/blink/public/platform/scheduler/child/webthread_base.h" #include "third_party/blink/public/platform/web_private_ptr.h" namespace base { +namespace sequence_manager { +class TaskQueue; +} class WaitableEvent; } namespace blink { -class WebScheduler; +class ThreadScheduler; } namespace blink { namespace scheduler { + class SingleThreadIdleTaskRunner; -class TaskQueue; -class WebSchedulerImpl; class NonMainThreadScheduler; class WorkerSchedulerProxy; class PLATFORM_EXPORT WebThreadImplForWorkerScheduler : public WebThreadBase, - public base::MessageLoop::DestructionObserver { + public base::MessageLoopCurrent::DestructionObserver { public: explicit WebThreadImplForWorkerScheduler( const WebThreadCreationParams& params); ~WebThreadImplForWorkerScheduler() override; // WebThread implementation. - WebScheduler* Scheduler() const override; + ThreadScheduler* Scheduler() const override; PlatformThreadId ThreadId() const override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override; @@ -44,7 +48,7 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler scheduler::SingleThreadIdleTaskRunner* GetIdleTaskRunner() const override; void Init() override; - // base::MessageLoop::DestructionObserver implementation. + // base::MessageLoopCurrent::DestructionObserver implementation. void WillDestroyCurrentMessageLoop() override; scheduler::NonMainThreadScheduler* GetNonMainThreadScheduler() { @@ -74,9 +78,9 @@ class PLATFORM_EXPORT WebThreadImplForWorkerScheduler const WebThreadType thread_type_; std::unique_ptr<scheduler::WorkerSchedulerProxy> worker_scheduler_proxy_; std::unique_ptr<scheduler::NonMainThreadScheduler> non_main_thread_scheduler_; - std::unique_ptr<scheduler::WebSchedulerImpl> web_scheduler_; scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner_; - scoped_refptr<TaskQueue> task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> task_queue_; + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> idle_task_runner_; base::AtomicFlag was_shutdown_on_thread_; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc index c7c44701b78..cc1dad6ce5b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc @@ -10,7 +10,6 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" #include "third_party/blink/renderer/platform/web_task_runner.h" @@ -62,9 +61,7 @@ void RemoveTaskObserver(WebThreadImplForWorkerScheduler* thread, } void ShutdownOnThread(WebThreadImplForWorkerScheduler* thread) { - WebSchedulerImpl* web_scheduler_impl = - static_cast<WebSchedulerImpl*>(thread->Scheduler()); - web_scheduler_impl->Shutdown(); + thread->Scheduler()->Shutdown(); } class WebThreadImplForWorkerSchedulerTest : public testing::Test { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.cc deleted file mode 100644 index 891a95f1162..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.cc +++ /dev/null @@ -1,88 +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/scheduler/child/worker_global_scope_scheduler.h" - -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" -#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h" - -namespace blink { -namespace scheduler { - -WorkerGlobalScopeScheduler::WorkerGlobalScopeScheduler( - NonMainThreadScheduler* non_main_thread_scheduler) { - task_queue_ = non_main_thread_scheduler->CreateTaskRunner(); -} - -WorkerGlobalScopeScheduler::~WorkerGlobalScopeScheduler() { -#if DCHECK_IS_ON() - DCHECK(is_disposed_); -#endif -} - -std::unique_ptr<FrameOrWorkerGlobalScopeScheduler::ActiveConnectionHandle> -WorkerGlobalScopeScheduler::OnActiveConnectionCreated() { - return nullptr; -} - -void WorkerGlobalScopeScheduler::Dispose() { - task_queue_->ShutdownTaskQueue(); -#if DCHECK_IS_ON() - is_disposed_ = true; -#endif -} - -scoped_refptr<base::SingleThreadTaskRunner> -WorkerGlobalScopeScheduler::GetTaskRunner(TaskType type) const { - switch (type) { - case TaskType::kDeprecatedNone: - case TaskType::kDOMManipulation: - case TaskType::kUserInteraction: - case TaskType::kNetworking: - case TaskType::kNetworkingControl: - case TaskType::kHistoryTraversal: - case TaskType::kEmbed: - case TaskType::kMediaElementEvent: - case TaskType::kCanvasBlobSerialization: - case TaskType::kMicrotask: - case TaskType::kJavascriptTimer: - case TaskType::kRemoteEvent: - case TaskType::kWebSocket: - case TaskType::kPostedMessage: - case TaskType::kUnshippedPortMessage: - case TaskType::kFileReading: - case TaskType::kDatabaseAccess: - case TaskType::kPresentation: - case TaskType::kSensor: - case TaskType::kPerformanceTimeline: - case TaskType::kWebGL: - case TaskType::kIdleTask: - case TaskType::kMiscPlatformAPI: - case TaskType::kUnspecedTimer: - case TaskType::kInternalLoading: - case TaskType::kUnthrottled: - case TaskType::kInternalTest: - case TaskType::kInternalWebCrypto: - case TaskType::kInternalIndexedDB: - case TaskType::kInternalMedia: - case TaskType::kInternalMediaRealTime: - case TaskType::kInternalIPC: - case TaskType::kInternalUserInteraction: - case TaskType::kInternalInspector: - case TaskType::kInternalAnimation: - // UnthrottledTaskRunner is generally discouraged in future. - // TODO(nhiroki): Identify which tasks can be throttled / suspendable and - // move them into other task runners. See also comments in - // Get(LocalFrame). (https://crbug.com/670534) - return TaskRunnerImpl::Create(task_queue_, type); - case TaskType::kCount: - NOTREACHED(); - break; - } - NOTREACHED(); - return nullptr; -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc deleted file mode 100644 index a38cde67c5a..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler_unittest.cc +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.h" - -#include <memory> -#include "base/macros.h" -#include "base/test/simple_test_tick_clock.h" -#include "base/test/test_simple_task_runner.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" -#include "third_party/blink/renderer/platform/wtf/functional.h" - -using testing::ElementsAreArray; - -namespace blink { -namespace scheduler { -// To avoid symbol collisions in jumbo builds. -namespace worker_global_scope_scheduler_unittest { - -void AppendToVectorTestTask(std::vector<std::string>* vector, - std::string value) { - vector->push_back(value); -} - -class WorkerGlobalScopeSchedulerTest : public testing::Test { - public: - WorkerGlobalScopeSchedulerTest() - : mock_task_runner_(new base::TestSimpleTaskRunner()), - scheduler_(new WorkerThreadScheduler( - WebThreadType::kTestThread, - TaskQueueManagerForTest::Create(nullptr, - mock_task_runner_, - &clock_), - nullptr /* proxy */)) { - clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); - } - - ~WorkerGlobalScopeSchedulerTest() override = default; - - void SetUp() override { - scheduler_->Init(); - global_scope_scheduler_ = - std::make_unique<WorkerGlobalScopeScheduler>(scheduler_.get()); - } - - void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } - - // Helper for posting a task. - void PostTestTask(std::vector<std::string>* run_order, - const std::string& task_descriptor) { - global_scope_scheduler_->GetTaskRunner(TaskType::kInternalTest) - ->PostTask(FROM_HERE, - WTF::Bind(&AppendToVectorTestTask, - WTF::Unretained(run_order), task_descriptor)); - } - - protected: - base::SimpleTestTickClock clock_; - scoped_refptr<base::TestSimpleTaskRunner> mock_task_runner_; - - std::unique_ptr<WorkerThreadScheduler> scheduler_; - std::unique_ptr<WorkerGlobalScopeScheduler> global_scope_scheduler_; - - DISALLOW_COPY_AND_ASSIGN(WorkerGlobalScopeSchedulerTest); -}; - -TEST_F(WorkerGlobalScopeSchedulerTest, TestPostTasks) { - std::vector<std::string> run_order; - PostTestTask(&run_order, "T1"); - PostTestTask(&run_order, "T2"); - RunUntilIdle(); - PostTestTask(&run_order, "T3"); - RunUntilIdle(); - EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2", "T3")); - - // Tasks should not run after the scheduler is disposed of. - global_scope_scheduler_->Dispose(); - run_order.clear(); - PostTestTask(&run_order, "T4"); - PostTestTask(&run_order, "T5"); - RunUntilIdle(); - EXPECT_TRUE(run_order.empty()); -} - -} // namespace worker_global_scope_scheduler_unittest -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.cc index f9ea5be00ef..577c6287ef8 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.cc @@ -29,7 +29,7 @@ void WorkerMetricsHelper::SetParentFrameType(FrameOriginType frame_type) { void WorkerMetricsHelper::RecordTaskMetrics( WorkerTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.h index b2837920399..5b1cd7319d5 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_metrics_helper.h @@ -20,7 +20,7 @@ class PLATFORM_EXPORT WorkerMetricsHelper : public MetricsHelper { ~WorkerMetricsHelper(); void RecordTaskMetrics(WorkerTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler.cc new file mode 100644 index 00000000000..158609a9da6 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler.cc @@ -0,0 +1,144 @@ +// 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/scheduler/child/worker_scheduler.h" + +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h" +#include "third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h" + +namespace blink { +namespace scheduler { + +WorkerScheduler::WorkerScheduler( + NonMainThreadScheduler* non_main_thread_scheduler) + : default_task_queue_(non_main_thread_scheduler->CreateTaskRunner()), + throttleable_task_queue_(non_main_thread_scheduler->CreateTaskRunner()), + thread_scheduler_(non_main_thread_scheduler) { + thread_scheduler_->RegisterWorkerScheduler(this); + if (WakeUpBudgetPool* wake_up_budget_pool = + thread_scheduler_->wake_up_budget_pool()) { + wake_up_budget_pool->AddQueue(thread_scheduler_->GetTickClock()->NowTicks(), + throttleable_task_queue_.get()); + } +} + +WorkerScheduler::~WorkerScheduler() { +#if DCHECK_IS_ON() + DCHECK(is_disposed_); +#endif +} + +std::unique_ptr<FrameOrWorkerScheduler::ActiveConnectionHandle> +WorkerScheduler::OnActiveConnectionCreated() { + return nullptr; +} + +void WorkerScheduler::Dispose() { + if (TaskQueueThrottler* throttler = + thread_scheduler_->task_queue_throttler()) { + throttler->ShutdownTaskQueue(throttleable_task_queue_.get()); + } + + thread_scheduler_->UnregisterWorkerScheduler(this); + + default_task_queue_->ShutdownTaskQueue(); + throttleable_task_queue_->ShutdownTaskQueue(); + +#if DCHECK_IS_ON() + is_disposed_ = true; +#endif +} + +scoped_refptr<base::SingleThreadTaskRunner> WorkerScheduler::GetTaskRunner( + TaskType type) const { + switch (type) { + case TaskType::kJavascriptTimer: + case TaskType::kPostedMessage: + return TaskQueueWithTaskType::Create(throttleable_task_queue_, type); + case TaskType::kDeprecatedNone: + case TaskType::kDOMManipulation: + case TaskType::kUserInteraction: + case TaskType::kNetworking: + case TaskType::kNetworkingControl: + case TaskType::kHistoryTraversal: + case TaskType::kEmbed: + case TaskType::kMediaElementEvent: + case TaskType::kCanvasBlobSerialization: + case TaskType::kMicrotask: + case TaskType::kRemoteEvent: + case TaskType::kWebSocket: + case TaskType::kUnshippedPortMessage: + case TaskType::kFileReading: + case TaskType::kDatabaseAccess: + case TaskType::kPresentation: + case TaskType::kSensor: + case TaskType::kPerformanceTimeline: + case TaskType::kWebGL: + case TaskType::kIdleTask: + case TaskType::kMiscPlatformAPI: + case TaskType::kInternalDefault: + case TaskType::kInternalLoading: + case TaskType::kUnthrottled: + case TaskType::kInternalTest: + case TaskType::kInternalWebCrypto: + case TaskType::kInternalIndexedDB: + case TaskType::kInternalMedia: + case TaskType::kInternalMediaRealTime: + case TaskType::kInternalIPC: + case TaskType::kInternalUserInteraction: + case TaskType::kInternalInspector: + case TaskType::kInternalWorker: + case TaskType::kInternalIntersectionObserver: + // UnthrottledTaskRunner is generally discouraged in future. + // TODO(nhiroki): Identify which tasks can be throttled / suspendable and + // move them into other task runners. See also comments in + // Get(LocalFrame). (https://crbug.com/670534) + return TaskQueueWithTaskType::Create(default_task_queue_, type); + case TaskType::kMainThreadTaskQueueV8: + case TaskType::kMainThreadTaskQueueCompositor: + case TaskType::kMainThreadTaskQueueDefault: + case TaskType::kMainThreadTaskQueueInput: + case TaskType::kMainThreadTaskQueueIdle: + case TaskType::kMainThreadTaskQueueIPC: + case TaskType::kMainThreadTaskQueueControl: + case TaskType::kCompositorThreadTaskQueueDefault: + case TaskType::kWorkerThreadTaskQueueDefault: + case TaskType::kCount: + NOTREACHED(); + break; + } + NOTREACHED(); + return nullptr; +} + +void WorkerScheduler::OnThrottlingStateChanged( + FrameScheduler::ThrottlingState throttling_state) { + if (throttling_state_ == throttling_state) + return; + throttling_state_ = throttling_state; + + if (TaskQueueThrottler* throttler = + thread_scheduler_->task_queue_throttler()) { + if (throttling_state_ == FrameScheduler::ThrottlingState::kThrottled) { + throttler->IncreaseThrottleRefCount(throttleable_task_queue_.get()); + } else { + throttler->DecreaseThrottleRefCount(throttleable_task_queue_.get()); + } + } +} + +scoped_refptr<base::sequence_manager::TaskQueue> +WorkerScheduler::DefaultTaskQueue() { + return default_task_queue_.get(); +} + +scoped_refptr<base::sequence_manager::TaskQueue> +WorkerScheduler::ThrottleableTaskQueue() { + return throttleable_task_queue_.get(); +} + +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h index 4493e189c6d..93e9ae6db2d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_global_scope_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h @@ -2,13 +2,14 @@ // 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_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_global_scope_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" namespace blink { @@ -20,12 +21,10 @@ class NonMainThreadScheduler; // global scope is created and destructed when it's closed. // // Unless stated otherwise, all methods must be called on the worker thread. -class PLATFORM_EXPORT WorkerGlobalScopeScheduler - : public FrameOrWorkerGlobalScopeScheduler { +class PLATFORM_EXPORT WorkerScheduler : public FrameOrWorkerScheduler { public: - explicit WorkerGlobalScopeScheduler( - NonMainThreadScheduler* non_main_thread_scheduler); - ~WorkerGlobalScopeScheduler() override; + explicit WorkerScheduler(NonMainThreadScheduler* non_main_thread_scheduler); + ~WorkerScheduler() override; std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override; @@ -38,11 +37,21 @@ class PLATFORM_EXPORT WorkerGlobalScopeScheduler // This must be called only from WorkerThread::GetTaskRunner(). scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) const; - // TODO(nhiroki): Add mechanism to throttle/suspend tasks in response to the - // state of the parent document (https://crbug.com/670534). + void OnThrottlingStateChanged( + FrameScheduler::ThrottlingState throtting_state); + + protected: + scoped_refptr<base::sequence_manager::TaskQueue> DefaultTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue(); private: - scoped_refptr<TaskQueue> task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> throttleable_task_queue_; + + FrameScheduler::ThrottlingState throttling_state_ = + FrameScheduler::ThrottlingState::kNotThrottled; + + NonMainThreadScheduler* thread_scheduler_; // NOT OWNED #if DCHECK_IS_ON() bool is_disposed_ = false; @@ -52,4 +61,4 @@ class PLATFORM_EXPORT WorkerGlobalScopeScheduler } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WORKER_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc index ebd392fe224..f556eab34e7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy_unittest.cc @@ -3,15 +3,16 @@ // found in the LICENSE file. #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" +#include "base/run_loop.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/child/webthread_impl_for_worker_scheduler.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/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" #include "third_party/blink/renderer/platform/waitable_event.h" @@ -22,9 +23,10 @@ namespace { class WorkerThreadSchedulerForTest : public WorkerThreadScheduler { public: - WorkerThreadSchedulerForTest(std::unique_ptr<TaskQueueManager> manager, - WorkerSchedulerProxy* proxy, - WaitableEvent* throtting_state_changed) + WorkerThreadSchedulerForTest( + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, + WorkerSchedulerProxy* proxy, + WaitableEvent* throtting_state_changed) : WorkerThreadScheduler(WebThreadType::kTestThread, std::move(manager), proxy), @@ -56,8 +58,8 @@ class WebThreadImplForWorkerSchedulerForTest std::unique_ptr<NonMainThreadScheduler> CreateNonMainThreadScheduler() override { auto scheduler = std::make_unique<WorkerThreadSchedulerForTest>( - TaskQueueManager::TakeOverCurrentThread(), worker_scheduler_proxy(), - throtting_state_changed_); + base::sequence_manager::TaskQueueManager::TakeOverCurrentThread(), + worker_scheduler_proxy(), throtting_state_changed_); scheduler_ = scheduler.get(); return scheduler; } @@ -84,12 +86,14 @@ std::unique_ptr<WebThreadImplForWorkerSchedulerForTest> CreateWorkerThread( class WorkerSchedulerProxyTest : public testing::Test { public: WorkerSchedulerProxyTest() - : mock_main_thread_task_runner_( - new cc::OrderedSimpleTaskRunner(&clock_, true)), + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED), main_thread_scheduler_(std::make_unique<MainThreadSchedulerImpl>( - TaskQueueManagerForTest::Create(nullptr, - mock_main_thread_task_runner_, - &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, + base::ThreadTaskRunnerHandle::Get(), + task_environment_.GetMockTickClock()), base::nullopt)), page_scheduler_( std::make_unique<PageSchedulerImpl>(nullptr, @@ -97,18 +101,19 @@ class WorkerSchedulerProxyTest : public testing::Test { false)), frame_scheduler_(page_scheduler_->CreateFrameSchedulerImpl( nullptr, - FrameScheduler::FrameType::kMainFrame)) {} + FrameScheduler::FrameType::kMainFrame)) { + // Null clock triggers some assertions. + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5)); + } - ~WorkerSchedulerProxyTest() { + ~WorkerSchedulerProxyTest() override { frame_scheduler_.reset(); page_scheduler_.reset(); main_thread_scheduler_->Shutdown(); } protected: - base::SimpleTestTickClock clock_; - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_main_thread_task_runner_; - + base::test::ScopedTaskEnvironment task_environment_; std::unique_ptr<MainThreadSchedulerImpl> main_thread_scheduler_; std::unique_ptr<PageSchedulerImpl> page_scheduler_; std::unique_ptr<FrameSchedulerImpl> frame_scheduler_; @@ -126,6 +131,12 @@ TEST_F(WorkerSchedulerProxyTest, VisibilitySignalReceived) { page_scheduler_->SetPageVisible(false); throtting_state_changed.Wait(); DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == + FrameScheduler::ThrottlingState::kHidden); + + // Trigger full throttling. + task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(30)); + throtting_state_changed.Wait(); + DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == FrameScheduler::ThrottlingState::kThrottled); page_scheduler_->SetPageVisible(true); @@ -133,7 +144,7 @@ TEST_F(WorkerSchedulerProxyTest, VisibilitySignalReceived) { DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == FrameScheduler::ThrottlingState::kNotThrottled); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } // Tests below check that no crashes occur during different shutdown sequences. @@ -150,13 +161,13 @@ TEST_F(WorkerSchedulerProxyTest, FrameSchedulerDestroyed) { page_scheduler_->SetPageVisible(false); throtting_state_changed.Wait(); DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == - FrameScheduler::ThrottlingState::kThrottled); + FrameScheduler::ThrottlingState::kHidden); frame_scheduler_.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); worker_thread.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } TEST_F(WorkerSchedulerProxyTest, ThreadDestroyed) { @@ -171,16 +182,16 @@ TEST_F(WorkerSchedulerProxyTest, ThreadDestroyed) { page_scheduler_->SetPageVisible(false); throtting_state_changed.Wait(); DCHECK(worker_thread->GetWorkerScheduler()->throttling_state() == - FrameScheduler::ThrottlingState::kThrottled); + FrameScheduler::ThrottlingState::kHidden); worker_thread.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); page_scheduler_->SetPageVisible(true); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); frame_scheduler_.reset(); - mock_main_thread_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); } } // namespace scheduler diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_unittest.cc new file mode 100644 index 00000000000..f439a1fe492 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_scheduler_unittest.cc @@ -0,0 +1,241 @@ +// 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/scheduler/child/worker_scheduler.h" + +#include <memory> +#include "base/macros.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/test/test_mock_time_task_runner.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" + +using testing::ElementsAreArray; +using testing::ElementsAre; + +namespace blink { +namespace scheduler { +// To avoid symbol collisions in jumbo builds. +namespace worker_scheduler_unittest { + +void AppendToVectorTestTask(std::vector<std::string>* vector, + std::string value) { + vector->push_back(value); +} + +void RunChainedTask(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + int count, + const base::TickClock* clock, + std::vector<base::TimeTicks>* tasks) { + tasks->push_back(clock->NowTicks()); + + if (count == 1) + return; + + // Add a delay of 50ms to ensure that wake-up based throttling does not affect + // us. + task_runner->PostDelayedTask( + FROM_HERE, + base::BindOnce(&RunChainedTask, task_runner, count - 1, + base::Unretained(clock), base::Unretained(tasks)), + base::TimeDelta::FromMilliseconds(50)); +} + +class WorkerThreadSchedulerForTest : public WorkerThreadScheduler { + public: + WorkerThreadSchedulerForTest( + WebThreadType thread_type, + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, + WorkerSchedulerProxy* proxy) + : WorkerThreadScheduler(thread_type, std::move(manager), proxy) {} + + const std::unordered_set<WorkerScheduler*>& worker_schedulers() { + return worker_schedulers_; + } + + using WorkerThreadScheduler::CreateTaskQueueThrottler; +}; + +class WorkerSchedulerForTest : public WorkerScheduler { + public: + explicit WorkerSchedulerForTest( + WorkerThreadSchedulerForTest* thread_scheduler) + : WorkerScheduler(thread_scheduler) {} + + using WorkerScheduler::DefaultTaskQueue; + using WorkerScheduler::ThrottleableTaskQueue; +}; + +class WorkerSchedulerTest : public testing::Test { + public: + WorkerSchedulerTest() + : mock_task_runner_(new base::TestMockTimeTaskRunner()), + scheduler_(new WorkerThreadSchedulerForTest( + WebThreadType::kTestThread, + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, + mock_task_runner_, + mock_task_runner_->GetMockTickClock()), + nullptr /* proxy */)) { + mock_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMicroseconds(5000)); + } + + ~WorkerSchedulerTest() override = default; + + void SetUp() override { + scheduler_->Init(); + worker_scheduler_ = + std::make_unique<WorkerSchedulerForTest>(scheduler_.get()); + } + + void TearDown() override { + if (worker_scheduler_) { + worker_scheduler_->Dispose(); + worker_scheduler_.reset(); + } + } + + const base::TickClock* GetClock() { + return mock_task_runner_->GetMockTickClock(); + } + + void RunUntilIdle() { mock_task_runner_->FastForwardUntilNoTasksRemain(); } + + // Helper for posting a task. + void PostTestTask(std::vector<std::string>* run_order, + const std::string& task_descriptor) { + worker_scheduler_->GetTaskRunner(TaskType::kInternalTest) + ->PostTask(FROM_HERE, + WTF::Bind(&AppendToVectorTestTask, + WTF::Unretained(run_order), task_descriptor)); + } + + protected: + scoped_refptr<base::TestMockTimeTaskRunner> mock_task_runner_; + + std::unique_ptr<WorkerThreadSchedulerForTest> scheduler_; + std::unique_ptr<WorkerSchedulerForTest> worker_scheduler_; + + DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerTest); +}; + +TEST_F(WorkerSchedulerTest, TestPostTasks) { + std::vector<std::string> run_order; + PostTestTask(&run_order, "T1"); + PostTestTask(&run_order, "T2"); + RunUntilIdle(); + PostTestTask(&run_order, "T3"); + RunUntilIdle(); + EXPECT_THAT(run_order, testing::ElementsAre("T1", "T2", "T3")); + + // Tasks should not run after the scheduler is disposed of. + worker_scheduler_->Dispose(); + run_order.clear(); + PostTestTask(&run_order, "T4"); + PostTestTask(&run_order, "T5"); + RunUntilIdle(); + EXPECT_TRUE(run_order.empty()); + + worker_scheduler_.reset(); +} + +TEST_F(WorkerSchedulerTest, RegisterWorkerSchedulers) { + EXPECT_THAT(scheduler_->worker_schedulers(), + testing::ElementsAre(worker_scheduler_.get())); + + std::unique_ptr<WorkerSchedulerForTest> worker_scheduler2 = + std::make_unique<WorkerSchedulerForTest>(scheduler_.get()); + + EXPECT_THAT(scheduler_->worker_schedulers(), + testing::UnorderedElementsAre(worker_scheduler_.get(), + worker_scheduler2.get())); + + worker_scheduler_->Dispose(); + worker_scheduler_.reset(); + + EXPECT_THAT(scheduler_->worker_schedulers(), + testing::ElementsAre(worker_scheduler2.get())); + + worker_scheduler2->Dispose(); + + EXPECT_THAT(scheduler_->worker_schedulers(), testing::ElementsAre()); +} + +TEST_F(WorkerSchedulerTest, ThrottleWorkerScheduler) { + scheduler_->CreateTaskQueueThrottler(); + + EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled( + worker_scheduler_->ThrottleableTaskQueue().get())); + + scheduler_->OnThrottlingStateChanged( + FrameScheduler::ThrottlingState::kThrottled); + EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled( + worker_scheduler_->ThrottleableTaskQueue().get())); + + scheduler_->OnThrottlingStateChanged( + FrameScheduler::ThrottlingState::kThrottled); + EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled( + worker_scheduler_->ThrottleableTaskQueue().get())); + + // Ensure that two calls with kThrottled do not mess with throttling + // refcount. + scheduler_->OnThrottlingStateChanged( + FrameScheduler::ThrottlingState::kNotThrottled); + EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled( + worker_scheduler_->ThrottleableTaskQueue().get())); +} + +TEST_F(WorkerSchedulerTest, ThrottleWorkerScheduler_CreateThrottled) { + scheduler_->CreateTaskQueueThrottler(); + + scheduler_->OnThrottlingStateChanged( + FrameScheduler::ThrottlingState::kThrottled); + + std::unique_ptr<WorkerSchedulerForTest> worker_scheduler2 = + std::make_unique<WorkerSchedulerForTest>(scheduler_.get()); + + // Ensure that newly created scheduler is throttled. + EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled( + worker_scheduler2->ThrottleableTaskQueue().get())); + + worker_scheduler2->Dispose(); +} + +TEST_F(WorkerSchedulerTest, ThrottleWorkerScheduler_RunThrottledTasks) { + scheduler_->CreateTaskQueueThrottler(); + + // Create a new |worker_scheduler| to ensure that it's properly initialised. + worker_scheduler_->Dispose(); + worker_scheduler_ = + std::make_unique<WorkerSchedulerForTest>(scheduler_.get()); + + scheduler_->OnThrottlingStateChanged( + FrameScheduler::ThrottlingState::kThrottled); + + std::vector<base::TimeTicks> tasks; + + worker_scheduler_->ThrottleableTaskQueue()->PostTask( + FROM_HERE, + base::BindOnce(&RunChainedTask, + worker_scheduler_->ThrottleableTaskQueue(), 5, + base::Unretained(GetClock()), base::Unretained(&tasks))); + + RunUntilIdle(); + + EXPECT_THAT(tasks, + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(1), + base::TimeTicks() + base::TimeDelta::FromSeconds(2), + base::TimeTicks() + base::TimeDelta::FromSeconds(3), + base::TimeTicks() + base::TimeDelta::FromSeconds(4), + base::TimeTicks() + base::TimeDelta::FromSeconds(5))); +} + +} // namespace worker_scheduler_unittest +} // namespace scheduler +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.cc index 58898d5c1b0..67098630669 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.cc @@ -10,8 +10,10 @@ namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + WorkerTaskQueue::WorkerTaskQueue( - std::unique_ptr<internal::TaskQueueImpl> impl, + std::unique_ptr<base::sequence_manager::internal::TaskQueueImpl> impl, const TaskQueue::Spec& spec, NonMainThreadScheduler* non_main_thread_scheduler) : TaskQueue(std::move(impl), spec), diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h index 049adb10eff..194cf956b06 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h @@ -12,14 +12,16 @@ namespace scheduler { class NonMainThreadScheduler; -class PLATFORM_EXPORT WorkerTaskQueue : public TaskQueue { +class PLATFORM_EXPORT WorkerTaskQueue + : public base::sequence_manager::TaskQueue { public: - WorkerTaskQueue(std::unique_ptr<internal::TaskQueueImpl> impl, - const Spec& spec, - NonMainThreadScheduler* non_main_thread_scheduler); + WorkerTaskQueue( + std::unique_ptr<base::sequence_manager::internal::TaskQueueImpl> impl, + const Spec& spec, + NonMainThreadScheduler* non_main_thread_scheduler); ~WorkerTaskQueue() override; - void OnTaskCompleted(const TaskQueue::Task& task, + void OnTaskCompleted(const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time); 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 d905bfc6327..15206469d37 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 @@ -4,14 +4,23 @@ #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" +#include <utility> + #include "base/time/default_tick_clock.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" namespace blink { namespace scheduler { +using base::sequence_manager::RealTimeDomain; +using base::sequence_manager::TaskQueue; +using base::sequence_manager::TaskQueueManager; +using base::sequence_manager::TaskTimeObserver; +using base::sequence_manager::TimeDomain; + SchedulerHelper::SchedulerHelper( std::unique_ptr<TaskQueueManager> task_queue_manager) : task_queue_manager_(std::move(task_queue_manager)), observer_(nullptr) { @@ -20,11 +29,13 @@ SchedulerHelper::SchedulerHelper( void SchedulerHelper::InitDefaultQueues( scoped_refptr<TaskQueue> default_task_queue, - scoped_refptr<TaskQueue> control_task_queue) { + scoped_refptr<TaskQueue> control_task_queue, + TaskType default_task_type) { control_task_queue->SetQueuePriority(TaskQueue::kControlPriority); DCHECK(task_queue_manager_); - task_queue_manager_->SetDefaultTaskRunner(default_task_queue); + task_queue_manager_->SetDefaultTaskRunner( + TaskQueueWithTaskType::Create(default_task_queue, default_task_type)); } SchedulerHelper::~SchedulerHelper() { @@ -129,5 +140,11 @@ base::TimeTicks SchedulerHelper::NowTicks() const { return base::TimeTicks::Now(); } +double SchedulerHelper::GetSamplingRateForRecordingCPUTime() const { + if (task_queue_manager_) + return task_queue_manager_->GetSamplingRateForRecordingCPUTime(); + return 0; +} + } // 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 4e365b2f5fa..f1fbdb5dc9c 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 @@ -6,10 +6,12 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_SCHEDULER_HELPER_H_ #include <stddef.h> +#include <memory> #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/time/tick_clock.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_selector.h" @@ -17,10 +19,12 @@ namespace blink { namespace scheduler { // Common scheduler functionality for default tasks. -class PLATFORM_EXPORT SchedulerHelper : public TaskQueueManager::Observer { +class PLATFORM_EXPORT SchedulerHelper + : public base::sequence_manager::TaskQueueManager::Observer { public: explicit SchedulerHelper( - std::unique_ptr<TaskQueueManager> task_queue_manager); + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager); ~SchedulerHelper() override; // TaskQueueManager::Observer implementation: @@ -31,12 +35,14 @@ class PLATFORM_EXPORT SchedulerHelper : public TaskQueueManager::Observer { base::TimeTicks NowTicks() const; // Returns the default task queue. - virtual scoped_refptr<TaskQueue> DefaultTaskQueue() = 0; + virtual scoped_refptr<base::sequence_manager::TaskQueue> + DefaultTaskQueue() = 0; // Returns the control task queue. Tasks posted to this queue are executed // with the highest priority. Care must be taken to avoid starvation of other // task queues. - virtual scoped_refptr<TaskQueue> ControlTaskQueue() = 0; + virtual scoped_refptr<base::sequence_manager::TaskQueue> + ControlTaskQueue() = 0; // Adds or removes a task observer from the scheduler. The observer will be // notified before and after every executed task. These functions can only be @@ -44,8 +50,10 @@ class PLATFORM_EXPORT SchedulerHelper : public TaskQueueManager::Observer { void AddTaskObserver(base::MessageLoop::TaskObserver* task_observer); void RemoveTaskObserver(base::MessageLoop::TaskObserver* task_observer); - void AddTaskTimeObserver(TaskTimeObserver* task_time_observer); - void RemoveTaskTimeObserver(TaskTimeObserver* task_time_observer); + void AddTaskTimeObserver( + base::sequence_manager::TaskTimeObserver* task_time_observer); + void RemoveTaskTimeObserver( + base::sequence_manager::TaskTimeObserver* task_time_observer); // Shuts down the scheduler by dropping any remaining pending work in the work // queues. After this call any work posted to the task queue will be @@ -79,20 +87,23 @@ class PLATFORM_EXPORT SchedulerHelper : public TaskQueueManager::Observer { void SweepCanceledDelayedTasks(); // Accessor methods. - RealTimeDomain* real_time_domain() const; - void RegisterTimeDomain(TimeDomain* time_domain); - void UnregisterTimeDomain(TimeDomain* time_domain); + base::sequence_manager::RealTimeDomain* real_time_domain() const; + void RegisterTimeDomain(base::sequence_manager::TimeDomain* time_domain); + void UnregisterTimeDomain(base::sequence_manager::TimeDomain* time_domain); bool GetAndClearSystemIsQuiescentBit(); + double GetSamplingRateForRecordingCPUTime() const; // Test helpers. void SetWorkBatchSizeForTesting(size_t work_batch_size); protected: - void InitDefaultQueues(scoped_refptr<TaskQueue> default_task_queue, - scoped_refptr<TaskQueue> control_task_queue); + void InitDefaultQueues( + scoped_refptr<base::sequence_manager::TaskQueue> default_task_queue, + scoped_refptr<base::sequence_manager::TaskQueue> control_task_queue, + TaskType default_task_type); base::ThreadChecker thread_checker_; - std::unique_ptr<TaskQueueManager> task_queue_manager_; + std::unique_ptr<base::sequence_manager::TaskQueueManager> task_queue_manager_; private: friend class SchedulerHelperTest; 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 c5e3720d208..011f4a96c39 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 @@ -8,14 +8,14 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" +#include "base/task/sequence_manager/lazy_now.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" using testing::_; using testing::AnyNumber; @@ -50,27 +50,30 @@ void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner, class SchedulerHelperTest : public testing::Test { public: SchedulerHelperTest() - : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, false)) { - std::unique_ptr<TaskQueueManagerForTest> task_queue_manager = - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_); + : task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME, + base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED) { + // Null clock triggers some assertions. + task_environment_.FastForwardBy(base::TimeDelta::FromMilliseconds(5)); + std::unique_ptr<base::sequence_manager::TaskQueueManagerForTest> + task_queue_manager = + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, base::ThreadTaskRunnerHandle::Get(), + task_environment_.GetMockTickClock()); task_queue_manager_ = task_queue_manager.get(); - scheduler_helper_ = std::make_unique<WorkerSchedulerHelper>( - std::move(task_queue_manager), nullptr); + scheduler_helper_ = std::make_unique<NonMainThreadSchedulerHelper>( + std::move(task_queue_manager), nullptr, TaskType::kInternalTest); default_task_runner_ = scheduler_helper_->DefaultWorkerTaskQueue(); - clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); } ~SchedulerHelperTest() override = default; void TearDown() override { // Check that all tests stop posting tasks. - mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - while (mock_task_runner_->RunUntilIdle()) { - } + task_environment_.FastForwardUntilNoTasksRemain(); + EXPECT_EQ(0u, task_environment_.GetPendingMainThreadTaskCount()); } - void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } - template <typename E> static void CallForEachEnumValue(E first, E last, @@ -82,11 +85,10 @@ class SchedulerHelperTest : public testing::Test { } protected: - base::SimpleTestTickClock clock_; - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; - - std::unique_ptr<WorkerSchedulerHelper> scheduler_helper_; - TaskQueueManagerForTest* task_queue_manager_; // Owned by scheduler_helper. + base::test::ScopedTaskEnvironment task_environment_; + std::unique_ptr<NonMainThreadSchedulerHelper> scheduler_helper_; + base::sequence_manager::TaskQueueManagerForTest* + task_queue_manager_; // Owned by scheduler_helper. scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest); @@ -103,7 +105,7 @@ TEST_F(SchedulerHelperTest, TestPostDefaultTask) { default_task_runner_->PostTask( FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D4")); - RunUntilIdle(); + task_environment_.RunUntilIdle(); EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"), std::string("D2"), std::string("D3"), std::string("D4"))); @@ -116,7 +118,7 @@ TEST_F(SchedulerHelperTest, TestRentrantTask) { FROM_HERE, base::BindOnce(AppendToVectorReentrantTask, base::RetainedRef(default_task_runner_), &run_order, &count, 5)); - RunUntilIdle(); + task_environment_.RunUntilIdle(); EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4)); } @@ -137,7 +139,7 @@ TEST_F(SchedulerHelperTest, GetNumberOfPendingTasks) { scheduler_helper_->ControlWorkerTaskQueue()->PostTask( FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "C1")); EXPECT_EQ(3U, task_queue_manager_->PendingTasksCount()); - RunUntilIdle(); + task_environment_.RunUntilIdle(); EXPECT_EQ(0U, task_queue_manager_->PendingTasksCount()); } @@ -160,7 +162,7 @@ TEST_F(SchedulerHelperTest, ObserversNotifiedFor_DefaultTaskRunner) { EXPECT_CALL(observer, WillProcessTask(_)).Times(1); EXPECT_CALL(observer, DidProcessTask(_)).Times(1); - RunUntilIdle(); + task_environment_.RunUntilIdle(); } TEST_F(SchedulerHelperTest, ObserversNotNotifiedFor_ControlTaskQueue) { @@ -172,7 +174,7 @@ TEST_F(SchedulerHelperTest, ObserversNotNotifiedFor_ControlTaskQueue) { EXPECT_CALL(observer, WillProcessTask(_)).Times(0); EXPECT_CALL(observer, DidProcessTask(_)).Times(0); - RunUntilIdle(); + task_environment_.RunUntilIdle(); } } // namespace scheduler_helper_unittest diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler.cc new file mode 100644 index 00000000000..67f51a1554d --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler.cc @@ -0,0 +1,15 @@ +// 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/scheduler/public/thread_scheduler.h" + +#include "third_party/blink/public/platform/platform.h" + +namespace blink { + +ThreadScheduler* ThreadScheduler::Current() { + return Platform::Current()->CurrentThread()->Scheduler(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h new file mode 100644 index 00000000000..2af85c76457 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h @@ -0,0 +1,45 @@ +// 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_COMMON_THREAD_SCHEDULER_IMPL_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THREAD_SCHEDULER_IMPL_H_ + +#include "third_party/blink/renderer/platform/platform_export.h" + +#include "base/single_thread_task_runner.h" +#include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" + +namespace base { +class TickClock; + +namespace sequence_manager { +class TimeDomain; +} +} // namespace base + +namespace blink { +namespace scheduler { + +// Scheduler-internal interface for the common methods between +// MainThreadSchedulerImpl and NonMainThreadSchedulerImpl which should +// not be exposed outside the scheduler. +class PLATFORM_EXPORT ThreadSchedulerImpl : virtual public ThreadScheduler, + virtual public WebThreadScheduler { + public: + virtual scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner() = 0; + + virtual void RegisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) = 0; + virtual void UnregisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) = 0; + virtual base::sequence_manager::TimeDomain* GetActiveTimeDomain() = 0; + + virtual const base::TickClock* GetTickClock() = 0; +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_THREAD_SCHEDULER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc index df387275201..160e35b7a29 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.cc @@ -12,6 +12,8 @@ namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + BudgetPool::BudgetPool(const char* name, BudgetPoolController* budget_pool_controller) : name_(name), @@ -51,7 +53,7 @@ void BudgetPool::DissociateQueue(TaskQueue* queue) { associated_task_queues_.erase(queue); } -void BudgetPool::EnableThrottling(LazyNow* lazy_now) { +void BudgetPool::EnableThrottling(base::sequence_manager::LazyNow* lazy_now) { if (is_enabled_) return; is_enabled_ = true; @@ -61,7 +63,7 @@ void BudgetPool::EnableThrottling(LazyNow* lazy_now) { BlockThrottledQueues(lazy_now->Now()); } -void BudgetPool::DisableThrottling(LazyNow* lazy_now) { +void BudgetPool::DisableThrottling(base::sequence_manager::LazyNow* lazy_now) { if (!is_enabled_) return; is_enabled_ = false; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h index 617444431c8..807c4ae48e2 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h @@ -10,10 +10,14 @@ #include "base/callback.h" #include "base/macros.h" #include "base/optional.h" +#include "base/task/sequence_manager/lazy_now.h" #include "base/time/time.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" +#include "third_party/blink/renderer/platform/platform_export.h" namespace base { +namespace sequence_manager { +class TaskQueue; +} namespace trace_event { class TracedValue; } @@ -22,7 +26,6 @@ class TracedValue; namespace blink { namespace scheduler { -class TaskQueue; class BudgetPoolController; enum class QueueBlockType; @@ -36,7 +39,7 @@ class PLATFORM_EXPORT BudgetPool { const char* Name() const; // Report task run time to the budget pool. - virtual void RecordTaskRunTime(TaskQueue* queue, + virtual void RecordTaskRunTime(base::sequence_manager::TaskQueue* queue, base::TimeTicks start_time, base::TimeTicks end_time) = 0; @@ -55,9 +58,10 @@ class PLATFORM_EXPORT BudgetPool { bool is_wake_up) const = 0; // Notifies budget pool that queue has work with desired run time. - virtual void OnQueueNextWakeUpChanged(TaskQueue* queue, - base::TimeTicks now, - base::TimeTicks desired_run_time) = 0; + virtual void OnQueueNextWakeUpChanged( + base::sequence_manager::TaskQueue* queue, + base::TimeTicks now, + base::TimeTicks desired_run_time) = 0; // Notifies budget pool that wakeup has happened. virtual void OnWakeUp(base::TimeTicks now) = 0; @@ -72,24 +76,25 @@ class PLATFORM_EXPORT BudgetPool { // Adds |queue| to given pool. If the pool restriction does not allow // a task to be run immediately and |queue| is throttled, |queue| becomes // disabled. - void AddQueue(base::TimeTicks now, TaskQueue* queue); + void AddQueue(base::TimeTicks now, base::sequence_manager::TaskQueue* queue); // Removes |queue| from given pool. If it is throttled, it does not // become enabled immediately, but a wake-up is scheduled if needed. - void RemoveQueue(base::TimeTicks now, TaskQueue* queue); + void RemoveQueue(base::TimeTicks now, + base::sequence_manager::TaskQueue* queue); // Unlike RemoveQueue, does not schedule a new wake-up for the queue. - void UnregisterQueue(TaskQueue* queue); + void UnregisterQueue(base::sequence_manager::TaskQueue* queue); // Enables this time budget pool. Queues from this pool will be // throttled based on their run time. - void EnableThrottling(LazyNow* now); + void EnableThrottling(base::sequence_manager::LazyNow* now); // Disables with time budget pool. Queues from this pool will not be // throttled based on their run time. A call to |PumpThrottledTasks| // will be scheduled to enable this queues back again and respect // timer alignment. Internal budget level will not regenerate with time. - void DisableThrottling(LazyNow* now); + void DisableThrottling(base::sequence_manager::LazyNow* now); bool IsThrottlingEnabled() const; @@ -106,11 +111,12 @@ class PLATFORM_EXPORT BudgetPool { BudgetPoolController* budget_pool_controller_; - std::unordered_set<TaskQueue*> associated_task_queues_; + std::unordered_set<base::sequence_manager::TaskQueue*> + associated_task_queues_; bool is_enabled_; private: - void DissociateQueue(TaskQueue* queue); + void DissociateQueue(base::sequence_manager::TaskQueue* queue); }; } // namespace scheduler diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc index 09b4f14de2c..9d65c9ce0a7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool_unittest.cc @@ -15,11 +15,11 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" namespace blink { namespace scheduler { @@ -34,7 +34,8 @@ class BudgetPoolTest : public testing::Test { mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true); scheduler_.reset(new MainThreadSchedulerImpl( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_), base::nullopt)); task_queue_throttler_ = scheduler_->task_queue_throttler(); start_time_ = clock_.NowTicks(); @@ -129,8 +130,9 @@ TEST_F(BudgetPoolTest, WakeUpBudgetPool) { WakeUpBudgetPool* pool = task_queue_throttler_->CreateWakeUpBudgetPool("test"); - scoped_refptr<TaskQueue> queue = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + scoped_refptr<base::sequence_manager::TaskQueue> queue = + scheduler_->NewTimerTaskQueue( + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); pool->SetWakeUpRate(0.1); pool->SetWakeUpDuration(base::TimeDelta::FromMilliseconds(10)); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc index 6eade22fc88..feb24ff95f5 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.cc @@ -13,6 +13,8 @@ namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + CPUTimeBudgetPool::CPUTimeBudgetPool( const char* name, BudgetPoolController* budget_pool_controller, diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h index 0f21f438267..db1571e9c34 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h @@ -10,8 +10,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/optional.h" -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace blink { @@ -26,7 +24,7 @@ class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool { TraceableVariableController* tracing_controller, base::TimeTicks now); - ~CPUTimeBudgetPool(); + ~CPUTimeBudgetPool() override; // Set max budget level, base::nullopt represent absence of max level. // Max budget level prevents accumulating arbitrary large budgets when @@ -72,7 +70,7 @@ class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool { base::RepeatingCallback<void(base::TimeDelta)> reporting_callback); // BudgetPool implementation: - void RecordTaskRunTime(TaskQueue* queue, + void RecordTaskRunTime(base::sequence_manager::TaskQueue* queue, base::TimeTicks start_time, base::TimeTicks end_time) final; bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const final; @@ -81,7 +79,7 @@ class PLATFORM_EXPORT CPUTimeBudgetPool : public BudgetPool { bool is_wake_up) const final; base::TimeTicks GetNextAllowedRunTime( base::TimeTicks desired_run_time) const final; - void OnQueueNextWakeUpChanged(TaskQueue* queue, + void OnQueueNextWakeUpChanged(base::sequence_manager::TaskQueue* queue, base::TimeTicks now, base::TimeTicks desired_run_time) final; void OnWakeUp(base::TimeTicks now) final; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc index e6d2c4c17ac..611510da31a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.cc @@ -9,15 +9,19 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/optional.h" +#include "base/time/tick_clock.h" #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.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" namespace blink { namespace scheduler { +using base::sequence_manager::LazyNow; +using base::sequence_manager::TaskQueue; + namespace { base::Optional<base::TimeTicks> NextTaskRunTime(LazyNow* lazy_now, @@ -63,12 +67,12 @@ base::Optional<T> Max(const base::Optional<T>& a, const base::Optional<T>& b) { } // namespace TaskQueueThrottler::TaskQueueThrottler( - MainThreadSchedulerImpl* main_thread_scheduler, + ThreadSchedulerImpl* thread_scheduler, TraceableVariableController* tracing_controller) - : control_task_queue_(main_thread_scheduler->ControlTaskQueue()), - main_thread_scheduler_(main_thread_scheduler), + : control_task_runner_(thread_scheduler->ControlTaskRunner()), + thread_scheduler_(thread_scheduler), tracing_controller_(tracing_controller), - tick_clock_(main_thread_scheduler->tick_clock()), + tick_clock_(thread_scheduler->GetTickClock()), time_domain_(new ThrottledTimeDomain()), allow_throttling_(true), weak_factory_(this) { @@ -78,7 +82,7 @@ TaskQueueThrottler::TaskQueueThrottler( base::BindRepeating(&TaskQueueThrottler::OnQueueNextWakeUpChanged, weak_factory_.GetWeakPtr()); - main_thread_scheduler_->RegisterTimeDomain(time_domain_.get()); + thread_scheduler_->RegisterTimeDomain(time_domain_.get()); } TaskQueueThrottler::~TaskQueueThrottler() { @@ -87,18 +91,18 @@ TaskQueueThrottler::~TaskQueueThrottler() { for (const TaskQueueMap::value_type& map_entry : queue_details_) { TaskQueue* task_queue = map_entry.first; if (IsThrottled(task_queue)) { - task_queue->SetTimeDomain(main_thread_scheduler_->GetActiveTimeDomain()); + task_queue->SetTimeDomain(thread_scheduler_->GetActiveTimeDomain()); task_queue->RemoveFence(); } if (map_entry.second.throttling_ref_count != 0) task_queue->SetObserver(nullptr); } - main_thread_scheduler_->UnregisterTimeDomain(time_domain_.get()); + thread_scheduler_->UnregisterTimeDomain(time_domain_.get()); } void TaskQueueThrottler::IncreaseThrottleRefCount(TaskQueue* task_queue) { - DCHECK_NE(task_queue, control_task_queue_.get()); + DCHECK_NE(task_queue, control_task_runner_.get()); std::pair<TaskQueueMap::iterator, bool> insert_result = queue_details_.insert(std::make_pair(task_queue, Metadata())); @@ -151,7 +155,7 @@ void TaskQueueThrottler::DecreaseThrottleRefCount(TaskQueue* task_queue) { if (!allow_throttling_) return; - task_queue->SetTimeDomain(main_thread_scheduler_->GetActiveTimeDomain()); + task_queue->SetTimeDomain(thread_scheduler_->GetActiveTimeDomain()); task_queue->RemoveFence(); } @@ -172,7 +176,7 @@ void TaskQueueThrottler::ShutdownTaskQueue(TaskQueue* task_queue) { // Reset a time domain reference to a valid domain, otherwise it's possible // to get a stale reference when deleting queue. - task_queue->SetTimeDomain(main_thread_scheduler_->GetActiveTimeDomain()); + task_queue->SetTimeDomain(thread_scheduler_->GetActiveTimeDomain()); task_queue->RemoveFence(); std::unordered_set<BudgetPool*> budget_pools = find_it->second.budget_pools; @@ -190,8 +194,8 @@ void TaskQueueThrottler::ShutdownTaskQueue(TaskQueue* task_queue) { void TaskQueueThrottler::OnQueueNextWakeUpChanged( TaskQueue* queue, base::TimeTicks next_wake_up) { - if (!control_task_queue_->RunsTasksInCurrentSequence()) { - control_task_queue_->PostTask( + if (!control_task_runner_->RunsTasksInCurrentSequence()) { + control_task_runner_->PostTask( FROM_HERE, base::BindOnce(forward_immediate_work_callback_, base::RetainedRef(queue), next_wake_up)); return; @@ -276,7 +280,7 @@ void TaskQueueThrottler::MaybeSchedulePumpThrottledTasks( TRACE_EVENT1("renderer.scheduler", "TaskQueueThrottler::MaybeSchedulePumpThrottledTasks", "delay_till_next_pump_ms", delay.InMilliseconds()); - control_task_queue_->PostDelayedTask( + control_task_runner_->PostDelayedTask( from_here, pump_throttled_tasks_closure_.GetCallback(), delay); } @@ -332,7 +336,7 @@ void TaskQueueThrottler::UpdateQueueThrottlingStateInternal(base::TimeTicks now, base::Optional<base::TimeTicks> unblock_until = GetTimeTasksCanRunUntil(queue, now, is_wake_up); DCHECK(unblock_until); - if (!unblock_until || unblock_until.value() > now) { + if (unblock_until.value() > now) { queue->InsertFenceAt(unblock_until.value()); } else if (unblock_until.value() == now) { queue->InsertFence(TaskQueue::InsertFencePosition::kNow); @@ -540,7 +544,7 @@ void TaskQueueThrottler::DisableThrottling() { TaskQueue* queue = map_entry.first; - queue->SetTimeDomain(main_thread_scheduler_->GetActiveTimeDomain()); + queue->SetTimeDomain(thread_scheduler_->GetActiveTimeDomain()); queue->RemoveFence(); } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h index ce3a9dda0bb..bfeadc4aad0 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h @@ -14,6 +14,7 @@ #include "base/optional.h" #include "base/threading/thread_checker.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/time_domain.h" #include "third_party/blink/renderer/platform/scheduler/child/cancelable_closure_holder.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.h" @@ -31,7 +32,7 @@ namespace blink { namespace scheduler { class BudgetPool; -class MainThreadSchedulerImpl; +class ThreadSchedulerImpl; class ThrottledTimeDomain; class CPUTimeBudgetPool; class WakeUpBudgetPool; @@ -51,22 +52,24 @@ class PLATFORM_EXPORT BudgetPoolController { // To be used by BudgetPool only, use BudgetPool::{Add,Remove}Queue // methods instead. - virtual void AddQueueToBudgetPool(TaskQueue* queue, + virtual void AddQueueToBudgetPool(base::sequence_manager::TaskQueue* queue, BudgetPool* budget_pool) = 0; - virtual void RemoveQueueFromBudgetPool(TaskQueue* queue, - BudgetPool* budget_pool) = 0; + virtual void RemoveQueueFromBudgetPool( + base::sequence_manager::TaskQueue* queue, + BudgetPool* budget_pool) = 0; // Deletes the budget pool. virtual void UnregisterBudgetPool(BudgetPool* budget_pool) = 0; // Ensure that an appropriate type of the fence is installed and schedule // a pump for this queue when needed. - virtual void UpdateQueueThrottlingState(base::TimeTicks now, - TaskQueue* queue) = 0; + virtual void UpdateQueueThrottlingState( + base::TimeTicks now, + base::sequence_manager::TaskQueue* queue) = 0; // Returns true if the |queue| is throttled (i.e. added to TaskQueueThrottler // and throttling is not disabled). - virtual bool IsThrottled(TaskQueue* queue) const = 0; + virtual bool IsThrottled(base::sequence_manager::TaskQueue* queue) const = 0; }; // The job of the TaskQueueThrottler is to control when tasks posted on @@ -80,7 +83,7 @@ class PLATFORM_EXPORT BudgetPoolController { // posted from a throttled task run next time the queue is pumped. // // Of course the TaskQueueThrottler isn't the only sub-system that wants to -// enable or disable queues. E.g. MainThreadSchedulerImpl also does this for +// enable or disable queues. E.g. ThreadSchedulerImpl also does this for // policy reasons. To prevent the systems from fighting, clients of // TaskQueueThrottler must use SetQueueEnabled rather than calling the function // directly on the queue. @@ -91,40 +94,43 @@ class PLATFORM_EXPORT BudgetPoolController { // See IncreaseThrottleRefCount & DecreaseThrottleRefCount. // // This class is main-thread only. -class PLATFORM_EXPORT TaskQueueThrottler : public TaskQueue::Observer, - public BudgetPoolController { +class PLATFORM_EXPORT TaskQueueThrottler + : public base::sequence_manager::TaskQueue::Observer, + public BudgetPoolController { public: - // We use tracing controller from MainThreadSchedulerImpl because an instance + // We use tracing controller from ThreadSchedulerImpl because an instance // of this class is always its member, so has the same lifetime. - TaskQueueThrottler(MainThreadSchedulerImpl* main_thread_scheduler, + TaskQueueThrottler(ThreadSchedulerImpl* thread_scheduler, TraceableVariableController* tracing_controller); ~TaskQueueThrottler() override; // TaskQueue::Observer implementation: - void OnQueueNextWakeUpChanged(TaskQueue* queue, + void OnQueueNextWakeUpChanged(base::sequence_manager::TaskQueue* queue, base::TimeTicks wake_up) override; // BudgetPoolController implementation: - void AddQueueToBudgetPool(TaskQueue* queue, BudgetPool* budget_pool) override; - void RemoveQueueFromBudgetPool(TaskQueue* queue, + void AddQueueToBudgetPool(base::sequence_manager::TaskQueue* queue, + BudgetPool* budget_pool) override; + void RemoveQueueFromBudgetPool(base::sequence_manager::TaskQueue* queue, BudgetPool* budget_pool) override; void UnregisterBudgetPool(BudgetPool* budget_pool) override; - void UpdateQueueThrottlingState(base::TimeTicks now, - TaskQueue* queue) override; - bool IsThrottled(TaskQueue* queue) const override; + void UpdateQueueThrottlingState( + base::TimeTicks now, + base::sequence_manager::TaskQueue* queue) override; + bool IsThrottled(base::sequence_manager::TaskQueue* queue) const override; // Increments the throttled refcount and causes |task_queue| to be throttled // if its not already throttled. - void IncreaseThrottleRefCount(TaskQueue* task_queue); + void IncreaseThrottleRefCount(base::sequence_manager::TaskQueue* task_queue); // If the refcouint is non-zero it's decremented. If the throttled refcount // becomes zero then |task_queue| is unthrottled. If the refcount was already // zero this function does nothing. - void DecreaseThrottleRefCount(TaskQueue* task_queue); + void DecreaseThrottleRefCount(base::sequence_manager::TaskQueue* task_queue); // Removes |task_queue| from |queue_details| and from appropriate budget pool. - void ShutdownTaskQueue(TaskQueue* task_queue); + void ShutdownTaskQueue(base::sequence_manager::TaskQueue* task_queue); // Disable throttling for all queues, this setting takes precedence over // all other throttling settings. Designed to be used when a global event @@ -140,16 +146,12 @@ class PLATFORM_EXPORT TaskQueueThrottler : public TaskQueue::Observer, static base::TimeTicks AlignedThrottledRunTime( base::TimeTicks unthrottled_runtime); - const scoped_refptr<TaskQueue>& task_queue() const { - return control_task_queue_; - } - // Returned object is owned by |TaskQueueThrottler|. CPUTimeBudgetPool* CreateCPUTimeBudgetPool(const char* name); WakeUpBudgetPool* CreateWakeUpBudgetPool(const char* name); // Accounts for given task for cpu-based throttling needs. - void OnTaskRunTimeReported(TaskQueue* task_queue, + void OnTaskRunTimeReported(base::sequence_manager::TaskQueue* task_queue, base::TimeTicks start_time, base::TimeTicks end_time); @@ -164,7 +166,8 @@ class PLATFORM_EXPORT TaskQueueThrottler : public TaskQueue::Observer, std::unordered_set<BudgetPool*> budget_pools; }; - using TaskQueueMap = std::unordered_map<TaskQueue*, Metadata>; + using TaskQueueMap = + std::unordered_map<base::sequence_manager::TaskQueue*, Metadata>; void PumpThrottledTasks(); @@ -177,30 +180,36 @@ class PLATFORM_EXPORT TaskQueueThrottler : public TaskQueue::Observer, // Return next possible time when queue is allowed to run in accordance // with throttling policy. - base::TimeTicks GetNextAllowedRunTime(TaskQueue* queue, - base::TimeTicks desired_run_time); + base::TimeTicks GetNextAllowedRunTime( + base::sequence_manager::TaskQueue* queue, + base::TimeTicks desired_run_time); - bool CanRunTasksAt(TaskQueue* queue, base::TimeTicks moment, bool is_wake_up); + bool CanRunTasksAt(base::sequence_manager::TaskQueue* queue, + base::TimeTicks moment, + bool is_wake_up); base::Optional<base::TimeTicks> GetTimeTasksCanRunUntil( - TaskQueue* queue, + base::sequence_manager::TaskQueue* queue, base::TimeTicks now, bool is_wake_up) const; void MaybeDeleteQueueMetadata(TaskQueueMap::iterator it); - void UpdateQueueThrottlingStateInternal(base::TimeTicks now, - TaskQueue* queue, - bool is_wake_up); + void UpdateQueueThrottlingStateInternal( + base::TimeTicks now, + base::sequence_manager::TaskQueue* queue, + bool is_wake_up); - base::Optional<QueueBlockType> GetQueueBlockType(base::TimeTicks now, - TaskQueue* queue); + base::Optional<QueueBlockType> GetQueueBlockType( + base::TimeTicks now, + base::sequence_manager::TaskQueue* queue); TaskQueueMap queue_details_; - base::RepeatingCallback<void(TaskQueue*, base::TimeTicks)> + base::RepeatingCallback<void(base::sequence_manager::TaskQueue*, + base::TimeTicks)> forward_immediate_work_callback_; - scoped_refptr<TaskQueue> control_task_queue_; - MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED + scoped_refptr<base::SingleThreadTaskRunner> control_task_runner_; + ThreadSchedulerImpl* thread_scheduler_; // NOT OWNED TraceableVariableController* tracing_controller_; // NOT OWNED const base::TickClock* tick_clock_; // NOT OWNED std::unique_ptr<ThrottledTimeDomain> time_domain_; 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 e429542157e..3bd39ee366e 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 @@ -18,12 +18,14 @@ #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.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/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" +using base::sequence_manager::LazyNow; +using base::sequence_manager::TaskQueue; using testing::ElementsAre; namespace blink { @@ -31,6 +33,16 @@ namespace scheduler { // To avoid symbol collisions in jumbo builds. namespace task_queue_throttler_unittest { +class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl { + public: + using MainThreadSchedulerImpl::ControlTaskQueue; + + MainThreadSchedulerImplForTest( + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, + base::Optional<base::Time> initial_virtual_time) + : MainThreadSchedulerImpl(std::move(manager), initial_virtual_time) {} +}; + bool MessageLoopTaskCounter(size_t* count) { *count = *count + 1; return true; @@ -80,13 +92,15 @@ class TaskQueueThrottlerTest : public testing::Test { clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(clock_.get(), true); - scheduler_.reset(new MainThreadSchedulerImpl( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, - clock_.get()), + scheduler_.reset(new MainThreadSchedulerImplForTest( + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, clock_.get()), base::nullopt)); + scheduler_->GetWakeUpBudgetPoolForTesting()->SetWakeUpDuration( + base::TimeDelta()); task_queue_throttler_ = scheduler_->task_queue_throttler(); timer_queue_ = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); } void TearDown() override { @@ -118,12 +132,14 @@ class TaskQueueThrottlerTest : public testing::Test { } bool IsQueueBlocked(TaskQueue* task_queue) { - internal::TaskQueueImpl* task_queue_impl = task_queue->GetTaskQueueImpl(); + base::sequence_manager::internal::TaskQueueImpl* task_queue_impl = + task_queue->GetTaskQueueImpl(); if (!task_queue_impl->IsQueueEnabled()) return true; return task_queue_impl->GetFenceForTest() == - static_cast<internal::EnqueueOrder>( - internal::EnqueueOrderValues::kBlockingFence); + static_cast<base::sequence_manager::internal::EnqueueOrder>( + base::sequence_manager::internal::EnqueueOrderValues:: + kBlockingFence); } protected: @@ -133,7 +149,7 @@ class TaskQueueThrottlerTest : public testing::Test { std::unique_ptr<AutoAdvancingTestClock> clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; - std::unique_ptr<MainThreadSchedulerImpl> scheduler_; + std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_; scoped_refptr<TaskQueue> timer_queue_; TaskQueueThrottler* task_queue_throttler_; // NOT OWNED @@ -351,7 +367,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, ThrotlingAnEmptyQueueDoesNotPostPumpThrottledTasksLocked) { task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_TRUE(scheduler_->ControlTaskQueue()->IsEmpty()); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, @@ -359,7 +375,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), base::TimeTicks()); // Check PostPumpThrottledTasksLocked was called. - EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_FALSE(scheduler_->ControlTaskQueue()->IsEmpty()); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, @@ -371,7 +387,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, task_queue_throttler_->OnQueueNextWakeUpChanged(timer_queue_.get(), base::TimeTicks()); // Check PostPumpThrottledTasksLocked was not called. - EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_TRUE(scheduler_->ControlTaskQueue()->IsEmpty()); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, @@ -383,11 +399,11 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, voter->SetQueueEnabled(false); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_TRUE(scheduler_->ControlTaskQueue()->IsEmpty()); // Enabling it should trigger a call to PostPumpThrottledTasksLocked. voter->SetQueueEnabled(true); - EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_FALSE(scheduler_->ControlTaskQueue()->IsEmpty()); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, @@ -400,11 +416,11 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, voter->SetQueueEnabled(false); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - EXPECT_TRUE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_TRUE(scheduler_->ControlTaskQueue()->IsEmpty()); // Enabling it should trigger a call to PostPumpThrottledTasksLocked. voter->SetQueueEnabled(true); - EXPECT_FALSE(task_queue_throttler_->task_queue()->IsEmpty()); + EXPECT_FALSE(scheduler_->ControlTaskQueue()->IsEmpty()); } TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, WakeUpForNonDelayedTask) { @@ -654,8 +670,8 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, base::TimeDelta::FromMilliseconds(1000))); run_times.clear(); - LazyNow lazy_now(clock_.get()); - pool->DisableThrottling(&lazy_now); + LazyNow lazy_now_1(clock_.get()); + pool->DisableThrottling(&lazy_now_1); EXPECT_FALSE(pool->IsThrottlingEnabled()); // Pool should not be throttled now. @@ -669,8 +685,8 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, base::TimeDelta::FromMilliseconds(2000))); run_times.clear(); - lazy_now = LazyNow(clock_.get()); - pool->EnableThrottling(&lazy_now); + LazyNow lazy_now_2(clock_.get()); + pool->EnableThrottling(&lazy_now_2); EXPECT_TRUE(pool->IsThrottlingEnabled()); // Because time pool was disabled, time budget level did not replenish @@ -742,7 +758,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, std::vector<base::TimeTicks> run_times; scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); CPUTimeBudgetPool* pool = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); @@ -1014,16 +1030,16 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, task_queue_throttler_->CreateCPUTimeBudgetPool("test"); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); - LazyNow lazy_now(clock_.get()); - pool->DisableThrottling(&lazy_now); + LazyNow lazy_now_1(clock_.get()); + pool->DisableThrottling(&lazy_now_1); pool->AddQueue(base::TimeTicks(), timer_queue_.get()); mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(100)); - lazy_now = LazyNow(clock_.get()); - pool->EnableThrottling(&lazy_now); + LazyNow lazy_now_2(clock_.get()); + pool->EnableThrottling(&lazy_now_2); timer_queue_->PostDelayedTask( FROM_HERE, base::BindOnce(&TestTask, &run_times, clock_.get()), @@ -1068,7 +1084,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, scoped_refptr<MainThreadTaskQueue> second_queue = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); task_queue_throttler_->IncreaseThrottleRefCount(timer_queue_.get()); task_queue_throttler_->IncreaseThrottleRefCount(second_queue.get()); @@ -1104,7 +1120,7 @@ TEST_P(TaskQueueThrottlerWithAutoAdvancingTimeTest, TwoBudgetPools) { std::vector<base::TimeTicks> run_times; scoped_refptr<TaskQueue> second_queue = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); CPUTimeBudgetPool* pool1 = task_queue_throttler_->CreateCPUTimeBudgetPool("test"); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.cc index 70aa1b8ba8f..dff3566df59 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.cc @@ -30,7 +30,7 @@ void ThrottledTimeDomain::SetNextTaskRunTime(base::TimeTicks run_time) { } base::Optional<base::TimeDelta> ThrottledTimeDomain::DelayTillNextTask( - LazyNow* lazy_now) { + base::sequence_manager::LazyNow* lazy_now) { if (next_task_run_time_ && next_task_run_time_ > lazy_now->Now()) return next_task_run_time_.value() - lazy_now->Now(); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h index 4cc739ef187..29b941b720e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/throttled_time_domain.h @@ -13,7 +13,8 @@ namespace scheduler { // A time domain for throttled tasks. behaves like an RealTimeDomain except it // relies on the owner (TaskQueueThrottler) to schedule wake-ups. -class PLATFORM_EXPORT ThrottledTimeDomain : public RealTimeDomain { +class PLATFORM_EXPORT ThrottledTimeDomain + : public base::sequence_manager::RealTimeDomain { public: ThrottledTimeDomain(); ~ThrottledTimeDomain() override; @@ -24,7 +25,8 @@ class PLATFORM_EXPORT ThrottledTimeDomain : public RealTimeDomain { const char* GetName() const override; void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override; void CancelWakeUpAt(base::TimeTicks run_time) override; - base::Optional<base::TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; + base::Optional<base::TimeDelta> DelayTillNextTask( + base::sequence_manager::LazyNow* lazy_now) override; using TimeDomain::WakeUpReadyDelayedQueues; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc index aa6f5a21548..6c1e5f2d155 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.cc @@ -12,6 +12,8 @@ namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + WakeUpBudgetPool::WakeUpBudgetPool(const char* name, BudgetPoolController* budget_pool_controller, base::TimeTicks now) diff --git a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h index a4879975781..be26b4e323b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h @@ -9,8 +9,6 @@ #include "base/macros.h" #include "base/optional.h" -#include "base/time/time.h" -#include "third_party/blink/renderer/platform/scheduler/base/lazy_now.h" namespace blink { namespace scheduler { @@ -33,7 +31,7 @@ class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool { void SetWakeUpDuration(base::TimeDelta duration); // BudgetPool implementation: - void RecordTaskRunTime(TaskQueue* queue, + void RecordTaskRunTime(base::sequence_manager::TaskQueue* queue, base::TimeTicks start_time, base::TimeTicks end_time) final; bool CanRunTasksAt(base::TimeTicks moment, bool is_wake_up) const final; @@ -42,7 +40,7 @@ class PLATFORM_EXPORT WakeUpBudgetPool : public BudgetPool { bool is_wake_up) const final; base::TimeTicks GetNextAllowedRunTime( base::TimeTicks desired_run_time) const final; - void OnQueueNextWakeUpChanged(TaskQueue* queue, + void OnQueueNextWakeUpChanged(base::sequence_manager::TaskQueue* queue, base::TimeTicks now, base::TimeTicks desired_run_time) final; void OnWakeUp(base::TimeTicks now) final; 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 new file mode 100644 index 00000000000..719d8e30b5c --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/common/web_thread_scheduler.cc @@ -0,0 +1,13 @@ +// 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/public/platform/scheduler/web_thread_scheduler.h" + +namespace blink { +namespace scheduler { + +WebThreadScheduler::~WebThreadScheduler() {} + +} // namespace scheduler +} // namespace blink 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 0308a8627ef..92b89d6e63d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/DEPS @@ -1,6 +1,8 @@ include_rules = [ "+base/metrics/single_sample_metrics.h", + "+cc", "+components/viz/common", + "+services/resource_coordinator/public/cpp/resource_coordinator_features.h", ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.cc index 92390abd805..c941ca527f6 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.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/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include "base/time/time_override.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" @@ -43,7 +43,8 @@ AutoAdvancingVirtualTimeDomain::~AutoAdvancingVirtualTimeDomain() { } base::Optional<base::TimeDelta> -AutoAdvancingVirtualTimeDomain::DelayTillNextTask(LazyNow* lazy_now) { +AutoAdvancingVirtualTimeDomain::DelayTillNextTask( + base::sequence_manager::LazyNow* lazy_now) { base::TimeTicks run_time; if (!NextScheduledRunTime(&run_time)) return base::nullopt; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h index e32dea00005..6bae605a65b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h @@ -2,8 +2,8 @@ // 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_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -24,7 +24,7 @@ class SchedulerHelper; // |ABCDE (Execution with AutoAdvancingVirtualTimeDomain) // |-----------------------------> time class PLATFORM_EXPORT AutoAdvancingVirtualTimeDomain - : public VirtualTimeDomain, + : public base::sequence_manager::VirtualTimeDomain, public base::MessageLoop::TaskObserver { public: enum class BaseTimeOverridePolicy { OVERRIDE, DO_NOT_OVERRIDE }; @@ -36,7 +36,8 @@ class PLATFORM_EXPORT AutoAdvancingVirtualTimeDomain ~AutoAdvancingVirtualTimeDomain() override; // TimeDomain implementation: - base::Optional<base::TimeDelta> DelayTillNextTask(LazyNow* lazy_now) override; + base::Optional<base::TimeDelta> DelayTillNextTask( + base::sequence_manager::LazyNow* lazy_now) override; void RequestWakeUpAt(base::TimeTicks now, base::TimeTicks run_time) override; void CancelWakeUpAt(base::TimeTicks run_time) override; const char* GetName() const override; @@ -117,4 +118,4 @@ class PLATFORM_EXPORT AutoAdvancingVirtualTimeDomain } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_AUTO_ADVANCING_VIRTUAL_TIME_DOMAIN_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc index 146cb812329..3e96a0bd539 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain_unittest.cc @@ -2,18 +2,19 @@ // 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/renderer/auto_advancing_virtual_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/auto_advancing_virtual_time_domain.h" #include <memory> -#include "base/test/simple_test_tick_clock.h" -#include "components/viz/test/ordered_simple_task_runner.h" +#include "base/run_loop.h" +#include "base/test/test_mock_time_task_runner.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" -#include "third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" -#include "third_party/blink/renderer/platform/scheduler/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" namespace blink { namespace scheduler { @@ -26,19 +27,21 @@ class AutoAdvancingVirtualTimeDomainTest : public testing::Test { ~AutoAdvancingVirtualTimeDomainTest() override = default; void SetUp() override { - clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); - - mock_task_runner_ = - base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); - - scheduler_helper_.reset(new WorkerSchedulerHelper( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), - nullptr)); + test_task_runner_ = base::WrapRefCounted(new base::TestMockTimeTaskRunner( + base::TestMockTimeTaskRunner::Type::kBoundToThread)); + // A null clock triggers some assertions. + test_task_runner_->AdvanceMockTickClock( + base::TimeDelta::FromMilliseconds(5)); + scheduler_helper_.reset(new NonMainThreadSchedulerHelper( + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, base::ThreadTaskRunnerHandle::Get(), + test_task_runner_->GetMockTickClock()), + nullptr, TaskType::kInternalTest)); scheduler_helper_->AddTaskTimeObserver(&test_task_time_observer_); task_queue_ = scheduler_helper_->DefaultWorkerTaskQueue(); initial_time_ = base::Time::FromJsTime(100000.0); - initial_time_ticks_ = clock_.NowTicks(); + initial_time_ticks_ = test_task_runner_->NowTicks(); auto_advancing_time_domain_.reset(new AutoAdvancingVirtualTimeDomain( initial_time_, initial_time_ticks_, scheduler_helper_.get(), AutoAdvancingVirtualTimeDomain::BaseTimeOverridePolicy::OVERRIDE)); @@ -51,14 +54,13 @@ class AutoAdvancingVirtualTimeDomainTest : public testing::Test { scheduler_helper_->UnregisterTimeDomain(auto_advancing_time_domain_.get()); } + scoped_refptr<base::TestMockTimeTaskRunner> test_task_runner_; base::Time initial_time_; base::TimeTicks initial_time_ticks_; - base::SimpleTestTickClock clock_; - scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; - std::unique_ptr<WorkerSchedulerHelper> scheduler_helper_; - scoped_refptr<TaskQueue> task_queue_; + std::unique_ptr<NonMainThreadSchedulerHelper> scheduler_helper_; + scoped_refptr<base::sequence_manager::TaskQueue> task_queue_; std::unique_ptr<AutoAdvancingVirtualTimeDomain> auto_advancing_time_domain_; - TestTaskTimeObserver test_task_time_observer_; + base::sequence_manager::TestTaskTimeObserver test_task_time_observer_; }; namespace { @@ -71,7 +73,7 @@ class MockObserver : public AutoAdvancingVirtualTimeDomain::Observer { MOCK_METHOD0(OnVirtualTimeAdvanced, void()); }; -} // namesapce +} // namespace TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeAdvances) { MockObserver mock_observer; @@ -83,9 +85,9 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeAdvances) { delay); EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); - EXPECT_EQ(initial_time_ticks_, clock_.NowTicks()); + EXPECT_EQ(initial_time_ticks_, test_task_runner_->NowTicks()); EXPECT_EQ(initial_time_ticks_ + delay, auto_advancing_time_domain_->CreateLazyNow().Now()); EXPECT_TRUE(task_run); @@ -105,9 +107,9 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeDoesNotAdvance) { auto_advancing_time_domain_->SetCanAdvanceVirtualTime(false); EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()).Times(0); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); - EXPECT_EQ(initial_time_ticks_, clock_.NowTicks()); + EXPECT_EQ(initial_time_ticks_, test_task_runner_->NowTicks()); EXPECT_EQ(initial_time_ticks_, auto_advancing_time_domain_->CreateLazyNow().Now()); EXPECT_FALSE(task_run); @@ -116,7 +118,7 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, VirtualTimeDoesNotAdvance) { } namespace { -void RepostingTask(scoped_refptr<TaskQueue> task_queue, +void RepostingTask(scoped_refptr<base::sequence_manager::TaskQueue> task_queue, int max_count, int* count) { if (++(*count) >= max_count) @@ -145,7 +147,7 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1000, count); EXPECT_EQ(102, delayed_task_run_at_count); @@ -164,7 +166,7 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1000, count); // If the initial count had been higher, the delayed task could have been @@ -206,13 +208,13 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, BaseTimeOverriden) { bool task_run = false; task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(base::Time::Now(), initial_time + delay); } TEST_F(AutoAdvancingVirtualTimeDomainTest, BaseTimeTicksOverriden) { - base::TimeTicks initial_time = clock_.NowTicks(); + base::TimeTicks initial_time = test_task_runner_->NowTicks(); EXPECT_EQ(base::TimeTicks::Now(), initial_time); // Make time advance. @@ -220,14 +222,14 @@ TEST_F(AutoAdvancingVirtualTimeDomainTest, BaseTimeTicksOverriden) { bool task_run = false; task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); - mock_task_runner_->RunUntilIdle(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(base::TimeTicks::Now(), initial_time + delay); } TEST_F(AutoAdvancingVirtualTimeDomainTest, DelayTillNextTaskHandlesPastRunTime) { - base::TimeTicks initial_time = clock_.NowTicks(); + base::TimeTicks initial_time = test_task_runner_->NowTicks(); // Post a task for t+10ms. bool task_run = false; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.cc index e945595a3d5..a9d758e211d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.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/renderer/platform/scheduler/renderer/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" #include "base/bind.h" diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h index c37ec85dcc8..2cf9c70a920 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h @@ -2,8 +2,8 @@ // 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_RENDERER_DEADLINE_TASK_RUNNER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_ #include "base/callback.h" #include "base/macros.h" @@ -48,4 +48,4 @@ class PLATFORM_EXPORT DeadlineTaskRunner { } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_DEADLINE_TASK_RUNNER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_DEADLINE_TASK_RUNNER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner_unittest.cc index 7cf087aa033..f56d0e87e92 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner_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/renderer/platform/scheduler/renderer/deadline_task_runner.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/deadline_task_runner.h" #include <memory> 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 11f92d93458..b061db7db52 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 @@ -14,17 +14,37 @@ #include "third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/child/default_params.h" #include "third_party/blink/renderer/platform/scheduler/child/page_visibility_state.h" -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.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/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace blink { + +// static +const char* FrameScheduler::ThrottlingStateToString(ThrottlingState state) { + switch (state) { + case ThrottlingState::kNotThrottled: + return "not throttled"; + case ThrottlingState::kHidden: + return "hidden"; + case ThrottlingState::kThrottled: + return "throttled"; + case ThrottlingState::kStopped: + return "frozen"; + default: + NOTREACHED(); + return nullptr; + } +} + namespace scheduler { +using base::sequence_manager::TaskQueue; + namespace { const char* VisibilityStateToString(bool is_visible) { @@ -98,21 +118,6 @@ FrameSchedulerImpl::FrameSchedulerImpl( this, &tracing_controller_, VisibilityStateToString), - page_visibility_(kDefaultPageVisibility, - "FrameScheduler.PageVisibility", - this, - &tracing_controller_, - PageVisibilityStateToString), - page_frozen_(false, - "FrameScheduler.PageFrozen", - this, - &tracing_controller_, - FrozenStateToString), - keep_active_(main_thread_scheduler->SchedulerKeepActive(), - "FrameScheduler.KeepActive", - this, - &tracing_controller_, - KeepActiveStateToString), frame_paused_(false, "FrameScheduler.FramePaused", this, @@ -137,9 +142,24 @@ FrameSchedulerImpl::FrameSchedulerImpl( this, &tracing_controller_, YesNoStateToString), - weak_factory_(this) { - DCHECK_EQ(throttling_state_, CalculateThrottlingState()); -} + page_frozen_for_tracing_(parent_page_scheduler_->IsFrozen(), + "FrameScheduler.PageFrozen", + this, + &tracing_controller_, + FrozenStateToString), + page_visibility_for_tracing_(parent_page_scheduler_->IsPageVisible() + ? PageVisibilityState::kVisible + : PageVisibilityState::kHidden, + "FrameScheduler.PageVisibility", + this, + &tracing_controller_, + PageVisibilityStateToString), + page_keep_active_for_tracing_(parent_page_scheduler_->KeepActive(), + "FrameScheduler.KeepActive", + this, + &tracing_controller_, + KeepActiveStateToString), + weak_factory_(this) {} namespace { @@ -147,7 +167,7 @@ void CleanUpQueue(MainThreadTaskQueue* queue) { if (!queue) return; queue->DetachFromMainThreadScheduler(); - queue->SetFrameScheduler(nullptr); + queue->DetachFromFrameScheduler(); queue->SetBlameContext(nullptr); queue->SetQueuePriority(TaskQueue::QueuePriority::kLowPriority); } @@ -203,16 +223,16 @@ std::unique_ptr<FrameScheduler::ThrottlingObserverHandle> FrameSchedulerImpl::AddThrottlingObserver(ObserverType type, Observer* observer) { DCHECK(observer); - observer->OnThrottlingStateChanged(CalculateThrottlingState()); - loader_observers_.insert(observer); + observer->OnThrottlingStateChanged(CalculateThrottlingState(type)); + throttling_observers_[observer] = type; return std::make_unique<ThrottlingObserverHandleImpl>(this, observer); } void FrameSchedulerImpl::RemoveThrottlingObserver(Observer* observer) { DCHECK(observer); - const auto found = loader_observers_.find(observer); - DCHECK(loader_observers_.end() != found); - loader_observers_.erase(found); + const auto found = throttling_observers_.find(observer); + DCHECK(throttling_observers_.end() != found); + throttling_observers_.erase(found); } void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) { @@ -221,7 +241,7 @@ void FrameSchedulerImpl::SetFrameVisible(bool frame_visible) { return; UMA_HISTOGRAM_BOOLEAN("RendererScheduler.IPC.FrameVisibility", frame_visible); frame_visible_ = frame_visible; - UpdateTaskQueueThrottling(); + UpdatePolicy(); } bool FrameSchedulerImpl::IsFrameVisible() const { @@ -239,7 +259,7 @@ void FrameSchedulerImpl::SetCrossOrigin(bool cross_origin) { } else { frame_origin_type_ = FrameOriginType::kSameOriginFrame; } - UpdateTaskQueueThrottling(); + UpdatePolicy(); } bool FrameSchedulerImpl::IsCrossOrigin() const { @@ -259,12 +279,12 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( // TODO(haraken): Optimize the mapping from TaskTypes to task runners. switch (type) { case TaskType::kJavascriptTimer: - return TaskRunnerImpl::Create(ThrottleableTaskQueue(), type); + return TaskQueueWithTaskType::Create(ThrottleableTaskQueue(), type); case TaskType::kInternalLoading: case TaskType::kNetworking: - return TaskRunnerImpl::Create(LoadingTaskQueue(), type); + return TaskQueueWithTaskType::Create(LoadingTaskQueue(), type); case TaskType::kNetworkingControl: - return TaskRunnerImpl::Create(LoadingControlTaskQueue(), type); + return TaskQueueWithTaskType::Create(LoadingControlTaskQueue(), type); // Throttling following tasks may break existing web pages, so tentatively // these are unthrottled. // TODO(nhiroki): Throttle them again after we're convinced that it's safe @@ -285,10 +305,10 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( case TaskType::kPerformanceTimeline: case TaskType::kWebGL: case TaskType::kIdleTask: - case TaskType::kUnspecedTimer: + case TaskType::kInternalDefault: case TaskType::kMiscPlatformAPI: // TODO(altimin): Move appropriate tasks to throttleable task queue. - return TaskRunnerImpl::Create(DeferrableTaskQueue(), type); + return TaskQueueWithTaskType::Create(DeferrableTaskQueue(), type); // PostedMessage can be used for navigation, so we shouldn't defer it // when expecting a user gesture. case TaskType::kPostedMessage: @@ -301,8 +321,7 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( case TaskType::kInternalMedia: case TaskType::kInternalMediaRealTime: case TaskType::kInternalUserInteraction: - case TaskType::kInternalAnimation: - return TaskRunnerImpl::Create(PausableTaskQueue(), type); + return TaskQueueWithTaskType::Create(PausableTaskQueue(), type); case TaskType::kUnthrottled: case TaskType::kInternalTest: case TaskType::kInternalWebCrypto: @@ -310,8 +329,22 @@ scoped_refptr<base::SingleThreadTaskRunner> FrameSchedulerImpl::GetTaskRunner( // The TaskType of Inspector tasks needs to be unpausable because they need // to run even on a paused page. case TaskType::kInternalInspector: - return TaskRunnerImpl::Create(UnpausableTaskQueue(), type); + // The TaskType of worker tasks needs to be unpausable (in addition to + // unthrottled and undeferred) not to prevent service workers that may + // control browser navigation on multiple tabs. + case TaskType::kInternalWorker: + case TaskType::kInternalIntersectionObserver: + return TaskQueueWithTaskType::Create(UnpausableTaskQueue(), type); case TaskType::kDeprecatedNone: + case TaskType::kMainThreadTaskQueueV8: + case TaskType::kMainThreadTaskQueueCompositor: + case TaskType::kMainThreadTaskQueueDefault: + case TaskType::kMainThreadTaskQueueInput: + case TaskType::kMainThreadTaskQueueIdle: + case TaskType::kMainThreadTaskQueueIPC: + case TaskType::kMainThreadTaskQueueControl: + case TaskType::kCompositorThreadTaskQueueDefault: + case TaskType::kWorkerThreadTaskQueueDefault: case TaskType::kCount: NOTREACHED(); break; @@ -325,9 +358,8 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::LoadingTaskQueue() { if (!loading_task_queue_) { // TODO(panicker): Avoid adding this queue in RS task_runners_. loading_task_queue_ = main_thread_scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoading); + MainThreadTaskQueue::QueueType::kFrameLoading, this); loading_task_queue_->SetBlameContext(blame_context_); - loading_task_queue_->SetFrameScheduler(this); loading_queue_enabled_voter_ = loading_task_queue_->CreateQueueEnabledVoter(); loading_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); @@ -339,9 +371,8 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::LoadingControlTaskQueue() { DCHECK(parent_page_scheduler_); if (!loading_control_task_queue_) { loading_control_task_queue_ = main_thread_scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoadingControl); + MainThreadTaskQueue::QueueType::kFrameLoadingControl, this); loading_control_task_queue_->SetBlameContext(blame_context_); - loading_control_task_queue_->SetFrameScheduler(this); loading_control_queue_enabled_voter_ = loading_control_task_queue_->CreateQueueEnabledVoter(); loading_control_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); @@ -357,12 +388,12 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::ThrottleableTaskQueue() { MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kFrameThrottleable) .SetCanBeThrottled(true) - .SetCanBeStopped(true) + .SetCanBeFrozen(true) .SetFreezeWhenKeepActive(true) .SetCanBeDeferred(true) - .SetCanBePaused(true)); + .SetCanBePaused(true) + .SetFrameScheduler(this)); throttleable_task_queue_->SetBlameContext(blame_context_); - throttleable_task_queue_->SetFrameScheduler(this); throttleable_queue_enabled_voter_ = throttleable_task_queue_->CreateQueueEnabledVoter(); throttleable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); @@ -374,7 +405,7 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::ThrottleableTaskQueue() { main_thread_scheduler_->tick_clock()->NowTicks(), throttleable_task_queue_.get()); } - UpdateTaskQueueThrottling(); + UpdateThrottling(); } return throttleable_task_queue_; } @@ -386,11 +417,11 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::DeferrableTaskQueue() { MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kFrameDeferrable) .SetCanBeDeferred(true) - .SetCanBeStopped( + .SetCanBeFrozen( RuntimeEnabledFeatures::StopNonTimersInBackgroundEnabled()) - .SetCanBePaused(true)); + .SetCanBePaused(true) + .SetFrameScheduler(this)); deferrable_task_queue_->SetBlameContext(blame_context_); - deferrable_task_queue_->SetFrameScheduler(this); deferrable_queue_enabled_voter_ = deferrable_task_queue_->CreateQueueEnabledVoter(); deferrable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); @@ -404,11 +435,11 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::PausableTaskQueue() { pausable_task_queue_ = main_thread_scheduler_->NewTaskQueue( MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kFramePausable) - .SetCanBeStopped( + .SetCanBeFrozen( RuntimeEnabledFeatures::StopNonTimersInBackgroundEnabled()) - .SetCanBePaused(true)); + .SetCanBePaused(true) + .SetFrameScheduler(this)); pausable_task_queue_->SetBlameContext(blame_context_); - pausable_task_queue_->SetFrameScheduler(this); pausable_queue_enabled_voter_ = pausable_task_queue_->CreateQueueEnabledVoter(); pausable_queue_enabled_voter_->SetQueueEnabled(!frame_paused_); @@ -421,16 +452,17 @@ scoped_refptr<TaskQueue> FrameSchedulerImpl::UnpausableTaskQueue() { if (!unpausable_task_queue_) { unpausable_task_queue_ = main_thread_scheduler_->NewTaskQueue( MainThreadTaskQueue::QueueCreationParams( - MainThreadTaskQueue::QueueType::kFrameUnpausable)); + MainThreadTaskQueue::QueueType::kFrameUnpausable) + .SetFrameScheduler(this)); unpausable_task_queue_->SetBlameContext(blame_context_); - unpausable_task_queue_->SetFrameScheduler(this); } return unpausable_task_queue_; } -scoped_refptr<TaskQueue> FrameSchedulerImpl::ControlTaskQueue() { +scoped_refptr<base::SingleThreadTaskRunner> +FrameSchedulerImpl::ControlTaskRunner() { DCHECK(parent_page_scheduler_); - return main_thread_scheduler_->ControlTaskQueue(); + return main_thread_scheduler_->ControlTaskRunner(); } blink::PageScheduler* FrameSchedulerImpl::GetPageScheduler() const { @@ -473,8 +505,7 @@ void FrameSchedulerImpl::DidCloseActiveConnection() { void FrameSchedulerImpl::AsValueInto( base::trace_event::TracedValue* state) const { state->SetBoolean("frame_visible", frame_visible_); - state->SetBoolean("page_visible", - page_visibility_ == PageVisibilityState::kVisible); + state->SetBoolean("page_visible", parent_page_scheduler_->IsPageVisible()); state->SetBoolean("cross_origin", IsCrossOrigin()); state->SetString("frame_type", frame_type_ == FrameScheduler::FrameType::kMainFrame @@ -514,20 +545,14 @@ void FrameSchedulerImpl::AsValueInto( } } -void FrameSchedulerImpl::SetPageVisibility( +void FrameSchedulerImpl::SetPageVisibilityForTracing( PageVisibilityState page_visibility) { - DCHECK(parent_page_scheduler_); - if (page_visibility_ == page_visibility) - return; - page_visibility_ = page_visibility; - if (page_visibility_ == PageVisibilityState::kVisible) - page_frozen_ = false; // visible page must not be frozen. - UpdateTaskQueues(); - UpdateTaskQueueThrottling(); + page_visibility_for_tracing_ = page_visibility; } bool FrameSchedulerImpl::IsPageVisible() const { - return page_visibility_ == PageVisibilityState::kVisible; + return parent_page_scheduler_ ? parent_page_scheduler_->IsPageVisible() + : true; } void FrameSchedulerImpl::SetPaused(bool frame_paused) { @@ -536,65 +561,76 @@ void FrameSchedulerImpl::SetPaused(bool frame_paused) { return; frame_paused_ = frame_paused; - UpdateTaskQueues(); + UpdatePolicy(); } -void FrameSchedulerImpl::SetPageFrozen(bool frozen) { - DCHECK(!frozen || page_visibility_ == PageVisibilityState::kHidden); - page_frozen_ = frozen; - UpdateTaskQueues(); +void FrameSchedulerImpl::SetPageFrozenForTracing(bool frozen) { + page_frozen_for_tracing_ = frozen; } -void FrameSchedulerImpl::SetKeepActive(bool keep_active) { - keep_active_ = keep_active; - UpdateTaskQueues(); +void FrameSchedulerImpl::SetPageKeepActiveForTracing(bool keep_active) { + page_keep_active_for_tracing_ = keep_active; } -void FrameSchedulerImpl::UpdateTaskQueues() { - // Per-frame (stoppable) task queues will be stopped after 5mins in +void FrameSchedulerImpl::UpdatePolicy() { + // Per-frame (stoppable) task queues will be frozen after 5mins in // background. They will be resumed when the page is visible. - UpdateTaskQueue(throttleable_task_queue_, - throttleable_queue_enabled_voter_.get()); - UpdateTaskQueue(loading_task_queue_, loading_queue_enabled_voter_.get()); - UpdateTaskQueue(loading_control_task_queue_, - loading_control_queue_enabled_voter_.get()); - UpdateTaskQueue(deferrable_task_queue_, - deferrable_queue_enabled_voter_.get()); - UpdateTaskQueue(pausable_task_queue_, pausable_queue_enabled_voter_.get()); - UpdateThrottlingState(); -} - -void FrameSchedulerImpl::UpdateTaskQueue( + UpdateQueuePolicy(throttleable_task_queue_, + throttleable_queue_enabled_voter_.get()); + UpdateQueuePolicy(loading_task_queue_, loading_queue_enabled_voter_.get()); + UpdateQueuePolicy(loading_control_task_queue_, + loading_control_queue_enabled_voter_.get()); + UpdateQueuePolicy(deferrable_task_queue_, + deferrable_queue_enabled_voter_.get()); + UpdateQueuePolicy(pausable_task_queue_, pausable_queue_enabled_voter_.get()); + + UpdateThrottling(); + + NotifyThrottlingObservers(); +} + +void FrameSchedulerImpl::UpdateQueuePolicy( const scoped_refptr<MainThreadTaskQueue>& queue, TaskQueue::QueueEnabledVoter* voter) { if (!queue || !voter) return; + DCHECK(parent_page_scheduler_); bool queue_paused = frame_paused_ && queue->CanBePaused(); - bool queue_frozen = page_frozen_ && queue->CanBeStopped(); + bool queue_frozen = + parent_page_scheduler_->IsFrozen() && queue->CanBeFrozen(); // Override freezing if keep-active is true. if (queue_frozen && !queue->FreezeWhenKeepActive()) - queue_frozen = !keep_active_; + queue_frozen = !parent_page_scheduler_->KeepActive(); voter->SetQueueEnabled(!queue_paused && !queue_frozen); } -void FrameSchedulerImpl::UpdateThrottlingState() { - FrameScheduler::ThrottlingState throttling_state = CalculateThrottlingState(); - if (throttling_state == throttling_state_) - return; - throttling_state_ = throttling_state; - for (auto observer : loader_observers_) - observer->OnThrottlingStateChanged(throttling_state_); +void FrameSchedulerImpl::NotifyThrottlingObservers() { + for (const auto& observer : throttling_observers_) { + observer.first->OnThrottlingStateChanged( + CalculateThrottlingState(observer.second)); + } } -FrameScheduler::ThrottlingState FrameSchedulerImpl::CalculateThrottlingState() - const { +FrameScheduler::ThrottlingState FrameSchedulerImpl::CalculateThrottlingState( + ObserverType type) const { + // Detached frames are not throttled. + if (!parent_page_scheduler_) + return FrameScheduler::ThrottlingState::kNotThrottled; + if (RuntimeEnabledFeatures::StopLoadingInBackgroundEnabled() && - page_frozen_ && !keep_active_) { - DCHECK(page_visibility_ == PageVisibilityState::kHidden); + parent_page_scheduler_->IsFrozen() && + !parent_page_scheduler_->KeepActive()) { + DCHECK(!parent_page_scheduler_->IsPageVisible()); return FrameScheduler::ThrottlingState::kStopped; } - if (page_visibility_ == PageVisibilityState::kHidden) + if (type == ObserverType::kLoader && + parent_page_scheduler_->HasActiveConnection()) { + return FrameScheduler::ThrottlingState::kNotThrottled; + } + if (parent_page_scheduler_->IsThrottled()) return FrameScheduler::ThrottlingState::kThrottled; + if (!parent_page_scheduler_->IsPageVisible()) + return FrameScheduler::ThrottlingState::kHidden; return FrameScheduler::ThrottlingState::kNotThrottled; } @@ -608,13 +644,15 @@ FrameSchedulerImpl::OnActiveConnectionCreated() { } bool FrameSchedulerImpl::ShouldThrottleTimers() const { - if (page_visibility_ == PageVisibilityState::kHidden) + if (parent_page_scheduler_ && parent_page_scheduler_->IsAudioPlaying()) + return false; + if (!parent_page_scheduler_->IsPageVisible()) return true; return RuntimeEnabledFeatures::TimerThrottlingForHiddenFramesEnabled() && !frame_visible_ && IsCrossOrigin(); } -void FrameSchedulerImpl::UpdateTaskQueueThrottling() { +void FrameSchedulerImpl::UpdateThrottling() { // Before we initialize a trottleable task queue, |task_queue_throttled_| // stays false and this function ensures it indicates whether are we holding // a queue reference for throttler or not. 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 91df102ab76..43f223c2c6f 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 @@ -10,6 +10,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" @@ -20,6 +21,9 @@ #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace base { +namespace sequence_manager { +class TaskQueue; +} // namespace sequence_manager namespace trace_event { class BlameContext; class TracedValue; @@ -32,7 +36,6 @@ namespace scheduler { class MainThreadSchedulerImpl; class MainThreadTaskQueue; class PageSchedulerImpl; -class TaskQueue; namespace main_thread_scheduler_impl_unittest { class MainThreadSchedulerImplTest; @@ -63,8 +66,6 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { bool IsFrameVisible() const override; bool IsPageVisible() const override; void SetPaused(bool frame_paused) override; - void SetPageFrozen(bool) override; - void SetKeepActive(bool) override; void SetCrossOrigin(bool cross_origin) override; bool IsCrossOrigin() const override; @@ -84,13 +85,18 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { void AsValueInto(base::trace_event::TracedValue* state) const; bool IsExemptFromBudgetBasedThrottling() const override; - scoped_refptr<TaskQueue> ControlTaskQueue(); - void SetPageVisibility(PageVisibilityState page_visibility); + scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner(); + + void UpdatePolicy(); bool has_active_connection() const { return has_active_connection_; } void OnTraceLogEnabled() { tracing_controller_.OnTraceLogEnabled(); } + void SetPageVisibilityForTracing(PageVisibilityState page_visibility); + void SetPageKeepActiveForTracing(bool keep_active); + void SetPageFrozenForTracing(bool frozen); + private: friend class PageSchedulerImpl; friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest; @@ -125,23 +131,24 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { void RemoveThrottleableQueueFromBackgroundCPUTimeBudgetPool(); void ApplyPolicyToThrottleableQueue(); bool ShouldThrottleTimers() const; - void UpdateTaskQueueThrottling(); - FrameScheduler::ThrottlingState CalculateThrottlingState() const; - void UpdateThrottlingState(); + FrameScheduler::ThrottlingState CalculateThrottlingState( + ObserverType type) const; void RemoveThrottlingObserver(Observer* observer); - void UpdateTaskQueues(); - void UpdateTaskQueue(const scoped_refptr<MainThreadTaskQueue>& queue, - TaskQueue::QueueEnabledVoter* voter); + void UpdateQueuePolicy( + const scoped_refptr<MainThreadTaskQueue>& queue, + base::sequence_manager::TaskQueue::QueueEnabledVoter* voter); + void UpdateThrottling(); + void NotifyThrottlingObservers(); void DidOpenActiveConnection(); void DidCloseActiveConnection(); - scoped_refptr<TaskQueue> LoadingTaskQueue(); - scoped_refptr<TaskQueue> LoadingControlTaskQueue(); - scoped_refptr<TaskQueue> ThrottleableTaskQueue(); - scoped_refptr<TaskQueue> DeferrableTaskQueue(); - scoped_refptr<TaskQueue> PausableTaskQueue(); - scoped_refptr<TaskQueue> UnpausableTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> LoadingTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> LoadingControlTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> ThrottleableTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> DeferrableTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> PausableTaskQueue(); + scoped_refptr<base::sequence_manager::TaskQueue> UnpausableTaskQueue(); base::WeakPtr<FrameSchedulerImpl> GetWeakPtr(); @@ -154,23 +161,23 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { scoped_refptr<MainThreadTaskQueue> deferrable_task_queue_; scoped_refptr<MainThreadTaskQueue> pausable_task_queue_; scoped_refptr<MainThreadTaskQueue> unpausable_task_queue_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> loading_queue_enabled_voter_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + loading_queue_enabled_voter_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> loading_control_queue_enabled_voter_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> throttleable_queue_enabled_voter_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> deferrable_queue_enabled_voter_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> pausable_queue_enabled_voter_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + deferrable_queue_enabled_voter_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + pausable_queue_enabled_voter_; MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED PageSchedulerImpl* parent_page_scheduler_; // NOT OWNED base::trace_event::BlameContext* blame_context_; // NOT OWNED - std::set<Observer*> loader_observers_; // NOT OWNED + // Observers are not owned by the scheduler. + std::unordered_map<Observer*, ObserverType> throttling_observers_; FrameScheduler::ThrottlingState throttling_state_; TraceableState<bool, kTracingCategoryNameInfo> frame_visible_; - TraceableState<PageVisibilityState, kTracingCategoryNameInfo> - page_visibility_; - TraceableState<bool, kTracingCategoryNameInfo> page_frozen_; - TraceableState<bool, kTracingCategoryNameInfo> keep_active_; TraceableState<bool, kTracingCategoryNameInfo> frame_paused_; TraceableState<FrameOriginType, kTracingCategoryNameInfo> frame_origin_type_; StateTracer<kTracingCategoryNameInfo> url_tracer_; @@ -181,6 +188,14 @@ class PLATFORM_EXPORT FrameSchedulerImpl : public FrameScheduler { int active_connection_count_; TraceableState<bool, kTracingCategoryNameInfo> has_active_connection_; + // These are the states of the Page. + // They should be accessed via GetPageScheduler()->SetPageState(). + // they are here because we don't support page-level tracing yet. + TraceableState<bool, kTracingCategoryNameInfo> page_frozen_for_tracing_; + TraceableState<PageVisibilityState, kTracingCategoryNameInfo> + page_visibility_for_tracing_; + TraceableState<bool, kTracingCategoryNameInfo> page_keep_active_for_tracing_; + base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl); 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 763ac9e2e76..e7c9e3858e4 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 @@ -10,14 +10,18 @@ #include "base/location.h" #include "base/test/simple_test_tick_clock.h" #include "components/viz/test/ordered_simple_task_runner.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/web_task_runner.h" +using base::sequence_manager::TaskQueue; +using testing::UnorderedElementsAre; + namespace blink { namespace scheduler { // To avoid symbol collisions in jumbo builds. @@ -33,7 +37,8 @@ class FrameSchedulerImplTest : public testing::Test { mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true); scheduler_.reset(new MainThreadSchedulerImpl( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_), base::nullopt)); page_scheduler_.reset( new PageSchedulerImpl(nullptr, scheduler_.get(), false)); @@ -85,6 +90,11 @@ class FrameSchedulerImplTest : public testing::Test { throttleable_task_queue().get()); } + FrameScheduler::ThrottlingState CalculateThrottlingState( + FrameScheduler::ObserverType type) { + return frame_scheduler_->CalculateThrottlingState(type); + } + base::SimpleTestTickClock clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<MainThreadSchedulerImpl> scheduler_; @@ -97,25 +107,35 @@ namespace { class MockThrottlingObserver final : public FrameScheduler::Observer { public: MockThrottlingObserver() - : throttled_count_(0u), not_throttled_count_(0u), stopped_count_(0u) {} - - void CheckObserverState(size_t throttled_count_expectation, - size_t not_throttled_count_expectation, - size_t stopped_count_expectation) { - EXPECT_EQ(throttled_count_expectation, throttled_count_); - EXPECT_EQ(not_throttled_count_expectation, not_throttled_count_); - EXPECT_EQ(stopped_count_expectation, stopped_count_); + : not_throttled_count_(0u), + hidden_count_(0u), + throttled_count_(0u), + stopped_count_(0u) {} + + inline void CheckObserverState(base::Location from, + size_t not_throttled_count_expectation, + size_t hidden_count_expectation, + size_t throttled_count_expectation, + size_t stopped_count_expectation) { + EXPECT_EQ(not_throttled_count_expectation, not_throttled_count_) + << from.ToString(); + EXPECT_EQ(hidden_count_expectation, hidden_count_) << from.ToString(); + EXPECT_EQ(throttled_count_expectation, throttled_count_) << from.ToString(); + EXPECT_EQ(stopped_count_expectation, stopped_count_) << from.ToString(); } void OnThrottlingStateChanged( FrameScheduler::ThrottlingState state) override { switch (state) { - case FrameScheduler::ThrottlingState::kThrottled: - throttled_count_++; - break; case FrameScheduler::ThrottlingState::kNotThrottled: not_throttled_count_++; break; + case FrameScheduler::ThrottlingState::kHidden: + hidden_count_++; + break; + case FrameScheduler::ThrottlingState::kThrottled: + throttled_count_++; + break; case FrameScheduler::ThrottlingState::kStopped: stopped_count_++; break; @@ -124,8 +144,9 @@ class MockThrottlingObserver final : public FrameScheduler::Observer { } private: - size_t throttled_count_; size_t not_throttled_count_; + size_t hidden_count_; + size_t throttled_count_; size_t stopped_count_; }; @@ -133,6 +154,11 @@ void IncrementCounter(int* counter) { ++*counter; } +void RecordQueueName(const scoped_refptr<TaskQueue> task_queue, + std::vector<std::string>* tasks) { + tasks->push_back(task_queue->GetName()); +} + } // namespace // Throttleable task queue is initialized lazily, so there're two scenarios: @@ -293,15 +319,15 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagEnabled) { UnpausableTaskQueue()->PostTask( FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); - frame_scheduler_->SetPageVisibility(PageVisibilityState::kHidden); - frame_scheduler_->SetPageFrozen(true); + page_scheduler_->SetPageVisible(false); + page_scheduler_->SetPageFrozen(true); EXPECT_EQ(0, counter); mock_task_runner_->RunUntilIdle(); // unpausable tasks continue to run. EXPECT_EQ(1, counter); - frame_scheduler_->SetPageFrozen(false); + page_scheduler_->SetPageFrozen(false); EXPECT_EQ(1, counter); mock_task_runner_->RunUntilIdle(); @@ -323,15 +349,15 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagDisabled) { UnpausableTaskQueue()->PostTask( FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); - frame_scheduler_->SetPageVisibility(PageVisibilityState::kHidden); - frame_scheduler_->SetPageFrozen(true); + page_scheduler_->SetPageVisible(false); + page_scheduler_->SetPageFrozen(true); EXPECT_EQ(0, counter); mock_task_runner_->RunUntilIdle(); // throttleable tasks are frozen, other tasks continue to run. EXPECT_EQ(4, counter); - frame_scheduler_->SetPageFrozen(false); + page_scheduler_->SetPageFrozen(false); EXPECT_EQ(4, counter); mock_task_runner_->RunUntilIdle(); @@ -341,46 +367,60 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndUnfreezeFlagDisabled) { TEST_F(FrameSchedulerImplTest, PageFreezeWithKeepActive) { ScopedStopLoadingInBackgroundForTest stop_loading_enabler(true); ScopedStopNonTimersInBackgroundForTest stop_non_timers_enabler(false); - int counter = 0; + std::vector<std::string> tasks; LoadingTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&RecordQueueName, LoadingTaskQueue(), &tasks)); ThrottleableTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, + base::BindOnce(&RecordQueueName, ThrottleableTaskQueue(), &tasks)); DeferrableTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, + base::BindOnce(&RecordQueueName, DeferrableTaskQueue(), &tasks)); PausableTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&RecordQueueName, PausableTaskQueue(), &tasks)); UnpausableTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, + base::BindOnce(&RecordQueueName, UnpausableTaskQueue(), &tasks)); - frame_scheduler_->SetKeepActive(true); // say we have a Service Worker - frame_scheduler_->SetPageVisibility(PageVisibilityState::kHidden); - frame_scheduler_->SetPageFrozen(true); + page_scheduler_->SetKeepActive(true); // say we have a Service Worker + page_scheduler_->SetPageVisible(false); + page_scheduler_->SetPageFrozen(true); - EXPECT_EQ(0, counter); + EXPECT_THAT(tasks, UnorderedElementsAre()); mock_task_runner_->RunUntilIdle(); // Everything runs except throttleable tasks (timers) - EXPECT_EQ(4, counter); + EXPECT_THAT(tasks, UnorderedElementsAre( + std::string(LoadingTaskQueue()->GetName()), + std::string(DeferrableTaskQueue()->GetName()), + std::string(PausableTaskQueue()->GetName()), + std::string(UnpausableTaskQueue()->GetName()))); + tasks.clear(); LoadingTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&RecordQueueName, LoadingTaskQueue(), &tasks)); - EXPECT_EQ(4, counter); + EXPECT_THAT(tasks, UnorderedElementsAre()); mock_task_runner_->RunUntilIdle(); - EXPECT_EQ(5, counter); // loading task runs + // loading task runs + EXPECT_THAT(tasks, + UnorderedElementsAre(std::string(LoadingTaskQueue()->GetName()))); + tasks.clear(); LoadingTaskQueue()->PostTask( - FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&RecordQueueName, LoadingTaskQueue(), &tasks)); // KeepActive is false when Service Worker stops. - frame_scheduler_->SetKeepActive(false); - EXPECT_EQ(5, counter); + page_scheduler_->SetKeepActive(false); + EXPECT_THAT(tasks, UnorderedElementsAre()); mock_task_runner_->RunUntilIdle(); - EXPECT_EQ(5, counter); // loading task does not run + EXPECT_THAT(tasks, UnorderedElementsAre()); // loading task does not run - frame_scheduler_->SetKeepActive(true); - EXPECT_EQ(5, counter); + tasks.clear(); + page_scheduler_->SetKeepActive(true); + EXPECT_THAT(tasks, UnorderedElementsAre()); mock_task_runner_->RunUntilIdle(); - EXPECT_EQ(6, counter); // loading task runs + // loading task runs + EXPECT_THAT(tasks, + UnorderedElementsAre(std::string(LoadingTaskQueue()->GetName()))); } TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) { @@ -398,15 +438,15 @@ TEST_F(FrameSchedulerImplTest, PageFreezeAndPageVisible) { UnpausableTaskQueue()->PostTask( FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); - frame_scheduler_->SetPageVisibility(PageVisibilityState::kHidden); - frame_scheduler_->SetPageFrozen(true); + page_scheduler_->SetPageVisible(false); + page_scheduler_->SetPageFrozen(true); EXPECT_EQ(0, counter); mock_task_runner_->RunUntilIdle(); EXPECT_EQ(1, counter); // Making the page visible should cause frozen queues to resume. - frame_scheduler_->SetPageVisibility(PageVisibilityState::kVisible); + page_scheduler_->SetPageVisible(true); EXPECT_EQ(1, counter); mock_task_runner_->RunUntilIdle(); @@ -418,12 +458,13 @@ TEST_F(FrameSchedulerImplTest, ThrottlingObserver) { std::unique_ptr<MockThrottlingObserver> observer = std::make_unique<MockThrottlingObserver>(); - size_t throttled_count = 0u; size_t not_throttled_count = 0u; + size_t hidden_count = 0u; + size_t throttled_count = 0u; size_t stopped_count = 0u; - observer->CheckObserverState(throttled_count, not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + throttled_count, stopped_count); auto observer_handle = frame_scheduler_->AddThrottlingObserver( FrameScheduler::ObserverType::kLoader, observer.get()); @@ -431,36 +472,48 @@ TEST_F(FrameSchedulerImplTest, ThrottlingObserver) { // Initial state should be synchronously notified here. // We assume kNotThrottled is notified as an initial state, but it could // depend on implementation details and can be changed. - observer->CheckObserverState(throttled_count, ++not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, ++not_throttled_count, hidden_count, + throttled_count, stopped_count); // Once the page gets to be invisible, it should notify the observer of - // kThrottled synchronously. + // kHidden synchronously. page_scheduler_->SetPageVisible(false); - observer->CheckObserverState(++throttled_count, not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, ++hidden_count, + throttled_count, stopped_count); - // When no state has changed, observers are not called. + // We do not issue new notifications without actually changing visibility + // state. page_scheduler_->SetPageVisible(false); - observer->CheckObserverState(throttled_count, not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + throttled_count, stopped_count); + + mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(30)); + + // The frame gets throttled after some time in background. + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + ++throttled_count, stopped_count); + + // We shouldn't issue new notifications for kThrottled state as well. + page_scheduler_->SetPageVisible(false); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + throttled_count, stopped_count); // Setting background page to STOPPED, notifies observers of kStopped. page_scheduler_->SetPageFrozen(true); - observer->CheckObserverState(throttled_count, not_throttled_count, - ++stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + throttled_count, ++stopped_count); // When page is not in the STOPPED state, then page visibility is used, // notifying observer of kThrottled. page_scheduler_->SetPageFrozen(false); - observer->CheckObserverState(++throttled_count, not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + ++throttled_count, stopped_count); // Going back to visible state should notify the observer of kNotThrottled // synchronously. page_scheduler_->SetPageVisible(true); - observer->CheckObserverState(throttled_count, ++not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, ++not_throttled_count, hidden_count, + throttled_count, stopped_count); // Remove from the observer list, and see if any other callback should not be // invoked when the condition is changed. @@ -471,8 +524,16 @@ TEST_F(FrameSchedulerImplTest, ThrottlingObserver) { clock_.Advance(base::TimeDelta::FromSeconds(100)); mock_task_runner_->RunUntilIdle(); - observer->CheckObserverState(throttled_count, not_throttled_count, - stopped_count); + observer->CheckObserverState(FROM_HERE, not_throttled_count, hidden_count, + throttled_count, stopped_count); +} + +TEST_F(FrameSchedulerImplTest, DefaultThrottlingState) { + EXPECT_EQ(CalculateThrottlingState(FrameScheduler::ObserverType::kLoader), + FrameScheduler::ThrottlingState::kNotThrottled); + EXPECT_EQ( + CalculateThrottlingState(FrameScheduler::ObserverType::kWorkerScheduler), + FrameScheduler::ThrottlingState::kNotThrottled); } } // namespace frame_scheduler_impl_unittest diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.cc index 4ee87d3e6cb..48bb7f4d028 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.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/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include "base/time/default_tick_clock.h" @@ -10,7 +10,8 @@ namespace blink { namespace scheduler { IdleTimeEstimator::IdleTimeEstimator( - const scoped_refptr<TaskQueue>& compositor_task_runner, + const scoped_refptr<base::sequence_manager::TaskQueue>& + compositor_task_runner, const base::TickClock* time_source, int sample_count, double estimation_percentile) diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h index 43cdbcb8bdb..48141651c0e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h @@ -2,8 +2,8 @@ // 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_RENDERER_IDLE_TIME_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_IDLE_TIME_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -19,7 +19,8 @@ namespace scheduler { class PLATFORM_EXPORT IdleTimeEstimator : public base::MessageLoop::TaskObserver { public: - IdleTimeEstimator(const scoped_refptr<TaskQueue>& compositor_task_runner, + IdleTimeEstimator(const scoped_refptr<base::sequence_manager::TaskQueue>& + compositor_task_runner, const base::TickClock* time_source, int sample_count, double estimation_percentile); @@ -40,7 +41,7 @@ class PLATFORM_EXPORT IdleTimeEstimator void DidProcessTask(const base::PendingTask& pending_task) override; private: - scoped_refptr<TaskQueue> compositor_task_queue_; + scoped_refptr<base::sequence_manager::TaskQueue> compositor_task_queue_; cc::RollingTimeDeltaHistory per_frame_compositor_task_runtime_; const base::TickClock* time_source_; // NOT OWNED double estimation_percentile_; @@ -57,4 +58,4 @@ class PLATFORM_EXPORT IdleTimeEstimator } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_IDLE_TIME_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_IDLE_TIME_ESTIMATOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_unittest.cc index 326bdccfd1a..57b5b940027 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator_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/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/idle_time_estimator.h" #include <memory> #include "base/memory/scoped_refptr.h" @@ -12,9 +12,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" -#include "third_party/blink/renderer/platform/scheduler/base/test_task_time_observer.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" -#include "third_party/blink/renderer/platform/scheduler/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/test_task_time_observer.h" namespace blink { namespace scheduler { @@ -22,7 +22,8 @@ namespace scheduler { class IdleTimeEstimatorForTest : public IdleTimeEstimator { public: IdleTimeEstimatorForTest( - const scoped_refptr<TaskQueue>& compositor_task_runner, + const scoped_refptr<base::sequence_manager::TaskQueue>& + compositor_task_runner, const base::TickClock* clock, int sample_count, double estimation_percentile) @@ -43,10 +44,11 @@ class IdleTimeEstimatorTest : public testing::Test { clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); - manager_ = - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_); + manager_ = base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_); compositor_task_queue_ = - manager_->CreateTaskQueue<TestTaskQueue>(TaskQueue::Spec("test_tq")); + manager_->CreateTaskQueue<base::sequence_manager::TestTaskQueue>( + base::sequence_manager::TaskQueue::Spec("test_tq")); estimator_.reset( new IdleTimeEstimatorForTest(compositor_task_queue_, &clock_, 10, 50)); } @@ -85,11 +87,11 @@ class IdleTimeEstimatorTest : public testing::Test { base::SimpleTestTickClock clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; - std::unique_ptr<TaskQueueManager> manager_; - scoped_refptr<TaskQueue> compositor_task_queue_; + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager_; + scoped_refptr<base::sequence_manager::TaskQueue> compositor_task_queue_; std::unique_ptr<IdleTimeEstimatorForTest> estimator_; const base::TimeDelta frame_length_; - TestTaskTimeObserver test_task_time_observer_; + base::sequence_manager::TestTaskTimeObserver test_task_time_observer_; }; TEST_F(IdleTimeEstimatorTest, InitialTimeEstimateWithNoData) { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc index 859fb62b089..783c18a88b7 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.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/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h" #include "base/bind.h" #include "base/metrics/histogram_macros.h" @@ -41,7 +41,7 @@ constexpr base::TimeDelta kLongIdlePeriodDiscardingThreshold = } // namespace -RendererMetricsHelper::PerQueueTypeDurationReporters:: +MainThreadMetricsHelper::PerQueueTypeDurationReporters:: PerQueueTypeDurationReporters() : overall(DURATION_PER_QUEUE_TYPE_METRIC_NAME), foreground(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Foreground"), @@ -73,7 +73,7 @@ RendererMetricsHelper::PerQueueTypeDurationReporters:: visible(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".Visible"), hidden_music(DURATION_PER_QUEUE_TYPE_METRIC_NAME ".HiddenMusic") {} -RendererMetricsHelper::RendererMetricsHelper( +MainThreadMetricsHelper::MainThreadMetricsHelper( MainThreadSchedulerImpl* main_thread_scheduler, base::TimeTicks now, bool renderer_backgrounded) @@ -81,19 +81,20 @@ RendererMetricsHelper::RendererMetricsHelper( main_thread_scheduler_(main_thread_scheduler), main_thread_load_tracker_( now, - base::BindRepeating(&RendererMetricsHelper::RecordMainThreadTaskLoad, - base::Unretained(this)), + base::BindRepeating( + &MainThreadMetricsHelper::RecordMainThreadTaskLoad, + base::Unretained(this)), kThreadLoadTrackerReportingInterval), background_main_thread_load_tracker_( now, base::BindRepeating( - &RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad, + &MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad, base::Unretained(this)), kThreadLoadTrackerReportingInterval), foreground_main_thread_load_tracker_( now, base::BindRepeating( - &RendererMetricsHelper::RecordForegroundMainThreadTaskLoad, + &MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad, base::Unretained(this)), kThreadLoadTrackerReportingInterval), per_frame_status_duration_reporter_(DURATION_PER_FRAME_TYPE_METRIC_NAME), @@ -118,42 +119,42 @@ RendererMetricsHelper::RendererMetricsHelper( } } -RendererMetricsHelper::~RendererMetricsHelper() = default; +MainThreadMetricsHelper::~MainThreadMetricsHelper() = default; -void RendererMetricsHelper::OnRendererForegrounded(base::TimeTicks now) { +void MainThreadMetricsHelper::OnRendererForegrounded(base::TimeTicks now) { foreground_main_thread_load_tracker_.Resume(now); background_main_thread_load_tracker_.Pause(now); } -void RendererMetricsHelper::OnRendererBackgrounded(base::TimeTicks now) { +void MainThreadMetricsHelper::OnRendererBackgrounded(base::TimeTicks now) { foreground_main_thread_load_tracker_.Pause(now); background_main_thread_load_tracker_.Resume(now); } -void RendererMetricsHelper::OnRendererShutdown(base::TimeTicks now) { +void MainThreadMetricsHelper::OnRendererShutdown(base::TimeTicks now) { foreground_main_thread_load_tracker_.RecordIdle(now); background_main_thread_load_tracker_.RecordIdle(now); main_thread_load_tracker_.RecordIdle(now); } -void RendererMetricsHelper::ResetForTest(base::TimeTicks now) { +void MainThreadMetricsHelper::ResetForTest(base::TimeTicks now) { main_thread_load_tracker_ = ThreadLoadTracker( now, - base::BindRepeating(&RendererMetricsHelper::RecordMainThreadTaskLoad, + base::BindRepeating(&MainThreadMetricsHelper::RecordMainThreadTaskLoad, base::Unretained(this)), kThreadLoadTrackerReportingInterval); background_main_thread_load_tracker_ = ThreadLoadTracker( now, base::BindRepeating( - &RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad, + &MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad, base::Unretained(this)), kThreadLoadTrackerReportingInterval); foreground_main_thread_load_tracker_ = ThreadLoadTracker( now, base::BindRepeating( - &RendererMetricsHelper::RecordForegroundMainThreadTaskLoad, + &MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad, base::Unretained(this)), kThreadLoadTrackerReportingInterval); } @@ -173,9 +174,9 @@ base::TimeDelta DurationOfIntervalOverlap(base::TimeTicks start1, } // namespace -void RendererMetricsHelper::RecordTaskMetrics( +void MainThreadMetricsHelper::RecordTaskMetrics( MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time) { @@ -344,8 +345,7 @@ void RendererMetricsHelper::RecordTaskMetrics( if (main_thread_scheduler_->main_thread_only().renderer_hidden) { per_queue_type_reporters_.hidden.RecordTask(queue_type, duration); - if (main_thread_scheduler_->ShouldDisableThrottlingBecauseOfAudio( - start_time)) { + if (main_thread_scheduler_->IsAudioPlaying()) { per_queue_type_reporters_.hidden_music.RecordTask(queue_type, duration); } } else { @@ -396,8 +396,8 @@ void RendererMetricsHelper::RecordTaskMetrics( } } -void RendererMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time, - double load) { +void MainThreadMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time, + double load) { int load_percentage = static_cast<int>(load * 100); DCHECK_LE(load_percentage, 100); @@ -429,7 +429,7 @@ void RendererMetricsHelper::RecordMainThreadTaskLoad(base::TimeTicks time, "MainThreadScheduler.RendererMainThreadLoad", load_percentage); } -void RendererMetricsHelper::RecordForegroundMainThreadTaskLoad( +void MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad( base::TimeTicks time, double load) { int load_percentage = static_cast<int>(load * 100); @@ -460,7 +460,7 @@ void RendererMetricsHelper::RecordForegroundMainThreadTaskLoad( load_percentage); } -void RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad( +void MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad( base::TimeTicks time, double load) { int load_percentage = static_cast<int>(load * 100); @@ -492,7 +492,7 @@ void RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad( } // static -void RendererMetricsHelper::RecordBackgroundedTransition( +void MainThreadMetricsHelper::RecordBackgroundedTransition( BackgroundedRendererTransition transition) { UMA_HISTOGRAM_ENUMERATION("RendererScheduler.BackgroundedRendererTransition", transition, BackgroundedRendererTransition::kCount); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h index c8dd67a9f83..0e851539360 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h @@ -2,8 +2,8 @@ // 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_RENDERER_RENDERER_METRICS_HELPER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_METRICS_HELPER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_METRICS_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_METRICS_HELPER_H_ #include "base/macros.h" #include "base/optional.h" @@ -12,9 +12,9 @@ #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/child/metrics_helper.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/renderer/frame_status.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/use_case.h" #include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h" #include "third_party/blink/renderer/platform/scheduler/util/thread_load_tracker.h" @@ -27,15 +27,15 @@ class MainThreadSchedulerImpl; // This enum is used for histogram and should not be renumbered. // It tracks the following possible transitions: -// -> kBackgrounded (-> [STOPPED_* -> kResumed])? -> kForegrounded +// -> kBackgrounded (-> [FROZEN_* -> kResumed])? -> kForegrounded enum class BackgroundedRendererTransition { // Renderer is backgrounded kBackgrounded = 0, - // Renderer is stopped after being backgrounded for a while - kStoppedAfterDelay = 1, - // Renderer is stopped due to critical resources, reserved for future use. - kStoppedDueToCriticalResources = 2, - // Renderer is resumed after being stopped + // Renderer is frozen after being backgrounded for a while + kFrozenAfterDelay = 1, + // Renderer is frozen due to critical resources, reserved for future use. + kFrozenDueToCriticalResources = 2, + // Renderer is resumed after being frozen kResumed = 3, // Renderer is foregrounded kForegrounded = 4, @@ -45,18 +45,18 @@ enum class BackgroundedRendererTransition { // Helper class to take care of metrics on behalf of MainThreadScheduler. // This class should be used only on the main thread. -class PLATFORM_EXPORT RendererMetricsHelper : public MetricsHelper { +class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper { public: static void RecordBackgroundedTransition( BackgroundedRendererTransition transition); - RendererMetricsHelper(MainThreadSchedulerImpl* main_thread_scheduler, - base::TimeTicks now, - bool renderer_backgrounded); - ~RendererMetricsHelper(); + MainThreadMetricsHelper(MainThreadSchedulerImpl* main_thread_scheduler, + base::TimeTicks now, + bool renderer_backgrounded); + ~MainThreadMetricsHelper(); void RecordTaskMetrics(MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start_time, base::TimeTicks end_time, base::Optional<base::TimeDelta> thread_time); @@ -135,10 +135,10 @@ class PLATFORM_EXPORT RendererMetricsHelper : public MetricsHelper { MainThreadTaskLoadState main_thread_task_load_state_; - DISALLOW_COPY_AND_ASSIGN(RendererMetricsHelper); + DISALLOW_COPY_AND_ASSIGN(MainThreadMetricsHelper); }; } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_METRICS_HELPER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_METRICS_HELPER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc index 34f40ea9c16..c31f8cd57b9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_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/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h" #include <memory> #include "base/macros.h" @@ -12,11 +12,13 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/page/launching_process_state.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" + +using base::sequence_manager::TaskQueue; namespace blink { namespace scheduler { @@ -25,7 +27,8 @@ namespace { class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl { public: MainThreadSchedulerImplForTest( - std::unique_ptr<TaskQueueManager> task_queue_manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, base::Optional<base::Time> initial_virtual_time) : MainThreadSchedulerImpl(std::move(task_queue_manager), initial_virtual_time){}; @@ -39,22 +42,24 @@ using base::Bucket; using testing::ElementsAre; using testing::UnorderedElementsAre; -class RendererMetricsHelperTest : public testing::Test { +class MainThreadMetricsHelperTest : public testing::Test { public: - RendererMetricsHelperTest() = default; - ~RendererMetricsHelperTest() = default; + MainThreadMetricsHelperTest() = default; + ~MainThreadMetricsHelperTest() override = default; - void SetUp() { + void SetUp() override { histogram_tester_.reset(new base::HistogramTester()); + clock_.Advance(base::TimeDelta::FromMilliseconds(1)); mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true); scheduler_ = std::make_unique<MainThreadSchedulerImplForTest>( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_), base::nullopt); metrics_helper_ = &scheduler_->main_thread_only().metrics_helper; } - void TearDown() { + void TearDown() override { scheduler_->Shutdown(); scheduler_.reset(); } @@ -84,7 +89,7 @@ class RendererMetricsHelperTest : public testing::Test { clock_.SetNowTicks(start + duration); scoped_refptr<MainThreadTaskQueueForTest> queue( new MainThreadTaskQueueForTest(QueueType::kDefault)); - queue->SetFrameScheduler(scheduler); + queue->SetFrameSchedulerForTest(scheduler); // Pass an empty task for recording. TaskQueue::PostedTask posted_task(base::OnceClosure(), FROM_HERE); TaskQueue::Task task(std::move(posted_task), base::TimeTicks()); @@ -224,17 +229,17 @@ class RendererMetricsHelperTest : public testing::Test { base::SimpleTestTickClock clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<MainThreadSchedulerImplForTest> scheduler_; - RendererMetricsHelper* metrics_helper_; // NOT OWNED + MainThreadMetricsHelper* metrics_helper_; // NOT OWNED std::unique_ptr<base::HistogramTester> histogram_tester_; std::unique_ptr<FakePageScheduler> playing_view_ = - FakePageScheduler::Builder().SetIsPlayingAudio(true).Build(); + FakePageScheduler::Builder().SetIsAudioPlaying(true).Build(); std::unique_ptr<FakePageScheduler> throtting_exempt_view_ = FakePageScheduler::Builder().SetIsThrottlingExempt(true).Build(); - DISALLOW_COPY_AND_ASSIGN(RendererMetricsHelperTest); + DISALLOW_COPY_AND_ASSIGN(MainThreadMetricsHelperTest); }; -TEST_F(RendererMetricsHelperTest, Metrics_PerQueueType) { +TEST_F(MainThreadMetricsHelperTest, Metrics_PerQueueType) { // QueueType::kDefault is checking sub-millisecond task aggregation, // FRAME_* tasks are checking normal task aggregation and other // queue types have a single task. @@ -332,7 +337,7 @@ TEST_F(RendererMetricsHelperTest, Metrics_PerQueueType) { Bucket(static_cast<int>(QueueType::kDetached), 150))); } -TEST_F(RendererMetricsHelperTest, Metrics_PerUseCase) { +TEST_F(MainThreadMetricsHelperTest, Metrics_PerUseCase) { RunTask(UseCase::kNone, Milliseconds(500), base::TimeDelta::FromMilliseconds(4000)); @@ -372,7 +377,7 @@ TEST_F(RendererMetricsHelperTest, Metrics_PerUseCase) { Bucket(static_cast<int>(UseCase::kMainThreadGesture), 60))); } -TEST_F(RendererMetricsHelperTest, GetFrameStatusTest) { +TEST_F(MainThreadMetricsHelperTest, GetFrameStatusTest) { DCHECK_EQ(GetFrameStatus(nullptr), FrameStatus::kNone); FrameStatus frame_statuses_tested[] = { @@ -391,8 +396,8 @@ TEST_F(RendererMetricsHelperTest, GetFrameStatusTest) { } } -TEST_F(RendererMetricsHelperTest, BackgroundedRendererTransition) { - scheduler_->SetStoppingWhenBackgroundedEnabled(true); +TEST_F(MainThreadMetricsHelperTest, BackgroundedRendererTransition) { + scheduler_->SetFreezingWhenBackgroundedEnabled(true); typedef BackgroundedRendererTransition Transition; int backgrounding_transitions = 0; @@ -449,7 +454,7 @@ TEST_F(RendererMetricsHelperTest, BackgroundedRendererTransition) { backgrounding_transitions), Bucket(static_cast<int>(Transition::kForegrounded), foregrounding_transitions), - Bucket(static_cast<int>(Transition::kStoppedAfterDelay), 1))); + Bucket(static_cast<int>(Transition::kFrozenAfterDelay), 1))); scheduler_->SetRendererBackgrounded(false); foregrounding_transitions++; @@ -462,11 +467,11 @@ TEST_F(RendererMetricsHelperTest, BackgroundedRendererTransition) { backgrounding_transitions), Bucket(static_cast<int>(Transition::kForegrounded), foregrounding_transitions), - Bucket(static_cast<int>(Transition::kStoppedAfterDelay), 1), + Bucket(static_cast<int>(Transition::kFrozenAfterDelay), 1), Bucket(static_cast<int>(Transition::kResumed), 1))); } -TEST_F(RendererMetricsHelperTest, TaskCountPerFrameStatus) { +TEST_F(MainThreadMetricsHelperTest, TaskCountPerFrameStatus) { int task_count = 0; struct CountPerFrameStatus { FrameStatus frame_status; @@ -511,7 +516,7 @@ TEST_F(RendererMetricsHelperTest, TaskCountPerFrameStatus) { Bucket(static_cast<int>(FrameStatus::kCrossOriginHiddenService), 7))); } -TEST_F(RendererMetricsHelperTest, TaskCountPerFrameTypeLongerThan) { +TEST_F(MainThreadMetricsHelperTest, TaskCountPerFrameTypeLongerThan) { int total_duration = 0; struct TasksPerFrameStatus { FrameStatus frame_status; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc index 93df1b7da10..ea6584920a5 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.cc @@ -4,13 +4,17 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + MainThreadSchedulerHelper::MainThreadSchedulerHelper( - std::unique_ptr<TaskQueueManager> task_queue_manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, MainThreadSchedulerImpl* main_thread_scheduler) : SchedulerHelper(std::move(task_queue_manager)), main_thread_scheduler_(main_thread_scheduler), @@ -22,7 +26,8 @@ MainThreadSchedulerHelper::MainThreadSchedulerHelper( NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kControl) .SetShouldNotifyObservers(false))) { - InitDefaultQueues(default_task_queue_, control_task_queue_); + InitDefaultQueues(default_task_queue_, control_task_queue_, + TaskType::kMainThreadTaskQueueDefault); task_queue_manager_->EnableCrashKeys("blink_scheduler_task_file_name", "blink_scheduler_task_function_name"); } @@ -55,6 +60,8 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerHelper::NewTaskQueue( scoped_refptr<MainThreadTaskQueue> task_queue = task_queue_manager_->CreateTaskQueue<MainThreadTaskQueue>( params.spec, params, main_thread_scheduler_); + if (params.fixed_priority) + task_queue->SetQueuePriority(params.fixed_priority.value()); if (params.used_for_important_tasks) task_queue->SetQueuePriority(TaskQueue::QueuePriority::kHighestPriority); return task_queue; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h index f82acb3aa0b..0b71b797ba9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_helper.h @@ -7,7 +7,7 @@ #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" namespace blink { namespace scheduler { @@ -17,7 +17,8 @@ class MainThreadSchedulerImpl; class PLATFORM_EXPORT MainThreadSchedulerHelper : public SchedulerHelper { public: MainThreadSchedulerHelper( - std::unique_ptr<TaskQueueManager> task_queue_manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, MainThreadSchedulerImpl* main_thread_scheduler); ~MainThreadSchedulerHelper() override; @@ -28,8 +29,8 @@ class PLATFORM_EXPORT MainThreadSchedulerHelper : public SchedulerHelper { scoped_refptr<MainThreadTaskQueue> ControlMainThreadTaskQueue(); protected: - scoped_refptr<TaskQueue> DefaultTaskQueue() override; - scoped_refptr<TaskQueue> ControlTaskQueue() override; + scoped_refptr<base::sequence_manager::TaskQueue> DefaultTaskQueue() override; + scoped_refptr<base::sequence_manager::TaskQueue> ControlTaskQueue() override; private: MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED 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 17e1f3cb036..292a82df666 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 @@ -4,7 +4,8 @@ #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include <memory> +#include <algorithm> +#include <utility> #include "base/bind.h" #include "base/debug/stack_trace.h" @@ -34,12 +35,17 @@ #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/child/process_state.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.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/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h" namespace blink { namespace scheduler { + +using base::sequence_manager::TaskQueue; +using base::sequence_manager::TaskTimeObserver; +using base::sequence_manager::TimeDomain; + namespace { // The run time of loading tasks is strongly bimodal. The vast majority are // very cheap, but there are usually a handful of very expensive tasks (e.g ~1 @@ -54,9 +60,6 @@ const double kShortIdlePeriodDurationPercentile = 50; // Amount of idle time left in a frame (as a ratio of the vsync interval) above // which main thread compositing can be considered fast. const double kFastCompositingIdleTimeThreshold = .2; -// We do not throttle anything while audio is played and shortly after that. -constexpr base::TimeDelta kThrottlingDelayAfterAudioIsPlayed = - base::TimeDelta::FromSeconds(5); constexpr base::TimeDelta kQueueingTimeWindowDuration = base::TimeDelta::FromSeconds(1); const double kSamplingRateForTaskUkm = 0.0001; @@ -65,7 +68,8 @@ const double kSamplingRateForTaskUkm = 0.0001; const char kWakeUpThrottlingTrial[] = "RendererSchedulerWakeUpThrottling"; const char kWakeUpDurationParam[] = "wake_up_duration_ms"; -constexpr base::TimeDelta kDefaultWakeUpDuration = base::TimeDelta(); +constexpr base::TimeDelta kDefaultWakeUpDuration = + base::TimeDelta::FromMilliseconds(3); base::TimeDelta GetWakeUpDuration() { int duration_ms; @@ -159,10 +163,10 @@ const char* TaskTypeToString(TaskType task_type) { return "IdleTask"; case TaskType::kMiscPlatformAPI: return "MiscPlatformAPI"; - case TaskType::kUnspecedTimer: - return "UnspecedTimer"; + case TaskType::kInternalDefault: + return "InternalDefault"; case TaskType::kInternalLoading: - return "UnspecedLoading"; + return "InternalLoading"; case TaskType::kUnthrottled: return "Unthrottled"; case TaskType::kInternalTest: @@ -181,8 +185,28 @@ const char* TaskTypeToString(TaskType task_type) { return "InternalUserInteraction"; case TaskType::kInternalInspector: return "InternalInspector"; - case TaskType::kInternalAnimation: - return "InternalAnimation"; + case TaskType::kInternalWorker: + return "InternalWorker"; + case TaskType::kMainThreadTaskQueueV8: + return "MainThreadTaskQueueV8"; + case TaskType::kMainThreadTaskQueueCompositor: + return "MainThreadTaskQueueCompositor"; + case TaskType::kMainThreadTaskQueueDefault: + return "MainThreadTaskQueueDefault"; + case TaskType::kMainThreadTaskQueueInput: + return "MainThreadTaskQueueInput"; + case TaskType::kMainThreadTaskQueueIdle: + return "MainThreadTaskQueueIdle"; + case TaskType::kMainThreadTaskQueueIPC: + return "MainThreadTaskQueueIPC"; + case TaskType::kMainThreadTaskQueueControl: + return "MainThreadTaskQueueControl"; + case TaskType::kInternalIntersectionObserver: + return "InternalIntersectionObserver"; + case TaskType::kCompositorThreadTaskQueueDefault: + return "CompositorThreadTaskQueueDefault"; + case TaskType::kWorkerThreadTaskQueueDefault: + return "WorkerThreadTaskQueueDefault"; case TaskType::kCount: return "Count"; } @@ -201,6 +225,13 @@ const char* OptionalTaskDescriptionToString( return MainThreadTaskQueue::NameForQueueType(desc->queue_type.value()); } +const char* OptionalTaskPriorityToString( + base::Optional<TaskQueue::QueuePriority> priority) { + if (!priority) + return nullptr; + return TaskQueue::PriorityToString(priority.value()); +} + bool IsUnconditionalHighPriorityInputEnabled() { return base::FeatureList::IsEnabled(kHighPriorityInput); } @@ -208,16 +239,19 @@ bool IsUnconditionalHighPriorityInputEnabled() { } // namespace MainThreadSchedulerImpl::MainThreadSchedulerImpl( - std::unique_ptr<TaskQueueManager> task_queue_manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, base::Optional<base::Time> initial_virtual_time) : helper_(std::move(task_queue_manager), this), - idle_helper_( - &helper_, - this, - "MainThreadSchedulerIdlePeriod", - base::TimeDelta(), - helper_.NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( - MainThreadTaskQueue::QueueType::kIdle))), + idle_helper_(&helper_, + this, + "MainThreadSchedulerIdlePeriod", + base::TimeDelta(), + helper_.NewTaskQueue( + MainThreadTaskQueue::QueueCreationParams( + MainThreadTaskQueue::QueueType::kIdle) + .SetFixedPriority( + TaskQueue::QueuePriority::kBestEffortPriority))), idle_canceled_delayed_task_sweeper_(&helper_, idle_helper_.IdleTaskRunner()), render_widget_scheduler_signals_(this), @@ -230,8 +264,11 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kInput) .SetShouldMonitorQuiescence(true) - .SetUsedForImportantTasks( - IsUnconditionalHighPriorityInputEnabled()))), + .SetFixedPriority( + IsUnconditionalHighPriorityInputEnabled() + ? base::make_optional( + TaskQueue::QueuePriority::kHighestPriority) + : base::nullopt))), compositor_task_queue_enabled_voter_( compositor_task_queue_->CreateQueueEnabledVoter()), input_task_queue_enabled_voter_( @@ -239,9 +276,9 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( delayed_update_policy_runner_( base::BindRepeating(&MainThreadSchedulerImpl::UpdatePolicy, base::Unretained(this)), - helper_.ControlMainThreadTaskQueue()), - seqlock_queueing_time_estimator_( - QueueingTimeEstimator(this, kQueueingTimeWindowDuration, 20)), + TaskQueueWithTaskType::Create(helper_.ControlMainThreadTaskQueue(), + TaskType::kMainThreadTaskQueueControl)), + queueing_time_estimator_(this, kQueueingTimeWindowDuration, 20), main_thread_only_(this, compositor_task_queue_, helper_.GetClock(), @@ -271,6 +308,11 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( ipc_task_queue_ = NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kIPC)); + v8_task_runner_ = TaskQueueWithTaskType::Create( + v8_task_queue_, TaskType::kMainThreadTaskQueueV8); + compositor_task_runner_ = TaskQueueWithTaskType::Create( + compositor_task_queue_, TaskType::kMainThreadTaskQueueCompositor); + TRACE_EVENT_OBJECT_CREATED_WITH_ID( TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "MainThreadScheduler", this); @@ -284,16 +326,16 @@ MainThreadSchedulerImpl::MainThreadSchedulerImpl( weak_factory_.GetWeakPtr()); } - int32_t delay_for_background_tab_stopping_millis; + int32_t delay_for_background_tab_freezing_millis; if (!base::StringToInt( - base::GetFieldTrialParamValue("BackgroundTabStopping", - "DelayForBackgroundTabStoppingMills"), - &delay_for_background_tab_stopping_millis)) { - delay_for_background_tab_stopping_millis = - kDelayForBackgroundTabStoppingMillis; + base::GetFieldTrialParamValue("BackgroundTabFreezing", + "DelayForBackgroundTabFreezingMills"), + &delay_for_background_tab_freezing_millis)) { + delay_for_background_tab_freezing_millis = + kDelayForBackgroundTabFreezingMillis; } - delay_for_background_tab_stopping_ = base::TimeDelta::FromMilliseconds( - delay_for_background_tab_stopping_millis); + delay_for_background_tab_freezing_ = base::TimeDelta::FromMilliseconds( + delay_for_background_tab_freezing_millis); internal::ProcessState::Get()->is_process_backgrounded = main_thread_only().renderer_backgrounded; @@ -364,37 +406,32 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly( kShortIdlePeriodDurationSampleCount, kShortIdlePeriodDurationPercentile), current_use_case(UseCase::kNone, - "MainThreadScheduler.UseCase", + "Scheduler.UseCase", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, UseCaseToString), longest_jank_free_task_duration( base::TimeDelta(), - "MainThreadScheduler.LongestJankFreeTaskDuration", + "Scheduler.LongestJankFreeTaskDuration", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, TimeDeltaToMilliseconds), renderer_pause_count(0, - "MainThreadScheduler.PauseCount", + "Scheduler.PauseCount", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_), - navigation_task_expected_count( - 0, - "MainThreadScheduler.NavigationTaskExpectedCount", - main_thread_scheduler_impl, - &main_thread_scheduler_impl->tracing_controller_), expensive_task_policy(ExpensiveTaskPolicy::kRun, - "MainThreadScheduler.ExpensiveTaskPolicy", + "Scheduler.ExpensiveTaskPolicy", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, ExpensiveTaskPolicyToString), rail_mode_for_tracing(current_policy.rail_mode(), - "MainThreadScheduler.RAILMode", + "Scheduler.RAILMode", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, RAILModeToString), renderer_hidden(false, - "MainThreadScheduler.Hidden", + "Scheduler.Hidden", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, HiddenStateToString), @@ -405,89 +442,88 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly( BackgroundStateToString), keep_active_fetch_or_worker( false, - "MainThreadScheduler.KeepRendererActive", + "Scheduler.KeepRendererActive", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), - stopping_when_backgrounded_enabled( + freezing_when_backgrounded_enabled( false, - "MainThreadScheduler.StoppingWhenBackgroundedEnabled", - main_thread_scheduler_impl, - &main_thread_scheduler_impl->tracing_controller_, - YesNoStateToString), - stopped_when_backgrounded( - false, - "MainThreadScheduler.StoppedWhenBackgrounded", + "MainThreadScheduler.FreezingWhenBackgroundedEnabled", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), + frozen_when_backgrounded(false, + "MainThreadScheduler.FrozenWhenBackgrounded", + main_thread_scheduler_impl, + &main_thread_scheduler_impl->tracing_controller_, + YesNoStateToString), loading_task_estimated_cost( base::TimeDelta(), - "MainThreadScheduler.LoadingTaskEstimatedCostMs", + "Scheduler.LoadingTaskEstimatedCostMs", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, TimeDeltaToMilliseconds), timer_task_estimated_cost( base::TimeDelta(), - "MainThreadScheduler.TimerTaskEstimatedCostMs", + "Scheduler.TimerTaskEstimatedCostMs", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, TimeDeltaToMilliseconds), loading_tasks_seem_expensive( false, - "MainThreadScheduler.LoadingTasksSeemExpensive", + "Scheduler.LoadingTasksSeemExpensive", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), timer_tasks_seem_expensive( false, - "MainThreadScheduler.TimerTasksSeemExpensive", + "Scheduler.TimerTasksSeemExpensive", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), touchstart_expected_soon(false, - "MainThreadScheduler.TouchstartExpectedSoon", + "Scheduler.TouchstartExpectedSoon", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), have_seen_a_begin_main_frame( false, - "MainThreadScheduler.HasSeenBeginMainFrame", + "Scheduler.HasSeenBeginMainFrame", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), have_reported_blocking_intervention_in_current_policy( false, - "MainThreadScheduler.HasReportedBlockingInterventionInCurrentPolicy", + "Scheduler.HasReportedBlockingInterventionInCurrentPolicy", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), have_reported_blocking_intervention_since_navigation( false, - "MainThreadScheduler.HasReportedBlockingInterventionSinceNavigation", + "Scheduler.HasReportedBlockingInterventionSinceNavigation", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), has_visible_render_widget_with_touch_handler( false, - "MainThreadScheduler.HasVisibleRenderWidgetWithTouchHandler", + "Scheduler.HasVisibleRenderWidgetWithTouchHandler", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), begin_frame_not_expected_soon( false, - "MainThreadScheduler.BeginFrameNotExpectedSoon", + "Scheduler.BeginFrameNotExpectedSoon", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), in_idle_period_for_testing( false, - "MainThreadScheduler.InIdlePeriod", + "Scheduler.InIdlePeriod", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), use_virtual_time(false, - "MainThreadScheduler.UseVirtualTime", + "Scheduler.UseVirtualTime", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), @@ -498,17 +534,17 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly( AudioPlayingStateToString), compositor_will_send_main_frame_not_expected( false, - "MainThreadScheduler.CompositorWillSendMainFrameNotExpected", + "Scheduler.CompositorWillSendMainFrameNotExpected", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), has_navigated(false, - "MainThreadScheduler.HasNavigated", + "Scheduler.HasNavigated", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), pause_timers_for_webview(false, - "MainThreadScheduler.PauseTimersForWebview", + "Scheduler.PauseTimersForWebview", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), @@ -523,10 +559,16 @@ MainThreadSchedulerImpl::MainThreadOnly::MainThreadOnly( RendererProcessTypeToString), task_description_for_tracing( base::nullopt, - "MainThreadScheduler.MainThreadTask", + "Scheduler.MainThreadTask", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, OptionalTaskDescriptionToString), + task_priority_for_tracing( + base::nullopt, + "Scheduler.TaskPriority", + main_thread_scheduler_impl, + &main_thread_scheduler_impl->tracing_controller_, + OptionalTaskPriorityToString), virtual_time_policy(VirtualTimePolicy::kAdvance), virtual_time_pause_count(0), max_virtual_time_task_starvation_count(0), @@ -540,48 +582,48 @@ MainThreadSchedulerImpl::AnyThread::AnyThread( MainThreadSchedulerImpl* main_thread_scheduler_impl) : awaiting_touch_start_response( false, - "MainThreadScheduler.AwaitingTouchstartResponse", + "Scheduler.AwaitingTouchstartResponse", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), in_idle_period(false, - "MainThreadScheduler.InIdlePeriod", + "Scheduler.InIdlePeriod", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), begin_main_frame_on_critical_path( false, - "MainThreadScheduler.BeginMainFrameOnCriticalPath", + "Scheduler.BeginMainFrameOnCriticalPath", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), last_gesture_was_compositor_driven( false, - "MainThreadScheduler.LastGestureWasCompositorDriven", + "Scheduler.LastGestureWasCompositorDriven", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), default_gesture_prevented( true, - "MainThreadScheduler.DefaultGesturePrevented", + "Scheduler.DefaultGesturePrevented", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), have_seen_a_potentially_blocking_gesture( false, - "MainThreadScheduler.HaveSeenPotentiallyBlockingGesture", + "Scheduler.HaveSeenPotentiallyBlockingGesture", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), waiting_for_meaningful_paint( false, - "MainThreadScheduler.WaitingForMeaningfulPaint", + "Scheduler.WaitingForMeaningfulPaint", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString), have_seen_input_since_navigation( false, - "MainThreadScheduler.HaveSeenInputSinceNavigation", + "Scheduler.HaveSeenInputSinceNavigation", main_thread_scheduler_impl, &main_thread_scheduler_impl->tracing_controller_, YesNoStateToString) {} @@ -589,8 +631,7 @@ MainThreadSchedulerImpl::AnyThread::AnyThread( MainThreadSchedulerImpl::AnyThread::~AnyThread() = default; MainThreadSchedulerImpl::CompositorThreadOnly::CompositorThreadOnly() - : last_input_type(blink::WebInputEvent::kUndefined), - main_thread_seems_unresponsive(false) {} + : last_input_type(blink::WebInputEvent::kUndefined) {} MainThreadSchedulerImpl::CompositorThreadOnly::~CompositorThreadOnly() = default; @@ -624,20 +665,22 @@ std::unique_ptr<blink::WebThread> MainThreadSchedulerImpl::CreateMainThread() { } scoped_refptr<base::SingleThreadTaskRunner> -MainThreadSchedulerImpl::DefaultTaskRunner() { - return helper_.DefaultMainThreadTaskQueue(); +MainThreadSchedulerImpl::ControlTaskRunner() { + return TaskQueueWithTaskType::Create(ControlTaskQueue(), + TaskType::kMainThreadTaskQueueControl); } scoped_refptr<base::SingleThreadTaskRunner> -MainThreadSchedulerImpl::CompositorTaskRunner() { - helper_.CheckOnValidThread(); - return compositor_task_queue_; +MainThreadSchedulerImpl::DefaultTaskRunner() { + return TaskQueueWithTaskType::Create(helper_.DefaultMainThreadTaskQueue(), + TaskType::kMainThreadTaskQueueDefault); } scoped_refptr<base::SingleThreadTaskRunner> MainThreadSchedulerImpl::InputTaskRunner() { helper_.CheckOnValidThread(); - return input_task_queue_; + return TaskQueueWithTaskType::Create(input_task_queue_, + TaskType::kMainThreadTaskQueueInput); } scoped_refptr<SingleThreadIdleTaskRunner> @@ -647,11 +690,13 @@ MainThreadSchedulerImpl::IdleTaskRunner() { scoped_refptr<base::SingleThreadTaskRunner> MainThreadSchedulerImpl::IPCTaskRunner() { - return ipc_task_queue_; + return TaskQueueWithTaskType::Create(ipc_task_queue_, + TaskType::kMainThreadTaskQueueIPC); } -scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::DefaultTaskQueue() { - return helper_.DefaultMainThreadTaskQueue(); +scoped_refptr<base::SingleThreadTaskRunner> +MainThreadSchedulerImpl::VirtualTimeControlTaskRunner() { + return virtual_time_control_task_queue_; } scoped_refptr<MainThreadTaskQueue> @@ -671,10 +716,13 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::V8TaskQueue() { } scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::ControlTaskQueue() { - helper_.CheckOnValidThread(); return helper_.ControlMainThreadTaskQueue(); } +scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::DefaultTaskQueue() { + return helper_.DefaultMainThreadTaskQueue(); +} + scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::VirtualTimeControlTaskQueue() { helper_.CheckOnValidThread(); @@ -687,7 +735,7 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTaskQueue( scoped_refptr<MainThreadTaskQueue> task_queue(helper_.NewTaskQueue(params)); std::unique_ptr<TaskQueue::QueueEnabledVoter> voter; - if (params.can_be_blocked || params.can_be_paused || params.can_be_stopped) + if (params.can_be_deferred || params.can_be_paused || params.can_be_frozen) voter = task_queue->CreateQueueEnabledVoter(); auto insert_result = @@ -720,29 +768,33 @@ scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTaskQueue( } scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType queue_type) { + MainThreadTaskQueue::QueueType queue_type, + FrameSchedulerImpl* frame_scheduler) { DCHECK_EQ(MainThreadTaskQueue::QueueClassForQueueType(queue_type), MainThreadTaskQueue::QueueClass::kLoading); return NewTaskQueue( MainThreadTaskQueue::QueueCreationParams(queue_type) .SetCanBePaused(true) - .SetCanBeStopped( + .SetCanBeFrozen( RuntimeEnabledFeatures::StopLoadingInBackgroundEnabled()) .SetCanBeDeferred(true) .SetUsedForImportantTasks( queue_type == - MainThreadTaskQueue::QueueType::kFrameLoadingControl)); + MainThreadTaskQueue::QueueType::kFrameLoadingControl) + .SetFrameScheduler(frame_scheduler)); } scoped_refptr<MainThreadTaskQueue> MainThreadSchedulerImpl::NewTimerTaskQueue( - MainThreadTaskQueue::QueueType queue_type) { + MainThreadTaskQueue::QueueType queue_type, + FrameSchedulerImpl* frame_scheduler) { DCHECK_EQ(MainThreadTaskQueue::QueueClassForQueueType(queue_type), MainThreadTaskQueue::QueueClass::kTimer); return NewTaskQueue(MainThreadTaskQueue::QueueCreationParams(queue_type) .SetCanBePaused(true) - .SetCanBeStopped(true) + .SetCanBeFrozen(true) .SetCanBeDeferred(true) - .SetCanBeThrottled(true)); + .SetCanBeThrottled(true) + .SetFrameScheduler(frame_scheduler)); } std::unique_ptr<WebRenderWidgetSchedulingState> @@ -930,12 +982,12 @@ void MainThreadSchedulerImpl::SetRendererBackgrounded(bool backgrounded) { if (backgrounded) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "MainThreadSchedulerImpl::OnRendererBackgrounded"); - RendererMetricsHelper::RecordBackgroundedTransition( + MainThreadMetricsHelper::RecordBackgroundedTransition( BackgroundedRendererTransition::kBackgrounded); } else { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"), "MainThreadSchedulerImpl::OnRendererForegrounded"); - RendererMetricsHelper::RecordBackgroundedTransition( + MainThreadMetricsHelper::RecordBackgroundedTransition( BackgroundedRendererTransition::kForegrounded); } @@ -943,10 +995,8 @@ void MainThreadSchedulerImpl::SetRendererBackgrounded(bool backgrounded) { internal::ProcessState::Get()->is_process_backgrounded = backgrounded; main_thread_only().background_status_changed_at = tick_clock()->NowTicks(); - seqlock_queueing_time_estimator_.seqlock.WriteBegin(); - seqlock_queueing_time_estimator_.data.OnRendererStateChanged( + queueing_time_estimator_.OnRendererStateChanged( backgrounded, main_thread_only().background_status_changed_at); - seqlock_queueing_time_estimator_.seqlock.WriteEnd(); UpdatePolicy(); @@ -984,19 +1034,16 @@ void MainThreadSchedulerImpl::ResumeTimersForAndroidWebView() { void MainThreadSchedulerImpl::OnAudioStateChanged() { bool is_audio_playing = false; for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) { - is_audio_playing = is_audio_playing || page_scheduler->IsPlayingAudio(); + is_audio_playing = is_audio_playing || page_scheduler->IsAudioPlaying(); } if (is_audio_playing == main_thread_only().is_audio_playing) return; - main_thread_only().last_audio_state_change = helper_.NowTicks(); main_thread_only().is_audio_playing = is_audio_playing; - - UpdatePolicy(); } -std::unique_ptr<MainThreadSchedulerImpl::RendererPauseHandle> +std::unique_ptr<ThreadScheduler::RendererPauseHandle> MainThreadSchedulerImpl::PauseRenderer() { return std::make_unique<RendererPauseHandleImpl>(this); } @@ -1029,11 +1076,11 @@ void MainThreadSchedulerImpl::EndIdlePeriod() { } void MainThreadSchedulerImpl::EndIdlePeriodForTesting( - const base::Closure& callback, + base::OnceClosure callback, base::TimeTicks time_remaining) { main_thread_only().in_idle_period_for_testing = false; EndIdlePeriod(); - callback.Run(); + std::move(callback).Run(); } bool MainThreadSchedulerImpl::PolicyNeedsUpdateForTesting() { @@ -1223,10 +1270,6 @@ void MainThreadSchedulerImpl::DidHandleInputEventOnMainThread( } } -base::TimeDelta MainThreadSchedulerImpl::MostRecentExpectedQueueingTime() { - return main_thread_only().most_recent_expected_queueing_time; -} - bool MainThreadSchedulerImpl::IsHighPriorityWorkAnticipated() { helper_.CheckOnValidThread(); if (helper_.IsShutdown()) @@ -1283,12 +1326,12 @@ base::TimeTicks MainThreadSchedulerImpl::CurrentIdleTaskDeadlineForTesting() } void MainThreadSchedulerImpl::RunIdleTasksForTesting( - const base::Closure& callback) { + base::OnceClosure callback) { main_thread_only().in_idle_period_for_testing = true; IdleTaskRunner()->PostIdleTask( FROM_HERE, base::BindOnce(&MainThreadSchedulerImpl::EndIdlePeriodForTesting, - weak_factory_.GetWeakPtr(), callback)); + weak_factory_.GetWeakPtr(), std::move(callback))); idle_helper_.EnableLongIdlePeriod(); } @@ -1392,33 +1435,22 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { new_policy_duration = touchstart_expected_flag_valid_for_duration; } - // Do not throttle while audio is playing or for a short period after that - // to make sure that pages playing short audio clips powered by timers - // work. - if (main_thread_only().last_audio_state_change && - !main_thread_only().is_audio_playing) { - UpdatePolicyDuration(now, - main_thread_only().last_audio_state_change.value() + - kThrottlingDelayAfterAudioIsPlayed, - &new_policy_duration); - } - - bool previously_stopped_when_backgrounded = - main_thread_only().stopped_when_backgrounded; - bool newly_stopped = false; + bool previously_frozen_when_backgrounded = + main_thread_only().frozen_when_backgrounded; + bool newly_frozen = false; if (main_thread_only().renderer_backgrounded && - main_thread_only().stopping_when_backgrounded_enabled) { + main_thread_only().freezing_when_backgrounded_enabled) { base::TimeTicks stop_at = main_thread_only().background_status_changed_at + - delay_for_background_tab_stopping_; + delay_for_background_tab_freezing_; - newly_stopped = !main_thread_only().stopped_when_backgrounded; - main_thread_only().stopped_when_backgrounded = now >= stop_at; - newly_stopped &= main_thread_only().stopped_when_backgrounded; + newly_frozen = !main_thread_only().frozen_when_backgrounded; + main_thread_only().frozen_when_backgrounded = now >= stop_at; + newly_frozen &= main_thread_only().frozen_when_backgrounded; - if (!main_thread_only().stopped_when_backgrounded) + if (!main_thread_only().frozen_when_backgrounded) UpdatePolicyDuration(now, stop_at, &new_policy_duration); } else { - main_thread_only().stopped_when_backgrounded = false; + main_thread_only().frozen_when_backgrounded = false; } if (new_policy_duration > base::TimeDelta()) { @@ -1530,8 +1562,7 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { new_policy.rail_mode() = v8::PERFORMANCE_IDLE; if (expensive_task_policy == ExpensiveTaskPolicy::kBlock && - (!main_thread_only().have_seen_a_begin_main_frame || - main_thread_only().navigation_task_expected_count > 0)) { + !main_thread_only().have_seen_a_begin_main_frame) { expensive_task_policy = ExpensiveTaskPolicy::kRun; } @@ -1557,10 +1588,10 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { } main_thread_only().expensive_task_policy = expensive_task_policy; - if (main_thread_only().stopped_when_backgrounded) { + if (main_thread_only().frozen_when_backgrounded) { // TODO(panicker): Remove this, as it is controlled at // FrameScheduler. This is currently needed to avoid early out. - new_policy.timer_queue_policy().is_stopped = true; + new_policy.timer_queue_policy().is_frozen = true; } if (main_thread_only().renderer_pause_count != 0) { @@ -1583,9 +1614,7 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { new_policy.timer_queue_policy().use_virtual_time = true; } - new_policy.should_disable_throttling() = - ShouldDisableThrottlingBecauseOfAudio(now) || - main_thread_only().use_virtual_time; + new_policy.should_disable_throttling() = main_thread_only().use_virtual_time; // Tracing is done before the early out check, because it's quite possible we // will otherwise miss this information in traces. @@ -1615,13 +1644,13 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { // TODO(skyostil): send these notifications after releasing the scheduler // lock. - if (main_thread_only().stopping_when_backgrounded_enabled) { - if (main_thread_only().stopped_when_backgrounded != - previously_stopped_when_backgrounded) { - SetStoppedInBackground(main_thread_only().stopped_when_backgrounded); - RendererMetricsHelper::RecordBackgroundedTransition( - main_thread_only().stopped_when_backgrounded - ? BackgroundedRendererTransition::kStoppedAfterDelay + if (main_thread_only().freezing_when_backgrounded_enabled) { + if (main_thread_only().frozen_when_backgrounded != + previously_frozen_when_backgrounded) { + SetFrozenInBackground(main_thread_only().frozen_when_backgrounded); + MainThreadMetricsHelper::RecordBackgroundedTransition( + main_thread_only().frozen_when_backgrounded + ? BackgroundedRendererTransition::kFrozenAfterDelay : BackgroundedRendererTransition::kResumed); } } @@ -1638,7 +1667,7 @@ void MainThreadSchedulerImpl::UpdatePolicyLocked(UpdateType update_type) { DCHECK(compositor_task_queue_->IsQueueEnabled()); main_thread_only().current_policy = new_policy; - if (newly_stopped) + if (newly_frozen) Platform::Current()->RequestPurgeMemory(); } @@ -1774,10 +1803,10 @@ bool MainThreadSchedulerImpl::CanEnterLongIdlePeriod( return true; } -void MainThreadSchedulerImpl::SetStoppedInBackground(bool stopped) const { +void MainThreadSchedulerImpl::SetFrozenInBackground(bool frozen) const { for (PageSchedulerImpl* page_scheduler : main_thread_only().page_schedulers) { // This moves the page to FROZEN lifecycle state. - page_scheduler->SetPageFrozen(stopped); + page_scheduler->SetPageFrozen(frozen); } } @@ -1801,9 +1830,16 @@ IdleTimeEstimator* MainThreadSchedulerImpl::GetIdleTimeEstimatorForTesting() { } WakeUpBudgetPool* MainThreadSchedulerImpl::GetWakeUpBudgetPoolForTesting() { + InitWakeUpBudgetPoolIfNeeded(); return main_thread_only().wake_up_budget_pool; } +base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime() { + return EnableVirtualTime(main_thread_only().initial_virtual_time.is_null() + ? BaseTimeOverridePolicy::DO_NOT_OVERRIDE + : BaseTimeOverridePolicy::OVERRIDE); +} + base::TimeTicks MainThreadSchedulerImpl::EnableVirtualTime( BaseTimeOverridePolicy policy) { if (main_thread_only().use_virtual_time) @@ -1941,6 +1977,10 @@ void MainThreadSchedulerImpl::SetVirtualTimePolicy(VirtualTimePolicy policy) { ApplyVirtualTimePolicy(); } +void MainThreadSchedulerImpl::SetInitialVirtualTime(base::Time time) { + main_thread_only().initial_virtual_time = time; +} + void MainThreadSchedulerImpl::SetInitialVirtualTimeOffset( base::TimeDelta offset) { main_thread_only().initial_virtual_time_offset = offset; @@ -2008,9 +2048,9 @@ void MainThreadSchedulerImpl::SetMaxVirtualTimeTaskStarvationCount( ApplyVirtualTimePolicy(); } -void MainThreadSchedulerImpl::SetStoppingWhenBackgroundedEnabled(bool enabled) { +void MainThreadSchedulerImpl::SetFreezingWhenBackgroundedEnabled(bool enabled) { // Note that this will only take effect for the next backgrounded signal. - main_thread_only().stopping_when_backgrounded_enabled = enabled; + main_thread_only().freezing_when_backgrounded_enabled = enabled; } std::unique_ptr<base::trace_event::ConvertableToTraceFormat> @@ -2092,15 +2132,13 @@ MainThreadSchedulerImpl::AsValueLocked(base::TimeTicks optional_now) const { main_thread_only().renderer_backgrounded); state->SetBoolean("keep_active_fetch_or_worker", main_thread_only().keep_active_fetch_or_worker); - state->SetBoolean("stopped_when_backgrounded", - main_thread_only().stopped_when_backgrounded); + state->SetBoolean("frozen_when_backgrounded", + main_thread_only().frozen_when_backgrounded); state->SetDouble("now", (optional_now - base::TimeTicks()).InMillisecondsF()); state->SetDouble( "fling_compositor_escalation_deadline", (any_thread().fling_compositor_escalation_deadline - base::TimeTicks()) .InMillisecondsF()); - state->SetInteger("navigation_task_expected_count", - main_thread_only().navigation_task_expected_count); state->SetDouble("last_idle_period_end_time", (any_thread().last_idle_period_end_time - base::TimeTicks()) .InMillisecondsF()); @@ -2179,13 +2217,17 @@ bool MainThreadSchedulerImpl::TaskQueuePolicy::IsQueueEnabled( return false; // TODO(panicker): Remove this, as it is redundant as we stop per-frame // task_queues in WebFrameScheduler - if (is_stopped && task_queue->CanBeStopped()) + if (is_frozen && task_queue->CanBeFrozen()) return false; return true; } TaskQueue::QueuePriority MainThreadSchedulerImpl::TaskQueuePolicy::GetPriority( MainThreadTaskQueue* task_queue) const { + base::Optional<TaskQueue::QueuePriority> fixed_priority = + task_queue->FixedPriority(); + if (fixed_priority) + return fixed_priority.value(); return task_queue->UsedForImportantTasks() ? TaskQueue::kHighestPriority : priority; } @@ -2206,7 +2248,7 @@ void MainThreadSchedulerImpl::TaskQueuePolicy::AsValueInto( state->SetBoolean("is_paused", is_paused); state->SetBoolean("is_throttled", is_throttled); state->SetBoolean("is_blocked", is_blocked); - state->SetBoolean("is_stopped", is_stopped); + state->SetBoolean("is_frozen", is_frozen); state->SetBoolean("use_virtual_time", use_virtual_time); state->SetString("priority", TaskQueue::PriorityToString(priority)); } @@ -2279,25 +2321,6 @@ void MainThreadSchedulerImpl::DispatchRequestBeginMainFrameNotExpected( } } -void MainThreadSchedulerImpl::AddPendingNavigation(NavigatingFrameType type) { - helper_.CheckOnValidThread(); - if (type == NavigatingFrameType::kMainFrame) { - main_thread_only().navigation_task_expected_count++; - UpdatePolicy(); - } -} - -void MainThreadSchedulerImpl::RemovePendingNavigation( - NavigatingFrameType type) { - helper_.CheckOnValidThread(); - DCHECK_GT(main_thread_only().navigation_task_expected_count, 0); - if (type == NavigatingFrameType::kMainFrame && - main_thread_only().navigation_task_expected_count > 0) { - main_thread_only().navigation_task_expected_count--; - UpdatePolicy(); - } -} - std::unique_ptr<base::SingleSampleMetric> MainThreadSchedulerImpl::CreateMaxQueueingTimeMetric() { return base::SingleSampleMetricsFactory::Get()->CreateCustomCountsMetric( @@ -2399,52 +2422,67 @@ void MainThreadSchedulerImpl::SetRAILModeObserver(RAILModeObserver* observer) { main_thread_only().rail_mode_observer = observer; } -bool MainThreadSchedulerImpl::MainThreadSeemsUnresponsive( - base::TimeDelta main_thread_responsiveness_threshold) { - base::TimeTicks now = tick_clock()->NowTicks(); - base::TimeDelta estimated_queueing_time; - - bool can_read = false; +void MainThreadSchedulerImpl::SetRendererProcessType(RendererProcessType type) { + main_thread_only().process_type = type; +} - base::subtle::Atomic32 version; - seqlock_queueing_time_estimator_.seqlock.TryRead(&can_read, &version); +WebScopedVirtualTimePauser +MainThreadSchedulerImpl::CreateWebScopedVirtualTimePauser( + const char* name, + WebScopedVirtualTimePauser::VirtualTaskDuration duration) { + return WebScopedVirtualTimePauser(this, duration, + WebString(WTF::String(name))); +} - // If we fail to determine if the main thread is busy, assume whether or not - // it's busy hasn't change since the last time we asked. - if (!can_read) - return GetCompositorThreadOnly().main_thread_seems_unresponsive; +void MainThreadSchedulerImpl::RunIdleTask(WebThread::IdleTask task, + base::TimeTicks deadline) { + std::move(task).Run((deadline - base::TimeTicks()).InSecondsF()); +} - QueueingTimeEstimator::State queueing_time_estimator_state = - seqlock_queueing_time_estimator_.data.GetState(); +void MainThreadSchedulerImpl::PostIdleTask(const base::Location& location, + WebThread::IdleTask task) { + IdleTaskRunner()->PostIdleTask( + location, + base::BindOnce(&MainThreadSchedulerImpl::RunIdleTask, std::move(task))); +} - // If we fail to determine if the main thread is busy, assume whether or not - // it's busy hasn't change since the last time we asked. - if (seqlock_queueing_time_estimator_.seqlock.ReadRetry(version)) - return GetCompositorThreadOnly().main_thread_seems_unresponsive; +void MainThreadSchedulerImpl::PostNonNestableIdleTask( + const base::Location& location, + WebThread::IdleTask task) { + IdleTaskRunner()->PostNonNestableIdleTask( + location, + base::BindOnce(&MainThreadSchedulerImpl::RunIdleTask, std::move(task))); +} - QueueingTimeEstimator queueing_time_estimator(queueing_time_estimator_state); +scoped_refptr<base::SingleThreadTaskRunner> +MainThreadSchedulerImpl::V8TaskRunner() { + return v8_task_runner_; +} - estimated_queueing_time = - queueing_time_estimator.EstimateQueueingTimeIncludingCurrentTask(now); +scoped_refptr<base::SingleThreadTaskRunner> +MainThreadSchedulerImpl::CompositorTaskRunner() { + return compositor_task_runner_; +} - bool main_thread_seems_unresponsive = - estimated_queueing_time > main_thread_responsiveness_threshold; - GetCompositorThreadOnly().main_thread_seems_unresponsive = - main_thread_seems_unresponsive; +std::unique_ptr<PageScheduler> MainThreadSchedulerImpl::CreatePageScheduler( + PageScheduler::Delegate* delegate) { + return std::make_unique<PageSchedulerImpl>( + delegate, this, + !RuntimeEnabledFeatures::TimerThrottlingForBackgroundTabsEnabled()); +} - return main_thread_seems_unresponsive; +std::unique_ptr<ThreadScheduler::RendererPauseHandle> +MainThreadSchedulerImpl::PauseScheduler() { + return PauseRenderer(); } -void MainThreadSchedulerImpl::SetRendererProcessType(RendererProcessType type) { - main_thread_only().process_type = type; +base::TimeTicks MainThreadSchedulerImpl::MonotonicallyIncreasingVirtualTime() { + return GetActiveTimeDomain()->Now(); } -WebScopedVirtualTimePauser -MainThreadSchedulerImpl::CreateWebScopedVirtualTimePauser( - const char* name, - WebScopedVirtualTimePauser::VirtualTaskDuration duration) { - return WebScopedVirtualTimePauser(this, duration, - WebString(WTF::String(name))); +WebMainThreadScheduler* +MainThreadSchedulerImpl::GetWebMainThreadSchedulerForTest() { + return this; } void MainThreadSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { @@ -2455,6 +2493,10 @@ void MainThreadSchedulerImpl::UnregisterTimeDomain(TimeDomain* time_domain) { helper_.UnregisterTimeDomain(time_domain); } +const base::TickClock* MainThreadSchedulerImpl::GetTickClock() { + return tick_clock(); +} + const base::TickClock* MainThreadSchedulerImpl::tick_clock() const { return helper_.GetClock(); } @@ -2482,14 +2524,17 @@ void MainThreadSchedulerImpl::OnTaskStarted(MainThreadTaskQueue* queue, const TaskQueue::Task& task, base::TimeTicks start) { main_thread_only().current_task_start_time = start; - seqlock_queueing_time_estimator_.seqlock.WriteBegin(); - seqlock_queueing_time_estimator_.data.OnTopLevelTaskStarted(start, queue); - seqlock_queueing_time_estimator_.seqlock.WriteEnd(); + queueing_time_estimator_.OnTopLevelTaskStarted(start, queue); main_thread_only().task_description_for_tracing = TaskDescriptionForTracing{ static_cast<TaskType>(task.task_type()), queue ? base::Optional<MainThreadTaskQueue::QueueType>(queue->queue_type()) : base::nullopt}; + + main_thread_only().task_priority_for_tracing = + queue + ? base::Optional<TaskQueue::QueuePriority>(queue->GetQueuePriority()) + : base::nullopt; } void MainThreadSchedulerImpl::OnTaskCompleted( @@ -2499,9 +2544,7 @@ void MainThreadSchedulerImpl::OnTaskCompleted( base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) { DCHECK_LE(start, end); - seqlock_queueing_time_estimator_.seqlock.WriteBegin(); - seqlock_queueing_time_estimator_.data.OnTopLevelTaskCompleted(end); - seqlock_queueing_time_estimator_.seqlock.WriteEnd(); + queueing_time_estimator_.OnTopLevelTaskCompleted(end); if (queue) task_queue_throttler()->OnTaskRunTimeReported(queue, start, end); @@ -2511,6 +2554,9 @@ void MainThreadSchedulerImpl::OnTaskCompleted( thread_time); main_thread_only().task_description_for_tracing = base::nullopt; + // Unset the state of |task_priority_for_tracing|. + main_thread_only().task_priority_for_tracing = base::nullopt; + RecordTaskUkm(queue, task, start, end, thread_time); } @@ -2520,7 +2566,7 @@ void MainThreadSchedulerImpl::RecordTaskUkm( base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) { - if (!ShouldRecordTaskUkm()) + if (!ShouldRecordTaskUkm(thread_time.has_value())) return; if (queue && queue->GetFrameScheduler()) { @@ -2578,9 +2624,7 @@ void MainThreadSchedulerImpl::RecordTaskUkmImpl( } void MainThreadSchedulerImpl::OnBeginNestedRunLoop() { - seqlock_queueing_time_estimator_.seqlock.WriteBegin(); - seqlock_queueing_time_estimator_.data.OnBeginNestedRunLoop(); - seqlock_queueing_time_estimator_.seqlock.WriteEnd(); + queueing_time_estimator_.OnBeginNestedRunLoop(); main_thread_only().nested_runloop = true; ApplyVirtualTimePolicy(); @@ -2612,8 +2656,6 @@ bool MainThreadSchedulerImpl::ContainsLocalMainFrame() { void MainThreadSchedulerImpl::OnQueueingTimeForWindowEstimated( base::TimeDelta queueing_time, bool is_disjoint_window) { - main_thread_only().most_recent_expected_queueing_time = queueing_time; - if (main_thread_only().has_navigated) { if (main_thread_only().max_queueing_time < queueing_time) { if (!main_thread_only().max_queueing_time_metric) { @@ -2662,32 +2704,24 @@ MainThreadSchedulerImpl::GetVirtualTimeDomain() { return virtual_time_domain_.get(); } -bool MainThreadSchedulerImpl::ShouldDisableThrottlingBecauseOfAudio( - base::TimeTicks now) { - if (!main_thread_only().last_audio_state_change) - return false; - - if (main_thread_only().is_audio_playing) - return true; - - return main_thread_only().last_audio_state_change.value() + - kThrottlingDelayAfterAudioIsPlayed > - now; -} - void MainThreadSchedulerImpl::AddQueueToWakeUpBudgetPool( MainThreadTaskQueue* queue) { - if (!main_thread_only().wake_up_budget_pool) { - main_thread_only().wake_up_budget_pool = - task_queue_throttler()->CreateWakeUpBudgetPool("renderer_wake_up_pool"); - main_thread_only().wake_up_budget_pool->SetWakeUpRate(1); - main_thread_only().wake_up_budget_pool->SetWakeUpDuration( - GetWakeUpDuration()); - } + InitWakeUpBudgetPoolIfNeeded(); main_thread_only().wake_up_budget_pool->AddQueue(tick_clock()->NowTicks(), queue); } +void MainThreadSchedulerImpl::InitWakeUpBudgetPoolIfNeeded() { + if (main_thread_only().wake_up_budget_pool) + return; + + main_thread_only().wake_up_budget_pool = + task_queue_throttler()->CreateWakeUpBudgetPool("renderer_wake_up_pool"); + main_thread_only().wake_up_budget_pool->SetWakeUpRate(1); + main_thread_only().wake_up_budget_pool->SetWakeUpDuration( + GetWakeUpDuration()); +} + TimeDomain* MainThreadSchedulerImpl::GetActiveTimeDomain() { if (main_thread_only().use_virtual_time) { return GetVirtualTimeDomain(); @@ -2710,10 +2744,33 @@ base::WeakPtr<MainThreadSchedulerImpl> MainThreadSchedulerImpl::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } -bool MainThreadSchedulerImpl::ShouldRecordTaskUkm() { - // This function returns true with probability of kSamplingRateForTaskUkm. +bool MainThreadSchedulerImpl::IsAudioPlaying() const { + return main_thread_only().is_audio_playing; +} + +bool MainThreadSchedulerImpl::ShouldIgnoreTaskForUkm(bool has_thread_time, + double* sampling_rate) { + const double thread_time_sampling_rate = + helper_.GetSamplingRateForRecordingCPUTime(); + if (thread_time_sampling_rate && *sampling_rate < thread_time_sampling_rate) { + if (!has_thread_time) + return true; + *sampling_rate /= thread_time_sampling_rate; + } + return false; +} + +bool MainThreadSchedulerImpl::ShouldRecordTaskUkm(bool has_thread_time) { + double sampling_rate = kSamplingRateForTaskUkm; + + // If thread_time is sampled as well, try to align UKM sampling with it so + // that we only record UKMs for tasks that also record thread_time. + if (ShouldIgnoreTaskForUkm(has_thread_time, &sampling_rate)) { + return false; + } + return main_thread_only().uniform_distribution( - main_thread_only().random_generator) < kSamplingRateForTaskUkm; + main_thread_only().random_generator) < sampling_rate; } // static 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 34b1aa1e53c..7b2b64a33c4 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 @@ -5,7 +5,11 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_SCHEDULER_IMPL_H_ +#include <map> +#include <memory> #include <random> +#include <set> +#include <string> #include "base/atomicops.h" #include "base/gtest_prod_util.h" @@ -17,25 +21,28 @@ #include "base/synchronization/lock.h" #include "base/trace_event/trace_log.h" #include "build/build_config.h" -#include "device/base/synchronization/shared_memory_seqlock_buffer.h" #include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h" #include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_time_observer.h" #include "third_party/blink/renderer/platform/scheduler/child/idle_canceled_delayed_task_sweeper.h" #include "third_party/blink/renderer/platform/scheduler/child/idle_helper.h" #include "third_party/blink/renderer/platform/scheduler/child/pollable_thread_safe_flag.h" -#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/deadline_task_runner.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" +#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.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/deadline_task_runner.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" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/use_case.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace base { @@ -49,6 +56,7 @@ namespace scheduler { namespace main_thread_scheduler_impl_unittest { class MainThreadSchedulerImplForTest; class MainThreadSchedulerImplTest; +FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, ShouldIgnoreTaskForUkm); FORWARD_DECLARE_TEST(MainThreadSchedulerImplTest, Tracing); } // namespace main_thread_scheduler_impl_unittest class PageSchedulerImpl; @@ -57,6 +65,7 @@ class WebRenderWidgetSchedulingState; class PLATFORM_EXPORT MainThreadSchedulerImpl : public WebMainThreadScheduler, + public ThreadSchedulerImpl, public IdleHelper::Delegate, public MainThreadSchedulerHelper::Observer, public RenderWidgetSignals::Observer, @@ -90,12 +99,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // If |initial_virtual_time| is specified then the scheduler will be created // with virtual time enabled and paused with base::Time will be overridden to // start at |initial_virtual_time|. - MainThreadSchedulerImpl(std::unique_ptr<TaskQueueManager> task_queue_manager, - base::Optional<base::Time> initial_virtual_time); + MainThreadSchedulerImpl( + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, + base::Optional<base::Time> initial_virtual_time); ~MainThreadSchedulerImpl() override; - // WebMainThreadSchedulerScheduler implementation: + // WebMainThreadScheduler implementation: std::unique_ptr<WebThread> CreateMainThread() override; scoped_refptr<SingleThreadIdleTaskRunner> IdleTaskRunner() override; scoped_refptr<base::SingleThreadTaskRunner> IPCTaskRunner() override; @@ -110,20 +121,17 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl InputEventState event_state) override; void DidHandleInputEventOnMainThread(const WebInputEvent& web_input_event, WebInputEventResult result) override; - base::TimeDelta MostRecentExpectedQueueingTime() override; void DidAnimateForInputOnCompositorThread() override; void SetRendererHidden(bool hidden) override; void SetRendererBackgrounded(bool backgrounded) override; void SetSchedulerKeepActive(bool keep_active) override; bool SchedulerKeepActive(); #if defined(OS_ANDROID) - void PauseTimersForAndroidWebView(); - void ResumeTimersForAndroidWebView(); + void PauseTimersForAndroidWebView() override; + void ResumeTimersForAndroidWebView() override; #endif - std::unique_ptr<RendererPauseHandle> PauseRenderer() override + std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseRenderer() override WARN_UNUSED_RESULT; - void AddPendingNavigation(NavigatingFrameType type) override; - void RemovePendingNavigation(NavigatingFrameType type) override; bool IsHighPriorityWorkAnticipated() override; bool ShouldYieldForHighPriorityWork() override; bool CanExceedIdleDeadlineIfRequired() const override; @@ -131,17 +139,43 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl void RemoveTaskObserver( base::MessageLoop::TaskObserver* task_observer) override; void Shutdown() override; - void SetStoppingWhenBackgroundedEnabled(bool enabled) override; + void SetFreezingWhenBackgroundedEnabled(bool enabled) override; void SetTopLevelBlameContext( base::trace_event::BlameContext* blame_context) override; void SetRAILModeObserver(RAILModeObserver* observer) override; - bool MainThreadSeemsUnresponsive( - base::TimeDelta main_thread_responsiveness_threshold) override; void SetRendererProcessType(RendererProcessType type) override; WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) override; + // ThreadScheduler implementation: + void PostIdleTask(const base::Location&, WebThread::IdleTask) override; + void PostNonNestableIdleTask(const base::Location&, + WebThread::IdleTask) override; + scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override; + scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; + std::unique_ptr<PageScheduler> CreatePageScheduler( + PageScheduler::Delegate*) override; + std::unique_ptr<ThreadScheduler::RendererPauseHandle> PauseScheduler() + override; + base::TimeTicks MonotonicallyIncreasingVirtualTime() override; + WebMainThreadScheduler* GetWebMainThreadSchedulerForTest() override; + NonMainThreadScheduler* AsNonMainThreadScheduler() override { + return nullptr; + } + + // WebMainThreadScheduler implementation: + scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; + scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override; + + // The following functions are defined in both WebThreadScheduler and + // ThreadScheduler, and have the same function signatures -- see above. + // This class implements those functions for both base classes. + // + // void Shutdown() override; + // + // TODO(yutak): Reduce the overlaps and simplify. + // AutoAdvancingVirtualTimeDomain::Observer implementation: void OnVirtualTimeAdvanced() override; @@ -161,10 +195,16 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl const char* split_description, base::TimeDelta queueing_time) override; - scoped_refptr<MainThreadTaskQueue> DefaultTaskQueue(); - scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue(); - scoped_refptr<MainThreadTaskQueue> InputTaskQueue(); - scoped_refptr<MainThreadTaskQueue> V8TaskQueue(); + // ThreadSchedulerImpl implementation: + scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner() override; + void RegisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) override; + void UnregisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) override; + base::sequence_manager::TimeDomain* GetActiveTimeDomain() override; + const base::TickClock* GetTickClock() override; + + scoped_refptr<base::SingleThreadTaskRunner> VirtualTimeControlTaskRunner(); // Returns a new task queue created with given params. scoped_refptr<MainThreadTaskQueue> NewTaskQueue( @@ -174,21 +214,13 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // to resource dispatch, foreground HTML parsing, etc... // Note: Tasks posted to kFrameLoadingControl queues must execute quickly. scoped_refptr<MainThreadTaskQueue> NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType queue_type); + MainThreadTaskQueue::QueueType queue_type, + FrameSchedulerImpl* frame_scheduler); // Returns a new timer task queue. This queue is intended for DOM Timers. scoped_refptr<MainThreadTaskQueue> NewTimerTaskQueue( - MainThreadTaskQueue::QueueType queue_type); - - // Returns a task queue where tasks run at the highest possible priority. - scoped_refptr<MainThreadTaskQueue> ControlTaskQueue(); - - // A control task queue which also respects virtual time. Only available if - // virtual time has been enabled. - scoped_refptr<MainThreadTaskQueue> VirtualTimeControlTaskQueue(); - - void RegisterTimeDomain(TimeDomain* time_domain); - void UnregisterTimeDomain(TimeDomain* time_domain); + MainThreadTaskQueue::QueueType queue_type, + FrameSchedulerImpl* frame_scheduler); using VirtualTimePolicy = PageScheduler::VirtualTimePolicy; using VirtualTimeObserver = PageScheduler::VirtualTimeObserver; @@ -196,6 +228,10 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl using BaseTimeOverridePolicy = AutoAdvancingVirtualTimeDomain::BaseTimeOverridePolicy; + // Tells the scheduler that all TaskQueues should use virtual time. Depending + // on the initial time, picks the policy to be either overriding or not. + base::TimeTicks EnableVirtualTime(); + // Tells the scheduler that all TaskQueues should use virtual time. Returns // the TimeTicks that virtual time offsets will be relative to. base::TimeTicks EnableVirtualTime(BaseTimeOverridePolicy policy); @@ -207,6 +243,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // Returns true if virtual time is not paused. bool VirtualTimeAllowedToAdvance() const; void SetVirtualTimePolicy(VirtualTimePolicy virtual_time_policy); + void SetInitialVirtualTime(base::Time time); void SetInitialVirtualTimeOffset(base::TimeDelta offset); void SetMaxVirtualTimeTaskStarvationCount(int max_task_starvation_count); void AddVirtualTimeObserver(VirtualTimeObserver*); @@ -218,8 +255,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl void AddPageScheduler(PageSchedulerImpl*); void RemovePageScheduler(PageSchedulerImpl*); - void AddTaskTimeObserver(TaskTimeObserver*); - void RemoveTaskTimeObserver(TaskTimeObserver*); + void AddTaskTimeObserver(base::sequence_manager::TaskTimeObserver*); + void RemoveTaskTimeObserver(base::sequence_manager::TaskTimeObserver*); // Snapshots this MainThreadSchedulerImpl for tracing. void CreateTraceEventObjectSnapshot() const; @@ -244,22 +281,20 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl TaskCostEstimator* GetTimerTaskCostEstimatorForTesting(); IdleTimeEstimator* GetIdleTimeEstimatorForTesting(); base::TimeTicks CurrentIdleTaskDeadlineForTesting() const; - void RunIdleTasksForTesting(const base::Closure& callback); - void EndIdlePeriodForTesting(const base::Closure& callback, + void RunIdleTasksForTesting(base::OnceClosure callback); + void EndIdlePeriodForTesting(base::OnceClosure callback, base::TimeTicks time_remaining); bool PolicyNeedsUpdateForTesting(); WakeUpBudgetPool* GetWakeUpBudgetPoolForTesting(); const base::TickClock* tick_clock() const; - RealTimeDomain* real_time_domain() const { + base::sequence_manager::RealTimeDomain* real_time_domain() const { return helper_.real_time_domain(); } AutoAdvancingVirtualTimeDomain* GetVirtualTimeDomain(); - TimeDomain* GetActiveTimeDomain(); - TaskQueueThrottler* task_queue_throttler() const { return task_queue_throttler_.get(); } @@ -269,15 +304,17 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl void OnShutdownTaskQueue(const scoped_refptr<MainThreadTaskQueue>& queue); void OnTaskStarted(MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start); void OnTaskCompleted(MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time); + bool IsAudioPlaying() const; + // base::trace_event::TraceLog::EnabledStateObserver implementation: void OnTraceLogEnabled() override; void OnTraceLogDisabled() override; @@ -285,11 +322,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl base::WeakPtr<MainThreadSchedulerImpl> GetWeakPtr(); protected: - // WebMainThreadScheduler implementation. - // Use *TaskQueue internally. - scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; - scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; - scoped_refptr<base::SingleThreadTaskRunner> InputTaskRunner() override; + scoped_refptr<MainThreadTaskQueue> ControlTaskQueue(); + scoped_refptr<MainThreadTaskQueue> DefaultTaskQueue(); + scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue(); + scoped_refptr<MainThreadTaskQueue> InputTaskQueue(); + scoped_refptr<MainThreadTaskQueue> V8TaskQueue(); + // A control task queue which also respects virtual time. Only available if + // virtual time has been enabled. + scoped_refptr<MainThreadTaskQueue> VirtualTimeControlTaskQueue(); // `current_use_case` will be overwritten by the next call to UpdatePolicy. // Thus, this function should be only used for testing purposes. @@ -299,14 +339,17 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl private: friend class WebRenderWidgetSchedulingState; - friend class RendererMetricsHelper; + friend class MainThreadMetricsHelper; - friend class RendererMetricsHelperTest; + friend class MainThreadMetricsHelperTest; friend class main_thread_scheduler_impl_unittest:: MainThreadSchedulerImplForTest; friend class main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest; FRIEND_TEST_ALL_PREFIXES( main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest, + ShouldIgnoreTaskForUkm); + FRIEND_TEST_ALL_PREFIXES( + main_thread_scheduler_impl_unittest::MainThreadSchedulerImplTest, Tracing); enum class ExpensiveTaskPolicy { kRun, kBlock, kThrottle }; @@ -319,7 +362,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl static const char* TimeDomainTypeToString(TimeDomainType domain_type); - void SetStoppedInBackground(bool) const; + void SetFrozenInBackground(bool) const; bool ContainsLocalMainFrame(); @@ -331,28 +374,29 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl is_paused(false), is_throttled(false), is_blocked(false), - is_stopped(false), + is_frozen(false), use_virtual_time(false), - priority(TaskQueue::kNormalPriority) {} + priority(base::sequence_manager::TaskQueue::kNormalPriority) {} bool is_enabled; bool is_paused; bool is_throttled; bool is_blocked; - bool is_stopped; + bool is_frozen; bool use_virtual_time; - TaskQueue::QueuePriority priority; + base::sequence_manager::TaskQueue::QueuePriority priority; bool IsQueueEnabled(MainThreadTaskQueue* task_queue) const; - TaskQueue::QueuePriority GetPriority(MainThreadTaskQueue* task_queue) const; + base::sequence_manager::TaskQueue::QueuePriority GetPriority( + MainThreadTaskQueue* task_queue) const; TimeDomainType GetTimeDomainType(MainThreadTaskQueue* task_queue) const; bool operator==(const TaskQueuePolicy& other) const { return is_enabled == other.is_enabled && is_paused == other.is_paused && is_throttled == other.is_throttled && - is_blocked == other.is_blocked && is_stopped == other.is_stopped && + is_blocked == other.is_blocked && is_frozen == other.is_frozen && use_virtual_time == other.use_virtual_time && priority == other.priority; } @@ -434,7 +478,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl class PollableNeedsUpdateFlag { public: - PollableNeedsUpdateFlag(base::Lock* write_lock); + explicit PollableNeedsUpdateFlag(base::Lock* write_lock); ~PollableNeedsUpdateFlag(); // Set the flag. May only be called if |write_lock| is held. @@ -452,7 +496,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl class TaskDurationMetricTracker; - class RendererPauseHandleImpl : public RendererPauseHandle { + class RendererPauseHandleImpl : public ThreadScheduler::RendererPauseHandle { public: explicit RendererPauseHandleImpl(MainThreadSchedulerImpl* scheduler); ~RendererPauseHandleImpl() override; @@ -494,7 +538,7 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // The amount of time to wait before suspending shared timers, and loading // etc. after the renderer has been backgrounded. This is used only if // background suspension is enabled. - static const int kDelayForBackgroundTabStoppingMillis = 5 * 60 * 1000; + static const int kDelayForBackgroundTabFreezingMillis = 5 * 60 * 1000; // The time we should stay in a priority-escalated mode after a call to // DidAnimateForInputOnCompositorThread(). @@ -554,15 +598,14 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl void ApplyTaskQueuePolicy( MainThreadTaskQueue* task_queue, - TaskQueue::QueueEnabledVoter* task_queue_enabled_voter, + base::sequence_manager::TaskQueue::QueueEnabledVoter* + task_queue_enabled_voter, const TaskQueuePolicy& old_task_queue_policy, const TaskQueuePolicy& new_task_queue_policy) const; static const char* ExpensiveTaskPolicyToString( ExpensiveTaskPolicy expensive_task_policy); - bool ShouldDisableThrottlingBecauseOfAudio(base::TimeTicks now); - void AddQueueToWakeUpBudgetPool(MainThreadTaskQueue* queue); void PauseRendererImpl(); @@ -582,25 +625,36 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl // TaskQueueThrottler. void VirtualTimeResumed(); - bool ShouldRecordTaskUkm(); + // Returns true if the current task should not be reported in UKM because no + // thread time was recorded for it. Also updates |sampling_rate| to account + // for the ignored tasks by sampling the remaining tasks with higher + // probability. + bool ShouldIgnoreTaskForUkm(bool has_thread_time, double* sampling_rate); + + // Returns true with probability of kSamplingRateForTaskUkm. + bool ShouldRecordTaskUkm(bool has_thread_time); + + static void RunIdleTask(WebThread::IdleTask, base::TimeTicks deadline); // Probabilistically record all task metadata for the current task. // If task belongs to a per-frame queue, this task is attributed to // a particular Page, otherwise it's attributed to all Pages in the process. void RecordTaskUkm(MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time); void RecordTaskUkmImpl(MainThreadTaskQueue* queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time, PageSchedulerImpl* page_scheduler, size_t page_schedulers_to_attribute); + void InitWakeUpBudgetPoolIfNeeded(); + // Indicates that scheduler has been shutdown. // It should be accessed only on the main thread, but couldn't be a member // of MainThreadOnly struct because last might be destructed before we @@ -621,19 +675,23 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl const scoped_refptr<MainThreadTaskQueue> compositor_task_queue_; const scoped_refptr<MainThreadTaskQueue> input_task_queue_; scoped_refptr<MainThreadTaskQueue> virtual_time_control_task_queue_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> compositor_task_queue_enabled_voter_; - std::unique_ptr<TaskQueue::QueueEnabledVoter> input_task_queue_enabled_voter_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + input_task_queue_enabled_voter_; - using TaskQueueVoterMap = - std::map<scoped_refptr<MainThreadTaskQueue>, - std::unique_ptr<TaskQueue::QueueEnabledVoter>>; + using TaskQueueVoterMap = std::map< + scoped_refptr<MainThreadTaskQueue>, + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter>>; TaskQueueVoterMap task_runners_; scoped_refptr<MainThreadTaskQueue> v8_task_queue_; scoped_refptr<MainThreadTaskQueue> ipc_task_queue_; + scoped_refptr<TaskQueueWithTaskType> v8_task_runner_; + scoped_refptr<TaskQueueWithTaskType> compositor_task_runner_; + // Note |virtual_time_domain_| is lazily created. std::unique_ptr<AutoAdvancingVirtualTimeDomain> virtual_time_domain_; @@ -641,12 +699,9 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl DeadlineTaskRunner delayed_update_policy_runner_; CancelableClosureHolder end_renderer_hidden_idle_period_closure_; - using SeqLockQueueingTimeEstimator = - device::SharedMemorySeqLockBuffer<QueueingTimeEstimator>; - - SeqLockQueueingTimeEstimator seqlock_queueing_time_estimator_; + QueueingTimeEstimator queueing_time_estimator_; - base::TimeDelta delay_for_background_tab_stopping_; + base::TimeDelta delay_for_background_tab_freezing_; // We have decided to improve thread safety at the cost of some boilerplate // (the accessors) for the following data members. @@ -667,15 +722,11 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl base::TimeTicks current_policy_expiration_time; base::TimeTicks estimated_next_frame_begin; base::TimeTicks current_task_start_time; - base::TimeDelta most_recent_expected_queueing_time; base::TimeDelta compositor_frame_interval; TraceableCounter<base::TimeDelta, kTracingCategoryNameDebug> longest_jank_free_task_duration; - base::Optional<base::TimeTicks> last_audio_state_change; TraceableCounter<int, kTracingCategoryNameInfo> renderer_pause_count; // Renderer is paused if non-zero. - TraceableCounter<int, kTracingCategoryNameDebug> - navigation_task_expected_count; TraceableState<ExpensiveTaskPolicy, kTracingCategoryNameInfo> expensive_task_policy; TraceableState<v8::RAILMode, kTracingCategoryNameInfo> @@ -685,8 +736,8 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl TraceableState<bool, kTracingCategoryNameDefault> keep_active_fetch_or_worker; TraceableState<bool, kTracingCategoryNameInfo> - stopping_when_backgrounded_enabled; - TraceableState<bool, kTracingCategoryNameInfo> stopped_when_backgrounded; + freezing_when_backgrounded_enabled; + TraceableState<bool, kTracingCategoryNameInfo> frozen_when_backgrounded; TraceableCounter<base::TimeDelta, kTracingCategoryNameInfo> loading_task_estimated_cost; TraceableCounter<base::TimeDelta, kTracingCategoryNameInfo> @@ -717,12 +768,16 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl std::set<PageSchedulerImpl*> page_schedulers; // Not owned. RAILModeObserver* rail_mode_observer; // Not owned. WakeUpBudgetPool* wake_up_budget_pool; // Not owned. - RendererMetricsHelper metrics_helper; + MainThreadMetricsHelper metrics_helper; TraceableState<RendererProcessType, kTracingCategoryNameTopLevel> process_type; TraceableState<base::Optional<TaskDescriptionForTracing>, kTracingCategoryNameInfo> task_description_for_tracing; // Don't use except for tracing. + TraceableState< + base::Optional<base::sequence_manager::TaskQueue::QueuePriority>, + kTracingCategoryNameInfo> + task_priority_for_tracing; // Only used for tracing. base::ObserverList<VirtualTimeObserver> virtual_time_observers; base::Time initial_virtual_time; base::TimeTicks initial_virtual_time_ticks; @@ -775,7 +830,6 @@ class PLATFORM_EXPORT MainThreadSchedulerImpl ~CompositorThreadOnly(); WebInputEvent::Type last_input_type; - bool main_thread_seems_unresponsive; std::unique_ptr<base::ThreadChecker> compositor_thread_checker; void CheckOnValidThread() { 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 a9bd594baa0..056a1ec5a75 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 @@ -22,13 +22,15 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/renderer/platform/scheduler/base/real_time_domain.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/child/features.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.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/frame_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" +using base::sequence_manager::TaskQueue; + namespace blink { namespace scheduler { // To avoid symbol collisions in jumbo builds. @@ -214,9 +216,15 @@ class MainThreadSchedulerImplForTest : public MainThreadSchedulerImpl { using MainThreadSchedulerImpl::OnIdlePeriodEnded; using MainThreadSchedulerImpl::OnIdlePeriodStarted; using MainThreadSchedulerImpl::OnPendingTasksChanged; + using MainThreadSchedulerImpl::CompositorTaskQueue; + using MainThreadSchedulerImpl::ControlTaskQueue; + using MainThreadSchedulerImpl::DefaultTaskQueue; + using MainThreadSchedulerImpl::InputTaskQueue; + using MainThreadSchedulerImpl::V8TaskQueue; + using MainThreadSchedulerImpl::VirtualTimeControlTaskQueue; MainThreadSchedulerImplForTest( - std::unique_ptr<TaskQueueManager> manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, base::Optional<base::Time> initial_virtual_time) : MainThreadSchedulerImpl(std::move(manager), initial_virtual_time), update_policy_count_(0) {} @@ -291,7 +299,7 @@ class MainThreadSchedulerImplTest : public testing::Test { base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); } Initialize(std::make_unique<MainThreadSchedulerImplForTest>( - TaskQueueManagerForTest::Create( + base::sequence_manager::TaskQueueManagerForTest::Create( message_loop_.get(), message_loop_ ? message_loop_->task_runner() : mock_task_runner_, &clock_), @@ -310,15 +318,15 @@ class MainThreadSchedulerImplTest : public testing::Test { compositor_task_runner_ = scheduler_->CompositorTaskQueue(); input_task_runner_ = scheduler_->InputTaskQueue(); loading_task_runner_ = scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoading); + MainThreadTaskQueue::QueueType::kFrameLoading, nullptr); loading_control_task_runner_ = scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoadingControl); + MainThreadTaskQueue::QueueType::kFrameLoadingControl, nullptr); idle_task_runner_ = scheduler_->IdleTaskRunner(); timer_task_runner_ = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); v8_task_runner_ = scheduler_->V8TaskQueue(); fake_queue_ = scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoading); + MainThreadTaskQueue::QueueType::kFrameLoading, nullptr); } void TearDown() override { @@ -583,10 +591,6 @@ class MainThreadSchedulerImplTest : public testing::Test { return scheduler_->main_thread_only().estimated_next_frame_begin; } - int NavigationTaskExpectedCount() { - return scheduler_->main_thread_only().navigation_task_expected_count; - } - void AdvanceTimeWithTask(double duration) { base::TimeTicks start = clock_.NowTicks(); scheduler_->OnTaskStarted(fake_queue_.get(), fake_task_, start); @@ -596,14 +600,6 @@ class MainThreadSchedulerImplTest : public testing::Test { base::nullopt); } - void GetQueueingTimeEstimatorLock() { - scheduler_->seqlock_queueing_time_estimator_.seqlock.WriteBegin(); - } - - void DropQueueingTimeEstimatorLock() { - scheduler_->seqlock_queueing_time_estimator_.seqlock.WriteEnd(); - } - void RunSlowCompositorTask() { // Run a long compositor task so that compositor tasks appear to be running // slow and thus compositor tasks will not be prioritized. @@ -700,9 +696,9 @@ class MainThreadSchedulerImplTest : public testing::Test { MainThreadSchedulerImpl::kEndIdleWhenHiddenDelayMillis); } - static base::TimeDelta delay_for_background_tab_stopping() { + static base::TimeDelta delay_for_background_tab_freezing() { return base::TimeDelta::FromMilliseconds( - MainThreadSchedulerImpl::kDelayForBackgroundTabStoppingMillis); + MainThreadSchedulerImpl::kDelayForBackgroundTabFreezingMillis); } static base::TimeDelta rails_response_time() { @@ -710,10 +706,6 @@ class MainThreadSchedulerImplTest : public testing::Test { MainThreadSchedulerImpl::kRailsResponseTimeMillis); } - static base::TimeDelta responsiveness_threshold() { - return base::TimeDelta::FromMilliseconds(200); - } - template <typename E> static void CallForEachEnumValue(E first, E last, @@ -1875,7 +1867,8 @@ class MainThreadSchedulerImplWithMockSchedulerTest mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); mock_scheduler_ = new MainThreadSchedulerImplForTest( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_), base::nullopt); Initialize(base::WrapUnique(mock_scheduler_)); } @@ -2110,7 +2103,6 @@ class MainThreadSchedulerImplWithMessageLoopTest void PostFromNestedRunloop( std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) { - base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get()); for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) { if (pair.second) { idle_task_runner_->PostIdleTask(FROM_HERE, std::move(pair.first)); @@ -2120,7 +2112,7 @@ class MainThreadSchedulerImplWithMessageLoopTest } } EnableIdleTasks(); - base::RunLoop().RunUntilIdle(); + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); } private: @@ -2307,7 +2299,7 @@ TEST_F(MainThreadSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) { EXPECT_EQ(1, run_count); } -void TestCanExceedIdleDeadlineIfRequiredTask(WebMainThreadScheduler* scheduler, +void TestCanExceedIdleDeadlineIfRequiredTask(ThreadScheduler* scheduler, bool* can_exceed_idle_deadline_out, int* run_count, base::TimeTicks deadline) { @@ -2527,7 +2519,7 @@ TEST_F(MainThreadSchedulerImplTest, ShutdownPreventsPostingOfNewTasks) { } TEST_F(MainThreadSchedulerImplTest, TestRendererBackgroundedTimerSuspension) { - scheduler_->SetStoppingWhenBackgroundedEnabled(true); + scheduler_->SetFreezingWhenBackgroundedEnabled(true); std::vector<std::string> run_order; PostTestTasks(&run_order, "T1 T2"); @@ -2551,7 +2543,7 @@ TEST_F(MainThreadSchedulerImplTest, TestRendererBackgroundedTimerSuspension) { EXPECT_THAT(run_order, testing::ElementsAre(std::string("T3"))); // Advance the time until after the scheduled timer queue suspension. - now = base::TimeTicks() + delay_for_background_tab_stopping() + + now = base::TimeTicks() + delay_for_background_tab_freezing() + base::TimeDelta::FromMilliseconds(10); run_order.clear(); clock_.SetNowTicks(now); @@ -2743,8 +2735,6 @@ TEST_F(MainThreadSchedulerImplTest, scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); SimulateExpensiveTasks(loading_task_runner_); ForceTouchStartToBeExpectedSoon(); - scheduler_->AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kChildFrame); PostTestTasks(&run_order, "L1 D1"); RunUntilIdle(); @@ -2755,108 +2745,6 @@ TEST_F(MainThreadSchedulerImplTest, } TEST_F(MainThreadSchedulerImplTest, - ExpensiveLoadingTasksNotBlockedIfMainFrameNavigationExpected) { - std::vector<std::string> run_order; - - DoMainFrame(); - scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); - SimulateExpensiveTasks(loading_task_runner_); - ForceTouchStartToBeExpectedSoon(); - scheduler_->AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - - PostTestTasks(&run_order, "L1 D1"); - RunUntilIdle(); - - EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase()); - EXPECT_TRUE(HaveSeenABeginMainframe()); - EXPECT_TRUE(LoadingTasksSeemExpensive()); - EXPECT_FALSE(TimerTasksSeemExpensive()); - EXPECT_TRUE(TouchStartExpectedSoon()); - EXPECT_EQ(1, NavigationTaskExpectedCount()); - EXPECT_THAT(run_order, - testing::ElementsAre(std::string("L1"), std::string("D1"))); - - // After the nagigation has been cancelled, the expensive loading tasks should - // get blocked. - scheduler_->RemovePendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - run_order.clear(); - - PostTestTasks(&run_order, "L1 D1"); - RunUntilIdle(); - - EXPECT_EQ(UseCase::kNone, CurrentUseCase()); - EXPECT_TRUE(HaveSeenABeginMainframe()); - EXPECT_TRUE(LoadingTasksSeemExpensive()); - EXPECT_FALSE(TimerTasksSeemExpensive()); - EXPECT_TRUE(TouchStartExpectedSoon()); - EXPECT_EQ(0, NavigationTaskExpectedCount()); - EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); - EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode()); -} - -TEST_F(MainThreadSchedulerImplTest, - ExpensiveLoadingTasksNotBlockedIfMainFrameNavigationExpected_Multiple) { - std::vector<std::string> run_order; - - DoMainFrame(); - scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); - SimulateExpensiveTasks(loading_task_runner_); - ForceTouchStartToBeExpectedSoon(); - scheduler_->AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - scheduler_->AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - - PostTestTasks(&run_order, "L1 D1"); - RunUntilIdle(); - - EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase()); - EXPECT_TRUE(HaveSeenABeginMainframe()); - EXPECT_TRUE(LoadingTasksSeemExpensive()); - EXPECT_FALSE(TimerTasksSeemExpensive()); - EXPECT_TRUE(TouchStartExpectedSoon()); - EXPECT_EQ(2, NavigationTaskExpectedCount()); - EXPECT_THAT(run_order, - testing::ElementsAre(std::string("L1"), std::string("D1"))); - - run_order.clear(); - scheduler_->RemovePendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - // Navigation task expected ref count non-zero so expensive tasks still not - // blocked. - PostTestTasks(&run_order, "L1 D1"); - RunUntilIdle(); - - EXPECT_EQ(UseCase::kNone, ForceUpdatePolicyAndGetCurrentUseCase()); - EXPECT_TRUE(HaveSeenABeginMainframe()); - EXPECT_TRUE(LoadingTasksSeemExpensive()); - EXPECT_FALSE(TimerTasksSeemExpensive()); - EXPECT_TRUE(TouchStartExpectedSoon()); - EXPECT_EQ(1, NavigationTaskExpectedCount()); - EXPECT_THAT(run_order, - testing::ElementsAre(std::string("L1"), std::string("D1"))); - - run_order.clear(); - scheduler_->RemovePendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType::kMainFrame); - // Navigation task expected ref count is now zero, the expensive loading tasks - // should get blocked. - PostTestTasks(&run_order, "L1 D1"); - RunUntilIdle(); - - EXPECT_EQ(UseCase::kNone, CurrentUseCase()); - EXPECT_TRUE(HaveSeenABeginMainframe()); - EXPECT_TRUE(LoadingTasksSeemExpensive()); - EXPECT_FALSE(TimerTasksSeemExpensive()); - EXPECT_TRUE(TouchStartExpectedSoon()); - EXPECT_EQ(0, NavigationTaskExpectedCount()); - EXPECT_THAT(run_order, testing::ElementsAre(std::string("D1"))); - EXPECT_EQ(v8::PERFORMANCE_RESPONSE, GetRAILMode()); -} - -TEST_F(MainThreadSchedulerImplTest, ExpensiveLoadingTasksNotBlockedDuringMainThreadGestures) { std::vector<std::string> run_order; @@ -3623,7 +3511,7 @@ TEST_F(MainThreadSchedulerImplTest, scheduler_->SetVirtualTimePolicy( PageSchedulerImpl::VirtualTimePolicy::kPause); scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); EXPECT_FALSE(timer_tq->HasActiveFence()); } @@ -3634,11 +3522,11 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) { EXPECT_TRUE(scheduler_->IsVirtualTimeEnabled()); scoped_refptr<MainThreadTaskQueue> loading_tq = scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoading); + MainThreadTaskQueue::QueueType::kFrameLoading, nullptr); scoped_refptr<TaskQueue> loading_control_tq = scheduler_->NewLoadingTaskQueue( - MainThreadTaskQueue::QueueType::kFrameLoadingControl); + MainThreadTaskQueue::QueueType::kFrameLoadingControl, nullptr); scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); scoped_refptr<MainThreadTaskQueue> unthrottled_tq = scheduler_->NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kUnthrottled)); @@ -3667,14 +3555,14 @@ TEST_F(MainThreadSchedulerImplTest, EnableVirtualTime) { EXPECT_EQ(unthrottled_tq->GetTimeDomain(), scheduler_->GetVirtualTimeDomain()); - EXPECT_EQ( - scheduler_ - ->NewLoadingTaskQueue(MainThreadTaskQueue::QueueType::kFrameLoading) - ->GetTimeDomain(), - scheduler_->GetVirtualTimeDomain()); + EXPECT_EQ(scheduler_ + ->NewLoadingTaskQueue( + MainThreadTaskQueue::QueueType::kFrameLoading, nullptr) + ->GetTimeDomain(), + scheduler_->GetVirtualTimeDomain()); EXPECT_EQ(scheduler_ ->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable) + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr) ->GetTimeDomain(), scheduler_->GetVirtualTimeDomain()); EXPECT_EQ(scheduler_ @@ -3716,7 +3604,7 @@ TEST_F(MainThreadSchedulerImplTest, DisableVirtualTimeForTesting) { MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); scoped_refptr<MainThreadTaskQueue> timer_tq = scheduler_->NewTimerTaskQueue( - MainThreadTaskQueue::QueueType::kFrameThrottleable); + MainThreadTaskQueue::QueueType::kFrameThrottleable, nullptr); scoped_refptr<MainThreadTaskQueue> unthrottled_tq = scheduler_->NewTaskQueue(MainThreadTaskQueue::QueueCreationParams( MainThreadTaskQueue::QueueType::kUnthrottled)); @@ -3846,80 +3734,6 @@ TEST_F(MainThreadSchedulerImplTest, base::TimeDelta::FromMilliseconds(1300))); } -TEST_F(MainThreadSchedulerImplTest, UnresponsiveMainThread) { - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - - // Add one second long task. - AdvanceTimeWithTask(1); - EXPECT_TRUE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - - // Wait a second. - clock_.Advance(base::TimeDelta::FromSecondsD(2)); - - AdvanceTimeWithTask(0.5); - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); -} - -// As |responsiveness_threshold| == expected queueing time threshold == 0.2s, -// for a task shorter than the length of the window (1s), the critical value of -// the length of task x can be calculated by (x/2) * (x/1) = 0.2, in which x = -// 0.6324. -TEST_F(MainThreadSchedulerImplTest, UnresponsiveMainThreadAboveThreshold) { - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - - AdvanceTimeWithTask(0.64); - EXPECT_TRUE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); -} - -// As |responsiveness_threshold| == expected queueing time threshold == 0.2s, -// for a task shorter than the length of the window (1s), the critical value of -// the length of task x can be calculated by (x/2) * (x/1) = 0.2, in which x = -// 0.6324. -TEST_F(MainThreadSchedulerImplTest, ResponsiveMainThreadBelowThreshold) { - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - - AdvanceTimeWithTask(0.63); - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); -} - -TEST_F(MainThreadSchedulerImplTest, ResponsiveMainThreadDuringTask) { - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - clock_.Advance(base::TimeDelta::FromSecondsD(2)); - scheduler_->OnTaskStarted(fake_queue_.get(), fake_task_, clock_.NowTicks()); - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); -} - -TEST_F(MainThreadSchedulerImplTest, UnresponsiveMainThreadWithContention) { - // Process a long task, lock the queueing time estimator, and check that we - // still report the main thread is unresponsive. - AdvanceTimeWithTask(1); - EXPECT_TRUE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - GetQueueingTimeEstimatorLock(); - EXPECT_TRUE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - - // Advance the clock, so that in the last second, we were responsive. - clock_.Advance(base::TimeDelta::FromSecondsD(2)); - // While the queueing time estimator is locked, we believe the thread to still - // be unresponsive. - EXPECT_TRUE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); - // Once we've dropped the lock, we realize the main thread is responsive. - DropQueueingTimeEstimatorLock(); - EXPECT_FALSE( - scheduler_->MainThreadSeemsUnresponsive(responsiveness_threshold())); -} - // Nav Start Nav Start assert // | | | // v v v @@ -4096,7 +3910,7 @@ class MainThreadSchedulerImplWithInitalVirtualTimeTest base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, false); } Initialize(std::make_unique<MainThreadSchedulerImplForTest>( - TaskQueueManagerForTest::Create( + base::sequence_manager::TaskQueueManagerForTest::Create( message_loop_.get(), message_loop_ ? message_loop_->task_runner() : mock_task_runner_, &clock_), @@ -4111,6 +3925,27 @@ TEST_F(MainThreadSchedulerImplWithInitalVirtualTimeTest, VirtualTimeOverride) { EXPECT_EQ(base::Time::Now(), base::Time::FromJsTime(1000000.0)); } +TEST_F(MainThreadSchedulerImplTest, ShouldIgnoreTaskForUkm) { + bool supports_thread_ticks = base::ThreadTicks::IsSupported(); + double sampling_rate; + + sampling_rate = 0.0001; + EXPECT_FALSE(scheduler_->ShouldIgnoreTaskForUkm(true, &sampling_rate)); + if (supports_thread_ticks) { + EXPECT_EQ(0.01, sampling_rate); + } else { + EXPECT_EQ(0.0001, sampling_rate); + } + + sampling_rate = 0.0001; + if (supports_thread_ticks) { + EXPECT_TRUE(scheduler_->ShouldIgnoreTaskForUkm(false, &sampling_rate)); + } else { + EXPECT_FALSE(scheduler_->ShouldIgnoreTaskForUkm(false, &sampling_rate)); + EXPECT_EQ(0.0001, sampling_rate); + } +} + } // namespace main_thread_scheduler_impl_unittest } // namespace scheduler } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.cc index 5aa213126a9..8f2584c5ec6 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.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/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" @@ -10,6 +10,12 @@ namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + +namespace internal { +using base::sequence_manager::internal::TaskQueueImpl; +} + // static const char* MainThreadTaskQueue::NameForQueueType( MainThreadTaskQueue::QueueType queue_type) { @@ -96,14 +102,15 @@ MainThreadTaskQueue::MainThreadTaskQueue( : TaskQueue(std::move(impl), spec), queue_type_(params.queue_type), queue_class_(QueueClassForQueueType(params.queue_type)), - can_be_blocked_(params.can_be_blocked), + fixed_priority_(params.fixed_priority), + can_be_deferred_(params.can_be_deferred), can_be_throttled_(params.can_be_throttled), can_be_paused_(params.can_be_paused), - can_be_stopped_(params.can_be_stopped), + can_be_frozen_(params.can_be_frozen), freeze_when_keep_active_(params.freeze_when_keep_active), used_for_important_tasks_(params.used_for_important_tasks), main_thread_scheduler_(main_thread_scheduler), - frame_scheduler_(nullptr) { + frame_scheduler_(params.frame_scheduler) { if (GetTaskQueueImpl()) { // TaskQueueImpl may be null for tests. // TODO(scheduler-dev): Consider mapping directly to @@ -169,8 +176,13 @@ FrameScheduler* MainThreadTaskQueue::GetFrameScheduler() const { return frame_scheduler_; } -void MainThreadTaskQueue::SetFrameScheduler(FrameScheduler* frame) { - frame_scheduler_ = frame; +void MainThreadTaskQueue::DetachFromFrameScheduler() { + frame_scheduler_ = nullptr; +} + +void MainThreadTaskQueue::SetFrameSchedulerForTest( + FrameScheduler* frame_scheduler) { + frame_scheduler_ = frame_scheduler; } } // namespace scheduler diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h index 6563c32549b..99c0747b15b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h @@ -2,11 +2,19 @@ // 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_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_ #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" + +namespace base { +namespace sequence_manager { +class TaskQueueManager; +} +} // namespace base namespace blink { @@ -16,7 +24,8 @@ namespace scheduler { class MainThreadSchedulerImpl; -class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { +class PLATFORM_EXPORT MainThreadTaskQueue + : public base::sequence_manager::TaskQueue { public: enum class QueueType { // Keep MainThreadTaskQueue::NameForQueueType in sync. @@ -77,15 +86,23 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { explicit QueueCreationParams(QueueType queue_type) : queue_type(queue_type), spec(NameForQueueType(queue_type)), - can_be_blocked(false), + frame_scheduler(nullptr), + can_be_deferred(false), can_be_throttled(false), can_be_paused(false), - can_be_stopped(false), + can_be_frozen(false), freeze_when_keep_active(false), used_for_important_tasks(false) {} + QueueCreationParams SetFixedPriority( + base::Optional<base::sequence_manager::TaskQueue::QueuePriority> + priority) { + fixed_priority = priority; + return *this; + } + QueueCreationParams SetCanBeDeferred(bool value) { - can_be_blocked = value; + can_be_deferred = value; return *this; } @@ -99,8 +116,8 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { return *this; } - QueueCreationParams SetCanBeStopped(bool value) { - can_be_stopped = value; + QueueCreationParams SetCanBeFrozen(bool value) { + can_be_frozen = value; return *this; } @@ -116,6 +133,10 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { // Forwarded calls to |spec|. + QueueCreationParams SetFrameScheduler(FrameSchedulerImpl* scheduler) { + frame_scheduler = scheduler; + return *this; + } QueueCreationParams SetShouldMonitorQuiescence(bool should_monitor) { spec = spec.SetShouldMonitorQuiescence(should_monitor); return *this; @@ -126,18 +147,21 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { return *this; } - QueueCreationParams SetTimeDomain(TimeDomain* domain) { + QueueCreationParams SetTimeDomain( + base::sequence_manager::TimeDomain* domain) { spec = spec.SetTimeDomain(domain); return *this; } QueueType queue_type; - TaskQueue::Spec spec; - FrameScheduler* frame_; - bool can_be_blocked; + base::sequence_manager::TaskQueue::Spec spec; + base::Optional<base::sequence_manager::TaskQueue::QueuePriority> + fixed_priority; + FrameScheduler* frame_scheduler; + bool can_be_deferred; bool can_be_throttled; bool can_be_paused; - bool can_be_stopped; + bool can_be_frozen; bool freeze_when_keep_active; bool used_for_important_tasks; }; @@ -148,21 +172,27 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { QueueClass queue_class() const { return queue_class_; } - bool CanBeDeferred() const { return can_be_blocked_; } + base::Optional<base::sequence_manager::TaskQueue::QueuePriority> + FixedPriority() const { + return fixed_priority_; + } + + bool CanBeDeferred() const { return can_be_deferred_; } bool CanBeThrottled() const { return can_be_throttled_; } bool CanBePaused() const { return can_be_paused_; } - bool CanBeStopped() const { return can_be_stopped_; } + bool CanBeFrozen() const { return can_be_frozen_; } bool FreezeWhenKeepActive() const { return freeze_when_keep_active_; } bool UsedForImportantTasks() const { return used_for_important_tasks_; } - void OnTaskStarted(const TaskQueue::Task& task, base::TimeTicks start); + void OnTaskStarted(const base::sequence_manager::TaskQueue::Task& task, + base::TimeTicks start); - void OnTaskCompleted(const TaskQueue::Task& task, + void OnTaskCompleted(const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time); @@ -173,28 +203,33 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { void ShutdownTaskQueue() override; FrameScheduler* GetFrameScheduler() const; - void SetFrameScheduler(FrameScheduler* frame); + void DetachFromFrameScheduler(); protected: - MainThreadTaskQueue(std::unique_ptr<internal::TaskQueueImpl> impl, - const Spec& spec, - const QueueCreationParams& params, - MainThreadSchedulerImpl* main_thread_scheduler); + void SetFrameSchedulerForTest(FrameScheduler* frame); + + MainThreadTaskQueue( + std::unique_ptr<base::sequence_manager::internal::TaskQueueImpl> impl, + const Spec& spec, + const QueueCreationParams& params, + MainThreadSchedulerImpl* main_thread_scheduler); private: - friend class TaskQueueManager; + friend class base::sequence_manager::TaskQueueManager; // Clear references to main thread scheduler and frame scheduler and dispatch // appropriate notifications. This is the common part of ShutdownTaskQueue and // DetachFromMainThreadScheduler. void ClearReferencesToSchedulers(); - QueueType queue_type_; - QueueClass queue_class_; - const bool can_be_blocked_; + const QueueType queue_type_; + const QueueClass queue_class_; + const base::Optional<base::sequence_manager::TaskQueue::QueuePriority> + fixed_priority_; + const bool can_be_deferred_; const bool can_be_throttled_; const bool can_be_paused_; - const bool can_be_stopped_; + const bool can_be_frozen_; const bool freeze_when_keep_active_; const bool used_for_important_tasks_; @@ -209,4 +244,4 @@ class PLATFORM_EXPORT MainThreadTaskQueue : public TaskQueue { } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_MAIN_THREAD_TASK_QUEUE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_MAIN_THREAD_TASK_QUEUE_H_ 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 c105a49f2f9..a12e5f32f40 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 @@ -12,10 +12,10 @@ #include "third_party/blink/renderer/platform/scheduler/base/virtual_time_domain.h" #include "third_party/blink/renderer/platform/scheduler/child/default_params.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/budget_pool.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/frame_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/auto_advancing_virtual_time_domain.h" namespace blink { namespace scheduler { @@ -32,6 +32,13 @@ constexpr double kDefaultMaxBackgroundThrottlingDelayInSeconds = 0; constexpr base::TimeDelta kMinimalBackgroundThrottlingDurationToReport = base::TimeDelta::FromSeconds(3); +// We do not throttle anything while audio is played and shortly after that. +constexpr base::TimeDelta kRecentAudioDelay = base::TimeDelta::FromSeconds(5); + +// Delay for fully throttling the page after backgrounding. +constexpr base::TimeDelta kThrottlingDelayAfterBackgrounding = + base::TimeDelta::FromSeconds(10); + // Values coming from the field trial config are interpreted as follows: // -1 is "not set". Scheduler should use a reasonable default. // 0 corresponds to base::nullopt. @@ -100,16 +107,22 @@ PageSchedulerImpl::PageSchedulerImpl( : main_thread_scheduler_(main_thread_scheduler), page_visibility_(kDefaultPageVisibility), disable_background_timer_throttling_(disable_background_timer_throttling), - is_audio_playing_(false), + audio_state_(AudioState::kSilent), is_frozen_(false), reported_background_throttling_since_navigation_(false), has_active_connection_(false), nested_runloop_(false), is_main_frame_local_(false), + is_throttled_(false), + keep_active_(main_thread_scheduler->SchedulerKeepActive()), background_time_budget_pool_(nullptr), delegate_(delegate), weak_factory_(this) { main_thread_scheduler->AddPageScheduler(this); + do_throttle_page_callback_.Reset(base::BindRepeating( + &PageSchedulerImpl::DoThrottlePage, base::Unretained(this))); + on_audio_silent_closure_.Reset(base::BindRepeating( + &PageSchedulerImpl::OnAudioSilent, base::Unretained(this))); } PageSchedulerImpl::~PageSchedulerImpl() { @@ -132,29 +145,52 @@ void PageSchedulerImpl::SetPageVisible(bool page_visible) { if (disable_background_timer_throttling_ || page_visibility_ == page_visibility) return; - page_visibility_ = page_visibility; - UpdateBackgroundThrottlingState(); - // Visible pages should not be frozen. - if (page_visibility_ == PageVisibilityState::kVisible && is_frozen_) - SetPageFrozen(false); + if (page_visibility_ == PageVisibilityState::kVisible) + SetPageFrozenImpl(false, NotificationPolicy::kDoNotNotifyFrames); + + for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) + frame_scheduler->SetPageVisibilityForTracing(page_visibility_); + + UpdateBackgroundThrottlingState(NotificationPolicy::kDoNotNotifyFrames); + + NotifyFrames(); } void PageSchedulerImpl::SetPageFrozen(bool frozen) { + SetPageFrozenImpl(frozen, NotificationPolicy::kNotifyFrames); +} + +void PageSchedulerImpl::SetPageFrozenImpl( + bool frozen, + PageSchedulerImpl::NotificationPolicy notification_policy) { if (is_frozen_ == frozen) return; is_frozen_ = frozen; for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) - frame_scheduler->SetPageFrozen(frozen); + frame_scheduler->SetPageFrozenForTracing(frozen); if (delegate_) delegate_->SetPageFrozen(frozen); + if (notification_policy == + PageSchedulerImpl::NotificationPolicy::kNotifyFrames) + NotifyFrames(); } void PageSchedulerImpl::SetKeepActive(bool keep_active) { + if (keep_active_ == keep_active) + return; + keep_active_ = keep_active; + for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) - frame_scheduler->SetKeepActive(keep_active); + frame_scheduler->SetPageKeepActiveForTracing(keep_active); + + NotifyFrames(); +} + +bool PageSchedulerImpl::KeepActive() const { + return keep_active_; } bool PageSchedulerImpl::IsMainFrameLocal() const { @@ -171,7 +207,7 @@ std::unique_ptr<FrameSchedulerImpl> PageSchedulerImpl::CreateFrameSchedulerImpl( MaybeInitializeBackgroundCPUTimeBudgetPool(); std::unique_ptr<FrameSchedulerImpl> frame_scheduler(new FrameSchedulerImpl( main_thread_scheduler_, this, blame_context, frame_type)); - frame_scheduler->SetPageVisibility(page_visibility_); + frame_scheduler->UpdatePolicy(); frame_schedulers_.insert(frame_scheduler.get()); return frame_scheduler; } @@ -196,8 +232,7 @@ void PageSchedulerImpl::ReportIntervention(const std::string& message) { } base::TimeTicks PageSchedulerImpl::EnableVirtualTime() { - return main_thread_scheduler_->EnableVirtualTime( - MainThreadSchedulerImpl::BaseTimeOverridePolicy::DO_NOT_OVERRIDE); + return main_thread_scheduler_->EnableVirtualTime(); } void PageSchedulerImpl::DisableVirtualTimeForTesting() { @@ -208,6 +243,10 @@ void PageSchedulerImpl::SetVirtualTimePolicy(VirtualTimePolicy policy) { main_thread_scheduler_->SetVirtualTimePolicy(policy); } +void PageSchedulerImpl::SetInitialVirtualTime(base::Time time) { + main_thread_scheduler_->SetInitialVirtualTime(time); +} + void PageSchedulerImpl::SetInitialVirtualTimeOffset(base::TimeDelta offset) { main_thread_scheduler_->SetInitialVirtualTimeOffset(offset); } @@ -219,7 +258,7 @@ bool PageSchedulerImpl::VirtualTimeAllowedToAdvance() const { void PageSchedulerImpl::GrantVirtualTimeBudget( base::TimeDelta budget, base::OnceClosure budget_exhausted_callback) { - main_thread_scheduler_->VirtualTimeControlTaskQueue()->PostDelayedTask( + main_thread_scheduler_->VirtualTimeControlTaskRunner()->PostDelayedTask( FROM_HERE, std::move(budget_exhausted_callback), budget); // This can shift time forwards if there's a pending MaybeAdvanceVirtualTime, // so it's important this is called second. @@ -237,7 +276,29 @@ void PageSchedulerImpl::RemoveVirtualTimeObserver( } void PageSchedulerImpl::AudioStateChanged(bool is_audio_playing) { - is_audio_playing_ = is_audio_playing; + if (is_audio_playing) { + audio_state_ = AudioState::kAudible; + on_audio_silent_closure_.Cancel(); + NotifyFrames(); + main_thread_scheduler_->OnAudioStateChanged(); + } else { + if (audio_state_ != AudioState::kAudible) + return; + on_audio_silent_closure_.Cancel(); + + audio_state_ = AudioState::kRecentlyAudible; + main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask( + FROM_HERE, on_audio_silent_closure_.GetCallback(), kRecentAudioDelay); + // No need to call NotifyFrames or + // MainThreadScheduler::OnAudioStateChanged here, as for outside world + // kAudible and kRecentlyAudible are the same thing. + } +} + +void PageSchedulerImpl::OnAudioSilent() { + DCHECK_EQ(audio_state_, AudioState::kRecentlyAudible); + audio_state_ = AudioState::kSilent; + NotifyFrames(); main_thread_scheduler_->OnAudioStateChanged(); } @@ -246,6 +307,10 @@ bool PageSchedulerImpl::IsExemptFromBudgetBasedThrottling() const { } bool PageSchedulerImpl::HasActiveConnectionForTest() const { + return HasActiveConnection(); +} + +bool PageSchedulerImpl::HasActiveConnection() const { return has_active_connection_; } @@ -253,14 +318,23 @@ void PageSchedulerImpl::RequestBeginMainFrameNotExpected(bool new_state) { delegate_->RequestBeginMainFrameNotExpected(new_state); } -bool PageSchedulerImpl::IsPlayingAudio() const { - return is_audio_playing_; +bool PageSchedulerImpl::IsAudioPlaying() const { + return audio_state_ == AudioState::kAudible || + audio_state_ == AudioState::kRecentlyAudible; +} + +bool PageSchedulerImpl::IsPageVisible() const { + return page_visibility_ == PageVisibilityState::kVisible; } bool PageSchedulerImpl::IsFrozen() const { return is_frozen_; } +bool PageSchedulerImpl::IsThrottled() const { + return is_throttled_; +} + void PageSchedulerImpl::OnConnectionUpdated() { bool has_active_connection = false; for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) { @@ -269,7 +343,7 @@ void PageSchedulerImpl::OnConnectionUpdated() { if (has_active_connection_ != has_active_connection) { has_active_connection_ = has_active_connection; - UpdateBackgroundThrottlingState(); + UpdateBackgroundBudgetPoolThrottlingState(); } } @@ -286,7 +360,7 @@ void PageSchedulerImpl::AsValueInto( page_visibility_ == PageVisibilityState::kVisible); state->SetBoolean("disable_background_timer_throttling", disable_background_timer_throttling_); - state->SetBoolean("is_audio_playing", is_audio_playing_); + state->SetBoolean("is_audio_playing", IsAudioPlaying()); state->SetBoolean("is_frozen", is_frozen_); state->SetBoolean("reported_background_throttling_since_navigation", reported_background_throttling_since_navigation_); @@ -315,7 +389,8 @@ void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool() { background_time_budget_pool_ = main_thread_scheduler_->task_queue_throttler()->CreateCPUTimeBudgetPool( "background"); - LazyNow lazy_now(main_thread_scheduler_->tick_clock()); + base::sequence_manager::LazyNow lazy_now( + main_thread_scheduler_->tick_clock()); BackgroundThrottlingSettings settings = GetBackgroundThrottlingSettings(); @@ -324,8 +399,6 @@ void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool() { background_time_budget_pool_->SetMaxThrottlingDelay( lazy_now.Now(), settings.max_throttling_delay); - UpdateBackgroundThrottlingState(); - background_time_budget_pool_->SetTimeBudgetRecoveryRate( lazy_now.Now(), settings.budget_recovery_rate); @@ -333,6 +406,8 @@ void PageSchedulerImpl::MaybeInitializeBackgroundCPUTimeBudgetPool() { background_time_budget_pool_->GrantAdditionalBudget( lazy_now.Now(), settings.initial_budget.value()); } + + UpdateBackgroundBudgetPoolThrottlingState(); } void PageSchedulerImpl::OnThrottlingReported( @@ -355,25 +430,47 @@ void PageSchedulerImpl::OnThrottlingReported( delegate_->ReportIntervention(String::FromUTF8(message.c_str())); } -void PageSchedulerImpl::UpdateBackgroundThrottlingState() { - for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) - frame_scheduler->SetPageVisibility(page_visibility_); +void PageSchedulerImpl::UpdateBackgroundThrottlingState( + NotificationPolicy notification_policy) { + if (page_visibility_ == PageVisibilityState::kVisible) { + is_throttled_ = false; + do_throttle_page_callback_.Cancel(); + UpdateBackgroundBudgetPoolThrottlingState(); + } else { + main_thread_scheduler_->ControlTaskRunner()->PostDelayedTask( + FROM_HERE, do_throttle_page_callback_.GetCallback(), + kThrottlingDelayAfterBackgrounding); + } + if (notification_policy == NotificationPolicy::kNotifyFrames) + NotifyFrames(); +} + +void PageSchedulerImpl::DoThrottlePage() { + do_throttle_page_callback_.Cancel(); + is_throttled_ = true; + UpdateBackgroundBudgetPoolThrottlingState(); + NotifyFrames(); } void PageSchedulerImpl::UpdateBackgroundBudgetPoolThrottlingState() { if (!background_time_budget_pool_) return; - LazyNow lazy_now(main_thread_scheduler_->tick_clock()); - if (page_visibility_ == PageVisibilityState::kVisible || - has_active_connection_) { - background_time_budget_pool_->DisableThrottling(&lazy_now); - } else { + base::sequence_manager::LazyNow lazy_now( + main_thread_scheduler_->tick_clock()); + if (is_throttled_ && !has_active_connection_) { background_time_budget_pool_->EnableThrottling(&lazy_now); + } else { + background_time_budget_pool_->DisableThrottling(&lazy_now); } } +void PageSchedulerImpl::NotifyFrames() { + for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) + frame_scheduler->UpdatePolicy(); +} + size_t PageSchedulerImpl::FrameCount() const { return frame_schedulers_.size(); } 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 beee564fefd..b7cd3a32fee 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 @@ -15,9 +15,9 @@ #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/child/page_visibility_state.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" namespace base { @@ -56,6 +56,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { void DisableVirtualTimeForTesting() override; bool VirtualTimeAllowedToAdvance() const override; void SetVirtualTimePolicy(VirtualTimePolicy) override; + void SetInitialVirtualTime(base::Time time) override; void SetInitialVirtualTimeOffset(base::TimeDelta offset) override; void GrantVirtualTimeBudget( base::TimeDelta budget, @@ -63,7 +64,7 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { void SetMaxVirtualTimeTaskStarvationCount( int max_task_starvation_count) override; void AudioStateChanged(bool is_audio_playing) override; - bool IsPlayingAudio() const override; + bool IsAudioPlaying() const override; bool IsExemptFromBudgetBasedThrottling() const override; bool HasActiveConnectionForTest() const override; void RequestBeginMainFrameNotExpected(bool new_state) override; @@ -73,7 +74,15 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { // Virtual for testing. virtual void ReportIntervention(const std::string& message); + bool IsPageVisible() const; bool IsFrozen() const; + // PageSchedulerImpl::HasActiveConnection can be used in non-test code, + // while PageScheduler::HasActiveConnectionForTest can't. + bool HasActiveConnection() const; + // Note that the frame can throttle queues even when the page is not throttled + // (e.g. for offscreen frames or recently backgrounded pages). + bool IsThrottled() const; + bool KeepActive() const; std::unique_ptr<FrameSchedulerImpl> CreateFrameSchedulerImpl( base::trace_event::BlameContext*, @@ -101,6 +110,18 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { private: friend class FrameSchedulerImpl; + enum class AudioState { + kSilent, + kAudible, + kRecentlyAudible, + }; + + enum class NotificationPolicy { kNotifyFrames, kDoNotNotifyFrames }; + + // Support not issuing a notification to frames when we disable freezing as + // a part of foregrounding the page. + void SetPageFrozenImpl(bool frozen, NotificationPolicy notification_policy); + CPUTimeBudgetPool* BackgroundCPUTimeBudgetPool(); void MaybeInitializeBackgroundCPUTimeBudgetPool(); @@ -108,27 +129,45 @@ class PLATFORM_EXPORT PageSchedulerImpl : public PageScheduler { // Depending on page visibility, either turns throttling off, or schedules a // call to enable it after a grace period. - void UpdateBackgroundThrottlingState(); + void UpdateBackgroundThrottlingState(NotificationPolicy notification_policy); // As a part of UpdateBackgroundThrottlingState set correct // background_time_budget_pool_ state depending on page visibility and // number of active connections. void UpdateBackgroundBudgetPoolThrottlingState(); + // Callback for marking page is silent after a delay since last audible + // signal. + void OnAudioSilent(); + + // Callback for enabling throttling in background after specified delay. + // TODO(altimin): Trigger throttling depending on the loading state + // of the page. + void DoThrottlePage(); + + // Notify frames that the page scheduler state has been updated. + void NotifyFrames(); + + void EnableThrottling(); + TraceableVariableController tracing_controller_; std::set<FrameSchedulerImpl*> frame_schedulers_; MainThreadSchedulerImpl* main_thread_scheduler_; PageVisibilityState page_visibility_; bool disable_background_timer_throttling_; - bool is_audio_playing_; + AudioState audio_state_; bool is_frozen_; bool reported_background_throttling_since_navigation_; bool has_active_connection_; bool nested_runloop_; bool is_main_frame_local_; + bool is_throttled_; + bool keep_active_; CPUTimeBudgetPool* background_time_budget_pool_; // Not owned. PageScheduler::Delegate* delegate_; // Not owned. + CancelableClosureHolder do_throttle_page_callback_; + CancelableClosureHolder on_audio_silent_closure_; base::WeakPtrFactory<PageSchedulerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(PageSchedulerImpl); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index 0b5260dbb29..67771e96e57 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc @@ -11,17 +11,19 @@ #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_param_associator.h" #include "base/metrics/field_trial_params.h" +#include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" #include "base/test/simple_test_tick_clock.h" #include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.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/scheduler/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" +using base::sequence_manager::TaskQueue; using testing::ElementsAre; using VirtualTimePolicy = blink::PageScheduler::VirtualTimePolicy; @@ -40,7 +42,8 @@ class PageSchedulerImplTest : public testing::Test { mock_task_runner_ = base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true); scheduler_.reset(new MainThreadSchedulerImpl( - TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_), base::nullopt)); page_scheduler_.reset(new PageSchedulerImpl( nullptr, scheduler_.get(), DisableBackgroundTimerThrottling())); @@ -64,12 +67,13 @@ class PageSchedulerImplTest : public testing::Test { } scoped_refptr<base::SingleThreadTaskRunner> ThrottleableTaskRunner() { - return TaskRunnerImpl::Create(ThrottleableTaskQueue(), - TaskType::kInternalTest); + return TaskQueueWithTaskType::Create(ThrottleableTaskQueue(), + TaskType::kInternalTest); } scoped_refptr<base::SingleThreadTaskRunner> LoadingTaskRunner() { - return TaskRunnerImpl::Create(LoadingTaskQueue(), TaskType::kInternalTest); + return TaskQueueWithTaskType::Create(LoadingTaskQueue(), + TaskType::kInternalTest); } scoped_refptr<TaskQueue> ThrottleableTaskQueue() { @@ -120,20 +124,25 @@ TEST_F(PageSchedulerImplTest, TestDestructionOfFrameSchedulersAfter) { namespace { -void RunRepeatingTask(scoped_refptr<TaskQueue>, int* run_count); +void RunRepeatingTask(scoped_refptr<TaskQueue>, + int* run_count, + base::TimeDelta delay); base::OnceClosure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, - int* run_count) { + int* run_count, + base::TimeDelta delay) { return base::BindOnce(&RunRepeatingTask, std::move(task_queue), - base::Unretained(run_count)); + base::Unretained(run_count), delay); } -void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count) { +void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, + int* run_count, + base::TimeDelta delay) { ++*run_count; TaskQueue* task_queue_ptr = task_queue.get(); task_queue_ptr->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(std::move(task_queue_ptr), run_count), - base::TimeDelta::FromMilliseconds(1)); + FROM_HERE, MakeRepeatingTask(std::move(task_queue_ptr), run_count, delay), + delay); } } // namespace @@ -143,7 +152,9 @@ TEST_F(PageSchedulerImplTest, RepeatingTimer_PageInForeground) { int run_count = 0; ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), + FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueue(), &run_count, + base::TimeDelta::FromMilliseconds(1)), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -155,8 +166,10 @@ TEST_F(PageSchedulerImplTest, RepeatingTimer_PageInBackgroundThenForeground) { int run_count = 0; ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), - base::TimeDelta::FromMilliseconds(1)); + FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueue(), &run_count, + base::TimeDelta::FromMilliseconds(20)), + base::TimeDelta::FromMilliseconds(20)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); EXPECT_EQ(1, run_count); @@ -167,9 +180,7 @@ TEST_F(PageSchedulerImplTest, RepeatingTimer_PageInBackgroundThenForeground) { run_count = 0; mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(1001, run_count); // Note we end up running 1001 here because the - // task was posted while throttled with a delay of 1ms so the first task was - // due to run before the 1s period started. + EXPECT_EQ(50, run_count); } TEST_F(PageSchedulerImplTest, RepeatingLoadingTask_PageInBackground) { @@ -177,7 +188,9 @@ TEST_F(PageSchedulerImplTest, RepeatingLoadingTask_PageInBackground) { int run_count = 0; LoadingTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(LoadingTaskQueue(), &run_count), + FROM_HERE, + MakeRepeatingTask(LoadingTaskQueue(), &run_count, + base::TimeDelta::FromMilliseconds(1)), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -197,17 +210,20 @@ TEST_F(PageSchedulerImplTest, RepeatingTimers_OneBackgroundOneForeground) { int run_count1 = 0; int run_count2 = 0; ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count1), - base::TimeDelta::FromMilliseconds(1)); + FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueue(), &run_count1, + base::TimeDelta::FromMilliseconds(20)), + base::TimeDelta::FromMilliseconds(20)); ThrottleableTaskQueueForScheduler(frame_scheduler2.get()) - ->PostDelayedTask(FROM_HERE, - MakeRepeatingTask(ThrottleableTaskQueueForScheduler( - frame_scheduler2.get()), - &run_count2), - base::TimeDelta::FromMilliseconds(1)); + ->PostDelayedTask( + FROM_HERE, + MakeRepeatingTask( + ThrottleableTaskQueueForScheduler(frame_scheduler2.get()), + &run_count2, base::TimeDelta::FromMilliseconds(20)), + base::TimeDelta::FromMilliseconds(20)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); - EXPECT_EQ(1000, run_count1); + EXPECT_EQ(50, run_count1); EXPECT_EQ(1, run_count2); } @@ -322,7 +338,9 @@ TEST_F(PageSchedulerImplTest, int run_count = 0; ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), + FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueue(), &run_count, + base::TimeDelta::FromMilliseconds(1)), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunTasksWhile(mock_task_runner_->TaskRunCountBelow(2000)); @@ -421,7 +439,9 @@ TEST_F(PageSchedulerImplTestWithDisabledBackgroundTimerThrottling, int run_count = 0; ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(ThrottleableTaskQueue(), &run_count), + FROM_HERE, + MakeRepeatingTask(ThrottleableTaskQueue(), &run_count, + base::TimeDelta::FromMilliseconds(1)), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(1)); @@ -495,8 +515,10 @@ TEST_F(PageSchedulerImplTest, DeleteThrottledQueue_InTask) { int run_count = 0; timer_task_queue->PostDelayedTask( - FROM_HERE, MakeRepeatingTask(timer_task_queue, &run_count), - base::TimeDelta::FromMilliseconds(1)); + FROM_HERE, + MakeRepeatingTask(timer_task_queue, &run_count, + base::TimeDelta::FromMilliseconds(100)), + base::TimeDelta::FromMilliseconds(100)); // Note this will run at time t = 10s since we start at time t = 5000us. // However, we still should run all tasks after frame scheduler deletion. @@ -504,8 +526,8 @@ TEST_F(PageSchedulerImplTest, DeleteThrottledQueue_InTask) { MakeDeletionTask(frame_scheduler), base::TimeDelta::FromMilliseconds(9990)); - mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(100)); - EXPECT_EQ(90015, run_count); + mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(20)); + EXPECT_EQ(110, run_count); } TEST_F(PageSchedulerImplTest, VirtualTimePauseCount_DETERMINISTIC_LOADING) { @@ -955,11 +977,13 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) { InitializeTrialParams(); page_scheduler_.reset( new PageSchedulerImpl(nullptr, scheduler_.get(), false)); + EXPECT_FALSE(page_scheduler_->IsThrottled()); std::vector<base::TimeTicks> run_times; frame_scheduler_ = page_scheduler_->CreateFrameSchedulerImpl( nullptr, FrameScheduler::FrameType::kSubframe); page_scheduler_->SetPageVisible(true); + EXPECT_FALSE(page_scheduler_->IsThrottled()); mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(2500)); @@ -983,6 +1007,12 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) { run_times.clear(); page_scheduler_->SetPageVisible(false); + EXPECT_FALSE(page_scheduler_->IsThrottled()); + + // Ensure that the page is fully throttled. + mock_task_runner_->RunUntilTime(base::TimeTicks() + + base::TimeDelta::FromSeconds(15)); + EXPECT_TRUE(page_scheduler_->IsThrottled()); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), @@ -996,7 +1026,7 @@ TEST_F(PageSchedulerImplTest, BackgroundTimerThrottling) { // Check that tasks are aligned and throttled. EXPECT_THAT( run_times, - ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(4), + ElementsAre(base::TimeTicks() + base::TimeDelta::FromSeconds(16), base::TimeTicks() + base::TimeDelta::FromSeconds(26))); base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting(); @@ -1169,6 +1199,73 @@ TEST_F(PageSchedulerImplTest, PageFreeze) { EXPECT_EQ(5, counter); } +TEST_F(PageSchedulerImplTest, AudioState) { + page_scheduler_->AudioStateChanged(true); + EXPECT_TRUE(page_scheduler_->IsAudioPlaying()); + + page_scheduler_->AudioStateChanged(false); + // We are audible for a certain period after raw signal disappearing. + EXPECT_TRUE(page_scheduler_->IsAudioPlaying()); + + mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(3)); + + page_scheduler_->AudioStateChanged(false); + // We are still audible. A new call to AudioStateChanged shouldn't change + // anything. + EXPECT_TRUE(page_scheduler_->IsAudioPlaying()); + + mock_task_runner_->RunForPeriod(base::TimeDelta::FromSeconds(3)); + + // Audio is finally silent. + EXPECT_FALSE(page_scheduler_->IsAudioPlaying()); +} + +TEST_F(PageSchedulerImplTest, PageSchedulerDestroyedWhileAudioChangePending) { + page_scheduler_->AudioStateChanged(true); + EXPECT_TRUE(page_scheduler_->IsAudioPlaying()); + page_scheduler_->AudioStateChanged(false); + + page_scheduler_.reset(); + + mock_task_runner_->RunUntilIdle(); +} + +TEST_F(PageSchedulerImplTest, AudiblePagesAreNotThrottled) { + page_scheduler_->SetPageVisible(false); + EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled( + ThrottleableTaskQueue().get())); + + // No throttling when the page is audible. + page_scheduler_->AudioStateChanged(true); + EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled( + ThrottleableTaskQueue().get())); + + // No throttling for some time after audio signal disappears. + page_scheduler_->AudioStateChanged(false); + EXPECT_FALSE(scheduler_->task_queue_throttler()->IsThrottled( + ThrottleableTaskQueue().get())); + + // Eventually throttling is reenabled again. + mock_task_runner_->RunUntilIdle(); + EXPECT_TRUE(scheduler_->task_queue_throttler()->IsThrottled( + ThrottleableTaskQueue().get())); +} + +TEST_F(PageSchedulerImplTest, BudgetBasedThrottlingForPageScheduler) { + page_scheduler_->SetPageVisible(false); +} + +TEST_F(PageSchedulerImplTest, KeepActiveSetForNewPages) { + scheduler_->SetSchedulerKeepActive(true); + + std::unique_ptr<PageSchedulerImpl> page_scheduler2 = + std::make_unique<PageSchedulerImpl>(nullptr, scheduler_.get(), + DisableBackgroundTimerThrottling()); + + EXPECT_TRUE(page_scheduler_->KeepActive()); + EXPECT_TRUE(page_scheduler2->KeepActive()); +} + } // namespace page_scheduler_impl_unittest } // namespace scheduler } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.cc index 75a6ed7b9b0..b31f3988d39 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.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/renderer/platform/scheduler/renderer/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" @@ -69,33 +69,87 @@ QueueingTimeEstimator::QueueingTimeEstimator( QueueingTimeEstimator::Client* client, base::TimeDelta window_duration, int steps_per_window) - : client_(client), state_(steps_per_window) { + : client_(client), + window_step_width_(window_duration / steps_per_window), + renderer_backgrounded_(kLaunchingProcessIsBackgrounded), + processing_task_(false), + in_nested_message_loop_(false), + calculator_(steps_per_window) { DCHECK_GE(steps_per_window, 1); - state_.window_step_width = window_duration / steps_per_window; } -QueueingTimeEstimator::QueueingTimeEstimator(const State& state) - : client_(nullptr), state_(state) {} - void QueueingTimeEstimator::OnTopLevelTaskStarted( base::TimeTicks task_start_time, MainThreadTaskQueue* queue) { - state_.OnTopLevelTaskStarted(client_, task_start_time, queue); + AdvanceTime(task_start_time); + current_task_start_time_ = task_start_time; + processing_task_ = true; + calculator_.UpdateStatusFromTaskQueue(queue); } void QueueingTimeEstimator::OnTopLevelTaskCompleted( base::TimeTicks task_end_time) { - state_.OnTopLevelTaskCompleted(client_, task_end_time); + DCHECK(processing_task_); + AdvanceTime(task_end_time); + processing_task_ = false; + current_task_start_time_ = base::TimeTicks(); + in_nested_message_loop_ = false; } void QueueingTimeEstimator::OnBeginNestedRunLoop() { - state_.OnBeginNestedRunLoop(); + in_nested_message_loop_ = true; } void QueueingTimeEstimator::OnRendererStateChanged( bool backgrounded, base::TimeTicks transition_time) { - state_.OnRendererStateChanged(client_, backgrounded, transition_time); + DCHECK_NE(backgrounded, renderer_backgrounded_); + if (!processing_task_) + AdvanceTime(transition_time); + renderer_backgrounded_ = backgrounded; +} + +void QueueingTimeEstimator::AdvanceTime(base::TimeTicks current_time) { + if (step_start_time_.is_null()) { + // Ignore any time before the first task. + if (!processing_task_) + return; + + step_start_time_ = current_task_start_time_; + } + base::TimeTicks reference_time = + processing_task_ ? current_task_start_time_ : step_start_time_; + if (in_nested_message_loop_ || renderer_backgrounded_ || + current_time - reference_time > kInvalidPeriodThreshold) { + // Skip steps when the renderer was backgrounded, when we are at a nested + // message loop, when a task took too long, or when we remained idle for + // too long. May cause |step_start_time_| to go slightly into the future. + // TODO(npm): crbug.com/776013. Base skipping long tasks/idling on a signal + // that we've been suspended. + step_start_time_ = + current_time.SnappedToNextTick(step_start_time_, window_step_width_); + calculator_.ResetStep(); + return; + } + while (TimePastStepEnd(current_time)) { + if (processing_task_) { + // Include the current task in this window. + calculator_.AddQueueingTime(ExpectedQueueingTimeFromTask( + current_task_start_time_, current_time, step_start_time_, + step_start_time_ + window_step_width_)); + } + calculator_.EndStep(client_); + step_start_time_ += window_step_width_; + } + if (processing_task_) { + calculator_.AddQueueingTime(ExpectedQueueingTimeFromTask( + current_task_start_time_, current_time, step_start_time_, + step_start_time_ + window_step_width_)); + } +} + +bool QueueingTimeEstimator::TimePastStepEnd(base::TimeTicks time) { + return time >= step_start_time_ + window_step_width_; } QueueingTimeEstimator::Calculator::Calculator(int steps_per_window) @@ -238,88 +292,6 @@ void QueueingTimeEstimator::Calculator::ResetStep() { step_expected_queueing_time_ = base::TimeDelta(); } -QueueingTimeEstimator::State::State(int steps_per_window) - : calculator_(steps_per_window) {} - -void QueueingTimeEstimator::State::OnTopLevelTaskStarted( - QueueingTimeEstimator::Client* client, - base::TimeTicks task_start_time, - MainThreadTaskQueue* queue) { - AdvanceTime(client, task_start_time); - current_task_start_time = task_start_time; - processing_task = true; - calculator_.UpdateStatusFromTaskQueue(queue); -} - -void QueueingTimeEstimator::State::OnTopLevelTaskCompleted( - QueueingTimeEstimator::Client* client, - base::TimeTicks task_end_time) { - DCHECK(processing_task); - AdvanceTime(client, task_end_time); - processing_task = false; - current_task_start_time = base::TimeTicks(); - in_nested_message_loop_ = false; -} - -void QueueingTimeEstimator::State::OnBeginNestedRunLoop() { - in_nested_message_loop_ = true; -} - -void QueueingTimeEstimator::State::OnRendererStateChanged( - QueueingTimeEstimator::Client* client, - bool backgrounded, - base::TimeTicks transition_time) { - DCHECK_NE(backgrounded, renderer_backgrounded); - if (!processing_task) - AdvanceTime(client, transition_time); - renderer_backgrounded = backgrounded; -} - -void QueueingTimeEstimator::State::AdvanceTime( - QueueingTimeEstimator::Client* client, - base::TimeTicks current_time) { - if (step_start_time.is_null()) { - // Ignore any time before the first task. - if (!processing_task) - return; - - step_start_time = current_task_start_time; - } - base::TimeTicks reference_time = - processing_task ? current_task_start_time : step_start_time; - if (in_nested_message_loop_ || renderer_backgrounded || - current_time - reference_time > kInvalidPeriodThreshold) { - // Skip steps when the renderer was backgrounded, when we are at a nested - // message loop, when a task took too long, or when we remained idle for - // too long. May cause |step_start_time| to go slightly into the future. - // TODO(npm): crbug.com/776013. Base skipping long tasks/idling on a signal - // that we've been suspended. - step_start_time = - current_time.SnappedToNextTick(step_start_time, window_step_width); - calculator_.ResetStep(); - return; - } - while (TimePastStepEnd(current_time)) { - if (processing_task) { - // Include the current task in this window. - calculator_.AddQueueingTime(ExpectedQueueingTimeFromTask( - current_task_start_time, current_time, step_start_time, - step_start_time + window_step_width)); - } - calculator_.EndStep(client); - step_start_time += window_step_width; - } - if (processing_task) { - calculator_.AddQueueingTime(ExpectedQueueingTimeFromTask( - current_task_start_time, current_time, step_start_time, - step_start_time + window_step_width)); - } -} - -bool QueueingTimeEstimator::State::TimePastStepEnd(base::TimeTicks time) { - return time >= step_start_time + window_step_width; -} - QueueingTimeEstimator::RunningAverage::RunningAverage(int size) { circular_buffer_.resize(size); index_ = 0; @@ -367,45 +339,5 @@ class RecordQueueingTimeClient : public QueueingTimeEstimator::Client { DISALLOW_COPY_AND_ASSIGN(RecordQueueingTimeClient); }; -base::TimeDelta QueueingTimeEstimator::EstimateQueueingTimeIncludingCurrentTask( - base::TimeTicks now) const { - RecordQueueingTimeClient record_queueing_time_client; - - // Make a copy of this QueueingTimeEstimator. We'll use it to evaluate the - // estimated input latency, assuming that any active task ends now. - QueueingTimeEstimator::State temporary_queueing_time_estimator_state(state_); - - // If there's a task in progress, pretend it ends now, and include it in the - // computation. If there's no task in progress, add an empty task to flush any - // stale windows. - if (temporary_queueing_time_estimator_state.current_task_start_time - .is_null()) { - temporary_queueing_time_estimator_state.OnTopLevelTaskStarted( - &record_queueing_time_client, now, nullptr); - } - temporary_queueing_time_estimator_state.OnTopLevelTaskCompleted( - &record_queueing_time_client, now); - - // Report the max of the queueing time for the last window, or the on-going - // window (tmp window in chart) which includes the current task. - // - // Estimate - // | - // v - // Actual Task |-------------------------... - // Assumed Task |----------------| - // Time |---o---o---o---o---o---o--------> - // 0 1 2 3 4 5 6 - // | s | s | s | s | s | s | - // |----last window----| - // |----tmp window-----| - base::TimeDelta last_window_queueing_time = - record_queueing_time_client.queueing_time(); - temporary_queueing_time_estimator_state.calculator_.EndStep( - &record_queueing_time_client); - return std::max(last_window_queueing_time, - record_queueing_time_client.queueing_time()); -} - } // namespace scheduler } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h index b31312639d2..7fb95dc6a99 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h @@ -2,15 +2,15 @@ // 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_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_ #include "base/macros.h" #include "base/time/time.h" #include "third_party/blink/public/common/page/launching_process_state.h" #include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_metrics_helper.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_task_queue.h" #include <array> #include <vector> @@ -110,36 +110,9 @@ class PLATFORM_EXPORT QueueingTimeEstimator { FrameStatus current_frame_status_ = FrameStatus::kNone; }; - class State { - public: - explicit State(int steps_per_window); - void OnTopLevelTaskStarted(Client* client, - base::TimeTicks task_start_time, - MainThreadTaskQueue* queue); - void OnTopLevelTaskCompleted(Client* client, base::TimeTicks task_end_time); - void OnBeginNestedRunLoop(); - void OnRendererStateChanged(Client* client, - bool backgrounded, - base::TimeTicks transition_time); - - base::TimeDelta window_step_width; - base::TimeTicks step_start_time; - base::TimeTicks current_task_start_time; - // |renderer_backgrounded| is the renderer's current status. - bool renderer_backgrounded = kLaunchingProcessIsBackgrounded; - bool processing_task = false; - Calculator calculator_; - - private: - void AdvanceTime(Client* client, base::TimeTicks current_time); - bool TimePastStepEnd(base::TimeTicks task_end_time); - bool in_nested_message_loop_ = false; - }; - QueueingTimeEstimator(Client* client, base::TimeDelta window_duration, int steps_per_window); - explicit QueueingTimeEstimator(const State& state); void OnTopLevelTaskStarted(base::TimeTicks task_start_time, MainThreadTaskQueue* queue); @@ -148,15 +121,19 @@ class PLATFORM_EXPORT QueueingTimeEstimator { void OnRendererStateChanged(bool backgrounded, base::TimeTicks transition_time); - // Returns all state except for the current |client_|. - const State& GetState() const { return state_; } - - base::TimeDelta EstimateQueueingTimeIncludingCurrentTask( - base::TimeTicks now) const; - private: + void AdvanceTime(base::TimeTicks current_time); + bool TimePastStepEnd(base::TimeTicks task_end_time); + Client* client_; // NOT OWNED. - State state_; + const base::TimeDelta window_step_width_; + base::TimeTicks step_start_time_; + base::TimeTicks current_task_start_time_; + // |renderer_backgrounded_| is the renderer's current status. + bool renderer_backgrounded_; + bool processing_task_; + bool in_nested_message_loop_; + Calculator calculator_; DISALLOW_ASSIGN(QueueingTimeEstimator); }; @@ -164,4 +141,4 @@ class PLATFORM_EXPORT QueueingTimeEstimator { } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_QUEUEING_TIME_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_QUEUEING_TIME_ESTIMATOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator_unittest.cc index 3e2d5412da0..d842b33411f 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/queueing_time_estimator_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator_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/renderer/platform/scheduler/renderer/queueing_time_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/queueing_time_estimator.h" #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "testing/gmock/include/gmock/gmock.h" @@ -40,8 +40,9 @@ class TestQueueingTimeEstimatorClient : public QueueingTimeEstimator::Client { MainThreadSchedulerImpl::kNumberExpectedQueueingTimeBuckets); } } - void OnReportFineGrainedExpectedQueueingTime(const char* split_description, - base::TimeDelta queueing_time) { + void OnReportFineGrainedExpectedQueueingTime( + const char* split_description, + base::TimeDelta queueing_time) override { if (split_eqts_.find(split_description) == split_eqts_.end()) split_eqts_[split_description] = std::vector<base::TimeDelta>(); split_eqts_[split_description].push_back(queueing_time); @@ -208,138 +209,6 @@ TEST_F(QueueingTimeEstimatorTest, MultiWindowTask) { fine_grained); } -// The main thread is considered unresponsive during a single long task. In this -// case, the single long task is 3 seconds long. -// Probability of being with the task = 3/5. Expected delay within task: -// avg(0, 3). Total expected queueing time = 3/5 * 3/2 = 0.9s. -// In this example, the queueing time comes from the current, incomplete window. -TEST_F(QueueingTimeEstimatorTest, - EstimateQueueingTimeDuringSingleLongTaskIncompleteWindow) { - QueueingTimeEstimatorForTest estimator( - &client, base::TimeDelta::FromSeconds(5), 1, time); - time += base::TimeDelta::FromMilliseconds(5000); - estimator.OnTopLevelTaskStarted(time, nullptr); - estimator.OnTopLevelTaskCompleted(time); - - base::TimeTicks start_time = time; - estimator.OnTopLevelTaskStarted(start_time, nullptr); - - time += base::TimeDelta::FromMilliseconds(3000); - - base::TimeDelta estimated_queueing_time = - estimator.EstimateQueueingTimeIncludingCurrentTask(time); - - EXPECT_EQ(base::TimeDelta::FromMilliseconds(900), estimated_queueing_time); - // Window time was not completed, so no UMA should be recorded. - histogram_tester.ExpectTotalCount( - "RendererScheduler.ExpectedTaskQueueingDuration", 0); - histogram_tester.ExpectTotalCount("ExpectedTaskQueueingDuration2", 0); -} - -// The main thread is considered unresponsive during a single long task, which -// exceeds the size of one window. We report the queueing time of the most -// recent window. Probability of being within the task = 100%, as the task -// fills the whole window. Expected delay within this task = avg(8, 3) = 5.5. -TEST_F(QueueingTimeEstimatorTest, - EstimateQueueingTimeDuringSingleLongTaskExceedingWindow) { - QueueingTimeEstimatorForTest estimator( - &client, base::TimeDelta::FromSeconds(5), 1, time); - time += base::TimeDelta::FromMilliseconds(5000); - estimator.OnTopLevelTaskStarted(time, nullptr); - estimator.OnTopLevelTaskCompleted(time); - - base::TimeTicks start_time = time; - estimator.OnTopLevelTaskStarted(start_time, nullptr); - - time += base::TimeDelta::FromMilliseconds(13000); - - base::TimeDelta estimated_queueing_time = - estimator.EstimateQueueingTimeIncludingCurrentTask(time); - - EXPECT_EQ(base::TimeDelta::FromMilliseconds(5500), estimated_queueing_time); -} - -// Estimate -// | -// v -// Task|------------------------------... -// Time|---o---o---o---o---o---o--------> -// 0 1 2 3 4 5 6 -// | s | s | s | s | s | -// |--------win1-------| -// |--------win2-------| -// -// s: step window -// win1: The last full window. -// win2: The partial window. -// -// EQT(win1) = (0.5 + 5.5) / 2 * (5 / 5) = 3 -// EQT(win2) = (4.5 + 0) / 2 * (4.5 / 5) = 2.025 -// So EQT = max(EQT(win1), EQT(win2)) = 3 -TEST_F(QueueingTimeEstimatorTest, - SlidingWindowEstimateQueueingTimeFullWindowLargerThanPartial) { - QueueingTimeEstimatorForTest estimator( - &client, base::TimeDelta::FromSeconds(5), 5, time); - time += base::TimeDelta::FromMilliseconds(5000); - estimator.OnTopLevelTaskStarted(time, nullptr); - estimator.OnTopLevelTaskCompleted(time); - - base::TimeTicks start_time = time; - estimator.OnTopLevelTaskStarted(start_time, nullptr); - - time += base::TimeDelta::FromMilliseconds(5500); - - base::TimeDelta estimated_queueing_time = - estimator.EstimateQueueingTimeIncludingCurrentTask(time); - - EXPECT_EQ(base::TimeDelta::FromMilliseconds(3000), estimated_queueing_time); - // Only EstimateQueueingTimeIncludingCurrentTask has been called after window - // completion, so UMA should not have been reported yet. - histogram_tester.ExpectTotalCount( - "RendererScheduler.ExpectedTaskQueueingDuration", 0); - histogram_tester.ExpectTotalCount( - "RendererScheduler.ExpectedTaskQueueingDuration3", 0); -} - -// Estimate -// | -// v -// Task |----------... -// Time|---o---o---o---o---o---o--------> -// 0 1 2 3 4 5 6 -// | s | s | s | s | s | -// |--------win1-------| -// |--------win2-------| -// -// s: step window -// win1: The last full window. -// win2: The partial window. -// -// EQT(win1) = 0 -// EQT(win2) = (0 + 0.5) / 2 * (0.5 / 2) = 0.025 -// So EQT = max(EQT(win1), EQT(win2)) = 0.025 -TEST_F(QueueingTimeEstimatorTest, - SlidingWindowEstimateQueueingTimePartialWindowLargerThanFull) { - QueueingTimeEstimatorForTest estimator( - &client, base::TimeDelta::FromSeconds(5), 5, time); - time += base::TimeDelta::FromMilliseconds(5000); - estimator.OnTopLevelTaskStarted(time, nullptr); - estimator.OnTopLevelTaskCompleted(time); - - time += base::TimeDelta::FromMilliseconds(5000); - base::TimeTicks start_time = time; - estimator.OnTopLevelTaskStarted(start_time, nullptr); - time += base::TimeDelta::FromMilliseconds(500); - - base::TimeDelta estimated_queueing_time = - estimator.EstimateQueueingTimeIncludingCurrentTask(time); - - EXPECT_EQ(base::TimeDelta::FromMilliseconds(25), estimated_queueing_time); - std::vector<BucketExpectation> expected = {{0, 1}}; - TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration", 1, expected); - TestHistogram("RendererScheduler.ExpectedTaskQueueingDuration3", 1, expected); -} - // Tasks containing nested run loops may be extremely long without // negatively impacting user experience. Ignore such tasks. TEST_F(QueueingTimeEstimatorTest, IgnoresTasksWithNestedMessageLoops) { @@ -822,7 +691,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByTaskQueueType) { MainThreadTaskQueue* queues_for_thousand[] = {frame_loading_queue.get(), frame_throttleable_queue.get(), unthrottled_queue.get()}; - for (auto queue : queues_for_thousand) { + for (auto* queue : queues_for_thousand) { estimator.OnTopLevelTaskStarted(time, queue); time += base::TimeDelta::FromMilliseconds(1000); estimator.OnTopLevelTaskCompleted(time); @@ -840,7 +709,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByTaskQueueType) { frame_pausable_queue.get(), unthrottled_queue.get(), compositor_queue.get()}; - for (auto queue : queues_for_six_hundred) { + for (auto* queue : queues_for_six_hundred) { estimator.OnTopLevelTaskStarted(time, queue); time += base::TimeDelta::FromMilliseconds(600); estimator.OnTopLevelTaskCompleted(time); @@ -988,7 +857,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { FakeFrameScheduler::Builder() .SetFrameType(FrameScheduler::FrameType::kMainFrame) .Build(); - queue1->SetFrameScheduler(frame1.get()); + queue1->SetFrameSchedulerForTest(frame1.get()); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(3000); estimator.OnTopLevelTaskCompleted(time); @@ -1002,14 +871,14 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { .SetIsPageVisible(true) .SetIsFrameVisible(true) .Build(); - queue1->SetFrameScheduler(frame2.get()); + queue1->SetFrameSchedulerForTest(frame2.get()); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(2000); estimator.OnTopLevelTaskCompleted(time); scoped_refptr<MainThreadTaskQueueForTest> queue2( new MainThreadTaskQueueForTest(QueueType::kTest)); - queue2->SetFrameScheduler(frame2.get()); + queue2->SetFrameSchedulerForTest(frame2.get()); time += base::TimeDelta::FromMilliseconds(1000); estimator.OnTopLevelTaskStarted(time, queue2.get()); time += base::TimeDelta::FromMilliseconds(2000); @@ -1024,7 +893,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { .SetIsFrameVisible(true) .SetIsExemptFromThrottling(true) .Build(); - queue1->SetFrameScheduler(frame3.get()); + queue1->SetFrameSchedulerForTest(frame3.get()); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(3000); estimator.OnTopLevelTaskCompleted(time); @@ -1036,7 +905,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { .SetIsFrameVisible(true) .SetIsExemptFromThrottling(true) .Build(); - queue1->SetFrameScheduler(frame4.get()); + queue1->SetFrameSchedulerForTest(frame4.get()); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(3000); // 1000 ms after beginning of window 4. @@ -1066,8 +935,8 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { .Build(); FakeFrameScheduler* schedulers_for_thousand[] = {frame5.get(), frame6.get(), frame7.get()}; - for (auto scheduler : schedulers_for_thousand) { - queue1->SetFrameScheduler(scheduler); + for (auto* scheduler : schedulers_for_thousand) { + queue1->SetFrameSchedulerForTest(scheduler); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(1000); estimator.OnTopLevelTaskCompleted(time); @@ -1102,8 +971,8 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { FakeFrameScheduler* schedulers_for_four_hundred[] = { frame2.get(), frame1.get(), frame8.get(), frame5.get(), frame6.get(), frame9.get(), frame7.get(), frame10.get(), frame11.get()}; - for (auto scheduler : schedulers_for_four_hundred) { - queue1->SetFrameScheduler(scheduler); + for (auto* scheduler : schedulers_for_four_hundred) { + queue1->SetFrameSchedulerForTest(scheduler); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(400); estimator.OnTopLevelTaskCompleted(time); @@ -1114,7 +983,7 @@ TEST_F(QueueingTimeEstimatorTest, SplitEQTByFrameStatus) { time += base::TimeDelta::FromMilliseconds(300); estimator.OnTopLevelTaskCompleted(time); - queue1->SetFrameScheduler(nullptr); + queue1->DetachFromFrameScheduler(); estimator.OnTopLevelTaskStarted(time, queue1.get()); time += base::TimeDelta::FromMilliseconds(300); estimator.OnTopLevelTaskCompleted(time); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.cc index fc1f0031564..b1f8cb8a296 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.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/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" #include "base/logging.h" #include "base/memory/ptr_util.h" diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h index e19b2133a9d..453e3b69468 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h @@ -2,8 +2,8 @@ // 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_RENDERER_RENDER_WIDGET_SIGNALS_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDER_WIDGET_SIGNALS_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_ #include <memory> @@ -58,4 +58,4 @@ class PLATFORM_EXPORT RenderWidgetSignals { } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDER_WIDGET_SIGNALS_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_RENDER_WIDGET_SIGNALS_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals_unittest.cc index 6e55af040dd..478e09f5e16 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals_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/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" #include "base/macros.h" #include "testing/gmock/include/gmock/gmock.h" @@ -21,7 +21,7 @@ namespace render_widget_signals_unittest { class MockObserver : public RenderWidgetSignals::Observer { public: MockObserver() = default; - virtual ~MockObserver() = default; + ~MockObserver() override = default; MOCK_METHOD1(SetAllRenderWidgetsHidden, void(bool hidden)); MOCK_METHOD1(SetHasVisibleRenderWidgetWithTouchHandler, diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.cc index f9ce0c49a66..0686a1eb0a3 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.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/renderer/platform/scheduler/renderer/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" #include "base/time/default_tick_clock.h" diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h index 2214c772114..c3e54a30e99 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h @@ -2,8 +2,8 @@ // 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_RENDERER_TASK_COST_ESTIMATOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_ #include "base/macros.h" #include "base/message_loop/message_loop.h" @@ -49,4 +49,4 @@ class PLATFORM_EXPORT TaskCostEstimator } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_TASK_COST_ESTIMATOR_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_TASK_COST_ESTIMATOR_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_unittest.cc index 45ff499a9e3..6d7b3bf6331 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/task_cost_estimator_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator_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/renderer/platform/scheduler/renderer/task_cost_estimator.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/task_cost_estimator.h" #include <memory> diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/use_case.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/use_case.h index ce4ad48ebdb..7ab1c4d57b2 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/use_case.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/use_case.h @@ -1,5 +1,5 @@ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USE_CASE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USE_CASE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_ namespace blink { namespace scheduler { @@ -39,4 +39,4 @@ enum class UseCase { } // namespace scheduler } // namespace blink -#endif +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USE_CASE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.cc index aeb7ba5ce40..361b57ef706 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.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/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" namespace blink { namespace scheduler { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model.h b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h index 247acf43847..afbab65cd6e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model.h @@ -2,8 +2,8 @@ // 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_RENDERER_USER_MODEL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USER_MODEL_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_ #include "base/macros.h" #include "base/trace_event/trace_event.h" @@ -83,4 +83,4 @@ class PLATFORM_EXPORT UserModel { } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_USER_MODEL_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_USER_MODEL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model_unittest.cc index 6d75270e750..b0ae0e39635 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/user_model_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/user_model_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/renderer/platform/scheduler/renderer/user_model.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/user_model.h" #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h" diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_main_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_main_thread_scheduler.cc index c04c216cf39..7009683434e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_main_thread_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_main_thread_scheduler.cc @@ -7,7 +7,6 @@ #include <memory> #include "base/command_line.h" #include "base/memory/ptr_util.h" -#include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" #include "base/time/default_tick_clock.h" #include "base/trace_event/trace_event.h" @@ -32,8 +31,9 @@ std::unique_ptr<WebMainThreadScheduler> WebMainThreadScheduler::Create( TRACE_EVENT_WARMUP_CATEGORY(TRACE_DISABLED_BY_DEFAULT("worker.scheduler")); std::unique_ptr<MainThreadSchedulerImpl> scheduler( - new MainThreadSchedulerImpl(TaskQueueManager::TakeOverCurrentThread(), - initial_virtual_time)); + new MainThreadSchedulerImpl( + base::sequence_manager::TaskQueueManager::TakeOverCurrentThread(), + initial_virtual_time)); return base::WrapUnique<WebMainThreadScheduler>(scheduler.release()); } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc index 2cfea4a953d..1b645c396ea 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/main_thread/web_render_widget_scheduling_state.cc @@ -4,7 +4,7 @@ #include "third_party/blink/public/platform/scheduler/web_render_widget_scheduling_state.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/render_widget_signals.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/render_widget_signals.h" namespace blink { namespace scheduler { diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_global_scope_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h index 0de37b8308b..5121a7f7b6a 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_global_scope_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h @@ -2,19 +2,19 @@ // 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_FRAME_OR_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ #include "third_party/blink/renderer/platform/wtf/allocator.h" namespace blink { -// This is the base class of FrameScheduler and WorkerGlobalScopeScheduler. -class FrameOrWorkerGlobalScopeScheduler { - USING_FAST_MALLOC(FrameOrWorkerGlobalScopeScheduler); +// This is the base class of FrameScheduler and WorkerScheduler. +class FrameOrWorkerScheduler { + USING_FAST_MALLOC(FrameOrWorkerScheduler); public: - virtual ~FrameOrWorkerGlobalScopeScheduler() = default; + virtual ~FrameOrWorkerScheduler() = default; class ActiveConnectionHandle { public: @@ -34,4 +34,4 @@ class FrameOrWorkerGlobalScopeScheduler { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_GLOBAL_SCOPE_SCHEDULER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_FRAME_OR_WORKER_SCHEDULER_H_ 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 edebfd1e745..c10e521fcb0 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 @@ -11,27 +11,37 @@ #include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h" -#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_global_scope_scheduler.h" +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { class PageScheduler; -class FrameScheduler : public FrameOrWorkerGlobalScopeScheduler { +class FrameScheduler : public FrameOrWorkerScheduler { public: - virtual ~FrameScheduler() = default; + ~FrameScheduler() override = default; // Observer type that regulates conditions to invoke callbacks. enum class ObserverType { kLoader, kWorkerScheduler }; // Represents throttling state. + // TODO(altimin): Move it into standalone LifecycleState. enum class ThrottlingState { - kThrottled, + // Frame is active and should not be throttled. kNotThrottled, + // Frame has just been backgrounded and can be throttled non-aggressively. + kHidden, + // Frame spent some time in background and can be fully throttled. + kThrottled, + // Frame is stopped, no tasks associated with it can run. kStopped, }; + PLATFORM_EXPORT static const char* ThrottlingStateToString( + ThrottlingState state); + // Represents the type of frame: main (top-level) vs not. enum class FrameType { kMainFrame, @@ -43,7 +53,8 @@ class FrameScheduler : public FrameOrWorkerGlobalScopeScheduler { public: virtual ~Observer() = default; - // Notified when throttling state is changed. + // Notified when throttling state is changed. May be called consecutively + // with the same value. virtual void OnThrottlingStateChanged(ThrottlingState) = 0; }; @@ -72,21 +83,13 @@ class FrameScheduler : public FrameOrWorkerGlobalScopeScheduler { // Query the page visibility state for the page associated with this frame. // The scheduler may throttle tasks associated with pages that are not // visible. + // TODO(altimin): Remove this method. virtual bool IsPageVisible() const = 0; // Set whether this frame is suspended. Only unthrottledTaskRunner tasks are // allowed to run on a suspended frame. virtual void SetPaused(bool) = 0; - // Notifies observers of transitioning to and from FROZEN state in - // background. - virtual void SetPageFrozen(bool) {} - - // Tells the scheduler about "keep-alive" state which can be due to: - // service workers, shared workers, or fetch keep-alive. - // If true, then the scheduler should not freeze relevant task queues. - virtual void SetKeepActive(bool) {} - // Set whether this frame is cross origin w.r.t. the top level frame. Cross // origin frames may use a different scheduling policy from same origin // frames. diff --git a/chromium/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h index a9aca3e3f92..fed347c79a1 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/public/non_main_thread_scheduler.h @@ -8,20 +8,28 @@ #include <memory> #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "third_party/blink/public/platform/scheduler/single_thread_idle_task_runner.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/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/common/thread_scheduler_impl.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/util/tracing_helper.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" namespace blink { namespace scheduler { +class TaskQueueWithTaskType; class WorkerSchedulerProxy; +class WorkerScheduler; +class TaskQueueThrottler; +class WakeUpBudgetPool; -class PLATFORM_EXPORT NonMainThreadScheduler : public WebThreadScheduler { +// TODO(yutak): Rename this class to NonMainThreadSchedulerImpl and consider +// changing all non-impl scheduler classes to have only static methods. +class PLATFORM_EXPORT NonMainThreadScheduler : public ThreadSchedulerImpl { public: ~NonMainThreadScheduler() override; @@ -29,27 +37,102 @@ class PLATFORM_EXPORT NonMainThreadScheduler : public WebThreadScheduler { WebThreadType thread_type, WorkerSchedulerProxy* proxy); + // Same as ThreadScheduler::Current(), but this asserts the caller is on + // a non-main thread. + static NonMainThreadScheduler* Current(); + // Blink should use NonMainThreadScheduler::DefaultTaskQueue instead of // WebThreadScheduler::DefaultTaskRunner. virtual scoped_refptr<WorkerTaskQueue> DefaultTaskQueue() = 0; // Must be called before the scheduler can be used. Does any post construction // initialization needed such as initializing idle period detection. - virtual void Init() = 0; + void Init(); + + virtual void OnTaskCompleted( + WorkerTaskQueue* worker_task_queue, + const base::sequence_manager::TaskQueue::Task& task, + base::TimeTicks start, + base::TimeTicks end, + base::Optional<base::TimeDelta> thread_time) = 0; + + // ThreadSchedulerImpl: + scoped_refptr<base::SingleThreadTaskRunner> ControlTaskRunner() override; + void RegisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) override; + void UnregisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) override; + base::sequence_manager::TimeDomain* GetActiveTimeDomain() override; + const base::TickClock* GetTickClock() override; + + // ThreadScheduler implementation. + // TODO(yutak): Some functions are only meaningful in main thread. Move them + // to MainThreadScheduler. + void PostIdleTask(const base::Location& location, + WebThread::IdleTask task) override; + void PostNonNestableIdleTask(const base::Location& location, + WebThread::IdleTask task) override; + scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() override; + scoped_refptr<base::SingleThreadTaskRunner> CompositorTaskRunner() override; + std::unique_ptr<PageScheduler> CreatePageScheduler( + PageScheduler::Delegate*) override; + std::unique_ptr<RendererPauseHandle> PauseScheduler() override + WARN_UNUSED_RESULT; - virtual void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, - const TaskQueue::Task& task, - base::TimeTicks start, - base::TimeTicks end, - base::Optional<base::TimeDelta> thread_time) = 0; + // Returns TimeTicks::Now() by default. + base::TimeTicks MonotonicallyIncreasingVirtualTime() override; + + NonMainThreadScheduler* AsNonMainThreadScheduler() override { return this; } + + // The following virtual methods are defined in *both* WebThreadScheduler + // and ThreadScheduler, with identical interfaces and semantics. They are + // overriden in a subclass, effectively implementing the virtual methods + // in both classes at the same time. This is allowed in C++, as long as + // there is only one final overrider (i.e. definitions in base classes are + // not used in instantiated objects, since otherwise they may have multiple + // definitions of the virtual function in question). + // + // virtual void Shutdown(); scoped_refptr<WorkerTaskQueue> CreateTaskRunner(); + // TaskQueueThrottler might be null if throttling is not enabled or + // not supported. + TaskQueueThrottler* task_queue_throttler() const { + return task_queue_throttler_.get(); + } + WakeUpBudgetPool* wake_up_budget_pool() const { return wake_up_budget_pool_; } + protected: explicit NonMainThreadScheduler( - std::unique_ptr<WorkerSchedulerHelper> helper); + std::unique_ptr<NonMainThreadSchedulerHelper> helper); + + friend class WorkerScheduler; + + // Each WorkerScheduler should notify NonMainThreadScheduler when it is + // created or destroyed. + virtual void RegisterWorkerScheduler(WorkerScheduler* worker_scheduler); + virtual void UnregisterWorkerScheduler(WorkerScheduler* worker_scheduler); + + // Called during Init() for delayed initialization for subclasses. + virtual void InitImpl() = 0; + + // This controller should be initialized before any TraceableVariables + // because they require one to initialize themselves. + TraceableVariableController traceable_variable_controller_; + + std::unique_ptr<NonMainThreadSchedulerHelper> helper_; + + // Worker schedulers associated with this thread. + std::unordered_set<WorkerScheduler*> worker_schedulers_; + + std::unique_ptr<TaskQueueThrottler> task_queue_throttler_; + // Owned by |task_queue_throttler_|. + WakeUpBudgetPool* wake_up_budget_pool_ = nullptr; - std::unique_ptr<WorkerSchedulerHelper> helper_; + private: + static void RunIdleTask(WebThread::IdleTask task, base::TimeTicks deadline); + scoped_refptr<TaskQueueWithTaskType> v8_task_runner_; DISALLOW_COPY_AND_ASSIGN(NonMainThreadScheduler); }; 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 fdec4b71f7f..c0cf79d9dff 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 @@ -94,6 +94,11 @@ class PLATFORM_EXPORT PageScheduler { kDeterministicLoading, }; + // This is used to set initial Date.now() while in virtual time mode. + virtual void SetInitialVirtualTime(base::Time time) = 0; + + // This is used for cross origin navigations to account for virtual time + // advancing in the previous renderer. virtual void SetInitialVirtualTimeOffset(base::TimeDelta offset) = 0; // Sets the virtual time policy, which is applied imemdiatly to all child @@ -136,7 +141,7 @@ class PLATFORM_EXPORT PageScheduler { virtual void AudioStateChanged(bool is_audio_playing) = 0; - virtual bool IsPlayingAudio() const = 0; + virtual bool IsAudioPlaying() const = 0; // Returns true if the page should be exempted from aggressive throttling // (e.g. due to a page maintaining an active connection). diff --git a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h index 9d6a22cdcce..5166bd66dcf 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/child/web_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h @@ -2,11 +2,12 @@ // 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_CHILD_WEB_SCHEDULER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEB_SCHEDULER_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_SCHEDULER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_SCHEDULER_H_ #include <memory> #include "base/location.h" +#include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "third_party/blink/public/platform/scheduler/web_main_thread_scheduler.h" @@ -14,16 +15,25 @@ #include "third_party/blink/renderer/platform/scheduler/public/page_scheduler.h" namespace blink { +namespace scheduler { +class NonMainThreadScheduler; +} // This class is used to submit tasks and pass other information from Blink to // the platform's scheduler. // TODO(skyostil): Replace this class with WebMainThreadScheduler. -class PLATFORM_EXPORT WebScheduler { +class PLATFORM_EXPORT ThreadScheduler { public: using RendererPauseHandle = scheduler::WebMainThreadScheduler::RendererPauseHandle; - virtual ~WebScheduler() = default; + // Return the current thread's ThreadScheduler. + // + // TODO(yutak): Replace all the "Platform::Current()->CurrentThread() + // ->Scheduler()" calls in Blink with this. + static ThreadScheduler* Current(); + + virtual ~ThreadScheduler() = default; // Called to prevent any more pending tasks from running. Must be called on // the associated WebThread. @@ -42,7 +52,7 @@ class PLATFORM_EXPORT WebScheduler { // its deadline has expired - post a new idle task for the continuation of // the work in this case. // Must be called from the associated WebThread. - virtual bool CanExceedIdleDeadlineIfRequired() = 0; + virtual bool CanExceedIdleDeadlineIfRequired() const = 0; // Schedule an idle task to run the associated WebThread. For non-critical // tasks which may be reordered relative to other task types and may be @@ -59,12 +69,13 @@ class PLATFORM_EXPORT WebScheduler { WebThread::IdleTask) = 0; // Returns a task runner for kV8 tasks. Can be called from any thread. - virtual base::SingleThreadTaskRunner* V8TaskRunner() = 0; + virtual scoped_refptr<base::SingleThreadTaskRunner> V8TaskRunner() = 0; // Returns a task runner for compositor tasks. This is intended only to be // used by specific animation and rendering related tasks (e.g. animated GIFS) // and should not generally be used. - virtual base::SingleThreadTaskRunner* CompositorTaskRunner() = 0; + virtual scoped_refptr<base::SingleThreadTaskRunner> + CompositorTaskRunner() = 0; // Creates a new PageScheduler for a given Page. Must be called from the // associated WebThread. @@ -76,18 +87,17 @@ class PLATFORM_EXPORT WebScheduler { virtual std::unique_ptr<RendererPauseHandle> PauseScheduler() WARN_UNUSED_RESULT = 0; - // Tells the scheduler that a navigation task is pending. - // TODO(alexclarke): Long term should this be a task trait? - virtual void AddPendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType) = 0; - - // Tells the scheduler that a navigation task is no longer pending. - virtual void RemovePendingNavigation( - scheduler::WebMainThreadScheduler::NavigatingFrameType) = 0; - // Returns the current time recognized by the scheduler, which may perhaps // be based on a real or virtual time domain. Used by Timer. - virtual base::TimeTicks MonotonicallyIncreasingVirtualTime() const = 0; + virtual base::TimeTicks MonotonicallyIncreasingVirtualTime() = 0; + + // Adds or removes a task observer from the scheduler. The observer will be + // notified before and after every executed task. These functions can only be + // called on the thread this scheduler was created on. + virtual void AddTaskObserver( + base::MessageLoop::TaskObserver* task_observer) = 0; + virtual void RemoveTaskObserver( + base::MessageLoop::TaskObserver* task_observer) = 0; // Test helpers. @@ -98,8 +108,10 @@ class PLATFORM_EXPORT WebScheduler { GetWebMainThreadSchedulerForTest() { return nullptr; } + + virtual scheduler::NonMainThreadScheduler* AsNonMainThreadScheduler() = 0; }; } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_CHILD_WEB_SCHEDULER_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_THREAD_SCHEDULER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/frame_status.cc b/chromium/third_party/blink/renderer/platform/scheduler/renderer/frame_status.cc index c4ef05aafe5..da08cbdaa7e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/frame_status.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/renderer/frame_status.cc @@ -41,7 +41,7 @@ FrameThrottlingState GetFrameThrottlingState( } PageScheduler* page_scheduler = frame_scheduler.GetPageScheduler(); - if (page_scheduler && page_scheduler->IsPlayingAudio()) { + if (page_scheduler && page_scheduler->IsAudioPlaying()) { if (frame_scheduler.IsFrameVisible()) return FrameThrottlingState::kVisibleService; return FrameThrottlingState::kHiddenService; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.cc b/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.cc deleted file mode 100644 index 4e0fa795827..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.cc +++ /dev/null @@ -1,61 +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/renderer/renderer_web_scheduler_impl.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" -#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h" - -namespace blink { -namespace scheduler { - -// TODO(kraynov): Ditch kDeprecatedNone here. -RendererWebSchedulerImpl::RendererWebSchedulerImpl( - MainThreadSchedulerImpl* main_thread_scheduler) - : WebSchedulerImpl(main_thread_scheduler, - main_thread_scheduler->IdleTaskRunner(), - main_thread_scheduler->V8TaskQueue()), - main_thread_scheduler_(main_thread_scheduler), - compositor_task_runner_( - TaskRunnerImpl::Create(main_thread_scheduler_->CompositorTaskQueue(), - TaskType::kDeprecatedNone)) {} - -RendererWebSchedulerImpl::~RendererWebSchedulerImpl() = default; - -base::SingleThreadTaskRunner* RendererWebSchedulerImpl::CompositorTaskRunner() { - return compositor_task_runner_.get(); -} - -std::unique_ptr<RendererWebSchedulerImpl::RendererPauseHandle> -RendererWebSchedulerImpl::PauseScheduler() { - return main_thread_scheduler_->PauseRenderer(); -} - -std::unique_ptr<blink::PageScheduler> -RendererWebSchedulerImpl::CreatePageScheduler( - PageScheduler::Delegate* delegate) { - return base::WrapUnique( - new PageSchedulerImpl(delegate, main_thread_scheduler_, - !blink::RuntimeEnabledFeatures:: - TimerThrottlingForBackgroundTabsEnabled())); -} - -base::TimeTicks RendererWebSchedulerImpl::MonotonicallyIncreasingVirtualTime() - const { - return main_thread_scheduler_->GetActiveTimeDomain()->Now(); -} - -WebMainThreadScheduler* -RendererWebSchedulerImpl::GetWebMainThreadSchedulerForTest() { - return main_thread_scheduler_; -} - -} // namespace scheduler -} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.h b/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.h deleted file mode 100644 index d0cffbd4c2b..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.h +++ /dev/null @@ -1,41 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_WEB_SCHEDULER_IMPL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_WEB_SCHEDULER_IMPL_H_ - -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler_impl.h" - -namespace blink { -namespace scheduler { - -class MainThreadSchedulerImpl; - -class PLATFORM_EXPORT RendererWebSchedulerImpl : public WebSchedulerImpl { - public: - explicit RendererWebSchedulerImpl( - MainThreadSchedulerImpl* main_thread_scheduler); - - ~RendererWebSchedulerImpl() override; - - // WebScheduler implementation: - base::SingleThreadTaskRunner* CompositorTaskRunner() override; - std::unique_ptr<RendererPauseHandle> PauseScheduler() override - WARN_UNUSED_RESULT; - std::unique_ptr<PageScheduler> CreatePageScheduler( - PageScheduler::Delegate*) override; - - base::TimeTicks MonotonicallyIncreasingVirtualTime() const override; - - WebMainThreadScheduler* GetWebMainThreadSchedulerForTest() override; - - private: - MainThreadSchedulerImpl* main_thread_scheduler_; // NOT OWNED - scoped_refptr<TaskRunnerImpl> compositor_task_runner_; -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_RENDERER_RENDERER_WEB_SCHEDULER_IMPL_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc index 087c9c2e138..3b31822773e 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.cc @@ -7,15 +7,13 @@ #include "base/location.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/renderer_web_scheduler_impl.h" namespace blink { namespace scheduler { WebThreadImplForRendererScheduler::WebThreadImplForRendererScheduler( MainThreadSchedulerImpl* scheduler) - : web_scheduler_(new RendererWebSchedulerImpl(scheduler)), - task_runner_(scheduler->DefaultTaskQueue()), + : task_runner_(scheduler->DefaultTaskRunner()), idle_task_runner_(scheduler->IdleTaskRunner()), scheduler_(scheduler), thread_id_(base::PlatformThread::CurrentId()) {} @@ -27,8 +25,8 @@ blink::PlatformThreadId WebThreadImplForRendererScheduler::ThreadId() const { return thread_id_; } -blink::WebScheduler* WebThreadImplForRendererScheduler::Scheduler() const { - return web_scheduler_.get(); +blink::ThreadScheduler* WebThreadImplForRendererScheduler::Scheduler() const { + return scheduler_; } SingleThreadIdleTaskRunner* @@ -52,12 +50,12 @@ void WebThreadImplForRendererScheduler::RemoveTaskObserverInternal( } void WebThreadImplForRendererScheduler::AddTaskTimeObserverInternal( - TaskTimeObserver* task_time_observer) { + base::sequence_manager::TaskTimeObserver* task_time_observer) { scheduler_->AddTaskTimeObserver(task_time_observer); } void WebThreadImplForRendererScheduler::RemoveTaskTimeObserverInternal( - TaskTimeObserver* task_time_observer) { + base::sequence_manager::TaskTimeObserver* task_time_observer) { scheduler_->RemoveTaskTimeObserver(task_time_observer); } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h index cb637c5a7df..478b78f0d18 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler.h @@ -7,17 +7,17 @@ #include "base/memory/scoped_refptr.h" #include "base/message_loop/message_loop.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/scheduler/child/webthread_base.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { -class WebScheduler; +class ThreadScheduler; }; namespace blink { namespace scheduler { class MainThreadSchedulerImpl; -class WebSchedulerImpl; class PLATFORM_EXPORT WebThreadImplForRendererScheduler : public WebThreadBase { public: @@ -26,7 +26,7 @@ class PLATFORM_EXPORT WebThreadImplForRendererScheduler : public WebThreadBase { ~WebThreadImplForRendererScheduler() override; // WebThread implementation. - WebScheduler* Scheduler() const override; + ThreadScheduler* Scheduler() const override; PlatformThreadId ThreadId() const override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override; @@ -40,10 +40,11 @@ class PLATFORM_EXPORT WebThreadImplForRendererScheduler : public WebThreadBase { void RemoveTaskObserverInternal( base::MessageLoop::TaskObserver* observer) override; - void AddTaskTimeObserverInternal(TaskTimeObserver*) override; - void RemoveTaskTimeObserverInternal(TaskTimeObserver*) override; + void AddTaskTimeObserverInternal( + base::sequence_manager::TaskTimeObserver*) override; + void RemoveTaskTimeObserverInternal( + base::sequence_manager::TaskTimeObserver*) override; - std::unique_ptr<WebSchedulerImpl> web_scheduler_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; MainThreadSchedulerImpl* scheduler_; // Not owned. diff --git a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc index f10992d66b4..c8d0f6e04b9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc @@ -15,8 +15,8 @@ #include "base/test/simple_test_tick_clock.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" namespace blink { namespace scheduler { @@ -43,10 +43,10 @@ class WebThreadImplForRendererSchedulerTest : public testing::Test { void SetUp() override { clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); scheduler_.reset(new MainThreadSchedulerImpl( - TaskQueueManagerForTest::Create(&message_loop_, - message_loop_.task_runner(), &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + &message_loop_, message_loop_.task_runner(), &clock_), base::nullopt)); - default_task_runner_ = scheduler_->DefaultTaskQueue(); + default_task_runner_ = scheduler_->DefaultTaskRunner(); thread_ = scheduler_->CreateMainThread(); } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc index d8df0ceae74..f24c42380d4 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.cc @@ -17,14 +17,6 @@ const char kTracingCategoryNameInfo[] = const char kTracingCategoryNameDebug[] = TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.debug"); -namespace { - -// No trace events should be created with this category. -const char kTracingCategoryNameVerboseSnapshots[] = - TRACE_DISABLED_BY_DEFAULT("renderer.scheduler.enable_verbose_snapshots"); - -} // namespace - namespace internal { void ValidateTracingCategory(const char* category) { @@ -40,19 +32,11 @@ void ValidateTracingCategory(const char* category) { } // namespace internal -bool AreVerboseSnapshotsEnabled() { - bool result = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(kTracingCategoryNameVerboseSnapshots, - &result); - return result; -} - void WarmupTracingCategories() { // No need to warm-up toplevel category here. TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameDefault); TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameInfo); TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameDebug); - TRACE_EVENT_WARMUP_CATEGORY(kTracingCategoryNameVerboseSnapshots); } std::string PointerToString(const void* pointer) { @@ -92,7 +76,7 @@ void TraceableVariableController::DeregisterTraceableVariable( } void TraceableVariableController::OnTraceLogEnabled() { - for (auto tracer : traceable_variables_) { + for (auto* tracer : traceable_variables_) { tracer->OnTraceLogEnabled(); } } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h index f9d4647b013..75e41431faa 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/util/tracing_helper.h @@ -34,8 +34,6 @@ PLATFORM_EXPORT void ValidateTracingCategory(const char* category); PLATFORM_EXPORT void WarmupTracingCategories(); -PLATFORM_EXPORT bool AreVerboseSnapshotsEnabled(); - PLATFORM_EXPORT std::string PointerToString(const void* pointer); PLATFORM_EXPORT double TimeDeltaToMilliseconds(const base::TimeDelta& value); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc index 1d1d37ee582..9da0528370f 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.cc @@ -15,7 +15,7 @@ WebThreadImplForUtilityThread::WebThreadImplForUtilityThread() WebThreadImplForUtilityThread::~WebThreadImplForUtilityThread() = default; -blink::WebScheduler* WebThreadImplForUtilityThread::Scheduler() const { +blink::ThreadScheduler* WebThreadImplForUtilityThread::Scheduler() const { NOTIMPLEMENTED(); return nullptr; } diff --git a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h index b6316416bfc..2228317522d 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h +++ b/chromium/third_party/blink/renderer/platform/scheduler/utility/webthread_impl_for_utility_thread.h @@ -7,6 +7,7 @@ #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "base/single_thread_task_runner.h" #include "third_party/blink/public/platform/scheduler/child/webthread_base.h" #include "third_party/blink/renderer/platform/platform_export.h" @@ -20,7 +21,7 @@ class PLATFORM_EXPORT WebThreadImplForUtilityThread ~WebThreadImplForUtilityThread() override; // WebThread implementation. - WebScheduler* Scheduler() const override; + ThreadScheduler* Scheduler() const override; PlatformThreadId ThreadId() const override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() const override; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc index 4e7ea136d11..2ff477006a3 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler.cc @@ -11,7 +11,9 @@ #include "base/message_loop/message_loop.h" #include "base/threading/thread.h" #include "base/threading/thread_task_runner_handle.h" +#include "third_party/blink/public/platform/task_type.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" namespace blink { @@ -19,11 +21,16 @@ namespace scheduler { CompositorThreadScheduler::CompositorThreadScheduler( base::Thread* thread, - std::unique_ptr<TaskQueueManager> task_queue_manager) - : NonMainThreadScheduler( - std::make_unique<WorkerSchedulerHelper>(std::move(task_queue_manager), - this)), - thread_(thread) {} + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager) + : NonMainThreadScheduler(std::make_unique<NonMainThreadSchedulerHelper>( + std::move(task_queue_manager), + this, + TaskType::kCompositorThreadTaskQueueDefault)), + thread_(thread), + default_task_runner_(TaskQueueWithTaskType::Create( + DefaultTaskQueue(), + TaskType::kCompositorThreadTaskQueueDefault)) {} CompositorThreadScheduler::~CompositorThreadScheduler() = default; @@ -31,11 +38,11 @@ scoped_refptr<WorkerTaskQueue> CompositorThreadScheduler::DefaultTaskQueue() { return helper_->DefaultWorkerTaskQueue(); } -void CompositorThreadScheduler::Init() {} +void CompositorThreadScheduler::InitImpl() {} void CompositorThreadScheduler::OnTaskCompleted( WorkerTaskQueue* worker_task_queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) { @@ -45,7 +52,7 @@ void CompositorThreadScheduler::OnTaskCompleted( scoped_refptr<base::SingleThreadTaskRunner> CompositorThreadScheduler::DefaultTaskRunner() { - return DefaultTaskQueue(); + return default_task_runner_; } scoped_refptr<scheduler::SingleThreadIdleTaskRunner> 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 8768e3b4af8..40b0819c71a 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 @@ -28,20 +28,20 @@ class PLATFORM_EXPORT CompositorThreadScheduler public: CompositorThreadScheduler( base::Thread* thread, - std::unique_ptr<TaskQueueManager> task_queue_manager); + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager); ~CompositorThreadScheduler() override; - // WorkerScheduler: + // NonMainThreadScheduler: scoped_refptr<WorkerTaskQueue> DefaultTaskQueue() override; - void Init() override; void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) override; - // ChildScheduler: + // WebThreadScheduler: scoped_refptr<base::SingleThreadTaskRunner> DefaultTaskRunner() override; scoped_refptr<scheduler::SingleThreadIdleTaskRunner> IdleTaskRunner() override; @@ -59,10 +59,15 @@ class PLATFORM_EXPORT CompositorThreadScheduler void DidProcessIdleTask() override; base::TimeTicks NowTicks() override; + protected: + // NonMainThreadScheduler: + void InitImpl() override; + private: base::Thread* thread_; CompositorMetricsHelper compositor_metrics_helper_; + scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; DISALLOW_COPY_AND_ASSIGN(CompositorThreadScheduler); }; diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc index 506fda0a632..627184f05e9 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler.cc @@ -6,31 +6,135 @@ #include <utility> -#include "base/message_loop/message_loop.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/wake_up_budget_pool.h" #include "third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.h" namespace blink { namespace scheduler { NonMainThreadScheduler::NonMainThreadScheduler( - std::unique_ptr<WorkerSchedulerHelper> helper) + std::unique_ptr<NonMainThreadSchedulerHelper> helper) : helper_(std::move(helper)) {} -NonMainThreadScheduler::~NonMainThreadScheduler() = default; +NonMainThreadScheduler::~NonMainThreadScheduler() { + DCHECK(worker_schedulers_.empty()); +} // static std::unique_ptr<NonMainThreadScheduler> NonMainThreadScheduler::Create( WebThreadType thread_type, WorkerSchedulerProxy* proxy) { return std::make_unique<WorkerThreadScheduler>( - thread_type, TaskQueueManager::TakeOverCurrentThread(), proxy); + thread_type, + base::sequence_manager::TaskQueueManager::TakeOverCurrentThread(), proxy); +} + +// static +NonMainThreadScheduler* NonMainThreadScheduler::Current() { + DCHECK_NE(Platform::Current()->CurrentThread(), + Platform::Current()->MainThread()); + return ThreadScheduler::Current()->AsNonMainThreadScheduler(); +} + +void NonMainThreadScheduler::Init() { + InitImpl(); + + // DefaultTaskQueue() is a virtual function, so it can't be called in the + // constructor. Also, DefaultTaskQueue() checks if InitImpl() is called. + // Therefore, v8_task_runner_ needs to be initialized here. + v8_task_runner_ = TaskQueueWithTaskType::Create( + DefaultTaskQueue(), TaskType::kMainThreadTaskQueueV8); } scoped_refptr<WorkerTaskQueue> NonMainThreadScheduler::CreateTaskRunner() { helper_->CheckOnValidThread(); - return helper_->NewTaskQueue(TaskQueue::Spec("worker_tq") - .SetShouldMonitorQuiescence(true) - .SetTimeDomain(nullptr)); + return helper_->NewTaskQueue( + base::sequence_manager::TaskQueue::Spec("worker_tq") + .SetShouldMonitorQuiescence(true) + .SetTimeDomain(nullptr)); +} + +void NonMainThreadScheduler::RunIdleTask(blink::WebThread::IdleTask task, + base::TimeTicks deadline) { + std::move(task).Run((deadline - base::TimeTicks()).InSecondsF()); +} + +void NonMainThreadScheduler::PostIdleTask(const base::Location& location, + blink::WebThread::IdleTask task) { + IdleTaskRunner()->PostIdleTask( + location, + base::BindOnce(&NonMainThreadScheduler::RunIdleTask, std::move(task))); +} + +void NonMainThreadScheduler::PostNonNestableIdleTask( + const base::Location& location, + blink::WebThread::IdleTask task) { + IdleTaskRunner()->PostNonNestableIdleTask( + location, + base::BindOnce(&NonMainThreadScheduler::RunIdleTask, std::move(task))); +} + +scoped_refptr<base::SingleThreadTaskRunner> +NonMainThreadScheduler::V8TaskRunner() { + return v8_task_runner_; +} + +scoped_refptr<base::SingleThreadTaskRunner> +NonMainThreadScheduler::CompositorTaskRunner() { + return nullptr; +} + +std::unique_ptr<blink::PageScheduler> +NonMainThreadScheduler::CreatePageScheduler(PageScheduler::Delegate* delegate) { + NOTREACHED(); + return nullptr; +} + +std::unique_ptr<NonMainThreadScheduler::RendererPauseHandle> +NonMainThreadScheduler::PauseScheduler() { + return nullptr; +} + +base::TimeTicks NonMainThreadScheduler::MonotonicallyIncreasingVirtualTime() { + return base::TimeTicks::Now(); +} + +void NonMainThreadScheduler::RegisterWorkerScheduler( + WorkerScheduler* worker_scheduler) { + worker_schedulers_.insert(worker_scheduler); +} + +void NonMainThreadScheduler::UnregisterWorkerScheduler( + WorkerScheduler* worker_scheduler) { + DCHECK(worker_schedulers_.find(worker_scheduler) != worker_schedulers_.end()); + worker_schedulers_.erase(worker_scheduler); +} + +scoped_refptr<base::SingleThreadTaskRunner> +NonMainThreadScheduler::ControlTaskRunner() { + return helper_->ControlWorkerTaskQueue(); +} + +void NonMainThreadScheduler::RegisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) { + return helper_->RegisterTimeDomain(time_domain); +} + +void NonMainThreadScheduler::UnregisterTimeDomain( + base::sequence_manager::TimeDomain* time_domain) { + return helper_->UnregisterTimeDomain(time_domain); +} + +base::sequence_manager::TimeDomain* +NonMainThreadScheduler::GetActiveTimeDomain() { + return helper_->real_time_domain(); +} + +const base::TickClock* NonMainThreadScheduler::GetTickClock() { + return helper_->GetClock(); } } // namespace scheduler diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.cc b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc index e66380e2f93..dd674be044b 100644 --- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.cc +++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.cc @@ -2,47 +2,56 @@ // 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/worker/worker_scheduler_helper.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" +#include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h" namespace blink { namespace scheduler { -WorkerSchedulerHelper::WorkerSchedulerHelper( - std::unique_ptr<TaskQueueManager> task_queue_manager, - NonMainThreadScheduler* non_main_thread_scheduler) +using base::sequence_manager::TaskQueue; + +NonMainThreadSchedulerHelper::NonMainThreadSchedulerHelper( + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, + NonMainThreadScheduler* non_main_thread_scheduler, + TaskType default_task_type) : SchedulerHelper(std::move(task_queue_manager)), non_main_thread_scheduler_(non_main_thread_scheduler), default_task_queue_(NewTaskQueue(TaskQueue::Spec("worker_default_tq") .SetShouldMonitorQuiescence(true))), control_task_queue_(NewTaskQueue(TaskQueue::Spec("worker_control_tq") .SetShouldNotifyObservers(false))) { - InitDefaultQueues(default_task_queue_, control_task_queue_); + InitDefaultQueues(default_task_queue_, control_task_queue_, + default_task_type); } -WorkerSchedulerHelper::~WorkerSchedulerHelper() { +NonMainThreadSchedulerHelper::~NonMainThreadSchedulerHelper() { control_task_queue_->ShutdownTaskQueue(); default_task_queue_->ShutdownTaskQueue(); } -scoped_refptr<WorkerTaskQueue> WorkerSchedulerHelper::DefaultWorkerTaskQueue() { +scoped_refptr<WorkerTaskQueue> +NonMainThreadSchedulerHelper::DefaultWorkerTaskQueue() { return default_task_queue_; } -scoped_refptr<TaskQueue> WorkerSchedulerHelper::DefaultTaskQueue() { +scoped_refptr<TaskQueue> NonMainThreadSchedulerHelper::DefaultTaskQueue() { return default_task_queue_; } -scoped_refptr<WorkerTaskQueue> WorkerSchedulerHelper::ControlWorkerTaskQueue() { +scoped_refptr<WorkerTaskQueue> +NonMainThreadSchedulerHelper::ControlWorkerTaskQueue() { return control_task_queue_; } -scoped_refptr<TaskQueue> WorkerSchedulerHelper::ControlTaskQueue() { +scoped_refptr<TaskQueue> NonMainThreadSchedulerHelper::ControlTaskQueue() { return control_task_queue_; } -scoped_refptr<WorkerTaskQueue> WorkerSchedulerHelper::NewTaskQueue( +scoped_refptr<WorkerTaskQueue> NonMainThreadSchedulerHelper::NewTaskQueue( const TaskQueue::Spec& spec) { return task_queue_manager_->CreateTaskQueue<WorkerTaskQueue>( spec, non_main_thread_scheduler_); diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h new file mode 100644 index 00000000000..8613de252ae --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h @@ -0,0 +1,47 @@ +// 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_SCHEDULER_WORKER_NON_MAIN_THREAD_SCHEDULER_HELPER_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_SCHEDULER_HELPER_H_ + +#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" + +#include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h" + +namespace blink { +namespace scheduler { + +class NonMainThreadScheduler; + +class PLATFORM_EXPORT NonMainThreadSchedulerHelper : public SchedulerHelper { + public: + NonMainThreadSchedulerHelper( + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, + NonMainThreadScheduler* non_main_thread_scheduler, + TaskType default_task_type); + ~NonMainThreadSchedulerHelper() override; + + scoped_refptr<WorkerTaskQueue> NewTaskQueue( + const base::sequence_manager::TaskQueue::Spec& spec); + + scoped_refptr<WorkerTaskQueue> DefaultWorkerTaskQueue(); + scoped_refptr<WorkerTaskQueue> ControlWorkerTaskQueue(); + + protected: + scoped_refptr<base::sequence_manager::TaskQueue> DefaultTaskQueue() override; + scoped_refptr<base::sequence_manager::TaskQueue> ControlTaskQueue() override; + + private: + NonMainThreadScheduler* non_main_thread_scheduler_; // NOT OWNED + const scoped_refptr<WorkerTaskQueue> default_task_queue_; + const scoped_refptr<WorkerTaskQueue> control_task_queue_; + + DISALLOW_COPY_AND_ASSIGN(NonMainThreadSchedulerHelper); +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_NON_MAIN_THREAD_SCHEDULER_HELPER_H_ diff --git a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h b/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h deleted file mode 100644 index 895fbd44f97..00000000000 --- a/chromium/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h +++ /dev/null @@ -1,43 +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_SCHEDULER_WORKER_WORKER_SCHEDULER_HELPER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_WORKER_SCHEDULER_HELPER_H_ - -#include "third_party/blink/renderer/platform/scheduler/common/scheduler_helper.h" - -#include "third_party/blink/renderer/platform/scheduler/child/worker_task_queue.h" - -namespace blink { -namespace scheduler { - -class NonMainThreadScheduler; - -class PLATFORM_EXPORT WorkerSchedulerHelper : public SchedulerHelper { - public: - WorkerSchedulerHelper(std::unique_ptr<TaskQueueManager> manager, - NonMainThreadScheduler* non_main_thread_scheduler); - ~WorkerSchedulerHelper() override; - - scoped_refptr<WorkerTaskQueue> NewTaskQueue(const TaskQueue::Spec& spec); - - scoped_refptr<WorkerTaskQueue> DefaultWorkerTaskQueue(); - scoped_refptr<WorkerTaskQueue> ControlWorkerTaskQueue(); - - protected: - scoped_refptr<TaskQueue> DefaultTaskQueue() override; - scoped_refptr<TaskQueue> ControlTaskQueue() override; - - private: - NonMainThreadScheduler* non_main_thread_scheduler_; // NOT OWNED - const scoped_refptr<WorkerTaskQueue> default_task_queue_; - const scoped_refptr<WorkerTaskQueue> control_task_queue_; - - DISALLOW_COPY_AND_ASSIGN(WorkerSchedulerHelper); -}; - -} // namespace scheduler -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_WORKER_SCHEDULER_HELPER_H_ 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 ad0fb1866db..65d1854cd35 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 @@ -15,12 +15,18 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" #include "third_party/blink/renderer/platform/scheduler/child/default_params.h" -#include "third_party/blink/renderer/platform/scheduler/worker/worker_scheduler_helper.h" +#include "third_party/blink/renderer/platform/scheduler/child/features.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" +#include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/child/worker_scheduler_proxy.h" +#include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h" +#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_helper.h" namespace blink { namespace scheduler { +using base::sequence_manager::TaskQueue; + namespace { // Workers could be short-lived, set a shorter interval than // the renderer thread. @@ -47,11 +53,13 @@ base::TimeTicks MonotonicTimeInSecondsToTimeTicks( WorkerThreadScheduler::WorkerThreadScheduler( WebThreadType thread_type, - std::unique_ptr<TaskQueueManager> task_queue_manager, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, WorkerSchedulerProxy* proxy) - : NonMainThreadScheduler( - std::make_unique<WorkerSchedulerHelper>(std::move(task_queue_manager), - this)), + : NonMainThreadScheduler(std::make_unique<NonMainThreadSchedulerHelper>( + std::move(task_queue_manager), + this, + TaskType::kWorkerThreadTaskQueueDefault)), idle_helper_(helper_.get(), this, "WorkerSchedulerIdlePeriod", @@ -65,6 +73,9 @@ WorkerThreadScheduler::WorkerThreadScheduler( throttling_state_(proxy ? proxy->throttling_state() : FrameScheduler::ThrottlingState::kNotThrottled), worker_metrics_helper_(thread_type), + default_task_runner_(TaskQueueWithTaskType::Create( + helper_->DefaultWorkerTaskQueue(), + TaskType::kWorkerThreadTaskQueueDefault)), weak_factory_(this) { thread_start_time_ = helper_->NowTicks(); load_tracker_.Resume(thread_start_time_); @@ -75,6 +86,11 @@ WorkerThreadScheduler::WorkerThreadScheduler( proxy->OnWorkerSchedulerCreated(GetWeakPtr()); } + if (thread_type == WebThreadType::kDedicatedWorkerThread && + base::FeatureList::IsEnabled(kDedicatedWorkerThrottling)) { + CreateTaskQueueThrottler(); + } + TRACE_EVENT_OBJECT_CREATED_WITH_ID( TRACE_DISABLED_BY_DEFAULT("worker.scheduler"), "WorkerScheduler", this); } @@ -88,8 +104,7 @@ WorkerThreadScheduler::~WorkerThreadScheduler() { scoped_refptr<base::SingleThreadTaskRunner> WorkerThreadScheduler::DefaultTaskRunner() { - DCHECK(initialized_); - return helper_->DefaultWorkerTaskQueue(); + return default_task_runner_; } scoped_refptr<SingleThreadIdleTaskRunner> @@ -137,6 +152,7 @@ void WorkerThreadScheduler::Shutdown() { UMA_HISTOGRAM_CUSTOM_TIMES( "WorkerThread.Runtime", delta, base::TimeDelta::FromSeconds(1), base::TimeDelta::FromDays(1), 50 /* bucket count */); + task_queue_throttler_.reset(); helper_->Shutdown(); } @@ -145,7 +161,7 @@ scoped_refptr<WorkerTaskQueue> WorkerThreadScheduler::DefaultTaskQueue() { return helper_->DefaultWorkerTaskQueue(); } -void WorkerThreadScheduler::Init() { +void WorkerThreadScheduler::InitImpl() { initialized_ = true; idle_helper_.EnableLongIdlePeriod(); } @@ -186,7 +202,18 @@ void WorkerThreadScheduler::DidProcessTask(double start_time, double end_time) { void WorkerThreadScheduler::OnThrottlingStateChanged( FrameScheduler::ThrottlingState throttling_state) { + if (throttling_state_ == throttling_state) + return; throttling_state_ = throttling_state; + + for (WorkerScheduler* worker_scheduler : worker_schedulers_) + worker_scheduler->OnThrottlingStateChanged(throttling_state); +} + +void WorkerThreadScheduler::RegisterWorkerScheduler( + WorkerScheduler* worker_scheduler) { + NonMainThreadScheduler::RegisterWorkerScheduler(worker_scheduler); + worker_scheduler->OnThrottlingStateChanged(throttling_state_); } scoped_refptr<WorkerTaskQueue> WorkerThreadScheduler::ControlTaskQueue() { @@ -197,5 +224,14 @@ base::WeakPtr<WorkerThreadScheduler> WorkerThreadScheduler::GetWeakPtr() { return weak_factory_.GetWeakPtr(); } +void WorkerThreadScheduler::CreateTaskQueueThrottler() { + if (task_queue_throttler_) + return; + task_queue_throttler_ = std::make_unique<TaskQueueThrottler>( + this, &traceable_variable_controller_); + wake_up_budget_pool_ = + task_queue_throttler_->CreateWakeUpBudgetPool("worker_wake_up_pool"); +} + } // namespace scheduler } // namespace blink 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 7391e257bfe..4bc59994057 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 @@ -19,19 +19,27 @@ #include "third_party/blink/renderer/platform/scheduler/util/task_duration_metric_reporter.h" #include "third_party/blink/renderer/platform/scheduler/util/thread_load_tracker.h" +namespace base { +namespace sequence_manager { +class TaskQueueManager; +} +} // namespace base + namespace blink { namespace scheduler { -class TaskQueueManager; class WorkerSchedulerProxy; -class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadScheduler, - public IdleHelper::Delegate, - public TaskTimeObserver { +class PLATFORM_EXPORT WorkerThreadScheduler + : public NonMainThreadScheduler, + public IdleHelper::Delegate, + public base::sequence_manager::TaskTimeObserver { public: - WorkerThreadScheduler(WebThreadType thread_type, - std::unique_ptr<TaskQueueManager> task_queue_manager, - WorkerSchedulerProxy* proxy); + WorkerThreadScheduler( + WebThreadType thread_type, + std::unique_ptr<base::sequence_manager::TaskQueueManager> + task_queue_manager, + WorkerSchedulerProxy* proxy); ~WorkerThreadScheduler() override; // WebThreadScheduler implementation: @@ -47,9 +55,8 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadScheduler, // NonMainThreadScheduler implementation: scoped_refptr<WorkerTaskQueue> DefaultTaskQueue() override; - void Init() override; void OnTaskCompleted(WorkerTaskQueue* worker_task_queue, - const TaskQueue::Task& task, + const base::sequence_manager::TaskQueue::Task& task, base::TimeTicks start, base::TimeTicks end, base::Optional<base::TimeDelta> thread_time) override; @@ -71,6 +78,9 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadScheduler, scoped_refptr<WorkerTaskQueue> ControlTaskQueue(); protected: + // NonMainThreadScheduler implementation: + void InitImpl() override; + // IdleHelper::Delegate implementation: bool CanEnterLongIdlePeriod( base::TimeTicks now, @@ -84,6 +94,10 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadScheduler, return throttling_state_; } + void RegisterWorkerScheduler(WorkerScheduler* worker_scheduler) override; + + void CreateTaskQueueThrottler(); + private: void MaybeStartLongIdlePeriod(); @@ -99,6 +113,8 @@ class PLATFORM_EXPORT WorkerThreadScheduler : public NonMainThreadScheduler, WorkerMetricsHelper worker_metrics_helper_; + scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; + base::WeakPtrFactory<WorkerThreadScheduler> weak_factory_; DISALLOW_COPY_AND_ASSIGN(WorkerThreadScheduler); 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 fe4fb13d42a..f2f9a1d7f29 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 @@ -12,7 +12,7 @@ #include "components/viz/test/ordered_simple_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" using testing::ElementsAreArray; @@ -52,8 +52,9 @@ void TimelineIdleTestTask(std::vector<std::string>* timeline, class WorkerThreadSchedulerForTest : public WorkerThreadScheduler { public: - WorkerThreadSchedulerForTest(std::unique_ptr<TaskQueueManager> manager, - base::SimpleTestTickClock* clock_) + WorkerThreadSchedulerForTest( + std::unique_ptr<base::sequence_manager::TaskQueueManager> manager, + base::SimpleTestTickClock* clock_) : WorkerThreadScheduler(WebThreadType::kTestThread, std::move(manager), nullptr), @@ -93,9 +94,10 @@ class WorkerThreadSchedulerTest : public testing::Test { WorkerThreadSchedulerTest() : mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)), scheduler_(new WorkerThreadSchedulerForTest( - TaskQueueManagerForTest::Create(nullptr, - mock_task_runner_, - &clock_), + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, + mock_task_runner_, + &clock_), &clock_)), timeline_(nullptr) { clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); diff --git a/chromium/third_party/blink/renderer/platform/scroll/DEPS b/chromium/third_party/blink/renderer/platform/scroll/DEPS index 8d825ff202e..4ae5c6e0ec8 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/DEPS +++ b/chromium/third_party/blink/renderer/platform/scroll/DEPS @@ -1,4 +1,25 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/scroll", + + # Dependencies. "+cc", - "-cc/blink", + "+third_party/blink/renderer/platform/animation", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/layout_test_support.h", + "+third_party/blink/renderer/platform/mac", + "+third_party/blink/renderer/platform/platform_chrome_client.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h", + "+third_party/blink/renderer/platform/timer.h", + "+third_party/blink/renderer/platform/transforms/transformation_matrix.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc b/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc index 95f4ff79908..ee1eb0892b5 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.cc @@ -6,7 +6,6 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/animation/compositor_scroll_offset_animation_curve.h" #include "third_party/blink/renderer/platform/geometry/int_size.h" diff --git a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h b/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h index 6a62d95b80c..150fac9da5c 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h +++ b/chromium/third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h @@ -32,7 +32,7 @@ class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator { return new ProgrammaticScrollAnimator(scrollable_area); } - virtual ~ProgrammaticScrollAnimator(); + ~ProgrammaticScrollAnimator() override; void ScrollToOffsetWithoutAnimation(const ScrollOffset&, bool is_sequenced_scroll); @@ -52,7 +52,7 @@ class ProgrammaticScrollAnimator : public ScrollAnimatorCompositorCoordinator { void LayerForCompositedScrollingDidChange( CompositorAnimationTimeline*) override; - void Trace(blink::Visitor*); + void Trace(blink::Visitor*) override; private: explicit ProgrammaticScrollAnimator(ScrollableArea*); diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc index 57675df549e..f6b0f889b8a 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.cc @@ -31,10 +31,11 @@ #include "third_party/blink/renderer/platform/scroll/scroll_animator.h" #include <memory> + #include "base/memory/scoped_refptr.h" #include "cc/animation/scroll_offset_animation_curve.h" +#include "cc/layers/layer.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/renderer/platform/animation/compositor_keyframe_model.h" #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" @@ -46,8 +47,8 @@ namespace blink { namespace { -WebLayer* ToWebLayer(GraphicsLayer* layer) { - return layer ? layer->PlatformLayer() : nullptr; +cc::Layer* ToCcLayer(GraphicsLayer* layer) { + return layer ? layer->CcLayer() : nullptr; } } // namespace @@ -161,7 +162,8 @@ bool ScrollAnimator::WillAnimateToOffset(const ScrollOffset& target_offset) { DCHECK(run_state_ == RunState::kRunningOnMainThread || run_state_ == RunState::kRunningOnCompositor || run_state_ == RunState::kRunningOnCompositorButNeedsUpdate || - run_state_ == RunState::kRunningOnCompositorButNeedsTakeover); + run_state_ == RunState::kRunningOnCompositorButNeedsTakeover || + run_state_ == RunState::kRunningOnCompositorButNeedsAdjustment); // Running on the main thread, simply update the target offset instead // of sending to the compositor. @@ -369,16 +371,16 @@ void ScrollAnimator::AddMainThreadScrollingReason() { // is a special case because its subframes cannot be scrolled // when the reason is set. When the subframes are ready to scroll // the reason has benn reset. - if (WebLayer* scroll_layer = - ToWebLayer(GetScrollableArea()->LayerForScrolling())) { + if (cc::Layer* scroll_layer = + ToCcLayer(GetScrollableArea()->LayerForScrolling())) { scroll_layer->AddMainThreadScrollingReasons( MainThreadScrollingReason::kHandlingScrollFromMainThread); } } void ScrollAnimator::RemoveMainThreadScrollingReason() { - if (WebLayer* scroll_layer = - ToWebLayer(GetScrollableArea()->LayerForScrolling())) { + if (cc::Layer* scroll_layer = + ToCcLayer(GetScrollableArea()->LayerForScrolling())) { scroll_layer->ClearMainThreadScrollingReasons( MainThreadScrollingReason::kHandlingScrollFromMainThread); } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h index 0ebcf411a9b..ef0292bd759 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator.h @@ -124,7 +124,7 @@ class PLATFORM_EXPORT ScrollAnimator : public ScrollAnimatorBase { void LayerForCompositedScrollingDidChange( CompositorAnimationTimeline*) override; - virtual void Trace(blink::Visitor*); + void Trace(blink::Visitor*) override; protected: // Returns whether or not the animation was sent to the compositor. diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h index 8db422f137d..6f7c3321727 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_base.h @@ -55,7 +55,7 @@ class PLATFORM_EXPORT ScrollAnimatorBase public: static ScrollAnimatorBase* Create(ScrollableArea*); - virtual ~ScrollAnimatorBase(); + ~ScrollAnimatorBase() override; virtual void Dispose() {} @@ -111,7 +111,7 @@ class PLATFORM_EXPORT ScrollAnimatorBase virtual bool SetScrollbarsVisibleForTesting(bool) { return false; } - virtual void Trace(blink::Visitor*); + void Trace(blink::Visitor*) override; protected: explicit ScrollAnimatorBase(ScrollableArea*); diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc index 48cb9f9df65..2d1541d2676 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.cc @@ -5,9 +5,9 @@ #include "third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h" #include <memory> + #include "cc/animation/scroll_offset_animation_curve.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/renderer/platform/animation/compositor_animation.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_host.h" #include "third_party/blink/renderer/platform/animation/compositor_animation_timeline.h" @@ -250,7 +250,7 @@ CompositorElementId ScrollAnimatorCompositorCoordinator::GetScrollElementId() return GetScrollableArea()->GetCompositorElementId(); GraphicsLayer* layer = GetScrollableArea()->LayerForScrolling(); - return layer ? layer->PlatformLayer()->GetElementId() : CompositorElementId(); + return layer ? layer->CcLayer()->element_id() : CompositorElementId(); } void ScrollAnimatorCompositorCoordinator::UpdateImplOnlyCompositorAnimations() { diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h index a40156f6e52..949bada88dc 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_compositor_coordinator.h @@ -83,7 +83,7 @@ class PLATFORM_EXPORT ScrollAnimatorCompositorCoordinator kRunningOnCompositorButNeedsAdjustment, }; - virtual ~ScrollAnimatorCompositorCoordinator(); + ~ScrollAnimatorCompositorCoordinator() override; bool HasAnimationThatRequiresService() const; void Dispose(); diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc index 617e7d68075..f228ae00944 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_animator_test.cc @@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/scroll/scroll_animator.h" +#include "base/single_thread_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" @@ -34,7 +35,7 @@ #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scroll/scroll_animator_base.h" #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" @@ -111,9 +112,10 @@ class MockScrollableAreaForAnimatorTest return ScrollableArea::GetScrollOffset(); } - void SetScrollOffset(const ScrollOffset& offset, - ScrollType type, - ScrollBehavior behavior = kScrollBehaviorInstant) { + void SetScrollOffset( + const ScrollOffset& offset, + ScrollType type, + ScrollBehavior behavior = kScrollBehaviorInstant) override { if (animator) animator->SetCurrentOffset(offset); ScrollableArea::SetScrollOffset(offset, type, behavior); @@ -131,7 +133,7 @@ class MockScrollableAreaForAnimatorTest return ScrollbarTheme::DeprecatedStaticGetTheme(); } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(animator); ScrollableArea::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h b/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h index db12b84734d..9215523cb35 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scroll_types.h @@ -27,6 +27,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLL_TYPES_H_ #include "third_party/blink/public/platform/web_gesture_event.h" +#include "third_party/blink/public/platform/web_scroll_types.h" #include "third_party/blink/renderer/platform/geometry/float_point.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -52,17 +53,8 @@ enum OverlayScrollbarClipBehavior { kExcludeOverlayScrollbarSizeForHitTesting }; -enum ScrollDirection { - kScrollUpIgnoringWritingMode, - kScrollDownIgnoringWritingMode, - kScrollLeftIgnoringWritingMode, - kScrollRightIgnoringWritingMode, - - kScrollBlockDirectionBackward, - kScrollBlockDirectionForward, - kScrollInlineDirectionBackward, - kScrollInlineDirectionForward -}; +using ScrollDirection = WebScrollDirection; +using ScrollGranularity = WebScrollGranularity; enum ScrollDirectionPhysical { kScrollUp, @@ -169,14 +161,6 @@ inline ScrollDirection ToScrollDirection(ScrollDirectionPhysical direction) { return kScrollUpIgnoringWritingMode; } -enum ScrollGranularity { - kScrollByLine, - kScrollByPage, - kScrollByDocument, - kScrollByPixel, - kScrollByPrecisePixel -}; - enum ScrollInertialPhase { kScrollInertialPhaseUnknown, kScrollInertialPhaseNonMomentum, diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc index c1ca05cb131..1fe39e6590c 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.cc @@ -36,7 +36,7 @@ #include "third_party/blink/renderer/platform/graphics/graphics_layer.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/platform_chrome_client.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scroll/main_thread_scrolling_reason.h" #include "third_party/blink/renderer/platform/scroll/programmatic_scroll_animator.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" @@ -158,6 +158,9 @@ float ScrollableArea::ScrollStep(ScrollGranularity granularity, ScrollResult ScrollableArea::UserScroll(ScrollGranularity granularity, const ScrollOffset& delta) { + TRACE_EVENT2("input", "ScrollableArea::UserScroll", "x", delta.Width(), "y", + delta.Height()); + float step_x = ScrollStep(granularity, kHorizontalScrollbar); float step_y = ScrollStep(granularity, kVerticalScrollbar); @@ -574,7 +577,7 @@ void ScrollableArea::CancelProgrammaticScrollAnimation() { bool ScrollableArea::ShouldScrollOnMainThread() const { if (GraphicsLayer* layer = LayerForScrolling()) { - uint32_t reasons = layer->PlatformLayer()->MainThreadScrollingReasons(); + uint32_t reasons = layer->CcLayer()->main_thread_scrolling_reasons(); // Should scroll on main thread unless the reason is the one that is set // by the ScrollAnimator, in which case, the animation can still be // scheduled on the compositor. diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h index b03b1aa6348..323bc8307c9 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area.h @@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLABLE_AREA_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLABLE_AREA_H_ +#include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/platform/geometry/float_quad.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" #include "third_party/blink/renderer/platform/graphics/color.h" @@ -156,7 +157,7 @@ class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin { } // See Source/core/layout/README.md for an explanation of scroll origin. - const IntPoint& ScrollOrigin() const { return scroll_origin_; } + virtual IntPoint ScrollOrigin() const { return scroll_origin_; } bool ScrollOriginChanged() const { return scroll_origin_changed_; } // This is used to determine whether the incoming fractional scroll offset @@ -373,7 +374,7 @@ class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin { // Need to promptly let go of owned animator objects. EAGERLY_FINALIZE(); - virtual void Trace(blink::Visitor*); + void Trace(blink::Visitor*) override; virtual void ClearScrollableArea(); @@ -492,7 +493,7 @@ class PLATFORM_EXPORT ScrollableArea : public GarbageCollectedMixin { unsigned mouse_over_scrollbar_ : 1; // Indicates that the next compositing update needs to call - // WebLayer::showScrollbars on our scroll layer. Ignored if not composited. + // cc::Layer::ShowScrollbars() on our scroll layer. Ignored if not composited. unsigned needs_show_scrollbar_layers_ : 1; unsigned uses_composited_scrolling_ : 1; diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc index 56443fae40e..b959f8a2afe 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollable_area_test.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" +#include "base/message_loop/message_loop.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/platform.h" @@ -29,7 +30,7 @@ class ScrollbarThemeWithMockInvalidation : public ScrollbarThemeMock { public: MOCK_CONST_METHOD0(ShouldRepaintAllPartsOnInvalidation, bool()); MOCK_CONST_METHOD3(InvalidateOnThumbPositionChange, - ScrollbarPart(const ScrollbarThemeClient&, float, float)); + ScrollbarPart(const Scrollbar&, float, float)); }; } // namespace @@ -103,7 +104,7 @@ TEST_F(ScrollableAreaTest, ScrollbarGraphicsLayerInvalidation) { graphics_layer_client.SetIsTrackingRasterInvalidations(true); FakeGraphicsLayer graphics_layer(graphics_layer_client); graphics_layer.SetDrawsContent(true); - graphics_layer.SetSize(FloatSize(111, 222)); + graphics_layer.SetSize(IntSize(111, 222)); EXPECT_CALL(*scrollable_area, LayerForHorizontalScrollbar()) .WillRepeatedly(Return(&graphics_layer)); @@ -187,10 +188,10 @@ TEST_F(ScrollableAreaTest, InvalidatesCompositedScrollbarsIfPartsNeedRepaint) { graphics_layer_client.SetIsTrackingRasterInvalidations(true); FakeGraphicsLayer layer_for_horizontal_scrollbar(graphics_layer_client); layer_for_horizontal_scrollbar.SetDrawsContent(true); - layer_for_horizontal_scrollbar.SetSize(FloatSize(10, 10)); + layer_for_horizontal_scrollbar.SetSize(IntSize(10, 10)); FakeGraphicsLayer layer_for_vertical_scrollbar(graphics_layer_client); layer_for_vertical_scrollbar.SetDrawsContent(true); - layer_for_vertical_scrollbar.SetSize(FloatSize(10, 10)); + layer_for_vertical_scrollbar.SetSize(IntSize(10, 10)); EXPECT_CALL(*scrollable_area, LayerForHorizontalScrollbar()) .WillRepeatedly(Return(&layer_for_horizontal_scrollbar)); EXPECT_CALL(*scrollable_area, LayerForVerticalScrollbar()) diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc index ffca17fb668..4b885d81259 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar.cc @@ -28,7 +28,7 @@ #include <algorithm> #include "third_party/blink/public/platform/web_gesture_event.h" #include "third_party/blink/public/platform/web_mouse_event.h" -#include "third_party/blink/public/platform/web_scrollbar.h" +#include "third_party/blink/public/platform/web_scrollbar_overlay_color_theme.h" #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/graphics/paint/cull_rect.h" #include "third_party/blink/renderer/platform/platform_chrome_client.h" @@ -636,33 +636,6 @@ void Scrollbar::SetNeedsPaintInvalidation(ScrollbarPart invalid_parts) { scrollable_area_->SetScrollbarNeedsPaintInvalidation(Orientation()); } -STATIC_ASSERT_ENUM(WebScrollbar::ScrollingMode::kAuto, kScrollbarAuto); -STATIC_ASSERT_ENUM(WebScrollbar::ScrollingMode::kAlwaysOff, - kScrollbarAlwaysOff); -STATIC_ASSERT_ENUM(WebScrollbar::ScrollingMode::kAlwaysOn, kScrollbarAlwaysOn); - -STATIC_ASSERT_ENUM(WebScrollbar::kHorizontal, kHorizontalScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kVertical, kVerticalScrollbar); - -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByLine, kScrollByLine); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByPage, kScrollByPage); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByDocument, kScrollByDocument); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollByPixel, kScrollByPixel); - -STATIC_ASSERT_ENUM(WebScrollbar::kRegularScrollbar, kRegularScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kSmallScrollbar, kSmallScrollbar); -STATIC_ASSERT_ENUM(WebScrollbar::kNoPart, kNoPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackButtonStartPart, kBackButtonStartPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardButtonStartPart, - kForwardButtonStartPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackTrackPart, kBackTrackPart); -STATIC_ASSERT_ENUM(WebScrollbar::kThumbPart, kThumbPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardTrackPart, kForwardTrackPart); -STATIC_ASSERT_ENUM(WebScrollbar::kBackButtonEndPart, kBackButtonEndPart); -STATIC_ASSERT_ENUM(WebScrollbar::kForwardButtonEndPart, kForwardButtonEndPart); -STATIC_ASSERT_ENUM(WebScrollbar::kScrollbarBGPart, kScrollbarBGPart); -STATIC_ASSERT_ENUM(WebScrollbar::kTrackBGPart, kTrackBGPart); -STATIC_ASSERT_ENUM(WebScrollbar::kAllParts, kAllParts); STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeDark, kScrollbarOverlayColorThemeDark); STATIC_ASSERT_ENUM(kWebScrollbarOverlayColorThemeLight, diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h index 82099a11f94..20eac35e4ac 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar.h @@ -29,7 +29,6 @@ #include "third_party/blink/renderer/platform/graphics/paint/display_item.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/scroll/scroll_types.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h" #include "third_party/blink/renderer/platform/timer.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -45,7 +44,6 @@ class WebGestureEvent; class WebMouseEvent; class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>, - public ScrollbarThemeClient, public DisplayItemClient { public: static Scrollbar* Create(ScrollableArea* scrollable_area, @@ -66,41 +64,40 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>, ~Scrollbar() override; - // ScrollbarThemeClient implementation. - int X() const override { return frame_rect_.X(); } - int Y() const override { return frame_rect_.Y(); } - int Width() const override { return frame_rect_.Width(); } - int Height() const override { return frame_rect_.Height(); } - IntSize Size() const override { return frame_rect_.Size(); } - IntPoint Location() const override { return frame_rect_.Location(); } + int X() const { return frame_rect_.X(); } + int Y() const { return frame_rect_.Y(); } + int Width() const { return frame_rect_.Width(); } + int Height() const { return frame_rect_.Height(); } + IntSize Size() const { return frame_rect_.Size(); } + IntPoint Location() const { return frame_rect_.Location(); } void SetFrameRect(const IntRect&); - IntRect FrameRect() const override { return frame_rect_; } + const IntRect& FrameRect() const { return frame_rect_; } - ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const override; - void GetTickmarks(Vector<IntRect>&) const override; - bool IsScrollableAreaActive() const override; + ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const; + void GetTickmarks(Vector<IntRect>&) const; + bool IsScrollableAreaActive() const; - IntPoint ConvertFromRootFrame(const IntPoint&) const override; + IntPoint ConvertFromRootFrame(const IntPoint&) const; - bool IsCustomScrollbar() const override { return false; } - ScrollbarOrientation Orientation() const override { return orientation_; } - bool IsLeftSideVerticalScrollbar() const override; + virtual bool IsCustomScrollbar() const { return false; } + ScrollbarOrientation Orientation() const { return orientation_; } + bool IsLeftSideVerticalScrollbar() const; - int Value() const override { return lroundf(current_pos_); } - float CurrentPos() const override { return current_pos_; } - int VisibleSize() const override { return visible_size_; } - int TotalSize() const override { return total_size_; } - int Maximum() const override { return total_size_ - visible_size_; } - ScrollbarControlSize GetControlSize() const override { return control_size_; } + int Value() const { return lroundf(current_pos_); } + float CurrentPos() const { return current_pos_; } + int VisibleSize() const { return visible_size_; } + int TotalSize() const { return total_size_; } + int Maximum() const { return total_size_ - visible_size_; } + ScrollbarControlSize GetControlSize() const { return control_size_; } - ScrollbarPart PressedPart() const override { return pressed_part_; } - ScrollbarPart HoveredPart() const override { return hovered_part_; } + ScrollbarPart PressedPart() const { return pressed_part_; } + ScrollbarPart HoveredPart() const { return hovered_part_; } - void StyleChanged() override {} - void SetScrollbarsHiddenIfOverlay(bool) override; - bool Enabled() const override { return enabled_; } - void SetEnabled(bool) override; + virtual void StyleChanged() {} + void SetScrollbarsHiddenIfOverlay(bool); + bool Enabled() const { return enabled_; } + virtual void SetEnabled(bool); // This returns device-scale-factor-aware pixel value. // e.g. 15 in dsf=1.0, 30 in dsf=2.0. @@ -125,7 +122,7 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>, void Paint(GraphicsContext&, const CullRect&) const; - bool IsOverlayScrollbar() const override; + virtual bool IsOverlayScrollbar() const; bool ShouldParticipateInHitTesting(); bool IsWindowActive() const; @@ -155,8 +152,8 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>, void MoveThumb(int pos, bool dragging_document = false); - float ElasticOverscroll() const override { return elastic_overscroll_; } - void SetElasticOverscroll(float elastic_overscroll) override { + float ElasticOverscroll() const { return elastic_overscroll_; } + void SetElasticOverscroll(float elastic_overscroll) { elastic_overscroll_ = elastic_overscroll; } @@ -234,11 +231,6 @@ class PLATFORM_EXPORT Scrollbar : public GarbageCollectedFinalized<Scrollbar>, float elastic_overscroll_; private: - void Invalidate() override { SetNeedsPaintInvalidation(kAllParts); } - void InvalidateRect(const IntRect&) override { - SetNeedsPaintInvalidation(kAllParts); - } - float ScrollableAreaCurrentPos() const; float ScrollableAreaTargetPos() const; bool ThumbWillBeUnderMouse() const; diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc new file mode 100644 index 00000000000..322ef7247bd --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.cc @@ -0,0 +1,173 @@ +// 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/scroll/scrollbar_layer_delegate.h" + +#include "third_party/blink/public/platform/web_point.h" +#include "third_party/blink/public/platform/web_rect.h" +#include "third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h" +#include "third_party/blink/renderer/platform/scroll/scroll_types.h" +#include "third_party/blink/renderer/platform/scroll/scrollbar.h" +#include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" +#include "ui/gfx/skia_util.h" + +namespace blink { + +namespace { + +class ScopedScrollbarPainter { + public: + ScopedScrollbarPainter(cc::PaintCanvas& canvas, float device_scale_factor) + : canvas_(canvas) { + builder_.Context().SetDeviceScaleFactor(device_scale_factor); + } + ~ScopedScrollbarPainter() { canvas_.drawPicture(builder_.EndRecording()); } + + GraphicsContext& Context() { return builder_.Context(); } + + private: + cc::PaintCanvas& canvas_; + PaintRecordBuilder builder_; +}; + +} // namespace + +ScrollbarLayerDelegate::ScrollbarLayerDelegate(blink::Scrollbar& scrollbar, + float device_scale_factor) + : scrollbar_(&scrollbar), + theme_(scrollbar.GetTheme()), + device_scale_factor_(device_scale_factor) {} + +ScrollbarLayerDelegate::~ScrollbarLayerDelegate() = default; + +cc::ScrollbarOrientation ScrollbarLayerDelegate::Orientation() const { + if (scrollbar_->Orientation() == kHorizontalScrollbar) + return cc::HORIZONTAL; + return cc::VERTICAL; +} + +bool ScrollbarLayerDelegate::IsLeftSideVerticalScrollbar() const { + return scrollbar_->IsLeftSideVerticalScrollbar(); +} + +bool ScrollbarLayerDelegate::HasThumb() const { + return theme_.HasThumb(*scrollbar_); +} + +bool ScrollbarLayerDelegate::IsOverlay() const { + return scrollbar_->IsOverlayScrollbar(); +} + +gfx::Point ScrollbarLayerDelegate::Location() const { + return scrollbar_->Location(); +} + +int ScrollbarLayerDelegate::ThumbThickness() const { + IntRect thumb_rect = theme_.ThumbRect(*scrollbar_); + if (scrollbar_->Orientation() == kHorizontalScrollbar) + return thumb_rect.Height(); + return thumb_rect.Width(); +} + +int ScrollbarLayerDelegate::ThumbLength() const { + IntRect thumb_rect = theme_.ThumbRect(*scrollbar_); + if (scrollbar_->Orientation() == kHorizontalScrollbar) + return thumb_rect.Width(); + return thumb_rect.Height(); +} + +gfx::Rect ScrollbarLayerDelegate::TrackRect() const { + return theme_.TrackRect(*scrollbar_); +} + +float ScrollbarLayerDelegate::ThumbOpacity() const { + return theme_.ThumbOpacity(*scrollbar_); +} + +bool ScrollbarLayerDelegate::NeedsPaintPart(cc::ScrollbarPart part) const { + if (part == cc::THUMB) + return scrollbar_->ThumbNeedsRepaint(); + return scrollbar_->TrackNeedsRepaint(); +} + +bool ScrollbarLayerDelegate::UsesNinePatchThumbResource() const { + return theme_.UsesNinePatchThumbResource(); +} + +gfx::Size ScrollbarLayerDelegate::NinePatchThumbCanvasSize() const { + DCHECK(theme_.UsesNinePatchThumbResource()); + return static_cast<gfx::Size>(theme_.NinePatchThumbCanvasSize(*scrollbar_)); +} + +gfx::Rect ScrollbarLayerDelegate::NinePatchThumbAperture() const { + DCHECK(theme_.UsesNinePatchThumbResource()); + return theme_.NinePatchThumbAperture(*scrollbar_); +} + +bool ScrollbarLayerDelegate::HasTickmarks() const { + Vector<IntRect> tickmarks; + scrollbar_->GetTickmarks(tickmarks); + return !tickmarks.IsEmpty(); +} + +void ScrollbarLayerDelegate::PaintPart(cc::PaintCanvas* canvas, + cc::ScrollbarPart part, + const gfx::Rect& content_rect) { + PaintCanvasAutoRestore auto_restore(canvas, true); + blink::Scrollbar& scrollbar = *scrollbar_; + + if (part == cc::THUMB) { + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + theme_.PaintThumb(painter.Context(), scrollbar, IntRect(content_rect)); + if (!theme_.ShouldRepaintAllPartsOnInvalidation()) + scrollbar.ClearThumbNeedsRepaint(); + return; + } + + if (part == cc::TICKMARKS) { + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + theme_.PaintTickmarks(painter.Context(), scrollbar, IntRect(content_rect)); + return; + } + + canvas->clipRect(gfx::RectToSkRect(content_rect)); + ScopedScrollbarPainter painter(*canvas, device_scale_factor_); + GraphicsContext& context = painter.Context(); + + theme_.PaintScrollbarBackground(context, scrollbar); + + if (theme_.HasButtons(scrollbar)) { + theme_.PaintButton(context, scrollbar, + theme_.BackButtonRect(scrollbar, kBackButtonStartPart), + kBackButtonStartPart); + theme_.PaintButton(context, scrollbar, + theme_.BackButtonRect(scrollbar, kBackButtonEndPart), + kBackButtonEndPart); + theme_.PaintButton( + context, scrollbar, + theme_.ForwardButtonRect(scrollbar, kForwardButtonStartPart), + kForwardButtonStartPart); + theme_.PaintButton( + context, scrollbar, + theme_.ForwardButtonRect(scrollbar, kForwardButtonEndPart), + kForwardButtonEndPart); + } + + IntRect track_paint_rect = theme_.TrackRect(scrollbar); + theme_.PaintTrackBackground(context, scrollbar, track_paint_rect); + + if (theme_.HasThumb(scrollbar)) { + theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect, + kForwardTrackPart); + theme_.PaintTrackPiece(painter.Context(), scrollbar, track_paint_rect, + kBackTrackPart); + } + + theme_.PaintTickmarks(painter.Context(), scrollbar, track_paint_rect); + + if (!theme_.ShouldRepaintAllPartsOnInvalidation()) + scrollbar.ClearTrackNeedsRepaint(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h new file mode 100644 index 00000000000..819ce5bd3ef --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_layer_delegate.h @@ -0,0 +1,62 @@ +// 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_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_ + +#include <memory> + +#include "base/macros.h" +#include "cc/input/scrollbar.h" +#include "cc/paint/paint_canvas.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/platform_export.h" + +namespace blink { + +class Scrollbar; +class ScrollbarTheme; + +// Implementation of cc::Scrollbar, providing a delegate to query about +// scrollbar state and to paint the image in the scrollbar. +class PLATFORM_EXPORT ScrollbarLayerDelegate : public cc::Scrollbar { + public: + ScrollbarLayerDelegate(blink::Scrollbar& scrollbar, + float device_scale_factor); + ~ScrollbarLayerDelegate() override; + + // cc::Scrollbar implementation. + cc::ScrollbarOrientation Orientation() const override; + bool IsLeftSideVerticalScrollbar() const override; + bool HasThumb() const override; + bool IsOverlay() const override; + gfx::Point Location() const override; + int ThumbThickness() const override; + int ThumbLength() const override; + gfx::Rect TrackRect() const override; + float ThumbOpacity() const override; + bool NeedsPaintPart(cc::ScrollbarPart part) const override; + bool HasTickmarks() const override; + void PaintPart(cc::PaintCanvas* canvas, + cc::ScrollbarPart part, + const gfx::Rect& content_rect) override; + + bool UsesNinePatchThumbResource() const override; + gfx::Size NinePatchThumbCanvasSize() const override; + gfx::Rect NinePatchThumbAperture() const override; + + private: + // Accessed by main and compositor threads, e.g., the compositor thread + // checks |Orientation()|. + CrossThreadPersistent<blink::Scrollbar> scrollbar_; + + ScrollbarTheme& theme_; + float device_scale_factor_; + + DISALLOW_COPY_AND_ASSIGN(ScrollbarLayerDelegate); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_LAYER_DELEGATE_H_ diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h index 0292b6bbc75..3101387404b 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h @@ -6,13 +6,14 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_TEST_SUITE_H_ #include <memory> +#include "base/single_thread_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/platform_chrome_client.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/scroll/scrollbar.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h" @@ -27,17 +28,8 @@ class MockPlatformChromeClient : public PlatformChromeClient { void SetIsPopup(bool is_popup) { is_popup_ = is_popup; } - void InvalidateRect(const IntRect&) override {} - - IntRect ViewportToScreen(const IntRect&, - const PlatformFrameView*) const override { - return IntRect(); - } - float WindowToViewportScalar(const float) const override { return 0; } - void ScheduleAnimation(const PlatformFrameView*) override {} - private: bool is_popup_; }; @@ -90,7 +82,7 @@ class MockScrollableArea : public GarbageCollectedFinalized<MockScrollableArea>, } bool ScrollAnimatorEnabled() const override { return false; } int PageStep(ScrollbarOrientation) const override { return 0; } - void ScrollControlWasSetNeedsPaintInvalidation() {} + void ScrollControlWasSetNeedsPaintInvalidation() override {} void SetScrollOrigin(const IntPoint& origin) { ScrollableArea::SetScrollOrigin(origin); } @@ -114,7 +106,7 @@ class MockScrollableArea : public GarbageCollectedFinalized<MockScrollableArea>, using ScrollableArea::VerticalScrollbarNeedsPaintInvalidation; using ScrollableArea::ClearNeedsPaintInvalidationForScrollControls; - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(chrome_client_); ScrollableArea::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc index d45f26cf4b0..4ca6b6a7dc0 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.cc @@ -25,6 +25,7 @@ #include "third_party/blink/renderer/platform/scroll/scrollbar_theme.h" +#include "base/optional.h" #include "build/build_config.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_mouse_event.h" @@ -42,7 +43,6 @@ #include "third_party/blink/renderer/platform/scroll/scrollbar.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #if !defined(OS_MACOSX) #include "third_party/blink/public/platform/web_theme_engine.h" @@ -141,7 +141,7 @@ bool ScrollbarTheme::Paint(const Scrollbar& scrollbar, return true; } -ScrollbarPart ScrollbarTheme::HitTest(const ScrollbarThemeClient& scrollbar, +ScrollbarPart ScrollbarTheme::HitTest(const Scrollbar& scrollbar, const IntPoint& position_in_root_frame) { ScrollbarPart result = kNoPart; if (!scrollbar.Enabled()) @@ -209,7 +209,7 @@ void ScrollbarTheme::PaintScrollCorner( #endif } -bool ScrollbarTheme::ShouldCenterOnThumb(const ScrollbarThemeClient& scrollbar, +bool ScrollbarTheme::ShouldCenterOnThumb(const Scrollbar& scrollbar, const WebMouseEvent& evt) { return Platform::Current()->ScrollbarBehavior()->ShouldCenterOnThumb( evt.button, evt.GetModifiers() & WebInputEvent::kShiftKey, @@ -260,9 +260,8 @@ void ScrollbarTheme::PaintTickmarks(GraphicsContext& context, #endif } -bool ScrollbarTheme::ShouldSnapBackToDragOrigin( - const ScrollbarThemeClient& scrollbar, - const WebMouseEvent& evt) { +bool ScrollbarTheme::ShouldSnapBackToDragOrigin(const Scrollbar& scrollbar, + const WebMouseEvent& evt) { IntPoint mouse_position = scrollbar.ConvertFromRootFrame( FlooredIntPoint(evt.PositionInRootFrame())); mouse_position.Move(scrollbar.X(), scrollbar.Y()); @@ -281,7 +280,7 @@ double ScrollbarTheme::OverlayScrollbarFadeOutDurationSeconds() const { return 0.0; } -int ScrollbarTheme::ThumbPosition(const ScrollbarThemeClient& scrollbar, +int ScrollbarTheme::ThumbPosition(const Scrollbar& scrollbar, float scroll_position) { if (scrollbar.Enabled()) { float size = scrollbar.TotalSize() - scrollbar.VisibleSize(); @@ -296,7 +295,7 @@ int ScrollbarTheme::ThumbPosition(const ScrollbarThemeClient& scrollbar, return 0; } -int ScrollbarTheme::ThumbLength(const ScrollbarThemeClient& scrollbar) { +int ScrollbarTheme::ThumbLength(const Scrollbar& scrollbar) { if (!scrollbar.Enabled()) return 0; @@ -315,7 +314,7 @@ int ScrollbarTheme::ThumbLength(const ScrollbarThemeClient& scrollbar) { return length; } -int ScrollbarTheme::TrackPosition(const ScrollbarThemeClient& scrollbar) { +int ScrollbarTheme::TrackPosition(const Scrollbar& scrollbar) { IntRect constrained_track_rect = ConstrainTrackRectToTrackPieces(scrollbar, TrackRect(scrollbar)); return (scrollbar.Orientation() == kHorizontalScrollbar) @@ -323,7 +322,7 @@ int ScrollbarTheme::TrackPosition(const ScrollbarThemeClient& scrollbar) { : constrained_track_rect.Y() - scrollbar.Y(); } -int ScrollbarTheme::TrackLength(const ScrollbarThemeClient& scrollbar) { +int ScrollbarTheme::TrackLength(const Scrollbar& scrollbar) { IntRect constrained_track_rect = ConstrainTrackRectToTrackPieces(scrollbar, TrackRect(scrollbar)); return (scrollbar.Orientation() == kHorizontalScrollbar) @@ -331,7 +330,7 @@ int ScrollbarTheme::TrackLength(const ScrollbarThemeClient& scrollbar) { : constrained_track_rect.Height(); } -IntRect ScrollbarTheme::ThumbRect(const ScrollbarThemeClient& scrollbar) { +IntRect ScrollbarTheme::ThumbRect(const Scrollbar& scrollbar) { if (!HasThumb(scrollbar)) return IntRect(); @@ -344,13 +343,13 @@ IntRect ScrollbarTheme::ThumbRect(const ScrollbarThemeClient& scrollbar) { return thumb_rect; } -int ScrollbarTheme::ThumbThickness(const ScrollbarThemeClient& scrollbar) { +int ScrollbarTheme::ThumbThickness(const Scrollbar& scrollbar) { IntRect track = TrackRect(scrollbar); return scrollbar.Orientation() == kHorizontalScrollbar ? track.Height() : track.Width(); } -void ScrollbarTheme::SplitTrack(const ScrollbarThemeClient& scrollbar, +void ScrollbarTheme::SplitTrack(const Scrollbar& scrollbar, const IntRect& unconstrained_track_rect, IntRect& before_thumb_rect, IntRect& thumb_rect, diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h index 624ace28340..5712dab6a82 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme.h @@ -52,11 +52,11 @@ class PLATFORM_EXPORT ScrollbarTheme { // which are explicitly invalidated will be repainted. virtual bool ShouldRepaintAllPartsOnInvalidation() const { return true; } - virtual void UpdateEnabledState(const ScrollbarThemeClient&) {} + virtual void UpdateEnabledState(const Scrollbar&) {} virtual bool Paint(const Scrollbar&, GraphicsContext&, const CullRect&); - virtual ScrollbarPart HitTest(const ScrollbarThemeClient&, const IntPoint&); + virtual ScrollbarPart HitTest(const Scrollbar&, const IntPoint&); // This returns a fixed value regardless of device-scale-factor. // This returns thickness when scrollbar is painted. i.e. It's not 0 even in @@ -73,7 +73,7 @@ class PLATFORM_EXPORT ScrollbarTheme { virtual bool SupportsControlTints() const { return false; } virtual bool UsesOverlayScrollbars() const { return false; } - virtual void UpdateScrollbarOverlayColorTheme(const ScrollbarThemeClient&) {} + virtual void UpdateScrollbarOverlayColorTheme(const Scrollbar&) {} // If true, scrollbars that become invisible (i.e. overlay scrollbars that // fade out) should be marked as disabled. This option exists since Mac and @@ -88,7 +88,7 @@ class PLATFORM_EXPORT ScrollbarTheme { // Returns parts of the scrollbar which must be repainted following a change // in the thumb position, given scroll positions before and after. virtual ScrollbarPart InvalidateOnThumbPositionChange( - const ScrollbarThemeClient&, + const Scrollbar&, float old_position, float new_position) const { return kAllParts; @@ -101,51 +101,49 @@ class PLATFORM_EXPORT ScrollbarTheme { const Scrollbar&, const IntRect&); - virtual bool ShouldCenterOnThumb(const ScrollbarThemeClient&, - const WebMouseEvent&); - virtual bool ShouldSnapBackToDragOrigin(const ScrollbarThemeClient&, + virtual bool ShouldCenterOnThumb(const Scrollbar&, const WebMouseEvent&); + virtual bool ShouldSnapBackToDragOrigin(const Scrollbar&, const WebMouseEvent&); - virtual bool ShouldDragDocumentInsteadOfThumb(const ScrollbarThemeClient&, + virtual bool ShouldDragDocumentInsteadOfThumb(const Scrollbar&, const WebMouseEvent&) { return false; } // The position of the thumb relative to the track. - int ThumbPosition(const ScrollbarThemeClient& scrollbar) { + int ThumbPosition(const Scrollbar& scrollbar) { return ThumbPosition(scrollbar, scrollbar.CurrentPos()); } virtual double OverlayScrollbarFadeOutDelaySeconds() const; virtual double OverlayScrollbarFadeOutDurationSeconds() const; // The position the thumb would have, relative to the track, at the specified // scroll position. - virtual int ThumbPosition(const ScrollbarThemeClient&, float scroll_position); + virtual int ThumbPosition(const Scrollbar&, float scroll_position); // The length of the thumb along the axis of the scrollbar. - virtual int ThumbLength(const ScrollbarThemeClient&); + virtual int ThumbLength(const Scrollbar&); // The position of the track relative to the scrollbar. - virtual int TrackPosition(const ScrollbarThemeClient&); + virtual int TrackPosition(const Scrollbar&); // The length of the track along the axis of the scrollbar. - virtual int TrackLength(const ScrollbarThemeClient&); + virtual int TrackLength(const Scrollbar&); // The opacity to be applied to the thumb. A theme overriding ThumbOpacity() // should also override PaintThumbWithOpacity(). - virtual float ThumbOpacity(const ScrollbarThemeClient&) const { return 1.0f; } + virtual float ThumbOpacity(const Scrollbar&) const { return 1.0f; } - virtual bool HasButtons(const ScrollbarThemeClient&) = 0; - virtual bool HasThumb(const ScrollbarThemeClient&) = 0; + virtual bool HasButtons(const Scrollbar&) = 0; + virtual bool HasThumb(const Scrollbar&) = 0; - virtual IntRect BackButtonRect(const ScrollbarThemeClient&, + virtual IntRect BackButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) = 0; - virtual IntRect ForwardButtonRect(const ScrollbarThemeClient&, + virtual IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) = 0; - virtual IntRect TrackRect(const ScrollbarThemeClient&, - bool painting = false) = 0; - virtual IntRect ThumbRect(const ScrollbarThemeClient&); - virtual int ThumbThickness(const ScrollbarThemeClient&); + virtual IntRect TrackRect(const Scrollbar&, bool painting = false) = 0; + virtual IntRect ThumbRect(const Scrollbar&); + virtual int ThumbThickness(const Scrollbar&); - virtual int MinimumThumbLength(const ScrollbarThemeClient&) = 0; + virtual int MinimumThumbLength(const Scrollbar&) = 0; - virtual void SplitTrack(const ScrollbarThemeClient&, + virtual void SplitTrack(const Scrollbar&, const IntRect& track, IntRect& start_track, IntRect& thumb, @@ -182,13 +180,13 @@ class PLATFORM_EXPORT ScrollbarTheme { virtual double InitialAutoscrollTimerDelay() { return 0.25; } virtual double AutoscrollTimerDelay() { return 0.05; } - virtual IntRect ConstrainTrackRectToTrackPieces(const ScrollbarThemeClient&, + virtual IntRect ConstrainTrackRectToTrackPieces(const Scrollbar&, const IntRect& rect) { return rect; } - virtual void RegisterScrollbar(ScrollbarThemeClient&) {} - virtual void UnregisterScrollbar(ScrollbarThemeClient&) {} + virtual void RegisterScrollbar(Scrollbar&) {} + virtual void UnregisterScrollbar(Scrollbar&) {} virtual bool IsMockTheme() const { return false; } @@ -198,14 +196,14 @@ class PLATFORM_EXPORT ScrollbarTheme { // painting code will use to paint the scrollbar into. The actual scrollbar // dimensions will be ignored for purposes of painting since the resource can // be then resized without a repaint. - virtual IntSize NinePatchThumbCanvasSize(const ScrollbarThemeClient&) const { + virtual IntSize NinePatchThumbCanvasSize(const Scrollbar&) const { NOTREACHED(); return IntSize(); } // For a nine-patch resource, the aperture defines the center patch that will // be stretched out. - virtual IntRect NinePatchThumbAperture(const ScrollbarThemeClient&) const { + virtual IntRect NinePatchThumbAperture(const Scrollbar&) const { NOTREACHED(); return IntRect(); } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc index 1633b0301bf..e2797eda5c9 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.cc @@ -77,10 +77,9 @@ bool operator!=(const PartPaintingParams& a, const PartPaintingParams& b) { return !(a == b); } -PartPaintingParams ButtonPartPaintingParams( - const ScrollbarThemeClient& scrollbar, - float position, - ScrollbarPart part) { +PartPaintingParams ButtonPartPaintingParams(const Scrollbar& scrollbar, + float position, + ScrollbarPart part) { WebThemeEngine::Part paint_part; WebThemeEngine::State state = WebThemeEngine::kStateNormal; bool check_min = false; @@ -156,16 +155,15 @@ int ScrollbarThemeAura::ScrollbarThickness(ScrollbarControlSize control_size) { return scrollbar_size.Width(); } -bool ScrollbarThemeAura::HasThumb(const ScrollbarThemeClient& scrollbar) { +bool ScrollbarThemeAura::HasThumb(const Scrollbar& scrollbar) { // This method is just called as a paint-time optimization to see if // painting the thumb can be skipped. We don't have to be exact here. return ThumbLength(scrollbar) > 0; } -IntRect ScrollbarThemeAura::BackButtonRect( - const ScrollbarThemeClient& scrollbar, - ScrollbarPart part, - bool) { +IntRect ScrollbarThemeAura::BackButtonRect(const Scrollbar& scrollbar, + ScrollbarPart part, + bool) { // Windows and Linux just have single arrows. if (part == kBackButtonEndPart) return IntRect(); @@ -174,10 +172,9 @@ IntRect ScrollbarThemeAura::BackButtonRect( return IntRect(scrollbar.X(), scrollbar.Y(), size.Width(), size.Height()); } -IntRect ScrollbarThemeAura::ForwardButtonRect( - const ScrollbarThemeClient& scrollbar, - ScrollbarPart part, - bool) { +IntRect ScrollbarThemeAura::ForwardButtonRect(const Scrollbar& scrollbar, + ScrollbarPart part, + bool) { // Windows and Linux just have single arrows. if (part == kForwardButtonStartPart) return IntRect(); @@ -194,8 +191,7 @@ IntRect ScrollbarThemeAura::ForwardButtonRect( return IntRect(x, y, size.Width(), size.Height()); } -IntRect ScrollbarThemeAura::TrackRect(const ScrollbarThemeClient& scrollbar, - bool) { +IntRect ScrollbarThemeAura::TrackRect(const Scrollbar& scrollbar, bool) { // The track occupies all space between the two buttons. IntSize bs = ButtonSize(scrollbar); if (scrollbar.Orientation() == kHorizontalScrollbar) { @@ -210,8 +206,7 @@ IntRect ScrollbarThemeAura::TrackRect(const ScrollbarThemeClient& scrollbar, scrollbar.Height() - 2 * bs.Height()); } -int ScrollbarThemeAura::MinimumThumbLength( - const ScrollbarThemeClient& scrollbar) { +int ScrollbarThemeAura::MinimumThumbLength(const Scrollbar& scrollbar) { if (scrollbar.Orientation() == kVerticalScrollbar) { return Platform::Current() ->ThemeEngine() @@ -317,7 +312,7 @@ bool ScrollbarThemeAura::ShouldRepaintAllPartsOnInvalidation() const { } ScrollbarPart ScrollbarThemeAura::InvalidateOnThumbPositionChange( - const ScrollbarThemeClient& scrollbar, + const Scrollbar& scrollbar, float old_position, float new_position) const { ScrollbarPart invalid_parts = kNoPart; @@ -343,7 +338,7 @@ bool ScrollbarThemeAura::HasScrollbarButtons( .IsEmpty(); }; -IntSize ScrollbarThemeAura::ButtonSize(const ScrollbarThemeClient& scrollbar) { +IntSize ScrollbarThemeAura::ButtonSize(const Scrollbar& scrollbar) { if (!HasScrollbarButtons(scrollbar.Orientation())) return IntSize(0, 0); diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h index dfdee4b89b3..6ad10afea4d 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h @@ -41,18 +41,17 @@ class PLATFORM_EXPORT ScrollbarThemeAura : public ScrollbarTheme { int ScrollbarThickness(ScrollbarControlSize) override; protected: - bool HasButtons(const ScrollbarThemeClient&) override { return true; } - bool HasThumb(const ScrollbarThemeClient&) override; + bool HasButtons(const Scrollbar&) override { return true; } + bool HasThumb(const Scrollbar&) override; - IntRect BackButtonRect(const ScrollbarThemeClient&, + IntRect BackButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - IntRect ForwardButtonRect(const ScrollbarThemeClient&, + IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - IntRect TrackRect(const ScrollbarThemeClient&, - bool painting = false) override; - int MinimumThumbLength(const ScrollbarThemeClient&) override; + IntRect TrackRect(const Scrollbar&, bool painting = false) override; + int MinimumThumbLength(const Scrollbar&) override; void PaintTrackBackground(GraphicsContext&, const Scrollbar&, @@ -69,7 +68,7 @@ class PLATFORM_EXPORT ScrollbarThemeAura : public ScrollbarTheme { bool ShouldRepaintAllPartsOnInvalidation() const override; ScrollbarPart InvalidateOnThumbPositionChange( - const ScrollbarThemeClient&, + const Scrollbar&, float old_position, float new_position) const override; @@ -79,7 +78,7 @@ class PLATFORM_EXPORT ScrollbarThemeAura : public ScrollbarTheme { FRIEND_TEST_ALL_PREFIXES(ScrollbarThemeAuraTest, NoButtonsReturnsSize0); virtual bool HasScrollbarButtons(ScrollbarOrientation) const; - IntSize ButtonSize(const ScrollbarThemeClient&); + IntSize ButtonSize(const Scrollbar&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc index 35f5ec78232..058bf7aaa46 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_aura_test.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_aura.h" +#include "base/message_loop/message_loop.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h deleted file mode 100644 index 3bebead8bec..00000000000 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h +++ /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: - * - * 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 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 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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_CLIENT_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCROLL_SCROLLBAR_THEME_CLIENT_H_ - -#include "third_party/blink/renderer/platform/geometry/int_point.h" -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/geometry/int_size.h" -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/scroll/scroll_types.h" -#include "third_party/blink/renderer/platform/wtf/vector.h" - -namespace blink { - -class PLATFORM_EXPORT ScrollbarThemeClient { - public: - virtual int X() const = 0; - virtual int Y() const = 0; - virtual int Width() const = 0; - virtual int Height() const = 0; - virtual IntSize Size() const = 0; - virtual IntPoint Location() const = 0; - - virtual void SetFrameRect(const IntRect&) = 0; - virtual IntRect FrameRect() const = 0; - - virtual void Invalidate() = 0; - virtual void InvalidateRect(const IntRect&) = 0; - - virtual ScrollbarOverlayColorTheme GetScrollbarOverlayColorTheme() const = 0; - virtual void GetTickmarks(Vector<IntRect>&) const = 0; - virtual bool IsScrollableAreaActive() const = 0; - - virtual IntPoint ConvertFromRootFrame(const IntPoint&) const = 0; - - virtual bool IsCustomScrollbar() const = 0; - virtual ScrollbarOrientation Orientation() const = 0; - virtual bool IsLeftSideVerticalScrollbar() const = 0; - - virtual int Value() const = 0; - virtual float CurrentPos() const = 0; - virtual int VisibleSize() const = 0; - virtual int TotalSize() const = 0; - virtual int Maximum() const = 0; - virtual ScrollbarControlSize GetControlSize() const = 0; - - virtual ScrollbarPart PressedPart() const = 0; - virtual ScrollbarPart HoveredPart() const = 0; - - virtual void StyleChanged() = 0; - virtual void SetScrollbarsHiddenIfOverlay(bool) = 0; - - virtual bool Enabled() const = 0; - virtual void SetEnabled(bool) = 0; - - virtual bool IsOverlayScrollbar() const = 0; - - virtual float ElasticOverscroll() const = 0; - virtual void SetElasticOverscroll(float) = 0; - - protected: - virtual ~ScrollbarThemeClient() = default; -}; - -} // namespace blink - -#endif // ScollbarThemeClient_h diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h index 379ecadc265..3372fdeb0ad 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.h @@ -41,8 +41,8 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme { public: ~ScrollbarThemeMac() override; - void RegisterScrollbar(ScrollbarThemeClient&) override; - void UnregisterScrollbar(ScrollbarThemeClient&) override; + void RegisterScrollbar(Scrollbar&) override; + void UnregisterScrollbar(Scrollbar&) override; void PreferencesChanged(float initial_button_delay, float autoscroll_button_delay, NSScrollerStyle preferred_scroller_style, @@ -66,17 +66,17 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme { bool ShouldRepaintAllPartsOnInvalidation() const override { return false; } ScrollbarPart InvalidateOnThumbPositionChange( - const ScrollbarThemeClient&, + const Scrollbar&, float old_position, float new_position) const override; - void UpdateEnabledState(const ScrollbarThemeClient&) override; + void UpdateEnabledState(const Scrollbar&) override; int ScrollbarThickness(ScrollbarControlSize = kRegularScrollbar) override; bool UsesOverlayScrollbars() const override; - void UpdateScrollbarOverlayColorTheme(const ScrollbarThemeClient&) override; + void UpdateScrollbarOverlayColorTheme(const Scrollbar&) override; WebScrollbarButtonsPlacement ButtonsPlacement() const override; - void SetNewPainterForScrollbar(ScrollbarThemeClient&, ScrollbarPainter); - ScrollbarPainter PainterForScrollbar(const ScrollbarThemeClient&) const; + void SetNewPainterForScrollbar(Scrollbar&, ScrollbarPainter); + ScrollbarPainter PainterForScrollbar(const Scrollbar&) const; void PaintTrackBackground(GraphicsContext&, const Scrollbar&, @@ -92,32 +92,31 @@ class PLATFORM_EXPORT ScrollbarThemeMac : public ScrollbarTheme { PaintThumbInternal(context, scrollbar, rect, ThumbOpacity(scrollbar)); } - float ThumbOpacity(const ScrollbarThemeClient&) const override; + float ThumbOpacity(const Scrollbar&) const override; static NSScrollerStyle RecommendedScrollerStyle(); protected: int MaxOverlapBetweenPages() override { return 40; } - bool ShouldDragDocumentInsteadOfThumb(const ScrollbarThemeClient&, + bool ShouldDragDocumentInsteadOfThumb(const Scrollbar&, const WebMouseEvent&) override; int ScrollbarPartToHIPressedState(ScrollbarPart); virtual void UpdateButtonPlacement(WebScrollbarButtonsPlacement) {} - IntRect TrackRect(const ScrollbarThemeClient&, - bool painting = false) override; - IntRect BackButtonRect(const ScrollbarThemeClient&, + IntRect TrackRect(const Scrollbar&, bool painting = false) override; + IntRect BackButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - IntRect ForwardButtonRect(const ScrollbarThemeClient&, + IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - bool HasButtons(const ScrollbarThemeClient&) override { return false; } - bool HasThumb(const ScrollbarThemeClient&) override; + bool HasButtons(const Scrollbar&) override { return false; } + bool HasThumb(const Scrollbar&) override; - int MinimumThumbLength(const ScrollbarThemeClient&) override; + int MinimumThumbLength(const Scrollbar&) override; int TickmarkBorderWidth() override { return 1; } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm index ae9ebdfa482..0e120742828 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mac.mm @@ -39,7 +39,6 @@ #include "third_party/blink/renderer/platform/mac/ns_scroller_imp_details.h" #include "third_party/blink/renderer/platform/mac/scroll_animator_mac.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "third_party/blink/renderer/platform/scroll/scrollbar_theme_client.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/retain_ptr.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -52,16 +51,16 @@ @end @interface BlinkScrollbarObserver : NSObject { - blink::ScrollbarThemeClient* _scrollbar; + blink::Scrollbar* _scrollbar; RetainPtr<ScrollbarPainter> _scrollbarPainter; } -- (id)initWithScrollbar:(blink::ScrollbarThemeClient*)scrollbar +- (id)initWithScrollbar:(blink::Scrollbar*)scrollbar painter:(const RetainPtr<ScrollbarPainter>&)painter; @end @implementation BlinkScrollbarObserver -- (id)initWithScrollbar:(blink::ScrollbarThemeClient*)scrollbar +- (id)initWithScrollbar:(blink::Scrollbar*)scrollbar painter:(const RetainPtr<ScrollbarPainter>&)painter { if (!(self = [super init])) return nil; @@ -97,7 +96,7 @@ namespace blink { -typedef HashSet<ScrollbarThemeClient*> ScrollbarSet; +typedef PersistentHeapHashSet<WeakMember<Scrollbar>> ScrollbarSet; static ScrollbarSet& GetScrollbarSet() { DEFINE_STATIC_LOCAL(ScrollbarSet, set, ()); @@ -108,12 +107,13 @@ static float g_initial_button_delay = 0.5f; static float g_autoscroll_button_delay = 0.05f; static NSScrollerStyle g_preferred_scroller_style = NSScrollerStyleLegacy; -typedef HashMap<ScrollbarThemeClient*, RetainPtr<BlinkScrollbarObserver>> +typedef PersistentHeapHashMap<WeakMember<Scrollbar>, + RetainPtr<BlinkScrollbarObserver>> ScrollbarPainterMap; static ScrollbarPainterMap& GetScrollbarPainterMap() { - static ScrollbarPainterMap* map = new ScrollbarPainterMap; - return *map; + DEFINE_STATIC_LOCAL(ScrollbarPainterMap, map, ()); + return map; } static bool SupportsExpandedScrollbars() { @@ -152,11 +152,9 @@ void ScrollbarThemeMac::PreferencesChanged( g_autoscroll_button_delay = autoscroll_button_delay; g_preferred_scroller_style = preferred_scroller_style; if (redraw && !GetScrollbarSet().IsEmpty()) { - ScrollbarSet::iterator end = GetScrollbarSet().end(); - for (ScrollbarSet::iterator it = GetScrollbarSet().begin(); it != end; - ++it) { - (*it)->StyleChanged(); - (*it)->Invalidate(); + for (const auto& scrollbar : GetScrollbarSet()) { + scrollbar->StyleChanged(); + scrollbar->SetNeedsPaintInvalidation(kAllParts); } } } @@ -170,7 +168,7 @@ double ScrollbarThemeMac::AutoscrollTimerDelay() { } bool ScrollbarThemeMac::ShouldDragDocumentInsteadOfThumb( - const ScrollbarThemeClient&, + const Scrollbar&, const WebMouseEvent& event) { return (event.GetModifiers() & WebInputEvent::Modifiers::kAltKey) != 0; } @@ -195,14 +193,14 @@ int ScrollbarThemeMac::ScrollbarPartToHIPressedState(ScrollbarPart part) { } ScrollbarPart ScrollbarThemeMac::InvalidateOnThumbPositionChange( - const ScrollbarThemeClient& scrollbar, + const Scrollbar& scrollbar, float old_position, float new_position) const { // ScrollAnimatorMac will invalidate scrollbar parts if necessary. return kNoPart; } -void ScrollbarThemeMac::RegisterScrollbar(ScrollbarThemeClient& scrollbar) { +void ScrollbarThemeMac::RegisterScrollbar(Scrollbar& scrollbar) { GetScrollbarSet().insert(&scrollbar); bool is_horizontal = scrollbar.Orientation() == kHorizontalScrollbar; @@ -223,13 +221,13 @@ void ScrollbarThemeMac::RegisterScrollbar(ScrollbarThemeClient& scrollbar) { UpdateScrollbarOverlayColorTheme(scrollbar); } -void ScrollbarThemeMac::UnregisterScrollbar(ScrollbarThemeClient& scrollbar) { +void ScrollbarThemeMac::UnregisterScrollbar(Scrollbar& scrollbar) { GetScrollbarPainterMap().erase(&scrollbar); GetScrollbarSet().erase(&scrollbar); } void ScrollbarThemeMac::SetNewPainterForScrollbar( - ScrollbarThemeClient& scrollbar, + Scrollbar& scrollbar, ScrollbarPainter new_painter) { RetainPtr<ScrollbarPainter> scrollbar_painter(kAdoptNS, [new_painter retain]); RetainPtr<BlinkScrollbarObserver> observer( @@ -242,9 +240,9 @@ void ScrollbarThemeMac::SetNewPainterForScrollbar( } ScrollbarPainter ScrollbarThemeMac::PainterForScrollbar( - const ScrollbarThemeClient& scrollbar) const { + const Scrollbar& scrollbar) const { return [GetScrollbarPainterMap() - .at(const_cast<ScrollbarThemeClient*>(&scrollbar)) + .at(const_cast<Scrollbar*>(&scrollbar)) .Get() painter]; } @@ -350,7 +348,7 @@ bool ScrollbarThemeMac::UsesOverlayScrollbars() const { } void ScrollbarThemeMac::UpdateScrollbarOverlayColorTheme( - const ScrollbarThemeClient& scrollbar) { + const Scrollbar& scrollbar) { ScrollbarPainter painter = PainterForScrollbar(scrollbar); switch (scrollbar.GetScrollbarOverlayColorTheme()) { case kScrollbarOverlayColorThemeDark: @@ -366,7 +364,7 @@ WebScrollbarButtonsPlacement ScrollbarThemeMac::ButtonsPlacement() const { return kWebScrollbarButtonsPlacementNone; } -bool ScrollbarThemeMac::HasThumb(const ScrollbarThemeClient& scrollbar) { +bool ScrollbarThemeMac::HasThumb(const Scrollbar& scrollbar) { ScrollbarPainter painter = PainterForScrollbar(scrollbar); int min_length_for_thumb = [painter knobMinLength] + [painter trackOverlapEndInset] + @@ -378,39 +376,35 @@ bool ScrollbarThemeMac::HasThumb(const ScrollbarThemeClient& scrollbar) { : scrollbar.Height()) >= min_length_for_thumb; } -IntRect ScrollbarThemeMac::BackButtonRect(const ScrollbarThemeClient& scrollbar, +IntRect ScrollbarThemeMac::BackButtonRect(const Scrollbar& scrollbar, ScrollbarPart part, bool painting) { DCHECK_EQ(ButtonsPlacement(), kWebScrollbarButtonsPlacementNone); return IntRect(); } -IntRect ScrollbarThemeMac::ForwardButtonRect( - const ScrollbarThemeClient& scrollbar, - ScrollbarPart part, - bool painting) { +IntRect ScrollbarThemeMac::ForwardButtonRect(const Scrollbar& scrollbar, + ScrollbarPart part, + bool painting) { DCHECK_EQ(ButtonsPlacement(), kWebScrollbarButtonsPlacementNone); return IntRect(); } -IntRect ScrollbarThemeMac::TrackRect(const ScrollbarThemeClient& scrollbar, +IntRect ScrollbarThemeMac::TrackRect(const Scrollbar& scrollbar, bool painting) { DCHECK(!HasButtons(scrollbar)); return scrollbar.FrameRect(); } -int ScrollbarThemeMac::MinimumThumbLength( - const ScrollbarThemeClient& scrollbar) { +int ScrollbarThemeMac::MinimumThumbLength(const Scrollbar& scrollbar) { return [PainterForScrollbar(scrollbar) knobMinLength]; } -void ScrollbarThemeMac::UpdateEnabledState( - const ScrollbarThemeClient& scrollbar) { +void ScrollbarThemeMac::UpdateEnabledState(const Scrollbar& scrollbar) { [PainterForScrollbar(scrollbar) setEnabled:scrollbar.Enabled()]; } -float ScrollbarThemeMac::ThumbOpacity( - const ScrollbarThemeClient& scrollbar) const { +float ScrollbarThemeMac::ThumbOpacity(const Scrollbar& scrollbar) const { ScrollbarPainter scrollbar_painter = PainterForScrollbar(scrollbar); return [scrollbar_painter knobAlpha]; } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc index 6728343cb18..73b2b3536c2 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.cc @@ -42,8 +42,7 @@ bool ScrollbarThemeMock::UsesOverlayScrollbars() const { return RuntimeEnabledFeatures::OverlayScrollbarsEnabled(); } -IntRect ScrollbarThemeMock::TrackRect(const ScrollbarThemeClient& scrollbar, - bool) { +IntRect ScrollbarThemeMock::TrackRect(const Scrollbar& scrollbar, bool) { return scrollbar.FrameRect(); } @@ -85,8 +84,7 @@ void ScrollbarThemeMock::PaintScrollCorner(GraphicsContext& context, context.FillRect(corner_rect, Color::kWhite); } -int ScrollbarThemeMock::MinimumThumbLength( - const ScrollbarThemeClient& scrollbar) { +int ScrollbarThemeMock::MinimumThumbLength(const Scrollbar& scrollbar) { return ScrollbarThickness(scrollbar.GetControlSize()); } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h index 4118b580bd5..e463fdf755e 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_mock.h @@ -38,21 +38,20 @@ class PLATFORM_EXPORT ScrollbarThemeMock : public ScrollbarTheme { bool UsesOverlayScrollbars() const override; protected: - bool HasButtons(const ScrollbarThemeClient&) override { return false; } - bool HasThumb(const ScrollbarThemeClient&) override { return true; } + bool HasButtons(const Scrollbar&) override { return false; } + bool HasThumb(const Scrollbar&) override { return true; } - IntRect BackButtonRect(const ScrollbarThemeClient&, + IntRect BackButtonRect(const Scrollbar&, ScrollbarPart, bool /*painting*/ = false) override { return IntRect(); } - IntRect ForwardButtonRect(const ScrollbarThemeClient&, + IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool /*painting*/ = false) override { return IntRect(); } - IntRect TrackRect(const ScrollbarThemeClient&, - bool painting = false) override; + IntRect TrackRect(const Scrollbar&, bool painting = false) override; void PaintTrackBackground(GraphicsContext&, const Scrollbar&, @@ -63,7 +62,7 @@ class PLATFORM_EXPORT ScrollbarThemeMock : public ScrollbarTheme { const DisplayItemClient&, const IntRect& corner_rect) override; - int MinimumThumbLength(const ScrollbarThemeClient&) override; + int MinimumThumbLength(const Scrollbar&) override; private: bool IsMockTheme() const final { return true; } diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc index b6f49e26a48..5d5a07aa083 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.cc @@ -63,7 +63,7 @@ bool ScrollbarThemeOverlay::ShouldRepaintAllPartsOnInvalidation() const { } ScrollbarPart ScrollbarThemeOverlay::InvalidateOnThumbPositionChange( - const ScrollbarThemeClient&, + const Scrollbar&, float old_position, float new_position) const { return kNoPart; @@ -103,7 +103,7 @@ double ScrollbarThemeOverlay::OverlayScrollbarFadeOutDurationSeconds() const { return style.fade_out_duration_seconds; } -int ScrollbarThemeOverlay::ThumbLength(const ScrollbarThemeClient& scrollbar) { +int ScrollbarThemeOverlay::ThumbLength(const Scrollbar& scrollbar) { int track_len = TrackLength(scrollbar); if (!scrollbar.TotalSize()) @@ -117,24 +117,23 @@ int ScrollbarThemeOverlay::ThumbLength(const ScrollbarThemeClient& scrollbar) { return length; } -bool ScrollbarThemeOverlay::HasThumb(const ScrollbarThemeClient& scrollbar) { +bool ScrollbarThemeOverlay::HasThumb(const Scrollbar& scrollbar) { return true; } -IntRect ScrollbarThemeOverlay::BackButtonRect(const ScrollbarThemeClient&, +IntRect ScrollbarThemeOverlay::BackButtonRect(const Scrollbar&, ScrollbarPart, bool) { return IntRect(); } -IntRect ScrollbarThemeOverlay::ForwardButtonRect(const ScrollbarThemeClient&, +IntRect ScrollbarThemeOverlay::ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool) { return IntRect(); } -IntRect ScrollbarThemeOverlay::TrackRect(const ScrollbarThemeClient& scrollbar, - bool) { +IntRect ScrollbarThemeOverlay::TrackRect(const Scrollbar& scrollbar, bool) { IntRect rect = scrollbar.FrameRect(); if (scrollbar.Orientation() == kHorizontalScrollbar) rect.InflateX(-scrollbar_margin_); @@ -143,7 +142,7 @@ IntRect ScrollbarThemeOverlay::TrackRect(const ScrollbarThemeClient& scrollbar, return rect; } -int ScrollbarThemeOverlay::ThumbThickness(const ScrollbarThemeClient&) { +int ScrollbarThemeOverlay::ThumbThickness(const Scrollbar&) { return thumb_thickness_; } @@ -204,9 +203,8 @@ void ScrollbarThemeOverlay::PaintThumb(GraphicsContext& context, canvas->restore(); } -ScrollbarPart ScrollbarThemeOverlay::HitTest( - const ScrollbarThemeClient& scrollbar, - const IntPoint& position) { +ScrollbarPart ScrollbarThemeOverlay::HitTest(const Scrollbar& scrollbar, + const IntPoint& position) { if (allow_hit_test_ == kDisallowHitTest) return kNoPart; @@ -247,7 +245,7 @@ bool ScrollbarThemeOverlay::UsesNinePatchThumbResource() const { } IntSize ScrollbarThemeOverlay::NinePatchThumbCanvasSize( - const ScrollbarThemeClient& scrollbar) const { + const Scrollbar& scrollbar) const { DCHECK(UsesNinePatchThumbResource()); WebThemeEngine::Part part = @@ -260,7 +258,7 @@ IntSize ScrollbarThemeOverlay::NinePatchThumbCanvasSize( } IntRect ScrollbarThemeOverlay::NinePatchThumbAperture( - const ScrollbarThemeClient& scrollbar) const { + const Scrollbar& scrollbar) const { DCHECK(UsesNinePatchThumbResource()); WebThemeEngine::Part part = WebThemeEngine::kPartScrollbarHorizontalThumb; @@ -271,8 +269,7 @@ IntRect ScrollbarThemeOverlay::NinePatchThumbAperture( return Platform::Current()->ThemeEngine()->NinePatchAperture(part); } -int ScrollbarThemeOverlay::MinimumThumbLength( - const ScrollbarThemeClient& scrollbar) { +int ScrollbarThemeOverlay::MinimumThumbLength(const Scrollbar& scrollbar) { if (scrollbar.Orientation() == kVerticalScrollbar) { return Platform::Current() ->ThemeEngine() diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h index 9990461217c..18c4748c0e5 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h @@ -49,7 +49,7 @@ class PLATFORM_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme { bool ShouldRepaintAllPartsOnInvalidation() const override; ScrollbarPart InvalidateOnThumbPositionChange( - const ScrollbarThemeClient&, + const Scrollbar&, float old_position, float new_position) const override; @@ -59,30 +59,29 @@ class PLATFORM_EXPORT ScrollbarThemeOverlay : public ScrollbarTheme { double OverlayScrollbarFadeOutDelaySeconds() const override; double OverlayScrollbarFadeOutDurationSeconds() const override; - int ThumbLength(const ScrollbarThemeClient&) override; + int ThumbLength(const Scrollbar&) override; - bool HasButtons(const ScrollbarThemeClient&) override { return false; } - bool HasThumb(const ScrollbarThemeClient&) override; + bool HasButtons(const Scrollbar&) override { return false; } + bool HasThumb(const Scrollbar&) override; - IntRect BackButtonRect(const ScrollbarThemeClient&, + IntRect BackButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - IntRect ForwardButtonRect(const ScrollbarThemeClient&, + IntRect ForwardButtonRect(const Scrollbar&, ScrollbarPart, bool painting = false) override; - IntRect TrackRect(const ScrollbarThemeClient&, - bool painting = false) override; - int ThumbThickness(const ScrollbarThemeClient&) override; + IntRect TrackRect(const Scrollbar&, bool painting = false) override; + int ThumbThickness(const Scrollbar&) override; int ThumbThickness() { return thumb_thickness_; } void PaintThumb(GraphicsContext&, const Scrollbar&, const IntRect&) override; - ScrollbarPart HitTest(const ScrollbarThemeClient&, const IntPoint&) override; + ScrollbarPart HitTest(const Scrollbar&, const IntPoint&) override; bool UsesNinePatchThumbResource() const override; - IntSize NinePatchThumbCanvasSize(const ScrollbarThemeClient&) const override; - IntRect NinePatchThumbAperture(const ScrollbarThemeClient&) const override; + IntSize NinePatchThumbCanvasSize(const Scrollbar&) const override; + IntRect NinePatchThumbAperture(const Scrollbar&) const override; - int MinimumThumbLength(const ScrollbarThemeClient&) override; + int MinimumThumbLength(const Scrollbar&) override; bool IsMobileTheme() const; diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h index fc6e95b05a7..d27b0dc4cd2 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_mock.h @@ -58,12 +58,12 @@ class PLATFORM_EXPORT ScrollbarThemeOverlayMock : public ScrollbarThemeOverlay { ScrollbarThemeOverlay::PaintThumb(gc, scrollbar, rect); } - bool ShouldSnapBackToDragOrigin(const ScrollbarThemeClient& scrollbar, + bool ShouldSnapBackToDragOrigin(const Scrollbar& scrollbar, const WebMouseEvent& evt) override { return false; } - int MinimumThumbLength(const ScrollbarThemeClient&) override { return 7; } + int MinimumThumbLength(const Scrollbar&) override { return 7; } private: double delay_in_seconds_; diff --git a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc index 2eed0f501bb..f711b205e3e 100644 --- a/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc +++ b/chromium/third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay_test.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/scroll/scrollbar_theme_overlay.h" +#include "base/message_loop/message_loop.h" #include "third_party/blink/renderer/platform/scroll/scrollbar_test_suite.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" diff --git a/chromium/third_party/blink/renderer/platform/shared_buffer.cc b/chromium/third_party/blink/renderer/platform/shared_buffer.cc index 986899f040d..c9702bfbca7 100644 --- a/chromium/third_party/blink/renderer/platform/shared_buffer.cc +++ b/chromium/third_party/blink/renderer/platform/shared_buffer.cc @@ -54,13 +54,12 @@ SharedBuffer::SharedBuffer() : size_(0) {} SharedBuffer::SharedBuffer(size_t size) : size_(size), buffer_(size) {} -SharedBuffer::SharedBuffer(const char* data, size_t size) : size_(0) { - AppendInternal(data, size); +SharedBuffer::SharedBuffer(const char* data, size_t size) : size_(size) { + buffer_.Append(data, size); } -SharedBuffer::SharedBuffer(const unsigned char* data, size_t size) : size_(0) { - AppendInternal(reinterpret_cast<const char*>(data), size); -} +SharedBuffer::SharedBuffer(const unsigned char* data, size_t size) + : SharedBuffer(reinterpret_cast<const char*>(data), size) {} SharedBuffer::~SharedBuffer() { Clear(); @@ -256,7 +255,7 @@ void SharedBuffer::OnMemoryDump(const String& dump_prefix, // If there is data in the segments, then it should have been allocated // using fastMalloc. const String data_dump_name = dump_prefix + "/segments"; - auto dump = memory_dump->CreateMemoryAllocatorDump(data_dump_name); + auto* dump = memory_dump->CreateMemoryAllocatorDump(data_dump_name); dump->AddScalar("size", "bytes", size_); memory_dump->AddSuballocation( dump->Guid(), String(WTF::Partitions::kAllocatedObjectPoolName)); diff --git a/chromium/third_party/blink/renderer/platform/shared_buffer_test.cc b/chromium/third_party/blink/renderer/platform/shared_buffer_test.cc index a1124645829..9edcb6a99e2 100644 --- a/chromium/third_party/blink/renderer/platform/shared_buffer_test.cc +++ b/chromium/third_party/blink/renderer/platform/shared_buffer_test.cc @@ -153,6 +153,28 @@ TEST(SharedBufferTest, constructorWithSizeOnly) { ASSERT_EQ(length, shared_buffer->GetSomeData(data, static_cast<size_t>(0u))); } +TEST(SharedBufferTest, constructorWithFlatData) { + Vector<char> data; + + while (data.size() < 10000ul) { + data.Append("FooBarBaz", 9ul); + auto shared_buffer = SharedBuffer::Create(data.begin(), data.size()); + + Vector<Vector<char>> segments; + shared_buffer->ForEachSegment( + [&segments](const char* segment, size_t segment_size, size_t) -> bool { + segments.emplace_back(); + segments.back().Append(segment, segment_size); + return true; + }); + + // Shared buffers constructed from flat data should stay flat. + ASSERT_EQ(segments.size(), 1ul); + ASSERT_EQ(segments.front().size(), data.size()); + EXPECT_EQ(memcmp(segments.front().begin(), data.begin(), data.size()), 0); + } +} + TEST(SharedBufferTest, FlatData) { auto check_flat_data = [](scoped_refptr<const SharedBuffer> shared_buffer) { const SharedBuffer::DeprecatedFlatData flat_buffer(shared_buffer); diff --git a/chromium/third_party/blink/renderer/platform/speech/DEPS b/chromium/third_party/blink/renderer/platform/speech/DEPS new file mode 100644 index 00000000000..1cf1137b89a --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/speech/DEPS @@ -0,0 +1,13 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/speech", + + # Dependencies. + "+third_party/blink/renderer/platform/exported/web_speech_synthesizer_client_impl.h", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc b/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc index 1c69a40f565..0ab189b4a53 100644 --- a/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc +++ b/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.cc @@ -34,7 +34,7 @@ PlatformSpeechSynthesisUtterance* PlatformSpeechSynthesisUtterance::Create( PlatformSpeechSynthesisUtterance::PlatformSpeechSynthesisUtterance( PlatformSpeechSynthesisUtteranceClient* client) - : client_(client), volume_(1.0f), rate_(1.0f), pitch_(1.0f) {} + : client_(client) {} void PlatformSpeechSynthesisUtterance::Trace(blink::Visitor* visitor) { visitor->Trace(client_); diff --git a/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h b/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h index 229d5e0b33d..8440d819358 100644 --- a/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h +++ b/chromium/third_party/blink/renderer/platform/speech/platform_speech_synthesis_utterance.h @@ -26,6 +26,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SPEECH_PLATFORM_SPEECH_SYNTHESIS_UTTERANCE_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SPEECH_PLATFORM_SPEECH_SYNTHESIS_UTTERANCE_H_ +#include "third_party/blink/public/platform/web_speech_synthesis_constants.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/speech/platform_speech_synthesis_voice.h" @@ -83,9 +84,9 @@ class PLATFORM_EXPORT PlatformSpeechSynthesisUtterance final String text_; String lang_; scoped_refptr<PlatformSpeechSynthesisVoice> voice_; - float volume_; - float rate_; - float pitch_; + float volume_ = SpeechSynthesisConstants::kDoublePrefNotSet; + float rate_ = SpeechSynthesisConstants::kDoublePrefNotSet; + float pitch_ = SpeechSynthesisConstants::kDoublePrefNotSet; double start_time_; }; diff --git a/chromium/third_party/blink/renderer/platform/supplementable.h b/chromium/third_party/blink/renderer/platform/supplementable.h index be20afad9be..50381117540 100644 --- a/chromium/third_party/blink/renderer/platform/supplementable.h +++ b/chromium/third_party/blink/renderer/platform/supplementable.h @@ -112,7 +112,7 @@ class Supplementable; // support wrapper-tracing. class PLATFORM_EXPORT TraceWrapperBaseForSupplement { public: - virtual void TraceWrappers(const ScriptWrappableVisitor* visitor) const {} + virtual void TraceWrappers(ScriptWrappableVisitor* visitor) const {} }; template <typename T> @@ -148,7 +148,7 @@ class Supplement : public GarbageCollectedMixin, : nullptr; } - virtual void Trace(blink::Visitor* visitor) { + void Trace(blink::Visitor* visitor) override { visitor->Trace(supplementable_); } @@ -204,8 +204,8 @@ class Supplementable : public GarbageCollectedMixin { #endif } - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(supplements_); } - virtual void TraceWrappers(const ScriptWrappableVisitor* visitor) const { + void Trace(blink::Visitor* visitor) override { visitor->Trace(supplements_); } + virtual void TraceWrappers(ScriptWrappableVisitor* visitor) const { for (const auto& supplement : supplements_.Values()) visitor->TraceWrappers(supplement); } diff --git a/chromium/third_party/blink/renderer/platform/testing/DEPS b/chromium/third_party/blink/renderer/platform/testing/DEPS index a9fe93b7c6e..c8468495efa 100644 --- a/chromium/third_party/blink/renderer/platform/testing/DEPS +++ b/chromium/third_party/blink/renderer/platform/testing/DEPS @@ -1,6 +1,11 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/testing", + + # Dependencies. "+base/at_exit.h", "+base/command_line.h", "+base/i18n/icu_util.h", @@ -14,6 +19,28 @@ include_rules = [ "+components/viz/test", "+mojo/edk/embedder", '+testing', + + "+third_party/blink/renderer/platform/font_family_names.h", + "+third_party/blink/renderer/platform/fonts", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/graphics", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/histogram.h", + "+third_party/blink/renderer/platform/image-decoders/image_decoder.h", + "+third_party/blink/renderer/platform/instrumentation", + "+third_party/blink/renderer/platform/language.h", + "+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/pod_arena.h", + "+third_party/blink/renderer/platform/scheduler", + "+third_party/blink/renderer/platform/scroll", + "+third_party/blink/renderer/platform/shared_buffer.h", + "+third_party/blink/renderer/platform/text", + "+third_party/blink/renderer/platform/timer.h", + "+third_party/blink/renderer/platform/waitable_event.h", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", ] specific_include_rules = { diff --git a/chromium/third_party/blink/renderer/platform/testing/compositor_test.h b/chromium/third_party/blink/renderer/platform/testing/compositor_test.h index 746d2ca5a25..bf4c8427c34 100644 --- a/chromium/third_party/blink/renderer/platform/testing/compositor_test.h +++ b/chromium/third_party/blink/renderer/platform/testing/compositor_test.h @@ -18,7 +18,7 @@ class CompositorTest : public testing::Test { public: CompositorTest(); - virtual ~CompositorTest(); + ~CompositorTest() override; protected: // Mock task runner is initialized here because tests create 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 c1d570134c9..009d2720875 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 @@ -22,12 +22,13 @@ class EmptyWebMediaPlayer : public WebMediaPlayer { void Seek(double seconds) override {} void SetRate(double) override {} void SetVolume(double) override {} - void EnterPictureInPicture() override {} - void ExitPictureInPicture() override {} + void EnterPictureInPicture(PipWindowOpenedCallback) override {} + void ExitPictureInPicture(PipWindowClosedCallback) override {} + void RegisterPictureInPictureWindowResizeCallback( + PipWindowResizedCallback) override {} WebTimeRanges Buffered() const override; WebTimeRanges Seekable() const override; void SetSinkId(const WebString& sink_id, - const WebSecurityOrigin&, WebSetSinkIdCallbacks*) override {} bool HasVideo() const override { return false; } bool HasAudio() const override { return false; } diff --git a/chromium/third_party/blink/renderer/platform/testing/message_loop_for_mojo.h b/chromium/third_party/blink/renderer/platform/testing/message_loop_for_mojo.h index cd4a443e2f3..e83f6e4c19f 100644 --- a/chromium/third_party/blink/renderer/platform/testing/message_loop_for_mojo.h +++ b/chromium/third_party/blink/renderer/platform/testing/message_loop_for_mojo.h @@ -5,10 +5,8 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_MESSAGE_LOOP_FOR_MOJO_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_MESSAGE_LOOP_FOR_MOJO_H_ -#include "base/message_loop/message_loop.h" // This file exists just in order to allow unittests to include -// "base/message_loop/message_loop.h" indirectly without adding a line of // "+base/message_loop" in their DEPS file. #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_MESSAGE_LOOP_FOR_MOJO_H_ diff --git a/chromium/third_party/blink/renderer/platform/testing/mock_web_crypto.h b/chromium/third_party/blink/renderer/platform/testing/mock_web_crypto.h index ce8ca5d4952..12c71c4022b 100644 --- a/chromium/third_party/blink/renderer/platform/testing/mock_web_crypto.h +++ b/chromium/third_party/blink/renderer/platform/testing/mock_web_crypto.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_MOCK_WEB_CRYPTO_H_ #include <memory> +#include "base/single_thread_task_runner.h" #include "testing/gmock/include/gmock/gmock.h" #include "third_party/blink/public/platform/web_crypto.h" #include "third_party/blink/public/platform/web_crypto_key_algorithm.h" 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 92a48c23c4d..14b2b280095 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 @@ -7,32 +7,112 @@ #include "third_party/blink/renderer/platform/graphics/paint/clip_paint_property_node.h" #include "third_party/blink/renderer/platform/graphics/paint/effect_paint_property_node.h" -#include "third_party/blink/renderer/platform/graphics/paint/paint_chunk_properties.h" +#include "third_party/blink/renderer/platform/graphics/paint/property_tree_state.h" #include "third_party/blink/renderer/platform/graphics/paint/transform_paint_property_node.h" namespace blink { -namespace test { -static inline scoped_refptr<EffectPaintPropertyNode> CreateOpacityOnlyEffect( +inline scoped_refptr<EffectPaintPropertyNode> CreateOpacityEffect( scoped_refptr<const EffectPaintPropertyNode> parent, - float opacity) { - scoped_refptr<TransformPaintPropertyNode> local_transform_space = - const_cast<TransformPaintPropertyNode*>(parent->LocalTransformSpace()); - scoped_refptr<ClipPaintPropertyNode> output_clip = - const_cast<ClipPaintPropertyNode*>(parent->OutputClip()); - return EffectPaintPropertyNode::Create( - std::move(parent), std::move(local_transform_space), - std::move(output_clip), kColorFilterNone, CompositorFilterOperations(), - opacity, SkBlendMode::kSrcOver); + scoped_refptr<const TransformPaintPropertyNode> local_transform_space, + scoped_refptr<const ClipPaintPropertyNode> output_clip, + float opacity, + CompositingReasons compositing_reasons = CompositingReason::kNone) { + EffectPaintPropertyNode::State state; + state.local_transform_space = local_transform_space; + state.output_clip = output_clip; + state.opacity = opacity; + state.direct_compositing_reasons = compositing_reasons; + return EffectPaintPropertyNode::Create(std::move(parent), std::move(state)); } -static inline PaintChunkProperties DefaultPaintChunkProperties() { - PaintChunkProperties default_properties(PropertyTreeState::Root()); +inline scoped_refptr<EffectPaintPropertyNode> CreateOpacityEffect( + scoped_refptr<const EffectPaintPropertyNode> parent, + float opacity, + CompositingReasons compositing_reasons = CompositingReason::kNone) { + return CreateOpacityEffect(parent, parent->LocalTransformSpace(), + parent->OutputClip(), opacity, + compositing_reasons); +} + +inline scoped_refptr<EffectPaintPropertyNode> CreateFilterEffect( + scoped_refptr<const EffectPaintPropertyNode> parent, + scoped_refptr<const TransformPaintPropertyNode> local_transform_space, + scoped_refptr<const ClipPaintPropertyNode> output_clip, + CompositorFilterOperations filter, + const FloatPoint& paint_offset = FloatPoint(), + CompositingReasons compositing_reasons = CompositingReason::kNone) { + EffectPaintPropertyNode::State state; + state.local_transform_space = local_transform_space; + state.output_clip = output_clip; + state.filter = std::move(filter); + state.paint_offset = paint_offset; + state.direct_compositing_reasons = compositing_reasons; + return EffectPaintPropertyNode::Create(std::move(parent), std::move(state)); +} + +inline scoped_refptr<EffectPaintPropertyNode> CreateFilterEffect( + scoped_refptr<const EffectPaintPropertyNode> parent, + CompositorFilterOperations filter, + const FloatPoint& paint_offset = FloatPoint(), + CompositingReasons compositing_reasons = CompositingReason::kNone) { + return CreateFilterEffect(parent, parent->LocalTransformSpace(), + parent->OutputClip(), filter, paint_offset, + compositing_reasons); +} + +inline scoped_refptr<ClipPaintPropertyNode> CreateClip( + scoped_refptr<const ClipPaintPropertyNode> parent, + scoped_refptr<const TransformPaintPropertyNode> local_transform_space, + const FloatRoundedRect& clip_rect, + CompositingReasons compositing_reasons = CompositingReason::kNone) { + ClipPaintPropertyNode::State state; + state.local_transform_space = local_transform_space; + state.clip_rect = clip_rect; + state.direct_compositing_reasons = compositing_reasons; + return ClipPaintPropertyNode::Create(parent, std::move(state)); +} + +inline scoped_refptr<ClipPaintPropertyNode> CreateClipPathClip( + scoped_refptr<const ClipPaintPropertyNode> parent, + scoped_refptr<const TransformPaintPropertyNode> local_transform_space, + const FloatRoundedRect& clip_rect) { + ClipPaintPropertyNode::State state; + state.local_transform_space = local_transform_space; + state.clip_rect = clip_rect; + state.clip_path = base::AdoptRef(new RefCountedPath); + return ClipPaintPropertyNode::Create(parent, std::move(state)); +} + +inline scoped_refptr<TransformPaintPropertyNode> CreateTransform( + scoped_refptr<const TransformPaintPropertyNode> parent, + const TransformationMatrix& matrix, + const FloatPoint3D& origin = FloatPoint3D(), + CompositingReasons compositing_reasons = CompositingReason::kNone) { + TransformPaintPropertyNode::State state; + state.matrix = matrix; + state.origin = origin; + state.direct_compositing_reasons = compositing_reasons; + return TransformPaintPropertyNode::Create(parent, std::move(state)); +} + +inline scoped_refptr<TransformPaintPropertyNode> CreateScrollTranslation( + scoped_refptr<const TransformPaintPropertyNode> parent, + float offset_x, + float offset_y, + scoped_refptr<const ScrollPaintPropertyNode> scroll, + CompositingReasons compositing_reasons = CompositingReason::kNone) { + TransformPaintPropertyNode::State state; + state.matrix.Translate(offset_x, offset_y); + state.direct_compositing_reasons = compositing_reasons; + state.scroll = scroll; + return TransformPaintPropertyNode::Create(parent, std::move(state)); +} - return default_properties; +inline PropertyTreeState DefaultPaintChunkProperties() { + return PropertyTreeState::Root(); } -} // namespace test } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_PROPERTY_TEST_HELPERS_H_ 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 0b6bf8f4c5c..c32b0eb1360 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 @@ -6,53 +6,45 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TESTING_PAINT_TEST_CONFIGURATIONS_H_ #include <gtest/gtest.h> +#include "third_party/blink/public/web/web_heap.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" namespace blink { enum { - kRootLayerScrolling = 1 << 0, - kSlimmingPaintV175 = 1 << 1, + kSlimmingPaintV175 = 1 << 0, + kBlinkGenPropertyTrees = 1 << 1, kSlimmingPaintV2 = 1 << 2, kUnderInvalidationChecking = 1 << 3, }; class PaintTestConfigurations : public testing::WithParamInterface<unsigned>, - private ScopedRootLayerScrollingForTest, private ScopedSlimmingPaintV175ForTest, + private ScopedBlinkGenPropertyTreesForTest, private ScopedSlimmingPaintV2ForTest, private ScopedPaintUnderInvalidationCheckingForTest { public: PaintTestConfigurations() - : ScopedRootLayerScrollingForTest(GetParam() & kRootLayerScrolling), - ScopedSlimmingPaintV175ForTest(GetParam() & kSlimmingPaintV175), + : ScopedSlimmingPaintV175ForTest(GetParam() & kSlimmingPaintV175), + ScopedBlinkGenPropertyTreesForTest(GetParam() & kBlinkGenPropertyTrees), ScopedSlimmingPaintV2ForTest(GetParam() & kSlimmingPaintV2), ScopedPaintUnderInvalidationCheckingForTest( GetParam() & kUnderInvalidationChecking) {} + ~PaintTestConfigurations() { + // Must destruct all objects before toggling back feature flags. + WebHeap::CollectAllGarbageForTesting(); + } }; -static constexpr unsigned kAllSlimmingPaintTestConfigurations[] = { - 0, - kSlimmingPaintV175, - kSlimmingPaintV2, - kRootLayerScrolling, - kSlimmingPaintV175 | kRootLayerScrolling, - kSlimmingPaintV2 | kRootLayerScrolling, -}; - -static constexpr unsigned kSlimmingPaintNonV1TestConfigurations[] = { - kSlimmingPaintV175, kSlimmingPaintV175 | kRootLayerScrolling, - kSlimmingPaintV2, kSlimmingPaintV2 | kRootLayerScrolling, -}; +#define INSTANTIATE_PAINT_TEST_CASE_P(test_class) \ + INSTANTIATE_TEST_CASE_P( \ + All, test_class, \ + ::testing::Values(0, kSlimmingPaintV175, kBlinkGenPropertyTrees, \ + kSlimmingPaintV2)) -static constexpr unsigned kSlimmingPaintV2TestConfigurations[] = { - kSlimmingPaintV2, kSlimmingPaintV2 | kRootLayerScrolling, -}; - -static constexpr unsigned kSlimmingPaintVersions[] = { - 0, kSlimmingPaintV175, kSlimmingPaintV2, -}; +#define INSTANTIATE_SPV2_TEST_CASE_P(test_class) \ + INSTANTIATE_TEST_CASE_P(All, test_class, ::testing::Values(kSlimmingPaintV2)) } // namespace blink 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 52b205c5fdd..0dfd6449b8d 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 @@ -55,27 +55,25 @@ TestPaintArtifact& TestPaintArtifact::Chunk( scoped_refptr<const TransformPaintPropertyNode> transform, scoped_refptr<const ClipPaintPropertyNode> clip, scoped_refptr<const EffectPaintPropertyNode> effect) { - PropertyTreeState property_tree_state(transform.get(), clip.get(), - effect.get()); - PaintChunkProperties properties(property_tree_state); - return Chunk(client, properties); + return Chunk(client, + PropertyTreeState(transform.get(), clip.get(), effect.get())); } TestPaintArtifact& TestPaintArtifact::Chunk( - const PaintChunkProperties& properties) { + const PropertyTreeState& properties) { return Chunk(NewClient(), properties); } -TestPaintArtifact& TestPaintArtifact::Chunk( - DisplayItemClient& client, - const PaintChunkProperties& properties) { - if (!paint_chunks_.IsEmpty()) - paint_chunks_.back().end_index = display_item_list_.size(); - paint_chunks_.push_back(PaintChunk( - display_item_list_.size(), 0, - PaintChunk::Id(client, DisplayItem::kDrawingFirst), properties)); +TestPaintArtifact& TestPaintArtifact::Chunk(DisplayItemClient& client, + const PropertyTreeState& state) { + auto& chunks = paint_chunks_data_.chunks; + if (!chunks.IsEmpty()) + chunks.back().end_index = display_item_list_.size(); + chunks.push_back( + PaintChunk(display_item_list_.size(), 0, + PaintChunk::Id(client, DisplayItem::kDrawingFirst), state)); // Assume PaintController has processed this chunk. - paint_chunks_.back().client_is_just_created = false; + chunks.back().client_is_just_created = false; return *this; } @@ -127,7 +125,7 @@ TestPaintArtifact& TestPaintArtifact::ScrollHitTest( } TestPaintArtifact& TestPaintArtifact::KnownToBeOpaque() { - paint_chunks_.back().known_to_be_opaque = true; + paint_chunks_data_.chunks.back().known_to_be_opaque = true; return *this; } @@ -135,10 +133,10 @@ const PaintArtifact& TestPaintArtifact::Build() { if (built_) return paint_artifact_; - if (!paint_chunks_.IsEmpty()) - paint_chunks_.back().end_index = display_item_list_.size(); - paint_artifact_ = - PaintArtifact(std::move(display_item_list_), std::move(paint_chunks_)); + if (!paint_chunks_data_.chunks.IsEmpty()) + paint_chunks_data_.chunks.back().end_index = display_item_list_.size(); + paint_artifact_ = PaintArtifact(std::move(display_item_list_), + std::move(paint_chunks_data_)); built_ = true; return paint_artifact_; } diff --git a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h index 89e0a096468..81aea7b349e 100644 --- a/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h +++ b/chromium/third_party/blink/renderer/platform/testing/test_paint_artifact.h @@ -49,7 +49,7 @@ class TestPaintArtifact { TestPaintArtifact& Chunk(scoped_refptr<const TransformPaintPropertyNode>, scoped_refptr<const ClipPaintPropertyNode>, scoped_refptr<const EffectPaintPropertyNode>); - TestPaintArtifact& Chunk(const PaintChunkProperties&); + TestPaintArtifact& Chunk(const PropertyTreeState&); TestPaintArtifact& RectDrawing(const FloatRect& bounds, Color); TestPaintArtifact& ForeignLayer(const FloatPoint&, const IntSize&, @@ -64,7 +64,7 @@ class TestPaintArtifact { scoped_refptr<const TransformPaintPropertyNode>, scoped_refptr<const ClipPaintPropertyNode>, scoped_refptr<const EffectPaintPropertyNode>); - TestPaintArtifact& Chunk(DisplayItemClient&, const PaintChunkProperties&); + TestPaintArtifact& Chunk(DisplayItemClient&, const PropertyTreeState&); TestPaintArtifact& RectDrawing(DisplayItemClient&, const FloatRect& bounds, Color); @@ -90,7 +90,7 @@ class TestPaintArtifact { // Exists if m_built is false. DisplayItemList display_item_list_; - Vector<PaintChunk> paint_chunks_; + PaintChunksAndRasterInvalidations paint_chunks_data_; // Exists if m_built is true. PaintArtifact paint_artifact_; diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc index 50eab238453..56fbb23341b 100644 --- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc +++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.cc @@ -38,14 +38,9 @@ #include "base/run_loop.h" #include "base/test/icu_test_util.h" #include "base/test/test_discardable_memory_allocator.h" -#include "cc/blink/web_compositor_support_impl.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "third_party/blink/public/platform/interface_provider.h" -#include "third_party/blink/public/platform/web_content_layer.h" -#include "third_party/blink/public/platform/web_external_texture_layer.h" -#include "third_party/blink/public/platform/web_image_layer.h" #include "third_party/blink/public/platform/web_runtime_features.h" -#include "third_party/blink/public/platform/web_scrollbar_layer.h" #include "third_party/blink/renderer/platform/font_family_names.h" #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/blink_resource_coordinator_base.h" @@ -58,7 +53,6 @@ #include "third_party/blink/renderer/platform/scheduler/base/task_queue_manager.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" -#include "third_party/blink/renderer/platform/wtf/cryptographically_random_number.h" #include "third_party/blink/renderer/platform/wtf/wtf.h" namespace blink { @@ -85,64 +79,13 @@ namespace { class DummyThread final : public blink::WebThread { public: bool IsCurrentThread() const override { return true; } - blink::WebScheduler* Scheduler() const override { return nullptr; } + blink::ThreadScheduler* Scheduler() const override { return nullptr; } }; } // namespace -std::unique_ptr<WebLayer> TestingCompositorSupport::CreateLayer() { - return nullptr; -} - -std::unique_ptr<WebLayer> TestingCompositorSupport::CreateLayerFromCCLayer( - cc::Layer*) { - return nullptr; -} - -std::unique_ptr<WebContentLayer> TestingCompositorSupport::CreateContentLayer( - WebContentLayerClient*) { - return nullptr; -} -std::unique_ptr<WebExternalTextureLayer> -TestingCompositorSupport::CreateExternalTextureLayer(cc::TextureLayerClient*) { - return nullptr; -} - -std::unique_ptr<WebImageLayer> TestingCompositorSupport::CreateImageLayer() { - return nullptr; -} - -std::unique_ptr<WebScrollbarLayer> -TestingCompositorSupport::CreateScrollbarLayer( - std::unique_ptr<WebScrollbar>, - WebScrollbarThemePainter, - std::unique_ptr<WebScrollbarThemeGeometry>) { - return nullptr; -} - -std::unique_ptr<WebScrollbarLayer> -TestingCompositorSupport::CreateOverlayScrollbarLayer( - std::unique_ptr<WebScrollbar>, - WebScrollbarThemePainter, - std::unique_ptr<WebScrollbarThemeGeometry>) { - return nullptr; -} - -std::unique_ptr<WebScrollbarLayer> -TestingCompositorSupport::CreateSolidColorScrollbarLayer( - WebScrollbar::Orientation, - int thumb_thickness, - int track_start, - bool is_left_side_vertical_scrollbar) { - return nullptr; -} - TestingPlatformSupport::TestingPlatformSupport() - : TestingPlatformSupport(TestingPlatformSupport::Config()) {} - -TestingPlatformSupport::TestingPlatformSupport(const Config& config) - : config_(config), - old_platform_(Platform::Current()), + : old_platform_(Platform::Current()), interface_provider_(new TestingInterfaceProvider) { DCHECK(old_platform_); } @@ -155,13 +98,6 @@ WebString TestingPlatformSupport::DefaultLocale() { return WebString::FromUTF8("en-US"); } -WebCompositorSupport* TestingPlatformSupport::CompositorSupport() { - if (config_.compositor_support) - return config_.compositor_support; - - return old_platform_ ? old_platform_->CompositorSupport() : nullptr; -} - WebThread* TestingPlatformSupport::CurrentThread() { return old_platform_ ? old_platform_->CurrentThread() : nullptr; } @@ -170,14 +106,6 @@ WebBlobRegistry* TestingPlatformSupport::GetBlobRegistry() { return old_platform_ ? old_platform_->GetBlobRegistry() : nullptr; } -WebClipboard* TestingPlatformSupport::Clipboard() { - return old_platform_ ? old_platform_->Clipboard() : nullptr; -} - -WebFileUtilities* TestingPlatformSupport::GetFileUtilities() { - return old_platform_ ? old_platform_->GetFileUtilities() : nullptr; -} - WebIDBFactory* TestingPlatformSupport::IdbFactory() { return old_platform_ ? old_platform_->IdbFactory() : nullptr; } @@ -235,10 +163,7 @@ ScopedUnittestsEnvironmentSetup::ScopedUnittestsEnvironmentSetup(int argc, WTF::Partitions::Initialize(nullptr); WTF::Initialize(nullptr); - compositor_support_ = std::make_unique<cc_blink::WebCompositorSupportImpl>(); - testing_platform_config_.compositor_support = compositor_support_.get(); - testing_platform_support_ = - std::make_unique<TestingPlatformSupport>(testing_platform_config_); + testing_platform_support_ = std::make_unique<TestingPlatformSupport>(); Platform::SetCurrentPlatformForTesting(testing_platform_support_.get()); if (BlinkResourceCoordinatorBase::IsEnabled()) { diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h index 33ad94665b3..b160d9a4261 100644 --- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h +++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support.h @@ -36,7 +36,6 @@ #include "base/macros.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_compositor_support.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" @@ -45,58 +44,22 @@ namespace base { class TestDiscardableMemoryAllocator; } -namespace cc_blink { -class WebCompositorSupportImpl; -} // namespace cc_blink - namespace blink { -class WebCompositorSupport; class WebThread; -class TestingCompositorSupport : public WebCompositorSupport { - std::unique_ptr<WebLayer> CreateLayer() override; - std::unique_ptr<WebLayer> CreateLayerFromCCLayer(cc::Layer*) override; - std::unique_ptr<WebContentLayer> CreateContentLayer( - WebContentLayerClient*) override; - std::unique_ptr<WebExternalTextureLayer> CreateExternalTextureLayer( - cc::TextureLayerClient*) override; - std::unique_ptr<WebImageLayer> CreateImageLayer() override; - std::unique_ptr<WebScrollbarLayer> CreateScrollbarLayer( - std::unique_ptr<WebScrollbar>, - WebScrollbarThemePainter, - std::unique_ptr<WebScrollbarThemeGeometry>) override; - std::unique_ptr<WebScrollbarLayer> CreateOverlayScrollbarLayer( - std::unique_ptr<WebScrollbar>, - WebScrollbarThemePainter, - std::unique_ptr<WebScrollbarThemeGeometry>) override; - std::unique_ptr<WebScrollbarLayer> CreateSolidColorScrollbarLayer( - WebScrollbar::Orientation, - int thumb_thickness, - int track_start, - bool is_left_side_vertical_scrollbar) override; -}; - // A base class to override Platform methods for testing. You can override the // behavior by subclassing TestingPlatformSupport or using // ScopedTestingPlatformSupport (see below). class TestingPlatformSupport : public Platform { public: - struct Config { - WebCompositorSupport* compositor_support = nullptr; - }; - TestingPlatformSupport(); - explicit TestingPlatformSupport(const Config&); ~TestingPlatformSupport() override; // Platform: WebString DefaultLocale() override; - WebCompositorSupport* CompositorSupport() override; WebThread* CurrentThread() override; WebBlobRegistry* GetBlobRegistry() override; - WebClipboard* Clipboard() override; - WebFileUtilities* GetFileUtilities() override; WebIDBFactory* IdbFactory() override; WebURLLoaderMockFactory* GetURLLoaderMockFactory() override; std::unique_ptr<blink::WebURLLoaderFactory> CreateDefaultURLLoaderFactory() @@ -109,7 +72,6 @@ class TestingPlatformSupport : public Platform { protected: class TestingInterfaceProvider; - const Config config_; Platform* const old_platform_; std::unique_ptr<TestingInterfaceProvider> interface_provider_; @@ -182,8 +144,6 @@ class ScopedUnittestsEnvironmentSetup final { std::unique_ptr<DummyPlatform> dummy_platform_; std::unique_ptr<DummyRendererResourceCoordinator> dummy_renderer_resource_coordinator_; - std::unique_ptr<cc_blink::WebCompositorSupportImpl> compositor_support_; - TestingPlatformSupport::Config testing_platform_config_; std::unique_ptr<TestingPlatformSupport> testing_platform_support_; }; diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc index 00012088c9c..810f5dc3ed7 100644 --- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc +++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.cc @@ -35,17 +35,13 @@ void PrepareCurrentThread(WaitableEvent* event, WebThread* thread) { TestingPlatformSupportWithMockScheduler:: TestingPlatformSupportWithMockScheduler() - : TestingPlatformSupportWithMockScheduler( - TestingPlatformSupport::Config()) {} - -TestingPlatformSupportWithMockScheduler:: - TestingPlatformSupportWithMockScheduler(const Config& config) - : TestingPlatformSupport(config), - mock_task_runner_(new cc::OrderedSimpleTaskRunner(&clock_, true)) { + : mock_task_runner_( + base::MakeRefCounted<cc::OrderedSimpleTaskRunner>(&clock_, true)) { DCHECK(IsMainThread()); - std::unique_ptr<scheduler::TaskQueueManagerForTest> task_queue_manager = - scheduler::TaskQueueManagerForTest::Create(nullptr, mock_task_runner_, - &clock_); + std::unique_ptr<base::sequence_manager::TaskQueueManagerForTest> + task_queue_manager = + base::sequence_manager::TaskQueueManagerForTest::Create( + nullptr, mock_task_runner_, &clock_); task_queue_manager_ = task_queue_manager.get(); scheduler_ = std::make_unique<scheduler::MainThreadSchedulerImpl>( std::move(task_queue_manager), base::nullopt); diff --git a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h index 8b483633dd6..c22570c3e55 100644 --- a/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h +++ b/chromium/third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h @@ -8,7 +8,7 @@ #include <memory> #include "base/test/simple_test_tick_clock.h" #include "third_party/blink/public/platform/web_thread.h" -#include "third_party/blink/renderer/platform/scheduler/test/task_queue_manager_for_test.h" +#include "third_party/blink/renderer/platform/scheduler/base/test/task_queue_manager_for_test.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" @@ -29,7 +29,6 @@ class TestingPlatformSupportWithMockScheduler : public TestingPlatformSupport { public: TestingPlatformSupportWithMockScheduler(); - explicit TestingPlatformSupportWithMockScheduler(const Config&); ~TestingPlatformSupportWithMockScheduler() override; // Platform: @@ -69,7 +68,7 @@ class TestingPlatformSupportWithMockScheduler : public TestingPlatformSupport { base::SimpleTestTickClock clock_; scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; std::unique_ptr<scheduler::MainThreadSchedulerImpl> scheduler_; - scheduler::TaskQueueManagerForTest* + base::sequence_manager::TaskQueueManagerForTest* task_queue_manager_; // Owned by scheduler_. std::unique_ptr<WebThread> thread_; }; 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 index a86dbb70161..53e4a2fdac9 100644 --- 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 @@ -7,7 +7,6 @@ #include <memory> #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_error.h" #include "third_party/blink/public/platform/web_rtc_rtp_receiver.h" #include "third_party/blink/public/platform/web_rtc_rtp_sender.h" #include "third_party/blink/public/platform/web_rtc_session_description.h" @@ -31,9 +30,12 @@ class DummyWebRTCRtpSender : public WebRTCRtpSender { std::unique_ptr<WebRTCDTMFSenderHandler> GetDtmfSender() const override { return nullptr; } - std::unique_ptr<WebRTCRtpParameters> GetParameters() const override { - return std::unique_ptr<WebRTCRtpParameters>(); + 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(std::unique_ptr<blink::WebRTCStatsReportCallback>) override {} private: @@ -85,9 +87,9 @@ WebRTCSessionDescription MockWebRTCPeerConnectionHandler::RemoteDescription() { return WebRTCSessionDescription(); } -WebRTCErrorType MockWebRTCPeerConnectionHandler::SetConfiguration( +webrtc::RTCErrorType MockWebRTCPeerConnectionHandler::SetConfiguration( const WebRTCConfiguration&) { - return WebRTCErrorType::kNone; + return webrtc::RTCErrorType::NONE; } void MockWebRTCPeerConnectionHandler::GetStats(const WebRTCStatsRequest&) {} 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 index f5bed12aefd..b3cd0e4c8df 100644 --- 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 @@ -5,6 +5,7 @@ #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 "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" @@ -32,7 +33,7 @@ class MockWebRTCPeerConnectionHandler : public WebRTCPeerConnectionHandler { const WebRTCSessionDescription&) override; WebRTCSessionDescription LocalDescription() override; WebRTCSessionDescription RemoteDescription() override; - WebRTCErrorType SetConfiguration(const WebRTCConfiguration&) override; + webrtc::RTCErrorType SetConfiguration(const WebRTCConfiguration&) override; void GetStats(const WebRTCStatsRequest&) override; void GetStats(std::unique_ptr<WebRTCStatsReportCallback>) override; std::unique_ptr<WebRTCRtpSender> AddTrack( diff --git a/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.cc b/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.cc index 7247f59aa6b..4343a44b45b 100644 --- a/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.cc +++ b/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.cc @@ -7,12 +7,10 @@ #include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_timeline.h" -#include "cc/blink/web_layer_impl.h" #include "cc/layers/layer.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_layer.h" #include "third_party/blink/public/platform/web_layer_tree_view.h" #include "third_party/blink/public/platform/web_size.h" @@ -48,9 +46,8 @@ WebLayerTreeViewImplForTesting::DefaultLayerTreeSettings() { return settings; } -bool WebLayerTreeViewImplForTesting::HasLayer(const WebLayer& layer) { - return layer.CcLayer()->GetLayerTreeHostForTesting() == - layer_tree_host_.get(); +bool WebLayerTreeViewImplForTesting::HasLayer(const cc::Layer& layer) { + return layer.GetLayerTreeHostForTesting() == layer_tree_host_.get(); } void WebLayerTreeViewImplForTesting::SetViewportSize( @@ -60,12 +57,12 @@ void WebLayerTreeViewImplForTesting::SetViewportSize( // TODO(ccameron): This likely causes surface invariant violations. layer_tree_host_->SetViewportSizeAndScale( gfx_size, layer_tree_host_->device_scale_factor(), - layer_tree_host_->local_surface_id()); + layer_tree_host_->local_surface_id_from_parent()); } -void WebLayerTreeViewImplForTesting::SetRootLayer(const blink::WebLayer& root) { - layer_tree_host_->SetRootLayer( - static_cast<const cc_blink::WebLayerImpl*>(&root)->layer()); +void WebLayerTreeViewImplForTesting::SetRootLayer( + scoped_refptr<cc::Layer> root) { + layer_tree_host_->SetRootLayer(root); } void WebLayerTreeViewImplForTesting::ClearRootLayer() { @@ -81,7 +78,7 @@ WebSize WebLayerTreeViewImplForTesting::GetViewportSize() const { layer_tree_host_->device_viewport_size().height()); } -void WebLayerTreeViewImplForTesting::SetBackgroundColor(WebColor color) { +void WebLayerTreeViewImplForTesting::SetBackgroundColor(SkColor color) { layer_tree_host_->set_background_color(color); } @@ -139,31 +136,18 @@ void WebLayerTreeViewImplForTesting::RegisterViewportLayers( const WebLayerTreeView::ViewportLayers& layers) { cc::LayerTreeHost::ViewportLayers viewport_layers; if (layers.overscroll_elasticity) { - viewport_layers.overscroll_elasticity = - static_cast<const cc_blink::WebLayerImpl*>(layers.overscroll_elasticity) - ->layer(); + viewport_layers.overscroll_elasticity = layers.overscroll_elasticity; } - viewport_layers.page_scale = - static_cast<const cc_blink::WebLayerImpl*>(layers.page_scale)->layer(); + viewport_layers.page_scale = layers.page_scale; if (layers.inner_viewport_container) { - viewport_layers.inner_viewport_container = - static_cast<const cc_blink::WebLayerImpl*>( - layers.inner_viewport_container) - ->layer(); + viewport_layers.inner_viewport_container = layers.inner_viewport_container; } if (layers.outer_viewport_container) { - viewport_layers.outer_viewport_container = - static_cast<const cc_blink::WebLayerImpl*>( - layers.outer_viewport_container) - ->layer(); + viewport_layers.outer_viewport_container = layers.outer_viewport_container; } - viewport_layers.inner_viewport_scroll = - static_cast<const cc_blink::WebLayerImpl*>(layers.inner_viewport_scroll) - ->layer(); + viewport_layers.inner_viewport_scroll = layers.inner_viewport_scroll; if (layers.outer_viewport_scroll) { - viewport_layers.outer_viewport_scroll = - static_cast<const cc_blink::WebLayerImpl*>(layers.outer_viewport_scroll) - ->layer(); + viewport_layers.outer_viewport_scroll = layers.outer_viewport_scroll; } layer_tree_host_->RegisterViewportLayers(viewport_layers); } diff --git a/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h b/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h index a715c170415..bfe8d1a3c89 100644 --- a/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h +++ b/chromium/third_party/blink/renderer/platform/testing/web_layer_tree_view_impl_for_testing.h @@ -14,14 +14,13 @@ namespace cc { class AnimationHost; +class Layer; class LayerTreeHost; class LayerTreeSettings; } namespace blink { -class WebLayer; - // Dummy WeblayerTeeView that does not support any actual compositing. class WebLayerTreeViewImplForTesting : public blink::WebLayerTreeView, @@ -36,15 +35,15 @@ class WebLayerTreeViewImplForTesting static cc::LayerTreeSettings DefaultLayerTreeSettings(); cc::LayerTreeHost* GetLayerTreeHost() { return layer_tree_host_.get(); } - bool HasLayer(const WebLayer&); + bool HasLayer(const cc::Layer&); void SetViewportSize(const blink::WebSize&); // blink::WebLayerTreeView implementation. - void SetRootLayer(const blink::WebLayer&) override; + void SetRootLayer(scoped_refptr<cc::Layer>) override; void ClearRootLayer() override; cc::AnimationHost* CompositorAnimationHost() override; WebSize GetViewportSize() const override; - void SetBackgroundColor(blink::WebColor) override; + void SetBackgroundColor(SkColor) override; void SetVisible(bool) override; void SetPageScaleFactorAndLimits(float page_scale_factor, float minimum, 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 ae4385607d2..43cea089b19 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 @@ -12,6 +12,7 @@ #include "third_party/blink/public/platform/web_url_loader_client.h" #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h" +#include "third_party/blink/renderer/platform/wtf/time.h" namespace blink { @@ -41,7 +42,7 @@ void WebURLLoaderMock::ServeAsynchronousRequest( WebURLLoaderTestDelegate* delegate, const WebURLResponse& response, const WebData& data, - const Optional<WebURLError>& error) { + const base::Optional<WebURLError>& error) { DCHECK(!using_default_loader_); if (!client_) return; @@ -79,7 +80,8 @@ void WebURLLoaderMock::ServeAsynchronousRequest( if (!self) return; - delegate->DidFinishLoading(client_, 0, data.size(), data.size(), data.size()); + delegate->DidFinishLoading(client_, TimeTicks(), data.size(), data.size(), + data.size()); } WebURL WebURLLoaderMock::ServeRedirect( @@ -105,6 +107,7 @@ WebURL WebURLLoaderMock::ServeRedirect( void WebURLLoaderMock::LoadSynchronously( const WebURLRequest& request, + WebURLLoaderClient* client, WebURLResponse& response, base::Optional<WebURLError>& error, WebData& data, @@ -119,7 +122,7 @@ void WebURLLoaderMock::LoadSynchronously( } AssertFallbackLoaderAvailability(request.Url(), default_loader_.get()); using_default_loader_ = true; - default_loader_->LoadSynchronously(request, response, error, data, + default_loader_->LoadSynchronously(request, client, response, error, data, encoded_data_length, encoded_body_length, downloaded_file_length, downloaded_blob); } diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h index ca63eec4a95..90accfd8f6c 100644 --- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h +++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock.h @@ -8,9 +8,9 @@ #include <memory> #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_url_loader.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { @@ -38,7 +38,7 @@ class WebURLLoaderMock : public WebURLLoader { void ServeAsynchronousRequest(WebURLLoaderTestDelegate* delegate, const WebURLResponse& response, const WebData& data, - const Optional<WebURLError>& error); + const base::Optional<WebURLError>& error); // Simulates the redirect being served. WebURL ServeRedirect(const WebURLRequest& request, @@ -46,8 +46,9 @@ class WebURLLoaderMock : public WebURLLoader { // WebURLLoader methods: void LoadSynchronously(const WebURLRequest&, + WebURLLoaderClient* client, WebURLResponse&, - Optional<WebURLError>&, + base::Optional<WebURLError>&, WebData&, int64_t& encoded_data_length, int64_t& encoded_body_length, diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc index 711876d3a34..5ea9210026a 100644 --- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc +++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.cc @@ -119,7 +119,7 @@ void WebURLLoaderMockFactoryImpl::ServeAsynchronousRequests() { pending_loaders_.erase(loader.get()); WebURLResponse response; - Optional<WebURLError> error; + base::Optional<WebURLError> error; WebData data; LoadRequest(request.Url(), &response, &error, &data); // Follow any redirects while the loader is still active. @@ -141,7 +141,7 @@ void WebURLLoaderMockFactoryImpl::ServeAsynchronousRequests() { } bool WebURLLoaderMockFactoryImpl::IsMockedURL(const blink::WebURL& url) { - Optional<WebURLError> error; + base::Optional<WebURLError> error; ResponseInfo response_info; return LookupURL(url, &error, &response_info); } @@ -153,7 +153,7 @@ void WebURLLoaderMockFactoryImpl::CancelLoad(WebURLLoaderMock* loader) { void WebURLLoaderMockFactoryImpl::LoadSynchronously( const WebURLRequest& request, WebURLResponse* response, - Optional<WebURLError>* error, + base::Optional<WebURLError>* error, WebData* data, int64_t* encoded_data_length) { LoadRequest(request.Url(), response, error, data); @@ -174,10 +174,11 @@ void WebURLLoaderMockFactoryImpl::RunUntilIdle() { base::RunLoop().RunUntilIdle(); } -void WebURLLoaderMockFactoryImpl::LoadRequest(const WebURL& url, - WebURLResponse* response, - Optional<WebURLError>* error, - WebData* data) { +void WebURLLoaderMockFactoryImpl::LoadRequest( + const WebURL& url, + WebURLResponse* response, + base::Optional<WebURLError>* error, + WebData* data) { ResponseInfo response_info; if (!LookupURL(url, error, &response_info)) { // Non mocked URLs should not have been passed to the default URLLoader. @@ -194,7 +195,7 @@ void WebURLLoaderMockFactoryImpl::LoadRequest(const WebURL& url, } bool WebURLLoaderMockFactoryImpl::LookupURL(const WebURL& url, - Optional<WebURLError>* error, + base::Optional<WebURLError>* error, ResponseInfo* response_info) { URLToErrorMap::const_iterator error_iter = url_to_error_info_.find(url); if (error_iter != url_to_error_info_.end()) diff --git a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h index c3481621d3c..3000148b2b0 100644 --- a/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h +++ b/chromium/third_party/blink/renderer/platform/testing/weburl_loader_mock_factory_impl.h @@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "third_party/blink/public/platform/web_url.h" #include "third_party/blink/public/platform/web_url_error.h" #include "third_party/blink/public/platform/web_url_loader_mock_factory.h" @@ -18,7 +19,6 @@ #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/kurl_hash.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { @@ -62,7 +62,7 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory { // Called by the loader to load a resource. void LoadSynchronously(const WebURLRequest& request, WebURLResponse* response, - Optional<WebURLError>* error, + base::Optional<WebURLError>* error, WebData* data, int64_t* encoded_data_length); void LoadAsynchronouly(const WebURLRequest& request, @@ -83,7 +83,7 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory { // accordingly. void LoadRequest(const WebURL& url, WebURLResponse* response, - Optional<WebURLError>* error, + base::Optional<WebURLError>* error, WebData* data); // Checks if the loader is pending. Otherwise, it may have been deleted. @@ -93,7 +93,7 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory { // // If the URL is found, returns true and sets |error| and |response_info|. bool LookupURL(const WebURL& url, - Optional<WebURLError>* error, + base::Optional<WebURLError>* error, ResponseInfo* response_info); // Reads |m_filePath| and puts its content in |data|. @@ -108,7 +108,7 @@ class WebURLLoaderMockFactoryImpl : public WebURLLoaderMockFactory { // All values must be valid, but we use Optional because HashMap requires // "empty value". - typedef HashMap<KURL, Optional<WebURLError>> URLToErrorMap; + typedef HashMap<KURL, base::Optional<WebURLError>> URLToErrorMap; URLToErrorMap url_to_error_info_; // Table of the registered URLs and the responses that they should receive. diff --git a/chromium/third_party/blink/renderer/platform/text/DEPS b/chromium/third_party/blink/renderer/platform/text/DEPS new file mode 100644 index 00000000000..a3eeba08689 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/text/DEPS @@ -0,0 +1,20 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/text", + + # Dependencies. + "+third_party/blink/renderer/platform/date_components.h", + "+third_party/blink/renderer/platform/fonts", + "+third_party/blink/renderer/platform/heap", + "+third_party/blink/renderer/platform/language.h", + "+third_party/blink/renderer/platform/layout_locale.h", + "+third_party/blink/renderer/platform/layout_test_support.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/weborigin", + "+third_party/blink/renderer/platform/wtf", +] diff --git a/chromium/third_party/blink/renderer/platform/text/bidi_resolver_test.cc b/chromium/third_party/blink/renderer/platform/text/bidi_resolver_test.cc index 4a66780d024..a9a0187f0b1 100644 --- a/chromium/third_party/blink/renderer/platform/text/bidi_resolver_test.cc +++ b/chromium/third_party/blink/renderer/platform/text/bidi_resolver_test.cc @@ -106,7 +106,7 @@ TEST(BidiResolver, ParagraphDirectionSurrogates) { // Test broken surrogate: trail appearing before // lead. (U+10858 units reversed) {{0xDC58, 0xD802}, 2, TextDirection::kLtr, false}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(kTestData); ++i) + for (size_t i = 0; i < arraysize(kTestData); ++i) TestDirectionality(kTestData[i]); } diff --git a/chromium/third_party/blink/renderer/platform/text/capitalize.cc b/chromium/third_party/blink/renderer/platform/text/capitalize.cc new file mode 100644 index 00000000000..858ef838910 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/text/capitalize.cc @@ -0,0 +1,60 @@ +// 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/text/capitalize.h" + +#include "third_party/blink/renderer/platform/text/text_break_iterator.h" +#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +String Capitalize(const String& string, UChar previous_character) { + if (string.IsNull()) + return string; + + unsigned length = string.length(); + const StringImpl& input = *string.Impl(); + + CHECK_LT(length, std::numeric_limits<unsigned>::max()); + StringBuffer<UChar> string_with_previous(length + 1); + string_with_previous[0] = previous_character == kNoBreakSpaceCharacter + ? kSpaceCharacter + : previous_character; + for (unsigned i = 1; i < length + 1; i++) { + // Replace   with a real space since ICU no longer treats   as a + // word separator. + if (input[i - 1] == kNoBreakSpaceCharacter) + string_with_previous[i] = kSpaceCharacter; + else + string_with_previous[i] = input[i - 1]; + } + + TextBreakIterator* boundary = + WordBreakIterator(string_with_previous.Characters(), length + 1); + if (!boundary) + return string; + + StringBuilder result; + result.ReserveCapacity(length); + + int32_t end_of_word; + int32_t start_of_word = boundary->first(); + for (end_of_word = boundary->next(); end_of_word != kTextBreakDone; + start_of_word = end_of_word, end_of_word = boundary->next()) { + if (start_of_word) { // Ignore first char of previous string + result.Append( + input[start_of_word - 1] == kNoBreakSpaceCharacter + ? kNoBreakSpaceCharacter + : WTF::Unicode::ToTitleCase(string_with_previous[start_of_word])); + } + for (int i = start_of_word + 1; i < end_of_word; i++) + result.Append(input[i - 1]); + } + + return result.ToString(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/capitalize.h b/chromium/third_party/blink/renderer/platform/text/capitalize.h new file mode 100644 index 00000000000..0490579b1cb --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/text/capitalize.h @@ -0,0 +1,21 @@ +// 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_TEXT_CAPITALIZE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_CAPITALIZE_H_ + +#include <unicode/utypes.h> +#include "third_party/blink/renderer/platform/platform_export.h" +#include "third_party/blink/renderer/platform/wtf/forward.h" + +namespace blink { + +// Capitalize (titlecase) each word of a string. +// https://drafts.csswg.org/css-text-3/#valdef-text-transform-capitalize +PLATFORM_EXPORT String Capitalize(const String&, + UChar previous_character = ' '); + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_CAPITALIZE_H_ diff --git a/chromium/third_party/blink/renderer/platform/text/capitalize_test.cc b/chromium/third_party/blink/renderer/platform/text/capitalize_test.cc new file mode 100644 index 00000000000..ffa15f97d81 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/text/capitalize_test.cc @@ -0,0 +1,35 @@ +// 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/text/capitalize.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/text/character.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +struct CapitalizeTestData { + String input; + String expected; + UChar previous_character = kSpaceCharacter; +}; + +class CapitalizeTest : public testing::Test, + public testing::WithParamInterface<CapitalizeTestData> { +}; + +INSTANTIATE_TEST_CASE_P(CapitalizeTest, + CapitalizeTest, + testing::Values(CapitalizeTestData{String(), String()}, + CapitalizeTestData{"", ""}, + CapitalizeTestData{"hello, world", + "Hello, World"})); + +TEST_P(CapitalizeTest, Data) { + const auto& data = GetParam(); + EXPECT_EQ(data.expected, Capitalize(data.input, data.previous_character)); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/character.cc b/chromium/third_party/blink/renderer/platform/text/character.cc index de4af537b67..76a37e6c180 100644 --- a/chromium/third_party/blink/renderer/platform/text/character.cc +++ b/chromium/third_party/blink/renderer/platform/text/character.cc @@ -61,9 +61,9 @@ static icu::UnicodeSet* createUnicodeSet(const UChar32* characters, return unicodeSet; } -#define CREATE_UNICODE_SET(name) \ - createUnicodeSet(name##Array, WTF_ARRAY_LENGTH(name##Array), name##Ranges, \ - WTF_ARRAY_LENGTH(name##Ranges)) +#define CREATE_UNICODE_SET(name) \ + createUnicodeSet(name##Array, arraysize(name##Array), name##Ranges, \ + arraysize(name##Ranges)) #define RETURN_HAS_PROPERTY(c, name) \ static icu::UnicodeSet* unicodeSet = nullptr; \ @@ -118,6 +118,10 @@ bool Character::IsPotentialCustomElementNameChar(UChar32 character) { RETURN_HAS_PROPERTY(character, kIsPotentialCustomElementNameChar); } +bool Character::IsBidiControl(UChar32 character) { + RETURN_HAS_PROPERTY(character, kIsBidiControl); +} + unsigned Character::ExpansionOpportunityCount(const LChar* characters, size_t length, TextDirection direction, diff --git a/chromium/third_party/blink/renderer/platform/text/character.h b/chromium/third_party/blink/renderer/platform/text/character.h index bbee1b062f1..22f0aaf93dd 100644 --- a/chromium/third_party/blink/renderer/platform/text/character.h +++ b/chromium/third_party/blink/renderer/platform/text/character.h @@ -102,6 +102,9 @@ class PLATFORM_EXPORT Character { } static bool IsPotentialCustomElementNameChar(UChar32 character); + // http://unicode.org/reports/tr9/#Directional_Formatting_Characters + static bool IsBidiControl(UChar32 character); + static bool TreatAsSpace(UChar32 c) { return c == kSpaceCharacter || c == kTabulationCharacter || c == kNewlineCharacter || c == kNoBreakSpaceCharacter; diff --git a/chromium/third_party/blink/renderer/platform/text/character_property.h b/chromium/third_party/blink/renderer/platform/text/character_property.h index e474c835507..4c6d88676d2 100644 --- a/chromium/third_party/blink/renderer/platform/text/character_property.h +++ b/chromium/third_party/blink/renderer/platform/text/character_property.h @@ -15,6 +15,7 @@ enum class CharacterProperty : CharacterPropertyType { kIsCJKIdeographOrSymbol = 0x0001, kIsUprightInMixedVertical = 0x0002, kIsPotentialCustomElementNameChar = 0x0004, + kIsBidiControl = 0x0008, }; inline CharacterProperty operator|(CharacterProperty a, CharacterProperty b) { diff --git a/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.cc b/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.cc index e4dd77bf68a..d3b4f6b1516 100644 --- a/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.cc +++ b/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.cc @@ -81,6 +81,7 @@ static void Generate(FILE* fp) { SET(kIsCJKIdeographOrSymbol); SET(kIsUprightInMixedVertical); SET(kIsPotentialCustomElementNameChar); + SET(kIsBidiControl); // Create a trie from the value array. UErrorCode error = U_ZERO_ERROR; diff --git a/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.h b/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.h index 57966cbd789..ee33611c7d7 100644 --- a/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.h +++ b/chromium/third_party/blink/renderer/platform/text/character_property_data_generator.h @@ -223,6 +223,13 @@ static const UChar32 kIsPotentialCustomElementNameCharRanges[] = { 0xF900, 0xFDCF, 0xFDF0, 0xFFFD, 0x10000, 0xEFFFF, }; +// http://unicode.org/reports/tr9/#Directional_Formatting_Characters +static const UChar32 kIsBidiControlArray[] = {0x061C, 0x200E, 0x200F}; + +static const UChar32 kIsBidiControlRanges[] = { + 0x202A, 0x202E, 0x2066, 0x2069, +}; + } // namespace blink #endif diff --git a/chromium/third_party/blink/renderer/platform/text/character_test.cc b/chromium/third_party/blink/renderer/platform/text/character_test.cc index 007442af75c..e82d4c91c0b 100644 --- a/chromium/third_party/blink/renderer/platform/text/character_test.cc +++ b/chromium/third_party/blink/renderer/platform/text/character_test.cc @@ -331,4 +331,22 @@ TEST(CharacterTest, Truncation) { EXPECT_FALSE(Character::IsNormalizedCanvasSpaceCharacter(test_char)); } +TEST(CharacterTest, IsBidiControl) { + EXPECT_TRUE(Character::IsBidiControl(0x202A)); // LEFT-TO-RIGHT EMBEDDING + EXPECT_TRUE(Character::IsBidiControl(0x202B)); // RIGHT-TO-LEFT EMBEDDING + EXPECT_TRUE(Character::IsBidiControl(0x202D)); // LEFT-TO-RIGHT OVERRIDE + EXPECT_TRUE(Character::IsBidiControl(0x202E)); // RIGHT-TO-LEFT OVERRIDE + EXPECT_TRUE(Character::IsBidiControl(0x202C)); // POP DIRECTIONAL FORMATTING + EXPECT_TRUE(Character::IsBidiControl(0x2066)); // LEFT-TO-RIGHT ISOLATE + EXPECT_TRUE(Character::IsBidiControl(0x2067)); // RIGHT-TO-LEFT ISOLATE + EXPECT_TRUE(Character::IsBidiControl(0x2068)); // FIRST STRONG ISOLATE + EXPECT_TRUE(Character::IsBidiControl(0x2069)); // POP DIRECTIONAL ISOLATE + EXPECT_TRUE(Character::IsBidiControl(0x200E)); // LEFT-TO-RIGHT MARK + EXPECT_TRUE(Character::IsBidiControl(0x200F)); // RIGHT-TO-LEFT MARK + EXPECT_TRUE(Character::IsBidiControl(0x061C)); // ARABIC LETTER MARK + EXPECT_FALSE(Character::IsBidiControl('A')); + EXPECT_FALSE(Character::IsBidiControl('0')); + EXPECT_FALSE(Character::IsBidiControl(0x05D0)); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc b/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc index b830775b8a7..c03f40b9990 100644 --- a/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc +++ b/chromium/third_party/blink/renderer/platform/text/hyphenation/hyphenator_aosp.cc @@ -174,7 +174,7 @@ bool Hyphenator::alphabetLookup(uint16_t* alpha_codes, alpha_codes[0] = 0; for (size_t i = 0; i < len; i++) { uint16_t c = word[i]; - auto p = std::lower_bound(begin, end, c << 11); + auto* p = std::lower_bound(begin, end, c << 11); if (p == end) { return false; } diff --git a/chromium/third_party/blink/renderer/platform/text/line_ending.cc b/chromium/third_party/blink/renderer/platform/text/line_ending.cc index 242c81d6f6b..9182cbd34a6 100644 --- a/chromium/third_party/blink/renderer/platform/text/line_ending.cc +++ b/chromium/third_party/blink/renderer/platform/text/line_ending.cc @@ -35,6 +35,7 @@ #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/noncopyable.h" #include "third_party/blink/renderer/platform/wtf/text/cstring.h" +#include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { @@ -89,18 +90,19 @@ class VectorCharAppendBuffer final : public OutputBuffer { Vector<char>& buffer_; }; -void InternalNormalizeLineEndingsToCRLF(const CString& from, - OutputBuffer& buffer) { - // Compute the new length. +template <typename CharType> +size_t RequiredSizeForCRLF(const CharType* data, size_t length) { size_t new_len = 0; - const char* p = from.data(); - while (p < from.data() + from.length()) { - char c = *p++; + const CharType* p = data; + while (p < data + length) { + CharType c = *p++; if (c == '\r') { - // Safe to look ahead because of trailing '\0'. - if (*p != '\n') { + if (p >= data + length || *p != '\n') { // Turn CR into CRLF. new_len += 2; + } else { + // We already have \r\n. We don't count this \r, and the + // following \n will count 2. } } else if (c == '\n') { // Turn LF into CRLF. @@ -110,23 +112,16 @@ void InternalNormalizeLineEndingsToCRLF(const CString& from, new_len += 1; } } - if (new_len < from.length()) - return; - - if (new_len == from.length()) { - buffer.Copy(from); - return; - } - - p = from.data(); - char* q = buffer.Allocate(new_len); + return new_len; +} - // Make a copy of the string. - while (p < from.data() + from.length()) { - char c = *p++; +template <typename CharType> +void NormalizeToCRLF(const CharType* src, size_t src_length, CharType* q) { + const CharType* p = src; + while (p < src + src_length) { + CharType c = *p++; if (c == '\r') { - // Safe to look ahead because of trailing '\0'. - if (*p != '\n') { + if (p >= src + src_length || *p != '\n') { // Turn CR into CRLF. *q++ = '\r'; *q++ = '\n'; @@ -142,6 +137,20 @@ void InternalNormalizeLineEndingsToCRLF(const CString& from, } } +void InternalNormalizeLineEndingsToCRLF(const CString& from, + OutputBuffer& buffer) { + size_t new_len = RequiredSizeForCRLF(from.data(), from.length()); + if (new_len < from.length()) + return; + + if (new_len == from.length()) { + buffer.Copy(from); + return; + } + + NormalizeToCRLF(from.data(), from.length(), buffer.Allocate(new_len)); +} + } // namespace void NormalizeLineEndingsToLF(const CString& from, Vector<char>& result) { @@ -202,6 +211,26 @@ CString NormalizeLineEndingsToCRLF(const CString& from) { return buffer.Buffer(); } +String NormalizeLineEndingsToCRLF(const String& src) { + size_t length = src.length(); + if (length == 0) + return src; + if (src.Is8Bit()) { + size_t new_length = RequiredSizeForCRLF(src.Characters8(), length); + if (new_length == length) + return src; + StringBuffer<LChar> buffer(new_length); + NormalizeToCRLF(src.Characters8(), length, buffer.Characters()); + return String::Adopt(buffer); + } + size_t new_length = RequiredSizeForCRLF(src.Characters16(), length); + if (new_length == length) + return src; + StringBuffer<UChar> buffer(new_length); + NormalizeToCRLF(src.Characters16(), length, buffer.Characters()); + return String::Adopt(buffer); +} + void NormalizeLineEndingsToNative(const CString& from, Vector<char>& result) { #if defined(OS_WIN) VectorCharAppendBuffer buffer(result); diff --git a/chromium/third_party/blink/renderer/platform/text/line_ending.h b/chromium/third_party/blink/renderer/platform/text/line_ending.h index 6dc43e228da..2c15f0f820a 100644 --- a/chromium/third_party/blink/renderer/platform/text/line_ending.h +++ b/chromium/third_party/blink/renderer/platform/text/line_ending.h @@ -40,6 +40,7 @@ namespace blink { // Normalize all line-endings in the given string to CRLF. PLATFORM_EXPORT CString NormalizeLineEndingsToCRLF(const CString& from); +PLATFORM_EXPORT String NormalizeLineEndingsToCRLF(const String& from); // Normalize all line-endings in the given string to LF and append the result to // the given buffer. diff --git a/chromium/third_party/blink/renderer/platform/text/line_ending_test.cc b/chromium/third_party/blink/renderer/platform/text/line_ending_test.cc new file mode 100644 index 00000000000..0ccc08456a9 --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/text/line_ending_test.cc @@ -0,0 +1,21 @@ +// 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/text/line_ending.h" + +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + +namespace blink { + +TEST(LineEndingTest, NormalizeLineEndingsToCRLF) { + EXPECT_EQ(String(""), NormalizeLineEndingsToCRLF("")); + EXPECT_EQ(String("\r\n"), NormalizeLineEndingsToCRLF("\n")); + EXPECT_EQ(String("\r\n"), NormalizeLineEndingsToCRLF("\r\n")); + EXPECT_EQ(String("\r\n"), NormalizeLineEndingsToCRLF("\r")); + + EXPECT_EQ(String("abc\r\ndef\r\n"), NormalizeLineEndingsToCRLF("abc\rdef\n")); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/locale_icu.cc b/chromium/third_party/blink/renderer/platform/text/locale_icu.cc index 1337a365ec0..13c08e0ec88 100644 --- a/chromium/third_party/blink/renderer/platform/text/locale_icu.cc +++ b/chromium/third_party/blink/renderer/platform/text/locale_icu.cc @@ -145,7 +145,7 @@ UDateFormat* LocaleICU::OpenDateFormat(UDateFormatStyle time_style, const UChar kGmtTimezone[3] = {'G', 'M', 'T'}; UErrorCode status = U_ZERO_ERROR; return udat_open(time_style, date_style, locale_.data(), kGmtTimezone, - WTF_ARRAY_LENGTH(kGmtTimezone), nullptr, -1, &status); + arraysize(kGmtTimezone), nullptr, -1, &status); } // We cannot use udat_*Symbols API to get standalone month names to use in @@ -259,8 +259,8 @@ void LocaleICU::InitializeCalendar() { static std::unique_ptr<Vector<String>> CreateFallbackMonthLabels() { std::unique_ptr<Vector<String>> labels = std::make_unique<Vector<String>>(); - labels->ReserveCapacity(WTF_ARRAY_LENGTH(WTF::kMonthFullName)); - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::kMonthFullName); ++i) + labels->ReserveCapacity(arraysize(WTF::kMonthFullName)); + for (unsigned i = 0; i < arraysize(WTF::kMonthFullName); ++i) labels->push_back(WTF::kMonthFullName[i]); return labels; } @@ -416,8 +416,8 @@ const Vector<String>& LocaleICU::ShortMonthLabels() { return short_month_labels_; } } - short_month_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(WTF::kMonthName)); - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::kMonthName); ++i) + short_month_labels_.ReserveCapacity(arraysize(WTF::kMonthName)); + for (unsigned i = 0; i < arraysize(WTF::kMonthName); ++i) short_month_labels_.push_back(WTF::kMonthName[i]); return short_month_labels_; } diff --git a/chromium/third_party/blink/renderer/platform/text/locale_mac.h b/chromium/third_party/blink/renderer/platform/text/locale_mac.h index 912fdbf9316..382682607da 100644 --- a/chromium/third_party/blink/renderer/platform/text/locale_mac.h +++ b/chromium/third_party/blink/renderer/platform/text/locale_mac.h @@ -48,7 +48,7 @@ class PLATFORM_EXPORT LocaleMac : public Locale { public: static std::unique_ptr<LocaleMac> Create(const String&); static std::unique_ptr<LocaleMac> Create(NSLocale*); - ~LocaleMac(); + ~LocaleMac() override; const Vector<String>& WeekDayShortLabels() override; unsigned FirstDayOfWeek() override; diff --git a/chromium/third_party/blink/renderer/platform/text/locale_mac.mm b/chromium/third_party/blink/renderer/platform/text/locale_mac.mm index 5c9f13272ce..6271af2bc49 100644 --- a/chromium/third_party/blink/renderer/platform/text/locale_mac.mm +++ b/chromium/third_party/blink/renderer/platform/text/locale_mac.mm @@ -127,7 +127,7 @@ const Vector<String>& LocaleMac::MonthLabels() { month_labels_.push_back(String([array objectAtIndex:i])); return month_labels_; } - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::kMonthFullName); ++i) + for (unsigned i = 0; i < arraysize(WTF::kMonthFullName); ++i) month_labels_.push_back(WTF::kMonthFullName[i]); return month_labels_; } @@ -142,7 +142,7 @@ const Vector<String>& LocaleMac::WeekDayShortLabels() { week_day_short_labels_.push_back(String([array objectAtIndex:i])); return week_day_short_labels_; } - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::kWeekdayName); ++i) { + for (unsigned i = 0; i < arraysize(WTF::kWeekdayName); ++i) { // weekdayName starts with Monday. week_day_short_labels_.push_back(WTF::kWeekdayName[(i + 6) % 7]); } @@ -254,7 +254,7 @@ const Vector<String>& LocaleMac::ShortMonthLabels() { short_month_labels_.push_back([array objectAtIndex:i]); return short_month_labels_; } - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(WTF::kMonthName); ++i) + for (unsigned i = 0; i < arraysize(WTF::kMonthName); ++i) short_month_labels_.push_back(WTF::kMonthName[i]); return short_month_labels_; } diff --git a/chromium/third_party/blink/renderer/platform/text/locale_win.cc b/chromium/third_party/blink/renderer/platform/text/locale_win.cc index a01610e2071..2030fbf60d9 100644 --- a/chromium/third_party/blink/renderer/platform/text/locale_win.cc +++ b/chromium/third_party/blink/renderer/platform/text/locale_win.cc @@ -148,13 +148,13 @@ void LocaleWin::EnsureShortMonthLabels() { LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10, LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12, }; - short_month_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(kTypes)); - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(kTypes); ++i) { + short_month_labels_.ReserveCapacity(arraysize(kTypes)); + for (unsigned i = 0; i < arraysize(kTypes); ++i) { short_month_labels_.push_back(GetLocaleInfoString(kTypes[i])); if (short_month_labels_.back().IsEmpty()) { short_month_labels_.Shrink(0); - short_month_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(WTF::kMonthName)); - for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::kMonthName); ++m) + short_month_labels_.ReserveCapacity(arraysize(WTF::kMonthName)); + for (unsigned m = 0; m < arraysize(WTF::kMonthName); ++m) short_month_labels_.push_back(WTF::kMonthName[m]); return; } @@ -274,13 +274,13 @@ void LocaleWin::EnsureMonthLabels() { LOCALE_SMONTHNAME7, LOCALE_SMONTHNAME8, LOCALE_SMONTHNAME9, LOCALE_SMONTHNAME10, LOCALE_SMONTHNAME11, LOCALE_SMONTHNAME12, }; - month_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(kTypes)); - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(kTypes); ++i) { + month_labels_.ReserveCapacity(arraysize(kTypes)); + for (unsigned i = 0; i < arraysize(kTypes); ++i) { month_labels_.push_back(GetLocaleInfoString(kTypes[i])); if (month_labels_.back().IsEmpty()) { month_labels_.Shrink(0); - month_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(WTF::kMonthFullName)); - for (unsigned m = 0; m < WTF_ARRAY_LENGTH(WTF::kMonthFullName); ++m) + month_labels_.ReserveCapacity(arraysize(WTF::kMonthFullName)); + for (unsigned m = 0; m < arraysize(WTF::kMonthFullName); ++m) month_labels_.push_back(WTF::kMonthFullName[m]); return; } @@ -295,14 +295,13 @@ void LocaleWin::EnsureWeekDayShortLabels() { LOCALE_SABBREVDAYNAME2, LOCALE_SABBREVDAYNAME3, LOCALE_SABBREVDAYNAME4, LOCALE_SABBREVDAYNAME5, LOCALE_SABBREVDAYNAME6}; - week_day_short_labels_.ReserveCapacity(WTF_ARRAY_LENGTH(kTypes)); - for (unsigned i = 0; i < WTF_ARRAY_LENGTH(kTypes); ++i) { + week_day_short_labels_.ReserveCapacity(arraysize(kTypes)); + for (unsigned i = 0; i < arraysize(kTypes); ++i) { week_day_short_labels_.push_back(GetLocaleInfoString(kTypes[i])); if (week_day_short_labels_.back().IsEmpty()) { week_day_short_labels_.Shrink(0); - week_day_short_labels_.ReserveCapacity( - WTF_ARRAY_LENGTH(WTF::kWeekdayName)); - for (unsigned w = 0; w < WTF_ARRAY_LENGTH(WTF::kWeekdayName); ++w) { + week_day_short_labels_.ReserveCapacity(arraysize(WTF::kWeekdayName)); + for (unsigned w = 0; w < arraysize(WTF::kWeekdayName); ++w) { // weekdayName starts with Monday. week_day_short_labels_.push_back(WTF::kWeekdayName[(w + 6) % 7]); } diff --git a/chromium/third_party/blink/renderer/platform/text/locale_win.h b/chromium/third_party/blink/renderer/platform/text/locale_win.h index c61238dc5bd..aa66f289549 100644 --- a/chromium/third_party/blink/renderer/platform/text/locale_win.h +++ b/chromium/third_party/blink/renderer/platform/text/locale_win.h @@ -43,7 +43,7 @@ namespace blink { class PLATFORM_EXPORT LocaleWin : public Locale { public: static std::unique_ptr<LocaleWin> Create(LCID, bool defaults_for_locale); - ~LocaleWin(); + ~LocaleWin() override; const Vector<String>& WeekDayShortLabels() override; unsigned FirstDayOfWeek() override; bool IsRTL() override; diff --git a/chromium/third_party/blink/renderer/platform/text/mac/hyphenation_mac.cc b/chromium/third_party/blink/renderer/platform/text/mac/hyphenation_mac.cc index 009de61f986..538074d088d 100644 --- a/chromium/third_party/blink/renderer/platform/text/mac/hyphenation_mac.cc +++ b/chromium/third_party/blink/renderer/platform/text/mac/hyphenation_mac.cc @@ -28,7 +28,8 @@ class HyphenationCF final : public Hyphenation { // locations and discards ones after |after_index|. // This version minimizes the computation for platforms that supports // LastHyphenLocation() but does not support HyphenLocations(). - size_t FirstHyphenLocation(const StringView& text, size_t after_index) const { + size_t FirstHyphenLocation(const StringView& text, + size_t after_index) const override { after_index = std::max(after_index, static_cast<size_t>(kMinimumPrefixLength - 1)); size_t hyphen_location = text.length(); diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc index 8b3625cfeec..6ff0d5437b7 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc +++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.cc @@ -204,11 +204,11 @@ static const unsigned char kBreakAllLineBreakClassTable[][BA_LB_COUNT / 8 + 1] = #undef DI #undef AL -static_assert(WTF_ARRAY_LENGTH(kAsciiLineBreakTable) == +static_assert(arraysize(kAsciiLineBreakTable) == kAsciiLineBreakTableLastChar - kAsciiLineBreakTableFirstChar + 1, "asciiLineBreakTable should be consistent"); -static_assert(WTF_ARRAY_LENGTH(kBreakAllLineBreakClassTable) == BA_LB_COUNT, +static_assert(arraysize(kBreakAllLineBreakClassTable) == BA_LB_COUNT, "breakAllLineBreakClassTable should be consistent"); static inline bool ShouldBreakAfter(UChar last_ch, UChar ch, UChar next_ch) { diff --git a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h index d5bff169749..02f32172082 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h +++ b/chromium/third_party/blink/renderer/platform/text/text_break_iterator.h @@ -147,33 +147,33 @@ class PLATFORM_EXPORT LazyLineBreakIterator final { const String& GetString() const { return string_; } UChar LastCharacter() const { - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); return prior_context_[1]; } UChar SecondToLastCharacter() const { - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); return prior_context_[0]; } void SetPriorContext(UChar last, UChar second_to_last) { - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); prior_context_[0] = second_to_last; prior_context_[1] = last; } void UpdatePriorContext(UChar last) { - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); prior_context_[0] = prior_context_[1]; prior_context_[1] = last; } void ResetPriorContext() { - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); prior_context_[0] = 0; prior_context_[1] = 0; @@ -181,7 +181,7 @@ class PLATFORM_EXPORT LazyLineBreakIterator final { unsigned PriorContextLength() const { unsigned prior_context_length = 0; - static_assert(WTF_ARRAY_LENGTH(prior_context_) == 2, + static_assert(arraysize(prior_context_) == 2, "TextBreakIterator has unexpected prior context length"); if (prior_context_[1]) { ++prior_context_length; diff --git a/chromium/third_party/blink/renderer/platform/text/text_run.h b/chromium/third_party/blink/renderer/platform/text/text_run.h index 2e5e3455e72..b70d5c5ac46 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_run.h +++ b/chromium/third_party/blink/renderer/platform/text/text_run.h @@ -24,15 +24,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_TEXT_RUN_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_TEXT_RUN_H_ +#include "base/optional.h" #include "third_party/blink/renderer/platform/fonts/glyph.h" -#include "third_party/blink/renderer/platform/geometry/float_rect.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/text/tab_size.h" #include "third_party/blink/renderer/platform/text/text_direction.h" #include "third_party/blink/renderer/platform/text/text_justify.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -300,19 +299,6 @@ inline void TextRun::SetTabSize(bool allow, TabSize size) { tab_size_ = size; } -// Container for parameters needed to paint TextRun. -struct TextRunPaintInfo { - STACK_ALLOCATED(); - - public: - explicit TextRunPaintInfo(const TextRun& r) - : run(r), from(0), to(r.length()) {} - - const TextRun& run; - unsigned from; - unsigned to; - FloatRect bounds; -}; - } // namespace blink + #endif diff --git a/chromium/third_party/blink/renderer/platform/text/text_run_test.cc b/chromium/third_party/blink/renderer/platform/text/text_run_test.cc index 4dd4b1e0ede..4ec66b1dfbf 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_run_test.cc +++ b/chromium/third_party/blink/renderer/platform/text/text_run_test.cc @@ -8,29 +8,23 @@ namespace blink { -#if defined(THREAD_SANITIZER) -#define MAYBE_IndexOfSubRun DISABLED_IndexOfSubRun // https://crbug.com/830648 -#else -#define MAYBE_IndexOfSubRun IndexOfSubRun -#endif - -TEST(TextRunTest, MAYBE_IndexOfSubRun) { - TextRun run(String("1234567890")); +TEST(TextRunTest, IndexOfSubRun) { + TextRun run("1234567890"); EXPECT_EQ(0u, run.IndexOfSubRun(run.SubRun(0, 4))); EXPECT_EQ(4u, run.IndexOfSubRun(run.SubRun(4, 4))); EXPECT_EQ(6u, run.IndexOfSubRun(run.SubRun(6, 4))); const unsigned kNotSubRun = std::numeric_limits<unsigned>::max(); EXPECT_EQ(kNotSubRun, run.IndexOfSubRun(run.SubRun(7, 4))); - EXPECT_EQ(kNotSubRun, run.IndexOfSubRun(TextRun(String("1")))); - EXPECT_EQ(kNotSubRun, run.IndexOfSubRun(TextRun(String(u"1")))); + EXPECT_EQ(kNotSubRun, run.IndexOfSubRun(TextRun("1"))); + EXPECT_EQ(kNotSubRun, run.IndexOfSubRun(TextRun(u"1"))); - TextRun run16(String(u"1234567890")); + TextRun run16(u"1234567890"); EXPECT_EQ(0u, run16.IndexOfSubRun(run16.SubRun(0, 4))); EXPECT_EQ(4u, run16.IndexOfSubRun(run16.SubRun(4, 4))); EXPECT_EQ(6u, run16.IndexOfSubRun(run16.SubRun(6, 4))); EXPECT_EQ(kNotSubRun, run16.IndexOfSubRun(run16.SubRun(7, 4))); - EXPECT_EQ(kNotSubRun, run16.IndexOfSubRun(TextRun(String("1")))); - EXPECT_EQ(kNotSubRun, run16.IndexOfSubRun(TextRun(String(u"1")))); + EXPECT_EQ(kNotSubRun, run16.IndexOfSubRun(TextRun("1"))); + EXPECT_EQ(kNotSubRun, run16.IndexOfSubRun(TextRun(u"1"))); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/text/unicode_utilities_test.cc b/chromium/third_party/blink/renderer/platform/text/unicode_utilities_test.cc index 712d7be2c80..125a2158e2d 100644 --- a/chromium/third_party/blink/renderer/platform/text/unicode_utilities_test.cc +++ b/chromium/third_party/blink/renderer/platform/text/unicode_utilities_test.cc @@ -139,14 +139,13 @@ TEST(UnicodeUtilitiesTest, FoldQuoteMarkOrSoftHyphenTest) { kRightSingleQuotationMarkCharacter, kSoftHyphenCharacter}; - String string_to_fold(kCharactersToFold, WTF_ARRAY_LENGTH(kCharactersToFold)); + String string_to_fold(kCharactersToFold, arraysize(kCharactersToFold)); Vector<UChar> buffer; string_to_fold.AppendTo(buffer); FoldQuoteMarksAndSoftHyphens(string_to_fold); - const String folded_string("\"\"\"\'\'\'\0", - WTF_ARRAY_LENGTH(kCharactersToFold)); + const String folded_string("\"\"\"\'\'\'\0", arraysize(kCharactersToFold)); EXPECT_EQ(string_to_fold, folded_string); FoldQuoteMarksAndSoftHyphens(buffer.data(), buffer.size()); @@ -159,37 +158,37 @@ TEST(UnicodeUtilitiesTest, OnlyKanaLettersEqualityTest) { // Check that non-Kana letters will be skipped. EXPECT_TRUE(CheckOnlyKanaLettersInStrings( - kNonKanaString1, WTF_ARRAY_LENGTH(kNonKanaString1), kNonKanaString2, - WTF_ARRAY_LENGTH(kNonKanaString2))); + kNonKanaString1, arraysize(kNonKanaString1), kNonKanaString2, + arraysize(kNonKanaString2))); const UChar kKanaString[] = {'e', 'f', 'g', 0x3041}; EXPECT_FALSE(CheckOnlyKanaLettersInStrings( - kKanaString, WTF_ARRAY_LENGTH(kKanaString), kNonKanaString2, - WTF_ARRAY_LENGTH(kNonKanaString2))); + kKanaString, arraysize(kKanaString), kNonKanaString2, + arraysize(kNonKanaString2))); // Compare with self. - EXPECT_TRUE(CheckOnlyKanaLettersInStrings( - kKanaString, WTF_ARRAY_LENGTH(kKanaString), kKanaString, - WTF_ARRAY_LENGTH(kKanaString))); + EXPECT_TRUE(CheckOnlyKanaLettersInStrings(kKanaString, arraysize(kKanaString), + kKanaString, + arraysize(kKanaString))); UChar voiced_kana_string1[] = {0x3042, 0x3099}; UChar voiced_kana_string2[] = {0x3042, 0x309A}; // Comparing strings with different sound marks should fail. EXPECT_FALSE(CheckOnlyKanaLettersInStrings( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); // Now strings will be the same. voiced_kana_string2[1] = 0x3099; EXPECT_TRUE(CheckOnlyKanaLettersInStrings( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); voiced_kana_string2[0] = 0x3043; EXPECT_FALSE(CheckOnlyKanaLettersInStrings( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); } TEST(UnicodeUtilitiesTest, StringsWithKanaLettersTest) { @@ -197,57 +196,53 @@ TEST(UnicodeUtilitiesTest, StringsWithKanaLettersTest) { const UChar kNonKanaString2[] = {'a', 'b', 'c'}; // Check that non-Kana letters will be compared. - EXPECT_TRUE(CheckKanaStringsEqual( - kNonKanaString1, WTF_ARRAY_LENGTH(kNonKanaString1), kNonKanaString2, - WTF_ARRAY_LENGTH(kNonKanaString2))); + EXPECT_TRUE(CheckKanaStringsEqual(kNonKanaString1, arraysize(kNonKanaString1), + kNonKanaString2, + arraysize(kNonKanaString2))); const UChar kKanaString[] = {'a', 'b', 'c', 0x3041}; - EXPECT_FALSE(CheckKanaStringsEqual(kKanaString, WTF_ARRAY_LENGTH(kKanaString), + EXPECT_FALSE(CheckKanaStringsEqual(kKanaString, arraysize(kKanaString), kNonKanaString2, - WTF_ARRAY_LENGTH(kNonKanaString2))); + arraysize(kNonKanaString2))); // Compare with self. - EXPECT_TRUE(CheckKanaStringsEqual(kKanaString, WTF_ARRAY_LENGTH(kKanaString), - kKanaString, - WTF_ARRAY_LENGTH(kKanaString))); + EXPECT_TRUE(CheckKanaStringsEqual(kKanaString, arraysize(kKanaString), + kKanaString, arraysize(kKanaString))); const UChar kKanaString2[] = {'x', 'y', 'z', 0x3041}; // Comparing strings with different non-Kana letters should fail. - EXPECT_FALSE(CheckKanaStringsEqual(kKanaString, WTF_ARRAY_LENGTH(kKanaString), - kKanaString2, - WTF_ARRAY_LENGTH(kKanaString2))); + EXPECT_FALSE(CheckKanaStringsEqual(kKanaString, arraysize(kKanaString), + kKanaString2, arraysize(kKanaString2))); const UChar kKanaString3[] = {'a', 'b', 'c', 0x3042, 0x3099, 'm', 'n', 'o'}; // Check that non-Kana letters after Kana letters will be compared. - EXPECT_TRUE( - CheckKanaStringsEqual(kKanaString3, WTF_ARRAY_LENGTH(kKanaString3), - kKanaString3, WTF_ARRAY_LENGTH(kKanaString3))); + EXPECT_TRUE(CheckKanaStringsEqual(kKanaString3, arraysize(kKanaString3), + kKanaString3, arraysize(kKanaString3))); const UChar kKanaString4[] = {'a', 'b', 'c', 0x3042, 0x3099, 'm', 'n', 'o', 'p'}; // And now comparing should fail. - EXPECT_FALSE( - CheckKanaStringsEqual(kKanaString3, WTF_ARRAY_LENGTH(kKanaString3), - kKanaString4, WTF_ARRAY_LENGTH(kKanaString4))); + EXPECT_FALSE(CheckKanaStringsEqual(kKanaString3, arraysize(kKanaString3), + kKanaString4, arraysize(kKanaString4))); UChar voiced_kana_string1[] = {0x3042, 0x3099}; UChar voiced_kana_string2[] = {0x3042, 0x309A}; // Comparing strings with different sound marks should fail. EXPECT_FALSE(CheckKanaStringsEqual( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); // Now strings will be the same. voiced_kana_string2[1] = 0x3099; EXPECT_TRUE(CheckKanaStringsEqual( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); voiced_kana_string2[0] = 0x3043; EXPECT_FALSE(CheckKanaStringsEqual( - voiced_kana_string1, WTF_ARRAY_LENGTH(voiced_kana_string1), - voiced_kana_string2, WTF_ARRAY_LENGTH(voiced_kana_string2))); + voiced_kana_string1, arraysize(voiced_kana_string1), voiced_kana_string2, + arraysize(voiced_kana_string2))); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/threading/DEPS b/chromium/third_party/blink/renderer/platform/threading/DEPS index 831fae70c03..7dd39b3f68b 100644 --- a/chromium/third_party/blink/renderer/platform/threading/DEPS +++ b/chromium/third_party/blink/renderer/platform/threading/DEPS @@ -1,6 +1,16 @@ include_rules = [ - # To whitelist base/ stuff Blink is allowed to include, we list up all - # directories and files instead of writing 'base/'. + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/threading", + + # Dependencies. "+base/task_scheduler", "+base/test", + "+third_party/blink/renderer/platform/cross_thread_functional.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/threading/background_task_runner.h", + "+third_party/blink/renderer/platform/waitable_event.h", + "+third_party/blink/renderer/platform/wtf", ] diff --git a/chromium/third_party/blink/renderer/platform/time_clamper.cc b/chromium/third_party/blink/renderer/platform/time_clamper.cc index 9e120ff6cc4..ab38f2afa44 100644 --- a/chromium/third_party/blink/renderer/platform/time_clamper.cc +++ b/chromium/third_party/blink/renderer/platform/time_clamper.cc @@ -5,16 +5,14 @@ #include "third_party/blink/renderer/platform/time_clamper.h" #include "base/bit_cast.h" +#include "base/rand_util.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/cryptographically_random_number.h" #include <cmath> namespace blink { -TimeClamper::TimeClamper() { - CryptographicallyRandomValues(&secret_, sizeof(secret_)); -} +TimeClamper::TimeClamper() : secret_(base::RandUint64()) {} double TimeClamper::ClampTimeResolution(double time_seconds) const { DCHECK_GE(time_seconds, 0); diff --git a/chromium/third_party/blink/renderer/platform/timer.cc b/chromium/third_party/blink/renderer/platform/timer.cc index 15a4992b6e1..dacd888c445 100644 --- a/chromium/third_party/blink/renderer/platform/timer.cc +++ b/chromium/third_party/blink/renderer/platform/timer.cc @@ -32,7 +32,7 @@ #include <limits> #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/address_sanitizer.h" #include "third_party/blink/renderer/platform/wtf/atomics.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" diff --git a/chromium/third_party/blink/renderer/platform/timer_test.cc b/chromium/third_party/blink/renderer/platform/timer_test.cc index 4e5460c7be6..7b69e301a43 100644 --- a/chromium/third_party/blink/renderer/platform/timer_test.cc +++ b/chromium/third_party/blink/renderer/platform/timer_test.cc @@ -7,19 +7,21 @@ #include <memory> #include <queue> #include "base/message_loop/message_loop.h" +#include "base/single_thread_task_runner.h" #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.h" #include "third_party/blink/renderer/platform/scheduler/base/task_queue_impl.h" -#include "third_party/blink/renderer/platform/scheduler/child/task_runner_impl.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/child/task_queue_with_task_type.h" #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h" -#include "third_party/blink/renderer/platform/scheduler/renderer/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/testing/testing_platform_support_with_mock_scheduler.h" #include "third_party/blink/renderer/platform/wtf/ref_counted.h" #include "third_party/blink/renderer/platform/wtf/time.h" +using base::sequence_manager::TaskQueue; using testing::ElementsAre; namespace blink { @@ -54,14 +56,11 @@ class TimerTest : public testing::Test { bool TimeTillNextDelayedTask(double* time) const { base::TimeTicks next_run_time; if (!platform_->GetMainThreadScheduler() - ->DefaultTaskQueue() - ->GetTimeDomain() + ->GetActiveTimeDomain() ->NextScheduledRunTime(&next_run_time)) return false; - *time = (next_run_time - platform_->GetMainThreadScheduler() - ->DefaultTaskQueue() - ->GetTimeDomain() - ->Now()) + *time = (next_run_time - + platform_->GetMainThreadScheduler()->GetActiveTimeDomain()->Now()) .InSecondsF(); return true; } @@ -130,7 +129,7 @@ class GCForbiddenScope final { TEST_F(TimerTest, StartOneShot_Zero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -143,7 +142,7 @@ TEST_F(TimerTest, StartOneShot_Zero) { TEST_F(TimerTest, StartOneShot_ZeroAndCancel) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -158,7 +157,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancel) { TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -180,7 +179,7 @@ TEST_F(TimerTest, StartOneShot_ZeroAndCancelThenRepost) { TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -200,7 +199,7 @@ TEST_F(TimerTest, StartOneShot_Zero_RepostingAfterRunning) { TEST_F(TimerTest, StartOneShot_NonZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -214,7 +213,7 @@ TEST_F(TimerTest, StartOneShot_NonZero) { TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -231,7 +230,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancel) { TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -257,7 +256,7 @@ TEST_F(TimerTest, StartOneShot_NonZeroAndCancelThenRepost) { TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -279,7 +278,7 @@ TEST_F(TimerTest, StartOneShot_NonZero_RepostingAfterRunning) { TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -294,7 +293,7 @@ TEST_F(TimerTest, PostingTimerTwiceWithSameRunTimeDoesNothing) { TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -305,7 +304,7 @@ TEST_F(TimerTest, PostingTimerTwiceWithNewerRunTimeCancelsOriginalTask) { TEST_F(TimerTest, PostingTimerTwiceWithLaterRunTimeCancelsOriginalTask) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -316,7 +315,7 @@ TEST_F(TimerTest, PostingTimerTwiceWithLaterRunTimeCancelsOriginalTask) { TEST_F(TimerTest, StartRepeatingTask) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); @@ -332,7 +331,7 @@ TEST_F(TimerTest, StartRepeatingTask) { TEST_F(TimerTest, StartRepeatingTask_ThenCancel) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); @@ -351,7 +350,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenCancel) { TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); @@ -371,7 +370,7 @@ TEST_F(TimerTest, StartRepeatingTask_ThenPostOneShot) { TEST_F(TimerTest, IsActive_NeverPosted) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); EXPECT_FALSE(timer.IsActive()); @@ -379,7 +378,7 @@ TEST_F(TimerTest, IsActive_NeverPosted) { TEST_F(TimerTest, IsActive_AfterPosting_OneShotZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -388,7 +387,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_OneShotZero) { TEST_F(TimerTest, IsActive_AfterPosting_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -397,7 +396,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_OneShotNonZero) { TEST_F(TimerTest, IsActive_AfterPosting_Repeating) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); @@ -406,7 +405,7 @@ TEST_F(TimerTest, IsActive_AfterPosting_Repeating) { TEST_F(TimerTest, IsActive_AfterRunning_OneShotZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -416,7 +415,7 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotZero) { TEST_F(TimerTest, IsActive_AfterRunning_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -426,7 +425,7 @@ TEST_F(TimerTest, IsActive_AfterRunning_OneShotNonZero) { TEST_F(TimerTest, IsActive_AfterRunning_Repeating) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(1), FROM_HERE); @@ -436,7 +435,7 @@ TEST_F(TimerTest, IsActive_AfterRunning_Repeating) { TEST_F(TimerTest, NextFireInterval_OneShotZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -445,7 +444,7 @@ TEST_F(TimerTest, NextFireInterval_OneShotZero) { TEST_F(TimerTest, NextFireInterval_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -456,7 +455,7 @@ TEST_F(TimerTest, NextFireInterval_OneShotNonZero_AfterAFewSeconds) { platform_->SetAutoAdvanceNowToPendingTasks(false); TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -466,7 +465,7 @@ TEST_F(TimerTest, NextFireInterval_OneShotNonZero_AfterAFewSeconds) { TEST_F(TimerTest, NextFireInterval_Repeating) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE); @@ -475,7 +474,7 @@ TEST_F(TimerTest, NextFireInterval_Repeating) { TEST_F(TimerTest, RepeatInterval_NeverStarted) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); EXPECT_FLOAT_EQ(0.0, timer.RepeatInterval()); @@ -483,7 +482,7 @@ TEST_F(TimerTest, RepeatInterval_NeverStarted) { TEST_F(TimerTest, RepeatInterval_OneShotZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -492,7 +491,7 @@ TEST_F(TimerTest, RepeatInterval_OneShotZero) { TEST_F(TimerTest, RepeatInterval_OneShotNonZero) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta::FromSeconds(10), FROM_HERE); @@ -501,7 +500,7 @@ TEST_F(TimerTest, RepeatInterval_OneShotNonZero) { TEST_F(TimerTest, RepeatInterval_Repeating) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(20), FROM_HERE); @@ -510,7 +509,7 @@ TEST_F(TimerTest, RepeatInterval_Repeating) { TEST_F(TimerTest, AugmentRepeatInterval) { TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE); EXPECT_FLOAT_EQ(10.0, timer.RepeatInterval()); @@ -534,7 +533,7 @@ TEST_F(TimerTest, AugmentRepeatInterval_TimerFireDelayed) { platform_->SetAutoAdvanceNowToPendingTasks(false); TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::CountingTask); timer.StartRepeating(TimeDelta::FromSeconds(10), FROM_HERE); EXPECT_FLOAT_EQ(10.0, timer.RepeatInterval()); @@ -552,7 +551,7 @@ TEST_F(TimerTest, RepeatingTimerDoesNotDrift) { platform_->SetAutoAdvanceNowToPendingTasks(false); TaskRunnerTimer<TimerTest> timer( - platform_->GetMainThreadScheduler()->DefaultTaskQueue(), this, + platform_->GetMainThreadScheduler()->DefaultTaskRunner(), this, &TimerTest::RecordNextFireTimeTask); timer.StartRepeating(TimeDelta::FromSeconds(2), FROM_HERE); @@ -604,12 +603,14 @@ class TimerForTest : public TaskRunnerTimer<TimerFiredClass> { }; TEST_F(TimerTest, UserSuppliedTaskRunner) { - scoped_refptr<scheduler::TaskQueue> task_runner( + scoped_refptr<TaskQueue> task_runner( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl = - scheduler::TaskRunnerImpl::Create(task_runner, TaskType::kInternalTest); - TimerForTest<TimerTest> timer(task_runner_impl, this, + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type = + scheduler::TaskQueueWithTaskType::Create(task_runner, + TaskType::kInternalTest); + TimerForTest<TimerTest> timer(task_queue_with_task_type, this, &TimerTest::CountingTask); timer.StartOneShot(TimeDelta(), FROM_HERE); @@ -621,7 +622,7 @@ TEST_F(TimerTest, RunOnHeapTimer) { scoped_refptr<OnHeapTimerOwner::Record> record = OnHeapTimerOwner::Record::Create(); Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner( - record, platform_->GetMainThreadScheduler()->DefaultTaskQueue()); + record, platform_->GetMainThreadScheduler()->DefaultTaskRunner()); owner->StartOneShot(TimeDelta(), FROM_HERE); @@ -634,7 +635,7 @@ TEST_F(TimerTest, DestructOnHeapTimer) { scoped_refptr<OnHeapTimerOwner::Record> record = OnHeapTimerOwner::Record::Create(); Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner( - record, platform_->GetMainThreadScheduler()->DefaultTaskQueue()); + record, platform_->GetMainThreadScheduler()->DefaultTaskRunner()); record->Dispose(); owner->StartOneShot(TimeDelta(), FROM_HERE); @@ -654,7 +655,7 @@ TEST_F(TimerTest, MarkOnHeapTimerAsUnreachable) { scoped_refptr<OnHeapTimerOwner::Record> record = OnHeapTimerOwner::Record::Create(); Persistent<OnHeapTimerOwner> owner = new OnHeapTimerOwner( - record, platform_->GetMainThreadScheduler()->DefaultTaskQueue()); + record, platform_->GetMainThreadScheduler()->DefaultTaskRunner()); record->Dispose(); owner->StartOneShot(TimeDelta(), FROM_HERE); @@ -683,9 +684,9 @@ class TaskObserver : public base::MessageLoop::TaskObserver { std::vector<scoped_refptr<base::SingleThreadTaskRunner>>* run_order) : task_runner_(std::move(task_runner)), run_order_(run_order) {} - void WillProcessTask(const base::PendingTask&) {} + void WillProcessTask(const base::PendingTask&) override {} - void DidProcessTask(const base::PendingTask&) { + void DidProcessTask(const base::PendingTask&) override { run_order_->push_back(task_runner_); } @@ -699,23 +700,27 @@ class TaskObserver : public base::MessageLoop::TaskObserver { TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) { std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order; - scoped_refptr<scheduler::TaskQueue> task_runner1( + scoped_refptr<TaskQueue> task_runner1( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl1 = - scheduler::TaskRunnerImpl::Create(task_runner1, TaskType::kInternalTest); - TaskObserver task_observer1(task_runner_impl1, &run_order); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 = + scheduler::TaskQueueWithTaskType::Create(task_runner1, + TaskType::kInternalTest); + TaskObserver task_observer1(task_queue_with_task_type1, &run_order); task_runner1->AddTaskObserver(&task_observer1); - scoped_refptr<scheduler::TaskQueue> task_runner2( + scoped_refptr<TaskQueue> task_runner2( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl2 = - scheduler::TaskRunnerImpl::Create(task_runner2, TaskType::kInternalTest); - TaskObserver task_observer2(task_runner_impl2, &run_order); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 = + scheduler::TaskQueueWithTaskType::Create(task_runner2, + TaskType::kInternalTest); + TaskObserver task_observer2(task_queue_with_task_type2, &run_order); task_runner2->AddTaskObserver(&task_observer2); - TimerForTest<TimerTest> timer(task_runner_impl1, this, + TimerForTest<TimerTest> timer(task_queue_with_task_type1, this, &TimerTest::CountingTask); double start_time = CurrentTimeTicksInSeconds(); @@ -724,13 +729,13 @@ TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) { platform_->RunForPeriodSeconds(0.5); - timer.MoveToNewTaskRunner(task_runner_impl2); + timer.MoveToNewTaskRunner(task_queue_with_task_type2); platform_->RunUntilIdle(); EXPECT_THAT(run_times_, ElementsAre(start_time + 1.0)); - EXPECT_THAT(run_order, ElementsAre(task_runner_impl2)); + EXPECT_THAT(run_order, ElementsAre(task_queue_with_task_type2)); EXPECT_TRUE(task_runner1->IsEmpty()); EXPECT_TRUE(task_runner2->IsEmpty()); @@ -739,23 +744,27 @@ TEST_F(TimerTest, MoveToNewTaskRunnerOneShot) { TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) { std::vector<scoped_refptr<base::SingleThreadTaskRunner>> run_order; - scoped_refptr<scheduler::TaskQueue> task_runner1( + scoped_refptr<TaskQueue> task_runner1( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl1 = - scheduler::TaskRunnerImpl::Create(task_runner1, TaskType::kInternalTest); - TaskObserver task_observer1(task_runner_impl1, &run_order); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 = + scheduler::TaskQueueWithTaskType::Create(task_runner1, + TaskType::kInternalTest); + TaskObserver task_observer1(task_queue_with_task_type1, &run_order); task_runner1->AddTaskObserver(&task_observer1); - scoped_refptr<scheduler::TaskQueue> task_runner2( + scoped_refptr<TaskQueue> task_runner2( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl2 = - scheduler::TaskRunnerImpl::Create(task_runner2, TaskType::kInternalTest); - TaskObserver task_observer2(task_runner_impl2, &run_order); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 = + scheduler::TaskQueueWithTaskType::Create(task_runner2, + TaskType::kInternalTest); + TaskObserver task_observer2(task_queue_with_task_type2, &run_order); task_runner2->AddTaskObserver(&task_observer2); - TimerForTest<TimerTest> timer(task_runner_impl1, this, + TimerForTest<TimerTest> timer(task_queue_with_task_type1, this, &TimerTest::CountingTask); double start_time = CurrentTimeTicksInSeconds(); @@ -764,15 +773,17 @@ TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) { platform_->RunForPeriodSeconds(2.5); - timer.MoveToNewTaskRunner(task_runner_impl2); + timer.MoveToNewTaskRunner(task_queue_with_task_type2); platform_->RunForPeriodSeconds(2); EXPECT_THAT(run_times_, ElementsAre(start_time + 1.0, start_time + 2.0, start_time + 3.0, start_time + 4.0)); - EXPECT_THAT(run_order, ElementsAre(task_runner_impl1, task_runner_impl1, - task_runner_impl2, task_runner_impl2)); + EXPECT_THAT( + run_order, + ElementsAre(task_queue_with_task_type1, task_queue_with_task_type1, + task_queue_with_task_type2, task_queue_with_task_type2)); EXPECT_TRUE(task_runner1->IsEmpty()); EXPECT_FALSE(task_runner2->IsEmpty()); @@ -781,19 +792,23 @@ TEST_F(TimerTest, MoveToNewTaskRunnerRepeating) { // This test checks that when inactive timer is moved to a different task // runner it isn't activated. TEST_F(TimerTest, MoveToNewTaskRunnerWithoutTasks) { - scoped_refptr<scheduler::TaskQueue> task_runner1( + scoped_refptr<TaskQueue> task_runner1( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl1 = - scheduler::TaskRunnerImpl::Create(task_runner1, TaskType::kInternalTest); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type1 = + scheduler::TaskQueueWithTaskType::Create(task_runner1, + TaskType::kInternalTest); - scoped_refptr<scheduler::TaskQueue> task_runner2( + scoped_refptr<TaskQueue> task_runner2( platform_->GetMainThreadScheduler()->NewTimerTaskQueue( - scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable)); - scoped_refptr<scheduler::TaskRunnerImpl> task_runner_impl2 = - scheduler::TaskRunnerImpl::Create(task_runner2, TaskType::kInternalTest); + scheduler::MainThreadTaskQueue::QueueType::kFrameThrottleable, + nullptr)); + scoped_refptr<scheduler::TaskQueueWithTaskType> task_queue_with_task_type2 = + scheduler::TaskQueueWithTaskType::Create(task_runner2, + TaskType::kInternalTest); - TimerForTest<TimerTest> timer(task_runner_impl1, this, + TimerForTest<TimerTest> timer(task_queue_with_task_type1, this, &TimerTest::CountingTask); platform_->RunUntilIdle(); diff --git a/chromium/third_party/blink/renderer/platform/transforms/DEPS b/chromium/third_party/blink/renderer/platform/transforms/DEPS new file mode 100644 index 00000000000..ab3e5b684bd --- /dev/null +++ b/chromium/third_party/blink/renderer/platform/transforms/DEPS @@ -0,0 +1,16 @@ +include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/transforms", + + # Dependencies. + "+third_party/blink/renderer/platform/animation", + "+third_party/blink/renderer/platform/cpu/mips/common_macros_msa.h", + "+third_party/blink/renderer/platform/geometry", + "+third_party/blink/renderer/platform/json", + "+third_party/blink/renderer/platform/length_functions.h", + "+third_party/blink/renderer/platform/length.h", + "+third_party/blink/renderer/platform/wtf", +] 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 2638c9974c2..c28d2bea671 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 @@ -36,7 +36,7 @@ class PLATFORM_EXPORT IdentityTransformOperation final return base::AdoptRef(new IdentityTransformOperation()); } - virtual bool CanBlendWith(const TransformOperation& other) const { + bool CanBlendWith(const TransformOperation& other) const override { return IsSameType(other); } 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 83e9188e6c7..a69bc6a4c19 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 @@ -48,7 +48,7 @@ class PLATFORM_EXPORT InterpolatedTransformOperation final new InterpolatedTransformOperation(from, to, progress)); } - virtual bool CanBlendWith(const TransformOperation& other) const { + bool CanBlendWith(const TransformOperation& other) const override { return IsSameType(other); } 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 d01da19fe28..304425ec65a 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 @@ -40,7 +40,7 @@ class PLATFORM_EXPORT Matrix3DTransformOperation final TransformationMatrix Matrix() const { return matrix_; } - virtual bool CanBlendWith(const TransformOperation& other) const { + bool CanBlendWith(const TransformOperation& other) const override { return false; } 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 2d0cdaedda4..409dd2104c6 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 @@ -51,7 +51,7 @@ class PLATFORM_EXPORT MatrixTransformOperation final return TransformationMatrix(a_, b_, c_, d_, e_, f_); } - virtual bool CanBlendWith(const TransformOperation& other) const { + bool CanBlendWith(const TransformOperation& other) const override { return false; } 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 28728bdac53..6928e93dd61 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 @@ -39,7 +39,7 @@ class PLATFORM_EXPORT PerspectiveTransformOperation final double Perspective() const { return p_; } - virtual bool CanBlendWith(const TransformOperation& other) const { + bool CanBlendWith(const TransformOperation& other) const override { return IsSameType(other); } 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 4fbdaa271eb..2aae491d965 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 @@ -69,7 +69,7 @@ class PLATFORM_EXPORT RotateTransformOperation : public TransformOperation { double& result_angle_a, double& result_angle_b); - virtual bool CanBlendWith(const TransformOperation& other) const; + bool CanBlendWith(const TransformOperation& other) const override; OperationType GetType() const override { return type_; } OperationType PrimitiveType() const final { return kRotate3D; } 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 91d37321729..d21dd97492c 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 @@ -53,7 +53,7 @@ class PLATFORM_EXPORT ScaleTransformOperation final double Y() const { return y_; } double Z() const { return z_; } - virtual bool CanBlendWith(const TransformOperation& other) const; + bool CanBlendWith(const TransformOperation& other) const override; void Apply(TransformationMatrix& transform, const FloatSize&) const override { transform.Scale3d(x_, y_, z_); @@ -80,7 +80,7 @@ class PLATFORM_EXPORT ScaleTransformOperation final return x_ == s->x_ && y_ == s->y_ && z_ == s->z_; } - virtual bool HasNonTrivial3DComponent() const { return z_ != 1.0; } + bool HasNonTrivial3DComponent() const override { return z_ != 1.0; } scoped_refptr<TransformOperation> Zoom(double factor) final { return this; } 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 11047965058..e638e60415d 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 @@ -41,7 +41,7 @@ class PLATFORM_EXPORT SkewTransformOperation final : public TransformOperation { double AngleX() const { return angle_x_; } double AngleY() const { return angle_y_; } - virtual bool CanBlendWith(const TransformOperation& other) const; + bool CanBlendWith(const TransformOperation& other) const override; static bool IsMatchingOperationType(OperationType type) { return type == kSkewX || type == kSkewY || type == kSkew; 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 ca2d669c5f2..ab95da6ec4e 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 @@ -118,8 +118,8 @@ TEST(TransformOperationsTest, EmpiricalAnimatedTranslatedBoundsTest) { // [0,1]. float progress[][2] = {{0, 1}, {-.25, 1.25}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(test_transforms); ++i) { - for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { + for (size_t i = 0; i < arraysize(test_transforms); ++i) { + for (size_t j = 0; j < arraysize(progress); ++j) { TransformOperations from_ops; TransformOperations to_ops; from_ops.Operations().push_back(TranslateTransformOperation::Create( @@ -181,8 +181,8 @@ TEST(TransformOperationsTest, EmpiricalAnimatedScaleBoundsTest) { // [0,1]. float progress[][2] = {{0, 1}, {-.25f, 1.25f}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(test_transforms); ++i) { - for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { + for (size_t i = 0; i < arraysize(test_transforms); ++i) { + for (size_t j = 0; j < arraysize(progress); ++j) { TransformOperations from_ops; TransformOperations to_ops; from_ops.Operations().push_back(TranslateTransformOperation::Create( @@ -213,7 +213,7 @@ TEST(TransformOperationsTest, AbsoluteAnimatedRotationBounds) { // 2 * sqrt(2) should give the same result. float sizes[] = {0, 0.1f, sqrt2, 2 * sqrt2}; to_ops.BlendedBoundsForBox(box, from_ops, 0, 1, &bounds); - for (size_t i = 0; i < WTF_ARRAY_LENGTH(sizes); ++i) { + for (size_t i = 0; i < arraysize(sizes); ++i) { box.SetSize(FloatPoint3D(sizes[i], sizes[i], 0)); EXPECT_TRUE(to_ops.BlendedBoundsForBox(box, from_ops, 0, 1, &bounds)); @@ -284,9 +284,9 @@ TEST(TransformOperationsTest, AbsoluteAnimatedOnAxisRotationBounds) { EXPECT_PRED_FORMAT2(FloatBoxTest::AssertAlmostEqual, box, bounds); } -// This would have been best as anonymous structs, but |WTF_ARRAY_LENGTH| +// This would have been best as anonymous structs, but |arraysize| // does not get along with anonymous structs once we support C++11 -// WTF_ARRAY_LENGTH will automatically support anonymous structs. +// arraysize will automatically support anonymous structs. struct ProblematicAxisTest { double x; @@ -314,7 +314,7 @@ TEST(TransformOperationsTest, AbsoluteAnimatedProblematicAxisRotationBounds) { {0, 1, 1, FloatBox(-1, dim1, dim1, 2, dim2, dim2)}, {1, 0, 1, FloatBox(dim1, -1, dim1, dim2, 2, dim2)}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { + for (size_t i = 0; i < arraysize(tests); ++i) { float x = tests[i].x; float y = tests[i].y; float z = tests[i].z; @@ -346,9 +346,9 @@ TEST(TransformOperationsTest, BlendedBoundsForRotationEmpiricalTests) { float progress[][2] = {{0, 1}, {-0.25f, 1.25f}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(axes); ++i) { - for (size_t j = 0; j < WTF_ARRAY_LENGTH(angles); ++j) { - for (size_t k = 0; k < WTF_ARRAY_LENGTH(progress); ++k) { + for (size_t i = 0; i < arraysize(axes); ++i) { + for (size_t j = 0; j < arraysize(angles); ++j) { + for (size_t k = 0; k < arraysize(progress); ++k) { float x = axes[i][0]; float y = axes[i][1]; float z = axes[i][2]; @@ -394,8 +394,8 @@ TEST(TransformOperationsTest, EmpiricalAnimatedPerspectiveBoundsTest) { float progress[][2] = {{0, 1}, {-0.1f, 1.1f}}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(depths); ++i) { - for (size_t j = 0; j < WTF_ARRAY_LENGTH(progress); ++j) { + for (size_t i = 0; i < arraysize(depths); ++i) { + for (size_t j = 0; j < arraysize(progress); ++j) { TransformOperations from_ops; TransformOperations to_ops; diff --git a/chromium/third_party/blink/renderer/platform/geometry/transform_state.cc b/chromium/third_party/blink/renderer/platform/transforms/transform_state.cc index 305b9f7ba7c..ac6b544e5e7 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/transform_state.cc +++ b/chromium/third_party/blink/renderer/platform/transforms/transform_state.cc @@ -23,7 +23,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/platform/geometry/transform_state.h" +#include "third_party/blink/renderer/platform/transforms/transform_state.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/platform/geometry/transform_state.h b/chromium/third_party/blink/renderer/platform/transforms/transform_state.h index 034ffeb36c2..67ff5b0fcd2 100644 --- a/chromium/third_party/blink/renderer/platform/geometry/transform_state.h +++ b/chromium/third_party/blink/renderer/platform/transforms/transform_state.h @@ -23,8 +23,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_TRANSFORM_STATE_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_TRANSFORM_STATE_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORM_STATE_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORM_STATE_H_ #include <memory> #include "third_party/blink/renderer/platform/geometry/float_point.h" @@ -154,4 +154,4 @@ class PLATFORM_EXPORT TransformState { } // namespace blink -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GEOMETRY_TRANSFORM_STATE_H_ +#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_TRANSFORMS_TRANSFORM_STATE_H_ diff --git a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc index 2a71d73dad6..69ff1646412 100644 --- a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc +++ b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.cc @@ -35,12 +35,14 @@ #include "third_party/blink/renderer/platform/geometry/float_rect.h" #include "third_party/blink/renderer/platform/geometry/int_rect.h" #include "third_party/blink/renderer/platform/geometry/layout_rect.h" +#include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/blink/renderer/platform/transforms/rotation.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/cpu.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "ui/gfx/transform.h" #if defined(ARCH_CPU_X86_64) #include <emmintrin.h> @@ -1881,6 +1883,11 @@ SkMatrix44 TransformationMatrix::ToSkMatrix44( return ret; } +gfx::Transform TransformationMatrix::ToTransform( + const TransformationMatrix& matrix) { + return gfx::Transform(TransformationMatrix::ToSkMatrix44(matrix)); +} + String TransformationMatrix::ToString(bool as_matrix) const { if (as_matrix) { // Return as a matrix in row-major order. @@ -1921,4 +1928,45 @@ std::ostream& operator<<(std::ostream& ostream, return ostream << transform.ToString(); } +static double RoundCloseToZero(double number) { + return std::abs(number) < 1e-7 ? 0 : number; +} + +std::unique_ptr<JSONArray> TransformAsJSONArray(const TransformationMatrix& t) { + std::unique_ptr<JSONArray> array = JSONArray::Create(); + { + std::unique_ptr<JSONArray> row = JSONArray::Create(); + row->PushDouble(RoundCloseToZero(t.M11())); + row->PushDouble(RoundCloseToZero(t.M12())); + row->PushDouble(RoundCloseToZero(t.M13())); + row->PushDouble(RoundCloseToZero(t.M14())); + array->PushArray(std::move(row)); + } + { + std::unique_ptr<JSONArray> row = JSONArray::Create(); + row->PushDouble(RoundCloseToZero(t.M21())); + row->PushDouble(RoundCloseToZero(t.M22())); + row->PushDouble(RoundCloseToZero(t.M23())); + row->PushDouble(RoundCloseToZero(t.M24())); + array->PushArray(std::move(row)); + } + { + std::unique_ptr<JSONArray> row = JSONArray::Create(); + row->PushDouble(RoundCloseToZero(t.M31())); + row->PushDouble(RoundCloseToZero(t.M32())); + row->PushDouble(RoundCloseToZero(t.M33())); + row->PushDouble(RoundCloseToZero(t.M34())); + array->PushArray(std::move(row)); + } + { + std::unique_ptr<JSONArray> row = JSONArray::Create(); + row->PushDouble(RoundCloseToZero(t.M41())); + row->PushDouble(RoundCloseToZero(t.M42())); + row->PushDouble(RoundCloseToZero(t.M43())); + row->PushDouble(RoundCloseToZero(t.M44())); + array->PushArray(std::move(row)); + } + return array; +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.h b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.h index 768903d8fa7..763d2b17bdb 100644 --- a/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.h +++ b/chromium/third_party/blink/renderer/platform/transforms/transformation_matrix.h @@ -35,6 +35,10 @@ #include "third_party/blink/renderer/platform/wtf/alignment.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" +namespace gfx { +class Transform; +} + namespace blink { class AffineTransform; @@ -43,6 +47,7 @@ class LayoutRect; class FloatRect; class FloatQuad; class FloatBox; +class JSONArray; struct Rotation; #if defined(ARCH_CPU_X86_64) #define TRANSFORMATION_MATRIX_USE_X86_64_SSE2 @@ -466,6 +471,7 @@ class PLATFORM_EXPORT TransformationMatrix { void ToColumnMajorFloatArray(FloatMatrix4& result) const; static SkMatrix44 ToSkMatrix44(const TransformationMatrix&); + static gfx::Transform ToTransform(const TransformationMatrix&); // If |asMatrix|, return the matrix in row-major order. Otherwise, return // the transform's decomposition which shows the translation, scale, etc. @@ -520,6 +526,8 @@ class PLATFORM_EXPORT TransformationMatrix { PLATFORM_EXPORT std::ostream& operator<<(std::ostream&, const TransformationMatrix&); +PLATFORM_EXPORT std::unique_ptr<JSONArray> TransformAsJSONArray( + const TransformationMatrix&); } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc index 0f0e8e8bec6..c537a94d38c 100644 --- a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc +++ b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator.cc @@ -98,18 +98,18 @@ void UkmTimeAggregator::Flush(TimeTicks current_time) { if (!has_data_) return; - auto builder = - recorder_->GetEntryBuilder(source_id_, event_name_.Utf8().data()); + ukm::UkmEntryBuilder builder(source_id_, event_name_.Utf8().data()); for (auto& record : metric_records_) { if (record.sample_count == 0) continue; - builder->AddMetric(record.worst_case_metric_name.Utf8().data(), - record.worst_case_duration.InMicroseconds()); - builder->AddMetric(record.average_metric_name.Utf8().data(), - record.total_duration.InMicroseconds() / - static_cast<int64_t>(record.sample_count)); + builder.SetMetric(record.worst_case_metric_name.Utf8().data(), + record.worst_case_duration.InMicroseconds()); + builder.SetMetric(record.average_metric_name.Utf8().data(), + record.total_duration.InMicroseconds() / + static_cast<int64_t>(record.sample_count)); record.reset(); } + builder.Record(recorder_); has_data_ = false; } diff --git a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc index 51814e94989..d2c8e2a5d8c 100644 --- a/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc +++ b/chromium/third_party/blink/renderer/platform/ukm_time_aggregator_test.cc @@ -10,6 +10,15 @@ namespace blink { namespace { +// These tests must use metrics defined in ukm.xml +const char* kEvent = "Blink.UpdateTime"; +const char* kMetric1 = "Compositing"; +const char* kMetric1Average = "Compositing.Average"; +const char* kMetric1WorstCase = "Compositing.WorstCase"; +const char* kMetric2 = "Paint"; +const char* kMetric2Average = "Paint.Average"; +const char* kMetric2WorstCase = "Paint.WorstCase"; + struct Timer { static double GetTime() { return fake_time; } static double fake_time; @@ -24,8 +33,8 @@ TEST(UkmTimeAggregatorTest, EmptyEventsNotRecorded) { ukm::TestUkmRecorder recorder; int64_t source_id = ukm::UkmRecorder::GetNewSourceID(); std::unique_ptr<UkmTimeAggregator> aggregator( - new UkmTimeAggregator("event", source_id, &recorder, - {"metric1", "metric2"}, TimeDelta::FromSeconds(1))); + new UkmTimeAggregator(kEvent, source_id, &recorder, {kMetric1, kMetric2}, + TimeDelta::FromSeconds(1))); Timer::fake_time += 10.; aggregator.reset(); @@ -41,8 +50,8 @@ TEST(UkmTimeAggregatorTest, EventsRecordedPerSecond) { ukm::TestUkmRecorder recorder; int64_t source_id = ukm::UkmRecorder::GetNewSourceID(); std::unique_ptr<UkmTimeAggregator> aggregator( - new UkmTimeAggregator("event", source_id, &recorder, - {"metric1", "metric2"}, TimeDelta::FromSeconds(1))); + new UkmTimeAggregator(kEvent, source_id, &recorder, {kMetric1, kMetric2}, + TimeDelta::FromSeconds(1))); // Have 100 events 99ms each; if the records are recorded once per second, we // should expect 9 records to be recorded while the timer ticks. 0-1, 1-2, // ..., 8-9 seconds. @@ -58,30 +67,28 @@ TEST(UkmTimeAggregatorTest, EventsRecordedPerSecond) { aggregator.reset(); EXPECT_EQ(recorder.entries_count(), 10u); - auto entries = recorder.GetEntriesByName("event"); + auto entries = recorder.GetEntriesByName(kEvent); EXPECT_EQ(entries.size(), 10u); for (auto* entry : entries) { - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.Average")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric1Average)); const int64_t* metric1_average = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.Average"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric1Average); EXPECT_NEAR(*metric1_average / 1e6, 0.099, 0.0001); - EXPECT_TRUE( - ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.WorstCase")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric1WorstCase)); const int64_t* metric1_worst = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.WorstCase"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric1WorstCase); EXPECT_NEAR(*metric1_worst / 1e6, 0.099, 0.0001); - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.Average")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric2Average)); const int64_t* metric2_average = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.Average"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric2Average); EXPECT_NEAR(*metric2_average / 1e6, 0.099, 0.0001); - EXPECT_TRUE( - ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.WorstCase")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric2WorstCase)); const int64_t* metric2_worst = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.WorstCase"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric2WorstCase); EXPECT_NEAR(*metric2_worst / 1e6, 0.099, 0.0001); } @@ -94,9 +101,9 @@ TEST(UkmTimeAggregatorTest, EventsAveragedCorrectly) { ukm::TestUkmRecorder recorder; int64_t source_id = ukm::UkmRecorder::GetNewSourceID(); - std::unique_ptr<UkmTimeAggregator> aggregator(new UkmTimeAggregator( - "event", source_id, &recorder, {"metric1", "metric2"}, - TimeDelta::FromSeconds(10000))); + std::unique_ptr<UkmTimeAggregator> aggregator( + new UkmTimeAggregator(kEvent, source_id, &recorder, {kMetric1, kMetric2}, + TimeDelta::FromSeconds(10000))); // 1, 2, and 3 seconds. for (int i = 1; i <= 3; ++i) { auto timer = aggregator->GetScopedTimer(0); @@ -114,31 +121,31 @@ TEST(UkmTimeAggregatorTest, EventsAveragedCorrectly) { } aggregator.reset(); - auto entries = recorder.GetEntriesByName("event"); + auto entries = recorder.GetEntriesByName(kEvent); EXPECT_EQ(entries.size(), 1u); auto* entry = entries[0]; - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.Average")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric1Average)); const int64_t* metric1_average = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.Average"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric1Average); // metric1 (1, 2, 3) average is 2 EXPECT_NEAR(*metric1_average / 1e6, 2.0, 0.0001); - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric1.WorstCase")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric1WorstCase)); const int64_t* metric1_worst = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric1.WorstCase"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric1WorstCase); // metric1 (1, 2, 3) worst case is 3 EXPECT_NEAR(*metric1_worst / 1e6, 3.0, 0.0001); - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.Average")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric2Average)); const int64_t* metric2_average = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.Average"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric2Average); // metric1 (3, 3, 3, 1) average is 2.5 EXPECT_NEAR(*metric2_average / 1e6, 2.5, 0.0001); - EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, "metric2.WorstCase")); + EXPECT_TRUE(ukm::TestUkmRecorder::EntryHasMetric(entry, kMetric2WorstCase)); const int64_t* metric2_worst = - ukm::TestUkmRecorder::GetEntryMetric(entry, "metric2.WorstCase"); + ukm::TestUkmRecorder::GetEntryMetric(entry, kMetric2WorstCase); // metric1 (3, 3, 3, 1) worst case is 3 EXPECT_NEAR(*metric2_worst / 1e6, 3.0, 0.0001); diff --git a/chromium/third_party/blink/renderer/platform/waitable_event.cc b/chromium/third_party/blink/renderer/platform/waitable_event.cc index 3b92b1e9f13..677113badc3 100644 --- a/chromium/third_party/blink/renderer/platform/waitable_event.cc +++ b/chromium/third_party/blink/renderer/platform/waitable_event.cc @@ -5,10 +5,10 @@ #include "third_party/blink/renderer/platform/waitable_event.h" #include <vector> +#include "base/optional.h" #include "base/synchronization/waitable_event.h" #include "third_party/blink/renderer/platform/heap/safe_point.h" #include "third_party/blink/renderer/platform/heap/thread_state.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/platform/web_mouse_event.cc b/chromium/third_party/blink/renderer/platform/web_mouse_event.cc index 116f214fda1..e21d084fddf 100644 --- a/chromium/third_party/blink/renderer/platform/web_mouse_event.cc +++ b/chromium/third_party/blink/renderer/platform/web_mouse_event.cc @@ -13,9 +13,9 @@ WebMouseEvent::WebMouseEvent(WebInputEvent::Type type, Button button_param, int click_count_param, int modifiers, - double time_stamp_seconds, + base::TimeTicks time_stamp, PointerId id_param) - : WebInputEvent(sizeof(WebMouseEvent), type, modifiers, time_stamp_seconds), + : WebInputEvent(sizeof(WebMouseEvent), type, modifiers, time_stamp), WebPointerProperties(id_param, WebPointerProperties::PointerType::kMouse, button_param), diff --git a/chromium/third_party/blink/renderer/platform/web_pointer_event.cc b/chromium/third_party/blink/renderer/platform/web_pointer_event.cc index db9d1237b55..c82c078b22f 100644 --- a/chromium/third_party/blink/renderer/platform/web_pointer_event.cc +++ b/chromium/third_party/blink/renderer/platform/web_pointer_event.cc @@ -32,7 +32,11 @@ WebInputEvent::Type PointerEventTypeForTouchPointState( WebPointerEvent::WebPointerEvent(const WebTouchEvent& touch_event, const WebTouchPoint& touch_point) - : WebInputEvent(sizeof(WebPointerEvent)), + : WebInputEvent(sizeof(WebPointerEvent), + PointerEventTypeForTouchPointState(touch_point.state), + touch_event.GetModifiers(), + touch_event.TimeStamp()), + WebPointerProperties(touch_point), hovering(touch_event.hovering), width(touch_point.radius_x * 2.f), @@ -40,9 +44,6 @@ WebPointerEvent::WebPointerEvent(const WebTouchEvent& touch_event, // WebInutEvent attributes SetFrameScale(touch_event.FrameScale()); SetFrameTranslate(touch_event.FrameTranslate()); - SetTimeStampSeconds(touch_event.TimeStampSeconds()); - SetType(PointerEventTypeForTouchPointState(touch_point.state)); - SetModifiers(touch_event.GetModifiers()); // WebTouchEvent attributes dispatch_type = touch_event.dispatch_type; moved_beyond_slop_region = touch_event.moved_beyond_slop_region; @@ -59,7 +60,10 @@ WebPointerEvent::WebPointerEvent(const WebTouchEvent& touch_event, WebPointerEvent::WebPointerEvent(WebInputEvent::Type type, const WebMouseEvent& mouse_event) - : WebInputEvent(sizeof(WebPointerEvent)), + : WebInputEvent(sizeof(WebPointerEvent), + type, + mouse_event.GetModifiers(), + mouse_event.TimeStamp()), WebPointerProperties(mouse_event), hovering(true), width(std::numeric_limits<float>::quiet_NaN()), @@ -68,17 +72,14 @@ WebPointerEvent::WebPointerEvent(WebInputEvent::Type type, DCHECK_LE(type, WebInputEvent::kPointerTypeLast); SetFrameScale(mouse_event.FrameScale()); SetFrameTranslate(mouse_event.FrameTranslate()); - SetTimeStampSeconds(mouse_event.TimeStampSeconds()); - SetType(type); - SetModifiers(mouse_event.GetModifiers()); } WebPointerEvent WebPointerEvent::CreatePointerCausesUaActionEvent( WebPointerProperties::PointerType type, - double time_stamp_seconds) { + base::TimeTicks time_stamp) { WebPointerEvent event; event.pointer_type = type; - event.SetTimeStampSeconds(time_stamp_seconds); + event.SetTimeStamp(time_stamp); event.SetType(WebInputEvent::Type::kPointerCausedUaAction); return event; } diff --git a/chromium/third_party/blink/renderer/platform/web_thread.cc b/chromium/third_party/blink/renderer/platform/web_thread.cc index 15d74082f25..5d100e61e50 100644 --- a/chromium/third_party/blink/renderer/platform/web_thread.cc +++ b/chromium/third_party/blink/renderer/platform/web_thread.cc @@ -10,7 +10,7 @@ #if defined(OS_WIN) #include <windows.h> -#elif defined(OS_POSIX) +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) #include <unistd.h> #endif @@ -36,7 +36,7 @@ WebThreadCreationParams& WebThreadCreationParams::SetFrameScheduler( #if defined(OS_WIN) static_assert(sizeof(blink::PlatformThreadId) >= sizeof(DWORD), "size of platform thread id is too small"); -#elif defined(OS_POSIX) +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) static_assert(sizeof(blink::PlatformThreadId) >= sizeof(pid_t), "size of platform thread id is too small"); #else diff --git a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc index b7c9540a3cc..fd0cd5f9958 100644 --- a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc +++ b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.cc @@ -9,7 +9,7 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/platform/heap/safe_point.h" #include "third_party/blink/renderer/platform/memory_coordinator.h" -#include "third_party/blink/renderer/platform/scheduler/child/web_scheduler.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { @@ -28,7 +28,7 @@ WebThreadSupportingGC::WebThreadSupportingGC( const WebThreadCreationParams* params, WebThread* thread) : thread_(thread) { - DCHECK(IsMainThread()); + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(!params || !thread); #if DCHECK_IS_ON() // We call this regardless of whether an existing thread is given or not, @@ -43,14 +43,14 @@ WebThreadSupportingGC::WebThreadSupportingGC( params ? *params : WebThreadCreationParams(WebThreadType::kTestThread)); thread_ = owning_thread_.get(); } - MemoryCoordinator::RegisterThread(thread_); + MemoryCoordinator::Instance().RegisterThread(thread_); } WebThreadSupportingGC::~WebThreadSupportingGC() { - DCHECK(IsMainThread()); + DETACH_FROM_THREAD(thread_checker_); // WebThread's destructor blocks until all the tasks are processed. owning_thread_.reset(); - MemoryCoordinator::UnregisterThread(thread_); + MemoryCoordinator::Instance().UnregisterThread(thread_); } void WebThreadSupportingGC::InitializeOnThread() { diff --git a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.h b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.h index c533dde5da3..4b7d177fafa 100644 --- a/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.h +++ b/chromium/third_party/blink/renderer/platform/web_thread_supporting_gc.h @@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEB_THREAD_SUPPORTING_GC_H_ #include <memory> +#include "base/threading/thread_checker.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/platform/heap/gc_task_runner.h" @@ -86,6 +87,8 @@ class PLATFORM_EXPORT WebThreadSupportingGC final { // existing thread via createForThread(). WebThread* thread_ = nullptr; std::unique_ptr<WebThread> owning_thread_; + + THREAD_CHECKER(thread_checker_); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/platform/web_vector_test.cc b/chromium/third_party/blink/renderer/platform/web_vector_test.cc index c90b0fdaf11..a0d8978ee9a 100644 --- a/chromium/third_party/blink/renderer/platform/web_vector_test.cc +++ b/chromium/third_party/blink/renderer/platform/web_vector_test.cc @@ -60,8 +60,8 @@ TEST(WebVectorTest, IsEmpty) { TEST(WebVectorTest, Swap) { const int kFirstData[] = {1, 2, 3, 4, 5}; const int kSecondData[] = {6, 5, 8}; - const size_t kFirstDataLength = WTF_ARRAY_LENGTH(kFirstData); - const size_t kSecondDataLength = WTF_ARRAY_LENGTH(kSecondData); + const size_t kFirstDataLength = arraysize(kFirstData); + const size_t kSecondDataLength = arraysize(kSecondData); WebVector<int> first(kFirstData, kFirstDataLength); WebVector<int> second(kSecondData, kSecondDataLength); @@ -136,9 +136,9 @@ TEST(WebVectorTest, EmplaceBackArgumentForwarding) { WebVector<WebString> vector; vector.reserve(1); WebUChar buffer[] = {'H', 'e', 'l', 'l', 'o', ' ', 'b', 'l', 'i', 'n', 'k'}; - vector.emplace_back(buffer, WTF_ARRAY_LENGTH(buffer)); + vector.emplace_back(buffer, arraysize(buffer)); ASSERT_EQ(1U, vector.size()); - EXPECT_EQ(WebString(buffer, WTF_ARRAY_LENGTH(buffer)), vector[0]); + EXPECT_EQ(WebString(buffer, arraysize(buffer)), vector[0]); } TEST(WebVectorTest, EmplaceBackElementPlacement) { diff --git a/chromium/third_party/blink/renderer/platform/weborigin/DEPS b/chromium/third_party/blink/renderer/platform/weborigin/DEPS index 41871a218f9..b33b9de59b3 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/DEPS +++ b/chromium/third_party/blink/renderer/platform/weborigin/DEPS @@ -1,5 +1,17 @@ include_rules = [ + # Don't depend on platform/. + "-third_party/blink/renderer/platform", + + # Module. + "+third_party/blink/renderer/platform/weborigin", + + # Dependencies. # net/ includes should be allowed only in a limited set of directories, # so we have separate DEPS from platform's one. "+net/base", + "+third_party/blink/renderer/platform/blob/blob_url.h", + "+third_party/blink/renderer/platform/platform_export.h", + "+third_party/blink/renderer/platform/runtime_enabled_features.h", + "+third_party/blink/renderer/platform/testing", + "+third_party/blink/renderer/platform/wtf", ] 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 93cfe0e38aa..76ef9117e81 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc +++ b/chromium/third_party/blink/renderer/platform/weborigin/kurl_test.cc @@ -83,7 +83,7 @@ TEST(KURLTest, Getters) { "xn--6qqa088eba", 0, "", nullptr, "/", nullptr, nullptr, nullptr, false}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(cases); i++) { + for (size_t i = 0; i < arraysize(cases); i++) { const GetterCase& c = cases[i]; const String& url = String::FromUTF8(c.url); @@ -174,7 +174,7 @@ TEST(KURLTest, Setters) { nullptr, "http://goo.com:92/#b"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(cases); i++) { + for (size_t i = 0; i < arraysize(cases); i++) { KURL kurl(cases[i].url); kurl.SetProtocol(cases[i].protocol); @@ -230,7 +230,7 @@ TEST(KURLTest, DecodeURLEscapeSequences) { {"%e4%bd%a0%e5%a5%bd", "\xe4\xbd\xa0\xe5\xa5\xbd"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(decode_cases); i++) { + for (size_t i = 0; i < arraysize(decode_cases); i++) { String input(decode_cases[i].input); String str = DecodeURLEscapeSequences(input); EXPECT_STREQ(decode_cases[i].output, str.Utf8().data()); @@ -243,8 +243,7 @@ TEST(KURLTest, DecodeURLEscapeSequences) { // Decode UTF-8. String decoded = DecodeURLEscapeSequences("%e6%bc%a2%e5%ad%97"); const UChar kDecodedExpected[] = {0x6F22, 0x5b57}; - EXPECT_EQ(String(kDecodedExpected, WTF_ARRAY_LENGTH(kDecodedExpected)), - decoded); + EXPECT_EQ(String(kDecodedExpected, arraysize(kDecodedExpected)), decoded); // Test the error behavior for invalid UTF-8 (we differ from WebKit here). String invalid = DecodeURLEscapeSequences("%e4%a0%e5%a5%bd"); @@ -272,7 +271,7 @@ TEST(KURLTest, EncodeWithURLEscapeSequences) { {"pqrstuvwxyz{|}~\x7f", "pqrstuvwxyz%7B%7C%7D~%7F"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(encode_cases); i++) { + for (size_t i = 0; i < arraysize(encode_cases); i++) { String input(encode_cases[i].input); String expected_output(encode_cases[i].output); String output = EncodeWithURLEscapeSequences(input); @@ -831,7 +830,7 @@ TEST(KURLTest, strippedForUseAsReferrer) { {"https://www.google.com/#", "https://www.google.com/"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(referrer_cases); i++) { + for (size_t i = 0; i < arraysize(referrer_cases); i++) { const KURL kurl(referrer_cases[i].input); String referrer = kurl.StrippedForUseAsReferrer(); EXPECT_STREQ(referrer_cases[i].output, referrer.Utf8().data()); 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 c756e55f4bf..8213041d59f 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc +++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.cc @@ -85,7 +85,7 @@ void SecurityOrigin::SetMap(URLSecurityOriginMap* map) { g_url_origin_map = map; } -static bool ShouldTreatAsUniqueOrigin(const KURL& url) { +static bool ShouldTreatAsOpaqueOrigin(const KURL& url) { if (!url.IsValid()) return true; @@ -118,11 +118,11 @@ SecurityOrigin::SecurityOrigin(const KURL& url) host_(url.Host()), port_(url.Port()), effective_port_(url.Port()), - is_unique_(false), + is_opaque_(false), universal_access_(false), domain_was_set_in_dom_(false), block_local_access_from_local_origin_(false), - is_unique_origin_potentially_trustworthy_(false) { + is_opaque_origin_potentially_trustworthy_(false) { if (protocol_.IsNull()) protocol_ = g_empty_string; if (host_.IsNull()) @@ -147,12 +147,12 @@ SecurityOrigin::SecurityOrigin() domain_(g_empty_string), port_(kInvalidPort), effective_port_(kInvalidPort), - is_unique_(true), + is_opaque_(true), universal_access_(false), domain_was_set_in_dom_(false), can_load_local_resources_(false), block_local_access_from_local_origin_(false), - is_unique_origin_potentially_trustworthy_(false) {} + is_opaque_origin_potentially_trustworthy_(false) {} SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) : protocol_(other->protocol_.IsolatedCopy()), @@ -160,20 +160,20 @@ SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) domain_(other->domain_.IsolatedCopy()), port_(other->port_), effective_port_(other->effective_port_), - is_unique_(other->is_unique_), + is_opaque_(other->is_opaque_), universal_access_(other->universal_access_), domain_was_set_in_dom_(other->domain_was_set_in_dom_), can_load_local_resources_(other->can_load_local_resources_), block_local_access_from_local_origin_( other->block_local_access_from_local_origin_), - is_unique_origin_potentially_trustworthy_( - other->is_unique_origin_potentially_trustworthy_) {} + is_opaque_origin_potentially_trustworthy_( + other->is_opaque_origin_potentially_trustworthy_) {} scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const KURL& url) { if (scoped_refptr<SecurityOrigin> origin = GetOriginFromMap(url)) return origin; - if (ShouldTreatAsUniqueOrigin(url)) + if (ShouldTreatAsOpaqueOrigin(url)) return base::AdoptRef(new SecurityOrigin()); if (ShouldUseInnerURL(url)) @@ -182,16 +182,16 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::Create(const KURL& url) { return base::AdoptRef(new SecurityOrigin(url)); } -scoped_refptr<SecurityOrigin> SecurityOrigin::CreateUnique() { +scoped_refptr<SecurityOrigin> SecurityOrigin::CreateUniqueOpaque() { scoped_refptr<SecurityOrigin> origin = base::AdoptRef(new SecurityOrigin()); - DCHECK(origin->IsUnique()); + DCHECK(origin->IsOpaque()); return origin; } scoped_refptr<SecurityOrigin> SecurityOrigin::CreateFromUrlOrigin( const url::Origin& origin) { if (origin.unique()) - return CreateUnique(); + return CreateUniqueOpaque(); DCHECK(String::FromUTF8(origin.scheme().c_str()).ContainsOnlyASCII()); DCHECK(String::FromUTF8(origin.host().c_str()).ContainsOnlyASCII()); @@ -201,7 +201,7 @@ scoped_refptr<SecurityOrigin> SecurityOrigin::CreateFromUrlOrigin( } url::Origin SecurityOrigin::ToUrlOrigin() const { - return IsUnique() + return IsOpaque() ? url::Origin() : url::Origin::CreateFromNormalizedTuple( StringUTF8Adaptor(protocol_).AsStringPiece().as_string(), @@ -234,7 +234,7 @@ bool SecurityOrigin::IsSecure(const KURL& url) { } bool SecurityOrigin::SerializesAsNull() const { - if (IsUnique()) + if (IsOpaque()) return true; if (IsLocal() && block_local_access_from_local_origin_) @@ -250,7 +250,7 @@ bool SecurityOrigin::CanAccess(const SecurityOrigin* other) const { if (this == other) return true; - if (IsUnique() || other->IsUnique()) + if (IsOpaque() || other->IsOpaque()) return false; // document.domain handling, as per @@ -298,13 +298,13 @@ bool SecurityOrigin::CanRequest(const KURL& url) const { if (GetOriginFromMap(url) == this) return true; - if (IsUnique()) + if (IsOpaque()) return false; scoped_refptr<const SecurityOrigin> target_origin = SecurityOrigin::Create(url); - if (target_origin->IsUnique()) + if (target_origin->IsOpaque()) return false; // We call isSameSchemeHostPort here instead of canAccess because we want @@ -324,6 +324,8 @@ bool SecurityOrigin::CanReadContent(const KURL& url) const { // This function exists because we treat data URLs as having a unique opaque // origin, see https://fetch.spec.whatwg.org/#main-fetch. + // TODO(dcheng): If we plumb around the 'precursor' origin, then maybe we + // don't need this? if (url.ProtocolIsData()) return true; @@ -351,8 +353,8 @@ bool SecurityOrigin::CanDisplay(const KURL& url) const { bool SecurityOrigin::IsPotentiallyTrustworthy() const { DCHECK_NE(protocol_, "data"); - if (IsUnique()) - return is_unique_origin_potentially_trustworthy_; + if (IsOpaque()) + return is_opaque_origin_potentially_trustworthy_; if (SchemeRegistry::ShouldTreatURLSchemeAsSecure(protocol_) || IsLocal() || IsLocalhost()) @@ -453,7 +455,7 @@ bool SecurityOrigin::IsSameSchemeHostPort(const SecurityOrigin* other) const { if (this == other) return true; - if (IsUnique() || other->IsUnique()) + if (IsOpaque() || other->IsOpaque()) return false; if (host_ != other->host_) @@ -477,10 +479,10 @@ bool SecurityOrigin::AreSameSchemeHostPort(const KURL& a, const KURL& b) { return origin_b->IsSameSchemeHostPort(origin_a.get()); } -const KURL& SecurityOrigin::UrlWithUniqueSecurityOrigin() { +const KURL& SecurityOrigin::UrlWithUniqueOpaqueOrigin() { DCHECK(IsMainThread()); - DEFINE_STATIC_LOCAL(const KURL, unique_security_origin_url, ("data:,")); - return unique_security_origin_url; + DEFINE_STATIC_LOCAL(const KURL, url, ("data:,")); + return url; } std::unique_ptr<SecurityOrigin::PrivilegeData> @@ -502,11 +504,11 @@ void SecurityOrigin::TransferPrivilegesFrom( privilege_data->block_local_access_from_local_origin_; } -void SecurityOrigin::SetUniqueOriginIsPotentiallyTrustworthy( - bool is_unique_origin_potentially_trustworthy) { - DCHECK(!is_unique_origin_potentially_trustworthy || IsUnique()); - is_unique_origin_potentially_trustworthy_ = - is_unique_origin_potentially_trustworthy; +void SecurityOrigin::SetOpaqueOriginIsPotentiallyTrustworthy( + bool is_opaque_origin_potentially_trustworthy) { + DCHECK(!is_opaque_origin_potentially_trustworthy || IsOpaque()); + is_opaque_origin_potentially_trustworthy_ = + is_opaque_origin_potentially_trustworthy; } String SecurityOrigin::CanonicalizeHost(const String& host, bool* success) { 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 a1ed1f0c9cb..e54f3f67f50 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h +++ b/chromium/third_party/blink/renderer/platform/weborigin/security_origin.h @@ -44,12 +44,25 @@ namespace blink { class KURL; class URLSecurityOriginMap; +// An identifier which defines the source of content (e.g. a document) and +// restricts what other objects it is permitted to access (based on their +// security origin). Most commonly, an origin is a (scheme, host, port, domain) +// tuple, such as the tuple origin (https, chromium.org, null, null). However, +// there are also opaque origins which do not have a corresponding tuple. +// +// See also: https://html.spec.whatwg.org/multipage/origin.html#concept-origin class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { WTF_MAKE_NONCOPYABLE(SecurityOrigin); public: static scoped_refptr<SecurityOrigin> Create(const KURL&); - static scoped_refptr<SecurityOrigin> CreateUnique(); + // Creates a new opaque SecurityOrigin that is guaranteed to be cross-origin + // to all currently existing SecurityOrigins. + static scoped_refptr<SecurityOrigin> CreateUniqueOpaque(); + // Deprecated alias for CreateOpaque(). + static scoped_refptr<SecurityOrigin> CreateUnique() { + return CreateUniqueOpaque(); + } static scoped_refptr<SecurityOrigin> CreateFromString(const String&); static scoped_refptr<SecurityOrigin> Create(const String& protocol, @@ -154,20 +167,20 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { void GrantUniversalAccess(); bool IsGrantedUniversalAccess() const { return universal_access_; } - bool CanAccessDatabase() const { return !IsUnique(); } - bool CanAccessLocalStorage() const { return !IsUnique(); } - bool CanAccessSharedWorkers() const { return !IsUnique(); } - bool CanAccessServiceWorkers() const { return !IsUnique(); } - bool CanAccessCookies() const { return !IsUnique(); } - bool CanAccessPasswordManager() const { return !IsUnique(); } - bool CanAccessFileSystem() const { return !IsUnique(); } - bool CanAccessCacheStorage() const { return !IsUnique(); } - bool CanAccessLocks() const { return !IsUnique(); } + bool CanAccessDatabase() const { return !IsOpaque(); } + bool CanAccessLocalStorage() const { return !IsOpaque(); } + bool CanAccessSharedWorkers() const { return !IsOpaque(); } + bool CanAccessServiceWorkers() const { return !IsOpaque(); } + bool CanAccessCookies() const { return !IsOpaque(); } + bool CanAccessPasswordManager() const { return !IsOpaque(); } + bool CanAccessFileSystem() const { return !IsOpaque(); } + bool CanAccessCacheStorage() const { return !IsOpaque(); } + bool CanAccessLocks() const { return !IsOpaque(); } // Technically, we should always allow access to sessionStorage, but we - // currently don't handle creating a sessionStorage area for unique + // currently don't handle creating a sessionStorage area for opaque // origins. - bool CanAccessSessionStorage() const { return !IsUnique(); } + bool CanAccessSessionStorage() const { return !IsOpaque(); } // The local SecurityOrigin is the most privileged SecurityOrigin. // The local SecurityOrigin can script any document, navigate to local @@ -177,29 +190,28 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { // Returns true if the host is one of 127.0.0.1/8, ::1/128, or "localhost". bool IsLocalhost() const; - // The origin is a globally unique identifier assigned when the Document is - // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin - // - // There's a subtle difference between a unique origin and an origin that - // has the SandboxOrigin flag set. The latter implies the former, and, in - // addition, the SandboxOrigin flag is inherited by iframes. - bool IsUnique() const { return is_unique_; } + // Returns true if the origin is not a tuple origin (i.e. an origin consisting + // of a scheme, host, port, and domain). Opaque origins are created for a + // variety of situations (see https://whatwg.org/C/origin.html#origin for more + // details), such as for documents generated from data: URLs or documents + // with the sandboxed origin browsing context flag set. + bool IsOpaque() const { return is_opaque_; } + // Deprecated alias for IsOpaque(). + bool IsUnique() const { return IsOpaque(); } // By default 'file:' URLs may access other 'file:' URLs. This method // denies access. If either SecurityOrigin sets this flag, the access // check will fail. void BlockLocalAccessFromLocalOrigin(); - // Convert this SecurityOrigin into a string. The string - // representation of a SecurityOrigin is similar to a URL, except it - // lacks a path component. The string representation does not encode - // the value of the SecurityOrigin's domain property. + // Convert this SecurityOrigin into a string. The string representation of a + // SecurityOrigin is similar to a URL, except it lacks a path component. The + // string representation does not encode the value of the SecurityOrigin's + // domain property. // // When using the string value, it's important to remember that it might be - // "null". This happens when this SecurityOrigin is unique. For example, - // this SecurityOrigin might have come from a sandboxed iframe, the - // SecurityOrigin might be empty, or we might have explicitly decided that - // we shouldTreatURLSchemeAsNoAccess. + // "null". This typically happens when this SecurityOrigin is opaque (e.g. the + // origin of a sandboxed iframe). String ToString() const; AtomicString ToAtomicString() const; @@ -214,7 +226,7 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { static bool AreSameSchemeHostPort(const KURL& a, const KURL& b); - static const KURL& UrlWithUniqueSecurityOrigin(); + static const KURL& UrlWithUniqueOpaqueOrigin(); // Transfer origin privileges from another security origin. // The following privileges are currently copied over: @@ -230,8 +242,8 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { std::unique_ptr<PrivilegeData> CreatePrivilegeData() const; void TransferPrivilegesFrom(std::unique_ptr<PrivilegeData>); - void SetUniqueOriginIsPotentiallyTrustworthy( - bool is_unique_origin_potentially_trustworthy); + void SetOpaqueOriginIsPotentiallyTrustworthy( + bool is_opaque_origin_potentially_trustworthy); // Only used for document.domain setting. The method should probably be moved // if we need it for something more general. @@ -255,12 +267,12 @@ class PLATFORM_EXPORT SecurityOrigin : public RefCounted<SecurityOrigin> { String domain_; uint16_t port_; uint16_t effective_port_; - const bool is_unique_; + const bool is_opaque_; bool universal_access_; bool domain_was_set_in_dom_; bool can_load_local_resources_; bool block_local_access_from_local_origin_; - bool is_unique_origin_potentially_trustworthy_; + bool is_opaque_origin_potentially_trustworthy_; }; } // namespace blink 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 a94433044c1..5c8d61a3ccd 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 @@ -48,14 +48,14 @@ const uint16_t kMaxAllowedPort = UINT16_MAX; class SecurityOriginTest : public testing::Test {}; -TEST_F(SecurityOriginTest, ValidPortsCreateNonUniqueOrigins) { +TEST_F(SecurityOriginTest, ValidPortsCreateTupleOrigins) { uint16_t ports[] = {0, 80, 443, 5000, kMaxAllowedPort}; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(ports); ++i) { + for (size_t i = 0; i < arraysize(ports); ++i) { scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::Create("http", "example.com", ports[i]); - EXPECT_FALSE(origin->IsUnique()) - << "Port " << ports[i] << " should not have generated a unique origin."; + EXPECT_FALSE(origin->IsOpaque()) + << "Port " << ports[i] << " should have generated a tuple origin."; } } @@ -148,7 +148,7 @@ TEST_F(SecurityOriginTest, IsPotentiallyTrustworthy) { {false, "filesystem:ftp://evil:99/foo"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(inputs); ++i) { + for (size_t i = 0; i < arraysize(inputs); ++i) { SCOPED_TRACE(inputs[i].url); scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::CreateFromString(inputs[i].url); @@ -156,14 +156,15 @@ TEST_F(SecurityOriginTest, IsPotentiallyTrustworthy) { EXPECT_EQ(inputs[i].access_granted, origin->IsPotentiallyTrustworthy()); } - // Unique origins are not considered secure. - scoped_refptr<SecurityOrigin> unique_origin = SecurityOrigin::CreateUnique(); - EXPECT_FALSE(unique_origin->IsPotentiallyTrustworthy()); + // Opaque origins are not considered secure. + scoped_refptr<SecurityOrigin> opaque_origin = + SecurityOrigin::CreateUniqueOpaque(); + EXPECT_FALSE(opaque_origin->IsPotentiallyTrustworthy()); // ... unless they are specially marked as such. - unique_origin->SetUniqueOriginIsPotentiallyTrustworthy(true); - EXPECT_TRUE(unique_origin->IsPotentiallyTrustworthy()); - unique_origin->SetUniqueOriginIsPotentiallyTrustworthy(false); - EXPECT_FALSE(unique_origin->IsPotentiallyTrustworthy()); + opaque_origin->SetOpaqueOriginIsPotentiallyTrustworthy(true); + EXPECT_TRUE(opaque_origin->IsPotentiallyTrustworthy()); + opaque_origin->SetOpaqueOriginIsPotentiallyTrustworthy(false); + EXPECT_FALSE(opaque_origin->IsPotentiallyTrustworthy()); } TEST_F(SecurityOriginTest, IsSecure) { @@ -201,11 +202,27 @@ TEST_F(SecurityOriginTest, IsSecureViaTrustworthy) { for (const char* test : urls) { KURL url(test); EXPECT_FALSE(SecurityOrigin::IsSecure(url)); - SecurityPolicy::AddOriginTrustworthyWhiteList(*SecurityOrigin::Create(url)); + SecurityPolicy::AddOriginTrustworthyWhiteList( + SecurityOrigin::CreateFromString(url)->ToRawString()); EXPECT_TRUE(SecurityOrigin::IsSecure(url)); } } +TEST_F(SecurityOriginTest, IsSecureViaTrustworthyHostnamePattern) { + KURL url("http://bar.foo.com"); + EXPECT_FALSE(SecurityOrigin::IsSecure(url)); + SecurityPolicy::AddOriginTrustworthyWhiteList("*.foo.com"); + EXPECT_TRUE(SecurityOrigin::IsSecure(url)); +} + +// Tests that a URL with no host does not match a hostname pattern. +TEST_F(SecurityOriginTest, IsSecureViaTrustworthyHostnamePatternEmptyHostname) { + KURL url("file://foo"); + EXPECT_FALSE(SecurityOrigin::IsSecure(url)); + SecurityPolicy::AddOriginTrustworthyWhiteList("*.foo.com"); + EXPECT_FALSE(SecurityOrigin::IsSecure(url)); +} + TEST_F(SecurityOriginTest, CanAccess) { struct TestCase { bool can_access; @@ -218,7 +235,7 @@ TEST_F(SecurityOriginTest, CanAccess) { {false, "https://foobar.com", "https://bazbar.com"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { + for (size_t i = 0; i < arraysize(tests); ++i) { scoped_refptr<const SecurityOrigin> origin1 = SecurityOrigin::CreateFromString(tests[i].origin1); scoped_refptr<const SecurityOrigin> origin2 = @@ -239,7 +256,7 @@ TEST_F(SecurityOriginTest, CanRequest) { {false, "https://foobar.com", "https://bazbar.com"}, }; - for (size_t i = 0; i < WTF_ARRAY_LENGTH(tests); ++i) { + for (size_t i = 0; i < arraysize(tests); ++i) { scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::CreateFromString(tests[i].origin); blink::KURL url(tests[i].url); @@ -303,10 +320,10 @@ TEST_F(SecurityOriginTest, CreateFromTuple) { } } -TEST_F(SecurityOriginTest, UniquenessPropagatesToBlobUrls) { +TEST_F(SecurityOriginTest, OpaquenessPropagatesToBlobUrls) { struct TestCase { const char* url; - bool expected_uniqueness; + bool expected_opaqueness; const char* expected_origin_string; } cases[]{ {"", true, "null"}, @@ -324,29 +341,29 @@ TEST_F(SecurityOriginTest, UniquenessPropagatesToBlobUrls) { for (const TestCase& test : cases) { scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::CreateFromString(test.url); - EXPECT_EQ(test.expected_uniqueness, origin->IsUnique()); + EXPECT_EQ(test.expected_opaqueness, origin->IsOpaque()); EXPECT_EQ(test.expected_origin_string, origin->ToString()); KURL blob_url = BlobURL::CreatePublicURL(origin.get()); scoped_refptr<const SecurityOrigin> blob_url_origin = SecurityOrigin::Create(blob_url); - EXPECT_EQ(blob_url_origin->IsUnique(), origin->IsUnique()); + EXPECT_EQ(blob_url_origin->IsOpaque(), origin->IsOpaque()); EXPECT_EQ(blob_url_origin->ToString(), origin->ToString()); EXPECT_EQ(blob_url_origin->ToRawString(), origin->ToRawString()); } } -TEST_F(SecurityOriginTest, UniqueOriginIsSameSchemeHostPort) { - scoped_refptr<const SecurityOrigin> unique_origin = - SecurityOrigin::CreateUnique(); +TEST_F(SecurityOriginTest, OpaqueOriginIsSameSchemeHostPort) { + scoped_refptr<const SecurityOrigin> opaque_origin = + SecurityOrigin::CreateUniqueOpaque(); scoped_refptr<const SecurityOrigin> tuple_origin = SecurityOrigin::CreateFromString("http://example.com"); - EXPECT_TRUE(unique_origin->IsSameSchemeHostPort(unique_origin.get())); - EXPECT_FALSE(SecurityOrigin::CreateUnique()->IsSameSchemeHostPort( - unique_origin.get())); - EXPECT_FALSE(tuple_origin->IsSameSchemeHostPort(unique_origin.get())); - EXPECT_FALSE(unique_origin->IsSameSchemeHostPort(tuple_origin.get())); + EXPECT_TRUE(opaque_origin->IsSameSchemeHostPort(opaque_origin.get())); + EXPECT_FALSE(SecurityOrigin::CreateUniqueOpaque()->IsSameSchemeHostPort( + opaque_origin.get())); + EXPECT_FALSE(tuple_origin->IsSameSchemeHostPort(opaque_origin.get())); + EXPECT_FALSE(opaque_origin->IsSameSchemeHostPort(tuple_origin.get())); } TEST_F(SecurityOriginTest, CanonicalizeHost) { 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 881f509c3ce..fa1c15badfc 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc +++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.cc @@ -29,6 +29,8 @@ #include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include <memory> + +#include "base/strings/pattern.h" #include "third_party/blink/public/platform/web_referrer_policy.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" @@ -40,6 +42,7 @@ #include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/parsing_utilities.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" +#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" #include "third_party/blink/renderer/platform/wtf/threading.h" namespace blink { @@ -242,15 +245,12 @@ Referrer SecurityPolicy::GenerateReferrer(ReferrerPolicy referrer_policy, referrer_policy_no_default); } -void SecurityPolicy::AddOriginTrustworthyWhiteList( - const SecurityOrigin& origin) { +void SecurityPolicy::AddOriginTrustworthyWhiteList(const String& origin) { #if DCHECK_IS_ON() // Must be called before we start other threads. DCHECK(WTF::IsBeforeThreadCreated()); #endif - if (origin.IsUnique()) - return; - TrustworthyOriginSet().insert(origin.ToRawString()); + TrustworthyOriginSet().insert(origin); } bool SecurityPolicy::IsOriginWhiteListedTrustworthy( @@ -259,7 +259,25 @@ bool SecurityPolicy::IsOriginWhiteListedTrustworthy( // allocations, copies, and frees. if (origin.IsUnique() || TrustworthyOriginSet().IsEmpty()) return false; - return TrustworthyOriginSet().Contains(origin.ToRawString()); + if (TrustworthyOriginSet().Contains(origin.ToRawString())) + return true; + + // KURL and SecurityOrigin hosts should be canonicalized to 8-bit strings. + CHECK(origin.Host().Is8Bit()); + StringUTF8Adaptor host_adaptor(origin.Host()); + for (const auto& origin_or_pattern : TrustworthyOriginSet()) { + // Origins and hostname patterns are expected to be canonicalized (including + // canonicalization to 8-bit strings) before being inserted into the + // TrustworthyOriginSet(). + CHECK(origin_or_pattern.Is8Bit()); + StringUTF8Adaptor origin_or_pattern_adaptor(origin_or_pattern); + if (base::MatchPattern(host_adaptor.AsStringPiece(), + origin_or_pattern_adaptor.AsStringPiece())) { + return true; + } + } + + return false; } bool SecurityPolicy::IsUrlWhiteListedTrustworthy(const KURL& url) { diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h index 285f481a398..38d16bcd971 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h +++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy.h @@ -92,7 +92,7 @@ class PLATFORM_EXPORT SecurityPolicy { static bool IsAccessToURLWhiteListed(const SecurityOrigin* active_origin, const KURL&); - static void AddOriginTrustworthyWhiteList(const SecurityOrigin&); + static void AddOriginTrustworthyWhiteList(const String&); static bool IsOriginWhiteListedTrustworthy(const SecurityOrigin&); static bool IsUrlWhiteListedTrustworthy(const KURL&); diff --git a/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc b/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc index c03f202572e..9790ee421c5 100644 --- a/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc +++ b/chromium/third_party/blink/renderer/platform/weborigin/security_policy_test.cc @@ -254,7 +254,7 @@ TEST(SecurityPolicyTest, TrustworthyWhiteList) { scoped_refptr<const SecurityOrigin> origin = SecurityOrigin::CreateFromString(url); EXPECT_FALSE(origin->IsPotentiallyTrustworthy()); - SecurityPolicy::AddOriginTrustworthyWhiteList(*origin); + SecurityPolicy::AddOriginTrustworthyWhiteList(origin->ToString()); EXPECT_TRUE(origin->IsPotentiallyTrustworthy()); } @@ -281,7 +281,7 @@ TEST(SecurityPolicyTest, TrustworthyWhiteList) { EXPECT_FALSE(origin1->IsPotentiallyTrustworthy()); EXPECT_FALSE(origin2->IsPotentiallyTrustworthy()); - SecurityPolicy::AddOriginTrustworthyWhiteList(*origin1); + SecurityPolicy::AddOriginTrustworthyWhiteList(origin1->ToString()); EXPECT_TRUE(origin1->IsPotentiallyTrustworthy()); EXPECT_TRUE(origin2->IsPotentiallyTrustworthy()); } diff --git a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn index e550bd2c7d8..c2abc5d4b67 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn +++ b/chromium/third_party/blink/renderer/platform/wtf/BUILD.gn @@ -56,7 +56,6 @@ jumbo_component("wtf") { "assertions.cc", "assertions.h", "atomics.h", - "auto_reset.h", "bit_vector.cc", "bit_vector.h", "bloom_filter.h", @@ -67,8 +66,6 @@ jumbo_component("wtf") { "conditional_destructor.h", "container_annotations.h", "cpu.h", - "cryptographically_random_number.cc", - "cryptographically_random_number.h", "date_math.cc", "date_math.h", "deque.h", @@ -116,7 +113,6 @@ jumbo_component("wtf") { "math_extras.h", "noncopyable.h", "not_found.h", - "optional.h", "process_metrics.h", "ref_counted.h", "ref_vector.h", @@ -194,6 +190,8 @@ jumbo_component("wtf") { "text/text_encoding_registry.h", "text/text_position.cc", "text/text_position.h", + "text/text_stream.cc", + "text/text_stream.h", "text/unicode.h", "text/utf8.cc", "text/utf8.h", @@ -321,7 +319,6 @@ jumbo_source_set("wtf_unittests_sources") { "hash_set_test.cc", "list_hash_set_test.cc", "math_extras_test.cc", - "optional_test.cc", "ref_ptr_test.cc", "saturated_arithmetic_test.cc", "scoped_logger_test.cc", diff --git a/chromium/third_party/blink/renderer/platform/wtf/README.md b/chromium/third_party/blink/renderer/platform/wtf/README.md index be3012efb34..c34ba5d3b12 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/README.md +++ b/chromium/third_party/blink/renderer/platform/wtf/README.md @@ -69,10 +69,7 @@ The below is a list of major libraries. For a complete list, look at * **Miscellaneous** [StdLibExtras.h] (`DEFINE_STATIC_LOCAL` etc.), - [Time.h], - [CryptographicallyRandomNumber.h], - [AutoReset.h], - [Optional.h] + [Time.h] ## History @@ -113,9 +110,6 @@ current location][4] Source/platform/wtf. [Noncopyable.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/noncopyable.h [StdLibExtras.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/std_lib_extras.h [Time.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/time.h -[CryptographicallyRandomNumber.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/cryptographically_random_number.h -[AutoReset.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/auto_reset.h -[Optional.h]: https://cs.chromium.org/chromium/src/third_party/blink/renderer/platform/wtf/optional.h [1]: https://chromium.googlesource.com/chromium/src/+/e372c152fc6e57743ebc508fe17f6eb131b4ff8d [2]: https://chromium.googlesource.com/chromium/src/+/547a6ca360a56fbee3d5ea4a71ba18f91622455c [3]: https://chromium.googlesource.com/chromium/src/+/478890427ee03fd88e6f0f58ee8220512044bed9/third_party/WebKit/WebCore/kwq/KWQAssertions.h 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 d87e5c928e9..590dd0b5d8e 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 @@ -100,6 +100,7 @@ class WTF_EXPORT PartitionAllocator { Free(ptr); // Not the system free, the one from this class. } + static void TraceMarkedBackingStore(void*) {} static void BackingWriteBarrier(void*) {} static bool IsAllocationAllowed() { return true; } diff --git a/chromium/third_party/blink/renderer/platform/wtf/auto_reset.h b/chromium/third_party/blink/renderer/platform/wtf/auto_reset.h deleted file mode 100644 index 5689c7e1de3..00000000000 --- a/chromium/third_party/blink/renderer/platform/wtf/auto_reset.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 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 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. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_AUTO_RESET_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_AUTO_RESET_H_ - -#include "base/auto_reset.h" - -namespace WTF { - -// WTF::AutoReset is base::AutoReset. See base/auto_reset.h for documentation. - -template <typename T> -using AutoReset = base::AutoReset<T>; - -} // namespace WTF - -using WTF::AutoReset; - -#endif diff --git a/chromium/third_party/blink/renderer/platform/wtf/byte_order.h b/chromium/third_party/blink/renderer/platform/wtf/byte_order.h index 94b6464021a..0d5fe42d842 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/byte_order.h +++ b/chromium/third_party/blink/renderer/platform/wtf/byte_order.h @@ -33,42 +33,12 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if defined(OS_POSIX) || defined(OS_FUCHSIA) #include <arpa/inet.h> #endif #if defined(OS_WIN) - -#include "third_party/blink/renderer/platform/wtf/byte_swap.h" - -#if defined(ARCH_CPU_BIG_ENDIAN) -inline uint16_t ntohs(uint16_t x) { - return x; -} -inline uint16_t htons(uint16_t x) { - return x; -} -inline uint32_t ntohl(uint32_t x) { - return x; -} -inline uint32_t htonl(uint32_t x) { - return x; -} -#else -inline uint16_t ntohs(uint16_t x) { - return WTF::Bswap16(x); -} -inline uint16_t htons(uint16_t x) { - return WTF::Bswap16(x); -} -inline uint32_t ntohl(uint32_t x) { - return WTF::Bswap32(x); -} -inline uint32_t htonl(uint32_t x) { - return WTF::Bswap32(x); -} -#endif - +#include <winsock2.h> #endif // defined(OS_WIN) #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_BYTE_ORDER_H_ diff --git a/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.cc b/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.cc deleted file mode 100644 index 4c68e424619..00000000000 --- a/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.cc +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 1996, David Mazieres <dm@uun.org> - * Copyright (c) 2008, Damien Miller <djm@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "third_party/blink/renderer/platform/wtf/cryptographically_random_number.h" - -#include "base/rand_util.h" - -namespace WTF { - -uint32_t CryptographicallyRandomNumber() { - uint32_t result; - CryptographicallyRandomValues(&result, sizeof(result)); - return result; -} - -void CryptographicallyRandomValues(void* buffer, size_t length) { - // This should really be crypto::RandBytes(), but WTF can't depend on crypto. - // The implementation of crypto::RandBytes() is just calling - // base::RandBytes(), so both are actually same. - base::RandBytes(buffer, length); -} - -} // namespace WTF diff --git a/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.h b/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.h deleted file mode 100644 index 411a3a5bd4f..00000000000 --- a/chromium/third_party/blink/renderer/platform/wtf/cryptographically_random_number.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. - * (http://www.torchmobile.com/) - * - * 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_CRYPTOGRAPHICALLY_RANDOM_NUMBER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_CRYPTOGRAPHICALLY_RANDOM_NUMBER_H_ - -#include <stdint.h> -#include <cstddef> -#include "third_party/blink/renderer/platform/wtf/wtf_export.h" - -namespace WTF { - -// These functions are threadsafe. -WTF_EXPORT uint32_t CryptographicallyRandomNumber(); -WTF_EXPORT void CryptographicallyRandomValues(void* buffer, size_t length); -} - -using WTF::CryptographicallyRandomNumber; -using WTF::CryptographicallyRandomValues; - -#endif diff --git a/chromium/third_party/blink/renderer/platform/wtf/date_math.cc b/chromium/third_party/blink/renderer/platform/wtf/date_math.cc index 183148d26a5..10f895e3a92 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/date_math.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/date_math.cc @@ -749,7 +749,7 @@ static double ParseDateFromNullTerminatedCharacters(const char* date_string, } have_tz = true; } else { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(known_zones); ++i) { + for (size_t i = 0; i < arraysize(known_zones); ++i) { if (0 == strncasecmp(date_string, known_zones[i].tz_name, strlen(known_zones[i].tz_name))) { offset = known_zones[i].tz_offset; @@ -804,29 +804,26 @@ double ParseDateFromNullTerminatedCharacters(const char* date_string) { } // See http://tools.ietf.org/html/rfc2822#section-3.3 for more information. -String MakeRFC2822DateString(unsigned day_of_week, - unsigned day, - unsigned month, - unsigned year, - unsigned hours, - unsigned minutes, - unsigned seconds, - int utc_offset) { +String MakeRFC2822DateString(const Time date, int utc_offset) { + Time::Exploded time_exploded; + date.UTCExplode(&time_exploded); + StringBuilder string_builder; - string_builder.Append(kWeekdayName[day_of_week]); + string_builder.Append(kWeekdayName[time_exploded.day_of_week]); string_builder.Append(", "); - string_builder.AppendNumber(day); + string_builder.AppendNumber(time_exploded.day_of_month); string_builder.Append(' '); - string_builder.Append(kMonthName[month]); + // |month| is 1-based in Exploded + string_builder.Append(kMonthName[time_exploded.month - 1]); string_builder.Append(' '); - string_builder.AppendNumber(year); + string_builder.AppendNumber(time_exploded.year); string_builder.Append(' '); - AppendTwoDigitNumber(string_builder, hours); + AppendTwoDigitNumber(string_builder, time_exploded.hour); string_builder.Append(':'); - AppendTwoDigitNumber(string_builder, minutes); + AppendTwoDigitNumber(string_builder, time_exploded.minute); string_builder.Append(':'); - AppendTwoDigitNumber(string_builder, seconds); + AppendTwoDigitNumber(string_builder, time_exploded.second); string_builder.Append(' '); string_builder.Append(utc_offset > 0 ? '+' : '-'); diff --git a/chromium/third_party/blink/renderer/platform/wtf/date_math.h b/chromium/third_party/blink/renderer/platform/wtf/date_math.h index 35e881eddf3..a7550acc1a3 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/date_math.h +++ b/chromium/third_party/blink/renderer/platform/wtf/date_math.h @@ -46,6 +46,7 @@ #include <stdint.h> #include <string.h> #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/wtf_export.h" namespace WTF { @@ -56,25 +57,12 @@ WTF_EXPORT void InitializeDates(); // these. WTF_EXPORT double ParseDateFromNullTerminatedCharacters( const char* date_string); -// dayOfWeek: [0, 6] 0 being Monday -// day: [1, 31] -// month: [0, 11] -// year: ex: 2011 -// hours: [0, 23] -// minutes: [0, 59] -// seconds: [0, 59] + // utcOffset: [-720,720]. -WTF_EXPORT String MakeRFC2822DateString(unsigned day_of_week, - unsigned day, - unsigned month, - unsigned year, - unsigned hours, - unsigned minutes, - unsigned seconds, - int utc_offset); +WTF_EXPORT String MakeRFC2822DateString(const Time date, int utc_offset); -const char kWeekdayName[7][4] = {"Mon", "Tue", "Wed", "Thu", - "Fri", "Sat", "Sun"}; +const char kWeekdayName[7][4] = {"Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"}; const char kMonthName[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; const char* const kMonthFullName[12] = { diff --git a/chromium/third_party/blink/renderer/platform/wtf/forward.h b/chromium/third_party/blink/renderer/platform/wtf/forward.h index 70aaf3091be..0d1ac36ec48 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/forward.h +++ b/chromium/third_party/blink/renderer/platform/wtf/forward.h @@ -54,6 +54,7 @@ class String; class StringBuilder; class StringImpl; class StringView; +class TextStream; class Uint8Array; class Uint8ClampedArray; class Uint16Array; 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 a43fd8a2c23..7011104db03 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/hash_table.h +++ b/chromium/third_party/blink/renderer/platform/wtf/hash_table.h @@ -534,8 +534,7 @@ struct Mover { STATIC_ONLY(Mover); static void Move(T&& from, T& to) { to.~T(); - ConstructTraits<T, Traits, Allocator>::ConstructAndNotifyElement( - &to, std::move(from)); + new (NotNull, &to) T(std::move(from)); } }; @@ -543,10 +542,9 @@ template <typename T, typename Allocator, typename Traits> struct Mover<T, Allocator, Traits, true> { STATIC_ONLY(Mover); static void Move(T&& from, T& to) { - to.~T(); Allocator::EnterGCForbiddenScope(); - ConstructTraits<T, Traits, Allocator>::ConstructAndNotifyElement( - &to, std::move(from)); + to.~T(); + new (NotNull, &to) T(std::move(from)); Allocator::LeaveGCForbiddenScope(); } }; @@ -1758,6 +1756,10 @@ HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits, Allocator>:: new_entry = reinserted_entry; } } + // 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_); deleted_count_ = 0; diff --git a/chromium/third_party/blink/renderer/platform/wtf/optional.h b/chromium/third_party/blink/renderer/platform/wtf/optional.h deleted file mode 100644 index 83184cdff67..00000000000 --- a/chromium/third_party/blink/renderer/platform/wtf/optional.h +++ /dev/null @@ -1,37 +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. - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_OPTIONAL_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_OPTIONAL_H_ - -#include "base/optional.h" -#include "base/stl_util.h" - -namespace WTF { - -// WTF::Optional is base::Optional. See base/optional.h for documentation. -// -// A clang plugin enforces that garbage collected types are not allocated -// outside of the heap. GC containers such as HeapVector are allowed though. -template <typename T> -using Optional = base::Optional<T>; - -constexpr base::nullopt_t nullopt = base::nullopt; -constexpr base::in_place_t in_place = base::in_place; - -template <typename T> -constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) { - return base::make_optional(std::forward<T>(value)); -} - -template <typename T> -T* OptionalOrNullptr(Optional<T>& optional) { - return base::OptionalOrNullptr(optional); -} - -} // namespace WTF - -using WTF::Optional; - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_OPTIONAL_H_ diff --git a/chromium/third_party/blink/renderer/platform/wtf/optional_test.cc b/chromium/third_party/blink/renderer/platform/wtf/optional_test.cc deleted file mode 100644 index 8f8424a7636..00000000000 --- a/chromium/third_party/blink/renderer/platform/wtf/optional_test.cc +++ /dev/null @@ -1,58 +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/wtf/optional.h" - -#include "testing/gtest/include/gtest/gtest.h" - -namespace WTF { -namespace { - -struct IntBox { - IntBox(int n) : number(n) {} - int number; -}; - -class DestructionNotifier { - public: - DestructionNotifier(bool& flag) : flag_(flag) {} - ~DestructionNotifier() { flag_ = true; } - - private: - bool& flag_; -}; - -TEST(OptionalTest, BooleanTest) { - Optional<int> optional; - EXPECT_FALSE(optional); - optional.emplace(0); - EXPECT_TRUE(optional); -} - -TEST(OptionalTest, Dereference) { - Optional<int> optional; - optional.emplace(1); - EXPECT_EQ(1, *optional); - - Optional<IntBox> optional_intbox; - optional_intbox.emplace(42); - EXPECT_EQ(42, optional_intbox->number); -} - -TEST(OptionalTest, DestructorCalled) { - // Destroying a disengaged optional shouldn't do anything. - { Optional<DestructionNotifier> optional; } - - // Destroying an engaged optional should call the destructor. - bool is_destroyed = false; - { - Optional<DestructionNotifier> optional; - optional.emplace(is_destroyed); - EXPECT_FALSE(is_destroyed); - } - EXPECT_TRUE(is_destroyed); -} - -} // namespace -} // namespace WTF diff --git a/chromium/third_party/blink/renderer/platform/wtf/std_lib_extras.h b/chromium/third_party/blink/renderer/platform/wtf/std_lib_extras.h index 9ed1567de78..c17bbec0f08 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/std_lib_extras.h +++ b/chromium/third_party/blink/renderer/platform/wtf/std_lib_extras.h @@ -289,17 +289,6 @@ inline To SafeCast(From value) { "Unsigned to signed conversion not allowed for types with " \ "identical size (could overflow)."); -// Macro that returns a compile time constant with the length of an array, but -// gives an error if passed a non-array. -template <typename T, size_t Size> -char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; -// GCC needs some help to deduce a 0 length array. -#if defined(COMPILER_GCC) -template <typename T> -char (&ArrayLengthHelperFunction(T (&)[0]))[0]; -#endif -#define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) - } // namespace WTF using WTF::SafeCast; diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h b/chromium/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h index 807617186a9..48ece3d1c35 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h +++ b/chromium/third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h @@ -40,7 +40,7 @@ class IntegerToStringConverter { "IntegerType must be a type of integer."); explicit IntegerToStringConverter(IntegerType input) { - LChar* end = buffer_ + WTF_ARRAY_LENGTH(buffer_); + LChar* end = buffer_ + arraysize(buffer_); begin_ = end; // We need to switch to the unsigned type when negating the value since diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/string_builder_test.cc b/chromium/third_party/blink/renderer/platform/wtf/text/string_builder_test.cc index c3066c2e92e..bc0d9472d5c 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/text/string_builder_test.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/text/string_builder_test.cc @@ -121,7 +121,7 @@ TEST(StringBuilderTest, Append) { EXPECT_EQ(3U, builder_for_u_char32_append.length()); const UChar result_array[] = {U16_LEAD(fraktur_a_char), U16_TRAIL(fraktur_a_char), 'A'}; - ExpectBuilderContent(String(result_array, WTF_ARRAY_LENGTH(result_array)), + ExpectBuilderContent(String(result_array, arraysize(result_array)), builder_for_u_char32_append); } diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_replacement_test.cc b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_replacement_test.cc index b5d94405b62..fe5e5df0f30 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_replacement_test.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_codec_replacement_test.cc @@ -48,7 +48,7 @@ TEST(TextCodecReplacement, EncodesToUTF8) { // "Kanji" in Chinese characters. const UChar kTestCase[] = {0x6F22, 0x5B57}; - size_t test_case_size = WTF_ARRAY_LENGTH(kTestCase); + size_t test_case_size = arraysize(kTestCase); CString result = codec->Encode(kTestCase, test_case_size, kEntitiesForUnencodables); diff --git a/chromium/third_party/blink/renderer/platform/text/text_stream.cc b/chromium/third_party/blink/renderer/platform/wtf/text/text_stream.cc index cc833aa1c44..80fa1752568 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_stream.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_stream.cc @@ -23,21 +23,12 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "third_party/blink/renderer/platform/text/text_stream.h" - -#include "third_party/blink/renderer/platform/geometry/float_point.h" -#include "third_party/blink/renderer/platform/geometry/float_rect.h" -#include "third_party/blink/renderer/platform/geometry/float_size.h" -#include "third_party/blink/renderer/platform/geometry/int_point.h" -#include "third_party/blink/renderer/platform/geometry/int_rect.h" -#include "third_party/blink/renderer/platform/geometry/layout_point.h" -#include "third_party/blink/renderer/platform/geometry/layout_rect.h" -#include "third_party/blink/renderer/platform/geometry/layout_size.h" -#include "third_party/blink/renderer/platform/layout_unit.h" +#include "third_party/blink/renderer/platform/wtf/text/text_stream.h" + #include "third_party/blink/renderer/platform/wtf/math_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" -namespace blink { +namespace WTF { // large enough for any integer or floating point value in string format, // including trailing null character @@ -127,55 +118,9 @@ String TextStream::Release() { return result; } -TextStream& operator<<(TextStream& ts, const IntRect& r) { - return ts << "at (" << r.X() << "," << r.Y() << ") size " << r.Width() << "x" - << r.Height(); -} - -TextStream& operator<<(TextStream& ts, const IntPoint& p) { - return ts << "(" << p.X() << "," << p.Y() << ")"; -} - -TextStream& operator<<(TextStream& ts, const FloatPoint& p) { - ts << "(" << TextStream::FormatNumberRespectingIntegers(p.X()); - ts << "," << TextStream::FormatNumberRespectingIntegers(p.Y()); - ts << ")"; - return ts; -} - -TextStream& operator<<(TextStream& ts, const FloatSize& s) { - ts << "width=" << TextStream::FormatNumberRespectingIntegers(s.Width()); - ts << " height=" << TextStream::FormatNumberRespectingIntegers(s.Height()); - return ts; -} - -TextStream& operator<<(TextStream& ts, const FloatRect& r) { - ts << "at (" << TextStream::FormatNumberRespectingIntegers(r.X()); - ts << "," << TextStream::FormatNumberRespectingIntegers(r.Y()); - ts << ") size " << TextStream::FormatNumberRespectingIntegers(r.Width()); - ts << "x" << TextStream::FormatNumberRespectingIntegers(r.Height()); - return ts; -} - -TextStream& operator<<(TextStream& ts, const LayoutUnit& unit) { - return ts << TextStream::FormatNumberRespectingIntegers(unit.ToDouble()); -} - -TextStream& operator<<(TextStream& ts, const LayoutPoint& point) { - return ts << FloatPoint(point); -} - -TextStream& operator<<(TextStream& ts, const LayoutRect& rect) { - return ts << FloatRect(rect); -} - -TextStream& operator<<(TextStream& ts, const LayoutSize& size) { - return ts << FloatSize(size); -} - void WriteIndent(TextStream& ts, int indent) { for (int i = 0; i != indent; ++i) ts << " "; } -} // namespace blink +} // namespace WTF diff --git a/chromium/third_party/blink/renderer/platform/text/text_stream.h b/chromium/third_party/blink/renderer/platform/wtf/text/text_stream.h index 5c7c0c0a474..13e39d64133 100644 --- a/chromium/third_party/blink/renderer/platform/text/text_stream.h +++ b/chromium/third_party/blink/renderer/platform/wtf/text/text_stream.h @@ -23,28 +23,18 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_TEXT_STREAM_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_TEXT_TEXT_STREAM_H_ +#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_TEXT_STREAM_H_ +#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_TEXT_STREAM_H_ -#include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/wtf/forward.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/unicode.h" #include "third_party/blink/renderer/platform/wtf/vector.h" +#include "third_party/blink/renderer/platform/wtf/wtf_export.h" -namespace blink { +namespace WTF { -class IntPoint; -class IntRect; -class FloatPoint; -class FloatRect; -class FloatSize; -class LayoutUnit; -class LayoutPoint; -class LayoutRect; -class LayoutSize; - -class PLATFORM_EXPORT TextStream final { +class WTF_EXPORT TextStream final { STACK_ALLOCATED(); public: @@ -73,17 +63,7 @@ class PLATFORM_EXPORT TextStream final { StringBuilder text_; }; -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const IntPoint&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const IntRect&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const FloatPoint&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const FloatSize&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const FloatRect&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const LayoutUnit&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const LayoutPoint&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const LayoutRect&); -PLATFORM_EXPORT TextStream& operator<<(TextStream&, const LayoutSize&); - -PLATFORM_EXPORT void WriteIndent(TextStream&, int indent); +WTF_EXPORT void WriteIndent(TextStream&, int indent); template <typename Item> TextStream& operator<<(TextStream& ts, const Vector<Item>& vector) { @@ -100,6 +80,6 @@ TextStream& operator<<(TextStream& ts, const Vector<Item>& vector) { return ts; } -} // namespace blink +} // namespace WTF #endif diff --git a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc index 85ea71d6991..9a54ed0efb9 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/text/wtf_string_test.cc @@ -494,7 +494,7 @@ TEST(StringTest, StringPrinter) { 0x30C8}; // "Test" in Japanese. EXPECT_EQ(CString("\"\\u30C6\\u30B9\\u30C8\""), ToCStringThroughPrinter( - String(kUnicodeSample, WTF_ARRAY_LENGTH(kUnicodeSample)))); + String(kUnicodeSample, arraysize(kUnicodeSample)))); } } // namespace WTF diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h index 7777fe96d7c..12c24ab9529 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h +++ b/chromium/third_party/blink/renderer/platform/wtf/threading_primitives.h @@ -41,15 +41,19 @@ #if defined(OS_WIN) #include <windows.h> -#endif - -#if defined(OS_POSIX) +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) #include <pthread.h> #endif namespace WTF { -#if defined(OS_POSIX) +#if defined(OS_WIN) +struct PlatformMutex { + CRITICAL_SECTION internal_mutex_; + size_t recursion_count_; +}; +typedef CONDITION_VARIABLE PlatformCondition; +#elif defined(OS_POSIX) || defined(OS_FUCHSIA) struct PlatformMutex { pthread_mutex_t internal_mutex_; #if DCHECK_IS_ON() @@ -57,15 +61,6 @@ struct PlatformMutex { #endif }; typedef pthread_cond_t PlatformCondition; -#elif defined(OS_WIN) -struct PlatformMutex { - CRITICAL_SECTION internal_mutex_; - size_t recursion_count_; -}; -typedef CONDITION_VARIABLE PlatformCondition; -#else -typedef void* PlatformMutex; -typedef void* PlatformCondition; #endif class WTF_EXPORT MutexBase { diff --git a/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc b/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc index 57e06eddf01..cf4f9837b3e 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/threading_pthreads.cc @@ -32,7 +32,7 @@ #include "build/build_config.h" -#if defined(OS_POSIX) +#if defined(OS_POSIX) || defined(OS_FUCHSIA) #include <errno.h> #include <limits.h> @@ -270,4 +270,4 @@ void WillCreateThread() { } // namespace WTF -#endif // defined(OS_POSIX) +#endif // defined(OS_POSIX) || defined(OS_FUCHSIA) diff --git a/chromium/third_party/blink/renderer/platform/wtf/time.h b/chromium/third_party/blink/renderer/platform/wtf/time.h index 29d7643192c..2822074b0c3 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/time.h +++ b/chromium/third_party/blink/renderer/platform/wtf/time.h @@ -21,6 +21,7 @@ namespace WTF { // For usage guideline please see the documentation in base/time/time.h using TimeDelta = base::TimeDelta; +using TimeTicks = base::TimeTicks; using Time = base::Time; using TimeTicks = base::TimeTicks; diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector.h b/chromium/third_party/blink/renderer/platform/wtf/vector.h index 322422cfef4..6a341478a70 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/vector.h +++ b/chromium/third_party/blink/renderer/platform/wtf/vector.h @@ -1983,8 +1983,9 @@ namespace base { #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ <= 7 // Workaround for g++7 and earlier family. // Due to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80654, without this -// Optional<WTF::Vector<T>> where T is non-copyable causes a compile error. -// As we know it is not trivially copy constructible, explicitly declare so. +// base::Optional<WTF::Vector<T>> where T is non-copyable causes a compile +// error. As we know it is not trivially copy constructible, explicitly declare +// so. // // It completes the declaration in base/template_util.h that was provided // for std::vector diff --git a/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc b/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc index 53302a62071..0e507355351 100644 --- a/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc +++ b/chromium/third_party/blink/renderer/platform/wtf/vector_test.cc @@ -26,9 +26,9 @@ #include "third_party/blink/renderer/platform/wtf/vector.h" #include <memory> +#include "base/optional.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/platform/wtf/hash_set.h" -#include "third_party/blink/renderer/platform/wtf/optional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/wtf_test_helper.h" @@ -108,13 +108,13 @@ TEST(VectorTest, Erase) { EXPECT_EQ(2, int_vector[2]); EXPECT_EQ(3, int_vector[3]); - auto first = int_vector.erase(int_vector.begin()); + auto* first = int_vector.erase(int_vector.begin()); EXPECT_EQ(3u, int_vector.size()); EXPECT_EQ(1, *first); EXPECT_EQ(int_vector.begin(), first); - auto last = std::lower_bound(int_vector.begin(), int_vector.end(), 3); - auto end = int_vector.erase(last); + auto* last = std::lower_bound(int_vector.begin(), int_vector.end(), 3); + auto* end = int_vector.erase(last); EXPECT_EQ(2u, int_vector.size()); EXPECT_EQ(int_vector.end(), end); } @@ -613,7 +613,7 @@ TEST(VectorTest, InitializerList) { } TEST(VectorTest, Optional) { - Optional<Vector<int>> vector; + base::Optional<Vector<int>> vector; EXPECT_FALSE(vector); vector.emplace(3); EXPECT_TRUE(vector); |