66
77namespace flutter {
88
9+ #define MINIMUM_FILTER_CACHE 2
10+
911ImageFilterLayer::ImageFilterLayer (sk_sp<SkImageFilter> filter)
10- : filter_(std::move(filter)) {}
12+ : filter_(std::move(filter)), render_count_( 1 ) {}
1113
1214void ImageFilterLayer::Preroll (PrerollContext* context,
1315 const SkMatrix& matrix) {
@@ -16,25 +18,29 @@ void ImageFilterLayer::Preroll(PrerollContext* context,
1618 Layer::AutoPrerollSaveLayerState save =
1719 Layer::AutoPrerollSaveLayerState::Create (context);
1820
19- child_paint_bounds_ = SkRect::MakeEmpty ();
20- PrerollChildren (context, matrix, &child_paint_bounds_ );
21+ SkRect child_bounds = SkRect::MakeEmpty ();
22+ PrerollChildren (context, matrix, &child_bounds );
2123 if (filter_) {
22- const SkIRect filter_input_bounds = child_paint_bounds_ .roundOut ();
24+ const SkIRect filter_input_bounds = child_bounds .roundOut ();
2325 SkIRect filter_output_bounds =
2426 filter_->filterBounds (filter_input_bounds, SkMatrix::I (),
2527 SkImageFilter::kForward_MapDirection );
26- set_paint_bounds (SkRect::Make (filter_output_bounds));
27- } else {
28- set_paint_bounds (child_paint_bounds_);
28+ child_bounds = SkRect::Make (filter_output_bounds);
2929 }
30+ set_paint_bounds (child_bounds);
3031
3132 if (!context->has_platform_view && context->raster_cache &&
3233 SkRect::Intersects (context->cull_rect , paint_bounds ())) {
3334 SkMatrix ctm = matrix;
3435#ifndef SUPPORT_FRACTIONAL_TRANSLATION
3536 ctm = RasterCache::GetIntegralTransCTM (ctm);
3637#endif
37- context->raster_cache ->Prepare (context, this , ctm);
38+ if (render_count_ >= MINIMUM_FILTER_CACHE) {
39+ context->raster_cache ->Prepare (context, this , ctm);
40+ } else {
41+ render_count_++;
42+ context->raster_cache ->Prepare (context, GetCacheableChild (), ctm);
43+ }
3844 }
3945}
4046
@@ -53,20 +59,36 @@ void ImageFilterLayer::Paint(PaintContext& context) const {
5359 RasterCacheResult layer_cache =
5460 context.raster_cache ->Get ((Layer*)this , ctm);
5561 if (layer_cache.is_valid ()) {
62+ FML_LOG (ERROR) << " Rendering filtered output from cache" ;
5663 layer_cache.draw (*context.leaf_nodes_canvas );
5764 return ;
5865 }
66+ layer_cache = context.raster_cache ->Get (GetCacheableChild (), ctm);
67+ if (layer_cache.is_valid ()) {
68+ sk_sp<SkImageFilter> transformed_filter =
69+ filter_->makeWithLocalMatrix (ctm);
70+ if (transformed_filter) {
71+ FML_LOG (ERROR) << " Filtering from cached child" ;
72+
73+ SkPaint paint;
74+ paint.setImageFilter (transformed_filter);
75+
76+ layer_cache.draw (*context.leaf_nodes_canvas , &paint);
77+ return ;
78+ }
79+ }
5980 }
6081
82+ FML_LOG (ERROR) << " Applying filter to child on the fly" ;
6183 SkPaint paint;
6284 paint.setImageFilter (filter_);
6385
6486 // Normally a save_layer is sized to the current layer bounds, but in this
6587 // case the bounds of the child may not be the same as the filtered version
6688 // so we use the child_paint_bounds_ which were snapshotted from the
6789 // Preroll on the children before we adjusted them based on the filter.
68- Layer::AutoSaveLayer save_layer =
69- Layer::AutoSaveLayer::Create ( context, child_paint_bounds_ , &paint);
90+ Layer::AutoSaveLayer save_layer = Layer::AutoSaveLayer::Create (
91+ context, GetChildContainer ()-> paint_bounds () , &paint);
7092 PaintChildren (context);
7193}
7294
0 commit comments