From 1cdd8d06be60b357a4853fd6d1f9cb97e2a21ca0 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 3 Oct 2024 21:20:33 -0500 Subject: [PATCH] [Impeller] remove aiks color_source. (flutter/engine#55603) Aiks color source is more or less a one to one copy of the impeller::DisplayListColorSource. We can rip it out, instead of flutter::DisplayList::ColorSource -> impeller::Aiks::ColorSource -> impelller:Entity::ColorSourceContents, just go directly flutter::DisplayList::ColorSource -> impelller:Entity::ColorSourceContents. Part of https://github.com/flutter/flutter/issues/142054 --- .../ci/licenses_golden/licenses_flutter | 4 - .../flutter/impeller/display_list/BUILD.gn | 2 - .../flutter/impeller/display_list/canvas.cc | 81 +++--- .../impeller/display_list/color_source.cc | 248 ----------------- .../impeller/display_list/color_source.h | 158 ----------- .../impeller/display_list/dl_dispatcher.cc | 253 ++---------------- .../flutter/impeller/display_list/paint.cc | 225 +++++++++++++++- .../src/flutter/impeller/display_list/paint.h | 7 +- .../impeller/display_list/skia_conversions.cc | 35 +++ .../impeller/display_list/skia_conversions.h | 6 + .../skia_conversions_unittests.cc | 81 ++++++ .../common/snapshot_controller_impeller.cc | 1 + 12 files changed, 408 insertions(+), 693 deletions(-) delete mode 100644 engine/src/flutter/impeller/display_list/color_source.cc delete mode 100644 engine/src/flutter/impeller/display_list/color_source.h diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index b7119dea06..d17f5081d6 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -42732,8 +42732,6 @@ ORIGIN: ../../../flutter/impeller/display_list/canvas.cc + ../../../flutter/LICE ORIGIN: ../../../flutter/impeller/display_list/canvas.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/color_filter.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/color_filter.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/display_list/color_source.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/display_list/color_source.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_atlas_geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_atlas_geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.cc + ../../../flutter/LICENSE @@ -45609,8 +45607,6 @@ FILE: ../../../flutter/impeller/display_list/canvas.cc FILE: ../../../flutter/impeller/display_list/canvas.h FILE: ../../../flutter/impeller/display_list/color_filter.cc FILE: ../../../flutter/impeller/display_list/color_filter.h -FILE: ../../../flutter/impeller/display_list/color_source.cc -FILE: ../../../flutter/impeller/display_list/color_source.h FILE: ../../../flutter/impeller/display_list/dl_atlas_geometry.cc FILE: ../../../flutter/impeller/display_list/dl_atlas_geometry.h FILE: ../../../flutter/impeller/display_list/dl_dispatcher.cc diff --git a/engine/src/flutter/impeller/display_list/BUILD.gn b/engine/src/flutter/impeller/display_list/BUILD.gn index f6ba958c29..fae78854d9 100644 --- a/engine/src/flutter/impeller/display_list/BUILD.gn +++ b/engine/src/flutter/impeller/display_list/BUILD.gn @@ -28,8 +28,6 @@ impeller_component("display_list") { "canvas.h", "color_filter.cc", "color_filter.h", - "color_source.cc", - "color_source.h", "dl_atlas_geometry.cc", "dl_atlas_geometry.h", "dl_dispatcher.cc", diff --git a/engine/src/flutter/impeller/display_list/canvas.cc b/engine/src/flutter/impeller/display_list/canvas.cc index 78d605d773..6b536d2963 100644 --- a/engine/src/flutter/impeller/display_list/canvas.cc +++ b/engine/src/flutter/impeller/display_list/canvas.cc @@ -8,10 +8,11 @@ #include #include +#include "display_list/effects/dl_color_source.h" #include "flutter/fml/logging.h" #include "flutter/fml/trace_event.h" -#include "impeller/display_list/color_source.h" #include "impeller/display_list/image_filter.h" +#include "impeller/display_list/skia_conversions.h" #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/color_source_contents.h" @@ -21,7 +22,6 @@ #include "impeller/entity/contents/solid_rrect_blur_contents.h" #include "impeller/entity/contents/text_contents.h" #include "impeller/entity/contents/texture_contents.h" -#include "impeller/entity/contents/tiled_texture_contents.h" #include "impeller/entity/contents/vertices_contents.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/entity/save_layer_utils.h" @@ -36,8 +36,7 @@ namespace { static std::shared_ptr CreateContentsForGeometryWithFilters( const Paint& paint, std::shared_ptr geometry) { - std::shared_ptr contents = - paint.color_source.GetContents(paint); + std::shared_ptr contents = paint.CreateContents(); // Attempt to apply the color filter on the CPU first. // Note: This is not just an optimization; some color sources rely on @@ -65,7 +64,8 @@ static std::shared_ptr CreateContentsForGeometryWithFilters( // Image input types will directly set their color filter, // if any. See `TiledTextureContents.SetColorFilter`. if (needs_color_filter && - paint.color_source.GetType() != ColorSource::Type::kImage) { + (!paint.color_source || + paint.color_source->type() != flutter::DlColorSourceType::kImage)) { std::shared_ptr color_filter = paint.GetColorFilter(); contents_copy = color_filter->WrapWithGPUColorFilter( FilterInput::Make(std::move(contents_copy)), @@ -82,41 +82,6 @@ static std::shared_ptr CreateContentsForGeometryWithFilters( return contents_copy; } -struct GetTextureColorSourceDataVisitor { - GetTextureColorSourceDataVisitor() {} - - std::optional operator()(const LinearGradientData& data) { - return std::nullopt; - } - - std::optional operator()(const RadialGradientData& data) { - return std::nullopt; - } - - std::optional operator()(const ConicalGradientData& data) { - return std::nullopt; - } - - std::optional operator()(const SweepGradientData& data) { - return std::nullopt; - } - - std::optional operator()(const ImageData& data) { return data; } - - std::optional operator()(const RuntimeEffectData& data) { - return std::nullopt; - } - - std::optional operator()(const std::monostate& data) { - return std::nullopt; - } -}; - -static std::optional GetImageColorSourceData( - const ColorSource& color_source) { - return std::visit(GetTextureColorSourceDataVisitor{}, color_source.GetData()); -} - static std::shared_ptr CreatePathContentsWithFilters( const Paint& paint, const Path& path) { @@ -484,8 +449,9 @@ void Canvas::DrawPaint(const Paint& paint) { bool Canvas::AttemptDrawBlurredRRect(const Rect& rect, Size corner_radii, const Paint& paint) { - if (paint.color_source.GetType() != ColorSource::Type::kColor || - paint.style != Paint::Style::kFill) { + if (paint.color_source && + (paint.color_source->type() != flutter::DlColorSourceType::kColor || + paint.style != Paint::Style::kFill)) { return false; } @@ -847,7 +813,8 @@ static bool UseColorSourceContents( return false; } if (vertices->HasTextureCoordinates() && - (paint.color_source.GetType() == ColorSource::Type::kColor)) { + (!paint.color_source || + paint.color_source->type() == flutter::DlColorSourceType::kColor)) { return true; } return !vertices->HasTextureCoordinates(); @@ -859,7 +826,8 @@ void Canvas::DrawVertices(const std::shared_ptr& vertices, // Override the blend mode with kDestination in order to match the behavior // of Skia's SK_LEGACY_IGNORE_DRAW_VERTICES_BLEND_WITH_NO_SHADER flag, which // is enabled when the Flutter engine builds Skia. - if (paint.color_source.GetType() == ColorSource::Type::kColor) { + if (!paint.color_source || + paint.color_source->type() == flutter::DlColorSourceType::kColor) { blend_mode = BlendMode::kDestination; } @@ -887,16 +855,29 @@ void Canvas::DrawVertices(const std::shared_ptr& vertices, // If there is a texture, use this directly. Otherwise render the color // source to a texture. - if (std::optional maybe_image_data = - GetImageColorSourceData(paint.color_source)) { - const ImageData& image_data = maybe_image_data.value(); + if (paint.color_source && + paint.color_source->type() == flutter::DlColorSourceType::kImage) { + const flutter::DlImageColorSource* image_color_source = + paint.color_source->asImage(); + FML_DCHECK(image_color_source && + image_color_source->image()->impeller_texture()); + auto texture = image_color_source->image()->impeller_texture(); + auto x_tile_mode = static_cast( + image_color_source->horizontal_tile_mode()); + auto y_tile_mode = + static_cast(image_color_source->vertical_tile_mode()); + auto sampler_descriptor = + skia_conversions::ToSamplerDescriptor(image_color_source->sampling()); + auto effect_transform = + skia_conversions::ToMatrix(image_color_source->matrix()); + auto contents = std::make_shared(); contents->SetBlendMode(blend_mode); contents->SetAlpha(paint.color.alpha); contents->SetGeometry(vertices); - contents->SetEffectTransform(image_data.effect_transform); - contents->SetTexture(image_data.texture); - contents->SetTileMode(image_data.x_tile_mode, image_data.y_tile_mode); + contents->SetEffectTransform(effect_transform); + contents->SetTexture(texture); + contents->SetTileMode(x_tile_mode, y_tile_mode); entity.SetContents(paint.WithFilters(std::move(contents))); AddRenderEntityToCurrentPass(entity); diff --git a/engine/src/flutter/impeller/display_list/color_source.cc b/engine/src/flutter/impeller/display_list/color_source.cc deleted file mode 100644 index 5d722afd6d..0000000000 --- a/engine/src/flutter/impeller/display_list/color_source.cc +++ /dev/null @@ -1,248 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "impeller/display_list/color_source.h" - -#include -#include -#include - -#include "impeller/core/sampler_descriptor.h" -#include "impeller/display_list/paint.h" -#include "impeller/entity/contents/conical_gradient_contents.h" -#include "impeller/entity/contents/filters/color_filter_contents.h" -#include "impeller/entity/contents/linear_gradient_contents.h" -#include "impeller/entity/contents/radial_gradient_contents.h" -#include "impeller/entity/contents/runtime_effect_contents.h" -#include "impeller/entity/contents/solid_color_contents.h" -#include "impeller/entity/contents/sweep_gradient_contents.h" -#include "impeller/entity/contents/tiled_texture_contents.h" -#include "impeller/geometry/color.h" -#include "impeller/geometry/matrix.h" -#include "impeller/geometry/scalar.h" -#include "impeller/runtime_stage/runtime_stage.h" - -namespace impeller { - -namespace { - -struct CreateContentsVisitor { - explicit CreateContentsVisitor(const Paint& p_paint) : paint(p_paint) {} - - const Paint& paint; - - std::shared_ptr operator()( - const LinearGradientData& data) { - auto contents = std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetColors(data.colors); - contents->SetStops(data.stops); - contents->SetEndPoints(data.start_point, data.end_point); - contents->SetTileMode(data.tile_mode); - contents->SetEffectTransform(data.effect_transform); - - std::vector bounds{data.start_point, data.end_point}; - auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); - if (intrinsic_size.has_value()) { - contents->SetColorSourceSize(intrinsic_size->GetSize()); - } - return contents; - } - - std::shared_ptr operator()( - const RadialGradientData& data) { - auto contents = std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetColors(data.colors); - contents->SetStops(data.stops); - contents->SetCenterAndRadius(data.center, data.radius); - contents->SetTileMode(data.tile_mode); - contents->SetEffectTransform(data.effect_transform); - - auto radius_pt = Point(data.radius, data.radius); - std::vector bounds{data.center + radius_pt, data.center - radius_pt}; - auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); - if (intrinsic_size.has_value()) { - contents->SetColorSourceSize(intrinsic_size->GetSize()); - } - return contents; - } - - std::shared_ptr operator()( - const ConicalGradientData& data) { - std::shared_ptr contents = - std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetColors(data.colors); - contents->SetStops(data.stops); - contents->SetCenterAndRadius(data.center, data.radius); - contents->SetTileMode(data.tile_mode); - contents->SetEffectTransform(data.effect_transform); - contents->SetFocus(data.focus_center, data.focus_radius); - - auto radius_pt = Point(data.radius, data.radius); - std::vector bounds{data.center + radius_pt, data.center - radius_pt}; - auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); - if (intrinsic_size.has_value()) { - contents->SetColorSourceSize(intrinsic_size->GetSize()); - } - return contents; - } - - std::shared_ptr operator()( - const SweepGradientData& data) { - auto contents = std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetCenterAndAngles(data.center, data.start_angle, data.end_angle); - contents->SetColors(data.colors); - contents->SetStops(data.stops); - contents->SetTileMode(data.tile_mode); - contents->SetEffectTransform(data.effect_transform); - - return contents; - } - - std::shared_ptr operator()(const ImageData& data) { - auto contents = std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetTexture(data.texture); - contents->SetTileModes(data.x_tile_mode, data.y_tile_mode); - contents->SetSamplerDescriptor(data.sampler_descriptor); - contents->SetEffectTransform(data.effect_transform); - if (paint.color_filter) { - TiledTextureContents::ColorFilterProc filter_proc = - [color_filter = paint.color_filter](FilterInput::Ref input) { - return color_filter->WrapWithGPUColorFilter( - std::move(input), ColorFilterContents::AbsorbOpacity::kNo); - }; - contents->SetColorFilter(filter_proc); - } - contents->SetColorSourceSize(Size::Ceil(data.texture->GetSize())); - return contents; - } - - std::shared_ptr operator()( - const RuntimeEffectData& data) { - auto contents = std::make_shared(); - contents->SetOpacityFactor(paint.color.alpha); - contents->SetRuntimeStage(data.runtime_stage); - contents->SetUniformData(data.uniform_data); - contents->SetTextureInputs(data.texture_inputs); - return contents; - } - - std::shared_ptr operator()(const std::monostate& data) { - auto contents = std::make_shared(); - contents->SetColor(paint.color); - return contents; - } -}; -} // namespace - -ColorSource::ColorSource() noexcept : color_source_data_(std::monostate()) {} - -ColorSource::~ColorSource() = default; - -ColorSource ColorSource::MakeColor() { - return {}; -} - -ColorSource ColorSource::MakeLinearGradient(Point start_point, - Point end_point, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform) { - ColorSource result; - result.type_ = Type::kLinearGradient; - result.color_source_data_ = - LinearGradientData{start_point, end_point, std::move(colors), - std::move(stops), tile_mode, effect_transform}; - return result; -} - -ColorSource ColorSource::MakeConicalGradient(Point center, - Scalar radius, - std::vector colors, - std::vector stops, - Point focus_center, - Scalar focus_radius, - Entity::TileMode tile_mode, - Matrix effect_transform) { - ColorSource result; - result.type_ = Type::kConicalGradient; - result.color_source_data_ = ConicalGradientData{ - center, radius, std::move(colors), std::move(stops), - focus_center, focus_radius, tile_mode, effect_transform}; - return result; -} - -ColorSource ColorSource::MakeRadialGradient(Point center, - Scalar radius, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform) { - ColorSource result; - result.type_ = Type::kRadialGradient; - result.color_source_data_ = - RadialGradientData{center, radius, std::move(colors), - std::move(stops), tile_mode, effect_transform}; - return result; -} - -ColorSource ColorSource::MakeSweepGradient(Point center, - Degrees start_angle, - Degrees end_angle, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform) { - ColorSource result; - result.type_ = Type::kSweepGradient; - result.color_source_data_ = SweepGradientData{ - center, start_angle, end_angle, std::move(colors), - std::move(stops), tile_mode, effect_transform}; - return result; -} - -ColorSource ColorSource::MakeImage(std::shared_ptr texture, - Entity::TileMode x_tile_mode, - Entity::TileMode y_tile_mode, - SamplerDescriptor sampler_descriptor, - Matrix effect_transform) { - ColorSource result; - result.type_ = Type::kImage; - result.color_source_data_ = - ImageData{std::move(texture), x_tile_mode, y_tile_mode, - std::move(sampler_descriptor), effect_transform}; - return result; -} - -ColorSource ColorSource::MakeRuntimeEffect( - std::shared_ptr runtime_stage, - std::shared_ptr> uniform_data, - std::vector texture_inputs) { - ColorSource result; - result.type_ = Type::kRuntimeEffect; - result.color_source_data_ = - RuntimeEffectData{std::move(runtime_stage), std::move(uniform_data), - std::move(texture_inputs)}; - return result; -} - -ColorSource::Type ColorSource::GetType() const { - return type_; -} - -std::shared_ptr ColorSource::GetContents( - const Paint& paint) const { - return std::visit(CreateContentsVisitor{paint}, color_source_data_); -} - -const ColorSourceData& ColorSource::GetData() const { - return color_source_data_; -} - -} // namespace impeller diff --git a/engine/src/flutter/impeller/display_list/color_source.h b/engine/src/flutter/impeller/display_list/color_source.h deleted file mode 100644 index 00e928e088..0000000000 --- a/engine/src/flutter/impeller/display_list/color_source.h +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_SOURCE_H_ -#define FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_SOURCE_H_ - -#include -#include -#include -#include - -#include "impeller/entity/contents/runtime_effect_contents.h" -#include "impeller/entity/entity.h" -#include "impeller/geometry/color.h" -#include "impeller/geometry/matrix.h" -#include "impeller/geometry/point.h" -#include "impeller/runtime_stage/runtime_stage.h" - -namespace impeller { - -struct Paint; - -struct LinearGradientData { - Point start_point; - Point end_point; - std::vector colors; - std::vector stops; - Entity::TileMode tile_mode; - Matrix effect_transform; -}; - -struct RadialGradientData { - Point center; - Scalar radius; - std::vector colors; - std::vector stops; - Entity::TileMode tile_mode; - Matrix effect_transform; -}; - -struct ConicalGradientData { - Point center; - Scalar radius; - std::vector colors; - std::vector stops; - Point focus_center; - Scalar focus_radius; - Entity::TileMode tile_mode; - Matrix effect_transform; -}; - -struct SweepGradientData { - Point center; - Degrees start_angle; - Degrees end_angle; - std::vector colors; - std::vector stops; - Entity::TileMode tile_mode; - Matrix effect_transform; -}; - -struct ImageData { - std::shared_ptr texture; - Entity::TileMode x_tile_mode; - Entity::TileMode y_tile_mode; - SamplerDescriptor sampler_descriptor; - Matrix effect_transform; -}; - -struct RuntimeEffectData { - std::shared_ptr runtime_stage; - std::shared_ptr> uniform_data; - std::vector texture_inputs; -}; - -using ColorSourceData = std::variant; - -class ColorSource { - public: - enum class Type { - kColor, - kImage, - kLinearGradient, - kRadialGradient, - kConicalGradient, - kSweepGradient, - kRuntimeEffect, - }; - - ColorSource() noexcept; - - ~ColorSource(); - - static ColorSource MakeColor(); - - static ColorSource MakeLinearGradient(Point start_point, - Point end_point, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform); - - static ColorSource MakeConicalGradient(Point center, - Scalar radius, - std::vector colors, - std::vector stops, - Point focus_center, - Scalar focus_radius, - Entity::TileMode tile_mode, - Matrix effect_transform); - - static ColorSource MakeRadialGradient(Point center, - Scalar radius, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform); - - static ColorSource MakeSweepGradient(Point center, - Degrees start_angle, - Degrees end_angle, - std::vector colors, - std::vector stops, - Entity::TileMode tile_mode, - Matrix effect_transform); - - static ColorSource MakeImage(std::shared_ptr texture, - Entity::TileMode x_tile_mode, - Entity::TileMode y_tile_mode, - SamplerDescriptor sampler_descriptor, - Matrix effect_transform); - - static ColorSource MakeRuntimeEffect( - std::shared_ptr runtime_stage, - std::shared_ptr> uniform_data, - std::vector texture_inputs); - - Type GetType() const; - - std::shared_ptr GetContents(const Paint& paint) const; - - const ColorSourceData& GetData() const; - - private: - Type type_ = Type::kColor; - ColorSourceData color_source_data_; -}; - -} // namespace impeller - -#endif // FLUTTER_IMPELLER_DISPLAY_LIST_COLOR_SOURCE_H_ diff --git a/engine/src/flutter/impeller/display_list/dl_dispatcher.cc b/engine/src/flutter/impeller/display_list/dl_dispatcher.cc index 9e7bb06df2..21d7948b31 100644 --- a/engine/src/flutter/impeller/display_list/dl_dispatcher.cc +++ b/engine/src/flutter/impeller/display_list/dl_dispatcher.cc @@ -11,6 +11,7 @@ #include #include +#include "display_list/effects/dl_color_source.h" #include "flutter/fml/logging.h" #include "impeller/core/formats.h" #include "impeller/display_list/aiks_context.h" @@ -23,7 +24,6 @@ #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/filters/inputs/filter_input.h" -#include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/entity.h" #include "impeller/geometry/color.h" #include "impeller/geometry/path.h" @@ -178,43 +178,6 @@ static BlendMode ToBlendMode(flutter::DlBlendMode mode) { FML_UNREACHABLE(); } -static Entity::TileMode ToTileMode(flutter::DlTileMode tile_mode) { - switch (tile_mode) { - case flutter::DlTileMode::kClamp: - return Entity::TileMode::kClamp; - case flutter::DlTileMode::kRepeat: - return Entity::TileMode::kRepeat; - case flutter::DlTileMode::kMirror: - return Entity::TileMode::kMirror; - case flutter::DlTileMode::kDecal: - return Entity::TileMode::kDecal; - } -} - -static impeller::SamplerDescriptor ToSamplerDescriptor( - const flutter::DlImageSampling options) { - impeller::SamplerDescriptor desc; - switch (options) { - case flutter::DlImageSampling::kNearestNeighbor: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest; - desc.mip_filter = impeller::MipFilter::kBase; - desc.label = "Nearest Sampler"; - break; - case flutter::DlImageSampling::kLinear: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; - desc.mip_filter = impeller::MipFilter::kBase; - desc.label = "Linear Sampler"; - break; - case flutter::DlImageSampling::kCubic: - case flutter::DlImageSampling::kMipmapLinear: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; - desc.mip_filter = impeller::MipFilter::kLinear; - desc.label = "Mipmap Linear Sampler"; - break; - } - return desc; -} - static impeller::SamplerDescriptor ToSamplerDescriptor( const flutter::DlFilterMode options) { impeller::SamplerDescriptor desc; @@ -233,17 +196,6 @@ static impeller::SamplerDescriptor ToSamplerDescriptor( return desc; } -static Matrix ToMatrix(const SkMatrix& m) { - return Matrix{ - // clang-format off - m[0], m[3], 0, m[6], - m[1], m[4], 0, m[7], - 0, 0, 1, 0, - m[2], m[5], 0, m[8], - // clang-format on - }; -} - // |flutter::DlOpReceiver| void DlDispatcherBase::setAntiAlias(bool aa) { AUTO_DEPTH_WATCHER(0u); @@ -326,170 +278,14 @@ void DlDispatcherBase::setStrokeJoin(flutter::DlStrokeJoin join) { } } -static std::optional ToColorSourceType( - flutter::DlColorSourceType type) { - switch (type) { - case flutter::DlColorSourceType::kColor: - return ColorSource::Type::kColor; - case flutter::DlColorSourceType::kImage: - return ColorSource::Type::kImage; - case flutter::DlColorSourceType::kLinearGradient: - return ColorSource::Type::kLinearGradient; - case flutter::DlColorSourceType::kRadialGradient: - return ColorSource::Type::kRadialGradient; - case flutter::DlColorSourceType::kConicalGradient: - return ColorSource::Type::kConicalGradient; - case flutter::DlColorSourceType::kSweepGradient: - return ColorSource::Type::kSweepGradient; - case flutter::DlColorSourceType::kRuntimeEffect: - return ColorSource::Type::kRuntimeEffect; - } -} - // |flutter::DlOpReceiver| void DlDispatcherBase::setColorSource(const flutter::DlColorSource* source) { AUTO_DEPTH_WATCHER(0u); - if (!source) { - paint_.color_source = ColorSource::MakeColor(); - return; - } - - std::optional type = ToColorSourceType(source->type()); - - if (!type.has_value()) { - FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown"; - paint_.color_source = ColorSource::MakeColor(); - return; - } - - switch (type.value()) { - case ColorSource::Type::kColor: { - const flutter::DlColorColorSource* color = source->asColor(); - - paint_.color_source = ColorSource::MakeColor(); - setColor(color->color()); - FML_DCHECK(color); - return; - } - case ColorSource::Type::kLinearGradient: { - const flutter::DlLinearGradientColorSource* linear = - source->asLinearGradient(); - FML_DCHECK(linear); - auto start_point = skia_conversions::ToPoint(linear->start_point()); - auto end_point = skia_conversions::ToPoint(linear->end_point()); - std::vector colors; - std::vector stops; - skia_conversions::ConvertStops(linear, colors, stops); - - auto tile_mode = ToTileMode(linear->tile_mode()); - auto matrix = ToMatrix(linear->matrix()); - - paint_.color_source = ColorSource::MakeLinearGradient( - start_point, end_point, std::move(colors), std::move(stops), - tile_mode, matrix); - return; - } - case ColorSource::Type::kConicalGradient: { - const flutter::DlConicalGradientColorSource* conical_gradient = - source->asConicalGradient(); - FML_DCHECK(conical_gradient); - Point center = skia_conversions::ToPoint(conical_gradient->end_center()); - DlScalar radius = conical_gradient->end_radius(); - Point focus_center = - skia_conversions::ToPoint(conical_gradient->start_center()); - DlScalar focus_radius = conical_gradient->start_radius(); - std::vector colors; - std::vector stops; - skia_conversions::ConvertStops(conical_gradient, colors, stops); - - auto tile_mode = ToTileMode(conical_gradient->tile_mode()); - auto matrix = ToMatrix(conical_gradient->matrix()); - - paint_.color_source = ColorSource::MakeConicalGradient( - center, radius, std::move(colors), std::move(stops), focus_center, - focus_radius, tile_mode, matrix); - return; - } - case ColorSource::Type::kRadialGradient: { - const flutter::DlRadialGradientColorSource* radialGradient = - source->asRadialGradient(); - FML_DCHECK(radialGradient); - auto center = skia_conversions::ToPoint(radialGradient->center()); - auto radius = radialGradient->radius(); - std::vector colors; - std::vector stops; - skia_conversions::ConvertStops(radialGradient, colors, stops); - - auto tile_mode = ToTileMode(radialGradient->tile_mode()); - auto matrix = ToMatrix(radialGradient->matrix()); - paint_.color_source = - ColorSource::MakeRadialGradient(center, radius, std::move(colors), - std::move(stops), tile_mode, matrix); - return; - } - case ColorSource::Type::kSweepGradient: { - const flutter::DlSweepGradientColorSource* sweepGradient = - source->asSweepGradient(); - FML_DCHECK(sweepGradient); - - auto center = skia_conversions::ToPoint(sweepGradient->center()); - auto start_angle = Degrees(sweepGradient->start()); - auto end_angle = Degrees(sweepGradient->end()); - std::vector colors; - std::vector stops; - skia_conversions::ConvertStops(sweepGradient, colors, stops); - - auto tile_mode = ToTileMode(sweepGradient->tile_mode()); - auto matrix = ToMatrix(sweepGradient->matrix()); - paint_.color_source = ColorSource::MakeSweepGradient( - center, start_angle, end_angle, std::move(colors), std::move(stops), - tile_mode, matrix); - return; - } - case ColorSource::Type::kImage: { - const flutter::DlImageColorSource* image_color_source = source->asImage(); - FML_DCHECK(image_color_source && - image_color_source->image()->impeller_texture()); - auto texture = image_color_source->image()->impeller_texture(); - auto x_tile_mode = ToTileMode(image_color_source->horizontal_tile_mode()); - auto y_tile_mode = ToTileMode(image_color_source->vertical_tile_mode()); - auto desc = ToSamplerDescriptor(image_color_source->sampling()); - auto matrix = ToMatrix(image_color_source->matrix()); - paint_.color_source = ColorSource::MakeImage(texture, x_tile_mode, - y_tile_mode, desc, matrix); - return; - } - case ColorSource::Type::kRuntimeEffect: { - const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source = - source->asRuntimeEffect(); - auto runtime_stage = - runtime_effect_color_source->runtime_effect()->runtime_stage(); - auto uniform_data = runtime_effect_color_source->uniform_data(); - auto samplers = runtime_effect_color_source->samplers(); - - std::vector texture_inputs; - - for (auto& sampler : samplers) { - if (sampler == nullptr) { - return; - } - auto* image = sampler->asImage(); - if (!sampler->asImage()) { - UNIMPLEMENTED; - return; - } - FML_DCHECK(image->image()->impeller_texture()); - texture_inputs.push_back({ - .sampler_descriptor = ToSamplerDescriptor(image->sampling()), - .texture = image->image()->impeller_texture(), - }); - } - - paint_.color_source = ColorSource::MakeRuntimeEffect( - runtime_stage, uniform_data, texture_inputs); - return; - } + if (!source || source->type() == flutter::DlColorSourceType::kColor) { + paint_.color_source = nullptr; + } else { + paint_.color_source = source; } } @@ -587,7 +383,7 @@ static std::shared_ptr ToImageFilter( auto blur = filter->asBlur(); auto sigma_x = Sigma(blur->sigma_x()); auto sigma_y = Sigma(blur->sigma_y()); - auto tile_mode = ToTileMode(blur->tile_mode()); + auto tile_mode = static_cast(blur->tile_mode()); return ImageFilter::MakeBlur( sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, tile_mode); } @@ -614,8 +410,9 @@ static std::shared_ptr ToImageFilter( case flutter::DlImageFilterType::kMatrix: { auto matrix_filter = filter->asMatrix(); FML_DCHECK(matrix_filter); - auto matrix = ToMatrix(matrix_filter->matrix()); - auto desc = ToSamplerDescriptor(matrix_filter->sampling()); + 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: { @@ -660,7 +457,7 @@ static std::shared_ptr ToImageFilter( return nullptr; } - auto matrix = ToMatrix(local_matrix_filter->matrix()); + auto matrix = skia_conversions::ToMatrix(local_matrix_filter->matrix()); return ImageFilter::MakeLocalMatrix(matrix, *image_filter); } } @@ -1110,11 +907,12 @@ void DlDispatcherBase::drawImageRect( SrcRectConstraint constraint = SrcRectConstraint::kFast) { AUTO_DEPTH_WATCHER(1u); - GetCanvas().DrawImageRect(image->impeller_texture(), // image - src, // source rect - dst, // destination rect - render_with_attributes ? paint_ : Paint(), // paint - ToSamplerDescriptor(sampling) // sampling + GetCanvas().DrawImageRect( + image->impeller_texture(), // image + src, // source rect + dst, // destination rect + render_with_attributes ? paint_ : Paint(), // paint + skia_conversions::ToSamplerDescriptor(sampling) // sampling ); } @@ -1146,15 +944,16 @@ void DlDispatcherBase::drawAtlas(const sk_sp atlas, bool render_with_attributes) { AUTO_DEPTH_WATCHER(1u); - auto geometry = DlAtlasGeometry(atlas->impeller_texture(), // - xform, // - tex, // - colors, // - static_cast(count), // - ToBlendMode(mode), // - ToSamplerDescriptor(sampling), // - skia_conversions::ToRect(cull_rect) // - ); + auto geometry = + DlAtlasGeometry(atlas->impeller_texture(), // + xform, // + tex, // + colors, // + static_cast(count), // + ToBlendMode(mode), // + skia_conversions::ToSamplerDescriptor(sampling), // + skia_conversions::ToRect(cull_rect) // + ); auto atlas_contents = std::make_shared(); atlas_contents->SetGeometry(&geometry); diff --git a/engine/src/flutter/impeller/display_list/paint.cc b/engine/src/flutter/impeller/display_list/paint.cc index 9733b635a1..cf7029a916 100644 --- a/engine/src/flutter/impeller/display_list/paint.cc +++ b/engine/src/flutter/impeller/display_list/paint.cc @@ -6,15 +6,31 @@ #include +#include "display_list/effects/dl_color_source.h" +#include "display_list/geometry/dl_path.h" +#include "fml/logging.h" +#include "impeller/display_list/skia_conversions.h" #include "impeller/entity/contents/color_source_contents.h" +#include "impeller/entity/contents/conical_gradient_contents.h" #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h" +#include "impeller/entity/contents/linear_gradient_contents.h" +#include "impeller/entity/contents/radial_gradient_contents.h" +#include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/contents/solid_color_contents.h" +#include "impeller/entity/contents/sweep_gradient_contents.h" +#include "impeller/entity/contents/tiled_texture_contents.h" #include "impeller/entity/geometry/geometry.h" namespace impeller { +using DlScalar = flutter::DlScalar; +using DlPoint = flutter::DlPoint; +using DlRect = flutter::DlRect; +using DlIRect = flutter::DlIRect; +using DlPath = flutter::DlPath; + /// A color matrix which inverts colors. // clang-format off constexpr ColorMatrix kColorInversion = { @@ -27,9 +43,213 @@ constexpr ColorMatrix kColorInversion = { }; // clang-format on +std::shared_ptr Paint::CreateContents() const { + if (color_source == nullptr) { + auto contents = std::make_shared(); + contents->SetColor(color); + return contents; + } + + switch (color_source->type()) { + case flutter::DlColorSourceType::kLinearGradient: { + const flutter::DlLinearGradientColorSource* linear = + color_source->asLinearGradient(); + FML_DCHECK(linear); + auto start_point = skia_conversions::ToPoint(linear->start_point()); + auto end_point = skia_conversions::ToPoint(linear->end_point()); + std::vector colors; + std::vector stops; + skia_conversions::ConvertStops(linear, colors, stops); + + auto tile_mode = static_cast(linear->tile_mode()); + auto effect_transform = skia_conversions::ToMatrix(linear->matrix()); + + auto contents = std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetEndPoints(start_point, end_point); + contents->SetTileMode(tile_mode); + contents->SetEffectTransform(effect_transform); + + std::array bounds{start_point, end_point}; + auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); + if (intrinsic_size.has_value()) { + contents->SetColorSourceSize(intrinsic_size->GetSize()); + } + return contents; + } + case flutter::DlColorSourceType::kRadialGradient: { + const flutter::DlRadialGradientColorSource* radialGradient = + color_source->asRadialGradient(); + FML_DCHECK(radialGradient); + auto center = skia_conversions::ToPoint(radialGradient->center()); + auto radius = radialGradient->radius(); + std::vector colors; + std::vector stops; + skia_conversions::ConvertStops(radialGradient, colors, stops); + + auto tile_mode = + static_cast(radialGradient->tile_mode()); + auto effect_transform = + skia_conversions::ToMatrix(radialGradient->matrix()); + + auto contents = std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetCenterAndRadius(center, radius); + contents->SetTileMode(tile_mode); + contents->SetEffectTransform(effect_transform); + + auto radius_pt = Point(radius, radius); + std::array bounds{center + radius_pt, center - radius_pt}; + auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); + if (intrinsic_size.has_value()) { + contents->SetColorSourceSize(intrinsic_size->GetSize()); + } + return contents; + } + case flutter::DlColorSourceType::kConicalGradient: { + const flutter::DlConicalGradientColorSource* conical_gradient = + color_source->asConicalGradient(); + FML_DCHECK(conical_gradient); + Point center = skia_conversions::ToPoint(conical_gradient->end_center()); + DlScalar radius = conical_gradient->end_radius(); + Point focus_center = + skia_conversions::ToPoint(conical_gradient->start_center()); + DlScalar focus_radius = conical_gradient->start_radius(); + std::vector colors; + std::vector stops; + skia_conversions::ConvertStops(conical_gradient, colors, stops); + + auto tile_mode = + static_cast(conical_gradient->tile_mode()); + auto effect_transform = + skia_conversions::ToMatrix(conical_gradient->matrix()); + + std::shared_ptr contents = + std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetCenterAndRadius(center, radius); + contents->SetTileMode(tile_mode); + contents->SetEffectTransform(effect_transform); + contents->SetFocus(focus_center, focus_radius); + + auto radius_pt = Point(radius, radius); + std::array bounds{center + radius_pt, center - radius_pt}; + auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end()); + if (intrinsic_size.has_value()) { + contents->SetColorSourceSize(intrinsic_size->GetSize()); + } + return contents; + } + case flutter::DlColorSourceType::kSweepGradient: { + const flutter::DlSweepGradientColorSource* sweepGradient = + color_source->asSweepGradient(); + FML_DCHECK(sweepGradient); + + auto center = skia_conversions::ToPoint(sweepGradient->center()); + auto start_angle = Degrees(sweepGradient->start()); + auto end_angle = Degrees(sweepGradient->end()); + std::vector colors; + std::vector stops; + skia_conversions::ConvertStops(sweepGradient, colors, stops); + + auto tile_mode = + static_cast(sweepGradient->tile_mode()); + auto effect_transform = + skia_conversions::ToMatrix(sweepGradient->matrix()); + + auto contents = std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetCenterAndAngles(center, start_angle, end_angle); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetTileMode(tile_mode); + contents->SetEffectTransform(effect_transform); + + return contents; + } + case flutter::DlColorSourceType::kImage: { + const flutter::DlImageColorSource* image_color_source = + color_source->asImage(); + FML_DCHECK(image_color_source && + image_color_source->image()->impeller_texture()); + auto texture = image_color_source->image()->impeller_texture(); + auto x_tile_mode = static_cast( + image_color_source->horizontal_tile_mode()); + auto y_tile_mode = static_cast( + image_color_source->vertical_tile_mode()); + auto sampler_descriptor = + skia_conversions::ToSamplerDescriptor(image_color_source->sampling()); + auto effect_transform = + skia_conversions::ToMatrix(image_color_source->matrix()); + + auto contents = std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetTexture(texture); + contents->SetTileModes(x_tile_mode, y_tile_mode); + contents->SetSamplerDescriptor(sampler_descriptor); + contents->SetEffectTransform(effect_transform); + if (color_filter) { + TiledTextureContents::ColorFilterProc filter_proc = + [color_filter = color_filter](FilterInput::Ref input) { + return color_filter->WrapWithGPUColorFilter( + std::move(input), ColorFilterContents::AbsorbOpacity::kNo); + }; + contents->SetColorFilter(filter_proc); + } + contents->SetColorSourceSize(Size::Ceil(texture->GetSize())); + return contents; + } + case flutter::DlColorSourceType::kRuntimeEffect: { + const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source = + color_source->asRuntimeEffect(); + auto runtime_stage = + runtime_effect_color_source->runtime_effect()->runtime_stage(); + auto uniform_data = runtime_effect_color_source->uniform_data(); + auto samplers = runtime_effect_color_source->samplers(); + + std::vector texture_inputs; + + for (auto& sampler : samplers) { + if (sampler == nullptr) { + return nullptr; + } + auto* image = sampler->asImage(); + if (!sampler->asImage()) { + return nullptr; + } + FML_DCHECK(image->image()->impeller_texture()); + texture_inputs.push_back({ + .sampler_descriptor = + skia_conversions::ToSamplerDescriptor(image->sampling()), + .texture = image->image()->impeller_texture(), + }); + } + + auto contents = std::make_shared(); + contents->SetOpacityFactor(color.alpha); + contents->SetRuntimeStage(std::move(runtime_stage)); + contents->SetUniformData(std::move(uniform_data)); + contents->SetTextureInputs(std::move(texture_inputs)); + return contents; + } + case flutter::DlColorSourceType::kColor: { + auto contents = std::make_shared(); + contents->SetColor(color); + return contents; + } + } + FML_UNREACHABLE(); +} + std::shared_ptr Paint::CreateContentsForGeometry( const std::shared_ptr& geometry) const { - auto contents = color_source.GetContents(*this); + 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 @@ -105,7 +325,8 @@ std::shared_ptr Paint::WithColorFilter( ColorFilterContents::AbsorbOpacity absorb_opacity) const { // Image input types will directly set their color filter, // if any. See `TiledTextureContents.SetColorFilter`. - if (color_source.GetType() == ColorSource::Type::kImage) { + if (color_source && + color_source->type() == flutter::DlColorSourceType::kImage) { return input; } diff --git a/engine/src/flutter/impeller/display_list/paint.h b/engine/src/flutter/impeller/display_list/paint.h index 582e8ae831..c482a02b2d 100644 --- a/engine/src/flutter/impeller/display_list/paint.h +++ b/engine/src/flutter/impeller/display_list/paint.h @@ -7,9 +7,10 @@ #include +#include "display_list/effects/dl_color_source.h" #include "impeller/display_list/color_filter.h" -#include "impeller/display_list/color_source.h" #include "impeller/display_list/image_filter.h" +#include "impeller/entity/contents/color_source_contents.h" #include "impeller/entity/contents/contents.h" #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" @@ -66,7 +67,7 @@ struct Paint { }; Color color = Color::Black(); - ColorSource color_source; + const flutter::DlColorSource* color_source = nullptr; Scalar stroke_width = 0.0; Cap stroke_cap = Cap::kButt; @@ -107,6 +108,8 @@ struct Paint { /// @brief Whether this paint has a color filter that can apply opacity bool HasColorFilter() const; + std::shared_ptr CreateContents() const; + std::shared_ptr WithMaskBlur(std::shared_ptr input, bool is_solid_color, const Matrix& ctm) const; diff --git a/engine/src/flutter/impeller/display_list/skia_conversions.cc b/engine/src/flutter/impeller/display_list/skia_conversions.cc index d1e2ef247c..e61e766d28 100644 --- a/engine/src/flutter/impeller/display_list/skia_conversions.cc +++ b/engine/src/flutter/impeller/display_list/skia_conversions.cc @@ -166,5 +166,40 @@ void ConvertStops(const flutter::DlGradientColorSourceBase* gradient, } } +impeller::SamplerDescriptor ToSamplerDescriptor( + const flutter::DlImageSampling options) { + impeller::SamplerDescriptor desc; + switch (options) { + case flutter::DlImageSampling::kNearestNeighbor: + desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest; + desc.mip_filter = impeller::MipFilter::kBase; + desc.label = "Nearest Sampler"; + break; + case flutter::DlImageSampling::kLinear: + desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; + desc.mip_filter = impeller::MipFilter::kBase; + desc.label = "Linear Sampler"; + break; + case flutter::DlImageSampling::kCubic: + case flutter::DlImageSampling::kMipmapLinear: + desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; + desc.mip_filter = impeller::MipFilter::kLinear; + desc.label = "Mipmap Linear Sampler"; + break; + } + return desc; +} + +Matrix ToMatrix(const SkMatrix& m) { + return Matrix{ + // clang-format off + m[0], m[3], 0, m[6], + m[1], m[4], 0, m[7], + 0, 0, 1, 0, + m[2], m[5], 0, m[8], + // clang-format on + }; +} + } // namespace skia_conversions } // namespace impeller diff --git a/engine/src/flutter/impeller/display_list/skia_conversions.h b/engine/src/flutter/impeller/display_list/skia_conversions.h index 7b54ad174c..133a857e52 100644 --- a/engine/src/flutter/impeller/display_list/skia_conversions.h +++ b/engine/src/flutter/impeller/display_list/skia_conversions.h @@ -8,6 +8,7 @@ #include "display_list/dl_color.h" #include "display_list/effects/dl_color_source.h" #include "impeller/core/formats.h" +#include "impeller/core/sampler_descriptor.h" #include "impeller/geometry/color.h" #include "impeller/geometry/path.h" #include "impeller/geometry/path_builder.h" @@ -55,6 +56,11 @@ Path ToPath(const SkRRect& rrect); std::optional ToPixelFormat(SkColorType type); +impeller::SamplerDescriptor ToSamplerDescriptor( + const flutter::DlImageSampling options); + +Matrix ToMatrix(const SkMatrix& m); + /// @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. /// diff --git a/engine/src/flutter/impeller/display_list/skia_conversions_unittests.cc b/engine/src/flutter/impeller/display_list/skia_conversions_unittests.cc index e662260723..73791782a5 100644 --- a/engine/src/flutter/impeller/display_list/skia_conversions_unittests.cc +++ b/engine/src/flutter/impeller/display_list/skia_conversions_unittests.cc @@ -5,13 +5,94 @@ #include "display_list/dl_color.h" #include "display_list/dl_tile_mode.h" #include "flutter/testing/testing.h" +#include "impeller/core/formats.h" #include "impeller/display_list/skia_conversions.h" #include "impeller/geometry/scalar.h" +#include "include/core/SkMatrix.h" #include "include/core/SkRRect.h" namespace impeller { namespace testing { +TEST(SkiaConversionTest, ToMatrixTranslate) { + SkMatrix sk_matrix = SkMatrix::Translate(100, 100); + Matrix matrix = skia_conversions::ToMatrix(sk_matrix); + + EXPECT_EQ(matrix.m[12], 100); + EXPECT_EQ(matrix.m[13], 100); + EXPECT_TRUE(matrix.IsTranslationScaleOnly()); + + matrix.m[12] = 0; + matrix.m[13] = 0; + + EXPECT_TRUE(matrix.IsIdentity()); +} + +TEST(SkiaConversionTest, ToMatrixScale) { + SkMatrix sk_matrix = SkMatrix::Scale(2, 2); + Matrix matrix = skia_conversions::ToMatrix(sk_matrix); + + EXPECT_EQ(matrix.m[0], 2); + EXPECT_EQ(matrix.m[5], 2); + EXPECT_TRUE(matrix.IsTranslationScaleOnly()); + + matrix.m[0] = 1; + matrix.m[5] = 1; + + EXPECT_TRUE(matrix.IsIdentity()); +} + +TEST(SkiaConversionTest, ToMatrixRotate) { + SkMatrix sk_matrix = SkMatrix::RotateDeg(90); + Matrix matrix = skia_conversions::ToMatrix(sk_matrix); + + EXPECT_EQ(matrix.vec[0], Vector4(0, 1, 0, 0)); + EXPECT_EQ(matrix.vec[1], Vector4(-1, 0, 0, 0)); + EXPECT_EQ(matrix.vec[2], Vector4(0, 0, 1, 0)); + EXPECT_EQ(matrix.vec[3], Vector4(0, 0, 0, 1)); + EXPECT_FALSE(matrix.IsTranslationScaleOnly()); +} + +TEST(SkiaConversionTest, ToMatrixSkew) { + SkMatrix sk_matrix = SkMatrix::Skew(2, 2); + Matrix matrix = skia_conversions::ToMatrix(sk_matrix); + + EXPECT_EQ(matrix.vec[0], Vector4(1, 2, 0, 0)); + EXPECT_EQ(matrix.vec[1], Vector4(2, 1, 0, 0)); + EXPECT_EQ(matrix.vec[2], Vector4(0, 0, 1, 0)); + EXPECT_EQ(matrix.vec[3], Vector4(0, 0, 0, 1)); + EXPECT_FALSE(matrix.IsTranslationScaleOnly()); +} + +TEST(SkiaConversionTest, ToSamplerDescriptor) { + EXPECT_EQ(skia_conversions::ToSamplerDescriptor( + flutter::DlImageSampling::kNearestNeighbor) + .min_filter, + impeller::MinMagFilter::kNearest); + EXPECT_EQ(skia_conversions::ToSamplerDescriptor( + flutter::DlImageSampling::kNearestNeighbor) + .mip_filter, + impeller::MipFilter::kBase); + + EXPECT_EQ( + skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear) + .min_filter, + impeller::MinMagFilter::kLinear); + EXPECT_EQ( + skia_conversions::ToSamplerDescriptor(flutter::DlImageSampling::kLinear) + .mip_filter, + impeller::MipFilter::kBase); + + EXPECT_EQ(skia_conversions::ToSamplerDescriptor( + flutter::DlImageSampling::kMipmapLinear) + .min_filter, + impeller::MinMagFilter::kLinear); + EXPECT_EQ(skia_conversions::ToSamplerDescriptor( + flutter::DlImageSampling::kMipmapLinear) + .mip_filter, + impeller::MipFilter::kLinear); +} + TEST(SkiaConversionsTest, SkPointToPoint) { for (int x = -100; x < 100; x += 4) { for (int y = -100; y < 100; y += 4) { diff --git a/engine/src/flutter/shell/common/snapshot_controller_impeller.cc b/engine/src/flutter/shell/common/snapshot_controller_impeller.cc index dcf0702dbc..4fae09f588 100644 --- a/engine/src/flutter/shell/common/snapshot_controller_impeller.cc +++ b/engine/src/flutter/shell/common/snapshot_controller_impeller.cc @@ -13,6 +13,7 @@ #include "flutter/impeller/display_list/dl_image_impeller.h" #include "flutter/impeller/geometry/size.h" #include "flutter/shell/common/snapshot_controller.h" +#include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/renderer/render_target.h" namespace flutter {