[Impeller] remove aiks color_filter and image_filter types. (flutter/engine#55654)
Like the color_source, these classes are just copies of the DL types. Use the DLTypes instead. Part of https://github.com/flutter/flutter/issues/142054
This commit is contained in:
parent
248c2a7062
commit
fd33d17487
@ -9,8 +9,10 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "display_list/effects/dl_color_source.h"
|
#include "display_list/effects/dl_color_source.h"
|
||||||
|
#include "display_list/effects/dl_image_filter.h"
|
||||||
#include "flutter/fml/logging.h"
|
#include "flutter/fml/logging.h"
|
||||||
#include "flutter/fml/trace_event.h"
|
#include "flutter/fml/trace_event.h"
|
||||||
|
#include "impeller/display_list/color_filter.h"
|
||||||
#include "impeller/display_list/image_filter.h"
|
#include "impeller/display_list/image_filter.h"
|
||||||
#include "impeller/display_list/skia_conversions.h"
|
#include "impeller/display_list/skia_conversions.h"
|
||||||
#include "impeller/entity/contents/atlas_contents.h"
|
#include "impeller/entity/contents/atlas_contents.h"
|
||||||
@ -41,12 +43,18 @@ static std::shared_ptr<Contents> CreateContentsForGeometryWithFilters(
|
|||||||
// Attempt to apply the color filter on the CPU first.
|
// Attempt to apply the color filter on the CPU first.
|
||||||
// Note: This is not just an optimization; some color sources rely on
|
// Note: This is not just an optimization; some color sources rely on
|
||||||
// CPU-applied color filters to behave properly.
|
// CPU-applied color filters to behave properly.
|
||||||
bool needs_color_filter = paint.HasColorFilter();
|
bool needs_color_filter = paint.color_filter || paint.invert_colors;
|
||||||
if (needs_color_filter) {
|
if (needs_color_filter &&
|
||||||
auto color_filter = paint.GetColorFilter();
|
contents->ApplyColorFilter([&](Color color) -> Color {
|
||||||
if (contents->ApplyColorFilter(color_filter->GetCPUColorFilterProc())) {
|
if (paint.color_filter) {
|
||||||
needs_color_filter = false;
|
color = GetCPUColorFilterProc(paint.color_filter)(color);
|
||||||
}
|
}
|
||||||
|
if (paint.invert_colors) {
|
||||||
|
color = color.ApplyColorMatrix(kColorInversion);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
})) {
|
||||||
|
needs_color_filter = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_apply_mask_filter = geometry->CanApplyMaskFilter();
|
bool can_apply_mask_filter = geometry->CanApplyMaskFilter();
|
||||||
@ -57,24 +65,32 @@ static std::shared_ptr<Contents> CreateContentsForGeometryWithFilters(
|
|||||||
// we need to be careful to only apply the color filter to the source
|
// we need to be careful to only apply the color filter to the source
|
||||||
// colors. CreateMaskBlur is able to handle this case.
|
// colors. CreateMaskBlur is able to handle this case.
|
||||||
return paint.mask_blur_descriptor->CreateMaskBlur(
|
return paint.mask_blur_descriptor->CreateMaskBlur(
|
||||||
contents, needs_color_filter ? paint.GetColorFilter() : nullptr);
|
contents, needs_color_filter ? paint.color_filter : nullptr,
|
||||||
|
needs_color_filter ? paint.invert_colors : false);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Contents> contents_copy = std::move(contents);
|
std::shared_ptr<Contents> contents_copy = std::move(contents);
|
||||||
|
|
||||||
// Image input types will directly set their color filter,
|
// Image input types will directly set their color filter,
|
||||||
// if any. See `TiledTextureContents.SetColorFilter`.
|
// if any. See `TiledTextureContents.SetColorFilter`.
|
||||||
if (needs_color_filter &&
|
if (needs_color_filter &&
|
||||||
(!paint.color_source ||
|
(!paint.color_source ||
|
||||||
paint.color_source->type() != flutter::DlColorSourceType::kImage)) {
|
paint.color_source->type() != flutter::DlColorSourceType::kImage)) {
|
||||||
std::shared_ptr<ColorFilter> color_filter = paint.GetColorFilter();
|
if (paint.color_filter) {
|
||||||
contents_copy = color_filter->WrapWithGPUColorFilter(
|
contents_copy = WrapWithGPUColorFilter(
|
||||||
FilterInput::Make(std::move(contents_copy)),
|
paint.color_filter, FilterInput::Make(std::move(contents_copy)),
|
||||||
ColorFilterContents::AbsorbOpacity::kYes);
|
ColorFilterContents::AbsorbOpacity::kYes);
|
||||||
}
|
}
|
||||||
|
if (paint.invert_colors) {
|
||||||
|
contents_copy =
|
||||||
|
WrapWithInvertColors(FilterInput::Make(contents_copy),
|
||||||
|
ColorFilterContents::AbsorbOpacity::kYes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (paint.image_filter) {
|
if (paint.image_filter) {
|
||||||
std::shared_ptr<FilterContents> filter = paint.image_filter->WrapInput(
|
std::shared_ptr<FilterContents> filter = WrapInput(
|
||||||
FilterInput::Make(std::move(contents_copy)));
|
paint.image_filter, FilterInput::Make(std::move(contents_copy)));
|
||||||
filter->SetRenderingMode(Entity::RenderingMode::kDirect);
|
filter->SetRenderingMode(Entity::RenderingMode::kDirect);
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
@ -471,12 +487,13 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
|
|||||||
|
|
||||||
// For symmetrically mask blurred solid RRects, absorb the mask blur and use
|
// For symmetrically mask blurred solid RRects, absorb the mask blur and use
|
||||||
// a faster SDF approximation.
|
// a faster SDF approximation.
|
||||||
|
Color rrect_color = paint.color;
|
||||||
Color rrect_color =
|
if (paint.invert_colors) {
|
||||||
paint.HasColorFilter()
|
rrect_color = rrect_color.ApplyColorMatrix(kColorInversion);
|
||||||
// Absorb the color filter, if any.
|
}
|
||||||
? paint.GetColorFilter()->GetCPUColorFilterProc()(paint.color)
|
if (paint.color_filter) {
|
||||||
: paint.color;
|
rrect_color = GetCPUColorFilterProc(paint.color_filter)(rrect_color);
|
||||||
|
}
|
||||||
|
|
||||||
Paint rrect_paint = {.mask_blur_descriptor = paint.mask_blur_descriptor};
|
Paint rrect_paint = {.mask_blur_descriptor = paint.mask_blur_descriptor};
|
||||||
|
|
||||||
@ -512,11 +529,13 @@ bool Canvas::AttemptDrawBlurredRRect(const Rect& rect,
|
|||||||
render_bounds.Expand(paint.mask_blur_descriptor->sigma.sigma * 4.0);
|
render_bounds.Expand(paint.mask_blur_descriptor->sigma.sigma * 4.0);
|
||||||
}
|
}
|
||||||
// Defer the alpha, blend mode, and image filter to a separate layer.
|
// Defer the alpha, blend mode, and image filter to a separate layer.
|
||||||
SaveLayer({.color = Color::White().WithAlpha(rrect_color.alpha),
|
SaveLayer(
|
||||||
|
Paint{
|
||||||
|
.color = Color::White().WithAlpha(rrect_color.alpha),
|
||||||
|
.image_filter = paint.image_filter,
|
||||||
.blend_mode = paint.blend_mode,
|
.blend_mode = paint.blend_mode,
|
||||||
.image_filter = paint.image_filter},
|
},
|
||||||
render_bounds, nullptr, ContentBoundsPromise::kContainsContents,
|
render_bounds, nullptr, ContentBoundsPromise::kContainsContents, 1u);
|
||||||
1u);
|
|
||||||
rrect_paint.color = rrect_color.WithAlpha(1);
|
rrect_paint.color = rrect_color.WithAlpha(1);
|
||||||
} else {
|
} else {
|
||||||
rrect_paint.color = rrect_color;
|
rrect_paint.color = rrect_color;
|
||||||
@ -892,8 +911,9 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
|
|||||||
auto src_paint = paint;
|
auto src_paint = paint;
|
||||||
src_paint.color = paint.color.WithAlpha(1.0);
|
src_paint.color = paint.color.WithAlpha(1.0);
|
||||||
|
|
||||||
std::shared_ptr<Contents> src_contents =
|
std::shared_ptr<ColorSourceContents> src_contents =
|
||||||
src_paint.CreateContentsForGeometry(vertices);
|
src_paint.CreateContents();
|
||||||
|
src_contents->SetGeometry(vertices);
|
||||||
|
|
||||||
// If the color source has an intrinsic size, then we use that to
|
// If the color source has an intrinsic size, then we use that to
|
||||||
// create the src contents as a simplification. Otherwise we use
|
// create the src contents as a simplification. Otherwise we use
|
||||||
@ -912,8 +932,8 @@ void Canvas::DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
|
|||||||
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
// NOLINTNEXTLINE(bugprone-unchecked-optional-access)
|
||||||
vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
|
vertices->GetTextureCoordinateCoverge().value_or(cvg.value());
|
||||||
}
|
}
|
||||||
src_contents = src_paint.CreateContentsForGeometry(
|
src_contents = src_paint.CreateContents();
|
||||||
Geometry::MakeRect(Rect::Round(src_coverage)));
|
src_contents->SetGeometry(Geometry::MakeRect(Rect::Round(src_coverage)));
|
||||||
|
|
||||||
auto contents = std::make_shared<VerticesSimpleBlendContents>();
|
auto contents = std::make_shared<VerticesSimpleBlendContents>();
|
||||||
contents->SetBlendMode(blend_mode);
|
contents->SetBlendMode(blend_mode);
|
||||||
@ -1049,7 +1069,7 @@ std::optional<Rect> Canvas::GetLocalCoverageLimit() const {
|
|||||||
|
|
||||||
void Canvas::SaveLayer(const Paint& paint,
|
void Canvas::SaveLayer(const Paint& paint,
|
||||||
std::optional<Rect> bounds,
|
std::optional<Rect> bounds,
|
||||||
const std::shared_ptr<ImageFilter>& backdrop_filter,
|
const flutter::DlImageFilter* backdrop_filter,
|
||||||
ContentBoundsPromise bounds_promise,
|
ContentBoundsPromise bounds_promise,
|
||||||
uint32_t total_content_depth,
|
uint32_t total_content_depth,
|
||||||
bool can_distribute_opacity) {
|
bool can_distribute_opacity) {
|
||||||
@ -1125,10 +1145,10 @@ void Canvas::SaveLayer(const Paint& paint,
|
|||||||
if (backdrop_filter) {
|
if (backdrop_filter) {
|
||||||
local_position = subpass_coverage.GetOrigin() - GetGlobalPassPosition();
|
local_position = subpass_coverage.GetOrigin() - GetGlobalPassPosition();
|
||||||
Canvas::BackdropFilterProc backdrop_filter_proc =
|
Canvas::BackdropFilterProc backdrop_filter_proc =
|
||||||
[backdrop_filter = backdrop_filter->Clone()](
|
[backdrop_filter = backdrop_filter](
|
||||||
const FilterInput::Ref& input, const Matrix& effect_transform,
|
const FilterInput::Ref& input, const Matrix& effect_transform,
|
||||||
Entity::RenderingMode rendering_mode) {
|
Entity::RenderingMode rendering_mode) {
|
||||||
auto filter = backdrop_filter->WrapInput(input);
|
auto filter = WrapInput(backdrop_filter, input);
|
||||||
filter->SetEffectTransform(effect_transform);
|
filter->SetEffectTransform(effect_transform);
|
||||||
filter->SetRenderingMode(rendering_mode);
|
filter->SetRenderingMode(rendering_mode);
|
||||||
return filter;
|
return filter;
|
||||||
|
@ -11,8 +11,8 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "display_list/effects/dl_image_filter.h"
|
||||||
#include "impeller/core/sampler_descriptor.h"
|
#include "impeller/core/sampler_descriptor.h"
|
||||||
#include "impeller/display_list/image_filter.h"
|
|
||||||
#include "impeller/display_list/paint.h"
|
#include "impeller/display_list/paint.h"
|
||||||
#include "impeller/entity/contents/atlas_contents.h"
|
#include "impeller/entity/contents/atlas_contents.h"
|
||||||
#include "impeller/entity/entity.h"
|
#include "impeller/entity/entity.h"
|
||||||
@ -132,7 +132,7 @@ class Canvas {
|
|||||||
void SaveLayer(
|
void SaveLayer(
|
||||||
const Paint& paint,
|
const Paint& paint,
|
||||||
std::optional<Rect> bounds = std::nullopt,
|
std::optional<Rect> bounds = std::nullopt,
|
||||||
const std::shared_ptr<ImageFilter>& backdrop_filter = nullptr,
|
const flutter::DlImageFilter* backdrop_filter = nullptr,
|
||||||
ContentBoundsPromise bounds_promise = ContentBoundsPromise::kUnknown,
|
ContentBoundsPromise bounds_promise = ContentBoundsPromise::kUnknown,
|
||||||
uint32_t total_content_depth = kMaxDepth,
|
uint32_t total_content_depth = kMaxDepth,
|
||||||
bool can_distribute_opacity = false);
|
bool can_distribute_opacity = false);
|
||||||
|
@ -3,14 +3,9 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "flutter/testing/testing.h"
|
#include "flutter/testing/testing.h"
|
||||||
#include "impeller/display_list/aiks_context.h"
|
|
||||||
#include "impeller/display_list/aiks_unittests.h"
|
#include "impeller/display_list/aiks_unittests.h"
|
||||||
#include "impeller/display_list/canvas.h"
|
#include "impeller/display_list/canvas.h"
|
||||||
#include "impeller/geometry/geometry_asserts.h"
|
#include "impeller/geometry/geometry_asserts.h"
|
||||||
#include "impeller/geometry/path_builder.h"
|
|
||||||
|
|
||||||
// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
|
|
||||||
// NOLINTBEGIN(bugprone-unchecked-optional-access)
|
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
namespace testing {
|
namespace testing {
|
||||||
@ -98,34 +93,5 @@ TEST_P(AiksTest, CanvasCTMCanBeUpdated) {
|
|||||||
Matrix::MakeTranslation({100.0, 100.0, 0.0}));
|
Matrix::MakeTranslation({100.0, 100.0, 0.0}));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(AiksTest, PaintWithFilters) {
|
|
||||||
// validate that a paint with a color filter "HasFilters", no other filters
|
|
||||||
// impact this setting.
|
|
||||||
Paint paint;
|
|
||||||
|
|
||||||
ASSERT_FALSE(paint.HasColorFilter());
|
|
||||||
|
|
||||||
paint.color_filter =
|
|
||||||
ColorFilter::MakeBlend(BlendMode::kSourceOver, Color::Blue());
|
|
||||||
|
|
||||||
ASSERT_TRUE(paint.HasColorFilter());
|
|
||||||
|
|
||||||
paint.image_filter = ImageFilter::MakeBlur(Sigma(1.0), Sigma(1.0),
|
|
||||||
FilterContents::BlurStyle::kNormal,
|
|
||||||
Entity::TileMode::kClamp);
|
|
||||||
|
|
||||||
ASSERT_TRUE(paint.HasColorFilter());
|
|
||||||
|
|
||||||
paint.mask_blur_descriptor = {};
|
|
||||||
|
|
||||||
ASSERT_TRUE(paint.HasColorFilter());
|
|
||||||
|
|
||||||
paint.color_filter = nullptr;
|
|
||||||
|
|
||||||
ASSERT_FALSE(paint.HasColorFilter());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
|
||||||
// NOLINTEND(bugprone-unchecked-optional-access)
|
|
||||||
|
@ -4,187 +4,99 @@
|
|||||||
|
|
||||||
#include "impeller/display_list/color_filter.h"
|
#include "impeller/display_list/color_filter.h"
|
||||||
|
|
||||||
#include <utility>
|
#include "display_list/effects/dl_color_filter.h"
|
||||||
|
#include "fml/logging.h"
|
||||||
|
#include "impeller/display_list/skia_conversions.h"
|
||||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||||
#include "impeller/entity/contents/filters/filter_contents.h"
|
|
||||||
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
||||||
#include "impeller/geometry/color.h"
|
#include "impeller/geometry/color.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
/*******************************************************************************
|
std::shared_ptr<ColorFilterContents> WrapWithInvertColors(
|
||||||
******* ColorFilter
|
const std::shared_ptr<FilterInput>& input,
|
||||||
******************************************************************************/
|
ColorFilterContents::AbsorbOpacity absorb_opacity) {
|
||||||
|
auto filter = ColorFilterContents::MakeColorMatrix({input}, kColorInversion);
|
||||||
ColorFilter::ColorFilter() = default;
|
|
||||||
|
|
||||||
ColorFilter::~ColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> ColorFilter::MakeBlend(BlendMode blend_mode,
|
|
||||||
Color color) {
|
|
||||||
return std::make_shared<BlendColorFilter>(blend_mode, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> ColorFilter::MakeMatrix(ColorMatrix color_matrix) {
|
|
||||||
return std::make_shared<MatrixColorFilter>(color_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> ColorFilter::MakeSrgbToLinear() {
|
|
||||||
return std::make_shared<SrgbToLinearColorFilter>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> ColorFilter::MakeLinearToSrgb() {
|
|
||||||
return std::make_shared<LinearToSrgbColorFilter>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> ColorFilter::MakeComposed(
|
|
||||||
const std::shared_ptr<ColorFilter>& outer,
|
|
||||||
const std::shared_ptr<ColorFilter>& inner) {
|
|
||||||
return std::make_shared<ComposedColorFilter>(outer, inner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* BlendColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
BlendColorFilter::BlendColorFilter(BlendMode blend_mode, Color color)
|
|
||||||
: blend_mode_(blend_mode), color_(color) {}
|
|
||||||
|
|
||||||
BlendColorFilter::~BlendColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilterContents> BlendColorFilter::WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const {
|
|
||||||
auto filter =
|
|
||||||
ColorFilterContents::MakeBlend(blend_mode_, {std::move(input)}, color_);
|
|
||||||
filter->SetAbsorbOpacity(absorb_opacity);
|
filter->SetAbsorbOpacity(absorb_opacity);
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorFilter::ColorFilterProc BlendColorFilter::GetCPUColorFilterProc() const {
|
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
||||||
return [filter_blend_mode = blend_mode_, filter_color = color_](Color color) {
|
const flutter::DlColorFilter* filter,
|
||||||
|
const std::shared_ptr<FilterInput>& input,
|
||||||
|
ColorFilterContents::AbsorbOpacity absorb_opacity) {
|
||||||
|
FML_DCHECK(filter);
|
||||||
|
|
||||||
|
switch (filter->type()) {
|
||||||
|
case flutter::DlColorFilterType::kBlend: {
|
||||||
|
const flutter::DlBlendColorFilter* blend_filter = filter->asBlend();
|
||||||
|
FML_DCHECK(blend_filter);
|
||||||
|
|
||||||
|
auto filter = ColorFilterContents::MakeBlend(
|
||||||
|
static_cast<BlendMode>(blend_filter->mode()), {input},
|
||||||
|
skia_conversions::ToColor(blend_filter->color()));
|
||||||
|
filter->SetAbsorbOpacity(absorb_opacity);
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
case flutter::DlColorFilterType::kMatrix: {
|
||||||
|
const flutter::DlMatrixColorFilter* matrix_filter = filter->asMatrix();
|
||||||
|
FML_DCHECK(matrix_filter);
|
||||||
|
|
||||||
|
impeller::ColorMatrix color_matrix;
|
||||||
|
matrix_filter->get_matrix(color_matrix.array);
|
||||||
|
auto filter = ColorFilterContents::MakeColorMatrix({input}, color_matrix);
|
||||||
|
filter->SetAbsorbOpacity(absorb_opacity);
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
case flutter::DlColorFilterType::kSrgbToLinearGamma: {
|
||||||
|
auto filter = ColorFilterContents::MakeSrgbToLinearFilter({input});
|
||||||
|
filter->SetAbsorbOpacity(absorb_opacity);
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
case flutter::DlColorFilterType::kLinearToSrgbGamma: {
|
||||||
|
auto filter = ColorFilterContents::MakeLinearToSrgbFilter({input});
|
||||||
|
filter->SetAbsorbOpacity(absorb_opacity);
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FML_UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorFilterProc GetCPUColorFilterProc(const flutter::DlColorFilter* filter) {
|
||||||
|
FML_DCHECK(filter);
|
||||||
|
|
||||||
|
switch (filter->type()) {
|
||||||
|
case flutter::DlColorFilterType::kBlend: {
|
||||||
|
const flutter::DlBlendColorFilter* blend_filter = filter->asBlend();
|
||||||
|
FML_DCHECK(blend_filter);
|
||||||
|
|
||||||
|
return [filter_blend_mode = static_cast<BlendMode>(blend_filter->mode()),
|
||||||
|
filter_color = skia_conversions::ToColor(blend_filter->color())](
|
||||||
|
Color color) {
|
||||||
return color.Blend(filter_color, filter_blend_mode);
|
return color.Blend(filter_color, filter_blend_mode);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case flutter::DlColorFilterType::kMatrix: {
|
||||||
|
const flutter::DlMatrixColorFilter* matrix_filter = filter->asMatrix();
|
||||||
|
FML_DCHECK(matrix_filter);
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> BlendColorFilter::Clone() const {
|
impeller::ColorMatrix color_matrix;
|
||||||
return std::make_shared<BlendColorFilter>(*this);
|
matrix_filter->get_matrix(color_matrix.array);
|
||||||
}
|
return [color_matrix = color_matrix](Color color) {
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* MatrixColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
MatrixColorFilter::MatrixColorFilter(ColorMatrix color_matrix)
|
|
||||||
: color_matrix_(color_matrix) {}
|
|
||||||
|
|
||||||
MatrixColorFilter::~MatrixColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilterContents> MatrixColorFilter::WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const {
|
|
||||||
auto filter =
|
|
||||||
ColorFilterContents::MakeColorMatrix({std::move(input)}, color_matrix_);
|
|
||||||
filter->SetAbsorbOpacity(absorb_opacity);
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorFilter::ColorFilterProc MatrixColorFilter::GetCPUColorFilterProc() const {
|
|
||||||
return [color_matrix = color_matrix_](Color color) {
|
|
||||||
return color.ApplyColorMatrix(color_matrix);
|
return color.ApplyColorMatrix(color_matrix);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
case flutter::DlColorFilterType::kSrgbToLinearGamma: {
|
||||||
std::shared_ptr<ColorFilter> MatrixColorFilter::Clone() const {
|
|
||||||
return std::make_shared<MatrixColorFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* SrgbToLinearColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
SrgbToLinearColorFilter::SrgbToLinearColorFilter() = default;
|
|
||||||
|
|
||||||
SrgbToLinearColorFilter::~SrgbToLinearColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilterContents>
|
|
||||||
SrgbToLinearColorFilter::WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const {
|
|
||||||
auto filter = ColorFilterContents::MakeSrgbToLinearFilter({std::move(input)});
|
|
||||||
filter->SetAbsorbOpacity(absorb_opacity);
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorFilter::ColorFilterProc SrgbToLinearColorFilter::GetCPUColorFilterProc()
|
|
||||||
const {
|
|
||||||
return [](Color color) { return color.SRGBToLinear(); };
|
return [](Color color) { return color.SRGBToLinear(); };
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> SrgbToLinearColorFilter::Clone() const {
|
case flutter::DlColorFilterType::kLinearToSrgbGamma: {
|
||||||
return std::make_shared<SrgbToLinearColorFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* LinearToSrgbColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
LinearToSrgbColorFilter::LinearToSrgbColorFilter() = default;
|
|
||||||
|
|
||||||
LinearToSrgbColorFilter::~LinearToSrgbColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilterContents>
|
|
||||||
LinearToSrgbColorFilter::WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const {
|
|
||||||
auto filter = ColorFilterContents::MakeSrgbToLinearFilter({std::move(input)});
|
|
||||||
filter->SetAbsorbOpacity(absorb_opacity);
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorFilter::ColorFilterProc LinearToSrgbColorFilter::GetCPUColorFilterProc()
|
|
||||||
const {
|
|
||||||
return [](Color color) { return color.LinearToSRGB(); };
|
return [](Color color) { return color.LinearToSRGB(); };
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> LinearToSrgbColorFilter::Clone() const {
|
FML_UNREACHABLE();
|
||||||
return std::make_shared<LinearToSrgbColorFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ComposedColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
ComposedColorFilter::ComposedColorFilter(
|
|
||||||
const std::shared_ptr<ColorFilter>& outer,
|
|
||||||
const std::shared_ptr<ColorFilter>& inner)
|
|
||||||
: outer_(outer), inner_(inner) {}
|
|
||||||
|
|
||||||
ComposedColorFilter::~ComposedColorFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<ColorFilterContents>
|
|
||||||
ComposedColorFilter::WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const {
|
|
||||||
std::shared_ptr<FilterContents> inner = inner_->WrapWithGPUColorFilter(
|
|
||||||
input, ColorFilterContents::AbsorbOpacity::kNo);
|
|
||||||
return outer_->WrapWithGPUColorFilter(FilterInput::Make(inner),
|
|
||||||
absorb_opacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilter::ColorFilterProc ComposedColorFilter::GetCPUColorFilterProc()
|
|
||||||
const {
|
|
||||||
return [inner = inner_, outer = outer_](Color color) {
|
|
||||||
auto inner_proc = inner->GetCPUColorFilterProc();
|
|
||||||
auto outer_proc = outer->GetCPUColorFilterProc();
|
|
||||||
return outer_proc(inner_proc(color));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> ComposedColorFilter::Clone() const {
|
|
||||||
return std::make_shared<ComposedColorFilter>(outer_, inner_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -5,176 +5,37 @@
|
|||||||
#ifndef FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_FILTER_H_
|
#ifndef FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_FILTER_H_
|
||||||
#define FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_FILTER_H_
|
#define FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_FILTER_H_
|
||||||
|
|
||||||
|
#include "display_list/effects/dl_color_filter.h"
|
||||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||||
#include "impeller/geometry/color.h"
|
#include "impeller/geometry/color.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
struct Paint;
|
/// A color matrix which inverts colors.
|
||||||
|
// clang-format off
|
||||||
/*******************************************************************************
|
static const constexpr ColorMatrix kColorInversion = {
|
||||||
******* ColorFilter
|
.array = {
|
||||||
******************************************************************************/
|
-1.0, 0, 0, 1.0, 0, //
|
||||||
|
0, -1.0, 0, 1.0, 0, //
|
||||||
class ColorFilter {
|
0, 0, -1.0, 1.0, 0, //
|
||||||
public:
|
1.0, 1.0, 1.0, 1.0, 0 //
|
||||||
/// A procedure that filters a given unpremultiplied color to produce a new
|
}
|
||||||
/// unpremultiplied color.
|
|
||||||
using ColorFilterProc = std::function<Color(Color)>;
|
|
||||||
|
|
||||||
ColorFilter();
|
|
||||||
|
|
||||||
virtual ~ColorFilter();
|
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> MakeBlend(BlendMode blend_mode,
|
|
||||||
Color color);
|
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> MakeMatrix(ColorMatrix color_matrix);
|
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> MakeSrgbToLinear();
|
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> MakeLinearToSrgb();
|
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> MakeComposed(
|
|
||||||
const std::shared_ptr<ColorFilter>& outer,
|
|
||||||
const std::shared_ptr<ColorFilter>& inner);
|
|
||||||
|
|
||||||
/// @brief Wraps the given filter input with a GPU-based filter that will
|
|
||||||
/// perform the color operation. The given input will first be
|
|
||||||
/// rendered to a texture and then filtered.
|
|
||||||
///
|
|
||||||
/// Note that this operation has no consideration for the original
|
|
||||||
/// geometry mask of the filter input. And the entire input texture is
|
|
||||||
/// treated as color information.
|
|
||||||
virtual std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const = 0;
|
|
||||||
|
|
||||||
/// @brief Returns a function that can be used to filter unpremultiplied
|
|
||||||
/// Impeller Colors on the CPU.
|
|
||||||
virtual ColorFilterProc GetCPUColorFilterProc() const = 0;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<ColorFilter> Clone() const = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*******************************************************************************
|
std::shared_ptr<ColorFilterContents> WrapWithInvertColors(
|
||||||
******* BlendColorFilter
|
const std::shared_ptr<FilterInput>& input,
|
||||||
******************************************************************************/
|
ColorFilterContents::AbsorbOpacity absorb_opacity);
|
||||||
|
|
||||||
class BlendColorFilter final : public ColorFilter {
|
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
||||||
public:
|
const flutter::DlColorFilter* filter,
|
||||||
BlendColorFilter(BlendMode blend_mode, Color color);
|
const std::shared_ptr<FilterInput>& input,
|
||||||
|
ColorFilterContents::AbsorbOpacity absorb_opacity);
|
||||||
|
|
||||||
~BlendColorFilter() override;
|
/// A procedure that filters a given unpremultiplied color to produce a new
|
||||||
|
/// unpremultiplied color.
|
||||||
|
using ColorFilterProc = std::function<Color(Color)>;
|
||||||
|
|
||||||
// |ColorFilter|
|
ColorFilterProc GetCPUColorFilterProc(const flutter::DlColorFilter* filter);
|
||||||
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilterProc GetCPUColorFilterProc() const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
BlendMode blend_mode_;
|
|
||||||
Color color_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* MatrixColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class MatrixColorFilter final : public ColorFilter {
|
|
||||||
public:
|
|
||||||
explicit MatrixColorFilter(ColorMatrix color_matrix);
|
|
||||||
|
|
||||||
~MatrixColorFilter() override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilterProc GetCPUColorFilterProc() const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
ColorMatrix color_matrix_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* SrgbToLinearColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class SrgbToLinearColorFilter final : public ColorFilter {
|
|
||||||
public:
|
|
||||||
explicit SrgbToLinearColorFilter();
|
|
||||||
|
|
||||||
~SrgbToLinearColorFilter() override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilterProc GetCPUColorFilterProc() const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> Clone() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* LinearToSrgbColorFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class LinearToSrgbColorFilter final : public ColorFilter {
|
|
||||||
public:
|
|
||||||
explicit LinearToSrgbColorFilter();
|
|
||||||
|
|
||||||
~LinearToSrgbColorFilter() override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilterProc GetCPUColorFilterProc() const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> Clone() const override;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Applies color filters as f(g(x)), where x is the input color.
|
|
||||||
class ComposedColorFilter final : public ColorFilter {
|
|
||||||
public:
|
|
||||||
ComposedColorFilter(const std::shared_ptr<ColorFilter>& outer,
|
|
||||||
const std::shared_ptr<ColorFilter>& inner);
|
|
||||||
|
|
||||||
~ComposedColorFilter() override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilterContents> WrapWithGPUColorFilter(
|
|
||||||
std::shared_ptr<FilterInput> input,
|
|
||||||
ColorFilterContents::AbsorbOpacity absorb_opacity) const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
ColorFilterProc GetCPUColorFilterProc() const override;
|
|
||||||
|
|
||||||
// |ColorFilter|
|
|
||||||
std::shared_ptr<ColorFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<ColorFilter> outer_;
|
|
||||||
std::shared_ptr<ColorFilter> inner_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
|
||||||
|
@ -114,70 +114,6 @@ struct DepthWatcher {
|
|||||||
#define UNIMPLEMENTED \
|
#define UNIMPLEMENTED \
|
||||||
FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
|
FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__;
|
||||||
|
|
||||||
static BlendMode ToBlendMode(flutter::DlBlendMode mode) {
|
|
||||||
switch (mode) {
|
|
||||||
case flutter::DlBlendMode::kClear:
|
|
||||||
return BlendMode::kClear;
|
|
||||||
case flutter::DlBlendMode::kSrc:
|
|
||||||
return BlendMode::kSource;
|
|
||||||
case flutter::DlBlendMode::kDst:
|
|
||||||
return BlendMode::kDestination;
|
|
||||||
case flutter::DlBlendMode::kSrcOver:
|
|
||||||
return BlendMode::kSourceOver;
|
|
||||||
case flutter::DlBlendMode::kDstOver:
|
|
||||||
return BlendMode::kDestinationOver;
|
|
||||||
case flutter::DlBlendMode::kSrcIn:
|
|
||||||
return BlendMode::kSourceIn;
|
|
||||||
case flutter::DlBlendMode::kDstIn:
|
|
||||||
return BlendMode::kDestinationIn;
|
|
||||||
case flutter::DlBlendMode::kSrcOut:
|
|
||||||
return BlendMode::kSourceOut;
|
|
||||||
case flutter::DlBlendMode::kDstOut:
|
|
||||||
return BlendMode::kDestinationOut;
|
|
||||||
case flutter::DlBlendMode::kSrcATop:
|
|
||||||
return BlendMode::kSourceATop;
|
|
||||||
case flutter::DlBlendMode::kDstATop:
|
|
||||||
return BlendMode::kDestinationATop;
|
|
||||||
case flutter::DlBlendMode::kXor:
|
|
||||||
return BlendMode::kXor;
|
|
||||||
case flutter::DlBlendMode::kPlus:
|
|
||||||
return BlendMode::kPlus;
|
|
||||||
case flutter::DlBlendMode::kModulate:
|
|
||||||
return BlendMode::kModulate;
|
|
||||||
case flutter::DlBlendMode::kScreen:
|
|
||||||
return BlendMode::kScreen;
|
|
||||||
case flutter::DlBlendMode::kOverlay:
|
|
||||||
return BlendMode::kOverlay;
|
|
||||||
case flutter::DlBlendMode::kDarken:
|
|
||||||
return BlendMode::kDarken;
|
|
||||||
case flutter::DlBlendMode::kLighten:
|
|
||||||
return BlendMode::kLighten;
|
|
||||||
case flutter::DlBlendMode::kColorDodge:
|
|
||||||
return BlendMode::kColorDodge;
|
|
||||||
case flutter::DlBlendMode::kColorBurn:
|
|
||||||
return BlendMode::kColorBurn;
|
|
||||||
case flutter::DlBlendMode::kHardLight:
|
|
||||||
return BlendMode::kHardLight;
|
|
||||||
case flutter::DlBlendMode::kSoftLight:
|
|
||||||
return BlendMode::kSoftLight;
|
|
||||||
case flutter::DlBlendMode::kDifference:
|
|
||||||
return BlendMode::kDifference;
|
|
||||||
case flutter::DlBlendMode::kExclusion:
|
|
||||||
return BlendMode::kExclusion;
|
|
||||||
case flutter::DlBlendMode::kMultiply:
|
|
||||||
return BlendMode::kMultiply;
|
|
||||||
case flutter::DlBlendMode::kHue:
|
|
||||||
return BlendMode::kHue;
|
|
||||||
case flutter::DlBlendMode::kSaturation:
|
|
||||||
return BlendMode::kSaturation;
|
|
||||||
case flutter::DlBlendMode::kColor:
|
|
||||||
return BlendMode::kColor;
|
|
||||||
case flutter::DlBlendMode::kLuminosity:
|
|
||||||
return BlendMode::kLuminosity;
|
|
||||||
}
|
|
||||||
FML_UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
static impeller::SamplerDescriptor ToSamplerDescriptor(
|
static impeller::SamplerDescriptor ToSamplerDescriptor(
|
||||||
const flutter::DlFilterMode options) {
|
const flutter::DlFilterMode options) {
|
||||||
impeller::SamplerDescriptor desc;
|
impeller::SamplerDescriptor desc;
|
||||||
@ -289,37 +225,11 @@ void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<ColorFilter> ToColorFilter(
|
|
||||||
const flutter::DlColorFilter* filter) {
|
|
||||||
if (filter == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
switch (filter->type()) {
|
|
||||||
case flutter::DlColorFilterType::kBlend: {
|
|
||||||
auto dl_blend = filter->asBlend();
|
|
||||||
auto blend_mode = ToBlendMode(dl_blend->mode());
|
|
||||||
auto color = skia_conversions::ToColor(dl_blend->color());
|
|
||||||
return ColorFilter::MakeBlend(blend_mode, color);
|
|
||||||
}
|
|
||||||
case flutter::DlColorFilterType::kMatrix: {
|
|
||||||
const flutter::DlMatrixColorFilter* dl_matrix = filter->asMatrix();
|
|
||||||
impeller::ColorMatrix color_matrix;
|
|
||||||
dl_matrix->get_matrix(color_matrix.array);
|
|
||||||
return ColorFilter::MakeMatrix(color_matrix);
|
|
||||||
}
|
|
||||||
case flutter::DlColorFilterType::kSrgbToLinearGamma:
|
|
||||||
return ColorFilter::MakeSrgbToLinear();
|
|
||||||
case flutter::DlColorFilterType::kLinearToSrgbGamma:
|
|
||||||
return ColorFilter::MakeLinearToSrgb();
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::DlOpReceiver|
|
// |flutter::DlOpReceiver|
|
||||||
void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
|
void DlDispatcherBase::setColorFilter(const flutter::DlColorFilter* filter) {
|
||||||
AUTO_DEPTH_WATCHER(0u);
|
AUTO_DEPTH_WATCHER(0u);
|
||||||
|
|
||||||
paint_.color_filter = ToColorFilter(filter);
|
paint_.color_filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// |flutter::DlOpReceiver|
|
// |flutter::DlOpReceiver|
|
||||||
@ -333,7 +243,7 @@ void DlDispatcherBase::setInvertColors(bool invert) {
|
|||||||
void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
|
void DlDispatcherBase::setBlendMode(flutter::DlBlendMode dl_mode) {
|
||||||
AUTO_DEPTH_WATCHER(0u);
|
AUTO_DEPTH_WATCHER(0u);
|
||||||
|
|
||||||
paint_.blend_mode = ToBlendMode(dl_mode);
|
paint_.blend_mode = skia_conversions::ToBlendMode(dl_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
|
static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) {
|
||||||
@ -372,102 +282,11 @@ void DlDispatcherBase::setMaskFilter(const flutter::DlMaskFilter* filter) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> ToImageFilter(
|
|
||||||
const flutter::DlImageFilter* filter) {
|
|
||||||
if (filter == nullptr) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (filter->type()) {
|
|
||||||
case flutter::DlImageFilterType::kBlur: {
|
|
||||||
auto blur = filter->asBlur();
|
|
||||||
auto sigma_x = Sigma(blur->sigma_x());
|
|
||||||
auto sigma_y = Sigma(blur->sigma_y());
|
|
||||||
auto tile_mode = static_cast<Entity::TileMode>(blur->tile_mode());
|
|
||||||
return ImageFilter::MakeBlur(
|
|
||||||
sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kDilate: {
|
|
||||||
auto dilate = filter->asDilate();
|
|
||||||
FML_DCHECK(dilate);
|
|
||||||
if (dilate->radius_x() < 0 || dilate->radius_y() < 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto radius_x = Radius(dilate->radius_x());
|
|
||||||
auto radius_y = Radius(dilate->radius_y());
|
|
||||||
return ImageFilter::MakeDilate(radius_x, radius_y);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kErode: {
|
|
||||||
auto erode = filter->asErode();
|
|
||||||
FML_DCHECK(erode);
|
|
||||||
if (erode->radius_x() < 0 || erode->radius_y() < 0) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto radius_x = Radius(erode->radius_x());
|
|
||||||
auto radius_y = Radius(erode->radius_y());
|
|
||||||
return ImageFilter::MakeErode(radius_x, radius_y);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kMatrix: {
|
|
||||||
auto matrix_filter = filter->asMatrix();
|
|
||||||
FML_DCHECK(matrix_filter);
|
|
||||||
auto matrix = skia_conversions::ToMatrix(matrix_filter->matrix());
|
|
||||||
auto desc =
|
|
||||||
skia_conversions::ToSamplerDescriptor(matrix_filter->sampling());
|
|
||||||
return ImageFilter::MakeMatrix(matrix, desc);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kCompose: {
|
|
||||||
auto compose = filter->asCompose();
|
|
||||||
FML_DCHECK(compose);
|
|
||||||
auto outer_dl_filter = compose->outer();
|
|
||||||
auto inner_dl_filter = compose->inner();
|
|
||||||
auto outer_filter = ToImageFilter(outer_dl_filter.get());
|
|
||||||
auto inner_filter = ToImageFilter(inner_dl_filter.get());
|
|
||||||
if (!outer_filter) {
|
|
||||||
return inner_filter;
|
|
||||||
}
|
|
||||||
if (!inner_filter) {
|
|
||||||
return outer_filter;
|
|
||||||
}
|
|
||||||
FML_DCHECK(outer_filter && inner_filter);
|
|
||||||
|
|
||||||
return ImageFilter::MakeCompose(*inner_filter, *outer_filter);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kColorFilter: {
|
|
||||||
auto color_filter_image_filter = filter->asColorFilter();
|
|
||||||
FML_DCHECK(color_filter_image_filter);
|
|
||||||
auto color_filter =
|
|
||||||
ToColorFilter(color_filter_image_filter->color_filter().get());
|
|
||||||
if (!color_filter) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
// When color filters are used as image filters, set the color filter's
|
|
||||||
// "absorb opacity" flag to false. For image filters, the snapshot
|
|
||||||
// opacity needs to be deferred until the result of the filter chain is
|
|
||||||
// being blended with the layer.
|
|
||||||
return ImageFilter::MakeFromColorFilter(*color_filter);
|
|
||||||
}
|
|
||||||
case flutter::DlImageFilterType::kLocalMatrix: {
|
|
||||||
auto local_matrix_filter = filter->asLocalMatrix();
|
|
||||||
FML_DCHECK(local_matrix_filter);
|
|
||||||
auto internal_filter = local_matrix_filter->image_filter();
|
|
||||||
FML_DCHECK(internal_filter);
|
|
||||||
|
|
||||||
auto image_filter = ToImageFilter(internal_filter.get());
|
|
||||||
if (!image_filter) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto matrix = skia_conversions::ToMatrix(local_matrix_filter->matrix());
|
|
||||||
return ImageFilter::MakeLocalMatrix(matrix, *image_filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::DlOpReceiver|
|
// |flutter::DlOpReceiver|
|
||||||
void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
|
void DlDispatcherBase::setImageFilter(const flutter::DlImageFilter* filter) {
|
||||||
AUTO_DEPTH_WATCHER(0u);
|
AUTO_DEPTH_WATCHER(0u);
|
||||||
|
|
||||||
paint_.image_filter = ToImageFilter(filter);
|
paint_.image_filter = filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
// |flutter::DlOpReceiver|
|
// |flutter::DlOpReceiver|
|
||||||
@ -497,8 +316,7 @@ void DlDispatcherBase::saveLayer(const DlRect& bounds,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetCanvas().SaveLayer(
|
GetCanvas().SaveLayer(
|
||||||
paint, impeller_bounds, ToImageFilter(backdrop), promise,
|
paint, impeller_bounds, backdrop, promise, total_content_depth,
|
||||||
total_content_depth,
|
|
||||||
// Unbounded content can still have user specified bounds that require a
|
// Unbounded content can still have user specified bounds that require a
|
||||||
// saveLayer to be created to perform the clip.
|
// saveLayer to be created to perform the clip.
|
||||||
options.can_distribute_opacity() && !options.content_is_unbounded());
|
options.can_distribute_opacity() && !options.content_is_unbounded());
|
||||||
@ -674,7 +492,7 @@ void DlDispatcherBase::drawColor(flutter::DlColor color,
|
|||||||
|
|
||||||
Paint paint;
|
Paint paint;
|
||||||
paint.color = skia_conversions::ToColor(color);
|
paint.color = skia_conversions::ToColor(color);
|
||||||
paint.blend_mode = ToBlendMode(dl_mode);
|
paint.blend_mode = skia_conversions::ToBlendMode(dl_mode);
|
||||||
GetCanvas().DrawPaint(paint);
|
GetCanvas().DrawPaint(paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,7 +768,7 @@ void DlDispatcherBase::drawAtlas(const sk_sp<flutter::DlImage> atlas,
|
|||||||
tex, //
|
tex, //
|
||||||
colors, //
|
colors, //
|
||||||
static_cast<size_t>(count), //
|
static_cast<size_t>(count), //
|
||||||
ToBlendMode(mode), //
|
skia_conversions::ToBlendMode(mode), //
|
||||||
skia_conversions::ToSamplerDescriptor(sampling), //
|
skia_conversions::ToSamplerDescriptor(sampling), //
|
||||||
skia_conversions::ToRect(cull_rect) //
|
skia_conversions::ToRect(cull_rect) //
|
||||||
);
|
);
|
||||||
@ -1117,7 +935,8 @@ static bool RequiresReadbackForBlends(
|
|||||||
const ContentContext& renderer,
|
const ContentContext& renderer,
|
||||||
flutter::DlBlendMode max_root_blend_mode) {
|
flutter::DlBlendMode max_root_blend_mode) {
|
||||||
return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
|
return !renderer.GetDeviceCapabilities().SupportsFramebufferFetch() &&
|
||||||
ToBlendMode(max_root_blend_mode) > Entity::kLastPipelineBlendMode;
|
skia_conversions::ToBlendMode(max_root_blend_mode) >
|
||||||
|
Entity::kLastPipelineBlendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasDlDispatcher::CanvasDlDispatcher(ContentContext& renderer,
|
CanvasDlDispatcher::CanvasDlDispatcher(ContentContext& renderer,
|
||||||
@ -1143,7 +962,7 @@ void CanvasDlDispatcher::drawVertices(
|
|||||||
|
|
||||||
GetCanvas().DrawVertices(
|
GetCanvas().DrawVertices(
|
||||||
std::make_shared<DlVerticesGeometry>(vertices, renderer_),
|
std::make_shared<DlVerticesGeometry>(vertices, renderer_),
|
||||||
ToBlendMode(dl_mode), paint_);
|
skia_conversions::ToBlendMode(dl_mode), paint_);
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Text Frame Dispatcher
|
//// Text Frame Dispatcher
|
||||||
|
@ -3,206 +3,107 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "impeller/display_list/image_filter.h"
|
#include "impeller/display_list/image_filter.h"
|
||||||
|
#include "fml/logging.h"
|
||||||
|
#include "impeller/display_list/color_filter.h"
|
||||||
|
#include "impeller/display_list/skia_conversions.h"
|
||||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||||
#include "impeller/entity/contents/filters/filter_contents.h"
|
#include "impeller/entity/contents/filters/filter_contents.h"
|
||||||
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
#include "impeller/entity/contents/filters/inputs/filter_input.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
/*******************************************************************************
|
std::shared_ptr<FilterContents> WrapInput(const flutter::DlImageFilter* filter,
|
||||||
******* ImageFilter
|
const FilterInput::Ref& input) {
|
||||||
******************************************************************************/
|
FML_DCHECK(filter);
|
||||||
|
|
||||||
ImageFilter::ImageFilter() = default;
|
switch (filter->type()) {
|
||||||
|
case flutter::DlImageFilterType::kBlur: {
|
||||||
|
auto blur_filter = filter->asBlur();
|
||||||
|
FML_DCHECK(blur_filter);
|
||||||
|
|
||||||
ImageFilter::~ImageFilter() = default;
|
return FilterContents::MakeGaussianBlur(
|
||||||
|
input, //
|
||||||
|
Sigma(blur_filter->sigma_x()), //
|
||||||
|
Sigma(blur_filter->sigma_y()), //
|
||||||
|
static_cast<Entity::TileMode>(blur_filter->tile_mode()), //
|
||||||
|
FilterContents::BlurStyle::kNormal //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case flutter::DlImageFilterType::kDilate: {
|
||||||
|
auto dilate_filter = filter->asDilate();
|
||||||
|
FML_DCHECK(dilate_filter);
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeBlur(
|
return FilterContents::MakeMorphology(
|
||||||
Sigma sigma_x,
|
input, //
|
||||||
Sigma sigma_y,
|
Radius(dilate_filter->radius_x()), //
|
||||||
FilterContents::BlurStyle blur_style,
|
Radius(dilate_filter->radius_y()), //
|
||||||
Entity::TileMode tile_mode) {
|
FilterContents::MorphType::kDilate //
|
||||||
return std::make_shared<BlurImageFilter>(sigma_x, sigma_y, blur_style,
|
);
|
||||||
tile_mode);
|
}
|
||||||
}
|
case flutter::DlImageFilterType::kErode: {
|
||||||
|
auto erode_filter = filter->asErode();
|
||||||
|
FML_DCHECK(erode_filter);
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeDilate(Radius radius_x,
|
return FilterContents::MakeMorphology(
|
||||||
Radius radius_y) {
|
input, //
|
||||||
return std::make_shared<DilateImageFilter>(radius_x, radius_y);
|
Radius(erode_filter->radius_x()), //
|
||||||
}
|
Radius(erode_filter->radius_y()), //
|
||||||
|
FilterContents::MorphType::kErode //
|
||||||
|
);
|
||||||
|
}
|
||||||
|
case flutter::DlImageFilterType::kMatrix: {
|
||||||
|
auto matrix_filter = filter->asMatrix();
|
||||||
|
FML_DCHECK(matrix_filter);
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeErode(Radius radius_x,
|
auto matrix = skia_conversions::ToMatrix(matrix_filter->matrix());
|
||||||
Radius radius_y) {
|
auto desc =
|
||||||
return std::make_shared<ErodeImageFilter>(radius_x, radius_y);
|
skia_conversions::ToSamplerDescriptor(matrix_filter->sampling());
|
||||||
}
|
return FilterContents::MakeMatrixFilter(input, matrix, desc);
|
||||||
|
}
|
||||||
|
case flutter::DlImageFilterType::kLocalMatrix: {
|
||||||
|
auto matrix_filter = filter->asLocalMatrix();
|
||||||
|
FML_DCHECK(matrix_filter);
|
||||||
|
FML_DCHECK(matrix_filter->image_filter());
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeMatrix(
|
auto matrix = skia_conversions::ToMatrix(matrix_filter->matrix());
|
||||||
const Matrix& matrix,
|
|
||||||
SamplerDescriptor sampler_descriptor) {
|
|
||||||
return std::make_shared<MatrixImageFilter>(matrix,
|
|
||||||
std::move(sampler_descriptor));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeCompose(
|
|
||||||
const ImageFilter& inner,
|
|
||||||
const ImageFilter& outer) {
|
|
||||||
return std::make_shared<ComposeImageFilter>(inner, outer);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeFromColorFilter(
|
|
||||||
const ColorFilter& color_filter) {
|
|
||||||
return std::make_shared<ColorImageFilter>(color_filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ImageFilter::MakeLocalMatrix(
|
|
||||||
const Matrix& matrix,
|
|
||||||
const ImageFilter& internal_filter) {
|
|
||||||
return std::make_shared<LocalMatrixImageFilter>(matrix, internal_filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> ImageFilter::GetFilterContents() const {
|
|
||||||
return WrapInput(FilterInput::Make(Rect()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* BlurImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
BlurImageFilter::BlurImageFilter(Sigma sigma_x,
|
|
||||||
Sigma sigma_y,
|
|
||||||
FilterContents::BlurStyle blur_style,
|
|
||||||
Entity::TileMode tile_mode)
|
|
||||||
: sigma_x_(sigma_x),
|
|
||||||
sigma_y_(sigma_y),
|
|
||||||
blur_style_(blur_style),
|
|
||||||
tile_mode_(tile_mode) {}
|
|
||||||
|
|
||||||
BlurImageFilter::~BlurImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> BlurImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return FilterContents::MakeGaussianBlur(input, sigma_x_, sigma_y_, tile_mode_,
|
|
||||||
blur_style_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> BlurImageFilter::Clone() const {
|
|
||||||
return std::make_shared<BlurImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* DilateImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
DilateImageFilter::DilateImageFilter(Radius radius_x, Radius radius_y)
|
|
||||||
: radius_x_(radius_x), radius_y_(radius_y) {}
|
|
||||||
|
|
||||||
DilateImageFilter::~DilateImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> DilateImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return FilterContents::MakeMorphology(input, radius_x_, radius_y_,
|
|
||||||
FilterContents::MorphType::kDilate);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> DilateImageFilter::Clone() const {
|
|
||||||
return std::make_shared<DilateImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ErodeImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
ErodeImageFilter::ErodeImageFilter(Radius radius_x, Radius radius_y)
|
|
||||||
: radius_x_(radius_x), radius_y_(radius_y) {}
|
|
||||||
|
|
||||||
ErodeImageFilter::~ErodeImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> ErodeImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return FilterContents::MakeMorphology(input, radius_x_, radius_y_,
|
|
||||||
FilterContents::MorphType::kErode);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ErodeImageFilter::Clone() const {
|
|
||||||
return std::make_shared<ErodeImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* MatrixImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
MatrixImageFilter::MatrixImageFilter(const Matrix& matrix,
|
|
||||||
SamplerDescriptor sampler_descriptor)
|
|
||||||
: matrix_(matrix), sampler_descriptor_(std::move(sampler_descriptor)) {}
|
|
||||||
|
|
||||||
MatrixImageFilter::~MatrixImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> MatrixImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return FilterContents::MakeMatrixFilter(input, matrix_, sampler_descriptor_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> MatrixImageFilter::Clone() const {
|
|
||||||
return std::make_shared<MatrixImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ComposeImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
ComposeImageFilter::ComposeImageFilter(const ImageFilter& inner,
|
|
||||||
const ImageFilter& outer)
|
|
||||||
: inner_(inner.Clone()), outer_(outer.Clone()) {}
|
|
||||||
|
|
||||||
ComposeImageFilter::~ComposeImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> ComposeImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return outer_->WrapInput(FilterInput::Make(inner_->WrapInput(input)));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ComposeImageFilter::Clone() const {
|
|
||||||
return std::make_shared<ComposeImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ColorImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
ColorImageFilter::ColorImageFilter(const ColorFilter& color_filter)
|
|
||||||
: color_filter_(color_filter.Clone()) {}
|
|
||||||
|
|
||||||
ColorImageFilter::~ColorImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> ColorImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return color_filter_->WrapWithGPUColorFilter(
|
|
||||||
input, ColorFilterContents::AbsorbOpacity::kNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> ColorImageFilter::Clone() const {
|
|
||||||
return std::make_shared<ColorImageFilter>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* LocalMatrixImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
LocalMatrixImageFilter::LocalMatrixImageFilter(
|
|
||||||
const Matrix& matrix,
|
|
||||||
const ImageFilter& internal_filter)
|
|
||||||
: matrix_(matrix), internal_filter_(internal_filter.Clone()) {}
|
|
||||||
|
|
||||||
LocalMatrixImageFilter::~LocalMatrixImageFilter() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> LocalMatrixImageFilter::WrapInput(
|
|
||||||
const FilterInput::Ref& input) const {
|
|
||||||
return FilterContents::MakeLocalMatrixFilter(
|
return FilterContents::MakeLocalMatrixFilter(
|
||||||
FilterInput::Make(internal_filter_->WrapInput(input)), matrix_);
|
FilterInput::Make(
|
||||||
}
|
WrapInput(matrix_filter->image_filter().get(), input)),
|
||||||
|
matrix);
|
||||||
|
}
|
||||||
|
case flutter::DlImageFilterType::kColorFilter: {
|
||||||
|
auto image_color_filter = filter->asColorFilter();
|
||||||
|
FML_DCHECK(image_color_filter);
|
||||||
|
auto color_filter = image_color_filter->color_filter();
|
||||||
|
FML_DCHECK(color_filter);
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> LocalMatrixImageFilter::Clone() const {
|
// When color filters are used as image filters, set the color filter's
|
||||||
return std::make_shared<LocalMatrixImageFilter>(*this);
|
// "absorb opacity" flag to false. For image filters, the snapshot
|
||||||
|
// opacity needs to be deferred until the result of the filter chain is
|
||||||
|
// being blended with the layer.
|
||||||
|
return WrapWithGPUColorFilter(color_filter.get(), input,
|
||||||
|
ColorFilterContents::AbsorbOpacity::kNo);
|
||||||
|
}
|
||||||
|
case flutter::DlImageFilterType::kCompose: {
|
||||||
|
auto compose = filter->asCompose();
|
||||||
|
FML_DCHECK(compose);
|
||||||
|
|
||||||
|
auto outer_dl_filter = compose->outer();
|
||||||
|
auto inner_dl_filter = compose->inner();
|
||||||
|
if (!outer_dl_filter) {
|
||||||
|
return WrapInput(inner_dl_filter.get(), input);
|
||||||
|
}
|
||||||
|
if (!inner_dl_filter) {
|
||||||
|
return WrapInput(outer_dl_filter.get(), input);
|
||||||
|
}
|
||||||
|
FML_DCHECK(outer_dl_filter && inner_dl_filter);
|
||||||
|
|
||||||
|
return WrapInput(
|
||||||
|
outer_dl_filter.get(),
|
||||||
|
FilterInput::Make(WrapInput(inner_dl_filter.get(), input)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FML_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -5,233 +5,15 @@
|
|||||||
#ifndef FLUTTER_IMPELLER_DISPLAY_LIST_IMAGE_FILTER_H_
|
#ifndef FLUTTER_IMPELLER_DISPLAY_LIST_IMAGE_FILTER_H_
|
||||||
#define FLUTTER_IMPELLER_DISPLAY_LIST_IMAGE_FILTER_H_
|
#define FLUTTER_IMPELLER_DISPLAY_LIST_IMAGE_FILTER_H_
|
||||||
|
|
||||||
#include "impeller/core/sampler_descriptor.h"
|
#include "display_list/effects/dl_image_filter.h"
|
||||||
#include "impeller/display_list/color_filter.h"
|
|
||||||
#include "impeller/entity/contents/filters/filter_contents.h"
|
#include "impeller/entity/contents/filters/filter_contents.h"
|
||||||
#include "impeller/entity/entity.h"
|
|
||||||
#include "impeller/geometry/matrix.h"
|
|
||||||
#include "impeller/geometry/sigma.h"
|
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
|
||||||
struct Paint;
|
/// @brief Generate a new FilterContents using this filter's configuration.
|
||||||
|
///
|
||||||
/*******************************************************************************
|
std::shared_ptr<FilterContents> WrapInput(const flutter::DlImageFilter* filter,
|
||||||
******* ImageFilter
|
const FilterInput::Ref& input);
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class ImageFilter {
|
|
||||||
public:
|
|
||||||
ImageFilter();
|
|
||||||
|
|
||||||
virtual ~ImageFilter();
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeBlur(
|
|
||||||
Sigma sigma_x,
|
|
||||||
Sigma sigma_y,
|
|
||||||
FilterContents::BlurStyle blur_style,
|
|
||||||
Entity::TileMode tile_mode);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeDilate(Radius radius_x,
|
|
||||||
Radius radius_y);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeErode(Radius radius_x,
|
|
||||||
Radius radius_y);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeMatrix(
|
|
||||||
const Matrix& matrix,
|
|
||||||
SamplerDescriptor sampler_descriptor);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeCompose(const ImageFilter& inner,
|
|
||||||
const ImageFilter& outer);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeFromColorFilter(
|
|
||||||
const ColorFilter& color_filter);
|
|
||||||
|
|
||||||
static std::shared_ptr<ImageFilter> MakeLocalMatrix(
|
|
||||||
const Matrix& matrix,
|
|
||||||
const ImageFilter& internal_filter);
|
|
||||||
|
|
||||||
/// @brief Generate a new FilterContents using this filter's configuration.
|
|
||||||
///
|
|
||||||
/// This is the same as WrapInput, except no input is set. The input
|
|
||||||
/// for the filter chain can be set later using.
|
|
||||||
/// FilterContents::SetLeafInputs().
|
|
||||||
///
|
|
||||||
/// @see `FilterContents::SetLeafInputs`
|
|
||||||
std::shared_ptr<FilterContents> GetFilterContents() const;
|
|
||||||
|
|
||||||
/// @brief Wraps the given filter input with a GPU-based image filter.
|
|
||||||
virtual std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const = 0;
|
|
||||||
|
|
||||||
virtual std::shared_ptr<ImageFilter> Clone() const = 0;
|
|
||||||
|
|
||||||
virtual int GetRequiredMipCount() const { return 1; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* BlurImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class BlurImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
BlurImageFilter(Sigma sigma_x,
|
|
||||||
Sigma sigma_y,
|
|
||||||
FilterContents::BlurStyle blur_style,
|
|
||||||
Entity::TileMode tile_mode);
|
|
||||||
|
|
||||||
~BlurImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
int GetRequiredMipCount() const override { return 4; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Sigma sigma_x_;
|
|
||||||
Sigma sigma_y_;
|
|
||||||
FilterContents::BlurStyle blur_style_;
|
|
||||||
Entity::TileMode tile_mode_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* DilateImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class DilateImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
DilateImageFilter(Radius radius_x, Radius radius_y);
|
|
||||||
|
|
||||||
~DilateImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Radius radius_x_;
|
|
||||||
Radius radius_y_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ErodeImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class ErodeImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
ErodeImageFilter(Radius radius_x, Radius radius_y);
|
|
||||||
|
|
||||||
~ErodeImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Radius radius_x_;
|
|
||||||
Radius radius_y_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* MatrixImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class MatrixImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
MatrixImageFilter(const Matrix& matrix, SamplerDescriptor sampler_descriptor);
|
|
||||||
|
|
||||||
~MatrixImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
const Matrix& GetMatrix() const { return matrix_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Matrix matrix_;
|
|
||||||
SamplerDescriptor sampler_descriptor_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ComposeImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class ComposeImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
ComposeImageFilter(const ImageFilter& inner, const ImageFilter& outer);
|
|
||||||
|
|
||||||
~ComposeImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<ImageFilter> inner_;
|
|
||||||
std::shared_ptr<ImageFilter> outer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* ColorImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class ColorImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
explicit ColorImageFilter(const ColorFilter& color_filter);
|
|
||||||
|
|
||||||
~ColorImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::shared_ptr<ColorFilter> color_filter_;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
******* LocalMatrixImageFilter
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
class LocalMatrixImageFilter : public ImageFilter {
|
|
||||||
public:
|
|
||||||
LocalMatrixImageFilter(const Matrix& matrix,
|
|
||||||
const ImageFilter& internal_filter);
|
|
||||||
|
|
||||||
~LocalMatrixImageFilter() override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<FilterContents> WrapInput(
|
|
||||||
const FilterInput::Ref& input) const override;
|
|
||||||
|
|
||||||
// |ImageFilter|
|
|
||||||
std::shared_ptr<ImageFilter> Clone() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Matrix matrix_;
|
|
||||||
std::shared_ptr<ImageFilter> internal_filter_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "display_list/effects/dl_color_filter.h"
|
||||||
#include "display_list/effects/dl_color_source.h"
|
#include "display_list/effects/dl_color_source.h"
|
||||||
#include "display_list/geometry/dl_path.h"
|
#include "display_list/geometry/dl_path.h"
|
||||||
#include "fml/logging.h"
|
#include "fml/logging.h"
|
||||||
|
#include "impeller/display_list/color_filter.h"
|
||||||
#include "impeller/display_list/skia_conversions.h"
|
#include "impeller/display_list/skia_conversions.h"
|
||||||
#include "impeller/entity/contents/color_source_contents.h"
|
#include "impeller/entity/contents/color_source_contents.h"
|
||||||
#include "impeller/entity/contents/conical_gradient_contents.h"
|
#include "impeller/entity/contents/conical_gradient_contents.h"
|
||||||
@ -31,18 +33,6 @@ using DlRect = flutter::DlRect;
|
|||||||
using DlIRect = flutter::DlIRect;
|
using DlIRect = flutter::DlIRect;
|
||||||
using DlPath = flutter::DlPath;
|
using DlPath = flutter::DlPath;
|
||||||
|
|
||||||
/// A color matrix which inverts colors.
|
|
||||||
// clang-format off
|
|
||||||
constexpr ColorMatrix kColorInversion = {
|
|
||||||
.array = {
|
|
||||||
-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
|
|
||||||
|
|
||||||
std::shared_ptr<ColorSourceContents> Paint::CreateContents() const {
|
std::shared_ptr<ColorSourceContents> Paint::CreateContents() const {
|
||||||
if (color_source == nullptr) {
|
if (color_source == nullptr) {
|
||||||
auto contents = std::make_shared<SolidColorContents>();
|
auto contents = std::make_shared<SolidColorContents>();
|
||||||
@ -194,11 +184,26 @@ std::shared_ptr<ColorSourceContents> Paint::CreateContents() const {
|
|||||||
contents->SetTileModes(x_tile_mode, y_tile_mode);
|
contents->SetTileModes(x_tile_mode, y_tile_mode);
|
||||||
contents->SetSamplerDescriptor(sampler_descriptor);
|
contents->SetSamplerDescriptor(sampler_descriptor);
|
||||||
contents->SetEffectTransform(effect_transform);
|
contents->SetEffectTransform(effect_transform);
|
||||||
if (color_filter) {
|
if (color_filter || invert_colors) {
|
||||||
TiledTextureContents::ColorFilterProc filter_proc =
|
TiledTextureContents::ColorFilterProc filter_proc =
|
||||||
[color_filter = color_filter](FilterInput::Ref input) {
|
[color_filter = color_filter,
|
||||||
return color_filter->WrapWithGPUColorFilter(
|
invert_colors = invert_colors](const FilterInput::Ref& input) {
|
||||||
std::move(input), ColorFilterContents::AbsorbOpacity::kNo);
|
if (invert_colors && color_filter) {
|
||||||
|
std::shared_ptr<FilterContents> color_filter_output =
|
||||||
|
WrapWithGPUColorFilter(
|
||||||
|
color_filter, input,
|
||||||
|
ColorFilterContents::AbsorbOpacity::kNo);
|
||||||
|
return WrapWithInvertColors(
|
||||||
|
FilterInput::Make(color_filter_output),
|
||||||
|
ColorFilterContents::AbsorbOpacity::kNo);
|
||||||
|
}
|
||||||
|
if (color_filter) {
|
||||||
|
return WrapWithGPUColorFilter(
|
||||||
|
color_filter, input,
|
||||||
|
ColorFilterContents::AbsorbOpacity::kNo);
|
||||||
|
}
|
||||||
|
return WrapWithInvertColors(
|
||||||
|
input, ColorFilterContents::AbsorbOpacity::kNo);
|
||||||
};
|
};
|
||||||
contents->SetColorFilter(filter_proc);
|
contents->SetColorFilter(filter_proc);
|
||||||
}
|
}
|
||||||
@ -247,32 +252,6 @@ std::shared_ptr<ColorSourceContents> Paint::CreateContents() const {
|
|||||||
FML_UNREACHABLE();
|
FML_UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Contents> Paint::CreateContentsForGeometry(
|
|
||||||
const std::shared_ptr<Geometry>& geometry) const {
|
|
||||||
auto contents = CreateContents();
|
|
||||||
|
|
||||||
// Attempt to apply the color filter on the CPU first.
|
|
||||||
// Note: This is not just an optimization; some color sources rely on
|
|
||||||
// CPU-applied color filters to behave properly.
|
|
||||||
auto color_filter = GetColorFilter();
|
|
||||||
bool needs_color_filter = !!color_filter;
|
|
||||||
if (color_filter &&
|
|
||||||
contents->ApplyColorFilter(color_filter->GetCPUColorFilterProc())) {
|
|
||||||
needs_color_filter = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
contents->SetGeometry(geometry);
|
|
||||||
if (mask_blur_descriptor.has_value()) {
|
|
||||||
// If there's a mask blur and we need to apply the color filter on the GPU,
|
|
||||||
// we need to be careful to only apply the color filter to the source
|
|
||||||
// colors. CreateMaskBlur is able to handle this case.
|
|
||||||
return mask_blur_descriptor->CreateMaskBlur(
|
|
||||||
contents, needs_color_filter ? color_filter : nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return contents;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<Contents> Paint::WithFilters(
|
std::shared_ptr<Contents> Paint::WithFilters(
|
||||||
std::shared_ptr<Contents> input) const {
|
std::shared_ptr<Contents> input) const {
|
||||||
input = WithColorFilter(input, ColorFilterContents::AbsorbOpacity::kYes);
|
input = WithColorFilter(input, ColorFilterContents::AbsorbOpacity::kYes);
|
||||||
@ -314,7 +293,7 @@ std::shared_ptr<FilterContents> Paint::WithImageFilter(
|
|||||||
if (!image_filter) {
|
if (!image_filter) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto filter = image_filter->WrapInput(FilterInput::Make(input));
|
auto filter = WrapInput(image_filter, FilterInput::Make(input));
|
||||||
filter->SetRenderingMode(rendering_mode);
|
filter->SetRenderingMode(rendering_mode);
|
||||||
filter->SetEffectTransform(effect_transform);
|
filter->SetEffectTransform(effect_transform);
|
||||||
return filter;
|
return filter;
|
||||||
@ -330,19 +309,34 @@ std::shared_ptr<Contents> Paint::WithColorFilter(
|
|||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto color_filter = GetColorFilter();
|
if (!color_filter && !invert_colors) {
|
||||||
if (!color_filter) {
|
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to apply the color filter on the CPU first.
|
// Attempt to apply the color filter on the CPU first.
|
||||||
// Note: This is not just an optimization; some color sources rely on
|
// Note: This is not just an optimization; some color sources rely on
|
||||||
// CPU-applied color filters to behave properly.
|
// CPU-applied color filters to behave properly.
|
||||||
if (input->ApplyColorFilter(color_filter->GetCPUColorFilterProc())) {
|
if (input->ApplyColorFilter([&](Color color) -> Color {
|
||||||
|
if (color_filter) {
|
||||||
|
color = GetCPUColorFilterProc(color_filter)(color);
|
||||||
|
}
|
||||||
|
if (invert_colors) {
|
||||||
|
color = color.ApplyColorMatrix(kColorInversion);
|
||||||
|
}
|
||||||
|
return color;
|
||||||
|
})) {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
return color_filter->WrapWithGPUColorFilter(FilterInput::Make(input),
|
|
||||||
|
if (color_filter) {
|
||||||
|
input = WrapWithGPUColorFilter(color_filter, FilterInput::Make(input),
|
||||||
absorb_opacity);
|
absorb_opacity);
|
||||||
|
}
|
||||||
|
if (invert_colors) {
|
||||||
|
input = WrapWithInvertColors(FilterInput::Make(input), absorb_opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
||||||
@ -375,10 +369,11 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
|||||||
|
|
||||||
std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
||||||
std::shared_ptr<ColorSourceContents> color_source_contents,
|
std::shared_ptr<ColorSourceContents> color_source_contents,
|
||||||
const std::shared_ptr<ColorFilter>& color_filter) const {
|
const flutter::DlColorFilter* color_filter,
|
||||||
// If it's a solid color and there is no color filter, then we can just get
|
bool invert_colors) const {
|
||||||
// away with doing one Gaussian blur.
|
// If it's a solid color then we can just get away with doing one Gaussian
|
||||||
if (color_source_contents->IsSolidColor() && !color_filter) {
|
// blur. The color filter will always be applied on the CPU.
|
||||||
|
if (color_source_contents->IsSolidColor()) {
|
||||||
return FilterContents::MakeGaussianBlur(
|
return FilterContents::MakeGaussianBlur(
|
||||||
FilterInput::Make(color_source_contents), sigma, sigma,
|
FilterInput::Make(color_source_contents), sigma, sigma,
|
||||||
Entity::TileMode::kDecal, style, color_source_contents->GetGeometry());
|
Entity::TileMode::kDecal, style, color_source_contents->GetGeometry());
|
||||||
@ -409,10 +404,14 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
|||||||
std::shared_ptr<Contents> color_contents = color_source_contents;
|
std::shared_ptr<Contents> color_contents = color_source_contents;
|
||||||
|
|
||||||
/// 4. Apply the user set color filter on the GPU, if applicable.
|
/// 4. Apply the user set color filter on the GPU, if applicable.
|
||||||
|
|
||||||
if (color_filter) {
|
if (color_filter) {
|
||||||
color_contents = color_filter->WrapWithGPUColorFilter(
|
color_contents =
|
||||||
FilterInput::Make(color_source_contents),
|
WrapWithGPUColorFilter(color_filter, FilterInput::Make(color_contents),
|
||||||
|
ColorFilterContents::AbsorbOpacity::kYes);
|
||||||
|
}
|
||||||
|
if (invert_colors) {
|
||||||
|
color_contents =
|
||||||
|
WrapWithInvertColors(FilterInput::Make(color_contents),
|
||||||
ColorFilterContents::AbsorbOpacity::kYes);
|
ColorFilterContents::AbsorbOpacity::kYes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -441,22 +440,8 @@ std::shared_ptr<FilterContents> Paint::MaskBlurDescriptor::CreateMaskBlur(
|
|||||||
Sigma(blur_sigma.y), style);
|
Sigma(blur_sigma.y), style);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> Paint::GetColorFilter() const {
|
|
||||||
if (invert_colors && color_filter) {
|
|
||||||
auto filter = ColorFilter::MakeMatrix(kColorInversion);
|
|
||||||
return ColorFilter::MakeComposed(filter, color_filter);
|
|
||||||
}
|
|
||||||
if (invert_colors) {
|
|
||||||
return ColorFilter::MakeMatrix(kColorInversion);
|
|
||||||
}
|
|
||||||
if (color_filter) {
|
|
||||||
return color_filter;
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Paint::HasColorFilter() const {
|
bool Paint::HasColorFilter() const {
|
||||||
return !!color_filter || invert_colors;
|
return color_filter || invert_colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "display_list/effects/dl_color_filter.h"
|
||||||
#include "display_list/effects/dl_color_source.h"
|
#include "display_list/effects/dl_color_source.h"
|
||||||
|
#include "display_list/effects/dl_image_filter.h"
|
||||||
#include "impeller/display_list/color_filter.h"
|
#include "impeller/display_list/color_filter.h"
|
||||||
#include "impeller/display_list/image_filter.h"
|
#include "impeller/display_list/image_filter.h"
|
||||||
#include "impeller/entity/contents/color_source_contents.h"
|
#include "impeller/entity/contents/color_source_contents.h"
|
||||||
@ -55,7 +57,8 @@ struct Paint {
|
|||||||
|
|
||||||
std::shared_ptr<FilterContents> CreateMaskBlur(
|
std::shared_ptr<FilterContents> CreateMaskBlur(
|
||||||
std::shared_ptr<ColorSourceContents> color_source_contents,
|
std::shared_ptr<ColorSourceContents> color_source_contents,
|
||||||
const std::shared_ptr<ColorFilter>& color_filter) const;
|
const flutter::DlColorFilter* color_filter,
|
||||||
|
bool invert_colors) const;
|
||||||
|
|
||||||
std::shared_ptr<FilterContents> CreateMaskBlur(
|
std::shared_ptr<FilterContents> CreateMaskBlur(
|
||||||
std::shared_ptr<TextureContents> texture_contents) const;
|
std::shared_ptr<TextureContents> texture_contents) const;
|
||||||
@ -68,6 +71,8 @@ struct Paint {
|
|||||||
|
|
||||||
Color color = Color::Black();
|
Color color = Color::Black();
|
||||||
const flutter::DlColorSource* color_source = nullptr;
|
const flutter::DlColorSource* color_source = nullptr;
|
||||||
|
const flutter::DlColorFilter* color_filter = nullptr;
|
||||||
|
const flutter::DlImageFilter* image_filter = nullptr;
|
||||||
|
|
||||||
Scalar stroke_width = 0.0;
|
Scalar stroke_width = 0.0;
|
||||||
Cap stroke_cap = Cap::kButt;
|
Cap stroke_cap = Cap::kButt;
|
||||||
@ -77,12 +82,8 @@ struct Paint {
|
|||||||
BlendMode blend_mode = BlendMode::kSourceOver;
|
BlendMode blend_mode = BlendMode::kSourceOver;
|
||||||
bool invert_colors = false;
|
bool invert_colors = false;
|
||||||
|
|
||||||
std::shared_ptr<ImageFilter> image_filter;
|
|
||||||
std::shared_ptr<ColorFilter> color_filter;
|
|
||||||
std::optional<MaskBlurDescriptor> mask_blur_descriptor;
|
std::optional<MaskBlurDescriptor> mask_blur_descriptor;
|
||||||
|
|
||||||
std::shared_ptr<ColorFilter> GetColorFilter() const;
|
|
||||||
|
|
||||||
/// @brief Wrap this paint's configured filters to the given contents.
|
/// @brief Wrap this paint's configured filters to the given contents.
|
||||||
/// @param[in] input The contents to wrap with paint's filters.
|
/// @param[in] input The contents to wrap with paint's filters.
|
||||||
/// @return The filter-wrapped contents. If there are no filters that need
|
/// @return The filter-wrapped contents. If there are no filters that need
|
||||||
@ -102,9 +103,6 @@ struct Paint {
|
|||||||
std::shared_ptr<Contents> input,
|
std::shared_ptr<Contents> input,
|
||||||
const Matrix& effect_transform = Matrix()) const;
|
const Matrix& effect_transform = Matrix()) const;
|
||||||
|
|
||||||
std::shared_ptr<Contents> CreateContentsForGeometry(
|
|
||||||
const std::shared_ptr<Geometry>& geometry) const;
|
|
||||||
|
|
||||||
/// @brief Whether this paint has a color filter that can apply opacity
|
/// @brief Whether this paint has a color filter that can apply opacity
|
||||||
bool HasColorFilter() const;
|
bool HasColorFilter() const;
|
||||||
|
|
||||||
|
@ -201,5 +201,69 @@ Matrix ToMatrix(const SkMatrix& m) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlendMode ToBlendMode(flutter::DlBlendMode mode) {
|
||||||
|
switch (mode) {
|
||||||
|
case flutter::DlBlendMode::kClear:
|
||||||
|
return BlendMode::kClear;
|
||||||
|
case flutter::DlBlendMode::kSrc:
|
||||||
|
return BlendMode::kSource;
|
||||||
|
case flutter::DlBlendMode::kDst:
|
||||||
|
return BlendMode::kDestination;
|
||||||
|
case flutter::DlBlendMode::kSrcOver:
|
||||||
|
return BlendMode::kSourceOver;
|
||||||
|
case flutter::DlBlendMode::kDstOver:
|
||||||
|
return BlendMode::kDestinationOver;
|
||||||
|
case flutter::DlBlendMode::kSrcIn:
|
||||||
|
return BlendMode::kSourceIn;
|
||||||
|
case flutter::DlBlendMode::kDstIn:
|
||||||
|
return BlendMode::kDestinationIn;
|
||||||
|
case flutter::DlBlendMode::kSrcOut:
|
||||||
|
return BlendMode::kSourceOut;
|
||||||
|
case flutter::DlBlendMode::kDstOut:
|
||||||
|
return BlendMode::kDestinationOut;
|
||||||
|
case flutter::DlBlendMode::kSrcATop:
|
||||||
|
return BlendMode::kSourceATop;
|
||||||
|
case flutter::DlBlendMode::kDstATop:
|
||||||
|
return BlendMode::kDestinationATop;
|
||||||
|
case flutter::DlBlendMode::kXor:
|
||||||
|
return BlendMode::kXor;
|
||||||
|
case flutter::DlBlendMode::kPlus:
|
||||||
|
return BlendMode::kPlus;
|
||||||
|
case flutter::DlBlendMode::kModulate:
|
||||||
|
return BlendMode::kModulate;
|
||||||
|
case flutter::DlBlendMode::kScreen:
|
||||||
|
return BlendMode::kScreen;
|
||||||
|
case flutter::DlBlendMode::kOverlay:
|
||||||
|
return BlendMode::kOverlay;
|
||||||
|
case flutter::DlBlendMode::kDarken:
|
||||||
|
return BlendMode::kDarken;
|
||||||
|
case flutter::DlBlendMode::kLighten:
|
||||||
|
return BlendMode::kLighten;
|
||||||
|
case flutter::DlBlendMode::kColorDodge:
|
||||||
|
return BlendMode::kColorDodge;
|
||||||
|
case flutter::DlBlendMode::kColorBurn:
|
||||||
|
return BlendMode::kColorBurn;
|
||||||
|
case flutter::DlBlendMode::kHardLight:
|
||||||
|
return BlendMode::kHardLight;
|
||||||
|
case flutter::DlBlendMode::kSoftLight:
|
||||||
|
return BlendMode::kSoftLight;
|
||||||
|
case flutter::DlBlendMode::kDifference:
|
||||||
|
return BlendMode::kDifference;
|
||||||
|
case flutter::DlBlendMode::kExclusion:
|
||||||
|
return BlendMode::kExclusion;
|
||||||
|
case flutter::DlBlendMode::kMultiply:
|
||||||
|
return BlendMode::kMultiply;
|
||||||
|
case flutter::DlBlendMode::kHue:
|
||||||
|
return BlendMode::kHue;
|
||||||
|
case flutter::DlBlendMode::kSaturation:
|
||||||
|
return BlendMode::kSaturation;
|
||||||
|
case flutter::DlBlendMode::kColor:
|
||||||
|
return BlendMode::kColor;
|
||||||
|
case flutter::DlBlendMode::kLuminosity:
|
||||||
|
return BlendMode::kLuminosity;
|
||||||
|
}
|
||||||
|
FML_UNREACHABLE();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace skia_conversions
|
} // namespace skia_conversions
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -61,6 +61,8 @@ impeller::SamplerDescriptor ToSamplerDescriptor(
|
|||||||
|
|
||||||
Matrix ToMatrix(const SkMatrix& m);
|
Matrix ToMatrix(const SkMatrix& m);
|
||||||
|
|
||||||
|
BlendMode ToBlendMode(flutter::DlBlendMode mode);
|
||||||
|
|
||||||
/// @brief Convert display list colors + stops into impeller colors and stops,
|
/// @brief Convert display list colors + stops into impeller colors and stops,
|
||||||
/// taking care to ensure that the stops monotonically increase from 0.0 to 1.0.
|
/// taking care to ensure that the stops monotonically increase from 0.0 to 1.0.
|
||||||
///
|
///
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "display_list/dl_blend_mode.h"
|
||||||
#include "display_list/dl_color.h"
|
#include "display_list/dl_color.h"
|
||||||
#include "display_list/dl_tile_mode.h"
|
#include "display_list/dl_tile_mode.h"
|
||||||
#include "flutter/testing/testing.h"
|
#include "flutter/testing/testing.h"
|
||||||
#include "impeller/core/formats.h"
|
#include "impeller/core/formats.h"
|
||||||
#include "impeller/display_list/skia_conversions.h"
|
#include "impeller/display_list/skia_conversions.h"
|
||||||
|
#include "impeller/geometry/color.h"
|
||||||
#include "impeller/geometry/scalar.h"
|
#include "impeller/geometry/scalar.h"
|
||||||
#include "include/core/SkMatrix.h"
|
#include "include/core/SkMatrix.h"
|
||||||
#include "include/core/SkRRect.h"
|
#include "include/core/SkRRect.h"
|
||||||
@ -292,5 +294,13 @@ TEST(SkiaConversionsTest, IsNearlySimpleRRect) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(SkiaConversionsTest, BlendMode) {
|
||||||
|
for (auto i = 0; i < static_cast<int>(flutter::DlBlendMode::kLastMode); i++) {
|
||||||
|
EXPECT_EQ(
|
||||||
|
skia_conversions::ToBlendMode(static_cast<flutter::DlBlendMode>(i)),
|
||||||
|
static_cast<BlendMode>(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace testing
|
} // namespace testing
|
||||||
} // namespace impeller
|
} // namespace impeller
|
||||||
|
@ -7,13 +7,11 @@
|
|||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "impeller/core/sampler_descriptor.h"
|
#include "impeller/core/sampler_descriptor.h"
|
||||||
#include "impeller/entity/contents/color_source_contents.h"
|
#include "impeller/entity/contents/color_source_contents.h"
|
||||||
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
#include "impeller/entity/contents/filters/color_filter_contents.h"
|
||||||
#include "impeller/entity/entity.h"
|
#include "impeller/entity/entity.h"
|
||||||
#include "impeller/geometry/path.h"
|
|
||||||
#include "impeller/renderer/capabilities.h"
|
#include "impeller/renderer/capabilities.h"
|
||||||
|
|
||||||
namespace impeller {
|
namespace impeller {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user