Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ FILE: ../../../flutter/flow/layers/layer.cc
FILE: ../../../flutter/flow/layers/layer.h
FILE: ../../../flutter/flow/layers/layer_raster_cache_item.cc
FILE: ../../../flutter/flow/layers/layer_raster_cache_item.h
FILE: ../../../flutter/flow/layers/layer_state_stack.cc
FILE: ../../../flutter/flow/layers/layer_state_stack.h
FILE: ../../../flutter/flow/layers/layer_tree.cc
FILE: ../../../flutter/flow/layers/layer_tree.h
FILE: ../../../flutter/flow/layers/layer_tree_unittests.cc
Expand Down
11 changes: 11 additions & 0 deletions display_list/display_list_color_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ class DlColorFilter
// pixels non-transparent and therefore expand the bounds.
virtual bool modifies_transparent_black() const = 0;

// Return a boolean indicating whether the color filtering operation can
// be applied either before or after modulating the pixels with an opacity
// value without changing the operation.
virtual bool can_commute_with_alpha() const { return false; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, if mostly CF can commute with alpha, but if the CF is a MtrixCF and has specific alpha in the matrix it should not commute with alpha?


// Return a DlBlendColorFilter pointer to this object iff it is a Blend
// type of ColorFilter, otherwise return nullptr.
virtual const DlBlendColorFilter* asBlend() const { return nullptr; }
Expand Down Expand Up @@ -150,6 +155,12 @@ class DlMatrixColorFilter final : public DlColorFilter {
sk_filter->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
}

bool can_commute_with_alpha() const override {
return matrix_[3] == 0 && matrix_[8] == 0 && matrix_[13] == 0 &&
matrix_[15] == 0 && matrix_[16] == 0 && matrix_[17] == 0 &&
(matrix_[18] >= 0.0 && matrix_[18] <= 1.0) && matrix_[19] == 0;
}

std::shared_ptr<DlColorFilter> shared() const override {
return std::make_shared<DlMatrixColorFilter>(this);
}
Expand Down
8 changes: 6 additions & 2 deletions display_list/display_list_paint.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ class DlPaint {
color_.argb = alpha << 24 | (color_.argb & 0x00FFFFFF);
return *this;
}
DlPaint& setOpacity(SkScalar opacity) {
setAlpha(SkScalarRoundToInt(opacity * 0xff));
return *this;
}

DlBlendMode getBlendMode() const {
return static_cast<DlBlendMode>(blendMode_);
Expand Down Expand Up @@ -166,7 +170,7 @@ class DlPaint {
return colorFilter_;
}
const DlColorFilter* getColorFilterPtr() const { return colorFilter_.get(); }
DlPaint& setColorFilter(std::shared_ptr<DlColorFilter> filter) {
DlPaint& setColorFilter(const std::shared_ptr<const DlColorFilter> filter) {
colorFilter_ = filter ? filter->shared() : nullptr;
return *this;
}
Expand All @@ -179,7 +183,7 @@ class DlPaint {
return imageFilter_;
}
const DlImageFilter* getImageFilterPtr() const { return imageFilter_.get(); }
DlPaint& setImageFilter(std::shared_ptr<DlImageFilter> filter) {
DlPaint& setImageFilter(const std::shared_ptr<const DlImageFilter> filter) {
imageFilter_ = filter;
return *this;
}
Expand Down
23 changes: 10 additions & 13 deletions display_list/display_list_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,6 @@

namespace flutter {

// clang-format off
constexpr float kInvertColorMatrix[20] = {
-1.0, 0, 0, 1.0, 0,
0, -1.0, 0, 1.0, 0,
0, 0, -1.0, 1.0, 0,
1.0, 1.0, 1.0, 1.0, 0
};
// clang-format on

void SkPaintDispatchHelper::save_opacity(SkScalar child_opacity) {
save_stack_.emplace_back(opacity_);
set_opacity(child_opacity);
Expand Down Expand Up @@ -96,13 +87,19 @@ void SkPaintDispatchHelper::setMaskFilter(const DlMaskFilter* filter) {
}

sk_sp<SkColorFilter> SkPaintDispatchHelper::makeColorFilter() const {
if (!invert_colors_) {
return color_filter_ ? color_filter_->skia_object() : nullptr;
return MakeColorFilter(invert_colors_, color_filter_.get());
}

sk_sp<SkColorFilter> SkPaintDispatchHelper::MakeColorFilter(
bool isInvertColors,
const DlColorFilter* color_filter) {
if (!isInvertColors) {
return color_filter ? color_filter->skia_object() : nullptr;
}
sk_sp<SkColorFilter> invert_filter =
SkColorFilters::Matrix(kInvertColorMatrix);
if (color_filter_) {
invert_filter = invert_filter->makeComposed(color_filter_->skia_object());
if (color_filter) {
invert_filter = invert_filter->makeComposed(color_filter->skia_object());
}
return invert_filter;
}
Expand Down
12 changes: 12 additions & 0 deletions display_list/display_list_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ class SkPaintDispatchHelper : public virtual Dispatcher {
}
}

// clang-format off
static constexpr float kInvertColorMatrix[20] = {
-1.0, 0, 0, 1.0, 0,
0, -1.0, 0, 1.0, 0,
0, 0, -1.0, 1.0, 0,
1.0, 1.0, 1.0, 1.0, 0
};
// clang-format on
static sk_sp<SkColorFilter> MakeColorFilter(
bool isInvertColors,
const DlColorFilter* color_filter);

void setAntiAlias(bool aa) override;
void setDither(bool dither) override;
void setStyle(DlDrawStyle style) override;
Expand Down
2 changes: 2 additions & 0 deletions flow/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ source_set("flow") {
"layers/layer.h",
"layers/layer_raster_cache_item.cc",
"layers/layer_raster_cache_item.h",
"layers/layer_state_stack.cc",
"layers/layer_state_stack.h",
"layers/layer_tree.cc",
"layers/layer_tree.h",
"layers/offscreen_surface.cc",
Expand Down
29 changes: 4 additions & 25 deletions flow/layers/backdrop_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,38 +47,17 @@ void BackdropFilterLayer::Preroll(PrerollContext* context,
PrerollChildren(context, matrix, &child_paint_bounds);
child_paint_bounds.join(context->cull_rect);
set_paint_bounds(child_paint_bounds);
context->subtree_can_inherit_opacity = true;
context->renderable_state_flags = SAVE_LAYER_RENDER_FLAGS;
}

void BackdropFilterLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "BackdropFilterLayer::Paint");
FML_DCHECK(needs_painting(context));

AutoCachePaint save_paint(context);
save_paint.setBlendMode(blend_mode_);
if (context.leaf_nodes_builder) {
// Note that we perform a saveLayer directly on the
// leaf_nodes_builder here similar to how the SkCanvas
// path specifies the kLeafNodesCanvas below.
// See https:://flutter.dev/go/backdrop-filter-with-overlay-canvas
context.leaf_nodes_builder->saveLayer(&paint_bounds(),
save_paint.dl_paint(), filter_.get());
auto mutator = context.state_stack.save();
mutator.applyBackdropFilter(paint_bounds(), filter_, blend_mode_);

PaintChildren(context);

context.leaf_nodes_builder->restore();
} else {
auto sk_filter = filter_ ? filter_->skia_object() : nullptr;
Layer::AutoSaveLayer save = Layer::AutoSaveLayer::Create(
context,
SkCanvas::SaveLayerRec{&paint_bounds(), save_paint.sk_paint(),
sk_filter.get(), 0},
// BackdropFilter should only happen on the leaf nodes canvas.
// See https:://flutter.dev/go/backdrop-filter-with-overlay-canvas
AutoSaveLayer::SaveMode::kLeafNodesCanvas);

PaintChildren(context);
}
PaintChildren(context);
}

} // namespace flutter
2 changes: 1 addition & 1 deletion flow/layers/backdrop_filter_layer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ TEST_F(BackdropFilterLayerTest, OpacityInheritance) {
parent->Add(layer);
clip->Add(parent);

clip->Preroll(preroll_context(), SkMatrix::I());
clip->Preroll(display_list_preroll_context(), SkMatrix::I());

clip->Paint(display_list_paint_context());

Expand Down
26 changes: 12 additions & 14 deletions flow/layers/checkerboard_layertree_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace testing {
using CheckerBoardLayerTest = LayerTest;

#ifndef NDEBUG
TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
Expand Down Expand Up @@ -68,7 +68,7 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect cull_bounds = SkRect::MakeXYWH(0.0, 0.0, 2.0, 4.0);
const SkRect child_bounds = SkRect::MakeXYWH(2.5, 5.0, 4.5, 4.0);
Expand Down Expand Up @@ -100,7 +100,7 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) {
EXPECT_EQ(mock_layer->parent_mutators(),
std::vector({Mutator(layer_bounds)}));

layer->Paint(check_board_context());
layer->Paint(checkerboard_context());

EXPECT_NE(
mock_canvas().draw_calls(),
Expand All @@ -118,7 +118,7 @@ TEST_F(CheckerBoardLayerTest, ClipRectSaveLayerCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
Expand Down Expand Up @@ -159,7 +159,7 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
Expand All @@ -183,7 +183,7 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) {
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_path)}));

layer->Paint(check_board_context());
layer->Paint(checkerboard_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
Expand All @@ -200,7 +200,7 @@ TEST_F(CheckerBoardLayerTest, ClipPathSaveLayerCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
Expand Down Expand Up @@ -241,7 +241,7 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) {
TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckerBoard) {
const SkMatrix initial_matrix = SkMatrix::Translate(0.5f, 1.0f);
const SkRect child_bounds = SkRect::MakeXYWH(1.0, 2.0, 2.0, 2.0);
const SkRect layer_bounds = SkRect::MakeXYWH(0.5, 1.0, 5.0, 6.0);
Expand All @@ -265,7 +265,7 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) {
EXPECT_EQ(mock_layer->parent_matrix(), initial_matrix);
EXPECT_EQ(mock_layer->parent_mutators(), std::vector({Mutator(layer_rrect)}));

layer->Paint(check_board_context());
layer->Paint(checkerboard_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
Expand All @@ -282,7 +282,7 @@ TEST_F(CheckerBoardLayerTest, ClipRRectSaveLayerCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) {
TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckerBoard) {
constexpr float initial_elevation = 20.0f;
SkPath layer_path;
layer_path.addRect(0, 0, 8, 8).close();
Expand All @@ -303,7 +303,6 @@ TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) {
const SkPaint clip_paint;
SkPaint layer_paint;
layer_paint.setColor(SK_ColorGREEN);
layer_paint.setAntiAlias(true);
layer->Paint(paint_context());
EXPECT_EQ(
mock_canvas().draw_calls(),
Expand All @@ -321,7 +320,7 @@ TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerNotCheckBoard) {
MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}));
}

TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) {
TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckerBoard) {
constexpr float initial_elevation = 20.0f;
SkPath layer_path;
layer_path.addRect(0, 0, 8, 8).close();
Expand All @@ -342,8 +341,7 @@ TEST_F(CheckerBoardLayerTest, PhysicalSaveLayerCheckBoard) {
const SkPaint clip_paint;
SkPaint layer_paint;
layer_paint.setColor(SK_ColorGREEN);
layer_paint.setAntiAlias(true);
layer->Paint(check_board_context());
layer->Paint(checkerboard_context());
EXPECT_NE(
mock_canvas().draw_calls(),
std::vector(
Expand Down
5 changes: 3 additions & 2 deletions flow/layers/clip_path_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ void ClipPathLayer::OnMutatorsStackPushClipShape(
mutators_stack.PushClipPath(clip_shape());
}

void ClipPathLayer::OnCanvasClipShape(SkCanvas* canvas) const {
canvas->clipPath(clip_shape(), clip_behavior() != Clip::hardEdge);
void ClipPathLayer::OnStackClipShape(
LayerStateStack::MutatorContext& mutator) const {
mutator.clipPath(clip_shape(), clip_behavior() != Clip::hardEdge);
}

} // namespace flutter
3 changes: 2 additions & 1 deletion flow/layers/clip_path_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ class ClipPathLayer : public ClipShapeLayer<SkPath> {

void OnMutatorsStackPushClipShape(MutatorsStack& mutators_stack) override;

void OnCanvasClipShape(SkCanvas* canvas) const override;
void OnStackClipShape(
LayerStateStack::MutatorContext& mutator) const override;

private:
FML_DISALLOW_COPY_AND_ASSIGN(ClipPathLayer);
Expand Down
Loading