44
55#include  " flutter/flow/compositor_context.h" 
66
7+ #include  < optional> 
78#include  " flutter/flow/layers/layer_tree.h" 
89#include  " third_party/skia/include/core/SkCanvas.h" 
910
1011namespace  flutter  {
1112
13+ std::optional<SkRect> FrameDamage::ComputeClipRect (
14+     flutter::LayerTree& layer_tree) {
15+   if  (layer_tree.root_layer ()) {
16+     PaintRegionMap empty_paint_region_map;
17+     DiffContext context (layer_tree.frame_size (),
18+                         layer_tree.device_pixel_ratio (),
19+                         layer_tree.paint_region_map (),
20+                         prev_layer_tree_ ? prev_layer_tree_->paint_region_map ()
21+                                          : empty_paint_region_map);
22+     context.PushCullRect (SkRect::MakeIWH (layer_tree.frame_size ().width (),
23+                                          layer_tree.frame_size ().height ()));
24+     {
25+       DiffContext::AutoSubtreeRestore subtree (&context);
26+       const  Layer* prev_root_layer = nullptr ;
27+       if  (!prev_layer_tree_ ||
28+           prev_layer_tree_->frame_size () != layer_tree.frame_size ()) {
29+         //  If there is no previous layer tree assume the entire frame must be
30+         //  repainted.
31+         context.MarkSubtreeDirty (SkRect::MakeIWH (
32+             layer_tree.frame_size ().width (), layer_tree.frame_size ().height ()));
33+       } else  {
34+         prev_root_layer = prev_layer_tree_->root_layer ();
35+       }
36+       layer_tree.root_layer ()->Diff (&context, prev_root_layer);
37+     }
38+ 
39+     damage_ = context.ComputeDamage (additional_damage_);
40+     return  SkRect::Make (damage_->buffer_damage );
41+   } else  {
42+     return  std::nullopt ;
43+   }
44+ }
45+ 
1246CompositorContext::CompositorContext (fml::Milliseconds frame_budget)
1347    : raster_time_(frame_budget), ui_time_(frame_budget) {}
1448
@@ -68,9 +102,15 @@ CompositorContext::ScopedFrame::~ScopedFrame() {
68102
69103RasterStatus CompositorContext::ScopedFrame::Raster (
70104    flutter::LayerTree& layer_tree,
71-     bool  ignore_raster_cache) {
105+     bool  ignore_raster_cache,
106+     FrameDamage* frame_damage) {
72107  TRACE_EVENT0 (" flutter" " CompositorContext::ScopedFrame::Raster" 
73-   bool  root_needs_readback = layer_tree.Preroll (*this , ignore_raster_cache);
108+ 
109+   std::optional<SkRect> clip_rect =
110+       frame_damage ? frame_damage->ComputeClipRect (layer_tree) : std::nullopt ;
111+ 
112+   bool  root_needs_readback = layer_tree.Preroll (
113+       *this , ignore_raster_cache, clip_rect ? *clip_rect : kGiantRect );
74114  bool  needs_save_layer = root_needs_readback && !surface_supports_readback ();
75115  PostPrerollResult post_preroll_result = PostPrerollResult::kSuccess ;
76116  if  (view_embedder_ && raster_thread_merger_) {
@@ -84,9 +124,16 @@ RasterStatus CompositorContext::ScopedFrame::Raster(
84124  if  (post_preroll_result == PostPrerollResult::kSkipAndRetryFrame ) {
85125    return  RasterStatus::kSkipAndRetry ;
86126  }
127+ 
128+   SkAutoCanvasRestore restore (canvas (), clip_rect.has_value ());
129+ 
87130  //  Clearing canvas after preroll reduces one render target switch when preroll
88131  //  paints some raster cache.
89132  if  (canvas ()) {
133+     if  (clip_rect) {
134+       canvas ()->clipRect (*clip_rect);
135+     }
136+ 
90137    if  (needs_save_layer) {
91138      TRACE_EVENT0 (" flutter" " Canvas::saveLayer" 
92139      SkRect bounds = SkRect::Make (layer_tree.frame_size ());
0 commit comments