summaryrefslogtreecommitdiffstats
path: root/chromium/cc/trees
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-12 09:13:00 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-16 09:58:26 +0000
commit03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch)
treecc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/cc/trees
parentfa98118a45f7e169f8846086dc2c22c49a8ba310 (diff)
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/trees')
-rw-r--r--chromium/cc/trees/damage_tracker.cc25
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc20
-rw-r--r--chromium/cc/trees/debug_rect_history.cc50
-rw-r--r--chromium/cc/trees/draw_properties_unittest.cc13
-rw-r--r--chromium/cc/trees/draw_property_utils.cc41
-rw-r--r--chromium/cc/trees/effect_node.cc14
-rw-r--r--chromium/cc/trees/effect_node.h8
-rw-r--r--chromium/cc/trees/layer_tree_host.cc35
-rw-r--r--chromium/cc/trees/layer_tree_host.h25
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h13
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc76
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h35
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc117
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_blending.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc10
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_masks.cc26
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc144
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc126
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_capture_content.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc12
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc28
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc13
-rw-r--r--chromium/cc/trees/layer_tree_impl.h11
-rw-r--r--chromium/cc/trees/layer_tree_settings.h2
-rw-r--r--chromium/cc/trees/occlusion_tracker.cc2
-rw-r--r--chromium/cc/trees/occlusion_tracker_unittest.cc4
-rw-r--r--chromium/cc/trees/property_tree.cc12
-rw-r--r--chromium/cc/trees/property_tree_builder.cc12
-rw-r--r--chromium/cc/trees/property_tree_builder_unittest.cc147
-rw-r--r--chromium/cc/trees/proxy_impl.cc50
-rw-r--r--chromium/cc/trees/proxy_impl.h4
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc12
-rw-r--r--chromium/cc/trees/single_thread_proxy.h6
-rw-r--r--chromium/cc/trees/ukm_manager.cc23
-rw-r--r--chromium/cc/trees/ukm_manager.h2
-rw-r--r--chromium/cc/trees/ukm_manager_unittest.cc7
36 files changed, 737 insertions, 399 deletions
diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc
index b6f3dc9822d..48499b8b57e 100644
--- a/chromium/cc/trees/damage_tracker.cc
+++ b/chromium/cc/trees/damage_tracker.cc
@@ -441,7 +441,17 @@ void DamageTracker::AccumulateDamageFromRenderSurface(
// The surface's old region is now exposed on the target surface, too.
damage_for_this_update_.Union(old_surface_rect);
+ render_surface->set_can_use_cached_backdrop_filtered_result(false);
} else {
+ // Check if current accumulated damage intersects the render surface.
+ gfx::Rect damage_on_target;
+ bool valid = damage_for_this_update_.GetAsRect(&damage_on_target);
+ if (valid && !damage_on_target.Intersects(surface_rect_in_target_space)) {
+ surfaces_with_backdrop_blur_filter.emplace_back(
+ std::make_pair(render_surface, surface_rect_in_target_space));
+ } else {
+ render_surface->set_can_use_cached_backdrop_filtered_result(false);
+ }
// Only the surface's damage_rect will damage the target surface.
gfx::Rect damage_rect_in_local_space;
bool is_valid_rect = render_surface->damage_tracker()->GetDamageRectIfValid(
@@ -460,21 +470,6 @@ void DamageTracker::AccumulateDamageFromRenderSurface(
}
}
- const FilterOperations& backdrop_filters = render_surface->BackdropFilters();
- if (!surface_is_new &&
- backdrop_filters.HasFilterOfType(FilterOperation::BLUR)) {
- gfx::Rect damage_on_target;
- bool valid = damage_for_this_update_.GetAsRect(&damage_on_target);
- if (!valid || damage_on_target.Intersects(surface_rect_in_target_space)) {
- render_surface->set_can_use_cached_backdrop_filtered_result(false);
- } else {
- surfaces_with_backdrop_blur_filter.push_back(
- std::make_pair(render_surface, surface_rect_in_target_space));
- }
- } else {
- render_surface->set_can_use_cached_backdrop_filtered_result(false);
- }
-
// True if any changes from contributing render surface.
has_damage_from_contributing_content_ |= !damage_for_this_update_.IsEmpty();
}
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index 3e4714170b6..4b9213336ec 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -2059,20 +2059,18 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
EmulateDrawingOneFrame(root);
+ // child1_'s render target has changed its surface property.
EXPECT_FALSE(
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
// Let run for one update and there should be no damage left.
- ClearDamageForAllSurfaces(root);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
GetRenderSurface(child1_)->can_use_cached_backdrop_filtered_result());
// CASE 1.1: Setting a non-intersecting update rect on the root
// doesn't invalidate child1_'s cached backdrop-filtered result.
- // Damage rect at 0,0 20x20 (expanded to -6,-6 32x32) doesn't intersect
- // 270,270 36x38.
- ClearDamageForAllSurfaces(root);
+ // Damage rect at 0,0 20x20 doesn't intersect 270,270 36x38.
root->UnionUpdateRect(gfx::Rect(0, 0, 20, 20));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(
@@ -2080,8 +2078,7 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 1.2: Setting an intersecting update rect on the root invalidates
// child1_'s cached backdrop-filtered result.
- // Damage rect at 260,260 20x20 (expanded to 254,254 32x32) intersects 270,270
- // 36x38.
+ // Damage rect at 260,260 20x20 intersects 270,270 36x38.
ClearDamageForAllSurfaces(root);
root->UnionUpdateRect(gfx::Rect(260, 260, 20, 20));
EmulateDrawingOneFrame(root);
@@ -2113,7 +2110,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->can_use_cached_backdrop_filtered_result());
// Let run for one update and there should be no damage left.
- ClearDamageForAllSurfaces(root);
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
@@ -2121,7 +2117,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 3.1: Adding a non-intersecting damage rect to a sibling layer under
// the render surface with the backdrop filter doesn't invalidate cached
// backdrop-filtered result. Damage rect on grand_child1_ at 302,302 1x1
- // expanded by a 6-pixel spread (296,296 13x13)
// doesn't intersect 280,280 15x16.
ClearDamageForAllSurfaces(root);
grand_child1_->AddDamageRect(gfx::Rect(2, 2, 1.f, 1.f));
@@ -2132,7 +2127,6 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
// CASE 3.2: Adding an intersecting damage rect to a sibling layer under the
// render surface with the backdrop filter invalidates cached
// backdrop-filtered result. Damage rect on grand_child2_ at 290,290 1x1
- // expanded by a 6-pixel spread (284,284 13x13)
// intersects 280,280 15x16.
ClearDamageForAllSurfaces(root);
grand_child2_->AddDamageRect(gfx::Rect(0, 0, 1.f, 1.f));
@@ -2151,8 +2145,8 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->damage_tracker()
->GetDamageRectIfValid(&damage_rect));
EXPECT_EQ(gfx::Rect(170, 170, 1.f, 1.f), damage_rect);
- // Damage rect at 170,170 1x1 (expanded to 164,164 13x13) in render target
- // local space doesn't intersect 180,180 15x16.
+ // Damage rect at 170,170 1x1 in render target local space doesn't intersect
+ // 180,180 15x16.
EXPECT_TRUE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
@@ -2166,8 +2160,8 @@ TEST_F(DamageTrackerTest, CanUseCachedBackdropFilterResultTest) {
->damage_tracker()
->GetDamageRectIfValid(&damage_rect));
EXPECT_EQ(gfx::Rect(170, 170, 11.f, 11.f), damage_rect);
- // Damage rect at 170,170 11x11 (expanded to 164,164 23x23) in render target
- // local space intersects 180,180 15x16
+ // Damage rect at 170,170 11x11 in render target local space intersects
+ // 180,180 15x16
EXPECT_FALSE(GetRenderSurface(grand_child4_)
->can_use_cached_backdrop_filtered_result());
diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc
index f9aae396584..f2455eb24d3 100644
--- a/chromium/cc/trees/debug_rect_history.cc
+++ b/chromium/cc/trees/debug_rect_history.cc
@@ -7,6 +7,7 @@
#include <stddef.h>
#include "base/memory/ptr_util.h"
+#include "cc/base/features.h"
#include "cc/base/math_util.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/layers/layer_impl.h"
@@ -161,24 +162,39 @@ void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) {
}
void DebugRectHistory::SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl) {
- EventListenerProperties event_properties =
- tree_impl->event_listener_properties(EventListenerClass::kMouseWheel);
- if (event_properties == EventListenerProperties::kNone ||
- event_properties == EventListenerProperties::kPassive) {
- return;
- }
+ // TODO(https://crbug.com/1136591): Need behavior confirmation.
+ // TODO(https://crbug.com/1136591): Need to check results in dev tools layer
+ // view.
+ if (base::FeatureList::IsEnabled(::features::kWheelEventRegions)) {
+ for (auto* layer : *tree_impl) {
+ const Region& region = layer->wheel_event_handler_region();
+ for (gfx::Rect rect : region) {
+ debug_rects_.emplace_back(
+ DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(
+ layer->ScreenSpaceTransform(), rect)));
+ }
+ }
+ } else {
+ EventListenerProperties event_properties =
+ tree_impl->event_listener_properties(EventListenerClass::kMouseWheel);
+ if (event_properties == EventListenerProperties::kNone ||
+ event_properties == EventListenerProperties::kPassive) {
+ return;
+ }
- // Since the wheel event handlers property is on the entire layer tree just
- // mark inner viewport if have listeners.
- ScrollNode* inner_scroll = tree_impl->InnerViewportScrollNode();
- if (!inner_scroll)
- return;
- debug_rects_.push_back(
- DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
- MathUtil::MapEnclosingClippedRect(
- tree_impl->property_trees()->transform_tree.ToScreen(
- inner_scroll->transform_id),
- gfx::Rect(inner_scroll->bounds))));
+ // Since the wheel event handlers property is on the entire layer tree just
+ // mark inner viewport if have listeners.
+ ScrollNode* inner_scroll = tree_impl->InnerViewportScrollNode();
+ if (!inner_scroll)
+ return;
+ debug_rects_.emplace_back(
+ DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(
+ tree_impl->property_trees()->transform_tree.ToScreen(
+ inner_scroll->transform_id),
+ gfx::Rect(inner_scroll->bounds))));
+ }
}
void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) {
diff --git a/chromium/cc/trees/draw_properties_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc
index 4335955fe9a..d461d6ae08d 100644
--- a/chromium/cc/trees/draw_properties_unittest.cc
+++ b/chromium/cc/trees/draw_properties_unittest.cc
@@ -12,7 +12,6 @@
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
-#include "base/test/scoped_feature_list.h"
#include "cc/animation/animation.h"
#include "cc/animation/animation_host.h"
#include "cc/animation/animation_id_provider.h"
@@ -8123,12 +8122,12 @@ TEST_F(DrawPropertiesTestWithLayerTree, RoundedCornerOnRenderSurface) {
UpdateMainDrawProperties();
CommitAndActivate();
- EXPECT_FALSE(
- GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty());
- EXPECT_FALSE(
- GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty());
- EXPECT_FALSE(
- GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty());
+ EXPECT_TRUE(
+ GetRenderSurfaceImpl(child_1)->mask_filter_info().HasRoundedCorners());
+ EXPECT_TRUE(
+ GetRenderSurfaceImpl(child_2)->mask_filter_info().HasRoundedCorners());
+ EXPECT_TRUE(
+ GetRenderSurfaceImpl(child_3)->mask_filter_info().HasRoundedCorners());
}
} // namespace
diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc
index 1e007fd3602..c2e79fc3b7e 100644
--- a/chromium/cc/trees/draw_property_utils.cc
+++ b/chromium/cc/trees/draw_property_utils.cc
@@ -706,27 +706,28 @@ ConditionalClip LayerClipRect(PropertyTrees* property_trees, LayerImpl* layer) {
layer->clip_tree_index(), target_node->id);
}
-std::pair<gfx::RRectF, bool> GetRoundedCornerRRect(
+std::pair<gfx::MaskFilterInfo, bool> GetMaskFilterInfoPair(
const PropertyTrees* property_trees,
int effect_tree_index,
bool for_render_surface) {
- static const std::pair<gfx::RRectF, bool> kEmptyRoundedCornerInfo(
- gfx::RRectF(), false);
+ static const std::pair<gfx::MaskFilterInfo, bool> kEmptyMaskFilterInfoPair =
+ std::make_pair(gfx::MaskFilterInfo(), false);
+
const EffectTree* effect_tree = &property_trees->effect_tree;
const EffectNode* effect_node = effect_tree->Node(effect_tree_index);
const int target_id = effect_node->target_id;
- // Return empty rrect if this node has a render surface but the function call
- // was made for a non render surface.
+ // Return empty mask info if this node has a render surface but the function
+ // call was made for a non render surface.
if (effect_node->HasRenderSurface() && !for_render_surface)
- return kEmptyRoundedCornerInfo;
+ return kEmptyMaskFilterInfoPair;
// Traverse the parent chain up to the render target to find a node which has
// a rounded corner bounds set.
const EffectNode* node = effect_node;
bool found_rounded_corner = false;
while (node) {
- if (!node->rounded_corner_bounds.IsEmpty()) {
+ if (node->mask_filter_info.HasRoundedCorners()) {
found_rounded_corner = true;
break;
}
@@ -749,17 +750,17 @@ std::pair<gfx::RRectF, bool> GetRoundedCornerRRect(
// While traversing up the parent chain we did not find any node with a
// rounded corner.
if (!node || !found_rounded_corner)
- return kEmptyRoundedCornerInfo;
+ return kEmptyMaskFilterInfoPair;
gfx::Transform to_target;
if (!property_trees->GetToTarget(node->transform_id, target_id, &to_target))
- return kEmptyRoundedCornerInfo;
+ return kEmptyMaskFilterInfoPair;
auto result =
- std::make_pair(node->rounded_corner_bounds, node->is_fast_rounded_corner);
+ std::make_pair(node->mask_filter_info, node->is_fast_rounded_corner);
- if (!to_target.TransformRRectF(&result.first))
- return kEmptyRoundedCornerInfo;
+ if (!result.first.Transform(to_target))
+ return kEmptyMaskFilterInfoPair;
return result;
}
@@ -839,9 +840,9 @@ void ComputeSurfaceDrawProperties(PropertyTrees* property_trees,
SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface);
SetSurfaceDrawTransform(property_trees, render_surface);
- render_surface->SetRoundedCornerRRect(
- GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(),
- /*for_render_surface*/ true)
+ render_surface->SetMaskFilterInfo(
+ GetMaskFilterInfoPair(property_trees, render_surface->EffectTreeIndex(),
+ /*for_render_surface=*/true)
.first);
render_surface->SetScreenSpaceTransform(
property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale(
@@ -1142,12 +1143,12 @@ void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list,
layer, property_trees->transform_tree, property_trees->effect_tree);
layer->draw_properties().screen_space_transform_is_animating =
transform_node->to_screen_is_potentially_animated;
- auto rounded_corner_info =
- GetRoundedCornerRRect(property_trees, layer->effect_tree_index(),
- /*from_render_surface*/ false);
- layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first;
+ auto mask_filter_info_pair =
+ GetMaskFilterInfoPair(property_trees, layer->effect_tree_index(),
+ /*from_render_surface=*/false);
+ layer->draw_properties().mask_filter_info = mask_filter_info_pair.first;
layer->draw_properties().is_fast_rounded_corner =
- rounded_corner_info.second;
+ mask_filter_info_pair.second;
}
// Compute effects and determine if render surfaces have contributing layers
diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc
index de8b74caf4a..fa07fea5b79 100644
--- a/chromium/cc/trees/effect_node.cc
+++ b/chromium/cc/trees/effect_node.cc
@@ -60,7 +60,7 @@ bool EffectNode::operator==(const EffectNode& other) const {
backdrop_filters == other.backdrop_filters &&
backdrop_filter_bounds == other.backdrop_filter_bounds &&
backdrop_mask_element_id == other.backdrop_mask_element_id &&
- rounded_corner_bounds == other.rounded_corner_bounds &&
+ mask_filter_info == other.mask_filter_info &&
is_fast_rounded_corner == other.is_fast_rounded_corner &&
node_or_ancestor_has_filters == other.node_or_ancestor_has_filters &&
affected_by_backdrop_filter == other.affected_by_backdrop_filter &&
@@ -158,12 +158,18 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const {
if (!backdrop_filters.IsEmpty())
value->SetString("backdrop_filters", backdrop_filters.ToString());
value->SetDouble("backdrop_filter_quality", backdrop_filter_quality);
- value->SetBoolean("is_fast_rounded_corner", is_fast_rounded_corner);
value->SetBoolean("node_or_ancestor_has_filters",
node_or_ancestor_has_filters);
- if (!rounded_corner_bounds.IsEmpty()) {
- MathUtil::AddToTracedValue("rounded_corner_bounds", rounded_corner_bounds,
+ if (!mask_filter_info.IsEmpty()) {
+ MathUtil::AddToTracedValue("mask_filter_bounds", mask_filter_info.bounds(),
value);
+ if (mask_filter_info.HasRoundedCorners()) {
+ MathUtil::AddCornerRadiiToTracedValue(
+ "mask_filter_rounded_corner_raii",
+ mask_filter_info.rounded_corner_bounds(), value);
+ value->SetBoolean("mask_filter_is_fast_rounded_corner",
+ is_fast_rounded_corner);
+ }
}
value->SetString("blend_mode", SkBlendMode_Name(blend_mode));
value->SetBoolean("cache_render_surface", cache_render_surface);
diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h
index 4834773cd21..2a2541d123d 100644
--- a/chromium/cc/trees/effect_node.h
+++ b/chromium/cc/trees/effect_node.h
@@ -11,6 +11,7 @@
#include "third_party/skia/include/core/SkBlendMode.h"
#include "ui/gfx/geometry/point_f.h"
#include "ui/gfx/geometry/size_f.h"
+#include "ui/gfx/mask_filter_info.h"
#include "ui/gfx/rrect_f.h"
namespace base {
@@ -80,9 +81,10 @@ struct CC_EXPORT EffectNode {
// image.
ElementId backdrop_mask_element_id;
- // Bounds of rounded corner rrect in the space of the transform node
- // associated with this effect node.
- gfx::RRectF rounded_corner_bounds;
+ // The mask filter information applied to this effect node. The coordinates of
+ // in the mask info is in the space of the transform node associated with this
+ // effect node.
+ gfx::MaskFilterInfo mask_filter_info;
SkBlendMode blend_mode;
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 8e390b365f4..03e3c41c5e5 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -33,6 +33,7 @@
#include "base/trace_event/traced_value.h"
#include "build/build_config.h"
#include "cc/base/devtools_instrumentation.h"
+#include "cc/base/features.h"
#include "cc/base/histograms.h"
#include "cc/base/math_util.h"
#include "cc/debug/rendering_stats_instrumentation.h"
@@ -46,6 +47,7 @@
#include "cc/metrics/ukm_smoothness_data.h"
#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
+#include "cc/tiles/raster_dark_mode_filter.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/compositor_commit_data.h"
#include "cc/trees/draw_property_utils.h"
@@ -141,7 +143,8 @@ LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode)
id_(s_layer_tree_host_sequence_number.GetNext() + 1),
task_graph_runner_(params.task_graph_runner),
event_listener_properties_(),
- mutator_host_(params.mutator_host) {
+ mutator_host_(params.mutator_host),
+ dark_mode_filter_(params.dark_mode_filter) {
DCHECK(task_graph_runner_);
DCHECK(!settings_.enable_checker_imaging || image_worker_task_runner_);
@@ -252,8 +255,8 @@ SwapPromiseManager* LayerTreeHost::GetSwapPromiseManager() {
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
LayerTreeHost::GetScopedEventMetricsMonitor(
- std::unique_ptr<EventMetrics> event_metrics) {
- return events_metrics_manager_.GetScopedMonitor(std::move(event_metrics));
+ EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) {
+ return events_metrics_manager_.GetScopedMonitor(std::move(done_callback));
}
void LayerTreeHost::ClearEventsMetrics() {
@@ -477,7 +480,7 @@ void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() {
}
bool LayerTreeHost::IsUsingLayerLists() const {
- return settings_.use_layer_lists && !force_use_property_tree_builder_;
+ return settings_.use_layer_lists;
}
void LayerTreeHost::CommitComplete() {
@@ -544,14 +547,15 @@ std::unique_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create(
settings_, client, task_runner_provider_.get(),
rendering_stats_instrumentation_.get(), task_graph_runner_,
- std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_),
- scheduling_client_);
+ std::move(mutator_host_impl), dark_mode_filter_, id_,
+ std::move(image_worker_task_runner_), scheduling_client_);
if (ukm_recorder_factory_) {
host_impl->InitializeUkm(ukm_recorder_factory_->CreateRecorder());
ukm_recorder_factory_.reset();
}
task_graph_runner_ = nullptr;
+ dark_mode_filter_ = nullptr;
compositor_delegate_weak_ptr_ = host_impl->AsWeakPtr();
return host_impl;
}
@@ -691,12 +695,13 @@ void LayerTreeHost::LayoutAndUpdateLayers() {
UpdateLayers();
}
-void LayerTreeHost::Composite(base::TimeTicks frame_begin_time, bool raster) {
+void LayerTreeHost::CompositeForTest(base::TimeTicks frame_begin_time,
+ bool raster) {
DCHECK(IsSingleThreaded());
// This function is only valid when not using the scheduler.
DCHECK(!settings_.single_thread_proxy_scheduler);
SingleThreadProxy* proxy = static_cast<SingleThreadProxy*>(proxy_.get());
- proxy->CompositeImmediately(frame_begin_time, raster);
+ proxy->CompositeImmediatelyForTest(frame_begin_time, raster); // IN-TEST
}
bool LayerTreeHost::UpdateLayers() {
@@ -1153,20 +1158,9 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
// This flag is sticky until a new tree comes along.
gpu_rasterization_histogram_recorded_ = false;
- force_use_property_tree_builder_ = false;
-
SetNeedsFullTreeSync();
}
-void LayerTreeHost::SetNonBlinkManagedRootLayer(
- scoped_refptr<Layer> root_layer) {
- SetRootLayer(std::move(root_layer));
-
- DCHECK(!root_layer || root_layer_->children().empty());
- if (IsUsingLayerLists() && root_layer_)
- force_use_property_tree_builder_ = true;
-}
-
void LayerTreeHost::RegisterViewportPropertyIds(
const ViewportPropertyIds& ids) {
DCHECK(IsUsingLayerLists());
@@ -1223,7 +1217,8 @@ void LayerTreeHost::SetEventListenerProperties(
// Thus when it changes, we want to request every layer to push properties
// and recompute its wheel event handler region, since the computation is
// done in PushPropertiesTo.
- if (event_class == EventListenerClass::kMouseWheel) {
+ if (event_class == EventListenerClass::kMouseWheel &&
+ !base::FeatureList::IsEnabled(::features::kWheelEventRegions)) {
bool new_property_is_blocking =
properties == EventListenerProperties::kBlocking ||
properties == EventListenerProperties::kBlockingAndPassive;
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index c528a84e40b..e5e66fa7cc6 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -37,7 +37,6 @@
#include "cc/layers/layer_collections.h"
#include "cc/layers/layer_list_iterator.h"
#include "cc/metrics/begin_main_frame_metrics.h"
-#include "cc/metrics/event_metrics.h"
#include "cc/metrics/events_metrics_manager.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "cc/paint/node_id.h"
@@ -65,6 +64,7 @@ struct PresentationFeedback;
namespace cc {
+class RasterDarkModeFilter;
class HeadsUpDisplayLayer;
class Layer;
class LayerTreeHostImpl;
@@ -110,6 +110,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
LayerTreeSettings const* settings = nullptr;
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner;
MutatorHost* mutator_host = nullptr;
+ RasterDarkModeFilter* dark_mode_filter = nullptr;
// The image worker task runner is used to schedule image decodes. The
// compositor thread may make sync calls to this thread, analogous to the
@@ -183,7 +184,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
SwapPromiseManager* GetSwapPromiseManager();
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
- GetScopedEventMetricsMonitor(std::unique_ptr<EventMetrics> event_metrics);
+ GetScopedEventMetricsMonitor(
+ EventsMetricsManager::ScopedMonitor::DoneCallback done_callback);
void ClearEventsMetrics();
size_t saved_events_metrics_count_for_testing() const {
@@ -281,7 +283,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// Synchronously performs a complete main frame update, commit and compositor
// frame. Used only in single threaded mode when the compositor's internal
// scheduling is disabled.
- void Composite(base::TimeTicks frame_begin_time, bool raster);
+ void CompositeForTest(base::TimeTicks frame_begin_time, bool raster);
// Requests a redraw (compositor frame) for the given rect.
void SetNeedsRedrawRect(const gfx::Rect& damage_rect);
@@ -341,14 +343,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
Layer* root_layer() { return root_layer_.get(); }
const Layer* root_layer() const { return root_layer_.get(); }
- // Sets the root layer which is not managed by blink, and we will initialize
- // its paint properties using PropertyTreeBuilder. For ui::Compositor, because
- // for now we always use PropertyTreeBulder, this function is equivalent to
- // SetRootLayer().
- // TODO(crbug.com/925855): This is temporary. Eventually we should let the
- // caller inform blink about the layer and remove the function.
- void SetNonBlinkManagedRootLayer(scoped_refptr<Layer> root_layer);
-
struct ViewportPropertyIds {
int overscroll_elasticity_transform = TransformTree::kInvalidNodeId;
int page_scale_transform = TransformTree::kInvalidNodeId;
@@ -911,15 +905,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// for every layer during property tree building.
bool has_copy_request_ = false;
- // When settings_.use_layer_lists is true, paint properties are generated by
- // blink and we don't use PropertyTreeBuilder, except that the root layer
- // is set by SetNonBlinkManagedRootLayer().
- // TODO(crbug.com/925855): Remove this field when removing
- // SetNonBlinkManagedRootLayer().
- bool force_use_property_tree_builder_ = false;
-
MutatorHost* mutator_host_;
+ RasterDarkModeFilter* dark_mode_filter_;
+
std::vector<std::pair<PaintImage, base::OnceCallback<void(bool)>>>
queued_image_decodes_;
std::unordered_map<int, base::OnceCallback<void(bool)>>
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index a97a40874fb..5a804d2f009 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -66,6 +66,16 @@ constexpr ManipulationInfo kManipulationInfoTouch = 1 << 1;
constexpr ManipulationInfo kManipulationInfoPrecisionTouchPad = 1 << 2;
constexpr ManipulationInfo kManipulationInfoPinchZoom = 1 << 3;
+struct PaintBenchmarkResult {
+ double record_time_ms = 0;
+ double record_time_caching_disabled_ms = 0;
+ double record_time_subsequence_caching_disabled_ms = 0;
+ double record_time_partial_invalidation_ms = 0;
+ double raster_invalidation_and_convert_time_ms = 0;
+ double paint_artifact_compositor_update_time_ms = 0;
+ size_t painter_memory_usage = 0;
+};
+
// A LayerTreeHost is bound to a LayerTreeHostClient. The main rendering
// loop (in ProxyMain or SingleThreadProxy) calls methods on the
// LayerTreeHost, which then handles them and also calls into the equivalent
@@ -172,6 +182,9 @@ class LayerTreeHostClient {
virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0;
virtual void NotifyThroughputTrackerResults(CustomTrackerResults results) = 0;
+ virtual void RunPaintBenchmark(int repeat_count,
+ PaintBenchmarkResult& result) {}
+
protected:
virtual ~LayerTreeHostClient() = default;
};
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index bb7ff971823..9efdf67d48c 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -149,6 +149,13 @@ const float kMobileViewportWidthEpsilon = 0.15f;
// kHitTestAsk after the threshold is reached.
const size_t kAssumeOverlapThreshold = 100;
+// gfx::DisplayColorSpaces stores up to 3 different color spaces. This should be
+// updated to match any size changes in DisplayColorSpaces.
+constexpr size_t kContainsSrgbCacheSize = 3;
+static_assert(kContainsSrgbCacheSize ==
+ gfx::DisplayColorSpaces::kConfigCount / 2,
+ "sRGB cache must match the size of DisplayColorSpaces");
+
bool HasFixedPageScale(LayerTreeImpl* active_tree) {
return active_tree->min_page_scale_factor() ==
active_tree->max_page_scale_factor();
@@ -365,12 +372,13 @@ std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create(
RenderingStatsInstrumentation* rendering_stats_instrumentation,
TaskGraphRunner* task_graph_runner,
std::unique_ptr<MutatorHost> mutator_host,
+ RasterDarkModeFilter* dark_mode_filter,
int id,
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
LayerTreeHostSchedulingClient* scheduling_client) {
return base::WrapUnique(new LayerTreeHostImpl(
settings, client, task_runner_provider, rendering_stats_instrumentation,
- task_graph_runner, std::move(mutator_host), id,
+ task_graph_runner, std::move(mutator_host), dark_mode_filter, id,
std::move(image_worker_task_runner), scheduling_client));
}
@@ -381,6 +389,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
RenderingStatsInstrumentation* rendering_stats_instrumentation,
TaskGraphRunner* task_graph_runner,
std::unique_ptr<MutatorHost> mutator_host,
+ RasterDarkModeFilter* dark_mode_filter,
int id,
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
LayerTreeHostSchedulingClient* scheduling_client)
@@ -408,6 +417,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
memory_history_(MemoryHistory::Create()),
debug_rect_history_(DebugRectHistory::Create()),
mutator_host_(std::move(mutator_host)),
+ dark_mode_filter_(dark_mode_filter),
rendering_stats_instrumentation_(rendering_stats_instrumentation),
micro_benchmark_controller_(this),
task_graph_runner_(task_graph_runner),
@@ -422,7 +432,8 @@ LayerTreeHostImpl::LayerTreeHostImpl(
frame_trackers_(settings.single_thread_proxy_scheduler,
compositor_frame_reporting_controller_.get()),
lcd_text_metrics_reporter_(LCDTextMetricsReporter::CreateIfNeeded(this)),
- frame_rate_estimator_(GetTaskRunner()) {
+ frame_rate_estimator_(GetTaskRunner()),
+ contains_srgb_cache_(kContainsSrgbCacheSize) {
DCHECK(mutator_host_);
mutator_host_->SetMutatorHostClient(this);
mutator_events_ = mutator_host_->CreateEvents();
@@ -610,7 +621,7 @@ void LayerTreeHostImpl::CommitComplete() {
if (mutator_host_->CurrentFrameHadRAF())
frame_trackers_.StartSequence(FrameSequenceTrackerType::kRAF);
if (mutator_host_->HasCanvasInvalidation())
- frame_trackers_.StartSequence(FrameSequenceTrackerType::kCanvas);
+ frame_trackers_.StartSequence(FrameSequenceTrackerType::kCanvasAnimation);
if (mutator_host_->HasJSAnimation())
frame_trackers_.StartSequence(FrameSequenceTrackerType::kJSAnimation);
@@ -976,8 +987,8 @@ LayerTreeHostImpl::CreateLatencyInfoSwapPromiseMonitor(
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
LayerTreeHostImpl::GetScopedEventMetricsMonitor(
- std::unique_ptr<EventMetrics> event_metrics) {
- return events_metrics_manager_.GetScopedMonitor(std::move(event_metrics));
+ EventsMetricsManager::ScopedMonitor::DoneCallback done_callback) {
+ return events_metrics_manager_.GetScopedMonitor(std::move(done_callback));
}
void LayerTreeHostImpl::NotifyInputEvent() {
@@ -1050,9 +1061,9 @@ static void AppendQuadsToFillScreen(
viz::SharedQuadState* shared_quad_state =
target_render_pass->CreateAndAppendSharedQuadState();
shared_quad_state->SetAll(gfx::Transform(), root_target_rect,
- root_target_rect, gfx::RRectF(), root_target_rect,
- false, are_contents_opaque, opacity,
- SkBlendMode::kSrcOver, sorting_context_id);
+ root_target_rect, gfx::MaskFilterInfo(),
+ root_target_rect, false, are_contents_opaque,
+ opacity, SkBlendMode::kSrcOver, sorting_context_id);
for (gfx::Rect screen_space_rect : fill_region) {
gfx::Rect visible_screen_space_rect = screen_space_rect;
@@ -1795,6 +1806,29 @@ gfx::ColorSpace LayerTreeHostImpl::GetRasterColorSpace(
if (result.IsHDR() && content_color_usage != gfx::ContentColorUsage::kHDR)
return gfx::ColorSpace::CreateDisplayP3D65();
+ // The raster color space should contain sRGB to avoid artifacts during
+ // rasterization.
+ if (!CheckColorSpaceContainsSrgb(result))
+ return srgb;
+
+ return result;
+}
+
+bool LayerTreeHostImpl::CheckColorSpaceContainsSrgb(
+ const gfx::ColorSpace& color_space) const {
+ constexpr gfx::ColorSpace srgb = gfx::ColorSpace::CreateSRGB();
+
+ // Color spaces without a custom primary matrix are cheap to compute, so the
+ // cache can be bypassed.
+ if (color_space.GetPrimaryID() != gfx::ColorSpace::PrimaryID::CUSTOM)
+ return color_space.Contains(srgb);
+
+ auto it = contains_srgb_cache_.Get(color_space);
+ if (it != contains_srgb_cache_.end())
+ return it->second;
+
+ bool result = color_space.Contains(srgb);
+ contains_srgb_cache_.Put(color_space, result);
return result;
}
@@ -1843,6 +1877,10 @@ int LayerTreeHostImpl::GetMSAASampleCountForRaster(
return RequestedMSAASampleCount();
}
+bool LayerTreeHostImpl::HasPendingTree() {
+ return pending_tree_ != nullptr;
+}
+
void LayerTreeHostImpl::NotifyReadyToActivate() {
// The TileManager may call this method while the pending tree is still being
// painted, as it isn't aware of the ongoing paint. We shouldn't tell the
@@ -2019,8 +2057,8 @@ void LayerTreeHostImpl::LogAverageLagEvents(
}
void LayerTreeHostImpl::NotifyThroughputTrackerResults(
- CustomTrackerResults results) {
- client_->NotifyThroughputTrackerResults(std::move(results));
+ const CustomTrackerResults& results) {
+ client_->NotifyThroughputTrackerResults(results);
}
void LayerTreeHostImpl::DidNotNeedBeginFrame() {
@@ -2142,8 +2180,11 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
}
if (GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) {
+ // TODO(savella) : Change to check for ActivelyScrollingType::kNone
+ const bool actively_scrolling =
+ GetActivelyScrollingType() == ActivelyScrollingType::kPrecise;
metadata.is_resourceless_software_draw_with_scroll_or_animation =
- IsActivelyPrecisionScrolling() || mutator_host_->NeedsTickAnimations();
+ actively_scrolling || mutator_host_->NeedsTickAnimations();
}
const base::flat_set<viz::SurfaceRange>& referenced_surfaces =
@@ -2172,6 +2213,7 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
if (std::unique_ptr<viz::DelegatedInkMetadata> delegated_ink_metadata =
active_tree_->take_delegated_ink_metadata()) {
+ delegated_ink_metadata->set_frame_time(CurrentBeginFrameArgs().frame_time);
TRACE_EVENT_INSTANT1(
"cc", "Delegated Ink Metadata set on compositor frame metadata",
TRACE_EVENT_SCOPE_THREAD, "ink metadata",
@@ -2342,7 +2384,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
if (!mutator_host_->NextFrameHasPendingRAF())
frame_trackers_.StopSequence(FrameSequenceTrackerType::kRAF);
if (!mutator_host_->HasCanvasInvalidation())
- frame_trackers_.StopSequence(FrameSequenceTrackerType::kCanvas);
+ frame_trackers_.StopSequence(FrameSequenceTrackerType::kCanvasAnimation);
if (!mutator_host_->HasJSAnimation())
frame_trackers_.StopSequence(FrameSequenceTrackerType::kJSAnimation);
@@ -2959,6 +3001,8 @@ void LayerTreeHostImpl::DidLoseLayerTreeFrameSink() {
has_valid_layer_tree_frame_sink_ = false;
client_->DidLoseLayerTreeFrameSinkOnImplThread();
lag_tracking_manager_.Clear();
+
+ dropped_frame_counter_.ResetFrameSorter();
}
bool LayerTreeHostImpl::OnlyExpandTopControlsAtPageTop() const {
@@ -2995,10 +3039,10 @@ bool LayerTreeHostImpl::IsPinchGestureActive() const {
return GetInputHandler().pinch_gesture_active();
}
-bool LayerTreeHostImpl::IsActivelyPrecisionScrolling() const {
+ActivelyScrollingType LayerTreeHostImpl::GetActivelyScrollingType() const {
if (!input_delegate_)
- return false;
- return input_delegate_->IsActivelyPrecisionScrolling();
+ return ActivelyScrollingType::kNone;
+ return input_delegate_->GetActivelyScrollingType();
}
bool LayerTreeHostImpl::ScrollAffectsScrollHandler() const {
@@ -3327,7 +3371,7 @@ void LayerTreeHostImpl::CreateTileManagerResources() {
viz::ResourceFormatToClosestSkColorType(/*gpu_compositing=*/true,
tile_format),
settings_.decoded_image_working_set_budget_bytes, max_texture_size_,
- paint_image_generator_client_id_);
+ paint_image_generator_client_id_, dark_mode_filter_);
} else {
bool gpu_compositing = !!layer_tree_frame_sink_->context_provider();
image_decode_cache_ = std::make_unique<SoftwareImageDecodeCache>(
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index c0c6166c5f6..eee1d46bc15 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -17,6 +17,7 @@
#include "base/callback.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
+#include "base/containers/mru_cache.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/shared_memory_mapping.h"
#include "base/optional.h"
@@ -25,6 +26,7 @@
#include "cc/base/synced_property.h"
#include "cc/benchmarks/micro_benchmark_controller_impl.h"
#include "cc/cc_export.h"
+#include "cc/input/actively_scrolling_type.h"
#include "cc/input/browser_controls_offset_manager_client.h"
#include "cc/input/input_handler.h"
#include "cc/input/scrollbar_animation_controller.h"
@@ -84,8 +86,10 @@ struct FrameTimingDetails;
namespace cc {
+enum class ActivelyScrollingType;
class BrowserControlsOffsetManager;
class CompositorFrameReportingController;
+class RasterDarkModeFilter;
class DebugRectHistory;
class EvictionTilePriorityQueue;
class DroppedFrameCounter;
@@ -179,6 +183,11 @@ class LayerTreeHostImplClient {
base::TimeDelta first_scroll_delay,
base::TimeTicks first_scroll_timestamp) = 0;
+ // Returns true if the client is currently compositing synchronously. This is
+ // only true in tests, but some behavior needs to be synchronized in non-test
+ // code as a result.
+ virtual bool IsInSynchronousComposite() const = 0;
+
protected:
virtual ~LayerTreeHostImplClient() = default;
};
@@ -258,6 +267,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
RenderingStatsInstrumentation* rendering_stats_instrumentation,
TaskGraphRunner* task_graph_runner,
std::unique_ptr<MutatorHost> mutator_host,
+ RasterDarkModeFilter* dark_mode_filter,
int id,
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
LayerTreeHostSchedulingClient* scheduling_client);
@@ -280,7 +290,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
std::unique_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
ui::LatencyInfo* latency);
std::unique_ptr<EventsMetricsManager::ScopedMonitor>
- GetScopedEventMetricsMonitor(std::unique_ptr<EventMetrics> event_metrics);
+ GetScopedEventMetricsMonitor(
+ EventsMetricsManager::ScopedMonitor::DoneCallback done_callback);
void NotifyInputEvent();
// BrowserControlsOffsetManagerClient implementation.
@@ -490,6 +501,8 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
int GetMSAASampleCountForRaster(
const scoped_refptr<DisplayItemList>& display_list) override;
+ bool HasPendingTree() override;
+
// ScrollbarAnimationControllerClient implementation.
void PostDelayedScrollbarAnimationTask(base::OnceClosure task,
base::TimeDelta delay) override;
@@ -612,7 +625,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
// LayerTreeHostImpl's interface.
bool IsPinchGestureActive() const;
// See comment in equivalent ThreadedInputHandler method for what this means.
- bool IsActivelyPrecisionScrolling() const;
+ ActivelyScrollingType GetActivelyScrollingType() const;
bool ScrollAffectsScrollHandler() const;
void SetExternalPinchGestureActive(bool active);
void set_force_smooth_wheel_scrolling_for_testing(bool enabled) {
@@ -800,6 +813,11 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
return &dropped_frame_counter_;
}
+ // Returns true if the client is currently compositing synchronously.
+ bool IsInSynchronousComposite() const {
+ return client_->IsInSynchronousComposite();
+ }
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -808,6 +826,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
RenderingStatsInstrumentation* rendering_stats_instrumentation,
TaskGraphRunner* task_graph_runner,
std::unique_ptr<MutatorHost> mutator_host,
+ RasterDarkModeFilter* dark_mode_filter,
int id,
scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner,
LayerTreeHostSchedulingClient* scheduling_client);
@@ -934,7 +953,10 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
const viz::FrameTimingDetails& details);
// Notifies client about the custom tracker results.
- void NotifyThroughputTrackerResults(CustomTrackerResults results);
+ void NotifyThroughputTrackerResults(const CustomTrackerResults& results);
+
+ // Wrapper for checking and updating |contains_srgb_cache_|.
+ bool CheckColorSpaceContainsSrgb(const gfx::ColorSpace& color_space) const;
// Once bound, this instance owns the InputHandler. However, an InputHandler
// need not be bound so this should be null-checked before dereferencing.
@@ -1052,6 +1074,7 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
std::unique_ptr<MutatorHost> mutator_host_;
std::unique_ptr<MutatorEvents> mutator_events_;
std::set<VideoFrameController*> video_frame_controllers_;
+ RasterDarkModeFilter* const dark_mode_filter_;
// Map from scroll element ID to scrollbar animation controller.
// There is one animation controller per pair of overlay scrollbars.
@@ -1178,6 +1201,12 @@ class CC_EXPORT LayerTreeHostImpl : public TileManagerClient,
base::WritableSharedMemoryMapping ukm_smoothness_mapping_;
+ // Cache for the results of calls to gfx::ColorSpace::Contains() on sRGB. This
+ // computation is deterministic for a given color space, can be called
+ // multiple times per frame, and incurs a non-trivial cost.
+ // mutable because |contains_srgb_cache_| is accessed in a const method.
+ mutable base::MRUCache<gfx::ColorSpace, bool> contains_srgb_cache_;
+
// Must be the last member to ensure this is destroyed first in the
// destruction order and invalidates all weak pointers.
base::WeakPtrFactory<LayerTreeHostImpl> weak_factory_{this};
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 120265911b3..a9c0a3e8e39 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -12,14 +12,14 @@
#include "base/base_switches.h"
#include "base/bind.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "base/command_line.h"
#include "base/location.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "base/run_loop.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -273,6 +273,7 @@ class LayerTreeHostImplTest : public testing::Test,
base::TimeTicks first_scroll_timestamp) override {
first_scroll_observed++;
}
+ bool IsInSynchronousComposite() const override { return false; }
void set_reduce_memory_result(bool reduce_memory_result) {
reduce_memory_result_ = reduce_memory_result;
}
@@ -291,7 +292,7 @@ class LayerTreeHostImplTest : public testing::Test,
host_impl_ = LayerTreeHostImpl::Create(
settings, this, &task_runner_provider_, &stats_instrumentation_,
&task_graph_runner_,
- AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0,
+ AnimationHost::CreateForTesting(ThreadInstance::IMPL), nullptr, 0,
image_worker_ ? image_worker_->task_runner() : nullptr, nullptr);
InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl_));
layer_tree_frame_sink_ = std::move(layer_tree_frame_sink);
@@ -1262,16 +1263,12 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
EXPECT_TRUE(did_request_commit_);
}
-// Ensure correct semantics for the IsActivelyPrecisionScrolling method. This
+// Ensure correct semantics for the GetActivelyScrollingType method. This
// method is used to determine scheduler policy so it wants to report true only
// when real scrolling is occurring (i.e. the compositor is consuming scroll
-// delta, the page isn't handling the events itself). We also only consider
-// this signal for non-animated scrolls. This is partially historical but also
-// makes some sense since touchscreen/high-precision touchpad scrolling has a
-// physical metaphor (movement sticks to finger) so smoothness should be
-// prioritized.
+// delta, the page isn't handling the events itself).
TEST_P(ScrollUnifiedLayerTreeHostImplTest,
- ActivelyTouchScrollingOnlyAfterScrollMovement) {
+ ActivelyScrollingOnlyAfterScrollMovement) {
SetupViewportLayersOuterScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
DrawFrame();
@@ -1286,29 +1283,33 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kNone);
// There is no extent upwards so the scroll won't consume any delta.
GetInputHandler().ScrollUpdate(
UpdateState(gfx::Point(), gfx::Vector2d(0, -10),
ui::ScrollInputType::kTouchscreen)
.get());
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kNone);
// This should scroll so ensure the bit flips to true.
GetInputHandler().ScrollUpdate(
UpdateState(gfx::Point(), gfx::Vector2d(0, 10),
ui::ScrollInputType::kTouchscreen)
.get());
- EXPECT_TRUE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kPrecise);
GetInputHandler().ScrollEnd();
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kNone);
}
ASSERT_EQ(10, CurrentScrollOffset(OuterViewportScrollLayer()).y());
- // Ensure an animated wheel scroll doesn't cause the bit to flip even when
- // scrolling occurs.
+ // Ensure an animated wheel scroll only causes the bit to flip when enabling
+ // smoothness mode (i.e. the value of GetParam().animate);
{
InputHandler::ScrollStatus status = GetInputHandler().ScrollBegin(
BeginState(gfx::Point(), gfx::Vector2dF(0, 10),
@@ -1316,11 +1317,13 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
.get(),
ui::ScrollInputType::kWheel);
EXPECT_EQ(ScrollThread::SCROLL_ON_IMPL_THREAD, status.thread);
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kNone);
GetInputHandler().ScrollUpdate(
AnimatedUpdateState(gfx::Point(), gfx::Vector2dF(0, 10)).get());
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kAnimated);
base::TimeTicks cur_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
@@ -1339,18 +1342,22 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
// The animation is setup in the first frame so tick at least twice to
// actually animate it.
ANIMATE(0);
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kAnimated);
ANIMATE(200);
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kAnimated);
ANIMATE(1000);
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kAnimated);
#undef ANIMATE
ASSERT_EQ(20, CurrentScrollOffset(OuterViewportScrollLayer()).y());
GetInputHandler().ScrollEnd();
- EXPECT_FALSE(host_impl_->IsActivelyPrecisionScrolling());
+ EXPECT_EQ(host_impl_->GetActivelyScrollingType(),
+ ActivelyScrollingType::kNone);
}
}
@@ -4942,6 +4949,7 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl {
rendering_stats_instrumentation,
task_graph_runner,
AnimationHost::CreateForTesting(ThreadInstance::IMPL),
+ nullptr,
0,
nullptr,
nullptr) {}
@@ -5404,32 +5412,6 @@ TEST_P(LayerTreeHostImplTestMultiScrollable,
EXPECT_FALSE(animation_task_.is_null());
}
-TEST_P(LayerTreeHostImplTestMultiScrollable, ScrollbarFlashWhenMouseEnter) {
- LayerTreeSettings settings = DefaultSettings();
- settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500);
- settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300);
- settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY;
- settings.scrollbar_flash_when_mouse_enter = true;
-
- SetUpLayers(settings);
-
- EXPECT_EQ(scrollbar_1_->Opacity(), 0);
- EXPECT_EQ(scrollbar_2_->Opacity(), 0);
-
- // Scroll should flash when mouse enter.
- GetInputHandler().MouseMoveAt(gfx::Point(1, 1));
-
- EXPECT_TRUE(scrollbar_1_->Opacity());
- EXPECT_FALSE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.is_null());
-
- GetInputHandler().MouseMoveAt(gfx::Point(51, 51));
-
- EXPECT_TRUE(scrollbar_1_->Opacity());
- EXPECT_TRUE(scrollbar_2_->Opacity());
- EXPECT_FALSE(animation_task_.is_null());
-}
-
TEST_P(ScrollUnifiedLayerTreeHostImplTest, ScrollHitTestOnScrollbar) {
LayerTreeSettings settings = DefaultSettings();
settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500);
@@ -10849,8 +10831,8 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
LayerTreeHostImpl::Create(
settings, this, &task_runner_provider_, &stats_instrumentation_,
&task_graph_runner_,
- AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr,
- nullptr);
+ AnimationHost::CreateForTesting(ThreadInstance::IMPL), nullptr, 0,
+ nullptr, nullptr);
layer_tree_host_impl->SetVisible(true);
layer_tree_host_impl->InitializeFrameSink(layer_tree_frame_sink.get());
@@ -11298,8 +11280,8 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest, MemoryLimits) {
host_impl_ = LayerTreeHostImpl::Create(
settings, this, &task_runner_provider_, &stats_instrumentation_,
&task_graph_runner_,
- AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr,
- nullptr);
+ AnimationHost::CreateForTesting(ThreadInstance::IMPL), nullptr, 0,
+ nullptr, nullptr);
InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl_));
// Gpu compositing.
@@ -11557,8 +11539,14 @@ class FrameSinkClient : public TestLayerTreeFrameSinkClient {
scoped_refptr<viz::ContextProvider> display_context_provider)
: display_context_provider_(std::move(display_context_provider)) {}
- std::unique_ptr<viz::SkiaOutputSurface> CreateDisplaySkiaOutputSurface()
- override {
+ 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_));
}
@@ -14067,20 +14055,21 @@ TEST_F(LayerTreeHostImplTest, FrameCounterReset) {
dropped_frame_counter->AddGoodFrame();
EXPECT_EQ(dropped_frame_counter->total_frames(), 1u);
- dropped_frame_counter->AddDroppedFrameAffectingSmoothness();
- // FCP not received, so the total_smoothness_dropped_ won't increase.
- EXPECT_EQ(dropped_frame_counter->total_smoothness_dropped(), 0u);
-
auto interval = base::TimeDelta::FromMilliseconds(16);
base::TimeTicks now = base::TimeTicks::Now();
auto deadline = now + interval;
viz::BeginFrameArgs args = viz::BeginFrameArgs::Create(
- BEGINFRAME_FROM_HERE, 1u /*source_id*/, 1u /*sequence_number*/, now,
+ BEGINFRAME_FROM_HERE, 1u /*source_id*/, 2u /*sequence_number*/, now,
deadline, interval, viz::BeginFrameArgs::NORMAL);
+
+ dropped_frame_counter->OnEndFrame(args, true);
+ // FCP not received, so the total_smoothness_dropped_ won't increase.
+ EXPECT_EQ(dropped_frame_counter->total_smoothness_dropped(), 0u);
+
BeginMainFrameMetrics begin_frame_metrics;
begin_frame_metrics.should_measure_smoothness = true;
host_impl_->ReadyToCommit(args, &begin_frame_metrics);
- dropped_frame_counter->AddDroppedFrameAffectingSmoothness();
+ dropped_frame_counter->OnEndFrame(args, true);
EXPECT_EQ(dropped_frame_counter->total_smoothness_dropped(), 1u);
total_frame_counter->set_total_frames_for_testing(1u);
@@ -15862,8 +15851,8 @@ TEST_P(ScrollUnifiedLayerTreeHostImplTest,
host_impl_ = LayerTreeHostImpl::Create(
DefaultSettings(), this, &task_runner_provider_, &stats_instrumentation_,
&task_graph_runner_,
- AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr,
- nullptr);
+ AnimationHost::CreateForTesting(ThreadInstance::IMPL), nullptr, 0,
+ nullptr, nullptr);
InputHandler::Create(static_cast<CompositorDelegateForInput&>(*host_impl_));
host_impl_->SetVisible(true);
@@ -18110,8 +18099,8 @@ TEST_F(LayerTreeHostImplTest, FrameElementIdHitTestOverlapRoundedCorners) {
// Add rounded corners to the layer, which are unable to be hit tested by the
// simple quad-based logic.
- CreateEffectNode(rounded_frame_layer).rounded_corner_bounds =
- gfx::RRectF(25, 25, 50, 50, 5);
+ CreateEffectNode(rounded_frame_layer).mask_filter_info =
+ gfx::MaskFilterInfo(gfx::RRectF(25, 25, 50, 50, 5));
UpdateDrawProperties(host_impl_->active_tree());
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
index 9100d9ea5b9..496bdbf6da9 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -202,7 +202,7 @@ class LayerTreeHostBlendingPixelTest
SkBitmap expected;
expected.allocN32Pixels(width, height);
- SkCanvas canvas(expected);
+ SkCanvas canvas(expected, SkSurfaceProps{});
canvas.clear(SK_ColorWHITE);
canvas.drawImage(surface->makeImageSnapshot(), 0, 0);
@@ -306,7 +306,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithRoot) {
SkBitmap expected;
expected.allocN32Pixels(kRootWidth, kRootHeight);
- SkCanvas canvas(expected);
+ SkCanvas canvas(expected, SkSurfaceProps{});
canvas.drawColor(kCSSOrange);
SkPaint paint;
paint.setBlendMode(current_blend_mode());
@@ -337,7 +337,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithBackdropFilter) {
SkBitmap expected;
expected.allocN32Pixels(kRootWidth, kRootHeight);
- SkCanvas canvas(expected);
+ SkCanvas canvas(expected, SkSurfaceProps{});
SkiaPaintCanvas paint_canvas(&canvas);
PaintFlags grayscale;
grayscale.setColor(kCSSOrange);
@@ -379,7 +379,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithTransparent) {
SkBitmap expected;
expected.allocN32Pixels(kRootWidth, kRootHeight);
- SkCanvas canvas(expected);
+ SkCanvas canvas(expected, SkSurfaceProps{});
canvas.drawColor(kCSSOrange);
SkPaint paint;
paint.setBlendMode(current_blend_mode());
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 880ec0a5bf5..3687e59cfa0 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -175,11 +175,11 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) {
float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
float percentage_pixels_small_error = 0.0f;
float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 1;
+ int large_error_allowed = 2;
int small_error_allowed = 0;
- // Windows using Dawn D3D12 has 2982 pixels off by 1.
+ // Windows using Dawn D3D12 has 4044 pixels off by max of 2.
if (use_d3d12())
- percentage_pixels_large_error = 1.864f; // 2982px / (400*400)
+ percentage_pixels_large_error = 2.5275f; // 4044px / (400*400)
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
percentage_pixels_large_error, percentage_pixels_small_error,
@@ -365,8 +365,10 @@ INSTANTIATE_TEST_SUITE_P(PixelResourceTest,
::testing::ValuesIn(viz::GetGpuRendererTypes()),
::testing::PrintToStringParamName());
+// TODO(michaelludwig): Re-enable after Skia roll and update expected images.
+// See skbug.com/9545
TEST_P(LayerTreeHostBlurFiltersPixelTestGPULayerList,
- BackdropFilterBlurOffAxis) {
+ DISABLED_BackdropFilterBlurOffAxis) {
#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
#if defined(OS_WIN)
// Windows has 116 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 95c904ca35e..63b1f719917 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc
@@ -58,12 +58,10 @@ class MaskContentLayerClient : public ContentLayerClient {
~MaskContentLayerClient() override = default;
bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting picture_control) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
display_list->StartPaint();
@@ -193,12 +191,10 @@ class SolidColorEmptyMaskContentLayerClient : public ContentLayerClient {
~SolidColorEmptyMaskContentLayerClient() override = default;
bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting picture_control) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
// Intentionally return a solid color, empty mask display list. This
// is a situation where all content should be masked out.
auto display_list = base::MakeRefCounted<DisplayItemList>();
@@ -332,8 +328,7 @@ TEST_P(LayerTreeHostMaskPixelTestWithLayerList, ImageMaskWithEffect) {
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(50, 50);
SkCanvas* canvas = surface->getCanvas();
scoped_refptr<DisplayItemList> mask_display_list =
- mask_client.PaintContentsToDisplayList(
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
+ mask_client.PaintContentsToDisplayList();
mask_display_list->Raster(canvas);
FakeContentLayerClient layer_client;
@@ -361,8 +356,7 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) {
SkCanvas* canvas = surface->getCanvas();
MaskContentLayerClient client(mask_bounds);
scoped_refptr<DisplayItemList> mask_display_list =
- client.PaintContentsToDisplayList(
- ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
+ client.PaintContentsToDisplayList();
mask_display_list->Raster(canvas);
FakeContentLayerClient mask_client;
@@ -447,10 +441,8 @@ class CheckerContentLayerClient : public ContentLayerClient {
: bounds_(bounds), color_(color), vertical_(vertical) {}
~CheckerContentLayerClient() override = default;
bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting picture_control) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
display_list->StartPaint();
@@ -496,10 +488,8 @@ class CircleContentLayerClient : public ContentLayerClient {
: bounds_(bounds) {}
~CircleContentLayerClient() override = default;
bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
gfx::Rect PaintableRegion() override { return gfx::Rect(bounds_); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting picture_control) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
display_list->StartPaint();
@@ -724,12 +714,10 @@ class StaticPictureLayer : private ContentLayerClient, public PictureLayer {
}
gfx::Rect PaintableRegion() override { return gfx::Rect(bounds()); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
return display_list_;
}
bool FillsBoundsCompletely() const override { return false; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
protected:
explicit StaticPictureLayer(scoped_refptr<DisplayItemList> display_list)
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 0cc4f38d0e1..d837df92f79 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -5,6 +5,7 @@
#include <stddef.h>
#include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
#include "cc/layers/content_layer_client.h"
#include "cc/layers/picture_layer.h"
#include "cc/paint/display_item_list.h"
@@ -48,6 +49,18 @@ class LayerTreeHostTilesPixelTest
target->RequestCopyOfOutput(CreateCopyOutputRequest());
}
+ void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override {
+ // Issue a GL finish before preparing tiles to ensure resources become
+ // available for use in a timely manner. Needed for the one-copy path.
+ viz::RasterContextProvider* context_provider =
+ host_impl->layer_tree_frame_sink()->worker_context_provider();
+ if (!context_provider)
+ return;
+
+ viz::RasterContextProvider::ScopedRasterContextLock lock(context_provider);
+ lock.RasterInterface()->Finish();
+ }
+
base::FilePath ref_file_;
std::unique_ptr<SkBitmap> result_bitmap_;
bool use_partial_raster_ = false;
@@ -59,8 +72,7 @@ class BlueYellowClient : public ContentLayerClient {
: size_(size), blue_top_(true) {}
gfx::Rect PaintableRegion() override { return gfx::Rect(size_); }
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting painting_status) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
display_list->StartPaint();
@@ -88,7 +100,6 @@ class BlueYellowClient : public ContentLayerClient {
}
bool FillsBoundsCompletely() const override { return true; }
- size_t GetApproximateUnsharedMemoryUsage() const override { return 0; }
void set_blue_top(bool b) { blue_top_ = b; }
@@ -131,21 +142,81 @@ class LayerTreeHostTilesTestPartialInvalidation
}
}
- void WillPrepareTilesOnThread(LayerTreeHostImpl* host_impl) override {
- // Issue a GL finish before preparing tiles to ensure resources become
- // available for use in a timely manner. Needed for the one-copy path.
- viz::RasterContextProvider* context_provider =
- host_impl->layer_tree_frame_sink()->worker_context_provider();
- if (!context_provider)
- return;
+ protected:
+ BlueYellowClient client_;
+ scoped_refptr<PictureLayer> picture_layer_;
+};
- viz::RasterContextProvider::ScopedRasterContextLock lock(context_provider);
- lock.RasterInterface()->Finish();
+class PrimaryColorClient : public ContentLayerClient {
+ public:
+ explicit PrimaryColorClient(const gfx::Size& size) : size_(size) {}
+
+ gfx::Rect PaintableRegion() override { return gfx::Rect(size_); }
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
+ // When painted, the DisplayItemList should produce blocks of red, green,
+ // and blue to test primary color reproduction.
+ auto display_list = base::MakeRefCounted<DisplayItemList>();
+
+ display_list->StartPaint();
+
+ int w = size_.width() / 3;
+ gfx::Rect red_rect(0, 0, w, size_.height());
+ gfx::Rect green_rect(w, 0, w, size_.height());
+ gfx::Rect blue_rect(w * 2, 0, w, size_.height());
+
+ PaintFlags flags;
+ flags.setStyle(PaintFlags::kFill_Style);
+
+ flags.setColor(SK_ColorRED);
+ display_list->push<DrawRectOp>(gfx::RectToSkRect(red_rect), flags);
+ flags.setColor(SK_ColorGREEN);
+ display_list->push<DrawRectOp>(gfx::RectToSkRect(green_rect), flags);
+ flags.setColor(SK_ColorBLUE);
+ display_list->push<DrawRectOp>(gfx::RectToSkRect(blue_rect), flags);
+
+ display_list->EndPaintOfUnpaired(PaintableRegion());
+ display_list->Finalize();
+ return display_list;
+ }
+
+ bool FillsBoundsCompletely() const override { return true; }
+
+ private:
+ gfx::Size size_;
+};
+
+class LayerTreeHostTilesTestRasterColorSpace
+ : public LayerTreeHostTilesPixelTest {
+ public:
+ LayerTreeHostTilesTestRasterColorSpace()
+ : client_(gfx::Size(150, 150)),
+ picture_layer_(PictureLayer::Create(&client_)) {
+ picture_layer_->SetBounds(gfx::Size(150, 150));
+ picture_layer_->SetIsDrawable(true);
+ }
+
+ void SetColorSpace(const gfx::ColorSpace& color_space) {
+ color_space_ = color_space;
+ }
+
+ void WillBeginTest() override {
+ LayerTreeHostTilesPixelTest::WillBeginTest();
+ DCHECK(color_space_.IsValid());
+ layer_tree_host()->SetDisplayColorSpaces(
+ gfx::DisplayColorSpaces(color_space_));
+ }
+
+ void DidCommitAndDrawFrame() override {
+ if (layer_tree_host()->SourceFrameNumber() == 1) {
+ Finish();
+ DoReadback();
+ }
}
protected:
- BlueYellowClient client_;
+ PrimaryColorClient client_;
scoped_refptr<PictureLayer> picture_layer_;
+ gfx::ColorSpace color_space_;
};
std::vector<RasterTestConfig> const kTestCases = {
@@ -169,7 +240,7 @@ INSTANTIATE_TEST_SUITE_P(All,
::testing::ValuesIn(kTestCases),
::testing::PrintToStringParamName());
-#if defined(OS_CHROMEOS) || defined(MEMORY_SANITIZER) || \
+#if BUILDFLAG(IS_CHROMEOS_ASH) || defined(MEMORY_SANITIZER) || \
defined(ADDRESS_SANITIZER) || defined(OS_FUCHSIA)
// TODO(crbug.com/1045521): Flakes on all slower bots.
#define MAYBE_PartialRaster DISABLED_PartialRaster
@@ -216,7 +287,7 @@ INSTANTIATE_TEST_SUITE_P(All,
#if (defined(OS_LINUX) || defined(OS_CHROMEOS)) && defined(THREAD_SANITIZER)
// Flaky on Linux TSAN. https://crbug.com/707711
#define MAYBE_PartialRaster DISABLED_PartialRaster
-#elif defined(OS_CHROMEOS) || defined(MEMORY_SANITIZER) || \
+#elif BUILDFLAG(IS_CHROMEOS_ASH) || defined(MEMORY_SANITIZER) || \
defined(ADDRESS_SANITIZER) || defined(OS_FUCHSIA)
// TODO(crbug.com/1045521): Flakes on all slower bots.
#define MAYBE_PartialRaster DISABLED_PartialRaster
@@ -237,6 +308,49 @@ TEST_P(LayerTreeHostTilesTestPartialInvalidationMultiThread, FullRaster) {
base::FilePath(FILE_PATH_LITERAL("blue_yellow_flipped.png")));
}
+INSTANTIATE_TEST_SUITE_P(All,
+ LayerTreeHostTilesTestRasterColorSpace,
+ ::testing::ValuesIn(kTestCases),
+ ::testing::PrintToStringParamName());
+
+// These tests verify that no artifacts are introduced when the color space for
+// rasterization doesn't contain the primary colors of sRGB.
+// See crbug.com/1073962 for more details.
+TEST_P(LayerTreeHostTilesTestRasterColorSpace, sRGB) {
+ SetColorSpace(gfx::ColorSpace::CreateSRGB());
+
+ RunPixelTest(picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("primary_colors.png")));
+}
+
+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")));
+}
+
+TEST_P(LayerTreeHostTilesTestRasterColorSpace, CustomColorSpace) {
+ // Create a color space with a different blue point.
+ SkColorSpacePrimaries primaries;
+ skcms_Matrix3x3 to_XYZD50;
+ primaries.fRX = 0.640f;
+ primaries.fRY = 0.330f;
+ primaries.fGX = 0.300f;
+ primaries.fGY = 0.600f;
+ primaries.fBX = 0.130f;
+ primaries.fBY = 0.080f;
+ primaries.fWX = 0.3127f;
+ primaries.fWY = 0.3290f;
+ primaries.toXYZD50(&to_XYZD50);
+ SetColorSpace(gfx::ColorSpace::CreateCustom(
+ to_XYZD50, gfx::ColorSpace::TransferID::IEC61966_2_1));
+
+ RunPixelTest(picture_layer_,
+ base::FilePath(FILE_PATH_LITERAL("primary_colors.png")));
+}
+
// This test doesn't work on Vulkan because on our hardware we can't render to
// RGBA4444 format using either SwiftShader or native Vulkan. See
// crbug.com/987278 for details
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 0bd998b5544..163146ca91e 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -11,7 +11,7 @@
#include "base/auto_reset.h"
#include "base/bind.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
@@ -2897,13 +2897,6 @@ MULTI_THREAD_BLOCKNOTIFY_TEST_F(
// its damage is preserved until the next time it is drawn.
class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest {
public:
- void InitializeSettings(LayerTreeSettings* settings) override {
- // If we don't set the minimum contents scale, it's harder to verify whether
- // the damage we get is correct. For other scale amounts, please see
- // LayerTreeHostTestDamageWithScale.
- settings->minimum_contents_scale = 1.f;
- }
-
void SetupTree() override {
root_layer_ = FakePictureLayer::Create(&client_);
root_layer_->SetIsDrawable(true);
@@ -3751,15 +3744,17 @@ SINGLE_AND_MULTI_THREAD_TEST_F(
// updates, i.e. abort commits after the paint stage and only request layer
// tree updates for layout.
//
-// The tests sends four Begin(Main)Frames in sequence: three animate_only
-// Begin(Main)Frames followed by a normal Begin(Main)Frame. The first three
-// should result in aborted commits, whereas the last one should complete the
+// The tests sends five Begin(Main)Frames in sequence: four animate_only
+// Begin(Main)Frames followed by a normal Begin(Main)Frame. The first frame
+// has animate_only force to false by CompositorFrameSinkSupport, since it
+// needs a complete frame to assure surface activation. Frames 2-4 should
+// result in aborted commits, whereas the last one should complete the
// previously aborted commits.
//
-// Between BeginMainFrames 2 and 3, the client also requests a new commit
-// (SetNeedsCommit), but not between BeginMainFrames 1 and 2. In multi-threaded
+// Between BeginMainFrames 3 and 4, the client also requests a new commit
+// (SetNeedsCommit), but not between BeginMainFrames 1-3. In multi-threaded
// mode, ProxyMain will run the animate pipeline stage only for BeginMainFrames
-// 1 and 3, as no new commit was requested between 1 and 2.
+// 2 and 4, as no new commit was requested between 2 and 3.
//
// The test uses the full-pipeline mode to ensure that each BeginFrame also
// incurs a BeginMainFrame.
@@ -3816,31 +3811,52 @@ class LayerTreeHostTestAnimateOnlyBeginFrames
void DidSendBeginMainFrameOnThread(LayerTreeHostImpl* host_impl) override {
++sent_begin_main_frame_count_;
- EXPECT_EQ(begin_frame_count_, sent_begin_main_frame_count_);
+ EXPECT_GE(begin_frame_count_, sent_begin_main_frame_count_);
+ }
+
+ void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl,
+ const viz::BeginFrameArgs& args) override {
+ EXPECT_EQ(args.animate_only,
+ (begin_frame_count_ >= 2 && begin_frame_count_ <= 4));
}
void DidFinishImplFrameOnThread(LayerTreeHostImpl* host_impl) override {
+ EXPECT_LE(sent_begin_main_frame_count_, begin_frame_count_);
if (begin_frame_count_ < 3) {
- if (begin_frame_count_ == 2) {
- // Request another commit before sending the third BeginMainFrame.
- PostSetNeedsCommitToMainThread();
- }
-
// Send another animation_only BeginFrame.
PostIssueBeginFrame(true);
} else if (begin_frame_count_ == 3) {
+ MainThreadTaskRunner()->PostTaskAndReply(
+ FROM_HERE,
+ base::BindOnce(&LayerTreeHostTestAnimateOnlyBeginFrames::
+ SetNeedsCommitOnMainThread,
+ base::Unretained(this)),
+ base::BindOnce(
+ &LayerTreeHostTestAnimateOnlyBeginFrames::PostIssueBeginFrame,
+ base::Unretained(this), true));
+ } else if (begin_frame_count_ == 4) {
PostIssueBeginFrame(false);
}
}
+ void SetNeedsCommitOnMainThread() { layer_tree_host()->SetNeedsCommit(); }
+
void UpdateLayerTreeHost() override { ++update_layer_tree_host_count_; }
- void DidCommit() override {
+ void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
+ if (begin_frame_count_ == 1)
+ host_impl->NotifyReadyToDraw();
+
++commit_count_;
+ // First commit is due to first frame having animate_only forced to false
+ // in ordser to create the surface.
+ if (commit_count_ == 1)
+ return;
+
// Fourth BeginMainFrame should lead to commit.
- EXPECT_EQ(4, begin_frame_count_);
- EXPECT_EQ(4, sent_begin_main_frame_count_);
+ EXPECT_EQ(5, begin_frame_count_);
+ EXPECT_EQ(3, sent_begin_main_frame_count_);
EndTest();
}
@@ -3850,23 +3866,15 @@ class LayerTreeHostTestAnimateOnlyBeginFrames
}
void AfterTest() override {
- EXPECT_EQ(1, commit_count_);
- EXPECT_EQ(4, begin_frame_count_);
- EXPECT_EQ(4, sent_begin_main_frame_count_);
-
- if (HasImplThread()) {
- // ProxyMain aborts the second BeginMainFrame before running the animate
- // pipeline stage, since no further updates were made since the first one.
- // Thus, we expect not to be called for the second BeginMainFrame.
- EXPECT_EQ(3, will_begin_main_frame_count_);
- EXPECT_EQ(3, update_layer_tree_host_count_);
- } else {
- EXPECT_EQ(4, will_begin_main_frame_count_);
- EXPECT_EQ(4, update_layer_tree_host_count_);
- }
+ EXPECT_EQ(2, commit_count_);
+ EXPECT_EQ(5, begin_frame_count_);
+ EXPECT_EQ(3, sent_begin_main_frame_count_);
+
+ EXPECT_EQ(3, will_begin_main_frame_count_);
+ EXPECT_EQ(3, update_layer_tree_host_count_);
// The final commit should not have been aborted.
- EXPECT_EQ(1, ready_to_commit_count_);
+ EXPECT_EQ(2, ready_to_commit_count_);
}
protected:
@@ -6726,7 +6734,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
new TestSwapPromise(&swap_promise_result_[0]));
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise0));
- layer_tree_host()->Composite(base::TimeTicks::Now(), raster);
+ layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
// Fail to swap (no damage) if not reclaiming resources from the Display.
std::unique_ptr<SwapPromise> swap_promise1(
@@ -6734,7 +6742,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise(
std::move(swap_promise1));
layer_tree_host()->SetNeedsCommit();
- layer_tree_host()->Composite(base::TimeTicks::Now(), raster);
+ layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
// Fail to draw (not visible).
std::unique_ptr<SwapPromise> swap_promise2(
@@ -6743,7 +6751,7 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise
std::move(swap_promise2));
layer_tree_host()->SetNeedsDisplayOnAllLayers();
layer_tree_host()->SetVisible(false);
- layer_tree_host()->Composite(base::TimeTicks::Now(), raster);
+ layer_tree_host()->CompositeForTest(base::TimeTicks::Now(), raster);
EndTest();
}
@@ -7985,7 +7993,7 @@ class LayerTreeHostTestQueueImageDecode : public LayerTreeHostTest {
return;
first_ = false;
- image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)),
+ image_ = DrawImage(CreateDiscardablePaintImage(gfx::Size(400, 400)), false,
SkIRect::MakeWH(400, 400), kNone_SkFilterQuality,
SkMatrix::I(), PaintImage::kDefaultFrameIndex,
gfx::ColorSpace());
@@ -8911,6 +8919,7 @@ class LayerTreeHostTestDelegatedInkMetadataOnAndOff
void DrawLayersOnThread(LayerTreeHostImpl* impl) override {
if (expected_metadata_.has_value()) {
+ EXPECT_EQ(metadata_frame_time_, impl->CurrentBeginFrameArgs().frame_time);
// Now try again with no metadata to confirm everything is cleared out.
expected_metadata_.reset();
}
@@ -8927,6 +8936,11 @@ class LayerTreeHostTestDelegatedInkMetadataOnAndOff
EXPECT_EQ(expected_metadata_->presentation_area(),
actual_metadata->presentation_area());
EXPECT_EQ(expected_metadata_->timestamp(), actual_metadata->timestamp());
+
+ // Record the frame time from the metadata so we can confirm that it
+ // matches the LayerTreeHostImpl's frame time in DrawLayersOnThread.
+ EXPECT_GT(actual_metadata->frame_time(), base::TimeTicks::Min());
+ metadata_frame_time_ = actual_metadata->frame_time();
} else {
EXPECT_FALSE(had_delegated_ink_metadata);
EXPECT_FALSE(actual_metadata);
@@ -8949,6 +8963,7 @@ class LayerTreeHostTestDelegatedInkMetadataOnAndOff
FakeContentLayerClient client_;
scoped_refptr<Layer> layer_;
bool set_needs_display_ = true;
+ base::TimeTicks metadata_frame_time_;
};
SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDelegatedInkMetadataOnAndOff);
@@ -8984,12 +8999,23 @@ class LayerTreeHostTestEventsMetrics : public LayerTreeHostTest {
private:
void SimulateEventOnMain() {
- auto scoped_event_monitor =
- layer_tree_host()->GetScopedEventMetricsMonitor(EventMetrics::Create(
- ui::ET_GESTURE_SCROLL_UPDATE,
- EventMetrics::ScrollUpdateType::kContinued, base::TimeTicks::Now(),
- ui::ScrollInputType::kWheel));
- layer_tree_host()->SetNeedsAnimate();
+ std::unique_ptr<EventMetrics> metrics = EventMetrics::Create(
+ ui::ET_GESTURE_SCROLL_UPDATE,
+ EventMetrics::ScrollUpdateType::kContinued, base::TimeTicks::Now(),
+ ui::ScrollInputType::kWheel);
+ {
+ auto done_callback = base::BindOnce(
+ [](std::unique_ptr<EventMetrics> metrics, bool handled) {
+ std::unique_ptr<EventMetrics> result =
+ handled ? std::move(metrics) : nullptr;
+ return result;
+ },
+ std::move(metrics));
+ auto scoped_event_monitor =
+ layer_tree_host()->GetScopedEventMetricsMonitor(
+ std::move(done_callback));
+ layer_tree_host()->SetNeedsAnimate();
+ }
EXPECT_SCOPED(VerifyMainSavedEventsMetricsCountOnMain(1));
}
@@ -9344,7 +9370,7 @@ class LayerTreeHostUkmSmoothnessMetric : public LayerTreeTest {
}
// Mark every frame as a dropped frame affecting smoothness.
- host_impl->dropped_frame_counter()->AddDroppedFrameAffectingSmoothness();
+ host_impl->dropped_frame_counter()->OnEndFrame(viz::BeginFrameArgs(), true);
host_impl->SetNeedsRedraw();
--frames_counter_;
}
@@ -9390,7 +9416,7 @@ class LayerTreeHostUkmSmoothnessMemoryOwnership : public LayerTreeTest {
}
// Mark every frame as a dropped frame affecting smoothness.
- host_impl->dropped_frame_counter()->AddDroppedFrameAffectingSmoothness();
+ host_impl->dropped_frame_counter()->OnEndFrame(viz::BeginFrameArgs(), true);
host_impl->SetNeedsRedraw();
--frames_counter_;
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
index 785d8265fa6..c7bf7b5b3cf 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_capture_content.cc
@@ -32,8 +32,7 @@ class FakeCaptureContentLayerClient : public FakeContentLayerClient {
holders_.push_back(holder);
}
- scoped_refptr<DisplayItemList> PaintContentsToDisplayList(
- PaintingControlSetting painting_control) override {
+ scoped_refptr<DisplayItemList> PaintContentsToDisplayList() override {
auto display_list = base::MakeRefCounted<DisplayItemList>();
for (auto& holder : holders_) {
display_list->StartPaint();
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index 9df178c8b29..b679607a722 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -468,8 +468,8 @@ class MultipleCompositeDoesNotCreateLayerTreeFrameSink
}
void BeginTest() override {
- layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
- layer_tree_host()->Composite(TicksFromMicroseconds(2), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(1), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(2), false);
}
void DidInitializeLayerTreeFrameSink() override { EXPECT_TRUE(false); }
@@ -510,12 +510,12 @@ class FailedCreateDoesNotCreateExtraLayerTreeFrameSink
void BeginTest() override {
// First composite tries to create a surface.
- layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(1), false);
EXPECT_EQ(num_requests_, 2);
EXPECT_TRUE(has_failed_);
// Second composite should not request or fail.
- layer_tree_host()->Composite(TicksFromMicroseconds(2), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(2), false);
EXPECT_EQ(num_requests_, 2);
EndTest();
}
@@ -561,7 +561,7 @@ class LayerTreeHostContextTestCommitAfterDelayedLayerTreeFrameSink
}
void BeginTest() override {
- layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(1), false);
}
void ScheduleComposite() override {
@@ -594,7 +594,7 @@ class LayerTreeHostContextTestAvoidUnnecessaryComposite
void BeginTest() override {
in_composite_ = true;
- layer_tree_host()->Composite(TicksFromMicroseconds(1), false);
+ layer_tree_host()->CompositeForTest(TicksFromMicroseconds(1), false);
in_composite_ = false;
}
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 108efa6939a..d6fbf463ba1 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -187,8 +187,16 @@ TEST_P(LayerTreeHostCopyRequestTestMultipleRequests, Test) {
// which causes callbacks for sync queries to be sent in reverse order.
class LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder
: public LayerTreeHostCopyRequestTestMultipleRequests {
+ std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
+ CreateDisplayControllerOnThread() override {
+ // In this implementation, none of the output surface has a real gpu thread,
+ // and there is no overlay support.
+ return nullptr;
+ }
+
std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread() override {
+ CreateDisplaySkiaOutputSurfaceOnThread(
+ viz::DisplayCompositorMemoryAndTaskController*) override {
auto skia_output_surface = viz::FakeSkiaOutputSurface::Create3d();
skia_output_surface->SetOutOfOrderCallbacks(true);
return skia_output_surface;
@@ -824,8 +832,15 @@ TEST_P(LayerTreeHostTestAsyncTwoReadbacksWithoutDraw, Test) {
class LayerTreeHostCopyRequestTestDeleteSharedImage
: public LayerTreeHostCopyRequestTest {
protected:
+ std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
+ CreateDisplayControllerOnThread() override {
+ // In this implementation, none of the output surface has a real gpu thread,
+ // and there is no overlay support.
+ return nullptr;
+ }
std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread() override {
+ CreateDisplaySkiaOutputSurfaceOnThread(
+ viz::DisplayCompositorMemoryAndTaskController*) override {
display_context_provider_ = viz::TestContextProvider::Create();
display_context_provider_->BindToCurrentThread();
return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
@@ -967,8 +982,15 @@ TEST_P(LayerTreeHostCopyRequestTestDeleteSharedImage, Test) {
class LayerTreeHostCopyRequestTestCountSharedImages
: public LayerTreeHostCopyRequestTest {
protected:
+ std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
+ CreateDisplayControllerOnThread() override {
+ // In this implementation, none of the output surface has a real gpu thread,
+ // and there is no overlay support.
+ return nullptr;
+ }
std::unique_ptr<viz::SkiaOutputSurface>
- CreateDisplaySkiaOutputSurfaceOnThread() override {
+ CreateDisplaySkiaOutputSurfaceOnThread(
+ viz::DisplayCompositorMemoryAndTaskController*) override {
display_context_provider_ = viz::TestContextProvider::Create();
display_context_provider_->BindToCurrentThread();
return viz::FakeSkiaOutputSurface::Create3d(display_context_provider_);
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index 256ab69ea1a..cb9d1d174d5 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -559,7 +559,7 @@ void LayerTreeImpl::PushPropertyTreesTo(LayerTreeImpl* target_tree) {
target_tree->SetPropertyTrees(&property_trees_);
- std::vector<EventMetrics> events_metrics;
+ EventMetrics::List events_metrics;
events_metrics.swap(events_metrics_from_main_thread_);
target_tree->AppendEventsMetricsFromMainThread(std::move(events_metrics));
}
@@ -2629,16 +2629,17 @@ LayerTreeImpl::TakePendingPageScaleAnimation() {
}
void LayerTreeImpl::AppendEventsMetricsFromMainThread(
- std::vector<EventMetrics> events_metrics) {
+ EventMetrics::List events_metrics) {
events_metrics_from_main_thread_.reserve(
events_metrics_from_main_thread_.size() + events_metrics.size());
events_metrics_from_main_thread_.insert(
- events_metrics_from_main_thread_.end(), events_metrics.begin(),
- events_metrics.end());
+ events_metrics_from_main_thread_.end(),
+ std::make_move_iterator(events_metrics.begin()),
+ std::make_move_iterator(events_metrics.end()));
}
-std::vector<EventMetrics> LayerTreeImpl::TakeEventsMetrics() {
- std::vector<EventMetrics> main_event_metrics_result;
+EventMetrics::List LayerTreeImpl::TakeEventsMetrics() {
+ EventMetrics::List main_event_metrics_result;
main_event_metrics_result.swap(events_metrics_from_main_thread_);
return main_event_metrics_result;
}
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 024a56c721f..b1638ab1490 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -658,9 +658,8 @@ class CC_EXPORT LayerTreeImpl {
std::unique_ptr<PendingPageScaleAnimation> pending_animation);
std::unique_ptr<PendingPageScaleAnimation> TakePendingPageScaleAnimation();
- void AppendEventsMetricsFromMainThread(
- std::vector<EventMetrics> events_metrics);
- std::vector<EventMetrics> TakeEventsMetrics();
+ void AppendEventsMetricsFromMainThread(EventMetrics::List events_metrics);
+ EventMetrics::List TakeEventsMetrics();
// Requests that we force send RenderFrameMetadata with the next frame.
void RequestForceSendMetadata() { force_send_metadata_request_ = true; }
@@ -726,6 +725,10 @@ class CC_EXPORT LayerTreeImpl {
return host_impl_->DrawTransform();
}
+ bool IsInSynchronousComposite() const {
+ return host_impl_->IsInSynchronousComposite();
+ }
+
// These functions are used for plumbing DelegatedInkMetadata from blink
// through the compositor and into viz via a compositor frame. They should
// only be called after the JS API |updateInkTrailStartPoint| has been
@@ -892,7 +895,7 @@ class CC_EXPORT LayerTreeImpl {
std::vector<LayerTreeHost::PresentationTimeCallback> presentation_callbacks_;
// Event metrics that are reported back from the main thread.
- std::vector<EventMetrics> events_metrics_from_main_thread_;
+ EventMetrics::List events_metrics_from_main_thread_;
std::unique_ptr<viz::DelegatedInkMetadata> delegated_ink_metadata_;
};
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index e5a58655788..3d411412c72 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -59,12 +59,10 @@ class CC_EXPORT LayerTreeSettings {
base::TimeDelta scrollbar_fade_duration;
base::TimeDelta scrollbar_thinning_duration;
bool scrollbar_flash_after_any_scroll_update = false;
- bool scrollbar_flash_when_mouse_enter = false;
SkColor solid_color_scrollbar_color = SK_ColorWHITE;
base::TimeDelta scroll_animation_duration_for_testing;
bool timeout_and_draw_when_animation_checkerboards = true;
bool layers_always_allowed_lcd_text = false;
- float minimum_contents_scale = 0.0625f;
float low_res_contents_scale_factor = 0.25f;
float top_controls_show_threshold = 0.5f;
float top_controls_hide_threshold = 0.5f;
diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc
index 7a6bf2068f6..b3ed41e48f5 100644
--- a/chromium/cc/trees/occlusion_tracker.cc
+++ b/chromium/cc/trees/occlusion_tracker.cc
@@ -350,7 +350,7 @@ void OcclusionTracker::MarkOccludedBehindLayer(const LayerImpl* layer) {
if (layer->Is3dSorted())
return;
- if (!layer->draw_properties().rounded_corner_bounds.IsEmpty())
+ if (!layer->draw_properties().mask_filter_info.IsEmpty())
return;
SimpleEnclosedRegion opaque_layer_region = layer->VisibleOpaqueRegion();
diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc
index c2dafbd27dd..ebe12ad0073 100644
--- a/chromium/cc/trees/occlusion_tracker_unittest.cc
+++ b/chromium/cc/trees/occlusion_tracker_unittest.cc
@@ -924,8 +924,8 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest {
filters.Append(FilterOperation::CreateOpacityFilter(0.5f));
GetEffectNode(opacity_layer)->filters = filters;
- CreateEffectNode(rounded_corner_layer).rounded_corner_bounds =
- gfx::RRectF(1, 2, 3, 4, 5, 6);
+ CreateEffectNode(rounded_corner_layer).mask_filter_info =
+ gfx::MaskFilterInfo(gfx::RRectF(1, 2, 3, 4, 5, 6));
this->CalcDrawEtc();
EXPECT_TRUE(rounded_corner_layer->contributes_to_drawn_render_surface());
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index a4a770d1948..d9da2f91bcc 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -344,6 +344,11 @@ gfx::Vector2dF TransformTree::StickyPositionOffset(TransformNode* node) {
gfx::Vector2dF ancestor_sticky_box_offset;
if (sticky_data->nearest_node_shifting_sticky_box !=
TransformTree::kInvalidNodeId) {
+ // TODO(crbug.com/1128479): Investigate why there would be an invalid index
+ // passed in. Early return for now.
+ if (sticky_data->nearest_node_shifting_sticky_box >=
+ static_cast<int>(property_trees()->transform_tree.size()))
+ return gfx::Vector2dF();
const StickyPositionNodeData* ancestor_sticky_data =
GetStickyPositionData(sticky_data->nearest_node_shifting_sticky_box);
DCHECK(ancestor_sticky_data);
@@ -354,6 +359,11 @@ gfx::Vector2dF TransformTree::StickyPositionOffset(TransformNode* node) {
gfx::Vector2dF ancestor_containing_block_offset;
if (sticky_data->nearest_node_shifting_containing_block !=
TransformTree::kInvalidNodeId) {
+ // TODO(crbug.com/1128479): Investigate why there would be an invalid index
+ // passed in. Early return for now.
+ if (sticky_data->nearest_node_shifting_containing_block >=
+ static_cast<int>(property_trees()->transform_tree.size()))
+ return gfx::Vector2dF();
const StickyPositionNodeData* ancestor_sticky_data = GetStickyPositionData(
sticky_data->nearest_node_shifting_containing_block);
DCHECK(ancestor_sticky_data);
@@ -1137,7 +1147,7 @@ bool EffectTree::HitTestMayBeAffectedByMask(int effect_id) const {
const EffectNode* effect_node = Node(effect_id);
for (; effect_node->id != kContentsRootNodeId;
effect_node = Node(effect_node->parent_id)) {
- if (!effect_node->rounded_corner_bounds.IsEmpty() ||
+ if (!effect_node->mask_filter_info.IsEmpty() ||
effect_node->has_masking_child)
return true;
}
diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc
index ab2eb2f52d1..d0f5851130c 100644
--- a/chromium/cc/trees/property_tree_builder.cc
+++ b/chromium/cc/trees/property_tree_builder.cc
@@ -7,7 +7,9 @@
#include <stddef.h>
#include <map>
+#include <memory>
#include <set>
+#include <utility>
#include "base/auto_reset.h"
#include "cc/base/math_util.h"
@@ -165,10 +167,6 @@ bool LayerClipsSubtree(Layer* layer) {
!layer->clip_rect().IsEmpty();
}
-gfx::RRectF RoundedCornerBounds(Layer* layer) {
- return gfx::RRectF(layer->EffectiveClipRect(), layer->corner_radii());
-}
-
void PropertyTreeBuilderContext::AddClipNodeIfNeeded(
const DataForRecursion& data_from_ancestor,
Layer* layer,
@@ -491,7 +489,8 @@ bool PropertyTreeBuilderContext::AddEffectNodeIfNeeded(
// This is currently in the local space of the layer and hence in an invalid
// space. Once we have the associated transform node for this effect node,
// we will update this to the transform node's coordinate space.
- node->rounded_corner_bounds = RoundedCornerBounds(layer);
+ node->mask_filter_info =
+ gfx::MaskFilterInfo(layer->EffectiveClipRect(), layer->corner_radii());
node->is_fast_rounded_corner = layer->is_fast_rounded_corner();
}
@@ -557,7 +556,8 @@ bool PropertyTreeBuilderContext::UpdateRenderSurfaceIfNeeded(
EffectNode* effect_node =
effect_tree_.Node(data_for_children->effect_tree_parent);
- const bool has_rounded_corner = !effect_node->rounded_corner_bounds.IsEmpty();
+ const bool has_rounded_corner =
+ effect_node->mask_filter_info.HasRoundedCorners();
// Having a rounded corner should trigger a transform node.
if (has_rounded_corner)
diff --git a/chromium/cc/trees/property_tree_builder_unittest.cc b/chromium/cc/trees/property_tree_builder_unittest.cc
index 243de4063b5..c824607608b 100644
--- a/chromium/cc/trees/property_tree_builder_unittest.cc
+++ b/chromium/cc/trees/property_tree_builder_unittest.cc
@@ -859,7 +859,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// Since this effect node has no descendants that draw and no descendant that
// has a rounded corner, it does not need a render surface.
const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -869,7 +870,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// Since this node has descendants with roudned corners, it needs a render
// surface. It also has 2 descendants that draw.
effect_node = GetEffectNode(rounded_corner_layer_2.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -879,7 +881,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// Since this node has a descendant that has a rounded corner, it will trigger
// the creation of a render surface.
effect_node = GetEffectNode(rounded_corner_layer_3.get());
- gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_3 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
kRoundedCorner3Radius);
@@ -889,7 +892,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// Since this node has no descendants that draw nor any descendant that has a
// rounded corner, it does not need a render surface.
effect_node = GetEffectNode(rounded_corner_layer_4.get());
- gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_4 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
kRoundedCorner4Radius);
@@ -918,7 +922,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// scale factor is 1.6 thus giving the target space origin of [24, 24]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_rrect_1 =
- rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_1_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
@@ -931,13 +936,16 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// scale factor is 1.6 thus giving the target space origin of [64, 64]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_2 =
- rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_2_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_2.IsEmpty());
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_2 =
- rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_2_impl->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(),
kRoundedCorner2Radius * kDeviceScale);
@@ -948,7 +956,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// device scale factor is 1.6 thus giving the target space origin of [64, 88].
// The corner radius is also scaled by a factor of 1.6 * transform scale.
const gfx::RRectF actual_self_rrect_3 =
- rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_3_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
bounds_in_target_space = kRoundedCornerLayer3Bound;
@@ -960,7 +969,9 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
bounds_in_target_space.set_size(transformed_size);
const gfx::RRectF actual_render_target_rrect_3 =
- rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_3_impl->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale);
@@ -972,7 +983,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
// rigin of [3.2, 3.2].
// The corner radius is also scaled by a factor of 3.2.
const gfx::RRectF actual_rrect_4 =
- rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_4_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer4Bound;
bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale);
EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space);
@@ -1042,7 +1054,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) {
// that has a rounded corner before the render surface, it does not need a
// render surface.
const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -1052,7 +1065,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) {
// Since this effect node has no descendants that draw and no descendant that
// has a rounded corner, it does not need a render surface.
effect_node = GetEffectNode(rounded_corner_layer_2.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -1077,7 +1091,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) {
// scale factor is 1.6 thus giving the target space origin of [96, 0]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_rrect_1 =
- rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_1_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
@@ -1088,7 +1103,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) {
// The render target for this layer is |render_surface|.
// The offset from the origin of the render target is [0, 0].
const gfx::RRectF actual_rrect_2 =
- rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_2_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space);
@@ -1157,7 +1173,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) {
// Since this effect node has 1 descendant with a rounded corner without a
// render surface along the chain, it need a render surface.
const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
kRoundedCorner1Radius);
@@ -1167,7 +1184,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) {
// Since this effect node has no descendants that draw and no descendant that
// has a rounded corner, it does not need a render surface.
effect_node = GetEffectNode(rounded_corner_layer_2.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
kRoundedCorner2Radius);
@@ -1192,13 +1210,16 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) {
// scale factor is 1.6 thus giving the target space origin of [0, 96]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_1 =
- rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_1_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_1 =
- rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_1_impl->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
kRoundedCorner1Radius * kDeviceScale);
@@ -1207,7 +1228,8 @@ TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) {
// The render target for this layer is |render_surface|.
// The offset from the origin of the render target is [0, 0].
const gfx::RRectF actual_rrect_2 =
- rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_2_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space);
@@ -1297,7 +1319,8 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// surface even though it has 2 layers in the subtree that draws content.
const EffectNode* effect_node =
GetEffectNode(fast_rounded_corner_layer.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
@@ -1307,7 +1330,8 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// Since this node has 2 descendants that draw, it will have a rounded corner.
effect_node = GetEffectNode(rounded_corner_layer.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
@@ -1336,7 +1360,8 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// The offset from the origin of the render target is [0, 0] and the device
// scale factor is 1.6.
const gfx::RRectF actual_rrect_1 =
- fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds;
+ fast_rounded_corner_layer_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
@@ -1347,9 +1372,9 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// This should have the same rounded corner boudns as fast rounded corner
// layer.
const gfx::RRectF layer_1_rrect =
- layer_1_impl->draw_properties().rounded_corner_bounds;
+ layer_1_impl->draw_properties().mask_filter_info.rounded_corner_bounds();
const gfx::RRectF layer_2_rrect =
- layer_2_impl->draw_properties().rounded_corner_bounds;
+ layer_2_impl->draw_properties().mask_filter_info.rounded_corner_bounds();
EXPECT_EQ(actual_rrect_1, layer_1_rrect);
EXPECT_EQ(actual_rrect_1, layer_2_rrect);
@@ -1359,13 +1384,16 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// scale factor is 1.6 thus giving the target space origin of [64, 64]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_2 =
- rounded_corner_layer_impl->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_2.IsEmpty());
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_2 =
- rounded_corner_layer_impl->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_impl->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(),
kRoundedCorner2Radius * kDeviceScale);
@@ -1373,9 +1401,9 @@ TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
// Layer 3 and layer 4 should have no rounded corner bounds set as their
// parent is a render surface.
const gfx::RRectF layer_3_rrect =
- layer_3_impl->draw_properties().rounded_corner_bounds;
+ layer_3_impl->draw_properties().mask_filter_info.rounded_corner_bounds();
const gfx::RRectF layer_4_rrect =
- layer_4_impl->draw_properties().rounded_corner_bounds;
+ layer_4_impl->draw_properties().mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(layer_3_rrect.IsEmpty());
EXPECT_TRUE(layer_4_rrect.IsEmpty());
}
@@ -1462,7 +1490,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has a descendant that has rounded corner, this node will
// require a render surface.
const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
@@ -1473,7 +1502,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has no descendant with rounded corner or drawable, it will
// not have a render surface.
effect_node = GetEffectNode(fast_rounded_corner_layer_2.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
@@ -1484,7 +1514,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has 1 descendant with a rounded corner, it should have a
// render surface.
effect_node = GetEffectNode(rounded_corner_layer_3.get());
- gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_3 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
@@ -1494,7 +1525,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer no descendants, it would no thave a render pass.
effect_node = GetEffectNode(rounded_corner_layer_4.get());
- gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_4 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
@@ -1523,13 +1555,16 @@ TEST_F(PropertyTreeBuilderTest,
// The offset from the origin of the render target is [5, 5] and the device
// scale factor is 1.6 giving a total offset of [8, 8].
const gfx::RRectF actual_self_rrect_1 =
- rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_1->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_1 =
- rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_impl_1->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
kRoundedCorner1Radius * kDeviceScale);
@@ -1539,7 +1574,8 @@ TEST_F(PropertyTreeBuilderTest,
// The offset from the origin of the render target is [0, 0] and the device
// scale factor is 1.6. The corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_2 =
- fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds;
+ fast_rounded_corner_layer_impl_2->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space);
@@ -1552,13 +1588,16 @@ TEST_F(PropertyTreeBuilderTest,
// scale factor is 1.6 thus giving the target space origin of [64, 64]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_3 =
- rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_3->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
bounds_in_target_space = kRoundedCornerLayer3Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_3 =
- rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_impl_3->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
kRoundedCorner3Radius * kDeviceScale);
@@ -1569,7 +1608,8 @@ TEST_F(PropertyTreeBuilderTest,
// scale factor is 1.6 thus giving the target space origin of [48, 0]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_4 =
- rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_4->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer4Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space);
@@ -1658,7 +1698,8 @@ TEST_F(PropertyTreeBuilderTest,
// surface.
const EffectNode* effect_node =
GetEffectNode(fast_rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_1 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_TRUE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
@@ -1669,7 +1710,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has no descendant with rounded corner or drawable, it will
// not have a render surface.
effect_node = GetEffectNode(rounded_corner_layer_1.get());
- gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_2 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
@@ -1680,7 +1722,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has a descendant with rounded corner, it should have a
// render surface.
effect_node = GetEffectNode(rounded_corner_layer_2.get());
- gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_3 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
@@ -1690,7 +1733,8 @@ TEST_F(PropertyTreeBuilderTest,
// Since this layer has no descendant, it does not need a render surface.
effect_node = GetEffectNode(rounded_corner_layer_3.get());
- gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
+ gfx::RRectF rounded_corner_bounds_4 =
+ effect_node->mask_filter_info.rounded_corner_bounds();
EXPECT_FALSE(effect_node->HasRenderSurface());
EXPECT_FALSE(effect_node->is_fast_rounded_corner);
EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
@@ -1719,14 +1763,16 @@ TEST_F(PropertyTreeBuilderTest,
// The offset from the origin of the render target is [5, 5] and the device
// scale factor is 1.6.
const gfx::RRectF actual_self_rrect_1 =
- fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
+ fast_rounded_corner_layer_impl_1->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_1 =
fast_rounded_corner_layer_impl_1->render_target()
- ->rounded_corner_bounds();
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
kRoundedCorner1Radius * kDeviceScale);
@@ -1736,7 +1782,8 @@ TEST_F(PropertyTreeBuilderTest,
// The offset from the origin of the render target is [0, 0] and the device
// scale factor is 1.6. The corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_2 =
- rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_1->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer2Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space);
@@ -1749,13 +1796,16 @@ TEST_F(PropertyTreeBuilderTest,
// scale factor is 1.6 thus giving the target space origin of [8, 8]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_3 =
- rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_2->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
bounds_in_target_space = kRoundedCornerLayer3Bound;
bounds_in_target_space.Scale(kDeviceScale);
const gfx::RRectF actual_render_target_rrect_3 =
- rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds();
+ rounded_corner_layer_impl_2->render_target()
+ ->mask_filter_info()
+ .rounded_corner_bounds();
EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
kRoundedCorner3Radius * kDeviceScale);
@@ -1766,7 +1816,8 @@ TEST_F(PropertyTreeBuilderTest,
// scale factor is 1.6 thus giving the target space origin of [0, 8]. The
// corner radius is also scaled by a factor of 1.6.
const gfx::RRectF actual_self_rrect_4 =
- rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds;
+ rounded_corner_layer_impl_3->draw_properties()
+ .mask_filter_info.rounded_corner_bounds();
bounds_in_target_space = kRoundedCornerLayer4Bound;
bounds_in_target_space.Scale(kDeviceScale);
EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space);
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index eefabd96dfb..13cccd11026 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -16,6 +16,7 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
+#include "cc/base/features.h"
#include "cc/benchmarks/benchmark_instrumentation.h"
#include "cc/input/browser_controls_offset_manager.h"
#include "cc/metrics/compositor_timing_history.h"
@@ -78,6 +79,7 @@ ProxyImpl::ProxyImpl(base::WeakPtr<ProxyMain> proxy_main_weak_ptr,
host_impl_ = layer_tree_host->CreateLayerTreeHostImpl(this);
const LayerTreeSettings& settings = layer_tree_host->GetSettings();
send_compositor_frame_ack_ = settings.send_compositor_frame_ack;
+ last_raster_priority_ = SAME_PRIORITY_FOR_BOTH_TREES;
SchedulerSettings scheduler_settings(settings.ToSchedulerSettings());
@@ -244,6 +246,10 @@ void ProxyImpl::RequestBeginMainFrameNotExpected(bool new_state) {
scheduler_->SetMainThreadWantsBeginMainFrameNotExpected(new_state);
}
+bool ProxyImpl::IsInSynchronousComposite() const {
+ return false;
+}
+
void ProxyImpl::NotifyReadyToCommitOnImpl(
CompletionEvent* completion,
LayerTreeHost* layer_tree_host,
@@ -385,10 +391,28 @@ bool ProxyImpl::IsBeginMainFrameExpected() {
void ProxyImpl::RenewTreePriority() {
DCHECK(IsImplThread());
- const bool user_interaction_in_progress =
+
+ bool scroll_type_considered_interaction = false;
+ bool non_scroll_interaction_in_progress =
host_impl_->IsPinchGestureActive() ||
- host_impl_->page_scale_animation_active() ||
- host_impl_->IsActivelyPrecisionScrolling();
+ host_impl_->page_scale_animation_active();
+
+ ActivelyScrollingType actively_scrolling_type =
+ host_impl_->GetActivelyScrollingType();
+
+ switch (actively_scrolling_type) {
+ case ActivelyScrollingType::kNone:
+ break;
+ case ActivelyScrollingType::kPrecise:
+ scroll_type_considered_interaction = true;
+ break;
+ case ActivelyScrollingType::kAnimated:
+ scroll_type_considered_interaction = base::FeatureList::IsEnabled(
+ features::kSchedulerSmoothnessForAnimatedScrolls);
+ }
+
+ bool user_interaction_in_progress =
+ non_scroll_interaction_in_progress || scroll_type_considered_interaction;
if (host_impl_->ukm_manager()) {
host_impl_->ukm_manager()->SetUserInteractionInProgress(
@@ -400,11 +424,19 @@ void ProxyImpl::RenewTreePriority() {
smoothness_priority_expiration_notifier_.Schedule();
// We use the same priority for both trees by default.
- TreePriority tree_priority = SAME_PRIORITY_FOR_BOTH_TREES;
+ TreePriority scheduler_tree_priority = SAME_PRIORITY_FOR_BOTH_TREES;
+ TreePriority raster_tree_priority = SAME_PRIORITY_FOR_BOTH_TREES;
// Smoothness takes priority if we have an expiration for it scheduled.
- if (smoothness_priority_expiration_notifier_.HasPendingNotification())
- tree_priority = SMOOTHNESS_TAKES_PRIORITY;
+ if (smoothness_priority_expiration_notifier_.HasPendingNotification()) {
+ scheduler_tree_priority = SMOOTHNESS_TAKES_PRIORITY;
+ if (non_scroll_interaction_in_progress ||
+ actively_scrolling_type == ActivelyScrollingType::kPrecise ||
+ last_raster_priority_ == SMOOTHNESS_TAKES_PRIORITY)
+ raster_tree_priority = SMOOTHNESS_TAKES_PRIORITY;
+ }
+
+ last_raster_priority_ = raster_tree_priority;
// New content always takes priority when ui resources have been evicted.
if (host_impl_->active_tree()->GetDeviceViewport().size().IsEmpty() ||
@@ -413,10 +445,10 @@ void ProxyImpl::RenewTreePriority() {
// tree might be freed. We need to set RequiresHighResToDraw to ensure that
// high res tiles will be required to activate pending tree.
host_impl_->SetRequiresHighResToDraw();
- tree_priority = NEW_CONTENT_TAKES_PRIORITY;
+ scheduler_tree_priority = raster_tree_priority = NEW_CONTENT_TAKES_PRIORITY;
}
- host_impl_->SetTreePriority(tree_priority);
+ host_impl_->SetTreePriority(raster_tree_priority);
// Only put the scheduler in impl latency prioritization mode if we don't
// have a scroll listener. This gives the scroll listener a better chance of
@@ -426,7 +458,7 @@ void ProxyImpl::RenewTreePriority() {
host_impl_->ScrollAffectsScrollHandler()
? ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER
: ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
- scheduler_->SetTreePrioritiesAndScrollState(tree_priority,
+ scheduler_->SetTreePrioritiesAndScrollState(scheduler_tree_priority,
scroll_handler_state);
}
diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h
index e8578e8abf9..815935a5d41 100644
--- a/chromium/cc/trees/proxy_impl.h
+++ b/chromium/cc/trees/proxy_impl.h
@@ -6,6 +6,7 @@
#define CC_TREES_PROXY_IMPL_H_
#include <memory>
+#include <vector>
#include "base/memory/weak_ptr.h"
#include "cc/base/completion_event.h"
@@ -148,6 +149,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
base::TimeTicks time) override;
void FrameIntervalUpdated(base::TimeDelta interval) override {}
bool HasCustomPropertyAnimations() const override;
+ bool IsInSynchronousComposite() const override;
DrawResult DrawInternal(bool forced_draw);
@@ -176,6 +178,8 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient,
bool send_compositor_frame_ack_;
+ TreePriority last_raster_priority_;
+
TaskRunnerProvider* task_runner_provider_;
DelayedUniqueNotifier smoothness_priority_expiration_notifier_;
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 62247ad3dbf..f2050b82334 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -557,9 +557,15 @@ void SingleThreadProxy::RequestBeginMainFrameNotExpected(bool new_state) {
}
}
-void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time,
- bool raster) {
- TRACE_EVENT0("cc,benchmark", "SingleThreadProxy::CompositeImmediately");
+bool SingleThreadProxy::IsInSynchronousComposite() const {
+ return inside_synchronous_composite_;
+}
+
+void SingleThreadProxy::CompositeImmediatelyForTest(
+ base::TimeTicks frame_begin_time,
+ bool raster) {
+ TRACE_EVENT0("cc,benchmark",
+ "SingleThreadProxy::CompositeImmediatelyForTest");
DCHECK(task_runner_provider_->IsMainThread());
#if DCHECK_IS_ON()
DCHECK(!inside_impl_frame_);
diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h
index b65b1069041..8b0960dbd4f 100644
--- a/chromium/cc/trees/single_thread_proxy.h
+++ b/chromium/cc/trees/single_thread_proxy.h
@@ -6,6 +6,8 @@
#define CC_TREES_SINGLE_THREAD_PROXY_H_
#include <limits>
+#include <memory>
+#include <vector>
#include "base/cancelable_callback.h"
#include "base/time/time.h"
@@ -138,6 +140,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
void NotifyPaintWorkletStateChange(
Scheduler::PaintWorkletState state) override;
void NotifyThroughputTrackerResults(CustomTrackerResults results) override;
+ bool IsInSynchronousComposite() const override;
void RequestNewLayerTreeFrameSink();
@@ -151,7 +154,8 @@ class CC_EXPORT SingleThreadProxy : public Proxy,
// Called by the legacy path where RenderWidget does the scheduling.
// Rasterization of tiles is only performed when |raster| is true.
- void CompositeImmediately(base::TimeTicks frame_begin_time, bool raster);
+ void CompositeImmediatelyForTest(base::TimeTicks frame_begin_time,
+ bool raster);
protected:
SingleThreadProxy(LayerTreeHost* layer_tree_host,
diff --git a/chromium/cc/trees/ukm_manager.cc b/chromium/cc/trees/ukm_manager.cc
index 348e4b66656..b3761e46d3d 100644
--- a/chromium/cc/trees/ukm_manager.cc
+++ b/chromium/cc/trees/ukm_manager.cc
@@ -116,6 +116,8 @@ void UkmManager::RecordThroughputUKM(
CASE_FOR_MAIN_THREAD_TRACKER(TouchScroll);
CASE_FOR_MAIN_THREAD_TRACKER(Video);
CASE_FOR_MAIN_THREAD_TRACKER(WheelScroll);
+ CASE_FOR_MAIN_THREAD_TRACKER(CanvasAnimation);
+ CASE_FOR_MAIN_THREAD_TRACKER(JSAnimation);
#undef CASE_FOR_MAIN_THREAD_TRACKER
default:
NOTREACHED();
@@ -261,6 +263,8 @@ void UkmManager::RecordCompositorLatencyUKM(
CASE_FOR_TRACKER(TouchScroll);
CASE_FOR_TRACKER(Video);
CASE_FOR_TRACKER(WheelScroll);
+ CASE_FOR_TRACKER(CanvasAnimation);
+ CASE_FOR_TRACKER(JSAnimation);
#undef CASE_FOR_TRACKER
default:
NOTREACHED();
@@ -272,23 +276,24 @@ void UkmManager::RecordCompositorLatencyUKM(
}
void UkmManager::RecordEventLatencyUKM(
- const std::vector<EventMetrics>& events_metrics,
+ const EventMetrics::List& events_metrics,
const std::vector<CompositorFrameReporter::StageData>& stage_history,
const viz::FrameTimingDetails& viz_breakdown) const {
using StageType = CompositorFrameReporter::StageType;
- for (const EventMetrics& event_metrics : events_metrics) {
+ for (const auto& event_metrics : events_metrics) {
ukm::builders::Graphics_Smoothness_EventLatency builder(source_id_);
- builder.SetEventType(static_cast<int64_t>(event_metrics.type()));
+ builder.SetEventType(static_cast<int64_t>(event_metrics->type()));
- if (event_metrics.scroll_type()) {
+ if (event_metrics->scroll_type()) {
builder.SetScrollInputType(
- static_cast<int64_t>(*event_metrics.scroll_type()));
+ static_cast<int64_t>(*event_metrics->scroll_type()));
if (!viz_breakdown.swap_timings.is_null()) {
builder.SetTotalLatencyToSwapBegin(
- (viz_breakdown.swap_timings.swap_start - event_metrics.time_stamp())
+ (viz_breakdown.swap_timings.swap_start -
+ event_metrics->time_stamp())
.InMicroseconds());
}
}
@@ -301,7 +306,7 @@ void UkmManager::RecordEventLatencyUKM(
auto stage_it = std::find_if(
stage_history.begin(), stage_history.end(),
[&event_metrics](const CompositorFrameReporter::StageData& stage) {
- return stage.start_time > event_metrics.time_stamp();
+ return stage.start_time > event_metrics->time_stamp();
});
// TODO(crbug.com/1079116): Ideally, at least the start time of
// SubmitCompositorFrameToPresentationCompositorFrame stage should be
@@ -314,13 +319,13 @@ void UkmManager::RecordEventLatencyUKM(
continue;
builder.SetBrowserToRendererCompositor(
- (stage_it->start_time - event_metrics.time_stamp()).InMicroseconds());
+ (stage_it->start_time - event_metrics->time_stamp()).InMicroseconds());
for (; stage_it != stage_history.end(); ++stage_it) {
// Total latency is calculated since the event timestamp.
const base::TimeTicks start_time =
stage_it->stage_type == StageType::kTotalLatency
- ? event_metrics.time_stamp()
+ ? event_metrics->time_stamp()
: stage_it->start_time;
switch (stage_it->stage_type) {
diff --git a/chromium/cc/trees/ukm_manager.h b/chromium/cc/trees/ukm_manager.h
index c4e3e833c65..b51147f71c3 100644
--- a/chromium/cc/trees/ukm_manager.h
+++ b/chromium/cc/trees/ukm_manager.h
@@ -60,7 +60,7 @@ class CC_EXPORT UkmManager {
const viz::FrameTimingDetails& viz_breakdown) const;
void RecordEventLatencyUKM(
- const std::vector<EventMetrics>& events_metrics,
+ const EventMetrics::List& events_metrics,
const std::vector<CompositorFrameReporter::StageData>& stage_history,
const viz::FrameTimingDetails& viz_breakdown) const;
diff --git a/chromium/cc/trees/ukm_manager_unittest.cc b/chromium/cc/trees/ukm_manager_unittest.cc
index a00d6826cba..6449021af38 100644
--- a/chromium/cc/trees/ukm_manager_unittest.cc
+++ b/chromium/cc/trees/ukm_manager_unittest.cc
@@ -360,8 +360,9 @@ TEST_F(UkmManagerTest, EventLatency) {
event_time, ui::ScrollInputType::kWheel),
};
EXPECT_THAT(event_metrics_ptrs, ::testing::Each(::testing::NotNull()));
- std::vector<EventMetrics> events_metrics = {
- *event_metrics_ptrs[0], *event_metrics_ptrs[1], *event_metrics_ptrs[2]};
+ EventMetrics::List events_metrics(
+ std::make_move_iterator(std::begin(event_metrics_ptrs)),
+ std::make_move_iterator(std::end(event_metrics_ptrs)));
const base::TimeTicks begin_impl_time =
(now += base::TimeDelta::FromMicroseconds(10));
@@ -418,7 +419,7 @@ TEST_F(UkmManagerTest, EventLatency) {
EXPECT_EQ(3u, entries.size());
for (size_t i = 0; i < entries.size(); i++) {
const auto* entry = entries[i];
- const auto* event_metrics = event_metrics_ptrs[i].get();
+ const auto* event_metrics = events_metrics[i].get();
EXPECT_NE(ukm::kInvalidSourceId, entry->source_id);
test_ukm_recorder_->ExpectEntrySourceHasUrl(entry, GURL(kTestUrl));