Flutter Engine
backdrop_filter_layer.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "flutter/flow/layers/backdrop_filter_layer.h"
6 
7 namespace flutter {
8 
9 BackdropFilterLayer::BackdropFilterLayer(sk_sp<SkImageFilter> filter,
10  SkBlendMode blend_mode)
11  : filter_(std::move(filter)), blend_mode_(blend_mode) {}
12 
13 #ifdef FLUTTER_ENABLE_DIFF_CONTEXT
14 
15 void BackdropFilterLayer::Diff(DiffContext* context, const Layer* old_layer) {
16  DiffContext::AutoSubtreeRestore subtree(context);
17  auto* prev = static_cast<const BackdropFilterLayer*>(old_layer);
18  if (!context->IsSubtreeDirty()) {
19  FML_DCHECK(prev);
20  if (filter_ != prev->filter_) {
21  context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer));
22  }
23  }
24 
25  // Backdrop filter paints everywhere in cull rect
26  auto paint_bounds = context->GetCullRect();
27  context->AddLayerBounds(paint_bounds);
28 
29  // convert paint bounds and filter to screen coordinates
30  context->GetTransform().mapRect(&paint_bounds);
31  auto input_filter_bounds = paint_bounds.roundOut();
32  auto filter = filter_->makeWithLocalMatrix(context->GetTransform());
33 
34  auto filter_bounds = // in screen coordinates
35  filter->filterBounds(input_filter_bounds, SkMatrix::I(),
36  SkImageFilter::kReverse_MapDirection);
37 
38  context->AddReadbackRegion(filter_bounds);
39 
40  DiffChildren(context, prev);
41 
42  context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
43 }
44 
45 #endif // FLUTTER_ENABLE_DIFF_CONTEXT
46 
48  const SkMatrix& matrix) {
50  Layer::AutoPrerollSaveLayerState::Create(context, true, bool(filter_));
51  SkRect child_paint_bounds = SkRect::MakeEmpty();
52  PrerollChildren(context, matrix, &child_paint_bounds);
53  child_paint_bounds.join(context->cull_rect);
54  set_paint_bounds(child_paint_bounds);
55 }
56 
58  TRACE_EVENT0("flutter", "BackdropFilterLayer::Paint");
59  FML_DCHECK(needs_painting(context));
60 
61  SkPaint paint;
62  paint.setBlendMode(blend_mode_);
64  context,
65  SkCanvas::SaveLayerRec{&paint_bounds(), &paint, filter_.get(), 0},
66  // BackdropFilter should only happen on the leaf nodes canvas.
67  // See https:://flutter.dev/go/backdrop-filter-with-overlay-canvas
68  AutoSaveLayer::SaveMode::kLeafNodesCanvas);
69  PaintChildren(context);
70 }
71 
72 } // namespace flutter
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
#define FML_DCHECK(condition)
Definition: logging.h:86
void Paint(PaintContext &context) const override
Definition: ref_ptr.h:252
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
void Preroll(PrerollContext *context, const SkMatrix &matrix) override
bool needs_painting(PaintContext &context) const
Definition: layer.h:249
static AutoPrerollSaveLayerState Create(PrerollContext *preroll_context, bool save_layer_is_active=true, bool layer_itself_performs_readback=false)
Definition: layer.cc:44
const SkRect & paint_bounds() const
Definition: layer.h:227
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:240
BackdropFilterLayer(sk_sp< SkImageFilter > filter, SkBlendMode blend_mode)
void PaintChildren(PaintContext &context) const
static AutoSaveLayer Create(const PaintContext &paint_context, const SkRect &bounds, const SkPaint *paint, SaveMode save_mode=SaveMode::kInternalNodesCanvas)
Definition: layer.cc:82