summaryrefslogtreecommitdiffstats
path: root/chromium/cc/trees
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-07 13:12:05 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:02:59 +0000
commit33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (patch)
treef6af110909c79b2759136554f1143d8b0572af0a /chromium/cc/trees
parent7d2c5d177e9813077a621df8d18c0deda73099b3 (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')
-rw-r--r--chromium/cc/trees/browser_controls_params.h4
-rw-r--r--chromium/cc/trees/commit_state.cc5
-rw-r--r--chromium/cc/trees/commit_state.h6
-rw-r--r--chromium/cc/trees/draw_properties_unittest.cc11
-rw-r--r--chromium/cc/trees/draw_property_utils.cc18
-rw-r--r--chromium/cc/trees/draw_property_utils.h7
-rw-r--r--chromium/cc/trees/effect_node.cc2
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink.h1
-rw-r--r--chromium/cc/trees/layer_tree_frame_sink_client.h1
-rw-r--r--chromium/cc/trees/layer_tree_host.cc62
-rw-r--r--chromium/cc/trees/layer_tree_host.h31
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h7
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc217
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h39
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc352
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc56
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc32
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc30
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc4
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc392
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc28
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc44
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_proxy.cc2
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc140
-rw-r--r--chromium/cc/trees/layer_tree_impl.h47
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h11
-rw-r--r--chromium/cc/trees/layer_tree_settings.h10
-rw-r--r--chromium/cc/trees/mutator_host.h28
-rw-r--r--chromium/cc/trees/property_tree.cc73
-rw-r--r--chromium/cc/trees/property_tree.h22
-rw-r--r--chromium/cc/trees/property_tree_builder.cc63
-rw-r--r--chromium/cc/trees/property_tree_builder_unittest.cc10
-rw-r--r--chromium/cc/trees/property_tree_unittest.cc27
-rw-r--r--chromium/cc/trees/proxy.h3
-rw-r--r--chromium/cc/trees/proxy_common.h1
-rw-r--r--chromium/cc/trees/proxy_impl.cc126
-rw-r--r--chromium/cc/trees/proxy_impl.h17
-rw-r--r--chromium/cc/trees/proxy_main.cc81
-rw-r--r--chromium/cc/trees/proxy_main.h4
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc4
-rw-r--r--chromium/cc/trees/render_frame_metadata.h9
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc86
-rw-r--r--chromium/cc/trees/single_thread_proxy.h7
-rw-r--r--chromium/cc/trees/target_property.h3
-rw-r--r--chromium/cc/trees/transform_node.h3
-rw-r--r--chromium/cc/trees/ukm_manager.cc125
-rw-r--r--chromium/cc/trees/ukm_manager.h21
-rw-r--r--chromium/cc/trees/ukm_manager_unittest.cc67
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<