@@ -43,9 +43,8 @@ std::optional<SkRect> FrameDamage::ComputeClipRect(
4343 context.ComputeDamage (additional_damage_, horizontal_clip_alignment_,
4444 vertical_clip_alignment_);
4545 return SkRect::Make (damage_->buffer_damage );
46- } else {
47- return std::nullopt ;
4846 }
47+ return std::nullopt ;
4948}
5049
5150CompositorContext::CompositorContext ()
@@ -125,10 +124,16 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
125124 FrameDamage* frame_damage) {
126125 TRACE_EVENT0 (" flutter" , " CompositorContext::ScopedFrame::Raster" );
127126
128- std::optional<SkRect> clip_rect =
129- frame_damage
130- ? frame_damage->ComputeClipRect (layer_tree, !ignore_raster_cache)
131- : std::nullopt ;
127+ std::optional<SkRect> clip_rect;
128+ if (frame_damage) {
129+ clip_rect = frame_damage->ComputeClipRect (layer_tree, !ignore_raster_cache);
130+
131+ if (aiks_context_ &&
132+ !ShouldPerformPartialRepaint (clip_rect, layer_tree.frame_size ())) {
133+ clip_rect = std::nullopt ;
134+ frame_damage->Reset ();
135+ }
136+ }
132137
133138 bool root_needs_readback = layer_tree.Preroll (
134139 *this , ignore_raster_cache, clip_rect ? *clip_rect : kGiantRect );
@@ -146,10 +151,22 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
146151 return RasterStatus::kSkipAndRetry ;
147152 }
148153
154+ if (aiks_context_) {
155+ PaintLayerTreeImpeller (layer_tree, clip_rect, ignore_raster_cache);
156+ } else {
157+ PaintLayerTreeSkia (layer_tree, clip_rect, needs_save_layer,
158+ ignore_raster_cache);
159+ }
160+ return RasterStatus::kSuccess ;
161+ }
162+
163+ void CompositorContext::ScopedFrame::PaintLayerTreeSkia (
164+ flutter::LayerTree& layer_tree,
165+ std::optional<SkRect> clip_rect,
166+ bool needs_save_layer,
167+ bool ignore_raster_cache) {
149168 DlAutoCanvasRestore restore (canvas (), clip_rect.has_value ());
150169
151- // Clearing canvas after preroll reduces one render target switch when preroll
152- // paints some raster cache.
153170 if (canvas ()) {
154171 if (clip_rect) {
155172 canvas ()->ClipRect (*clip_rect);
@@ -164,9 +181,48 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
164181 }
165182 canvas ()->Clear (DlColor::kTransparent ());
166183 }
167- layer_tree. Paint (* this , ignore_raster_cache);
184+
168185 // The canvas()->Restore() is taken care of by the DlAutoCanvasRestore
169- return RasterStatus::kSuccess ;
186+ layer_tree.Paint (*this , ignore_raster_cache);
187+ }
188+
189+ void CompositorContext::ScopedFrame::PaintLayerTreeImpeller (
190+ flutter::LayerTree& layer_tree,
191+ std::optional<SkRect> clip_rect,
192+ bool ignore_raster_cache) {
193+ if (canvas () && clip_rect) {
194+ canvas ()->Translate (-clip_rect->x (), -clip_rect->y ());
195+ }
196+
197+ layer_tree.Paint (*this , ignore_raster_cache);
198+ }
199+
200+ // / @brief The max ratio of pixel width or height to size that is dirty which
201+ // / results in a partial repaint.
202+ // /
203+ // / Performing a partial repaint has a small overhead - Impeller needs to
204+ // / allocate a fairly large resolve texture for the root pass instead of
205+ // / using the drawable texture, and a final blit must be performed. At a
206+ // / minimum, if the damage rect is the entire buffer, we must not perform
207+ // / a partial repaint. Beyond that, we could only experimentally
208+ // / determine what this value should be. From looking at the Flutter
209+ // / Gallery, we noticed that there are occassionally small partial
210+ // / repaints which shave off trivial numbers of pixels.
211+ constexpr float kImpellerRepaintRatio = 0 .7f ;
212+
213+ bool CompositorContext::ShouldPerformPartialRepaint (
214+ std::optional<SkRect> damage_rect,
215+ SkISize layer_tree_size) {
216+ if (!damage_rect.has_value ()) {
217+ return false ;
218+ }
219+ if (damage_rect->width () >= layer_tree_size.width () &&
220+ damage_rect->height () >= layer_tree_size.height ()) {
221+ return false ;
222+ }
223+ auto rx = damage_rect->width () / layer_tree_size.width ();
224+ auto ry = damage_rect->height () / layer_tree_size.height ();
225+ return rx <= kImpellerRepaintRatio || ry <= kImpellerRepaintRatio ;
170226}
171227
172228void CompositorContext::OnGrContextCreated () {
0 commit comments