0

Consider device pixel factor in merge sparsity

This is actually the main reason of the bug with high dpr. Consider
dpr to make the sparsity check unrelated to dpr for the same web page.
Previously we too many layers couldn't be merged because of a much
lower effective sparsity tolerance with high dpr.

This is behind killswitch FewerSubsequences (not strictly suitable
but related as we added a similar sparsity check in PaintLayerPainter
behind the same switch).

Bug: 40929618
Change-Id: I0f77b515d03222b0e90be93278731e5c99a34771
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6353377
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Reviewed-by: Philip Rogers <pdr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1432793}
This commit is contained in:
Xianzhu Wang
2025-03-14 09:45:33 -07:00
committed by Chromium LUCI CQ
parent 5dbe955986
commit 5a17fd5c48
8 changed files with 26 additions and 5 deletions

@ -2969,6 +2969,8 @@ void LocalFrameView::PushPaintArtifactToCompositor(bool repainted) {
paint_artifact_compositor_->SetLCDTextPreference(
page->GetSettings().GetLCDTextPreference());
paint_artifact_compositor_->SetDevicePixelRatio(
frame_->GetDocument()->DevicePixelRatio());
SCOPED_UMA_AND_UKM_TIMER(GetUkmAggregator(),
LocalFrameUkmAggregator::kCompositingCommit);

@ -117,6 +117,14 @@ void PaintArtifactCompositor::SetLCDTextPreference(
lcd_text_preference_ = preference;
}
void PaintArtifactCompositor::SetDevicePixelRatio(float ratio) {
if (device_pixel_ratio_ == ratio) {
return;
}
SetNeedsUpdate();
device_pixel_ratio_ = ratio;
}
std::unique_ptr<JSONArray> PaintArtifactCompositor::GetPendingLayersAsJSON()
const {
std::unique_ptr<JSONArray> result = std::make_unique<JSONArray>();
@ -764,6 +772,7 @@ void PaintArtifactCompositor::Layerizer::LayerizeGroup(
--candidate_index;
PendingLayer& candidate_layer = pending_layers_[candidate_index];
if (candidate_layer.Merge(new_layer, compositor_.lcd_text_preference_,
compositor_.device_pixel_ratio_,
is_composited_scroll)) {
pending_layers_.pop_back();
break;

@ -235,6 +235,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
ContentLayerClientImpl* ContentLayerClientForTesting(wtf_size_t i) const;
void SetLCDTextPreference(LCDTextPreference);
void SetDevicePixelRatio(float ratio);
// Returns true if a property tree node associated with |element_id| exists
// on any of the PropertyTrees constructed by |Update|.
@ -328,6 +329,7 @@ class PLATFORM_EXPORT PaintArtifactCompositor final
UpdateType previous_update_for_testing_ = UpdateType::kNone;
LCDTextPreference lcd_text_preference_ = LCDTextPreference::kIgnored;
float device_pixel_ratio_ = 1.f;
scoped_refptr<cc::Layer> root_layer_;

@ -207,6 +207,7 @@ static constexpr float kMergeSparsityAreaTolerance = 10000;
bool PendingLayer::CanMerge(
const PendingLayer& guest,
LCDTextPreference lcd_text_preference,
float device_pixel_ratio,
IsCompositedScrollFunction is_composited_scroll,
gfx::RectF& merged_bounds,
PropertyTreeState& merged_state,
@ -272,8 +273,11 @@ bool PendingLayer::CanMerge(
if (!guest.has_decomposited_blend_mode_) {
float sum_area = new_home_bounds.Rect().size().GetArea() +
new_guest_bounds.Rect().size().GetArea();
if (merged_bounds.size().GetArea() - sum_area >
kMergeSparsityAreaTolerance) {
float tolerance = kMergeSparsityAreaTolerance;
if (RuntimeEnabledFeatures::FewerSubsequencesEnabled()) {
tolerance *= device_pixel_ratio * device_pixel_ratio;
}
if (merged_bounds.size().GetArea() - sum_area > tolerance) {
return false;
}
@ -344,6 +348,7 @@ bool PendingLayer::CanMerge(
bool PendingLayer::Merge(const PendingLayer& guest,
LCDTextPreference lcd_text_preference,
float device_pixel_ratio,
IsCompositedScrollFunction is_composited_scroll) {
gfx::RectF merged_bounds;
PropertyTreeState merged_state(PropertyTreeState::kUninitialized);
@ -353,8 +358,9 @@ bool PendingLayer::Merge(const PendingLayer& guest,
cc::HitTestOpaqueness merged_hit_test_opaqueness =
cc::HitTestOpaqueness::kMixed;
if (!CanMerge(guest, lcd_text_preference, is_composited_scroll, merged_bounds,
merged_state, merged_rect_known_to_be_opaque,
if (!CanMerge(guest, lcd_text_preference, device_pixel_ratio,
is_composited_scroll, merged_bounds, merged_state,
merged_rect_known_to_be_opaque,
merged_text_known_to_be_on_opaque_background,
merged_solid_color_chunk_index, merged_hit_test_opaqueness)) {
return false;

@ -88,6 +88,7 @@ class PLATFORM_EXPORT PendingLayer {
// Returns whether the merge is successful.
bool Merge(const PendingLayer& guest,
LCDTextPreference lcd_text_preference,
float device_pixel_ratio,
IsCompositedScrollFunction);
// Returns true if `guest` that could be upcasted with decomposited blend
@ -187,6 +188,7 @@ class PLATFORM_EXPORT PendingLayer {
bool CanMerge(const PendingLayer& guest,
LCDTextPreference lcd_text_preference,
float device_pixel_ratio,
IsCompositedScrollFunction,
gfx::RectF& merged_bounds,
PropertyTreeState& merged_state,

@ -38,7 +38,7 @@ bool Merge(PendingLayer& home,
LCDTextPreference lcd_text_preference = LCDTextPreference::kIgnored,
PendingLayer::IsCompositedScrollFunction is_composited_scroll =
DefaultIsCompositedScroll) {
return home.Merge(guest, lcd_text_preference, is_composited_scroll);
return home.Merge(guest, lcd_text_preference, 1.f, is_composited_scroll);
}
TEST(PendingLayerTest, Merge) {

Binary file not shown.

Before

(image error) Size: 29 KiB

After

(image error) Size: 30 KiB

Binary file not shown.

Before

(image error) Size: 29 KiB

After

(image error) Size: 30 KiB