Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e2e2be5

Browse files
committed
Specify clip alignment for partial repaint
1 parent ba8f1c5 commit e2e2be5

File tree

7 files changed

+74
-4
lines changed

7 files changed

+74
-4
lines changed

flow/compositor_context.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ std::optional<SkRect> FrameDamage::ComputeClipRect(
3636
layer_tree.root_layer()->Diff(&context, prev_root_layer);
3737
}
3838

39-
damage_ = context.ComputeDamage(additional_damage_);
39+
damage_ =
40+
context.ComputeDamage(additional_damage_, horizontal_clip_alignment_,
41+
vertical_clip_alignment_);
4042
return SkRect::Make(damage_->buffer_damage);
4143
} else {
4244
return std::nullopt;
@@ -134,6 +136,9 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
134136
// paints some raster cache.
135137
if (canvas()) {
136138
if (clip_rect) {
139+
// if (bottom > height) {
140+
// bottom = height;
141+
// }
137142
canvas()->clipRect(*clip_rect);
138143
}
139144

flow/compositor_context.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ class FrameDamage {
6969
additional_damage_.join(damage);
7070
}
7171

72+
// Specifies clip rect alignment.
73+
void SetClipAlignment(int horizontal, int vertical) {
74+
horizontal_clip_alignment_ = horizontal;
75+
vertical_clip_alignment_ = vertical;
76+
}
77+
7278
// Calculates clip rect for current rasterization. This is diff of layer tree
7379
// and previous layer tree + any additional provideddamage.
7480
// If previous layer tree is not specified, clip rect will be nulloptional,
@@ -90,6 +96,8 @@ class FrameDamage {
9096
SkIRect additional_damage_ = SkIRect::MakeEmpty();
9197
std::optional<Damage> damage_;
9298
const LayerTree* prev_layer_tree_ = nullptr;
99+
int vertical_clip_alignment_ = 1;
100+
int horizontal_clip_alignment_ = 1;
93101
};
94102

95103
class CompositorContext {

flow/diff_context.cc

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,33 @@ SkRect DiffContext::ApplyFilterBoundsAdjustment(SkRect rect) const {
6767
return rect;
6868
}
6969

70-
Damage DiffContext::ComputeDamage(
71-
const SkIRect& accumulated_buffer_damage) const {
70+
void DiffContext::AlignRect(SkIRect& rect,
71+
int horizontal_alignment,
72+
int vertical_alignment) const {
73+
auto top = rect.top();
74+
auto left = rect.left();
75+
auto right = rect.right();
76+
auto bottom = rect.bottom();
77+
if (top % vertical_alignment != 0) {
78+
top -= top % vertical_alignment;
79+
}
80+
if (left % horizontal_alignment != 0) {
81+
left -= left % horizontal_alignment;
82+
}
83+
if (right % horizontal_alignment != 0) {
84+
right += horizontal_alignment - right % horizontal_alignment;
85+
}
86+
if (bottom % horizontal_alignment != 0) {
87+
bottom += horizontal_alignment - bottom % horizontal_alignment;
88+
}
89+
right = std::min(right, frame_size_.width());
90+
bottom = std::min(bottom, frame_size_.height());
91+
rect = SkIRect::MakeLTRB(left, top, right, bottom);
92+
}
93+
94+
Damage DiffContext::ComputeDamage(const SkIRect& accumulated_buffer_damage,
95+
int horizontal_clip_alignment,
96+
int vertical_clip_alignment) const {
7297
SkRect buffer_damage = SkRect::Make(accumulated_buffer_damage);
7398
buffer_damage.join(damage_);
7499
SkRect frame_damage(damage_);
@@ -90,6 +115,13 @@ Damage DiffContext::ComputeDamage(
90115
SkIRect frame_clip = SkIRect::MakeSize(frame_size_);
91116
res.buffer_damage.intersect(frame_clip);
92117
res.frame_damage.intersect(frame_clip);
118+
119+
if (horizontal_clip_alignment > 1 || vertical_clip_alignment > 1) {
120+
AlignRect(res.buffer_damage, horizontal_clip_alignment,
121+
vertical_clip_alignment);
122+
AlignRect(res.frame_damage, horizontal_clip_alignment,
123+
vertical_clip_alignment);
124+
}
93125
return res;
94126
}
95127

flow/diff_context.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,12 @@ class DiffContext {
133133
//
134134
// additional_damage is the previously accumulated frame_damage for
135135
// current framebuffer
136-
Damage ComputeDamage(const SkIRect& additional_damage) const;
136+
//
137+
// clip_alignment controls the alignment of resulting frame and surface
138+
// damage.
139+
Damage ComputeDamage(const SkIRect& additional_damage,
140+
int horizontal_clip_alignment = 1,
141+
int vertical_clip_alignment = 1) const;
137142

138143
double frame_device_pixel_ratio() const { return frame_device_pixel_ratio_; };
139144

@@ -230,6 +235,10 @@ class DiffContext {
230235

231236
void AddDamage(const SkRect& rect);
232237

238+
void AlignRect(SkIRect& rect,
239+
int horizontal_alignment,
240+
int vertical_clip_alignment) const;
241+
233242
struct Readback {
234243
// Index of rects_ entry that this readback belongs to. Used to
235244
// determine if subtree has any readback

flow/surface_frame.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ class SurfaceFrame {
3232
// this means that the surface will provide valid existing damage.
3333
bool supports_partial_repaint = false;
3434

35+
// For some targets it may be beneficial or even required to snap clip
36+
// rect to tile grid. I.e. repainting part of a tile may cause performance
37+
// degradation if the tile needs to be decompressed first.
38+
int vertical_clip_alignment = 1;
39+
int horizontal_clip_alignment = 1;
40+
3541
// This is the area of framebuffer that lags behind the front buffer.
3642
//
3743
// Correctly providing exiting_damage is necessary for supporting double and

shell/common/rasterizer.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,9 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe(
570570
if (frame->framebuffer_info().existing_damage && !force_full_repaint) {
571571
damage->SetPreviousLayerTree(last_layer_tree_.get());
572572
damage->AddAdditonalDamage(*frame->framebuffer_info().existing_damage);
573+
damage->SetClipAlignment(
574+
frame->framebuffer_info().horizontal_clip_alignment,
575+
frame->framebuffer_info().vertical_clip_alignment);
573576
}
574577
}
575578

shell/platform/android/android_surface_gl.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ SurfaceFrame::FramebufferInfo AndroidSurfaceGL::GLContextFramebufferInfo()
133133
res.supports_readback = true;
134134
res.supports_partial_repaint = onscreen_surface_->SupportsPartialRepaint();
135135
res.existing_damage = onscreen_surface_->InitialDamage();
136+
// Some devices (Pixel2 XL) needs EGL_KHR_partial_update rect aligned to 4,
137+
// otherwise there are glitches
138+
// (https://github.com/flutter/flutter/issues/97482#)
139+
// Larger alignment might be beneficial for tile base renderers.
140+
res.horizontal_clip_alignment = 32;
141+
res.vertical_clip_alignment = 32;
142+
136143
return res;
137144
}
138145

0 commit comments

Comments
 (0)