diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-09-07 13:12:05 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-11-09 10:02:59 +0000 |
commit | 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (patch) | |
tree | f6af110909c79b2759136554f1143d8b0572af0a /chromium/cc/trees | |
parent | 7d2c5d177e9813077a621df8d18c0deda73099b3 (diff) |
BASELINE: Update Chromium to 104.0.5112.120
Change-Id: I5d2726c2ab018d75d055739b6ba64317904f05bb
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438935
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/trees')
50 files changed, 1374 insertions, 1017 deletions
diff --git a/chromium/cc/trees/browser_controls_params.h b/chromium/cc/trees/browser_controls_params.h index 91311103e78..9aab1b8a303 100644 --- a/chromium/cc/trees/browser_controls_params.h +++ b/chromium/cc/trees/browser_controls_params.h @@ -10,10 +10,6 @@ namespace cc { struct CC_EXPORT BrowserControlsParams { - BrowserControlsParams() = default; - BrowserControlsParams(const BrowserControlsParams& other) = default; - ~BrowserControlsParams() = default; - // The height of the top controls (always 0 on platforms where URL-bar hiding // isn't supported). float top_controls_height = 0.f; diff --git a/chromium/cc/trees/commit_state.cc b/chromium/cc/trees/commit_state.cc index e541fa5d25f..6abac8a47ea 100644 --- a/chromium/cc/trees/commit_state.cc +++ b/chromium/cc/trees/commit_state.cc @@ -38,7 +38,10 @@ CommitState::CommitState(const CommitState& prev) overscroll_behavior(prev.overscroll_behavior), background_color(prev.background_color), viewport_property_ids(prev.viewport_property_ids), - local_surface_id_from_parent(prev.local_surface_id_from_parent) { + local_surface_id_from_parent(prev.local_surface_id_from_parent), + previous_surfaces_visual_update_duration( + prev.previous_surfaces_visual_update_duration), + visual_update_duration(prev.visual_update_duration) { memcpy(event_listener_properties, prev.event_listener_properties, sizeof(event_listener_properties)); } diff --git a/chromium/cc/trees/commit_state.h b/chromium/cc/trees/commit_state.h index b4978d873b7..85f2ad29805 100644 --- a/chromium/cc/trees/commit_state.h +++ b/chromium/cc/trees/commit_state.h @@ -12,6 +12,7 @@ #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" +#include "base/memory/raw_ptr.h" #include "base/time/time.h" #include "cc/benchmarks/micro_benchmark_impl.h" #include "cc/cc_export.h" @@ -104,6 +105,8 @@ struct CC_EXPORT CommitState { SkColor background_color = SK_ColorWHITE; ViewportPropertyIds viewport_property_ids; viz::LocalSurfaceId local_surface_id_from_parent; + base::TimeDelta previous_surfaces_visual_update_duration; + base::TimeDelta visual_update_duration; // ------------------------------------------------------------------------- // Take/reset: these values are reset on the LayerTreeHost between commits. @@ -120,6 +123,7 @@ struct CC_EXPORT CommitState { bool new_local_surface_id_request = false; bool next_commit_forces_recalculate_raster_scales = false; bool next_commit_forces_redraw = false; + uint64_t trace_id = 0; EventMetrics::List event_metrics; // Latency information for work done in ProxyMain::BeginMainFrame. The // unique_ptr is allocated in RequestMainFrameUpdate, and passed to Blink's @@ -162,7 +166,7 @@ struct CC_EXPORT ThreadUnsafeCommitState { } LayerListConstIterator end() const { return LayerListConstIterator(nullptr); } - MutatorHost* mutator_host; + raw_ptr<MutatorHost> mutator_host; PropertyTrees property_trees; scoped_refptr<Layer> root_layer; }; diff --git a/chromium/cc/trees/draw_properties_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc index f18d813c165..6534341fdfa 100644 --- a/chromium/cc/trees/draw_properties_unittest.cc +++ b/chromium/cc/trees/draw_properties_unittest.cc @@ -1680,14 +1680,16 @@ TEST_F(DrawPropertiesTest, LargeTransforms) { static bool TransformIsAnimating(LayerImpl* layer) { MutatorHost* host = layer->layer_tree_impl()->mutator_host(); - return host->IsAnimatingTransformProperty( - layer->element_id(), layer->GetElementTypeForAnimation()); + return host->IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::TRANSFORM); } static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) { MutatorHost* host = layer->layer_tree_impl()->mutator_host(); - return host->HasPotentiallyRunningTransformAnimation( - layer->element_id(), layer->GetElementTypeForAnimation()); + return host->HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::TRANSFORM); } TEST_F(DrawPropertiesTest, @@ -6648,6 +6650,7 @@ TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) { std::unique_ptr<KeyframeModel> transform_animation(KeyframeModel::Create( std::move(curve), 3, 3, KeyframeModel::TargetPropertyId(TargetProperty::TRANSFORM))); + transform_animation->set_affects_pending_elements(false); scoped_refptr<Animation> animation(Animation::Create(1)); timeline_impl()->AttachAnimation(animation); animation->AddKeyframeModel(std::move(transform_animation)); diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 02a889cad64..b9d99c69cb4 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -28,6 +28,7 @@ #include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" +#include "cc/trees/viewport_property_ids.h" #include "components/viz/common/display/de_jelly.h" #include "components/viz/common/shared_element_resource_id.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -1425,7 +1426,8 @@ void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, } } -void ComputeTransforms(TransformTree* transform_tree) { +void ComputeTransforms(TransformTree* transform_tree, + const ViewportPropertyIds& viewport_property_ids) { if (!transform_tree->needs_update()) { #if DCHECK_IS_ON() // If the transform tree does not need an update, no TransformNode should @@ -1439,7 +1441,7 @@ void ComputeTransforms(TransformTree* transform_tree) { } for (int i = kContentsRootPropertyNodeId; i < static_cast<int>(transform_tree->size()); ++i) - transform_tree->UpdateTransforms(i); + transform_tree->UpdateTransforms(i, &viewport_property_ids); transform_tree->set_needs_update(false); } @@ -1460,14 +1462,16 @@ void UpdatePropertyTrees(LayerTreeHost* layer_tree_host) { property_trees->clip_tree_mutable().set_needs_update(true); property_trees->effect_tree_mutable().set_needs_update(true); } - ComputeTransforms(&property_trees->transform_tree_mutable()); + + ComputeTransforms(&property_trees->transform_tree_mutable(), + layer_tree_host->viewport_property_ids()); ComputeEffects(&property_trees->effect_tree_mutable()); // Computation of clips uses ToScreen which is updated while computing // transforms. So, ComputeTransforms should be before ComputeClips. ComputeClips(property_trees); } -void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, +void UpdatePropertyTreesAndRenderSurfaces(LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees) { if (property_trees->transform_tree().needs_update()) { property_trees->clip_tree_mutable().set_needs_update(true); @@ -1475,7 +1479,8 @@ void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, } UpdateRenderTarget(&property_trees->effect_tree_mutable()); - ComputeTransforms(&property_trees->transform_tree_mutable()); + ComputeTransforms(&property_trees->transform_tree_mutable(), + layer_tree_impl->viewport_property_ids()); ComputeEffects(&property_trees->effect_tree_mutable()); // Computation of clips uses ToScreen which is updated while computing // transforms. So, ComputeTransforms should be before ComputeClips. @@ -1555,8 +1560,7 @@ void CalculateDrawProperties( gfx::RectF(layer_tree_impl->GetDeviceViewport())); property_trees->transform_tree_mutable().SetRootScaleAndTransform( layer_tree_impl->device_scale_factor(), layer_tree_impl->DrawTransform()); - UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl->root_layer(), - property_trees); + UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl, property_trees); { TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates"); diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index b80b38e3ab9..2c6d94c42a2 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -24,6 +24,7 @@ class TransformTree; class PropertyTrees; struct EffectNode; struct TransformNode; +struct ViewportPropertyIds; namespace draw_property_utils { @@ -32,7 +33,9 @@ void CC_EXPORT ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, // Computes combined (screen space) transforms for every node in the transform // tree. This must be done prior to calling |ComputeClips|. -void CC_EXPORT ComputeTransforms(TransformTree* transform_tree); +void CC_EXPORT +ComputeTransforms(TransformTree* transform_tree, + const ViewportPropertyIds& viewport_property_ids); // Computes screen space opacity for every node in the opacity tree. void CC_EXPORT ComputeEffects(EffectTree* effect_tree); @@ -40,7 +43,7 @@ void CC_EXPORT ComputeEffects(EffectTree* effect_tree); void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host); void CC_EXPORT -UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, +UpdatePropertyTreesAndRenderSurfaces(LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index b08f9cf0e5e..ffaddbaecc2 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -182,7 +182,7 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value); if (mask_filter_info.HasRoundedCorners()) { MathUtil::AddCornerRadiiToTracedValue( - "mask_filter_rounded_corner_raii", + "mask_filter_rounded_corners_radii", mask_filter_info.rounded_corner_bounds(), value); value->SetBoolean("mask_filter_is_fast_rounded_corner", is_fast_rounded_corner); diff --git a/chromium/cc/trees/layer_tree_frame_sink.h b/chromium/cc/trees/layer_tree_frame_sink.h index e68f245b08e..2aa0f851421 100644 --- a/chromium/cc/trees/layer_tree_frame_sink.h +++ b/chromium/cc/trees/layer_tree_frame_sink.h @@ -21,7 +21,6 @@ #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/gpu/raster_context_provider.h" #include "components/viz/common/resources/returned_resource.h" -#include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/color_space.h" namespace gpu { diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h index 82dcc904980..6855ae2576f 100644 --- a/chromium/cc/trees/layer_tree_frame_sink_client.h +++ b/chromium/cc/trees/layer_tree_frame_sink_client.h @@ -11,7 +11,6 @@ #include "base/memory/ref_counted.h" #include "cc/cc_export.h" #include "components/viz/common/resources/returned_resource.h" -#include "gpu/command_buffer/common/texture_in_use_response.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/rect.h" diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 730f3952679..9636bffb09f 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -409,6 +409,8 @@ std::unique_ptr<CommitState> LayerTreeHost::WillCommit( client_->WillCommit(has_updates ? *result : *pending_commit_state()); pending_commit_state()->source_frame_number++; commit_completion_event_ = std::move(completion); + pending_commit_state()->previous_surfaces_visual_update_duration = + base::TimeDelta(); return result; } @@ -732,7 +734,7 @@ void LayerTreeHost::SetDebugState(const LayerTreeDebugState& new_debug_state) { void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) { DCHECK(IsMainThread()); - DCHECK(CommitRequested()); + DCHECK(syncing_deltas_for_test_ || CommitRequested()); if (page_scale_delta == 1.f) return; float page_scale = @@ -1011,6 +1013,21 @@ void LayerTreeHost::UpdateScrollOffsetFromImpl( transform_node->needs_local_transform_update = true; transform_node->transform_changed = true; transform_tree.set_needs_update(true); + + // If the scroll was realized on the compositor, then its transform node + // is already updated (see LayerTreeImpl::DidUpdateScrollOffset) and we + // are now "catching up" to it on main, so we don't need a commit. + // + // But if the scroll was NOT realized on the compositor, we need a + // commit to push the transform change. + // + // Skip this if scroll unification is disabled as we will not set + // ScrollNode::is_composited in that case. + // + if (base::FeatureList::IsEnabled(features::kScrollUnification) && + !scroll_tree.CanRealizeScrollsOnCompositor(*scroll_node)) { + SetNeedsCommit(); + } } // The transform tree has been modified which requires a call to @@ -1089,6 +1106,11 @@ void LayerTreeHost::NotifyThroughputTrackerResults( client_->NotifyThroughputTrackerResults(std::move(results)); } +void LayerTreeHost::ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) { + client_->ReportEventLatency(std::move(latencies)); +} + const base::WeakPtr<CompositorDelegateForInput>& LayerTreeHost::GetDelegateForInput() const { DCHECK(IsMainThread()); @@ -1378,7 +1400,7 @@ void LayerTreeHost::SetPageScaleFactorAndLimits(float page_scale_factor, // We should never process non-unit page_scale_delta for an OOPIF subframe. // TODO(wjmaclean): Remove this dcheck as a pre-condition to closing the bug. // https://crbug.com/845097 - DCHECK(!settings_.is_layer_tree_for_subframe || + DCHECK(settings_.is_for_scalable_page || page_scale_factor == pending_commit_state()->page_scale_factor) << "Setting PSF in oopif subframe: old psf = " << pending_commit_state()->page_scale_factor @@ -1505,6 +1527,13 @@ void LayerTreeHost::SetLocalSurfaceIdFromParent( pending_commit_state()->local_surface_id_from_parent = local_surface_id_from_parent; + // When we are switching to a new viz::LocalSurfaceId add our current visual + // update duration to that of previous surfaces, and clear out the total. So + // that we can begin to track the updates for this new Surface. + pending_commit_state()->previous_surfaces_visual_update_duration += + pending_commit_state()->visual_update_duration; + pending_commit_state()->visual_update_duration = base::TimeDelta(); + // If the parent sequence number has not advanced, then there is no need to // commit anything. This can occur when the child sequence number has // advanced. Which means that child has changed visual properites, and the @@ -1582,11 +1611,11 @@ void LayerTreeHost::AddLayerShouldPushProperties(Layer* layer) { } void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) { - DCHECK(CommitRequested()); + DCHECK(syncing_deltas_for_test_ || CommitRequested()); // We should never process non-unit page_scale_delta for an OOPIF subframe. // TODO(wjmaclean): Remove this check as a pre-condition to closing the bug. // https://crbug.com/845097 - DCHECK(!settings_.is_layer_tree_for_subframe || + DCHECK(settings_.is_for_scalable_page || page_scale == pending_commit_state()->page_scale_factor) << "Setting PSF in oopif subframe: old psf = " << pending_commit_state()->page_scale_factor @@ -1597,7 +1626,7 @@ void LayerTreeHost::SetPageScaleFromImplSide(float page_scale) { void LayerTreeHost::SetElasticOverscrollFromImplSide( gfx::Vector2dF elastic_overscroll) { - DCHECK(CommitRequested()); + DCHECK(syncing_deltas_for_test_ || CommitRequested()); pending_commit_state()->elastic_overscroll = elastic_overscroll; } @@ -1704,6 +1733,9 @@ void LayerTreeHost::SetMutatorsNeedRebuildPropertyTrees() { void LayerTreeHost::SetElementFilterMutated(ElementId element_id, ElementListType list_type, const FilterOperations& filters) { + if (list_type != ElementListType::ACTIVE) + return; + if (IsUsingLayerLists()) { // In BlinkGenPropertyTrees/CompositeAfterPaint we always have property // tree nodes and can set the filter directly on the effect node. @@ -1721,6 +1753,9 @@ void LayerTreeHost::SetElementBackdropFilterMutated( ElementId element_id, ElementListType list_type, const FilterOperations& backdrop_filters) { + if (list_type != ElementListType::ACTIVE) + return; + if (IsUsingLayerLists()) { // In BlinkGenPropertyTrees/CompositeAfterPaint we always have property // tree nodes and can set the backdrop_filter directly on the effect node. @@ -1740,6 +1775,9 @@ void LayerTreeHost::SetElementOpacityMutated(ElementId element_id, DCHECK_GE(opacity, 0.f); DCHECK_LE(opacity, 1.f); + if (list_type != ElementListType::ACTIVE) + return; + if (IsUsingLayerLists()) { property_trees()->effect_tree_mutable().OnOpacityAnimated(element_id, opacity); @@ -1767,6 +1805,9 @@ void LayerTreeHost::SetElementTransformMutated( ElementId element_id, ElementListType list_type, const gfx::Transform& transform) { + if (list_type != ElementListType::ACTIVE) + return; + if (IsUsingLayerLists()) { property_trees()->transform_tree_mutable().OnTransformAnimated(element_id, transform); @@ -1921,12 +1962,6 @@ void LayerTreeHost::SetRenderFrameObserver( proxy_->SetRenderFrameObserver(std::move(observer)); } -void LayerTreeHost::SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) { - DCHECK(IsMainThread()); - proxy_->SetEnableFrameRateThrottling(enable_frame_rate_throttling); -} - void LayerTreeHost::SetDelegatedInkMetadata( std::unique_ptr<gfx::DelegatedInkMetadata> metadata) { pending_commit_state()->delegated_ink_metadata = std::move(metadata); @@ -1948,4 +1983,9 @@ uint32_t LayerTreeHost::GetAverageThroughput() const { return proxy_->GetAverageThroughput(); } +void LayerTreeHost::IncrementVisualUpdateDuration( + base::TimeDelta visual_update_duration) { + pending_commit_state()->visual_update_duration += visual_update_duration; +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index feccd6a65bd..abe129ddb22 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -441,10 +441,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { ->event_listener_properties[static_cast<size_t>(event_class)]; } - // Indicates that its acceptable to throttle the frame rate for this content - // to prioritize lower power/CPU use. - void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling); - void SetViewportRectAndScale( const gfx::Rect& device_viewport_rect, float device_scale_factor, @@ -720,6 +716,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void NotifyThroughputTrackerResults(CustomTrackerResults results); void NotifyTransitionRequestsFinished( const std::vector<uint32_t>& sequence_ids); + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies); LayerTreeHostClient* client() { DCHECK(IsMainThread()); @@ -809,6 +807,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { return recording_scale_factor_; } + const ViewportPropertyIds& viewport_property_ids() const { + return pending_commit_state()->viewport_property_ids; + } + void SetSourceURL(ukm::SourceId source_id, const GURL& url); base::ReadOnlySharedMemoryRegion CreateSharedMemoryForSmoothnessUkm(); @@ -838,6 +840,23 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Returns a percentage representing average throughput of last X seconds. uint32_t GetAverageThroughput() const; + // TODO(szager): Remove these once threaded compositing is enabled for all + // web_tests. + bool in_composite_for_test() const { return in_composite_for_test_; } + [[nodiscard]] base::AutoReset<bool> ForceSyncCompositeForTest() { + return base::AutoReset<bool>(&in_composite_for_test_, true); + } + + // Blink compositor unit tests sometimes want to simulate pushing deltas + // without going through the whole lifecycle to test the effects of the + // deltas. This flag turns off DCHECKs that deltas being set to main are + // during a commit phase so these tests can do this. + [[nodiscard]] base::AutoReset<bool> SimulateSyncingDeltasForTesting() { + return base::AutoReset<bool>(&syncing_deltas_for_test_, true); + } + + void IncrementVisualUpdateDuration(base::TimeDelta visual_update_duration); + protected: LayerTreeHost(InitParams params, CompositorMode mode); @@ -1015,6 +1034,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // for histograms. mutable bool waited_for_protected_sequence_ = false; + bool in_composite_for_test_ = false; + + bool syncing_deltas_for_test_ = false; + // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate // objects. base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{ diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index 0e775a23e53..f52db87ce1a 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -6,10 +6,12 @@ #define CC_TREES_LAYER_TREE_HOST_CLIENT_H_ #include <memory> +#include <vector> #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "cc/input/browser_controls_state.h" +#include "cc/metrics/event_latency_tracker.h" #include "cc/metrics/frame_sequence_tracker_collection.h" #include "cc/trees/paint_holding_reason.h" #include "cc/trees/property_tree.h" @@ -188,6 +190,8 @@ class LayerTreeHostClient { // RecordEndOfFrameMetrics. virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0; virtual void NotifyThroughputTrackerResults(CustomTrackerResults results) = 0; + virtual void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) = 0; // Should only be implemented by Blink. virtual std::unique_ptr<WebVitalMetrics> GetWebVitalMetrics() = 0; @@ -203,9 +207,6 @@ class LayerTreeHostClient { // must be safe to use on both the compositor and main threads. class LayerTreeHostSchedulingClient { public: - // Indicates that the compositor thread scheduled a BeginMainFrame to run on - // the main thread. - virtual void DidScheduleBeginMainFrame() = 0; // Called unconditionally when BeginMainFrame runs on the main thread. virtual void DidRunBeginMainFrame() = 0; }; diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 14e13169de8..aca208728d0 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -259,9 +259,6 @@ void RecordSourceIdConsistency(bool all_valid, bool all_unique) { } // namespace -DEFINE_SCOPED_UMA_HISTOGRAM_TIMER(PendingTreeRasterDurationHistogramTimer, - "Scheduling.%s.PendingTreeRasterDuration") - void LayerTreeHostImpl::DidUpdateScrollAnimationCurve() { // Because we updated the animation target, notify the // `LatencyInfoSwapPromiseMonitor` to tell it that something happened that @@ -320,6 +317,11 @@ void LayerTreeHostImpl::SetNeedsFullViewportRedraw() { SetNeedsRedraw(); } +void LayerTreeHostImpl::SetDeferBeginMainFrame( + bool defer_begin_main_frame) const { + client_->SetDeferBeginMainFrameFromImpl(defer_begin_main_frame); +} + bool LayerTreeHostImpl::IsInHighLatencyMode() const { return impl_thread_phase_ == ImplThreadPhase::IDLE; } @@ -385,7 +387,9 @@ LayerTreeHostImpl::LayerTreeHostImpl( current_begin_frame_tracker_(FROM_HERE), compositor_frame_reporting_controller_( std::make_unique<CompositorFrameReportingController>( - /*should_report_metrics=*/!settings.single_thread_proxy_scheduler, + /*should_report_histograms=*/!settings + .single_thread_proxy_scheduler, + /*should_report_ukm=*/!settings.single_thread_proxy_scheduler, id)), settings_(settings), is_synchronous_single_threaded_(!task_runner_provider->HasImplThread() && @@ -455,14 +459,16 @@ LayerTreeHostImpl::LayerTreeHostImpl( compositor_frame_reporting_controller_->SetFrameSequenceTrackerCollection( &frame_trackers_); -#if BUILDFLAG(IS_CHROMEOS_ASH) const bool is_ui = settings.is_layer_tree_for_ui; if (is_ui) { + compositor_frame_reporting_controller_->set_event_latency_tracker(this); + +#if BUILDFLAG(IS_CHROMEOS_ASH) dropped_frame_counter_.EnableReporForUI(); compositor_frame_reporting_controller_->SetThreadAffectsSmoothness( FrameInfo::SmoothEffectDrivingThread::kMain, true); - } #endif // BUILDFLAG(IS_CHROMEOS_ASH) + } dropped_frame_counter_.set_total_counter(&total_frame_counter_); frame_trackers_.set_custom_tracker_results_added_callback( @@ -522,11 +528,6 @@ const ThreadedInputHandler& LayerTreeHostImpl::GetInputHandler() const { return static_cast<const ThreadedInputHandler&>(*input_delegate_.get()); } -void LayerTreeHostImpl::WillSendBeginMainFrame() { - if (scheduling_client_) - scheduling_client_->DidScheduleBeginMainFrame(); -} - void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) { frame_trackers_.NotifyBeginMainFrame(args); } @@ -586,12 +587,14 @@ void LayerTreeHostImpl::ReadyToCommit( } } -void LayerTreeHostImpl::BeginCommit(int source_frame_number) { +void LayerTreeHostImpl::BeginCommit(int source_frame_number, + uint64_t trace_id) { TRACE_EVENT0("cc", "LayerTreeHostImpl::BeginCommit"); if (!CommitToActiveTree()) CreatePendingTree(); sync_tree()->set_source_frame_number(source_frame_number); + sync_tree()->set_trace_id(trace_id); } // This function commits the LayerTreeHost, as represented by CommitState, to an @@ -719,6 +722,10 @@ void LayerTreeHostImpl::CommitComplete() { mutator_host_->HasSmilAnimation()) { frame_trackers_.StartSequence( FrameSequenceTrackerType::kMainThreadAnimation); + if (mutator_host_->HasSharedElementTransition()) { + frame_trackers_.StartSequence( + FrameSequenceTrackerType::kSETMainThreadAnimation); + } } for (const auto& info : mutator_host_->TakePendingThroughputTrackerInfos()) { @@ -750,8 +757,6 @@ void LayerTreeHostImpl::UpdateSyncTreeAfterCommitOrImplSideInvalidation() { // and the updated data for the image from the main frame. PaintImageIdFlatSet images_to_invalidate = tile_manager_.TakeImagesToInvalidateOnSyncTree(); - if (ukm_manager_) - ukm_manager_->AddCheckerboardedImages(images_to_invalidate.size()); const auto& animated_images = image_animation_controller_.AnimateForSyncTree(CurrentBeginFrameArgs()); @@ -914,10 +919,6 @@ void LayerTreeHostImpl::NotifyPendingTreeFullyPainted() { // Scheduler to wait for ReadyToDraw signal to avoid Checkerboard. if (CommitToActiveTree()) NotifyReadyToDraw(); - } else if (!CommitToActiveTree()) { - DCHECK(!pending_tree_raster_duration_timer_); - pending_tree_raster_duration_timer_ = - std::make_unique<PendingTreeRasterDurationHistogramTimer>(); } } @@ -1020,19 +1021,6 @@ void LayerTreeHostImpl::StartPageScaleAnimation(const gfx::Point& target_offset, bool anchor_point, float page_scale, base::TimeDelta duration) { - // Temporary crash logging for https://crbug.com/845097. - static bool has_dumped_without_crashing = false; - if (settings().is_layer_tree_for_subframe && !has_dumped_without_crashing) { - has_dumped_without_crashing = true; - static auto* psf_oopif_animation_error = - base::debug::AllocateCrashKeyString("psf_oopif_animation_error", - base::debug::CrashKeySize::Size32); - base::debug::SetCrashKeyString( - psf_oopif_animation_error, - base::StringPrintf("%p", InnerViewportScrollNode())); - base::debug::DumpWithoutCrashing(); - } - if (!InnerViewportScrollNode()) return; @@ -1308,8 +1296,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { int num_missing_tiles = 0; int num_incomplete_tiles = 0; int64_t checkerboarded_no_recording_content_area = 0; - int64_t checkerboarded_needs_raster_content_area = 0; - int64_t total_visible_area = 0; + bool have_copy_request = active_tree()->property_trees()->effect_tree().HasCopyRequests(); bool have_missing_animated_tiles = false; @@ -1389,9 +1376,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { num_incomplete_tiles += append_quads_data.num_incomplete_tiles; checkerboarded_no_recording_content_area += append_quads_data.checkerboarded_no_recording_content_area; - checkerboarded_needs_raster_content_area += - append_quads_data.checkerboarded_needs_raster_content_area; - total_visible_area += append_quads_data.visible_layer_area; + if (append_quads_data.num_missing_tiles > 0) { have_missing_animated_tiles |= layer->screen_space_transform_is_animating(); @@ -1490,30 +1475,6 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { frame->has_missing_content = num_missing_tiles > 0 || num_incomplete_tiles > 0; - if (ukm_manager_) { - ukm_manager_->AddCheckerboardStatsForFrame( - checkerboarded_no_recording_content_area + - checkerboarded_needs_raster_content_area, - num_missing_tiles, total_visible_area); - } - - if (active_tree_->has_ever_been_drawn()) { - UMA_HISTOGRAM_COUNTS_100( - "Compositing.RenderPass.AppendQuadData.NumMissingTiles", - num_missing_tiles); - UMA_HISTOGRAM_COUNTS_100( - "Compositing.RenderPass.AppendQuadData.NumIncompleteTiles", - num_incomplete_tiles); - UMA_HISTOGRAM_COUNTS_1M( - "Compositing.RenderPass.AppendQuadData." - "CheckerboardedNoRecordingContentArea", - checkerboarded_no_recording_content_area); - UMA_HISTOGRAM_COUNTS_1M( - "Compositing.RenderPass.AppendQuadData." - "CheckerboardedNeedRasterContentArea", - checkerboarded_needs_raster_content_area); - } - TRACE_EVENT_END2("cc,benchmark", "LayerTreeHostImpl::CalculateRenderPasses", "draw_result", draw_result, "missing tiles", num_missing_tiles); @@ -1547,11 +1508,6 @@ void LayerTreeHostImpl::SetViewportDamage(const gfx::Rect& damage_rect) { viewport_damage_rect_.Union(damage_rect); } -void LayerTreeHostImpl::SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) { - enable_frame_rate_throttling_ = enable_frame_rate_throttling; -} - void LayerTreeHostImpl::InvalidateContentOnImplSide() { DCHECK(!pending_tree_); // Invalidation should never be ran outside the impl frame for non @@ -1750,7 +1706,9 @@ void LayerTreeHostImpl::EvictTexturesForTesting() { UpdateTileManagerMemoryPolicy(ManagedMemoryPolicy(0)); } -void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting(bool block) { +void LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting( + bool block, + bool notify_if_blocked) { NOTREACHED(); } @@ -1923,24 +1881,23 @@ TargetColorParams LayerTreeHostImpl::GetTargetColorParams( if (!hdr_color_space.IsValid()) return params; - // It's expensive to rasterize in HDR, so we only want to do so when we know - // we have HDR content to rasterize. - if (hdr_color_space.IsHDR() && - content_color_usage != gfx::ContentColorUsage::kHDR) { - params.color_space = gfx::ColorSpace::CreateDisplayP3D65(); - return params; - } + if (hdr_color_space.IsHDR()) { + if (content_color_usage == gfx::ContentColorUsage::kHDR) { + // Rasterization of HDR content is always done in extended-sRGB space. + params.color_space = gfx::ColorSpace::CreateExtendedSRGB(); - // The raster color space should contain sRGB to avoid artifacts during - // rasterization. - if (CheckColorSpaceContainsSrgb(hdr_color_space)) { - params.color_space = hdr_color_space; + // Only report the HDR capabilities if they are requested. + params.hdr_max_luminance_relative = + display_cs.GetHDRMaxLuminanceRelative(); + } else { + // If the content is not HDR, then use Display P3 as the rasterization + // color space. + params.color_space = gfx::ColorSpace::CreateDisplayP3D65(); + } + return params; } - // Only report the HDR capabilities if they are requested. - if (content_color_usage == gfx::ContentColorUsage::kHDR) - params.hdr_max_luminance_relative = display_cs.GetHDRMaxLuminanceRelative(); - + params.color_space = hdr_color_space; return params; } @@ -2005,7 +1962,6 @@ void LayerTreeHostImpl::NotifyReadyToActivate() { // than wait for the TileManager to actually raster the content! if (!pending_tree_fully_painted_) return; - pending_tree_raster_duration_timer_.reset(); client_->NotifyReadyToActivate(); } @@ -2186,23 +2142,6 @@ void LayerTreeHostImpl::ReclaimResources( // In OOM, we now might be able to release more resources that were held // because they were exported. if (resource_pool_) { - if (resource_pool_->memory_usage_bytes()) { - const size_t kMegabyte = 1024 * 1024; - // This is a good time to log memory usage. A chunk of work has just - // completed but none of the memory used for that work has likely been - // freed. - std::string client_suffix; - if (settings_.commit_to_active_tree) { - client_suffix = "Browser"; - } else if (settings_.is_layer_tree_for_subframe) { - client_suffix = "OOPIF"; - } else { - client_suffix = "Renderer"; - } - base::UmaHistogramMemoryMB( - "Compositing.ResourcePoolMemoryUsage." + client_suffix, - static_cast<int>(resource_pool_->memory_usage_bytes() / kMegabyte)); - } resource_pool_->ReduceResourceUsage(); } @@ -2276,6 +2215,11 @@ void LayerTreeHostImpl::OnCompositorFrameTransitionDirectiveProcessed( SetNeedsCommit(); } +void LayerTreeHostImpl::ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) { + client_->ReportEventLatency(std::move(latencies)); +} + void LayerTreeHostImpl::OnCanDrawStateChangedForTree() { client_->OnCanDrawStateChanged(CanDraw()); } @@ -2469,6 +2413,14 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata( child_local_surface_id_allocator_.GetCurrentLocalSurfaceId(); } + metadata.previous_surfaces_visual_update_duration = + active_tree()->previous_surfaces_visual_update_duration(); + metadata.current_surface_visual_update_duration = + active_tree()->visual_update_duration(); + // We only want to report the durations from a Commit the first time. Not for + // subsequent Impl-only frames. + active_tree()->ClearVisualUpdateDurations(); + return metadata; } @@ -2516,9 +2468,15 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers( } base::TimeTicks submit_time = base::TimeTicks::Now(); - layer_tree_frame_sink_->SubmitCompositorFrame( - std::move(compositor_frame), - /*hit_test_data_changed=*/false); + { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.SubmitCompositorFrame", + TRACE_ID_GLOBAL(active_tree()->trace_id()), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + layer_tree_frame_sink_->SubmitCompositorFrame( + std::move(compositor_frame), + /*hit_test_data_changed=*/false); + } #if DCHECK_IS_ON() if (!doing_sync_draw_) { @@ -2554,6 +2512,11 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers( !mutator_host_->HasSmilAnimation()) { frame_trackers_.StopSequence( FrameSequenceTrackerType::kMainThreadAnimation); + frame_trackers_.StopSequence( + FrameSequenceTrackerType::kSETMainThreadAnimation); + } else if (!mutator_host_->HasSharedElementTransition()) { + frame_trackers_.StopSequence( + FrameSequenceTrackerType::kSETMainThreadAnimation); } if (lcd_text_metrics_reporter_) { @@ -2575,7 +2538,6 @@ absl::optional<LayerTreeHostImpl::SubmitInfo> LayerTreeHostImpl::DrawLayers( } active_tree_->ResetAllChangeTracking(); - active_tree_->set_has_ever_been_drawn(true); devtools_instrumentation::DidDrawFrame( id_, frame->begin_frame_ack.frame_id.sequence_number); benchmark_instrumentation::IssueImplThreadRenderingStatsEvent( @@ -2595,6 +2557,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( TRACE_ID_GLOBAL(CurrentBeginFrameArgs().trace_id), TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step", "GenerateCompositorFrame"); + rendering_stats_instrumentation_->IncrementFrameCount(1); memory_history_->SaveEntry(tile_manager_.memory_stats_from_last_assign()); @@ -2686,13 +2649,11 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( constexpr auto kTwiceOfDefaultInterval = viz::BeginFrameArgs::DefaultInterval() * 2; constexpr auto kMinDelta = kTwiceOfDefaultInterval - kFudgeDelta; - if (enable_frame_rate_throttling_) { - metadata.preferred_frame_interval = viz::BeginFrameArgs::MaxInterval(); - } else if (mutator_host_->MainThreadAnimationsCount() == 0 && - !mutator_host_->HasSmilAnimation() && - mutator_host_->NeedsTickAnimations() && - !frame_rate_estimator_.input_priority_mode() && - mutator_host_->MinimumTickInterval() > kMinDelta) { + if (mutator_host_->MainThreadAnimationsCount() == 0 && + !mutator_host_->HasSmilAnimation() && + mutator_host_->NeedsTickAnimations() && + !frame_rate_estimator_.input_priority_mode() && + mutator_host_->MinimumTickInterval() > kMinDelta) { // All animations are impl-thread animations that tick at no more than // half the default display compositing fps. // Here and below with FrameRateEstimator::GetPreferredInterval(), the @@ -3327,12 +3288,6 @@ void LayerTreeHostImpl::ActivateSyncTree() { pending_tree_->local_surface_id_from_parent().ToString()); active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kBeginningSync); - // In most cases, this will be reset in NotifyReadyToActivate, since we - // activate the pending tree only when its ready. But an activation may be - // forced, in the case of a context loss for instance, so reset it here as - // well. - pending_tree_raster_duration_timer_.reset(); - // Process any requests in the UI resource queue. The request queue is // given in LayerTreeHost::FinishCommit. This must take place before the // swap. @@ -4169,7 +4124,7 @@ LayerTreeHostImpl::ProcessCompositorDeltas() { // We should never process non-unit page_scale_delta for an OOPIF subframe. // TODO(wjmaclean): Remove this DCHECK as a pre-condition to closing the bug. // https://crbug.com/845097 - DCHECK(!settings().is_layer_tree_for_subframe || + DCHECK(settings().is_for_scalable_page || commit_data->page_scale_delta == 1.f); commit_data->top_controls_delta = active_tree()->top_controls_shown_ratio()->PullDeltaForMainThread(); @@ -4290,6 +4245,14 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time, FrameSequenceTrackerType::kCompositorAnimation); } + if (animated && mutator_host_->HasSharedElementTransition()) { + frame_trackers_.StartSequence( + FrameSequenceTrackerType::kSETCompositorAnimation); + } else { + frame_trackers_.StopSequence( + FrameSequenceTrackerType::kSETCompositorAnimation); + } + // TODO(crbug.com/551138): We could return true only if the animations are on // the active tree. There's no need to cause a draw to take place from // animations starting/ticking on the pending tree. @@ -4333,6 +4296,13 @@ void LayerTreeHostImpl::RegisterScrollbarAnimationController( scrollbar_opacity); } +void LayerTreeHostImpl::DidRegisterScrollbarLayer( + ElementId scroll_element_id, + ScrollbarOrientation orientation) { + if (input_delegate_) + input_delegate_->DidRegisterScrollbar(scroll_element_id, orientation); +} + void LayerTreeHostImpl::DidUnregisterScrollbarLayer( ElementId scroll_element_id, ScrollbarOrientation orientation) { @@ -4404,6 +4374,10 @@ ScrollbarSet LayerTreeHostImpl::ScrollbarsFor(ElementId id) const { return active_tree_->ScrollbarsFor(id); } +bool LayerTreeHostImpl::IsFluentScrollbar() const { + return settings().enable_fluent_scrollbar; +} + void LayerTreeHostImpl::AddVideoFrameController( VideoFrameController* controller) { bool was_empty = video_frame_controllers_.empty(); @@ -5152,6 +5126,15 @@ void LayerTreeHostImpl::RequestInvalidationForAnimatedImages() { client_->NeedsImplSideInvalidation(needs_first_draw_on_activation); } +bool LayerTreeHostImpl::IsReadyToActivate() const { + return client_->IsReadyToActivate(); +} + +void LayerTreeHostImpl::RequestImplSideInvalidationForRerasterTiling() { + bool needs_first_draw_on_activation = true; + client_->NeedsImplSideInvalidation(needs_first_draw_on_activation); +} + base::WeakPtr<LayerTreeHostImpl> LayerTreeHostImpl::AsWeakPtr() { return weak_factory_.GetWeakPtr(); } diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index 782a3c0de89..1b985be80c6 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -32,6 +32,7 @@ #include "cc/layers/layer_collections.h" #include "cc/metrics/average_lag_tracking_manager.h" #include "cc/metrics/dropped_frame_counter.h" +#include "cc/metrics/event_latency_tracker.h" #include "cc/metrics/event_metrics.h" #include "cc/metrics/events_metrics_manager.h" #include "cc/metrics/frame_sequence_tracker_collection.h" @@ -92,7 +93,6 @@ class MemoryHistory; class MutatorEvents; class MutatorHost; class PageScaleAnimation; -class PendingTreeRasterDurationHistogramTimer; class RasterTilePriorityQueue; class RasterBufferProvider; class RasterQueryQueue; @@ -119,6 +119,7 @@ class LayerTreeHostImplClient { virtual void DidReceiveCompositorFrameAckOnImplThread() = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; virtual void NotifyReadyToActivate() = 0; + virtual bool IsReadyToActivate() = 0; virtual void NotifyReadyToDraw() = 0; // Please call these 2 functions through // LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsOneBeginImplFrame(). @@ -127,6 +128,7 @@ class LayerTreeHostImplClient { virtual void SetNeedsCommitOnImplThread() = 0; virtual void SetNeedsPrepareTilesOnImplThread() = 0; virtual void SetVideoNeedsBeginFrames(bool needs_begin_frames) = 0; + virtual void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) = 0; virtual bool IsInsideDraw() = 0; virtual void RenewTreePriority() = 0; virtual void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task, @@ -180,6 +182,9 @@ class LayerTreeHostImplClient { virtual size_t CommitDurationSampleCountForTesting() const = 0; + virtual void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) = 0; + protected: virtual ~LayerTreeHostImplClient() = default; }; @@ -193,7 +198,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, public VideoFrameControllerClient, public MutatorHostClient, public ImageAnimationController::Client, - public CompositorDelegateForInput { + public CompositorDelegateForInput, + public EventLatencyTracker { public: // This structure is used to build all the state required for producing a // single CompositorFrame. The |render_passes| list becomes the set of @@ -318,7 +324,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, return viewport_damage_rect_; } - virtual void WillSendBeginMainFrame(); + virtual void WillSendBeginMainFrame() {} virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args); virtual void BeginMainFrameAborted( CommitEarlyOutReason reason, @@ -329,7 +335,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, const viz::BeginFrameArgs& commit_args, const BeginMainFrameMetrics* begin_main_frame_metrics, bool commit_timeout = false); - virtual void BeginCommit(int source_frame_number); + virtual void BeginCommit(int source_frame_number, uint64_t trace_id); virtual void FinishCommit(CommitState& commit_state, const ThreadUnsafeCommitState& unsafe_state); virtual void CommitComplete(); @@ -343,7 +349,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, void DidAnimateScrollOffset(); void SetFullViewportDamage(); void SetViewportDamage(const gfx::Rect& damage_rect); - void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling); // Interface for ThreadedInputHandler void BindToInputHandler( @@ -371,6 +376,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, const LayerTreeSettings& GetSettings() const override; LayerTreeHostImpl& GetImplDeprecated() override; const LayerTreeHostImpl& GetImplDeprecated() const override; + void SetDeferBeginMainFrame(bool defer_begin_main_frame) const override; bool CanInjectJankOnMain() const; FrameSequenceTrackerCollection& frame_trackers() { return frame_trackers_; } @@ -481,8 +487,11 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, // When blocking, this prevents client_->NotifyReadyToActivate() from being // called. When disabled, it calls client_->NotifyReadyToActivate() - // immediately if any notifications had been blocked while blocking. - virtual void BlockNotifyReadyToActivateForTesting(bool block); + // immediately if any notifications had been blocked while blocking and + // notify_if_blocked is true. + virtual void BlockNotifyReadyToActivateForTesting( + bool block, + bool notify_if_blocked = true); // Prevents notifying the |client_| when an impl side invalidation request is // made. When unblocked, the disabled request will immediately be called. @@ -495,6 +504,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, void RegisterScrollbarAnimationController(ElementId scroll_element_id, float initial_opacity); + void DidRegisterScrollbarLayer(ElementId scroll_element_id, + ScrollbarOrientation orientation); void DidUnregisterScrollbarLayer(ElementId scroll_element_id, ScrollbarOrientation orientation); ScrollbarAnimationController* ScrollbarAnimationControllerForElementId( @@ -535,6 +546,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, void SetNeedsRedrawForScrollbarAnimation() override; ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override; void DidChangeScrollbarVisibility() override; + bool IsFluentScrollbar() const override; // VideoBeginFrameSource implementation. void AddVideoFrameController(VideoFrameController* controller) override; @@ -561,6 +573,10 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, void OnCompositorFrameTransitionDirectiveProcessed( uint32_t sequence_id) override; + // EventLatencyTracker implementation. + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) override; + // Called from LayerTreeImpl. void OnCanDrawStateChangedForTree(); @@ -879,6 +895,10 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, return throttle_decider_.ids(); } + bool IsReadyToActivate() const; + + void RequestImplSideInvalidationForRerasterTiling(); + protected: LayerTreeHostImpl( const LayerTreeSettings& settings, @@ -1181,9 +1201,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, bool may_throttle_if_undrawn_frames_ = true; - std::unique_ptr<PendingTreeRasterDurationHistogramTimer> - pending_tree_raster_duration_timer_; - // These completion states to be transfered to the main thread when we // begin main frame. The pair represents a request id and the completion (ie // success) state. @@ -1270,8 +1287,6 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient, FrameRateEstimator frame_rate_estimator_; bool has_observed_first_scroll_delay_ = false; - bool enable_frame_rate_throttling_ = false; - // True if we are measuring smoothness in TotalFrameCounter and // DroppedFrameCounter. Currently true when first contentful paint is done. bool is_measuring_smoothness_ = false; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index f7bca00a04a..3b1e8aa5ed6 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -83,7 +83,6 @@ #include "components/viz/common/quads/tile_draw_quad.h" #include "components/viz/common/surfaces/frame_sink_id.h" #include "components/viz/common/surfaces/region_capture_bounds.h" -#include "components/viz/service/display/gl_renderer.h" #include "components/viz/service/display/skia_output_surface.h" #include "components/viz/test/begin_frame_args_test.h" #include "components/viz/test/fake_output_surface.h" @@ -215,6 +214,11 @@ class LayerTreeHostImplTest : public testing::Test, did_notify_ready_to_activate_ = true; host_impl_->ActivateSyncTree(); } + bool IsReadyToActivate() override { + // in NotifyReadyToActivate(), call ActivateSyncTree() directly + // so this is always false + return false; + } void NotifyReadyToDraw() override {} void SetNeedsRedrawOnImplThread() override { did_request_redraw_ = true; } void SetNeedsOneBeginImplFrameOnImplThread() override { @@ -225,6 +229,7 @@ class LayerTreeHostImplTest : public testing::Test, } void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; } void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {} + void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override {} bool IsInsideDraw() override { return false; } void RenewTreePriority() override {} void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task, @@ -272,6 +277,8 @@ class LayerTreeHostImplTest : public testing::Test, void NotifyPaintWorkletStateChange( Scheduler::PaintWorkletState state) override {} void NotifyThroughputTrackerResults(CustomTrackerResults results) override {} + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) override {} void DidObserveFirstScrollDelay( base::TimeDelta first_scroll_delay, @@ -674,7 +681,7 @@ class LayerTreeHostImplTest : public testing::Test, FakeRasterSource::CreateFromRecordingSource(recording_source.get()); // Create the pending tree. - host_impl_->BeginCommit(0); + host_impl_->BeginCommit(0, /*trace_id=*/1); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); LayerImpl* root = SetupRootLayer<FakePictureLayerImpl>( pending_tree, layer_size, raster_source); @@ -3485,7 +3492,6 @@ class MissingTilesLayer : public LayerImpl { AppendQuadsData* append_quads_data) override { append_quads_data->num_missing_tiles += 10; append_quads_data->checkerboarded_no_recording_content_area += 200; - append_quads_data->checkerboarded_needs_raster_content_area += 200; append_quads_data->visible_layer_area += 200; } }; @@ -4407,9 +4413,11 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, SyncSubpixelScrollDelta) { // Verify this scroll delta is consistent with the snapped position of the // scroll layer. - draw_property_utils::ComputeTransforms(&scroll_layer->layer_tree_impl() - ->property_trees() - ->transform_tree_mutable()); + draw_property_utils::ComputeTransforms( + &scroll_layer->layer_tree_impl() + ->property_trees() + ->transform_tree_mutable(), + scroll_layer->layer_tree_impl()->viewport_property_ids()); EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0, -19), scroll_layer->ScreenSpaceTransform().To2dTranslation()); } @@ -6242,7 +6250,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, auto* layer = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); layer->SetBounds(gfx::Size(10, 10)); layer->SetDrawsContent(true); - layer->SetBackgroundColor(SK_ColorRED); + layer->SetBackgroundColor(SkColors::kRed); CopyProperties(root, layer); UpdateDrawProperties(host_impl_->active_tree()); @@ -11043,7 +11051,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); // This will damage everything. - root->SetBackgroundColor(SK_ColorBLACK); + root->SetBackgroundColor(SkColors::kBlack); args = viz::CreateBeginFrameArgsForTesting( BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1, base::TimeTicks() + base::Milliseconds(1)); @@ -11250,13 +11258,13 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) { auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), gfx::Size(10, 10)); root->SetDrawsContent(true); - root->SetBackgroundColor(SK_ColorRED); + root->SetBackgroundColor(SkColors::kRed); // Child layer is in the bottom right corner. auto* child = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); - child->SetBackgroundColor(SK_ColorRED); + child->SetBackgroundColor(SkColors::kRed); CopyProperties(root, child); child->SetOffsetToTransformParent(gfx::Vector2dF(9, 9)); @@ -11278,11 +11286,6 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) { DrawFrameAndTestDamage(no_damage, child); } -class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer { - public: - using viz::GLRenderer::ShouldAntialiasQuad; -}; - TEST_P(ScrollUnifiedLayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { // Due to precision issues (especially on Android), sometimes far // away quads can end up thinking they need AA. @@ -11334,16 +11337,12 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { ASSERT_LE(1u, frame.render_passes[0]->quad_list.size()); const viz::DrawQuad* quad = frame.render_passes[0]->quad_list.front(); - bool clipped = false, force_aa = false; - gfx::QuadF device_layer_quad = MathUtil::MapQuad( + bool clipped = false; + MathUtil::MapQuad( quad->shared_quad_state->quad_to_target_transform, gfx::QuadF(gfx::RectF(quad->shared_quad_state->visible_quad_layer_rect)), &clipped); EXPECT_FALSE(clipped); - bool antialiased = - GLRendererWithSetupQuadForAntialiasing::ShouldAntialiasQuad( - device_layer_quad, clipped, force_aa); - EXPECT_FALSE(antialiased); host_impl_->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); @@ -11530,7 +11529,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>( host_impl_->active_tree(), gfx::Size(10, 10)); - root->SetBackgroundColor(SK_ColorRED); + root->SetBackgroundColor(SkColors::kRed); UpdateDrawProperties(host_impl_->active_tree()); // RequiresHighResToDraw is set when new output surface is used. @@ -11651,108 +11650,6 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, CreateETC1UIResource) { EXPECT_NE(viz::kInvalidResourceId, id1); } -class FrameSinkClient : public TestLayerTreeFrameSinkClient { - public: - explicit FrameSinkClient( - scoped_refptr<viz::ContextProvider> display_context_provider) - : display_context_provider_(std::move(display_context_provider)) {} - - std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController> - CreateDisplayController() override { - // In this implementation, no output surface has a real gpu thread, and - // there is no overlay support. - return nullptr; - } - std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface( - viz::DisplayCompositorMemoryAndTaskController*) override { - return viz::FakeSkiaOutputSurface::Create3d( - std::move(display_context_provider_)); - } - - std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurface( - scoped_refptr<viz::ContextProvider> compositor_context_provider) - override { - return viz::FakeOutputSurface::Create3d( - std::move(display_context_provider_)); - } - - void DisplayReceivedLocalSurfaceId( - const viz::LocalSurfaceId& local_surface_id) override {} - void DisplayReceivedCompositorFrame( - const viz::CompositorFrame& frame) override {} - void DisplayWillDrawAndSwap( - bool will_draw_and_swap, - viz::AggregatedRenderPassList* render_passes) override {} - void DisplayDidDrawAndSwap() override {} - - private: - scoped_refptr<viz::ContextProvider> display_context_provider_; -}; - -using LayerTreeHostImplTestWithRenderer = LayerTreeHostImplTest; - -TEST_F(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) { - viz::DebugRendererSettings debug_settings; - - scoped_refptr<viz::TestContextProvider> context_provider = - viz::TestContextProvider::Create(); - FrameSinkClient test_client(context_provider); - - constexpr bool synchronous_composite = true; - constexpr bool disable_display_vsync = false; - constexpr double refresh_rate = 60.0; - std::unique_ptr<TaskRunnerProvider> task_runner_provider = - TaskRunnerProvider::Create(base::ThreadTaskRunnerHandle::Get(), nullptr); - auto layer_tree_frame_sink = std::make_unique<TestLayerTreeFrameSink>( - context_provider, viz::TestContextProvider::CreateWorker(), nullptr, - viz::RendererSettings(), &debug_settings, task_runner_provider.get(), - synchronous_composite, disable_display_vsync, refresh_rate); - layer_tree_frame_sink->SetClient(&test_client); - - CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); - - LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); - struct Helper { - std::unique_ptr<viz::CopyOutputResult> unprocessed_result; - void OnResult(base::OnceClosure finished, - std::unique_ptr<viz::CopyOutputResult> result) { - unprocessed_result = std::move(result); - std::move(finished).Run(); - } - } helper; - - GetEffectNode(root)->has_copy_request = true; - base::RunLoop copy_request_run_loop; - GetPropertyTrees(root)->effect_tree_mutable().AddCopyRequest( - root->effect_tree_index(), - std::make_unique<viz::CopyOutputRequest>( - viz::CopyOutputRequest::ResultFormat::RGBA, - viz::CopyOutputRequest::ResultDestination::kNativeTextures, - base::BindOnce(&Helper::OnResult, base::Unretained(&helper), - copy_request_run_loop.QuitClosure()))); - DrawFrame(); - - auto* sii = context_provider->SharedImageInterface(); - // The CopyOutputResult has a ref on the viz::ContextProvider and a shared - // image allocated. - copy_request_run_loop.Run(); - EXPECT_TRUE(helper.unprocessed_result); - EXPECT_FALSE(context_provider->HasOneRef()); - EXPECT_EQ(1u, sii->shared_image_count()); - - host_impl_->ReleaseLayerTreeFrameSink(); - host_impl_ = nullptr; - - // The texture release callback that was given to the CopyOutputResult has - // been canceled, and the shared image deleted. - EXPECT_TRUE(context_provider->HasOneRef()); - EXPECT_EQ(0u, sii->shared_image_count()); - - // When resetting the CopyOutputResult, it will run its texture release - // callback. This should not cause a crash, etc. - helper.unprocessed_result.reset(); -} - // This tests the case where hit testing only on scrollable layers returns a // layer that's outside the scroll chain of the first hit test *any* layer. See // LayerTreeHostImpl::IsInitialScrollHitTestReliable for details. @@ -13729,6 +13626,65 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, host_impl_ = nullptr; } +// Tests that no scrolls occur when thumb_len equals track_len. +TEST_P(ScrollUnifiedLayerTreeHostImplTest, ScrollOnLargeThumb) { + LayerTreeSettings settings = DefaultSettings(); + settings.compositor_threaded_scrollbar_scrolling = true; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + + // Setup the viewport. + const gfx::Size viewport_size = gfx::Size(360, 600); + const gfx::Size content_size = gfx::Size(345, 3800); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); + + // Set up the scrollbar and its dimensions. + LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); + layer_tree_impl->set_painted_device_scale_factor(2.5f); + auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + layer_tree_impl, ScrollbarOrientation::VERTICAL, false, true); + SetupScrollbarLayerCommon(scroll_layer, scrollbar); + scrollbar->SetHitTestable(true); + + const gfx::Size scrollbar_size = gfx::Size(15, 600); + scrollbar->SetBounds(scrollbar_size); + + // Set up the thumb dimensions. + scrollbar->SetThumbThickness(15); + scrollbar->SetThumbLength(575); + scrollbar->SetTrackRect(gfx::Rect(0, 15, 15, 575)); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); + + TestInputHandlerClient input_handler_client; + GetInputHandler().BindToClient(&input_handler_client); + + // PointerDown on the scrollbar should populate drag_state. + GetInputHandler().MouseDown(gfx::PointF(350, 300), + /*jump_key_modifier*/ false); + EXPECT_TRUE(GetInputHandler() + .scrollbar_controller_for_testing() + ->drag_state_.has_value()); + + // Moving the mouse downwards should result in no scroll. + InputHandlerPointerResult res = + GetInputHandler().MouseMoveAt(gfx::Point(350, 600)); + EXPECT_EQ(res.scroll_delta.y(), 0); + + // Moving the mouse upwards should result in no scroll. + res = GetInputHandler().MouseMoveAt(gfx::Point(350, 0)); + EXPECT_EQ(res.scroll_delta.y(), 0); + + // End the scroll. + GetInputHandler().MouseUp(gfx::PointF(350, 0)); + EXPECT_TRUE(!GetInputHandler() + .scrollbar_controller_for_testing() + ->drag_state_.has_value()); + + // Tear down the LayerTreeHostImpl before the InputHandlerClient. + host_impl_->ReleaseLayerTreeFrameSink(); + host_impl_ = nullptr; +} + // Tests that deleting a horizontal scrollbar doesn't affect the autoscroll task // for the vertical scrollbar. TEST_P(ScrollUnifiedLayerTreeHostImplTest, AutoscrollOnDeletedScrollbar) { @@ -13777,12 +13733,45 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, AutoscrollOnDeletedScrollbar) { ->AutoscrollTaskIsScheduled()); // If a call comes in to delete the scrollbar layer for which the autoscroll - // was scheduled, the autoscroll task should be cancelled. - host_impl_->DidUnregisterScrollbarLayer(scroll_layer->element_id(), - ScrollbarOrientation::VERTICAL); - EXPECT_FALSE(GetInputHandler() - .scrollbar_controller_for_testing() - ->AutoscrollTaskIsScheduled()); + // was scheduled, the autoscroll task should set a waiting state instead of + // initiating an autoscroll, in case the scrollbar comes back. + layer_tree_impl->UnregisterScrollbar(scrollbar); + + EXPECT_TRUE(GetInputHandler() + .scrollbar_controller_for_testing() + ->AutoscrollTaskIsScheduled()); + + GetInputHandler() + .scrollbar_controller_for_testing() + ->cancelable_autoscroll_task_->callback() + .Run(); + GetInputHandler() + .scrollbar_controller_for_testing() + ->cancelable_autoscroll_task_.reset(); + EXPECT_EQ(GetInputHandler() + .scrollbar_controller_for_testing() + ->autoscroll_state_->status, + ScrollbarController::AutoScrollStatus::AUTOSCROLL_READY); + + // Re-register the scrollbar. An autoscroll task should be posted that + // actually starts a scroll animation + layer_tree_impl->RegisterScrollbar(scrollbar); + + EXPECT_TRUE(GetInputHandler() + .scrollbar_controller_for_testing() + ->AutoscrollTaskIsScheduled()); + + GetInputHandler() + .scrollbar_controller_for_testing() + ->cancelable_autoscroll_task_->callback() + .Run(); + GetInputHandler() + .scrollbar_controller_for_testing() + ->cancelable_autoscroll_task_.reset(); + EXPECT_EQ(GetInputHandler() + .scrollbar_controller_for_testing() + ->autoscroll_state_->status, + ScrollbarController::AutoScrollStatus::AUTOSCROLL_SCROLLING); // End the scroll. GetInputHandler().MouseUp(gfx::PointF(350, 580)); @@ -14336,9 +14325,10 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, ThumbDragAfterJumpClick) { scrollbar->SetBounds(scrollbar_size); host_impl_->set_force_smooth_wheel_scrolling_for_testing(true); + const int thumb_len = 50; // Set up the thumb dimensions. scrollbar->SetThumbThickness(15); - scrollbar->SetThumbLength(50); + scrollbar->SetThumbLength(thumb_len); scrollbar->SetTrackRect(gfx::Rect(0, 15, 15, 575)); // Set up scrollbar arrows. @@ -14371,11 +14361,17 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, ThumbDragAfterJumpClick) { .scrollbar_controller_for_testing() ->drag_state_.has_value()); - // This verifies that the jump click delta was accounted for correctly. + // This verifies that the start/snap-back position is the scroll position + // before any jump-click EXPECT_FLOAT_EQ(GetInputHandler() .scrollbar_controller_for_testing() ->drag_state_->scroll_position_at_start_, - 243.80952f); + 0.0f); + + EXPECT_FLOAT_EQ(GetInputHandler() + .scrollbar_controller_for_testing() + ->drag_state_->drag_origin.y(), + 15.0f + thumb_len / 2.0f); } // Tear down the LayerTreeHostImpl before the InputHandlerClient. @@ -14454,10 +14450,16 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, // existing scroll offset animations are aborted and a new autoscroll // animation is created. Test passes if unit test doesn't hit any DCHECK // failures. + GetInputHandler().scrollbar_controller_for_testing()->autoscroll_state_ = + ScrollbarController::AutoScrollState(); + GetInputHandler() + .scrollbar_controller_for_testing() + ->autoscroll_state_->velocity = 800; GetInputHandler() .scrollbar_controller_for_testing() - ->StartAutoScrollAnimation(/*scroll_velocity*/ 800, - ScrollbarPart::FORWARD_TRACK); + ->autoscroll_state_->pressed_scrollbar_part = + ScrollbarPart::FORWARD_TRACK; + GetInputHandler().scrollbar_controller_for_testing()->StartAutoScroll(); EXPECT_TRUE(GetImplAnimationHost()->ImplOnlyScrollAnimatingElement()); } @@ -15797,7 +15799,7 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, } TEST_P(ScrollUnifiedLayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { - // Check page scale factor update in property trees when an update is made + // Check page scale factor updates the property trees when an update is made // on the active tree. CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 3); @@ -15816,20 +15818,26 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { EXPECT_EQ(gfx::Vector2dF(2, 2), active_tree_node->local.To2dScale()); EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); EXPECT_EQ(2, host_impl_->active_tree()->current_page_scale_factor()); + EXPECT_EQ(2, host_impl_->active_tree() + ->property_trees() + ->transform_tree() + .page_scale_factor()); TransformNode* pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode(); - // Before pending tree updates draw properties, its properties are still - // based on 1.0 page scale, except for current_page_scale_factor() which is a - // shared data between the active and pending trees. - EXPECT_TRUE(pending_tree_node->local.IsIdentity()); + + // Since the pending tree shares the scale factor with the active tree, its + // value and property trees should also have been updated. + EXPECT_TRUE(pending_tree_node->local.IsScale2d()); + EXPECT_EQ(gfx::Vector2dF(2, 2), pending_tree_node->local.To2dScale()); EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); EXPECT_EQ(2, host_impl_->pending_tree()->current_page_scale_factor()); - EXPECT_EQ(1, host_impl_->pending_tree() + EXPECT_EQ(2, host_impl_->pending_tree() ->property_trees() ->transform_tree() .page_scale_factor()); + // Update draw properties doesn't change the correct values host_impl_->pending_tree()->set_needs_update_draw_properties(); UpdateDrawProperties(host_impl_->pending_tree()); pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode(); @@ -16168,7 +16176,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, CheckerImagingTileInvalidation) { host_impl_->WillBeginImplFrame(begin_frame_args); // Create the pending tree. - host_impl_->BeginCommit(0); + host_impl_->BeginCommit(0, /*trace_id=*/1); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); auto* root = SetupRootLayer<FakePictureLayerImpl>(pending_tree, layer_size, raster_source); @@ -16303,7 +16311,7 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, RasterColorSpaceHDR) { EXPECT_EQ(wcg_params.sdr_max_luminance_nits, kCustomWhiteLevel); EXPECT_EQ(wcg_params.hdr_max_luminance_relative, 1.f); - EXPECT_EQ(hdr_params.color_space, hdr); + EXPECT_EQ(hdr_params.color_space, gfx::ColorSpace::CreateExtendedSRGB()); EXPECT_EQ(hdr_params.sdr_max_luminance_nits, kCustomWhiteLevel); EXPECT_EQ(hdr_params.hdr_max_luminance_relative, kHDRMaxLuminanceRelative); } @@ -18295,4 +18303,62 @@ TEST_F(LayerTreeHostImplTest, CollectRegionCaptureBounds) { collected_bounds.bounds().find(kFourthId)->second); } +// Check if picturelayer's ScrollInteractionInProgress() return true even when +// BrowserControl is consuming ScrollUpdate. +TEST_P(LayerTreeHostImplBrowserControlsTest, + BrowserControlsScrollInteractionInProgress) { + gfx::Size inner_size = gfx::Size(100, 100); + gfx::Size outer_size = gfx::Size(100, 100); + gfx::Size content_size = gfx::Size(100, 200); + SetupBrowserControlsAndScrollLayerWithVirtualViewport(inner_size, outer_size, + content_size); + + LayerTreeImpl* active_tree = host_impl_->active_tree(); + + // Create a content layer beneath the outer viewport scroll layer. + scoped_refptr<FakeRasterSource> raster_source( + FakeRasterSource::CreateFilled(content_size)); + + auto* picture_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->active_tree(), raster_source); + CopyProperties(OuterViewportScrollLayer(), picture_layer); + picture_layer->SetBounds(content_size); + picture_layer->SetDrawsContent(true); + picture_layer->SetNeedsPushProperties(); + active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 2.0f); + DrawFrame(); + + EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, + GetInputHandler() + .ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 50), + ui::ScrollInputType::kTouchscreen) + .get(), + ui::ScrollInputType::kTouchscreen) + .thread); + // shownratio == 1 + EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), false); + + // 0 < shownratio <1 + GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(), + gfx::Vector2dF(0, 25), + ui::ScrollInputType::kTouchscreen) + .get()); + EXPECT_GT(host_impl_->active_tree()->CurrentTopControlsShownRatio(), 0); + EXPECT_LT(host_impl_->active_tree()->CurrentTopControlsShownRatio(), 1); + EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), true); + + GetInputHandler().ScrollUpdate(UpdateState(gfx::Point(), + gfx::Vector2dF(0, 30), + ui::ScrollInputType::kTouchscreen) + .get()); + // now shownratio == 0 + EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), true); + + GetInputHandler().ScrollEnd(); + // scroll end, shownratio == 0 + EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + EXPECT_EQ(picture_layer->ScrollInteractionInProgress(), false); +} } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index f8b31c672ca..fc3d5a9f063 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -63,7 +63,6 @@ using RenderPassOptions = uint32_t; const uint32_t kUseMasks = 1 << 0; const uint32_t kUseAntialiasing = 1 << 1; const uint32_t kUseColorMatrix = 1 << 2; -const uint32_t kForceShaders = 1 << 3; class LayerTreeHostBlendingPixelTest : public LayerTreeHostPixelResourceTest, @@ -72,8 +71,7 @@ class LayerTreeHostBlendingPixelTest public: LayerTreeHostBlendingPixelTest() : LayerTreeHostPixelResourceTest(resource_type()), - force_antialiasing_(false), - force_blending_with_shaders_(false) { + force_antialiasing_(false) { pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true); } @@ -93,8 +91,6 @@ class LayerTreeHostBlendingPixelTest override { viz::RendererSettings modified_renderer_settings = renderer_settings; modified_renderer_settings.force_antialiasing = force_antialiasing_; - modified_renderer_settings.force_blending_with_shaders = - force_blending_with_shaders_; return LayerTreeHostPixelResourceTest::CreateLayerTreeFrameSink( modified_renderer_settings, refresh_rate, compositor_context_provider, worker_context_provider); @@ -211,10 +207,6 @@ class LayerTreeHostBlendingPixelTest const int kRootWidth = 2; const int kRootHeight = kRootWidth * kCSSTestColorsCount; - // Force shaders only applies to gl renderer. - if (renderer_type_ != viz::RendererType::kGL && flags & kForceShaders) - return; - SCOPED_TRACE(TestTypeToString()); SCOPED_TRACE(SkBlendMode_Name(current_blend_mode())); @@ -229,10 +221,8 @@ class LayerTreeHostBlendingPixelTest CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags); force_antialiasing_ = (flags & kUseAntialiasing); - force_blending_with_shaders_ = (flags & kForceShaders); - if ((renderer_type_ == viz::RendererType::kGL && force_antialiasing_) || - renderer_type_ == viz::RendererType::kSkiaVk) { + if (renderer_type_ == viz::RendererType::kSkiaVk) { // Blending results might differ with one pixel. float percentage_pixels_error = 35.f; float percentage_pixels_small_error = 0.f; @@ -252,7 +242,6 @@ class LayerTreeHostBlendingPixelTest } bool force_antialiasing_; - bool force_blending_with_shaders_; FakeContentLayerClient mask_client_; FakeContentLayerClient backdrop_client_; SkColor misc_opaque_color_ = 0xffc86464; @@ -261,9 +250,6 @@ class LayerTreeHostBlendingPixelTest std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - {viz::RendererType::kGL, TestRasterType::kZeroCopy}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) @@ -423,44 +409,6 @@ TEST_P(LayerTreeHostBlendingPixelTest, RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix); } -TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShaders) { - RunBlendingWithRenderPass(kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersAA) { - RunBlendingWithRenderPass(kUseAntialiasing | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRenderPassShadersWithMask) { - RunBlendingWithRenderPass(kUseMasks | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, - BlendingWithRenderPassShadersWithMaskAA) { - RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, - BlendingWithRenderPassShadersColorMatrix) { - RunBlendingWithRenderPass(kUseColorMatrix | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, - BlendingWithRenderPassShadersColorMatrixAA) { - RunBlendingWithRenderPass(kUseAntialiasing | kUseColorMatrix | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, - BlendingWithRenderPassShadersWithMaskColorMatrix) { - RunBlendingWithRenderPass(kUseMasks | kUseColorMatrix | kForceShaders); -} - -TEST_P(LayerTreeHostBlendingPixelTest, - BlendingWithRenderPassShadersWithMaskColorMatrixAA) { - RunBlendingWithRenderPass(kUseMasks | kUseAntialiasing | kUseColorMatrix | - kForceShaders); -} - } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index 40114681266..e4b55f0fee0 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -32,8 +32,6 @@ class LayerTreeHostFiltersPixelTest // generating separate base line file paths. const char* GetRendererSuffix() { switch (renderer_type_) { - case viz::RendererType::kGL: - return "gl"; case viz::RendererType::kSkiaGL: return "skia_gl"; case viz::RendererType::kSkiaVk: @@ -151,12 +149,9 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterInvalid) { } TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) { -#if BUILDFLAG(IS_FUCHSIA) - // TODO(crbug.com/1311459): This test case fails on SwiftShader FEMU due - // to a new implementation of log/exp functions in SwiftShader. We should - // re-enable the test case once the bug is fixed. +#if defined(MEMORY_SANITIZER) if (renderer_type() == viz::RendererType::kSkiaVk) { - GTEST_SKIP(); + GTEST_SKIP() << "TODO(crbug.com/1324336): Uninitialized data error"; } #endif if (use_software_renderer()) { @@ -180,7 +175,9 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) { gfx::RRectF backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())), 0); blur->SetBackdropFilterBounds(backdrop_filter_bounds); -#if BUILDFLAG(IS_WIN) || defined(ARCH_CPU_ARM64) +#if BUILDFLAG(IS_FUCHSIA) + pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false); +#elif BUILDFLAG(IS_WIN) || defined(ARCH_CPU_ARM64) // Windows and ARM64 have 436 pixels off by 1: crbug.com/259915 float percentage_pixels_large_error = 1.09f; // 436px / (200*200) float percentage_pixels_small_error = 0.0f; @@ -249,6 +246,11 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRounded) { } TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) { +#if defined(MEMORY_SANITIZER) + if (renderer_type() == viz::RendererType::kSkiaVk) { + GTEST_SKIP() << "TODO(crbug.com/1324336): Uninitialized data error"; + } +#endif scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(200, 200), SK_ColorWHITE); @@ -553,14 +555,6 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterClipped) { } TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) { -#if BUILDFLAG(IS_FUCHSIA) - // TODO(crbug.com/1311459): This test case fails on SwiftShader FEMU due - // to a new implementation of log/exp functions in SwiftShader. We should - // re-enable the test case once the bug is fixed. - if (renderer_type() == viz::RendererType::kSkiaVk) { - GTEST_SKIP(); - } -#endif scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); @@ -599,7 +593,11 @@ TEST_P(LayerTreeHostFiltersPixelTest, ImageFilterScaled) { filter->SetBackdropFilters(filters); filter->ClearBackdropFilterBounds(); -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \ +#if BUILDFLAG(IS_FUCHSIA) + if (renderer_type() == viz::RendererType::kSkiaVk) { + pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false); + } +#elif BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH) || \ defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_ARM64) #if BUILDFLAG(IS_WIN) // Windows has 153 pixels off by at most 2: crbug.com/225027 diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index 6666f037039..c6bb12f88f5 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -31,11 +31,6 @@ namespace { std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - {viz::RendererType::kGL, TestRasterType::kGpu}, - {viz::RendererType::kGL, TestRasterType::kOneCopy}, - {viz::RendererType::kGL, TestRasterType::kZeroCopy}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, {viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, @@ -69,13 +64,13 @@ class MaskContentLayerClient : public ContentLayerClient { display_list->push<SaveOp>(); display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), SkClipOp::kIntersect, false); - SkColor color = SK_ColorTRANSPARENT; + SkColor4f color = SkColors::kTransparent; display_list->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(SkIntToScalar(2)); - flags.setColor(SK_ColorWHITE); + flags.setColor(SkColors::kWhite); gfx::Rect inset_rect(bounds_); while (!inset_rect.IsEmpty()) { @@ -259,7 +254,7 @@ class LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask LayerList layers = layer_tree_host()->root_layer()->children(); DCHECK_EQ(3u, layers.size()); // Set background to red. - layers[0]->SetBackgroundColor(SK_ColorRED); + layers[0]->SetBackgroundColor(SkColors::kRed); // Remove the green layer. layers.erase(layers.begin() + 1); layer_tree_host()->root_layer()->SetChildLayerList(layers); @@ -449,7 +444,7 @@ class CheckerContentLayerClient : public ContentLayerClient { display_list->push<SaveOp>(); display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), SkClipOp::kIntersect, false); - SkColor color = SK_ColorTRANSPARENT; + SkColor4f color = SkColors::kTransparent; display_list->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; @@ -496,7 +491,7 @@ class CircleContentLayerClient : public ContentLayerClient { display_list->push<SaveOp>(); display_list->push<ClipRectOp>(gfx::RectToSkRect(PaintableRegion()), SkClipOp::kIntersect, false); - SkColor color = SK_ColorTRANSPARENT; + SkColor4f color = SkColors::kTransparent; display_list->push<DrawColorOp>(color, SkBlendMode::kSrc); PaintFlags flags; @@ -788,8 +783,10 @@ class LayerTreeHostMaskAsBlendingPixelTest static scoped_refptr<Layer> CreateCheckerboardLayer(const gfx::Size& bounds) { constexpr int kGridSize = 8; - static const SkColor color_even = SkColorSetRGB(153, 153, 153); - static const SkColor color_odd = SkColorSetRGB(102, 102, 102); + static const SkColor4f color_even = + SkColor4f::FromColor(SkColorSetRGB(153, 153, 153)); + static const SkColor4f color_odd = + SkColor4f::FromColor(SkColorSetRGB(102, 102, 102)); auto display_list = base::MakeRefCounted<DisplayItemList>(); display_list->StartPaint(); @@ -873,15 +870,6 @@ class LayerTreeHostMaskAsBlendingPixelTest MaskTestConfig const kTestConfigs[] = { MaskTestConfig{{viz::RendererType::kSoftware, TestRasterType::kBitmap}, 0}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, 0}, - MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, - kUseAntialiasing}, - MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, - kForceShaders}, - MaskTestConfig{{viz::RendererType::kGL, TestRasterType::kZeroCopy}, - kUseAntialiasing | kForceShaders}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, 0}, MaskTestConfig{{viz::RendererType::kSkiaGL, TestRasterType::kZeroCopy}, kUseAntialiasing}, diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index 873f6469fc5..12d20437f73 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -441,10 +441,6 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) { ReadbackTestConfig const kTestConfigs[] = { ReadbackTestConfig{viz::RendererType::kSoftware, TestReadBackType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kTexture}, - ReadbackTestConfig{viz::RendererType::kGL, TestReadBackType::kBitmap}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kTexture}, ReadbackTestConfig{viz::RendererType::kSkiaGL, TestReadBackType::kBitmap}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index 76fc847c36a..fa8d72496d7 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -12,6 +12,7 @@ #include "cc/paint/paint_flags.h" #include "cc/paint/paint_op_buffer.h" #include "cc/test/layer_tree_pixel_test.h" +#include "cc/test/pixel_comparator.h" #include "cc/test/test_layer_tree_frame_sink.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/test/buildflags.h" @@ -222,10 +223,6 @@ class LayerTreeHostTilesTestRasterColorSpace std::vector<RasterTestConfig> const kTestCases = { {viz::RendererType::kSoftware, TestRasterType::kBitmap}, #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - {viz::RendererType::kGL, TestRasterType::kOneCopy}, - {viz::RendererType::kGL, TestRasterType::kGpu}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, {viz::RendererType::kSkiaGL, TestRasterType::kGpu}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) @@ -265,9 +262,6 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidation, FullRaster) { std::vector<RasterTestConfig> const kTestCasesMultiThread = { #if BUILDFLAG(ENABLE_GL_BACKEND_TESTS) -#if BUILDFLAG(ENABLE_GL_RENDERER_TESTS) - {viz::RendererType::kGL, TestRasterType::kOneCopy}, -#endif // BUILDFLAG(ENABLE_GL_RENDERER_TESTS) {viz::RendererType::kSkiaGL, TestRasterType::kOneCopy}, #endif // BUILDFLAG(ENABLE_GL_BACKEND_TESTS) #if BUILDFLAG(ENABLE_VULKAN_BACKEND_TESTS) @@ -335,11 +329,18 @@ TEST_P(LayerTreeHostTilesTestRasterColorSpace, GenericRGB) { SetColorSpace(gfx::ColorSpace(gfx::ColorSpace::PrimaryID::APPLE_GENERIC_RGB, gfx::ColorSpace::TransferID::GAMMA18)); - RunPixelTest(picture_layer_, - base::FilePath(FILE_PATH_LITERAL("primary_colors.png"))); + // Software rasterizer ignores XYZD50 matrix + const auto* target_png = + renderer_type() == viz::RendererType::kSoftware + ? FILE_PATH_LITERAL("primary_colors.png") + : FILE_PATH_LITERAL("primary_colors_sRGB_in_AdobeRGB.png"); + RunPixelTest(picture_layer_, base::FilePath(target_png)); } TEST_P(LayerTreeHostTilesTestRasterColorSpace, CustomColorSpace) { +#if BUILDFLAG(IS_FUCHSIA) + pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false); +#endif // Create a color space with a different blue point. SkColorSpacePrimaries primaries; skcms_Matrix3x3 to_XYZD50; @@ -355,8 +356,11 @@ TEST_P(LayerTreeHostTilesTestRasterColorSpace, CustomColorSpace) { SetColorSpace(gfx::ColorSpace::CreateCustom( to_XYZD50, gfx::ColorSpace::TransferID::SRGB)); - RunPixelTest(picture_layer_, - base::FilePath(FILE_PATH_LITERAL("primary_colors.png"))); + // Software rasterizer ignores XYZD50 matrix + const auto* target_png = renderer_type() == viz::RendererType::kSoftware + ? FILE_PATH_LITERAL("primary_colors.png") + : FILE_PATH_LITERAL("primary_colors_icced.png"); + RunPixelTest(picture_layer_, base::FilePath(target_png)); } // This test doesn't work on Vulkan because on our hardware we can't render to diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index a2c426e4e93..c66f51e04c6 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -79,6 +79,7 @@ #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/tile_draw_quad.h" #include "components/viz/service/display/output_surface.h" +#include "components/viz/service/display/skia_output_surface.h" #include "components/viz/test/begin_frame_args_test.h" #include "components/viz/test/fake_output_surface.h" #include "components/viz/test/test_gles2_interface.h" @@ -109,10 +110,6 @@ using testing::StrictMock; namespace cc { namespace { -const char kUserInteraction[] = "Compositor.UserInteraction"; -const char kCheckerboardArea[] = "CheckerboardedContentArea"; -const char kCheckerboardAreaRatio[] = "CheckerboardedContentAreaRatio"; -const char kMissingTiles[] = "NumMissingTiles"; bool LayerSubtreeHasCopyRequest(Layer* layer) { const LayerTreeHost* host = layer->layer_tree_host(); @@ -315,15 +312,12 @@ class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest { public: void BeginTest() override { PostSetNeedsCommitToMainThread(); - EXPECT_EQ(0, main_frame_scheduled_count_); EXPECT_EQ(0, main_frame_run_count_); } - void DidScheduleBeginMainFrame() override { main_frame_scheduled_count_++; } void DidRunBeginMainFrame() override { main_frame_run_count_++; } void DidBeginMainFrame() override { - EXPECT_EQ(1, main_frame_scheduled_count_); EXPECT_EQ(1, main_frame_run_count_); EndTest(); } @@ -331,7 +325,6 @@ class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest { void AfterTest() override {} private: - int main_frame_scheduled_count_ = 0; int main_frame_run_count_ = 0; }; @@ -7391,30 +7384,6 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { // thread. MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); -class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy - : public LayerTreeHostTestCrispUpAfterPinchEnds { - protected: - std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<viz::ContextProvider> compositor_context_provider) - override { - scoped_refptr<viz::TestContextProvider> display_context_provider = - viz::TestContextProvider::Create(); - viz::TestGLES2Interface* gl = - display_context_provider->UnboundTestContextGL(); - gl->set_support_sync_query(true); -#if BUILDFLAG(IS_MAC) - gl->set_support_texture_rectangle(true); -#endif - display_context_provider->BindToCurrentThread(); - return LayerTreeTest::CreateDisplayOutputSurfaceOnThread( - std::move(display_context_provider)); - } -}; - -// This test does pinching on the impl side which is not supported in single -// thread. -MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy); - class RasterizeWithGpuRasterizationCreatesResources : public LayerTreeHostTest { protected: void SetUpUnboundContextProviders( @@ -8534,7 +8503,7 @@ class LayerTreeHostTestDiscardAckAfterRelease : public LayerTreeHostTest { // LayerTreeFrameSink was not released. We must receive the ack. EXPECT_TRUE(received_ack_); // Cause damage so that we draw and swap. - layer_tree_host()->root_layer()->SetBackgroundColor(SK_ColorGREEN); + layer_tree_host()->root_layer()->SetBackgroundColor(SkColors::kGreen); break; case 2: // LayerTreeFrameSink was released. The ack must be discarded. @@ -8782,74 +8751,6 @@ class LayerTreeHostTestImageDecodingHints : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestImageDecodingHints); -class LayerTreeHostTestCheckerboardUkm : public LayerTreeHostTest { - public: - LayerTreeHostTestCheckerboardUkm() : url_(GURL("https://example.com")), - ukm_source_id_(123) {} - void BeginTest() override { - PostSetNeedsCommitToMainThread(); - layer_tree_host()->SetSourceURL(ukm_source_id_, url_); - } - - void SetupTree() override { - gfx::Size layer_size(100, 100); - content_layer_client_.set_bounds(layer_size); - content_layer_client_.set_fill_with_nonsolid_color(true); - layer_tree_host()->SetRootLayer( - FakePictureLayer::Create(&content_layer_client_)); - layer_tree_host()->root_layer()->SetBounds(layer_size); - LayerTreeTest::SetupTree(); - } - - void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - if (impl->active_tree()->source_frame_number() != 0) - return; - - // We have an active tree. Start a pinch gesture so we start recording - // stats. - impl->GetInputHandler().PinchGestureBegin( - gfx::Point(100, 100), ui::ScrollInputType::kTouchscreen); - } - - void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - if (!impl->GetInputHandler().pinch_gesture_active()) - return; - - // We just drew a frame, stats for it should have been recorded. End the - // gesture so they are flushed to the recorder. - impl->GetInputHandler().PinchGestureEnd(gfx::Point(50, 50)); - - // RenewTreePriority will run when the smoothness expiration timer fires. - // Synthetically do it here so the UkmManager is notified. - impl->RenewTreePriorityForTesting(); - - auto* recorder = static_cast<ukm::TestUkmRecorder*>( - impl->ukm_manager()->recorder_for_testing()); - // Tie the source id to the URL. In production, this is already done in - // Document, and the source id is passed down to cc. - recorder->UpdateSourceURL(ukm_source_id_, url_); - - const auto& entries = recorder->GetEntriesByName(kUserInteraction); - EXPECT_EQ(1u, entries.size()); - for (const auto* entry : entries) { - recorder->ExpectEntrySourceHasUrl(entry, url_); - recorder->ExpectEntryMetric(entry, kCheckerboardArea, 0); - recorder->ExpectEntryMetric(entry, kMissingTiles, 0); - recorder->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 0); - } - - EndTest(); - } - - private: - const GURL url_; - const ukm::SourceId ukm_source_id_; - FakeContentLayerClient content_layer_client_; -}; - -// Only multi-thread mode needs to record UKMs. -MULTI_THREAD_TEST_F(LayerTreeHostTestCheckerboardUkm); - class DontUpdateLayersWithEmptyBounds : public LayerTreeTest { protected: void SetupTree() override { @@ -10122,7 +10023,7 @@ class LayerTreeHostTestOccludedTileReleased void AddLayerThatObscuresPictureLayer() { auto covering_layer = SolidColorLayer::Create(); covering_layer->SetBounds(gfx::Size(100, 100)); - covering_layer->SetBackgroundColor(SK_ColorRED); + covering_layer->SetBackgroundColor(SkColors::kRed); covering_layer->SetIsDrawable(true); layer_tree_host()->root_layer()->AddChild(covering_layer); added_obscuring_layer_ = true; @@ -10146,5 +10047,292 @@ class LayerTreeHostTestNoCommitDeadlock : public LayerTreeHostTest { }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoCommitDeadlock); + +// In real site, problem happened like this +// 1. commit +// 2. tiling is delayed, so NotifyReadyToActivate is not triggered +// 3. Draw is called and NotifyReadyToActivate is triggered +// during PrepareDraw() by TileManager's CheckForCompletedTask(). +// 4. pending_tree()::UpdateDrawProperties() is called after PrepareDraw(), +// and tiling is recreated if transform is changed +// 5. Activation happen right after the Draw +// So tiling with empty tiles will be activated to active tree. +class LayerTreeHostTestDelayRecreateTiling + : public LayerTreeHostTestWithHelper { + public: + LayerTreeHostTestDelayRecreateTiling() {} + + void SetupTree() override { + client_.set_fill_with_nonsolid_color(true); + scoped_refptr<FakePictureLayer> root_layer = + FakePictureLayer::Create(&client_); + root_layer->SetBounds(gfx::Size(150, 150)); + root_layer->SetIsDrawable(true); + + layer_on_main_ = + CreateAndAddFakePictureLayer(gfx::Size(30, 30), root_layer.get()); + + // initial transform to force transform node + gfx::Transform transform; + transform.Scale(2.0f, 1.0f); + layer_on_main_->SetTransform(transform); + + layer_tree_host()->SetRootLayer(root_layer); + + LayerTreeHostTest::SetupTree(); + client_.set_bounds(root_layer->bounds()); + + layer_id_ = layer_on_main_->id(); + } + + void WillCommit(const CommitState&) override { + TransformTree& transform_tree = + layer_tree_host()->property_trees()->transform_tree_mutable(); + TransformNode* node = + transform_tree.Node(layer_on_main_->transform_tree_index()); + + gfx::Transform transform; + transform.Scale(2.0f, 1.0f); + transform.Translate(0.0f, 0.8f); + + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // in frame1, translation changed and animation start + transform_tree.OnTransformAnimated(layer_on_main_->element_id(), + transform); + node->has_potential_animation = true; + break; + } + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( + host_impl->pending_tree()->LayerById(layer_id_)); + + TransformTree& transform_tree = + host_impl->pending_tree()->property_trees()->transform_tree_mutable(); + TransformNode* node = + transform_tree.Node(layer_impl->transform_tree_index()); + + if (host_impl->pending_tree()->source_frame_number() == 2) { + // delay Activation for this pending tree + host_impl->BlockNotifyReadyToActivateForTesting(true); + + // to reproduce problem, conditions to recreate tiling should be changed + // after commitcomplete + // e.g., transform change, animation status change + // commitcomplete -> beginimpl -> draw (pending's updatedrawproperties) + // in beginimpl, scroll can be handled, so transform can be changed + // in draw, UpdateAnimationState can change animation status + node->has_potential_animation = false; + transform_tree.set_needs_update(true); + host_impl->pending_tree()->set_needs_update_draw_properties(); + + // to make sure Draw happen + host_impl->SetNeedsRedraw(); + } + } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + if (host_impl->pending_tree() && + host_impl->pending_tree()->source_frame_number() == 2) { + host_impl->BlockNotifyReadyToActivateForTesting(false, false); + // BlockNotifyReadyToActivateForTesting(false) call NotifyReadyToActivate, + // but NotifyReadyToActivate should be called directly instead of PostTask + // because it should called inside PrepareToDraw() + host_impl->NotifyReadyToActivate(); + } + return draw_result; + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->LayerById(layer_id_)); + + gfx::AxisTransform2d tiling_transform = + layer_impl->HighResTiling()->raster_transform(); + + switch (host_impl->active_tree()->source_frame_number()) { + case 0: + PostSetNeedsCommitToMainThread(); + break; + case 1: + PostSetNeedsCommitToMainThread(); + break; + case 2: + if (should_delay_recreating_tiling_) { + // translation is changed in frame2, but recreating tiling should not + // happen because ReadyToActivate is true + ASSERT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f)); + ASSERT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0)); + should_delay_recreating_tiling_ = false; + } else { + // Invalidating implside will trigger recreating tiling without next + // commit + ASSERT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f)); + ASSERT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0.8f)); + EndTest(); + } + break; + case 3: + NOTREACHED() << "We shouldn't see another commit in this test"; + break; + } + } + + protected: + FakeContentLayerClient client_; + // to access layer information in main and impl + int layer_id_; + // to access layer information in main's WillCommit() + scoped_refptr<FakePictureLayer> layer_on_main_; + bool should_delay_recreating_tiling_ = true; +}; +MULTI_THREAD_TEST_F(LayerTreeHostTestDelayRecreateTiling); + +// This test validate that recreating tiling is delayed by veto conditions and +// the delayed tiling is created again when the veto conditions are reset. +class LayerTreeHostTestInvalidateImplSideForRerasterTiling + : public LayerTreeHostTestWithHelper { + public: + void SetupTree() override { + client_.set_fill_with_nonsolid_color(true); + scoped_refptr<FakePictureLayer> root_layer = + FakePictureLayer::Create(&client_); + root_layer->SetBounds(gfx::Size(150, 150)); + root_layer->SetIsDrawable(true); + + layer_on_main_ = + CreateAndAddFakePictureLayer(gfx::Size(30, 30), root_layer.get()); + + // initial transform to force transform node + gfx::Transform transform; + transform.Scale(2.0f, 1.0f); + layer_on_main_->SetTransform(transform); + + layer_tree_host()->SetRootLayer(root_layer); + + LayerTreeHostTest::SetupTree(); + client_.set_bounds(root_layer->bounds()); + + layer_id_ = layer_on_main_->id(); + } + + void WillCommit(const CommitState&) override { + TransformTree& transform_tree = + layer_tree_host()->property_trees()->transform_tree_mutable(); + TransformNode* node = + transform_tree.Node(layer_on_main_->transform_tree_index()); + + gfx::Transform transform; + transform.Scale(2.0f, 1.0f); + transform.Translate(0.0f, 0.8f); + + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // in frame1, translation changed and animation start + transform_tree.OnTransformAnimated(layer_on_main_->element_id(), + transform); + node->has_potential_animation = true; + break; + } + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void ClearAnimationForLayer(LayerTreeImpl* tree_impl, + FakePictureLayerImpl* layer_impl) { + if (!tree_impl) + return; + + TransformTree& transform_tree = + tree_impl->property_trees()->transform_tree_mutable(); + TransformNode* node = + transform_tree.Node(layer_impl->transform_tree_index()); + + node->has_potential_animation = false; + transform_tree.set_needs_update(true); + tree_impl->set_needs_update_draw_properties(); + } + + TransformNode* TransformNodeForLayer(LayerTreeImpl* tree_impl, + FakePictureLayerImpl* layer_impl) { + TransformTree& transform_tree = + tree_impl->property_trees()->transform_tree_mutable(); + TransformNode* node = + transform_tree.Node(layer_impl->transform_tree_index()); + return node; + } + + void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { + if (host_impl->active_tree()->source_frame_number() == 2) { + FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->LayerById(layer_id_)); + gfx::AxisTransform2d tiling_transform = + target_layer->HighResTiling()->raster_transform(); + TransformNode* node = + TransformNodeForLayer(host_impl->active_tree(), target_layer); + if (node->has_potential_animation) { + // in frame 2, active tree still have old tiling because animation is + // still active. + EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f)); + EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0)); + + // now clear animation and trigger a new draw to check if invalidation + // implside will be requested for rerastering tiling. + ClearAnimationForLayer(host_impl->active_tree(), target_layer); + ClearAnimationForLayer(host_impl->recycle_tree(), target_layer); + host_impl->SetNeedsRedraw(); + } + } + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + FakePictureLayerImpl* target_layer = static_cast<FakePictureLayerImpl*>( + host_impl->active_tree()->LayerById(layer_id_)); + gfx::AxisTransform2d tiling_transform = + target_layer->HighResTiling()->raster_transform(); + TransformNode* node = + TransformNodeForLayer(host_impl->active_tree(), target_layer); + switch (host_impl->active_tree()->source_frame_number()) { + case 0: + PostSetNeedsCommitToMainThread(); + break; + case 1: + PostSetNeedsCommitToMainThread(); + break; + case 2: + if (node->has_potential_animation) { + // translation is changed in frame2, but recreating tiling should not + // happen because animation is still active. + EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f)); + EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0)); + + // trigger draw to check if invalidating implside is not triggered + // if animation is still active. + host_impl->SetNeedsRedraw(); + } else { + // check if invalidation implside was requested successfully. + // new tiling should be created. + EXPECT_EQ(tiling_transform.scale(), gfx::Vector2dF(2.0f, 1.0f)); + EXPECT_EQ(tiling_transform.translation(), gfx::Vector2dF(0, 0.8f)); + EndTest(); + } + break; + } + } + + protected: + FakeContentLayerClient client_; + // to access layer information in main and impl + int layer_id_; + // to access layer information in main's WillCommit() + scoped_refptr<FakePictureLayer> layer_on_main_; +}; +MULTI_THREAD_TEST_F(LayerTreeHostTestInvalidateImplSideForRerasterTiling); } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index 0a61548c68a..8dd6266cc57 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -60,6 +60,14 @@ class LayerTreeHostAnimationTest : public LayerTreeTest { timeline_->AttachAnimation(animation_child_.get()); } + void DetachAnimationsFromTimeline() { + if (animation_) + timeline_->DetachAnimation(animation_.get()); + if (animation_child_) + timeline_->DetachAnimation(animation_child_.get()); + animation_host()->RemoveAnimationTimeline(timeline_.get()); + } + void GetImplTimelineAndAnimationByID(const LayerTreeHostImpl& host_impl) { AnimationHost* animation_host_impl = GetImplAnimationHost(&host_impl); timeline_impl_ = animation_host_impl->GetTimelineById(timeline_id_); @@ -71,6 +79,14 @@ class LayerTreeHostAnimationTest : public LayerTreeTest { EXPECT_TRUE(animation_child_impl_); } + void CleanupBeforeDestroy() override { + // This needs to happen on the main thread (so can't happen in + // EndTest()), and needs to happen before DestroyLayerTreeHost() + // (which will trigger assertions if we don't do this), so it can't + // happen in AfterTest(). + DetachAnimationsFromTimeline(); + } + AnimationHost* GetImplAnimationHost( const LayerTreeHostImpl* host_impl) const { return static_cast<AnimationHost*>(host_impl->mutator_host()); @@ -902,10 +918,8 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted scroll_layer_element_id_ = scroll_layer_->element_id(); } - KeyframeEffect& ScrollOffsetKeyframeEffect( - const LayerTreeHostImpl& host_impl, - scoped_refptr<FakePictureLayer> layer, - ElementId element_id) const { + KeyframeEffect& ScrollOffsetKeyframeEffect(const LayerTreeHostImpl& host_impl, + ElementId element_id) const { scoped_refptr<ElementAnimations> element_animations = GetImplAnimationHost(&host_impl) ->GetElementAnimationsForElementId(element_id); @@ -941,8 +955,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted // This happens after the impl-only animation is added in // WillCommitCompleteOnThread. gfx::KeyframeModel* keyframe_model = - ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_, - scroll_layer_element_id_) + ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_element_id_) .GetKeyframeModel(TargetProperty::SCROLL_OFFSET); DCHECK(keyframe_model); const ScrollOffsetAnimationCurve* curve = @@ -969,8 +982,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->sync_tree()->source_frame_number() == 2) { gfx::KeyframeModel* keyframe_model = - ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_, - scroll_layer_element_id_) + ScrollOffsetKeyframeEffect(*host_impl, scroll_layer_element_id_) .GetKeyframeModel(TargetProperty::SCROLL_OFFSET); DCHECK(keyframe_model); const ScrollOffsetAnimationCurve* curve = diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index 6c47500d499..838e0a4b151 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -15,8 +15,6 @@ namespace cc { namespace { -const char kRenderingEvent[] = "Compositor.Rendering"; -const char kCheckerboardImagesMetric[] = "CheckerboardedImagesCount"; class LayerTreeHostCheckerImagingTest : public LayerTreeTest { public: @@ -29,26 +27,6 @@ class LayerTreeHostCheckerImagingTest : public LayerTreeTest { PostSetNeedsCommitToMainThread(); } - void VerifyUkmAndEndTest(LayerTreeHostImpl* impl) { - auto* recorder = static_cast<ukm::TestUkmRecorder*>( - impl->ukm_manager()->recorder_for_testing()); - // Tie the source id to the URL. In production, this is already done in - // Document, and the source id is passed down to cc. - recorder->UpdateSourceURL(ukm_source_id_, url_); - - // Change the source to ensure any accumulated metrics are flushed. - ukm::SourceId newSourceId = ukm::AssignNewSourceId(); - impl->ukm_manager()->SetSourceId(newSourceId); - recorder->UpdateSourceURL(newSourceId, GURL("chrome://test2")); - - const auto& entries = recorder->GetEntriesByName(kRenderingEvent); - ASSERT_EQ(1u, entries.size()); - auto* entry = entries[0]; - recorder->ExpectEntrySourceHasUrl(entry, url_); - recorder->ExpectEntryMetric(entry, kCheckerboardImagesMetric, 1); - EndTest(); - } - void InitializeSettings(LayerTreeSettings* settings) override { settings->enable_checker_imaging = true; settings->min_image_bytes_to_checker = 512 * 1024; @@ -154,7 +132,7 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame expected_update_rect.Union(gfx::Rect(600, 0, 50, 500)); EXPECT_EQ(sync_layer_impl->update_rect(), expected_update_rect); - VerifyUkmAndEndTest(host_impl); + EndTest(); } break; default: NOTREACHED(); @@ -219,7 +197,7 @@ class LayerTreeHostCheckerImagingTestImplSideTree void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { num_of_activations_++; if (num_of_activations_ == 2) { - VerifyUkmAndEndTest(host_impl); + EndTest(); } } diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index ce695f67d4a..992af86c6d0 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -204,26 +204,12 @@ class LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder return nullptr; } - std::unique_ptr<viz::SkiaOutputSurface> - CreateDisplaySkiaOutputSurfaceOnThread( + std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread( viz::DisplayCompositorMemoryAndTaskController*) override { auto skia_output_surface = viz::FakeSkiaOutputSurface::Create3d(); skia_output_surface->SetOutOfOrderCallbacks(true); return skia_output_surface; } - - std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<viz::ContextProvider> compositor_context_provider) - override { - // Since this test does not override CreateLayerTreeFrameSink, the - // |compositor_context_provider| will be a viz::TestContextProvider. - auto* context_support = static_cast<viz::TestContextSupport*>( - compositor_context_provider->ContextSupport()); - context_support->set_out_of_order_callbacks(true); - - return viz::FakeOutputSurface::Create3d( - std::move(compositor_context_provider)); - } }; INSTANTIATE_TEST_SUITE_P( @@ -888,25 +874,13 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage // and there is no overlay support. return nullptr; } - std::unique_ptr<viz::SkiaOutputSurface> - CreateDisplaySkiaOutputSurfaceOnThread( + std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread( viz::DisplayCompositorMemoryAndTaskController*) override { display_context_provider_ = viz::TestContextProvider::Create(); display_context_provider_->BindToCurrentThread(); return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_); } - std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<viz::ContextProvider> compositor_context_provider) - override { - // Since this test does not override CreateLayerTreeFrameSink, the - // |compositor_context_provider| will be a viz::TestContextProvider. - display_context_provider_ = static_cast<viz::TestContextProvider*>( - compositor_context_provider.get()); - return viz::FakeOutputSurface::Create3d( - std::move(compositor_context_provider)); - } - void SetupTree() override { root_ = FakePictureLayer::Create(&client_); root_->SetBounds(gfx::Size(20, 20)); @@ -1045,25 +1019,13 @@ class LayerTreeHostCopyRequestTestCountSharedImages // and there is no overlay support. return nullptr; } - std::unique_ptr<viz::SkiaOutputSurface> - CreateDisplaySkiaOutputSurfaceOnThread( + std::unique_ptr<viz::SkiaOutputSurface> CreateSkiaOutputSurfaceOnThread( viz::DisplayCompositorMemoryAndTaskController*) override { display_context_provider_ = viz::TestContextProvider::Create(); display_context_provider_->BindToCurrentThread(); return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_); } - std::unique_ptr<viz::OutputSurface> CreateDisplayOutputSurfaceOnThread( - scoped_refptr<viz::ContextProvider> compositor_context_provider) - override { - // Since this test does not override CreateLayerTreeFrameSink, the - // |compositor_context_provider| will be a viz::TestContextProvider. - display_context_provider_ = static_cast<viz::TestContextProvider*>( - compositor_context_provider.get()); - return viz::FakeOutputSurface::Create3d( - std::move(compositor_context_provider)); - } - void SetupTree() override { // The layers in this test have solid color content, so they don't // actually allocate any textures, making counting easier. diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 92c066cc2e7..364df3eb933 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -387,7 +387,7 @@ class LayerTreeHostProxyTestCommitWaitsForActivationMFBA // case above). We unblock activate to allow this main frame to commit. auto unblock = base::BindOnce( &LayerTreeHostImpl::BlockNotifyReadyToActivateForTesting, - base::Unretained(impl), false); + base::Unretained(impl), false, true); // Post the unblock instead of doing it immediately so that the main // frame is fully processed by the compositor thread, and it has a full // opportunity to wrongly unblock the main thread. diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index bb4c9a09d73..13788d94cba 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -166,7 +166,6 @@ LayerTreeImpl::LayerTreeImpl( needs_full_tree_sync_(true), needs_surface_ranges_sync_(false), next_activation_forces_redraw_(false), - has_ever_been_drawn_(false), handle_visibility_changed_(false), have_scroll_event_handlers_(false), event_listener_properties_(), @@ -735,8 +734,6 @@ void LayerTreeImpl::PullLayerTreePropertiesFrom(CommitState& commit_state) { if (commit_state.force_send_metadata_request) RequestForceSendMetadata(); - set_has_ever_been_drawn(false); - // TODO(ericrk): The viewport changes caused by |top_controls_shown_ratio_| // changes should propagate back to the main tree. This does not currently // happen, so we must force the impl tree to update its viewports if @@ -755,6 +752,10 @@ void LayerTreeImpl::PullLayerTreePropertiesFrom(CommitState& commit_state) { // Transfer page transition directives. for (auto& request : commit_state.document_transition_requests) AddDocumentTransitionRequest(std::move(request)); + + SetVisualUpdateDurations( + commit_state.previous_surfaces_visual_update_duration, + commit_state.visual_update_duration); } void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) { @@ -844,6 +845,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { // This should match the property synchronization in // LayerTreeHost::finishCommitOnImplThread(). target_tree->set_source_frame_number(source_frame_number()); + target_tree->set_trace_id(trace_id()); target_tree->set_background_color(background_color()); target_tree->set_have_scroll_event_handlers(have_scroll_event_handlers()); target_tree->set_event_listener_properties( @@ -862,8 +864,6 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { else target_tree->set_hud_layer(nullptr); - target_tree->has_ever_been_drawn_ = false; - // Note: this needs to happen after SetPropertyTrees. target_tree->HandleTickmarksVisibilityChange(); target_tree->HandleScrollbarShowRequests(); @@ -881,6 +881,9 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { for (auto& request : TakeDocumentTransitionRequests()) target_tree->AddDocumentTransitionRequest(std::move(request)); + + target_tree->SetVisualUpdateDurations( + previous_surfaces_visual_update_duration_, visual_update_duration_); } void LayerTreeImpl::HandleTickmarksVisibilityChange() { @@ -1153,23 +1156,45 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id, int transform_node_index) { // This includes all animations, even those that are finished but // haven't yet been deleted. - if (mutator_host()->HasAnyAnimationTargetingProperty( - element_id, TargetProperty::TRANSFORM)) { - TransformTree& transform_tree = property_trees()->transform_tree_mutable(); - if (TransformNode* node = transform_tree.Node(transform_node_index)) { - ElementListType list_type = GetElementTypeForAnimation(); - bool has_potential_animation = - mutator_host()->HasPotentiallyRunningTransformAnimation(element_id, - list_type); - if (node->has_potential_animation != has_potential_animation) { - node->has_potential_animation = has_potential_animation; - node->maximum_animation_scale = - mutator_host()->MaximumScale(element_id, list_type); - transform_tree.set_needs_update(true); - set_needs_update_draw_properties(); + + // A given ElementId should be associated with only a single transform + // property. However, the ElementId is opaque to cc. (If it comes from + // blink, it was constructed with a CompositorElementIdNamespace specific to + // the correct property. Otherwise, only the transform property should be + // used.) + const TargetProperty::Type transform_properties[] = { + TargetProperty::TRANSFORM, TargetProperty::SCALE, TargetProperty::ROTATE, + TargetProperty::TRANSLATE}; +#if DCHECK_IS_ON() + unsigned property_count = 0u; +#endif + + for (TargetProperty::Type property : transform_properties) { + if (mutator_host()->HasAnyAnimationTargetingProperty(element_id, + property)) { +#if DCHECK_IS_ON() + ++property_count; +#endif + TransformTree& transform_tree = + property_trees()->transform_tree_mutable(); + if (TransformNode* node = transform_tree.Node(transform_node_index)) { + ElementListType list_type = GetElementTypeForAnimation(); + bool has_potential_animation = + mutator_host()->HasPotentiallyRunningAnimationForProperty( + element_id, list_type, property); + if (node->has_potential_animation != has_potential_animation) { + node->has_potential_animation = has_potential_animation; + node->maximum_animation_scale = + mutator_host()->MaximumScale(element_id, list_type); + transform_tree.set_needs_update(true); + set_needs_update_draw_properties(); + } } } } +#if DCHECK_IS_ON() + DCHECK_LE(property_count, 1u); +#endif } void LayerTreeImpl::UpdatePageScaleNode() { @@ -1187,7 +1212,7 @@ void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) { float clamped_page_scale = ClampPageScaleFactorToLimits(active_page_scale); // Temporary crash logging for https://crbug.com/845097. static bool has_dumped_without_crashing = false; - if (host_impl_->settings().is_layer_tree_for_subframe && + if (!host_impl_->settings().is_for_scalable_page && clamped_page_scale != 1.f && !has_dumped_without_crashing) { has_dumped_without_crashing = true; static auto* psf_oopif_error = base::debug::AllocateCrashKeyString( @@ -1196,10 +1221,8 @@ void LayerTreeImpl::SetPageScaleOnActiveTree(float active_page_scale) { psf_oopif_error, base::StringPrintf("%f", clamped_page_scale)); base::debug::DumpWithoutCrashing(); } - if (page_scale_factor()->SetCurrent(clamped_page_scale)) { + if (page_scale_factor()->SetCurrent(clamped_page_scale)) DidUpdatePageScale(); - UpdatePageScaleNode(); - } } void LayerTreeImpl::PushPageScaleFromMainThread(float page_scale_factor, @@ -1230,10 +1253,6 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor, if (changed_page_scale) DidUpdatePageScale(); - - DCHECK(lifecycle().AllowsPropertyTreeAccess()); - if (page_scale_factor) - UpdatePageScaleNode(); } void LayerTreeImpl::SetBrowserControlsParams( @@ -1338,27 +1357,33 @@ bool LayerTreeImpl::SetPageScaleFactorLimits(float min_page_scale_factor, } void LayerTreeImpl::DidUpdatePageScale() { - if (IsActiveTree()) + if (IsActiveTree()) { page_scale_factor()->SetCurrent( ClampPageScaleFactorToLimits(current_page_scale_factor())); - set_needs_update_draw_properties(); - - // Viewport scrollbar sizes depend on the page scale factor. - SetScrollbarGeometriesNeedUpdate(); + // Ensure the other trees are kept in sync. + if (host_impl_->pending_tree()) + host_impl_->pending_tree()->DidUpdatePageScale(); + if (host_impl_->recycle_tree()) + host_impl_->recycle_tree()->DidUpdatePageScale(); - if (IsActiveTree()) { if (settings().scrollbar_flash_after_any_scroll_update) { host_impl_->FlashAllScrollbars(true); - return; - } - if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) { + } else if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) { if (ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( scroll_node->element_id)) controller->DidScrollUpdate(); } } + + DCHECK(lifecycle().AllowsPropertyTreeAccess()); + UpdatePageScaleNode(); + + set_needs_update_draw_properties(); + + // Viewport scrollbar sizes depend on the page scale factor. + SetScrollbarGeometriesNeedUpdate(); } void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) { @@ -1564,11 +1589,14 @@ bool LayerTreeImpl::UpdateDrawProperties( this, &render_surface_list_, output_update_layer_list_for_testing); if (const char* client_name = GetClientNameForMetrics()) { - UMA_HISTOGRAM_COUNTS_1M( - base::StringPrintf( - "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs", - client_name), - timer.Elapsed().InMicroseconds()); + // This metric is only recorded for the Browser. + if (settings().single_thread_proxy_scheduler) { + UMA_HISTOGRAM_COUNTS_1M( + base::StringPrintf( + "Compositing.%s.LayerTreeImpl.CalculateDrawPropertiesUs", + client_name), + timer.Elapsed().InMicroseconds()); + } UMA_HISTOGRAM_COUNTS_100( base::StringPrintf("Compositing.%s.NumRenderSurfaces", client_name), base::saturated_cast<int>(render_surface_list_.size())); @@ -1854,6 +1882,10 @@ bool LayerTreeImpl::IsSyncTree() const { return host_impl_->sync_tree() == this; } +bool LayerTreeImpl::HasPendingTree() const { + return host_impl_->pending_tree() != nullptr; +} + LayerImpl* LayerTreeImpl::FindActiveTreeLayerById(int id) { LayerTreeImpl* tree = host_impl_->active_tree(); if (!tree) @@ -2154,6 +2186,11 @@ void LayerTreeImpl::RegisterScrollbar(ScrollbarLayerImplBase* scrollbar_layer) { *scrollbar_layer_id = scrollbar_layer->id(); + if (IsActiveTree()) { + host_impl_->DidRegisterScrollbarLayer(scroll_element_id, + scrollbar_layer->orientation()); + } + if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() && scrollbar_layer->GetScrollbarAnimator() != LayerTreeSettings::NO_ANIMATOR) { @@ -2895,4 +2932,25 @@ bool LayerTreeImpl::HasDocumentTransitionRequests() const { return !document_transition_requests_.empty(); } +bool LayerTreeImpl::IsReadyToActivate() const { + return host_impl_->IsReadyToActivate(); +} + +void LayerTreeImpl::ClearVisualUpdateDurations() { + previous_surfaces_visual_update_duration_ = base::TimeDelta(); + visual_update_duration_ = base::TimeDelta(); +} + +void LayerTreeImpl::SetVisualUpdateDurations( + base::TimeDelta previous_surfaces_visual_update_duration, + base::TimeDelta visual_update_duration) { + previous_surfaces_visual_update_duration_ = + previous_surfaces_visual_update_duration; + visual_update_duration_ = visual_update_duration; +} + +void LayerTreeImpl::RequestImplSideInvalidationForRerasterTiling() { + host_impl_->RequestImplSideInvalidationForRerasterTiling(); +} + } // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index fd335404e21..172bcc07769 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -139,6 +139,7 @@ class CC_EXPORT LayerTreeImpl { bool IsPendingTree() const; bool IsRecycleTree() const; bool IsSyncTree() const; + bool HasPendingTree() const; LayerImpl* FindActiveTreeLayerById(int id); LayerImpl* FindPendingTreeLayerById(int id); // TODO(bokan): PinchGestureActive is a layering violation, it's not related @@ -165,6 +166,8 @@ class CC_EXPORT LayerTreeImpl { const scoped_refptr<DisplayItemList>& display_list); TargetColorParams GetTargetColorParams( gfx::ContentColorUsage content_color_usage) const; + bool IsReadyToActivate() const; + void RequestImplSideInvalidationForRerasterTiling(); // Tree specific methods exposed to layer-impl tree. // --------------------------------------------------------------------------- @@ -221,9 +224,14 @@ class CC_EXPORT LayerTreeImpl { // Adapts an iterator of std::unique_ptr<LayerImpl> to an iterator of // LayerImpl*. template <typename Iterator> - class IteratorAdapter - : public std::iterator<std::forward_iterator_tag, LayerImpl*> { + class IteratorAdapter { public: + using iterator_category = std::forward_iterator_tag; + using value_type = LayerImpl*; + using difference_type = std::ptrdiff_t; + using pointer = LayerImpl**; + using reference = LayerImpl*&; + explicit IteratorAdapter(Iterator it) : it_(it) {} bool operator==(IteratorAdapter o) const { return it_ == o.it_; } bool operator!=(IteratorAdapter o) const { return !(*this == o); } @@ -278,6 +286,9 @@ class CC_EXPORT LayerTreeImpl { source_frame_number_ = frame_number; } + uint64_t trace_id() const { return trace_id_; } + void set_trace_id(uint64_t val) { trace_id_ = val; } + bool is_first_frame_after_commit() const { return source_frame_number_ != is_first_frame_after_commit_tracker_; } @@ -432,13 +443,17 @@ class CC_EXPORT LayerTreeImpl { float page_scale_factor_for_scroll() const { DCHECK(external_page_scale_factor_ == 1.f || current_page_scale_factor() == 1.f || - !settings().is_layer_tree_for_subframe); + settings().is_for_scalable_page); return external_page_scale_factor_ * current_page_scale_factor(); } const gfx::DisplayColorSpaces& display_color_spaces() const { return display_color_spaces_; } + const ViewportPropertyIds& viewport_property_ids() const { + return viewport_property_ids_; + } + SyncedElasticOverscroll* elastic_overscroll() { return elastic_overscroll_.get(); } @@ -492,11 +507,6 @@ class CC_EXPORT LayerTreeImpl { void ForceRedrawNextActivation() { next_activation_forces_redraw_ = true; } - void set_has_ever_been_drawn(bool has_drawn) { - has_ever_been_drawn_ = has_drawn; - } - bool has_ever_been_drawn() const { return has_ever_been_drawn_; } - void set_ui_resource_request_queue(UIResourceRequestQueue queue); const RenderSurfaceList& GetRenderSurfaceList() const; @@ -783,6 +793,17 @@ class CC_EXPORT LayerTreeImpl { bool HasDocumentTransitionRequests() const; + void ClearVisualUpdateDurations(); + void SetVisualUpdateDurations( + base::TimeDelta previous_surfaces_visual_update_duration, + base::TimeDelta visual_update_duration); + base::TimeDelta previous_surfaces_visual_update_duration() const { + return previous_surfaces_visual_update_duration_; + } + base::TimeDelta visual_update_duration() const { + return visual_update_duration_; + } + protected: float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, @@ -810,6 +831,7 @@ class CC_EXPORT LayerTreeImpl { raw_ptr<LayerTreeHostImpl> host_impl_; int source_frame_number_; + uint64_t trace_id_ = 0; int is_first_frame_after_commit_tracker_; raw_ptr<HeadsUpDisplayLayerImpl> hud_layer_; PropertyTrees property_trees_; @@ -896,8 +918,6 @@ class CC_EXPORT LayerTreeImpl { bool next_activation_forces_redraw_; - bool has_ever_been_drawn_; - bool handle_visibility_changed_; std::vector<std::unique_ptr<SwapPromise>> swap_promise_list_; @@ -942,6 +962,13 @@ class CC_EXPORT LayerTreeImpl { // Document transition requests to be transferred to Viz. std::vector<std::unique_ptr<DocumentTransitionRequest>> document_transition_requests_; + + // The cumulative time spent performing visual updates for all Surfaces before + // this one. + base::TimeDelta previous_surfaces_visual_update_duration_; + // The cumulative time spent performing visual updates for the current + // Surface. + base::TimeDelta visual_update_duration_; }; } // namespace cc diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h index fa3b501754c..939a54f9115 100644 --- a/chromium/cc/trees/layer_tree_mutator.h +++ b/chromium/cc/trees/layer_tree_mutator.h @@ -5,18 +5,19 @@ #ifndef CC_TREES_LAYER_TREE_MUTATOR_H_ #define CC_TREES_LAYER_TREE_MUTATOR_H_ +#include <memory> +#include <string> +#include <unordered_map> +#include <vector> + #include "base/callback_forward.h" +#include "base/check.h" #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/trees/animation_effect_timings.h" #include "cc/trees/animation_options.h" #include "third_party/abseil-cpp/absl/types/optional.h" -#include <memory> -#include <string> -#include <unordered_map> -#include <vector> - namespace cc { // TOOD(kevers): Remove kDrop once confirmed that it is no longer needed under diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index f6094a5defe..8dfe968b631 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -114,7 +114,11 @@ class CC_EXPORT LayerTreeSettings { // Indicates the case when a sub-frame gets its own LayerTree because it's // rendered in a different process from its ancestor frames. - bool is_layer_tree_for_subframe = false; + bool is_for_embedded_frame = false; + + // Indicates when the LayerTree is for a portal element, GuestView, or top + // level frame. In all these cases we may have a page scale. + bool is_for_scalable_page = true; // Determines whether we disallow non-exact matches when finding resources // in ResourcePool. Only used for layout or pixel tests, as non-deterministic @@ -204,6 +208,10 @@ class CC_EXPORT LayerTreeSettings { // even if the layer is not drawn. For example, if the layer is occluded it is // still considered drawn and will not be impacted by this feature. bool release_tile_resources_for_hidden_layers = false; + + // Whether Fluent scrollbar is enabled. Please check https://crbug.com/1292117 + // to find the link to the Fluent Scrollbar spec and related CLs. + bool enable_fluent_scrollbar = false; }; class CC_EXPORT LayerListSettings : public LayerTreeSettings { diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h index 0c344bb1b9e..819856cde5a 100644 --- a/chromium/cc/trees/mutator_host.h +++ b/chromium/cc/trees/mutator_host.h @@ -82,29 +82,14 @@ class MutatorHost { virtual bool ScrollOffsetAnimationWasInterrupted( ElementId element_id) const = 0; - virtual bool IsAnimatingFilterProperty(ElementId element_id, - ElementListType list_type) const = 0; - virtual bool IsAnimatingBackdropFilterProperty( - ElementId element_id, - ElementListType list_type) const = 0; - virtual bool IsAnimatingOpacityProperty(ElementId element_id, - ElementListType list_type) const = 0; - virtual bool IsAnimatingTransformProperty( - ElementId element_id, - ElementListType list_type) const = 0; + virtual bool IsAnimatingProperty(ElementId element_id, + ElementListType list_type, + TargetProperty::Type property) const = 0; - virtual bool HasPotentiallyRunningFilterAnimation( - ElementId element_id, - ElementListType list_type) const = 0; - virtual bool HasPotentiallyRunningBackdropFilterAnimation( + virtual bool HasPotentiallyRunningAnimationForProperty( ElementId element_id, - ElementListType list_type) const = 0; - virtual bool HasPotentiallyRunningOpacityAnimation( - ElementId element_id, - ElementListType list_type) const = 0; - virtual bool HasPotentiallyRunningTransformAnimation( - ElementId element_id, - ElementListType list_type) const = 0; + ElementListType list_type, + TargetProperty::Type property) const = 0; virtual bool HasAnyAnimationTargetingProperty( ElementId element_id, @@ -156,6 +141,7 @@ class MutatorHost { virtual bool HasCanvasInvalidation() const = 0; virtual bool HasJSAnimation() const = 0; virtual bool HasSmilAnimation() const = 0; + virtual bool HasSharedElementTransition() const = 0; // Iterates through all animations and returns the minimum tick interval. // Returns 0 if there is a continuous animation which should be ticked diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index 5a2ac9990a6..7a3bb079487 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -22,6 +22,7 @@ #include "cc/trees/property_tree.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" +#include "cc/trees/viewport_property_ids.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "ui/gfx/geometry/outsets_f.h" #include "ui/gfx/geometry/point_conversions.h" @@ -57,7 +58,6 @@ PropertyTree<T>& PropertyTree<T>::operator=(const PropertyTree<T>&) = default; TransformTree::TransformTree(PropertyTrees* property_trees) : PropertyTree<TransformNode>(property_trees), page_scale_factor_(1.f), - overscroll_node_id_(kInvalidPropertyNodeId), fixed_elements_dont_overscroll_(false), device_scale_factor_(1.f), device_transform_scale_factor_(1.f) { @@ -128,7 +128,6 @@ void TransformTree::clear() { PropertyTree<TransformNode>::clear(); page_scale_factor_ = 1.f; - overscroll_node_id_ = kInvalidPropertyNodeId; fixed_elements_dont_overscroll_ = false; device_scale_factor_ = 1.f; device_transform_scale_factor_ = 1.f; @@ -174,14 +173,16 @@ void TransformTree::ResetChangeTracking() { } } -void TransformTree::UpdateTransforms(int id) { +void TransformTree::UpdateTransforms( + int id, + const ViewportPropertyIds* viewport_property_ids) { TransformNode* node = Node(id); TransformNode* parent_node = parent(node); DCHECK(parent_node); // TODO(flackr): Only dirty when scroll offset changes. if (node->sticky_position_constraint_id >= 0 || node->needs_local_transform_update || ShouldUndoOverscroll(node)) { - UpdateLocalTransform(node); + UpdateLocalTransform(node, viewport_property_ids); } else { UndoSnapping(node); } @@ -460,12 +461,19 @@ bool TransformTree::ShouldUndoOverscroll(const TransformNode* node) const { void TransformTree::UpdateFixedNodeTransformAndClip( const TransformNode* node, - gfx::Vector2dF& fixed_position_adjustment) { - if (!ShouldUndoOverscroll(node) || - overscroll_node_id_ == kInvalidPropertyNodeId) + gfx::Vector2dF& fixed_position_adjustment, + const ViewportPropertyIds* viewport_property_ids) { + const int transform_id = + viewport_property_ids + ? viewport_property_ids->overscroll_elasticity_transform + : kInvalidPropertyNodeId; + const int clip_id = viewport_property_ids ? viewport_property_ids->outer_clip + : kInvalidPropertyNodeId; + if (!ShouldUndoOverscroll(node) || transform_id == kInvalidPropertyNodeId || + clip_id == kInvalidPropertyNodeId) return; - const TransformNode* overscroll_node = Node(overscroll_node_id_); + const TransformNode* overscroll_node = Node(transform_id); const gfx::Vector2dF overscroll_offset = overscroll_node->scroll_offset.OffsetFromOrigin(); if (overscroll_offset.IsZero()) @@ -475,24 +483,24 @@ void TransformTree::UpdateFixedNodeTransformAndClip( gfx::ScaleVector2d(overscroll_offset, 1.f / page_scale_factor()); ClipTree& clip_tree = property_trees()->clip_tree_mutable(); - ClipNode* clip_node = clip_tree.Node(clip_tree.overscroll_node_id()); - - if (clip_node) { - // Inflate the clip rect based on the overscroll direction. - gfx::OutsetsF outsets; - fixed_position_adjustment.x() < 0 - ? outsets.set_left(-fixed_position_adjustment.x()) - : outsets.set_right(fixed_position_adjustment.x()); - fixed_position_adjustment.y() < 0 - ? outsets.set_top(-fixed_position_adjustment.y()) - : outsets.set_bottom(fixed_position_adjustment.y()); - - clip_node->clip.Outset(outsets); - clip_tree.set_needs_update(true); - } -} - -void TransformTree::UpdateLocalTransform(TransformNode* node) { + ClipNode* clip_node = clip_tree.Node(clip_id); + DCHECK(clip_node); + + // Inflate the clip rect based on the overscroll direction. + gfx::OutsetsF outsets; + fixed_position_adjustment.x() < 0 + ? outsets.set_left(-fixed_position_adjustment.x()) + : outsets.set_right(fixed_position_adjustment.x()); + fixed_position_adjustment.y() < 0 + ? outsets.set_top(-fixed_position_adjustment.y()) + : outsets.set_bottom(fixed_position_adjustment.y()); + clip_node->clip.Outset(outsets); + clip_tree.set_needs_update(true); +} + +void TransformTree::UpdateLocalTransform( + TransformNode* node, + const ViewportPropertyIds* viewport_property_ids) { gfx::Transform transform; transform.Translate3d(node->post_translation.x() + node->origin.x(), node->post_translation.y() + node->origin.y(), @@ -504,7 +512,8 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) { property_trees()->outer_viewport_container_bounds_delta().y()); } - UpdateFixedNodeTransformAndClip(node, fixed_position_adjustment); + UpdateFixedNodeTransformAndClip(node, fixed_position_adjustment, + viewport_property_ids); transform.Translate(fixed_position_adjustment - node->scroll_offset.OffsetFromOrigin()); transform.Translate(StickyPositionOffset(node)); @@ -709,7 +718,6 @@ void TransformTree::SetToScreen(int node_id, const gfx::Transform& transform) { bool TransformTree::operator==(const TransformTree& other) const { return PropertyTree::operator==(other) && page_scale_factor_ == other.page_scale_factor() && - overscroll_node_id_ == other.overscroll_node_id() && fixed_elements_dont_overscroll_ == other.fixed_elements_dont_overscroll() && device_scale_factor_ == other.device_scale_factor() && @@ -1265,8 +1273,7 @@ EffectTree::CopyRequestMap EffectTree::TakeCopyRequests() { } ClipTree::ClipTree(PropertyTrees* property_trees) - : PropertyTree<ClipNode>(property_trees), - overscroll_node_id_(kInvalidPropertyNodeId) {} + : PropertyTree<ClipNode>(property_trees) {} void ClipTree::SetViewportClip(gfx::RectF viewport_rect) { if (size() < 2) @@ -1286,8 +1293,7 @@ gfx::RectF ClipTree::ViewportClip() const { #if DCHECK_IS_ON() bool ClipTree::operator==(const ClipTree& other) const { - return PropertyTree::operator==(other) && - overscroll_node_id_ == other.overscroll_node_id(); + return PropertyTree::operator==(other); } #endif @@ -1964,6 +1970,9 @@ bool PropertyTrees::ElementIsAnimatingChanged( const ElementId element_id = it->second; switch (property) { case TargetProperty::TRANSFORM: + case TargetProperty::SCALE: + case TargetProperty::ROTATE: + case TargetProperty::TRANSLATE: if (TransformNode* transform_node = transform_tree_mutable().FindNodeFromElementId(element_id)) { if (mask.currently_running[property]) diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 12ecb6eb4af..78f52a32cbc 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -53,6 +53,7 @@ class LayerTreeImpl; class RenderSurfaceImpl; struct RenderSurfacePropertyChangedFlags; struct CompositorCommitData; +struct ViewportPropertyIds; using SyncedScrollOffset = SyncedProperty<AdditionGroup<gfx::PointF, gfx::Vector2dF>>; @@ -182,7 +183,9 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { const gfx::Transform& transform); void ResetChangeTracking(); // Updates the parent, target, and screen space transforms and snapping. - void UpdateTransforms(int id); + void UpdateTransforms( + int id, + const ViewportPropertyIds* viewport_property_ids = nullptr); void UpdateTransformChanged(TransformNode* node, TransformNode* parent_node); void UpdateNodeAndAncestorsAreAnimatedOrInvertible( TransformNode* node, @@ -199,8 +202,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { } float page_scale_factor() const { return page_scale_factor_; } - void set_overscroll_node_id(int id) { overscroll_node_id_ = id; } - int overscroll_node_id() const { return overscroll_node_id_; } void set_fixed_elements_dont_overscroll(bool value) { fixed_elements_dont_overscroll_ = value; } @@ -249,7 +250,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { bool ShouldUndoOverscroll(const TransformNode* node) const; void UpdateFixedNodeTransformAndClip( const TransformNode* node, - gfx::Vector2dF& fixed_position_adjustment); + gfx::Vector2dF& fixed_position_adjustment, + const ViewportPropertyIds* viewport_property_ids); const StickyPositionNodeData* GetStickyPositionData(int node_id) const { return const_cast<TransformTree*>(this)->MutableStickyPositionData(node_id); @@ -276,7 +278,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { StickyPositionNodeData* MutableStickyPositionData(int node_id); gfx::Vector2dF StickyPositionOffset(TransformNode* node); - void UpdateLocalTransform(TransformNode* node); + void UpdateLocalTransform(TransformNode* node, + const ViewportPropertyIds* viewport_property_ids); void UpdateScreenSpaceTransform(TransformNode* node, TransformNode* parent_node); void UpdateAnimationProperties(TransformNode* node, @@ -291,7 +294,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { // scale is calculated using page scale factor, device scale factor and the // scale factor of device transform. So we need to store them explicitly. float page_scale_factor_; - int overscroll_node_id_; bool fixed_elements_dont_overscroll_; float device_scale_factor_; float device_transform_scale_factor_; @@ -333,14 +335,6 @@ class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> { void SetViewportClip(gfx::RectF viewport_rect); gfx::RectF ViewportClip() const; - - void set_overscroll_node_id(int id) { overscroll_node_id_ = id; } - int overscroll_node_id() const { return overscroll_node_id_; } - - private: - // Used to track the ClipNode that is corresponding to the overscroll - // TransformNode. - int overscroll_node_id_; }; class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index 20c374bd36d..00eb3a85b00 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -112,14 +112,16 @@ class PropertyTreeBuilderContext { // Methods to query state from the AnimationHost ---------------------- bool OpacityIsAnimating(const MutatorHost& host, Layer* layer) { - return host.IsAnimatingOpacityProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); + return host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::OPACITY); } bool HasPotentiallyRunningOpacityAnimation(const MutatorHost& host, Layer* layer) { - return host.HasPotentiallyRunningOpacityAnimation( - layer->element_id(), layer->GetElementTypeForAnimation()); + return host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::OPACITY); } bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) { @@ -128,25 +130,49 @@ bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) { } bool FilterIsAnimating(const MutatorHost& host, Layer* layer) { - return host.IsAnimatingFilterProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); + return host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::FILTER); } bool HasPotentiallyRunningFilterAnimation(const MutatorHost& host, Layer* layer) { - return host.HasPotentiallyRunningFilterAnimation( - layer->element_id(), layer->GetElementTypeForAnimation()); + return host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::FILTER); } bool TransformIsAnimating(const MutatorHost& host, Layer* layer) { - return host.IsAnimatingTransformProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); + DCHECK(!host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::SCALE) && + !host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::ROTATE) && + !host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::TRANSLATE)) + << "individual transform properties only supported in layer lists mode"; + return host.IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::TRANSFORM); } bool HasPotentiallyRunningTransformAnimation(const MutatorHost& host, Layer* layer) { - return host.HasPotentiallyRunningTransformAnimation( - layer->element_id(), layer->GetElementTypeForAnimation()); + DCHECK(!host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::SCALE) && + !host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::ROTATE) && + !host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::TRANSLATE)) + << "individual transform properties only supported in layer lists mode"; + return host.HasPotentiallyRunningAnimationForProperty( + layer->element_id(), layer->GetElementTypeForAnimation(), + TargetProperty::TRANSFORM); } float MaximumAnimationScale(const MutatorHost& host, Layer* layer) { @@ -236,6 +262,13 @@ bool PropertyTreeBuilderContext::AddTransformNodeIfNeeded( // the Running state right after commit on the compositor thread. const bool has_any_transform_animation = HasAnyAnimationTargetingProperty( mutator_host_, layer, TargetProperty::TRANSFORM); + DCHECK(!HasAnyAnimationTargetingProperty(mutator_host_, layer, + TargetProperty::SCALE) && + !HasAnyAnimationTargetingProperty(mutator_host_, layer, + TargetProperty::ROTATE) && + !HasAnyAnimationTargetingProperty(mutator_host_, layer, + TargetProperty::TRANSLATE)) + << "individual transform properties only supported in layer lists mode"; const bool has_surface = created_render_surface; @@ -683,13 +716,15 @@ void PropertyTreeBuilderContext::AddScrollNodeIfNeeded( void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor, Layer* layer, DataForRecursion* data_for_children) { - SkColor background_color = layer->background_color(); + // TODO(crbug/1308932): Remove toSkColor and make all SkColor4f. + SkColor background_color = layer->background_color().toSkColor(); data_for_children->safe_opaque_background_color = SkColorGetA(background_color) == 255 ? background_color : data_from_ancestor.safe_opaque_background_color; + // TODO(crbug/1308932): Remove FromColor and make all SkColor4f. layer->SetSafeOpaqueBackgroundColor( - data_for_children->safe_opaque_background_color); + SkColor4f::FromColor(data_for_children->safe_opaque_background_color)); } void PropertyTreeBuilderContext::BuildPropertyTreesInternal( diff --git a/chromium/cc/trees/property_tree_builder_unittest.cc b/chromium/cc/trees/property_tree_builder_unittest.cc index b5639ee0e11..5b5f96f4476 100644 --- a/chromium/cc/trees/property_tree_builder_unittest.cc +++ b/chromium/cc/trees/property_tree_builder_unittest.cc @@ -489,8 +489,9 @@ TEST_F(PropertyTreeBuilderTest, AnimatedOpacityCreatesRenderSurface) { static bool FilterIsAnimating(LayerImpl* layer) { MutatorHost* host = layer->layer_tree_impl()->mutator_host(); - return host->IsAnimatingFilterProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); + return host->IsAnimatingProperty(layer->element_id(), + layer->GetElementTypeForAnimation(), + TargetProperty::FILTER); } // Verify that having an animated filter (but no current filter, as these @@ -526,8 +527,9 @@ TEST_F(PropertyTreeBuilderTest, AnimatedFilterCreatesRenderSurface) { bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { MutatorHost* host = layer.layer_tree_impl()->mutator_host(); - return host->HasPotentiallyRunningFilterAnimation( - layer.element_id(), layer.GetElementTypeForAnimation()); + return host->HasPotentiallyRunningAnimationForProperty( + layer.element_id(), layer.GetElementTypeForAnimation(), + TargetProperty::FILTER); } // Verify that having a filter animation with a delayed start time creates a diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc index b2ec896d7a4..13dcfc9ab46 100644 --- a/chromium/cc/trees/property_tree_unittest.cc +++ b/chromium/cc/trees/property_tree_unittest.cc @@ -16,6 +16,7 @@ #include "cc/trees/layer_tree_impl.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" +#include "cc/trees/viewport_property_ids.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/geometry/test/geometry_util.h" @@ -202,6 +203,7 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) { FakeProtectedSequenceSynchronizer synchronizer; PropertyTrees property_trees(synchronizer); + ViewportPropertyIds viewport_property_ids; ClipTree& clip_tree = property_trees.clip_tree_mutable(); const gfx::RectF clip_rect(0, 0, 100, 100); ClipNode clip_node; @@ -209,20 +211,20 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) { clip_node.parent_id = 0; clip_node.clip = clip_rect; clip_tree.Insert(clip_node, 0); - clip_tree.set_overscroll_node_id(clip_node.id); + viewport_property_ids.outer_clip = clip_node.id; TransformTree& transform_tree = property_trees.transform_tree_mutable(); TransformNode contents_root; contents_root.local.Translate(2, 2); contents_root.id = transform_tree.Insert(contents_root, 0); - transform_tree.UpdateTransforms(1); + transform_tree.UpdateTransforms(1, &viewport_property_ids); const gfx::PointF overscroll_offset(0, 10); TransformNode overscroll_node; overscroll_node.scroll_offset = overscroll_offset; overscroll_node.id = transform_tree.Insert(overscroll_node, 1); + viewport_property_ids.overscroll_elasticity_transform = overscroll_node.id; - transform_tree.set_overscroll_node_id(overscroll_node.id); transform_tree.set_fixed_elements_dont_overscroll(true); TransformNode fixed_node; @@ -231,8 +233,9 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) { EXPECT_TRUE(transform_tree.ShouldUndoOverscroll(&fixed_node)); - transform_tree.UpdateTransforms(2); // overscroll_node - transform_tree.UpdateTransforms(3); // fixed_node + transform_tree.UpdateTransforms(2, + &viewport_property_ids); // overscroll_node + transform_tree.UpdateTransforms(3, &viewport_property_ids); // fixed_node gfx::Transform expected; expected.Translate(overscroll_offset.OffsetFromOrigin()); @@ -240,7 +243,7 @@ TEST(PropertyTreeTest, FixedElementInverseTranslation) { gfx::RectF expected_clip_rect(clip_rect); expected_clip_rect.set_height(clip_rect.height() + overscroll_offset.y()); - EXPECT_EQ(clip_tree.Node(clip_tree.overscroll_node_id())->clip, + EXPECT_EQ(clip_tree.Node(viewport_property_ids.outer_clip)->clip, expected_clip_rect); } @@ -279,7 +282,7 @@ TEST(PropertyTreeTest, TransformsWithFlattening) { tree.Node(grand_child)->local = rotation_about_x; tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); property_trees.ResetCachedData(); gfx::Transform flattened_rotation_about_x = rotation_about_x; @@ -306,7 +309,7 @@ TEST(PropertyTreeTest, TransformsWithFlattening) { // Remove flattening at grand_child, and recompute transforms. tree.Node(grand_child)->flattens_inherited_transform = false; tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); property_trees.GetToTarget(grand_child, effect_parent, &to_target); EXPECT_TRANSFORM_EQ(rotation_about_x * rotation_about_x, to_target); @@ -417,7 +420,7 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) { tree.Node(grand_parent_id)->needs_local_transform_update = true; tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); transform.MakeIdentity(); tree.CombineTransformsBetween(child_id, grand_parent_id, &transform); @@ -428,7 +431,7 @@ TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) { tree.Node(grand_parent_id)->needs_local_transform_update = true; tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); transform.MakeIdentity(); tree.CombineTransformsBetween(child_id, grand_parent_id, &transform); @@ -456,7 +459,7 @@ TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) { tree.Node(grand_child)->flattens_inherited_transform = true; tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); gfx::Transform flattened_rotation_about_x = rotation_about_x; flattened_rotation_about_x.FlattenTo2d(); @@ -511,7 +514,7 @@ TEST(PropertyTreeTest, SingularTransformSnapTest) { child_node->local.Translate(1.3f, 1.3f); tree.set_needs_update(true); - draw_property_utils::ComputeTransforms(&tree); + draw_property_utils::ComputeTransforms(&tree, ViewportPropertyIds()); property_trees.ResetCachedData(); gfx::Transform from_target; diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h index ce648e1d98c..6c879ed922d 100644 --- a/chromium/cc/trees/proxy.h +++ b/chromium/cc/trees/proxy.h @@ -101,9 +101,6 @@ class CC_EXPORT Proxy { virtual void SetRenderFrameObserver( std::unique_ptr<RenderFrameMetadataObserver> observer) = 0; - virtual void SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) = 0; - // Returns a percentage representing average throughput of last X seconds. // Only implemenented for single threaded proxy. virtual uint32_t GetAverageThroughput() const = 0; diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h index d8b8725949a..a1d9117c252 100644 --- a/chromium/cc/trees/proxy_common.h +++ b/chromium/cc/trees/proxy_common.h @@ -31,6 +31,7 @@ struct CC_EXPORT BeginMainFrameAndCommitState { ActiveFrameSequenceTrackers active_sequence_trackers = 0; bool evicted_ui_resources = false; std::vector<uint32_t> finished_transition_request_sequence_ids; + uint64_t trace_id = 0; }; } // namespace cc diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index d7a12d0a16f..e253b21d1ba 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -77,9 +77,9 @@ class ScopedCommitCompletionEvent { } private: - CompletionEvent* const event_; + const raw_ptr<CompletionEvent> event_; CommitTimestamps commit_timestamps_; - base::SingleThreadTaskRunner* main_thread_task_runner_; + raw_ptr<base::SingleThreadTaskRunner> main_thread_task_runner_; base::WeakPtr<ProxyMain> proxy_main_weak_ptr_; }; @@ -188,10 +188,34 @@ void ProxyImpl::InitializeLayerTreeFrameSinkOnImpl( scheduler_->DidCreateAndInitializeLayerTreeFrameSink(); } -void ProxyImpl::SetDeferBeginMainFrameOnImpl( - bool defer_begin_main_frame) const { +bool ProxyImpl::ShouldDeferBeginMainFrame() const { + return main_wants_defer_begin_main_frame_ || + impl_wants_defer_begin_main_frame_; +} + +void ProxyImpl::SetDeferBeginMainFrameFromMain(bool defer_begin_main_frame) { + // This is the impl-side update of a main-thread request (that is, through + // ProxyMain::SetDeferMainFrameUpdate) to defer BeginMainFrame. + DCHECK(IsImplThread()); + bool was_deferring = ShouldDeferBeginMainFrame(); + + main_wants_defer_begin_main_frame_ = defer_begin_main_frame; + + bool should_defer = ShouldDeferBeginMainFrame(); + if (was_deferring != should_defer) + scheduler_->SetDeferBeginMainFrame(ShouldDeferBeginMainFrame()); +} + +void ProxyImpl::SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) { + // This is a request from the impl thread to defer BeginMainFrame. DCHECK(IsImplThread()); - scheduler_->SetDeferBeginMainFrame(defer_begin_main_frame); + bool was_deferring = ShouldDeferBeginMainFrame(); + + impl_wants_defer_begin_main_frame_ = defer_begin_main_frame; + + bool should_defer = ShouldDeferBeginMainFrame(); + if (was_deferring != should_defer) + scheduler_->SetDeferBeginMainFrame(ShouldDeferBeginMainFrame()); } void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { @@ -201,7 +225,6 @@ void ProxyImpl::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { } void ProxyImpl::SetNeedsCommitOnImpl() { - DCHECK(IsImplThread()); SetNeedsCommitOnImplThread(); } @@ -287,6 +310,14 @@ void ProxyImpl::FrameSinksToThrottleUpdated( NOTREACHED(); } +void ProxyImpl::ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) { + DCHECK(IsImplThread()); + MainThreadTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&ProxyMain::ReportEventLatency, + proxy_main_weak_ptr_, std::move(latencies))); +} + void ProxyImpl::NotifyReadyToCommitOnImpl( CompletionEvent* completion_event, std::unique_ptr<CommitState> commit_state, @@ -295,7 +326,12 @@ void ProxyImpl::NotifyReadyToCommitOnImpl( const viz::BeginFrameArgs& commit_args, CommitTimestamps* commit_timestamps, bool commit_timeout) { - TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToCommitOnImpl"); + { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.NotifyReadyToCommitOnImpl", + TRACE_ID_LOCAL(commit_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } DCHECK(!data_for_commit_.get()); DCHECK(IsImplThread()); DCHECK(base::FeatureList::IsEnabled(features::kNonBlockingCommit) || @@ -381,11 +417,22 @@ void ProxyImpl::OnCanDrawStateChanged(bool can_draw) { } void ProxyImpl::NotifyReadyToActivate() { - TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToActivate"); + if (host_impl_->sync_tree() && + !scheduler_->pending_tree_is_ready_for_activation()) { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.NotifyReadyToActivate", + TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } DCHECK(IsImplThread()); scheduler_->NotifyReadyToActivate(); } +bool ProxyImpl::IsReadyToActivate() { + DCHECK(IsImplThread()); + return scheduler_->IsReadyToActivate(); +} + void ProxyImpl::NotifyReadyToDraw() { TRACE_EVENT0("cc", "ProxyImpl::NotifyReadyToDraw"); DCHECK(IsImplThread()); @@ -458,11 +505,6 @@ void ProxyImpl::RenewTreePriority() { bool user_interaction_in_progress = non_scroll_interaction_in_progress || scroll_type_considered_interaction; - if (host_impl_->ukm_manager()) { - host_impl_->ukm_manager()->SetUserInteractionInProgress( - user_interaction_in_progress); - } - if (host_impl_->CurrentScrollCheckerboardsDueToNoRecording() && base::FeatureList::IsEnabled( features::kPreferNewContentForCheckerboardedScrolls)) { @@ -665,7 +707,20 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame( host_impl_->FrameSequenceTrackerActiveTypes(); begin_main_frame_state->evicted_ui_resources = host_impl_->EvictedUIResourcesExist(); + begin_main_frame_state->trace_id = + (0x1llu << 51) | // Signature bit chosen at random to avoid collisions + (args.frame_id.source_id << 32) | + (args.frame_id.sequence_number & 0xffffffff); host_impl_->WillSendBeginMainFrame(); + { + TRACE_EVENT_WITH_FLOW1( + "viz,benchmark", "Graphics.Pipeline", TRACE_ID_GLOBAL(args.trace_id), + TRACE_EVENT_FLAG_FLOW_IN, "step", "SendBeginMainFrame"); + TRACE_EVENT_WITH_FLOW0("viz,benchmark", + "MainFrame.SendBeginMainFrameOnImpl", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_OUT); + } MainThreadTaskRunner()->PostTask( FROM_HERE, base::BindOnce(&ProxyMain::BeginMainFrame, proxy_main_weak_ptr_, @@ -693,7 +748,12 @@ DrawResult ProxyImpl::ScheduledActionDrawForced() { } void ProxyImpl::ScheduledActionCommit() { - TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionCommit"); + { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.BeginCommit", + TRACE_ID_LOCAL(data_for_commit_->commit_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } DCHECK(IsImplThread()); DCHECK(base::FeatureList::IsEnabled(features::kNonBlockingCommit) || IsMainThreadBlocked()); @@ -707,8 +767,9 @@ void ProxyImpl::ScheduledActionCommit() { allow_cross_thread_ref_count_access; auto* commit_state = data_for_commit_->commit_state.get(); - auto* unsafe_state = data_for_commit_->unsafe_state; - host_impl_->BeginCommit(commit_state->source_frame_number); + auto* unsafe_state = data_for_commit_->unsafe_state.get(); + host_impl_->BeginCommit(commit_state->source_frame_number, + commit_state->trace_id); host_impl_->FinishCommit(*commit_state, *unsafe_state); base::TimeTicks finish_time = base::TimeTicks::Now(); if (data_for_commit_->commit_timestamps) @@ -725,16 +786,30 @@ void ProxyImpl::ScheduledActionCommit() { } data_for_commit_.reset(); - scheduler_->DidCommit(); - // Delay this step until afer the main thread has been released as it's - // often a good bit of work to update the tree and prepare the new frame. - host_impl_->CommitComplete(); +} + +void ProxyImpl::ScheduledActionPostCommit() { + DCHECK(IsImplThread()); + TRACE_EVENT_WITH_FLOW0("viz,benchmark", "MainFrame.CommitComplete", + TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + // This is run as a separate step from commit because it can be time-consuming + // and ought not delay sending the next BeginMainFrame. + host_impl_->CommitComplete(); + // TODO(szager): This should be set at activation time. crbug.com/1323906 next_frame_is_newly_committed_frame_ = true; } void ProxyImpl::ScheduledActionActivateSyncTree() { - TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionActivateSyncTree"); + if (host_impl_->sync_tree() && + host_impl_->sync_tree()->source_frame_number() != + host_impl_->active_tree()->source_frame_number()) { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.Activate", + TRACE_ID_LOCAL(host_impl_->sync_tree()->trace_id()), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } DCHECK(IsImplThread()); host_impl_->ActivateSyncTree(); } @@ -785,6 +860,10 @@ DrawResult ProxyImpl::DrawInternal(bool forced_draw) { DCHECK(IsImplThread()); DCHECK(host_impl_.get()); + TRACE_EVENT_WITH_FLOW0("viz,benchmark", "MainFrame.Draw", + TRACE_ID_LOCAL(host_impl_->active_tree()->trace_id()), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + base::AutoReset<bool> mark_inside(&inside_draw_, true); // This method is called on a forced draw, regardless of whether we are able @@ -887,11 +966,6 @@ void ProxyImpl::SetRenderFrameObserver( host_impl_->SetRenderFrameObserver(std::move(observer)); } -void ProxyImpl::SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) { - host_impl_->SetEnableFrameRateThrottling(enable_frame_rate_throttling); -} - ProxyImpl::DataForCommit::DataForCommit( std::unique_ptr<ScopedCommitCompletionEvent> commit_completion_event, std::unique_ptr<CommitState> commit_state, diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index 19cd52164e5..53859c996e7 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -56,7 +56,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator); void InitializePaintWorkletLayerPainterOnImpl( std::unique_ptr<PaintWorkletLayerPainter> painter); - void SetDeferBeginMainFrameOnImpl(bool defer_begin_main_frame) const; + void SetDeferBeginMainFrameFromMain(bool defer_begin_main_frame); void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect); void SetNeedsCommitOnImpl(); void SetTargetLocalSurfaceIdOnImpl( @@ -81,7 +81,6 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, base::WritableSharedMemoryMapping ukm_smoothness_data); void SetRenderFrameObserver( std::unique_ptr<RenderFrameMetadataObserver> observer); - void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling); void MainFrameWillHappenOnImplForTesting(CompletionEvent* completion, bool* main_frame_will_happen); @@ -97,6 +96,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; void NotifyReadyToActivate() override; + bool IsReadyToActivate() override; void NotifyReadyToDraw() override; // Please call these 2 functions through // LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsOneBeginImplFrame(). @@ -105,6 +105,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void SetNeedsPrepareTilesOnImplThread() override; void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; + void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override; bool IsInsideDraw() override; void RenewTreePriority() override; void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task, @@ -133,6 +134,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, bool IsInSynchronousComposite() const override; void FrameSinksToThrottleUpdated( const base::flat_set<viz::FrameSinkId>& id) override; + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) override; // SchedulerClient implementation bool WillBeginImplFrame(const viz::BeginFrameArgs& args) override; @@ -146,6 +149,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, DrawResult ScheduledActionDrawIfPossible() override; DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; + void ScheduledActionPostCommit() override; void ScheduledActionActivateSyncTree() override; void ScheduledActionBeginLayerTreeFrameSinkCreation() override; void ScheduledActionPrepareTiles() override; @@ -162,6 +166,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, bool IsImplThread() const; bool IsMainThreadBlocked() const; base::SingleThreadTaskRunner* MainThreadTaskRunner(); + bool ShouldDeferBeginMainFrame() const; const int layer_tree_host_id_; @@ -181,10 +186,10 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, // Set when the main thread is waiting on a commit to complete. std::unique_ptr<ScopedCommitCompletionEvent> commit_completion_event; std::unique_ptr<CommitState> commit_state; - const ThreadUnsafeCommitState* unsafe_state; + raw_ptr<const ThreadUnsafeCommitState> unsafe_state; // This is passed from the main thread so the impl thread can record // timestamps at the beginning and end of commit. - CommitTimestamps* commit_timestamps = nullptr; + raw_ptr<CommitTimestamps> commit_timestamps = nullptr; }; std::unique_ptr<DataForCommit> data_for_commit_; @@ -218,6 +223,10 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, // A weak pointer to ProxyMain that is invalidated when LayerTreeFrameSink is // released. base::WeakPtr<ProxyMain> proxy_main_frame_sink_bound_weak_ptr_; + + // Either thread can request deferring BeginMainFrame; keep track of both. + bool main_wants_defer_begin_main_frame_ = false; + bool impl_wants_defer_begin_main_frame_ = false; }; } // namespace cc diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index 0f36361559d..4bd1151680d 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -131,11 +131,19 @@ void ProxyMain::BeginMainFrame( DCHECK_EQ(NO_PIPELINE_STAGE, current_pipeline_stage_); DCHECK(!layer_tree_host_->in_commit()); + { + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.BeginMainFrameOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT); + } base::TimeTicks begin_main_frame_start_time = base::TimeTicks::Now(); + const viz::BeginFrameArgs& frame_args = + begin_main_frame_state->begin_frame_args; benchmark_instrumentation::ScopedBeginFrameTask begin_frame_task( benchmark_instrumentation::kDoBeginFrame, - begin_main_frame_state->begin_frame_args.frame_id.sequence_number); + frame_args.frame_id.sequence_number); // This needs to run unconditionally, so do it before any early-returns. if (layer_tree_host_->scheduling_client()) @@ -156,6 +164,10 @@ void ProxyMain::BeginMainFrame( if (!layer_tree_host_->IsVisible()) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_NotVisible", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_WITH_FLOW1( + "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN, "reason", "ABORTED_NOT_VISIBLE"); // In this case, since the commit is deferred to a later time, gathered // events metrics are not discarded so that they can be reported if the // commit happens in the future. @@ -180,6 +192,11 @@ void ProxyMain::BeginMainFrame( if (defer_main_frame_update_) { TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_WITH_FLOW1("viz,benchmark", + "MainFrame.BeginMainFrameAbortedOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN, "reason", + "ABORTED_DEFERRED_MAIN_FRAME_UPDATE"); // In this case, since the commit is deferred to a later time, gathered // events metrics are not discarded so that they can be reported if the // commit happens in the future. @@ -243,12 +260,11 @@ void ProxyMain::BeginMainFrame( // See LayerTreeHostClient::BeginMainFrame for more documentation on // what this does. - layer_tree_host_->BeginMainFrame(begin_main_frame_state->begin_frame_args); + layer_tree_host_->BeginMainFrame(frame_args); // Updates cc animations on the main-thread. This is necessary in order // to track animation states such that they are cleaned up properly. - layer_tree_host_->AnimateLayers( - begin_main_frame_state->begin_frame_args.frame_time); + layer_tree_host_->AnimateLayers(frame_args.frame_time); // Recreates all UI resources if the compositor thread evicted UI resources // because it became invisible or there was a lost context when the compositor @@ -269,13 +285,17 @@ void ProxyMain::BeginMainFrame( // When we don't need to produce a CompositorFrame, there's also no need to // commit our updates. We still need to run layout and paint though, as it can // have side effects on page loading behavior. - skip_commit |= begin_main_frame_state->begin_frame_args.animate_only; + skip_commit |= frame_args.animate_only; if (skip_commit) { current_pipeline_stage_ = NO_PIPELINE_STAGE; layer_tree_host_->DidBeginMainFrame(); TRACE_EVENT_INSTANT0("cc", "EarlyOut_DeferCommit_InsideBeginMainFrame", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_WITH_FLOW1( + "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN, "reason", "ABORTED_DEFERRED_COMMIT"); layer_tree_host_->RecordEndOfFrameMetrics( begin_main_frame_start_time, begin_main_frame_state->active_sequence_trackers); @@ -324,8 +344,7 @@ void ProxyMain::BeginMainFrame( final_pipeline_stage_ = COMMIT_PIPELINE_STAGE; commit_trace_ = std::make_unique<devtools_instrumentation::ScopedCommitTrace>( - layer_tree_host_->GetId(), - begin_main_frame_state->begin_frame_args.frame_id.sequence_number); + layer_tree_host_->GetId(), frame_args.frame_id.sequence_number); auto completion_event_ptr = std::make_unique<CompletionEvent>( base::WaitableEvent::ResetPolicy::MANUAL); @@ -336,6 +355,12 @@ void ProxyMain::BeginMainFrame( std::unique_ptr<CommitState> commit_state = layer_tree_host_->WillCommit( std::move(completion_event_ptr), has_updates); DCHECK_EQ(has_updates, (bool)commit_state.get()); + if (commit_state.get()) { + commit_state->trace_id = + (0x1llu << 52) | // Signature bit chosen at random to avoid collisions + (frame_args.frame_id.source_id << 32) | + (commit_state->source_frame_number & 0xffffffff); + } current_pipeline_stage_ = COMMIT_PIPELINE_STAGE; if (!has_updates) { @@ -344,6 +369,10 @@ void ProxyMain::BeginMainFrame( layer_tree_host_->DidBeginMainFrame(); TRACE_EVENT_INSTANT0("cc,raf_investigation", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD); + TRACE_EVENT_WITH_FLOW1( + "viz,benchmark", "MainFrame.BeginMainFrameAbortedOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN, "reason", "FINISHED_NO_UPDATES"); std::vector<std::unique_ptr<SwapPromise>> swap_promises = layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises(); @@ -383,6 +412,15 @@ void ProxyMain::BeginMainFrame( CommitTimestamps commit_timestamps; bool blocking = !base::FeatureList::IsEnabled(features::kNonBlockingCommit); { + TRACE_EVENT_WITH_FLOW0("viz,benchmark", + "MainFrame.NotifyReadyToCommitOnMain", + TRACE_ID_LOCAL(begin_main_frame_state->trace_id), + TRACE_EVENT_FLAG_FLOW_IN); + TRACE_EVENT_WITH_FLOW0( + "viz,benchmark", "MainFrame.NotifyReadyToCommitOnMain", + TRACE_ID_LOCAL(commit_state->trace_id), TRACE_EVENT_FLAG_FLOW_OUT); + } + { TRACE_EVENT0("cc,raf_investigation", "ProxyMain::BeginMainFrame::commit"); absl::optional<DebugScopedSetMainThreadBlocked> main_thread_blocked; @@ -390,13 +428,13 @@ void ProxyMain::BeginMainFrame( main_thread_blocked.emplace(task_runner_provider_); ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl, - base::Unretained(proxy_impl_.get()), - completion_event, std::move(commit_state), - &unsafe_state, begin_main_frame_start_time, - begin_main_frame_state->begin_frame_args, - blocking ? &commit_timestamps : nullptr, - commit_timeout)); + FROM_HERE, + base::BindOnce(&ProxyImpl::NotifyReadyToCommitOnImpl, + base::Unretained(proxy_impl_.get()), completion_event, + std::move(commit_state), &unsafe_state, + begin_main_frame_start_time, frame_args, + blocking ? &commit_timestamps : nullptr, + commit_timeout)); if (blocking) layer_tree_host_->WaitForProtectedSequenceCompletion(); } @@ -442,6 +480,11 @@ void ProxyMain::DidObserveFirstScrollDelay( first_scroll_timestamp); } +void ProxyMain::ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) { + layer_tree_host_->ReportEventLatency(std::move(latencies)); +} + bool ProxyMain::IsStarted() const { DCHECK(IsMainThread()); return started_; @@ -542,7 +585,7 @@ void ProxyMain::SetDeferMainFrameUpdate(bool defer_main_frame_update) { // The impl thread needs to know that it should not issue BeginMainFrame. ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyImpl::SetDeferBeginMainFrameOnImpl, + FROM_HERE, base::BindOnce(&ProxyImpl::SetDeferBeginMainFrameFromMain, base::Unretained(proxy_impl_.get()), defer_main_frame_update)); } @@ -760,14 +803,6 @@ void ProxyMain::SetRenderFrameObserver( base::Unretained(proxy_impl_.get()), std::move(observer))); } -void ProxyMain::SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) { - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyImpl::SetEnableFrameRateThrottling, - base::Unretained(proxy_impl_.get()), - enable_frame_rate_throttling)); -} - uint32_t ProxyMain::GetAverageThroughput() const { NOTIMPLEMENTED(); return 0u; diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 79c20cae77d..1f0be862d15 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -12,6 +12,7 @@ #include "base/time/time.h" #include "cc/cc_export.h" #include "cc/input/browser_controls_state.h" +#include "cc/metrics/event_latency_tracker.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/paint_holding_reason.h" #include "cc/trees/proxy.h" @@ -71,6 +72,8 @@ class CC_EXPORT ProxyMain : public Proxy { void NotifyThroughputTrackerResults(CustomTrackerResults results); void DidObserveFirstScrollDelay(base::TimeDelta first_scroll_delay, base::TimeTicks first_scroll_timestamp); + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies); CommitPipelineStage max_requested_pipeline_stage() const { return max_requested_pipeline_stage_; @@ -117,7 +120,6 @@ class CC_EXPORT ProxyMain : public Proxy { base::WritableSharedMemoryMapping ukm_smoothness_data) override; void SetRenderFrameObserver( std::unique_ptr<RenderFrameMetadataObserver> observer) override; - void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling) override; uint32_t GetAverageThroughput() const override; // Returns |true| if the request was actually sent, |false| if one was diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc index 9e9e03db514..51add834b40 100644 --- a/chromium/cc/trees/render_frame_metadata.cc +++ b/chromium/cc/trees/render_frame_metadata.cc @@ -36,6 +36,10 @@ bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const { external_page_scale_factor == other.external_page_scale_factor && top_controls_height == other.top_controls_height && top_controls_shown_ratio == other.top_controls_shown_ratio && + previous_surfaces_visual_update_duration == + other.previous_surfaces_visual_update_duration && + current_surface_visual_update_duration == + other.current_surface_visual_update_duration && #if BUILDFLAG(IS_ANDROID) bottom_controls_height == other.bottom_controls_height && bottom_controls_shown_ratio == other.bottom_controls_shown_ratio && diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h index c83dd6b387c..0c0395e5eb5 100644 --- a/chromium/cc/trees/render_frame_metadata.h +++ b/chromium/cc/trees/render_frame_metadata.h @@ -5,6 +5,7 @@ #ifndef CC_TREES_RENDER_FRAME_METADATA_H_ #define CC_TREES_RENDER_FRAME_METADATA_H_ +#include "base/time/time.h" #include "build/build_config.h" #include "cc/cc_export.h" #include "components/viz/common/quads/selection.h" @@ -114,6 +115,14 @@ class CC_EXPORT RenderFrameMetadata { viz::VerticalScrollDirection new_vertical_scroll_direction = viz::VerticalScrollDirection::kNull; + // The cumulative time spent performing visual updates for all + // `local_surface_id` before this one. + base::TimeDelta previous_surfaces_visual_update_duration; + + // The cumulative time spent performing visual updates for the current + // `local_surface_id`. + base::TimeDelta current_surface_visual_update_duration; + #if BUILDFLAG(IS_ANDROID) // Used to position Android bottom bar, whose position is computed by the // renderer compositor. diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index c23b716f2da..0066ee64b58 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -230,39 +230,42 @@ void SingleThreadProxy::DoCommit(const viz::BeginFrameArgs& commit_args) { layer_tree_host_->GetId(), commit_args.frame_id.sequence_number); // Commit immediately. - { - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - DebugScopedSetImplThread impl(task_runner_provider_); + DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); + DebugScopedSetImplThread impl(task_runner_provider_); - host_impl_->BeginCommit(commit_state->source_frame_number); + host_impl_->BeginCommit(commit_state->source_frame_number, + commit_state->trace_id); - host_impl_->FinishCommit(*commit_state, unsafe_state); - commit_state.reset(); - completion_event->Signal(); + host_impl_->FinishCommit(*commit_state, unsafe_state); + commit_state.reset(); + completion_event->Signal(); - if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidCommit(); + { + DebugScopedSetMainThread main(task_runner_provider_); + IssueImageDecodeFinishedCallbacks(); + } +} - { - DebugScopedSetMainThread main(task_runner_provider_); - IssueImageDecodeFinishedCallbacks(); - } - host_impl_->CommitComplete(); +void SingleThreadProxy::DoPostCommit() { + TRACE_EVENT0("cc", "SingleThreadProxy::DoPostCommit"); + DCHECK(task_runner_provider_->IsMainThread()); - std::vector<uint32_t> ids = - host_impl_->TakeFinishedTransitionRequestSequenceIds(); - { - DebugScopedSetMainThread main(task_runner_provider_); - layer_tree_host_->NotifyTransitionRequestsFinished(ids); - } + DebugScopedSetImplThread impl(task_runner_provider_); + host_impl_->CommitComplete(); - // Commit goes directly to the active tree, but we need to synchronously - // "activate" the tree still during commit to satisfy any potential - // SetNextCommitWaitsForActivation calls. Unfortunately, the tree - // might not be ready to draw, so DidActivateSyncTree must set - // the flag to force the tree to not draw until textures are ready. - NotifyReadyToActivate(); + std::vector<uint32_t> ids = + host_impl_->TakeFinishedTransitionRequestSequenceIds(); + { + DebugScopedSetMainThread main(task_runner_provider_); + layer_tree_host_->NotifyTransitionRequestsFinished(ids); } + + // Commit goes directly to the active tree, but we need to synchronously + // "activate" the tree still during commit to satisfy any potential + // SetNextCommitWaitsForActivation calls. Unfortunately, the tree + // might not be ready to draw, so DidActivateSyncTree must set + // the flag to force the tree to not draw until textures are ready. + NotifyReadyToActivate(); } void SingleThreadProxy::IssueImageDecodeFinishedCallbacks() { @@ -444,6 +447,13 @@ void SingleThreadProxy::NotifyReadyToActivate() { scheduler_on_impl_thread_->NotifyReadyToActivate(); } +bool SingleThreadProxy::IsReadyToActivate() { + DCHECK(!task_runner_provider_->HasImplThread() || + task_runner_provider_->IsImplThread()); + return scheduler_on_impl_thread_ && + scheduler_on_impl_thread_->IsReadyToActivate(); +} + void SingleThreadProxy::NotifyReadyToDraw() { DCHECK(!task_runner_provider_->HasImplThread() || task_runner_provider_->IsImplThread()); @@ -707,6 +717,7 @@ void SingleThreadProxy::CompositeImmediatelyForTest( base::AutoReset<bool> inside_composite(&inside_synchronous_composite_, true); if (layer_tree_frame_sink_lost_) { + auto sync = layer_tree_host_->ForceSyncCompositeForTest(); // IN-TEST RequestNewLayerTreeFrameSink(); // RequestNewLayerTreeFrameSink could have synchronously created an output // surface, so check again before returning. @@ -741,6 +752,7 @@ void SingleThreadProxy::CompositeImmediatelyForTest( commit_requested_ = false; DoPainting(begin_frame_args); DoCommit(begin_frame_args); + DoPostCommit(); DCHECK_EQ( 0u, @@ -882,6 +894,14 @@ size_t SingleThreadProxy::CommitDurationSampleCountForTesting() const { ->CommitDurationSampleCountForTesting(); // IN-TEST } +void SingleThreadProxy::ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) { + DCHECK(!task_runner_provider_->HasImplThread() || + task_runner_provider_->IsImplThread()); + DebugScopedSetMainThread main(task_runner_provider_); + layer_tree_host_->ReportEventLatency(std::move(latencies)); +} + void SingleThreadProxy::SetRenderFrameObserver( std::unique_ptr<RenderFrameMetadataObserver> observer) { DCHECK(task_runner_provider_->IsMainThread()); @@ -889,11 +909,6 @@ void SingleThreadProxy::SetRenderFrameObserver( host_impl_->SetRenderFrameObserver(std::move(observer)); } -void SingleThreadProxy::SetEnableFrameRateThrottling( - bool enable_frame_rate_throttling) { - DCHECK(task_runner_provider_->IsMainThread()); -} - uint32_t SingleThreadProxy::GetAverageThroughput() const { DebugScopedSetImplThread impl(task_runner_provider_); return host_impl_->dropped_frame_counter()->GetAverageThroughput(); @@ -1114,6 +1129,14 @@ void SingleThreadProxy::ScheduledActionCommit() { DoCommit(scheduler_on_impl_thread_->last_dispatched_begin_main_frame_args()); } +void SingleThreadProxy::ScheduledActionPostCommit() { + // DebugScopedSetImplThread here is just a formality; all SchedulerClient + // methods should have it. + DebugScopedSetImplThread impl(task_runner_provider_); + DebugScopedSetMainThread main(task_runner_provider_); + DoPostCommit(); +} + void SingleThreadProxy::ScheduledActionActivateSyncTree() { DebugScopedSetImplThread impl(task_runner_provider_); host_impl_->ActivateSyncTree(); @@ -1130,6 +1153,7 @@ void SingleThreadProxy::ScheduledActionBeginLayerTreeFrameSinkCreation() { ScheduleRequestNewLayerTreeFrameSink(); } else { DebugScopedSetMainThread main(task_runner_provider_); + auto sync = layer_tree_host_->ForceSyncCompositeForTest(); // IN-TEST RequestNewLayerTreeFrameSink(); } } diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 76ed39ca284..fef5133be31 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -76,7 +76,6 @@ class CC_EXPORT SingleThreadProxy : public Proxy, base::WritableSharedMemoryMapping ukm_smoothness_data) override; void SetRenderFrameObserver( std::unique_ptr<RenderFrameMetadataObserver> observer) override; - void SetEnableFrameRateThrottling(bool enable_frame_rate_throttling) override; uint32_t GetAverageThroughput() const override; void UpdateBrowserControlsState(BrowserControlsState constraints, @@ -95,6 +94,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, DrawResult ScheduledActionDrawIfPossible() override; DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; + void ScheduledActionPostCommit() override; void ScheduledActionActivateSyncTree() override; void ScheduledActionBeginLayerTreeFrameSinkCreation() override; void ScheduledActionPrepareTiles() override; @@ -112,12 +112,14 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; void NotifyReadyToActivate() override; + bool IsReadyToActivate() override; void NotifyReadyToDraw() override; void SetNeedsRedrawOnImplThread() override; void SetNeedsOneBeginImplFrameOnImplThread() override; void SetNeedsPrepareTilesOnImplThread() override; void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; + void SetDeferBeginMainFrameFromImpl(bool defer_begin_main_frame) override {} bool IsInsideDraw() override; void RenewTreePriority() override; void PostDelayedAnimationTaskOnImplThread(base::OnceClosure task, @@ -145,6 +147,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy, const base::flat_set<viz::FrameSinkId>& ids) override; void ClearHistory() override; size_t CommitDurationSampleCountForTesting() const override; + void ReportEventLatency( + std::vector<EventLatencyTracker::LatencyData> latencies) override; void RequestNewLayerTreeFrameSink(); @@ -168,6 +172,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DoBeginMainFrame(const viz::BeginFrameArgs& begin_frame_args); void DoPainting(const viz::BeginFrameArgs& commit_args); void DoCommit(const viz::BeginFrameArgs& commit_args); + void DoPostCommit(); DrawResult DoComposite(LayerTreeHostImpl::FrameData* frame); void DoSwap(); void DidCommitAndDrawFrame(); diff --git a/chromium/cc/trees/target_property.h b/chromium/cc/trees/target_property.h index a60b371119c..184e1b74a96 100644 --- a/chromium/cc/trees/target_property.h +++ b/chromium/cc/trees/target_property.h @@ -14,6 +14,9 @@ namespace TargetProperty { // Must be zero-based as this will be stored in a bitset. enum Type { TRANSFORM = 0, + SCALE, + ROTATE, + TRANSLATE, OPACITY, FILTER, SCROLL_OFFSET, diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h index b6177e0a92e..e3e7ca9f0d7 100644 --- a/chromium/cc/trees/transform_node.h +++ b/chromium/cc/trees/transform_node.h @@ -112,7 +112,8 @@ struct CC_EXPORT TransformNode { // visibility, not this transform one. bool delegates_to_parent_for_backface : 1; - // Set to true, if the compositing reason is will-change:transform. + // Set to true, if the compositing reason is will-change:transform, scale, + // rotate, or translate (for the CSS property that created this node). bool will_change_transform : 1; // Set to true, if the node or it's parent |will_change_transform| is true. diff --git a/chromium/cc/trees/ukm_manager.cc b/chromium/cc/trees/ukm_manager.cc index 2685122aaf0..6d8e8540aad 100644 --- a/chromium/cc/trees/ukm_manager.cc +++ b/chromium/cc/trees/ukm_manager.cc @@ -22,82 +22,12 @@ UkmManager::UkmManager(std::unique_ptr<ukm::UkmRecorder> recorder) DCHECK(recorder_); } -UkmManager::~UkmManager() { - RecordCheckerboardUkm(); - RecordRenderingUkm(); -} +UkmManager::~UkmManager() = default; void UkmManager::SetSourceId(ukm::SourceId source_id) { - // If we accumulated any metrics, record them before resetting the source. - RecordCheckerboardUkm(); - RecordRenderingUkm(); - source_id_ = source_id; } -void UkmManager::SetUserInteractionInProgress(bool in_progress) { - if (user_interaction_in_progress_ == in_progress) - return; - - user_interaction_in_progress_ = in_progress; - if (!user_interaction_in_progress_) - RecordCheckerboardUkm(); -} - -void UkmManager::AddCheckerboardStatsForFrame(int64_t checkerboard_area, - int64_t num_missing_tiles, - int64_t total_visible_area) { - DCHECK_GE(total_visible_area, checkerboard_area); - if (source_id_ == ukm::kInvalidSourceId || !user_interaction_in_progress_) - return; - - checkerboarded_content_area_ += checkerboard_area; - num_missing_tiles_ += num_missing_tiles; - total_visible_area_ += total_visible_area; - num_of_frames_++; -} - -void UkmManager::AddCheckerboardedImages(int num_of_checkerboarded_images) { - if (user_interaction_in_progress_) { - num_of_images_checkerboarded_during_interaction_ += - num_of_checkerboarded_images; - } - total_num_of_checkerboarded_images_ += num_of_checkerboarded_images; -} - -void UkmManager::RecordCheckerboardUkm() { - // Only make a recording if there was any visible area from PictureLayers, - // which can be checkerboarded. - if (num_of_frames_ > 0 && total_visible_area_ > 0) { - DCHECK_NE(source_id_, ukm::kInvalidSourceId); - ukm::builders::Compositor_UserInteraction(source_id_) - .SetCheckerboardedContentArea(checkerboarded_content_area_ / - num_of_frames_) - .SetNumMissingTiles(num_missing_tiles_ / num_of_frames_) - .SetCheckerboardedContentAreaRatio( - (checkerboarded_content_area_ * 100) / total_visible_area_) - .SetCheckerboardedImagesCount( - num_of_images_checkerboarded_during_interaction_) - .Record(recorder_.get()); - } - - checkerboarded_content_area_ = 0; - num_missing_tiles_ = 0; - num_of_frames_ = 0; - total_visible_area_ = 0; - num_of_images_checkerboarded_during_interaction_ = 0; -} - -void UkmManager::RecordRenderingUkm() { - if (source_id_ == ukm::kInvalidSourceId) - return; - - ukm::builders::Compositor_Rendering(source_id_) - .SetCheckerboardedImagesCount(total_num_of_checkerboarded_images_) - .Record(recorder_.get()); - total_num_of_checkerboarded_images_ = 0; -} - void UkmManager::RecordThroughputUKM( FrameSequenceTrackerType tracker_type, FrameInfo::SmoothEffectDrivingThread thread_type, @@ -121,7 +51,11 @@ void UkmManager::RecordThroughputUKM( CASE_FOR_MAIN_THREAD_TRACKER(CanvasAnimation); CASE_FOR_MAIN_THREAD_TRACKER(JSAnimation); #undef CASE_FOR_MAIN_THREAD_TRACKER - default: + case FrameSequenceTrackerType::kSETCompositorAnimation: + case FrameSequenceTrackerType::kSETMainThreadAnimation: + break; + case FrameSequenceTrackerType::kCustom: + case FrameSequenceTrackerType::kMaxType: NOTREACHED(); break; } @@ -144,7 +78,13 @@ void UkmManager::RecordThroughputUKM( CASE_FOR_COMPOSITOR_THREAD_TRACKER(Video); CASE_FOR_COMPOSITOR_THREAD_TRACKER(WheelScroll); #undef CASE_FOR_COMPOSITOR_THREAD_TRACKER - default: + case FrameSequenceTrackerType::kCanvasAnimation: + case FrameSequenceTrackerType::kJSAnimation: + case FrameSequenceTrackerType::kSETCompositorAnimation: + case FrameSequenceTrackerType::kSETMainThreadAnimation: + break; + case FrameSequenceTrackerType::kCustom: + case FrameSequenceTrackerType::kMaxType: NOTREACHED(); break; } @@ -208,7 +148,7 @@ void UkmManager::RecordCompositorLatencyUKM( CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame); CASE_FOR_STAGE(TotalLatency); #undef CASE_FOR_STAGE - default: + case StageType::kStageTypeCount: NOTREACHED(); break; } @@ -227,6 +167,7 @@ void UkmManager::RecordCompositorLatencyUKM( CASE_FOR_BLINK_BREAKDOWN(Animate); CASE_FOR_BLINK_BREAKDOWN(StyleUpdate); CASE_FOR_BLINK_BREAKDOWN(LayoutUpdate); + CASE_FOR_BLINK_BREAKDOWN(Accessibility); CASE_FOR_BLINK_BREAKDOWN(Prepaint); CASE_FOR_BLINK_BREAKDOWN(CompositingInputs); CASE_FOR_BLINK_BREAKDOWN(Paint); @@ -234,7 +175,7 @@ void UkmManager::RecordCompositorLatencyUKM( CASE_FOR_BLINK_BREAKDOWN(UpdateLayers); CASE_FOR_BLINK_BREAKDOWN(BeginMainSentToStarted); #undef CASE_FOR_BLINK_BREAKDOWN - default: + case CompositorFrameReporter::BlinkBreakdown::kBreakdownCount: NOTREACHED(); break; } @@ -259,7 +200,7 @@ void UkmManager::RecordCompositorLatencyUKM( CASE_FOR_VIZ_BREAKDOWN(BufferReadyToLatch); CASE_FOR_VIZ_BREAKDOWN(LatchToSwapEnd); #undef CASE_FOR_VIZ_BREAKDOWN - default: + case CompositorFrameReporter::VizBreakdown::kBreakdownCount: NOTREACHED(); break; } @@ -287,7 +228,11 @@ void UkmManager::RecordCompositorLatencyUKM( CASE_FOR_TRACKER(CanvasAnimation); CASE_FOR_TRACKER(JSAnimation); #undef CASE_FOR_TRACKER - default: + case FrameSequenceTrackerType::kSETCompositorAnimation: + case FrameSequenceTrackerType::kSETMainThreadAnimation: + break; + case FrameSequenceTrackerType::kCustom: + case FrameSequenceTrackerType::kMaxType: NOTREACHED(); break; } @@ -397,15 +342,13 @@ void UkmManager::RecordEventLatencyUKM( auto stage_it = std::find_if( stage_history.begin(), stage_history.end(), [dispatch_timestamp](const CompositorFrameReporter::StageData& stage) { - return stage.start_time > dispatch_timestamp; + return stage.start_time >= dispatch_timestamp; }); - // TODO(crbug.com/1079116): Ideally, at least the start time of + // TODO(crbug.com/1330903): Ideally, at least the start time of // SubmitCompositorFrameToPresentationCompositorFrame stage should be - // greater than the final event dispatch timestamp, but apparently, this is - // not always the case (see crbug.com/1093698). For now, skip to the next - // event in such cases. Hopefully, the work to reduce discrepancies between - // the new EventLatency and the old Event.Latency metrics would fix this - // issue. If not, we need to reconsider investigating this issue. + // greater than or equal to the final event dispatch timestamp, but + // apparently, this is not always the case (see crbug.com/1330903). Skip + // recording compositor stages for now until we investigate the issue. if (stage_it == stage_history.end()) continue; @@ -426,7 +369,8 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame, SubmitCompositorFrame); #undef CASE_FOR_STAGE - default: + case StageType::kTotalLatency: + case StageType::kStageTypeCount: NOTREACHED(); break; } @@ -447,7 +391,8 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame, SubmitCompositorFrame); #undef CASE_FOR_STAGE - default: + case StageType::kTotalLatency: + case StageType::kStageTypeCount: NOTREACHED(); break; } @@ -456,7 +401,6 @@ void UkmManager::RecordEventLatencyUKM( NOTREACHED(); break; } - for (; stage_it != stage_history.end(); ++stage_it) { // Total latency is calculated since the event timestamp. const base::TimeTicks start_time = @@ -478,7 +422,7 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_STAGE(SubmitCompositorFrameToPresentationCompositorFrame); CASE_FOR_STAGE(TotalLatency); #undef CASE_FOR_STAGE - default: + case StageType::kStageTypeCount: NOTREACHED(); break; } @@ -497,6 +441,7 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_BLINK_BREAKDOWN(Animate); CASE_FOR_BLINK_BREAKDOWN(StyleUpdate); CASE_FOR_BLINK_BREAKDOWN(LayoutUpdate); + CASE_FOR_BLINK_BREAKDOWN(Accessibility); CASE_FOR_BLINK_BREAKDOWN(Prepaint); CASE_FOR_BLINK_BREAKDOWN(CompositingInputs); CASE_FOR_BLINK_BREAKDOWN(Paint); @@ -504,7 +449,7 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_BLINK_BREAKDOWN(UpdateLayers); CASE_FOR_BLINK_BREAKDOWN(BeginMainSentToStarted); #undef CASE_FOR_BLINK_BREAKDOWN - default: + case CompositorFrameReporter::BlinkBreakdown::kBreakdownCount: NOTREACHED(); break; } @@ -529,7 +474,7 @@ void UkmManager::RecordEventLatencyUKM( CASE_FOR_VIZ_BREAKDOWN(BufferReadyToLatch); CASE_FOR_VIZ_BREAKDOWN(LatchToSwapEnd); #undef CASE_FOR_VIZ_BREAKDOWN - default: + case CompositorFrameReporter::VizBreakdown::kBreakdownCount: NOTREACHED(); break; } diff --git a/chromium/cc/trees/ukm_manager.h b/chromium/cc/trees/ukm_manager.h index 1345e2482f1..1c0a157c036 100644 --- a/chromium/cc/trees/ukm_manager.h +++ b/chromium/cc/trees/ukm_manager.h @@ -38,15 +38,6 @@ class CC_EXPORT UkmManager { void SetSourceId(ukm::SourceId source_id); - // These metrics are recorded while a user interaction is in progress. - void SetUserInteractionInProgress(bool in_progress); - void AddCheckerboardStatsForFrame(int64_t checkerboard_area, - int64_t num_missing_tiles, - int64_t total_visible_area); - - // These metrics are recorded until the source URL changes. - void AddCheckerboardedImages(int num_of_checkerboarded_images); - void RecordThroughputUKM(FrameSequenceTrackerType tracker_type, FrameInfo::SmoothEffectDrivingThread thread_type, int64_t throughput) const; @@ -72,18 +63,6 @@ class CC_EXPORT UkmManager { ukm::UkmRecorder* recorder_for_testing() { return recorder_.get(); } private: - void RecordCheckerboardUkm(); - void RecordRenderingUkm(); - - bool user_interaction_in_progress_ = false; - int64_t num_of_images_checkerboarded_during_interaction_ = 0; - int64_t checkerboarded_content_area_ = 0; - int64_t num_missing_tiles_ = 0; - int64_t total_visible_area_ = 0; - int64_t num_of_frames_ = 0; - - int total_num_of_checkerboarded_images_ = 0; - ukm::SourceId source_id_ = ukm::kInvalidSourceId; std::unique_ptr<ukm::UkmRecorder> recorder_; }; diff --git a/chromium/cc/trees/ukm_manager_unittest.cc b/chromium/cc/trees/ukm_manager_unittest.cc index 2fa9afde6da..abb3a9bdbb5 100644 --- a/chromium/cc/trees/ukm_manager_unittest.cc +++ b/chromium/cc/trees/ukm_manager_unittest.cc @@ -25,15 +25,6 @@ namespace { const char kTestUrl[] = "https://example.com/foo"; const int64_t kTestSourceId1 = 100; -const int64_t kTestSourceId2 = 200; - -const char kUserInteraction[] = "Compositor.UserInteraction"; -const char kRendering[] = "Compositor.Rendering"; - -const char kCheckerboardArea[] = "CheckerboardedContentArea"; -const char kCheckerboardAreaRatio[] = "CheckerboardedContentAreaRatio"; -const char kMissingTiles[] = "NumMissingTiles"; -const char kCheckerboardedImagesCount[] = "CheckerboardedImagesCount"; // Names of compositor/event latency UKM events. const char kCompositorLatency[] = "Graphics.Smoothness.Latency"; @@ -244,64 +235,6 @@ class UkmManagerTest : public testing::Test { base::SimpleTestTickClock test_tick_clock_; }; -TEST_F(UkmManagerTest, Basic) { - manager_->SetUserInteractionInProgress(true); - manager_->AddCheckerboardStatsForFrame(5, 1, 10); - manager_->AddCheckerboardStatsForFrame(15, 3, 30); - manager_->AddCheckerboardedImages(6); - manager_->SetUserInteractionInProgress(false); - - // We should see a single entry for the interaction above. - const auto& entries = test_ukm_recorder_->GetEntriesByName(kUserInteraction); - ukm::SourceId original_id = ukm::kInvalidSourceId; - EXPECT_EQ(1u, entries.size()); - for (const auto* entry : entries) { - original_id = entry->source_id; - EXPECT_NE(ukm::kInvalidSourceId, entry->source_id); - test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl)); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardArea, 10); - test_ukm_recorder_->ExpectEntryMetric(entry, kMissingTiles, 2); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 50); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 6); - } - test_ukm_recorder_->Purge(); - - // Try pushing some stats while no user interaction is happening. No entries - // should be pushed. - manager_->AddCheckerboardStatsForFrame(6, 1, 10); - manager_->AddCheckerboardStatsForFrame(99, 3, 100); - EXPECT_EQ(0u, test_ukm_recorder_->entries_count()); - manager_->SetUserInteractionInProgress(true); - EXPECT_EQ(0u, test_ukm_recorder_->entries_count()); - - // Record a few entries and change the source before the interaction ends. The - // stats collected up till this point should be recorded before the source is - // swapped. - manager_->AddCheckerboardStatsForFrame(10, 1, 100); - manager_->AddCheckerboardStatsForFrame(30, 5, 100); - - manager_->SetSourceId(kTestSourceId2); - - const auto& entries2 = test_ukm_recorder_->GetEntriesByName(kUserInteraction); - EXPECT_EQ(1u, entries2.size()); - for (const auto* entry : entries2) { - EXPECT_EQ(original_id, entry->source_id); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardArea, 20); - test_ukm_recorder_->ExpectEntryMetric(entry, kMissingTiles, 3); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardAreaRatio, 20); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 0); - } - - // An entry for rendering is emitted when the URL changes. - const auto& entries_rendering = - test_ukm_recorder_->GetEntriesByName(kRendering); - EXPECT_EQ(1u, entries_rendering.size()); - for (const auto* entry : entries_rendering) { - EXPECT_EQ(original_id, entry->source_id); - test_ukm_recorder_->ExpectEntryMetric(entry, kCheckerboardedImagesCount, 6); - } -} - class UkmManagerCompositorLatencyTest : public UkmManagerTest, public testing::WithParamInterface< |