From 0a92a914ccba2a3010232b8738752d0bb4e0a789 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 23 Aug 2023 17:13:33 -0700 Subject: [PATCH 01/17] Implement enough to theoretically draw dashed lines. --- lib/ui/text/paragraph_builder.cc | 4 +- .../txt/src/skia/paragraph_builder_skia.cc | 5 +- .../txt/src/skia/paragraph_builder_skia.h | 6 +- third_party/txt/src/skia/paragraph_skia.cc | 83 ++++++++++++++----- third_party/txt/src/skia/paragraph_skia.h | 1 + third_party/txt/src/txt/paragraph_builder.cc | 6 +- third_party/txt/src/txt/paragraph_builder.h | 3 +- 7 files changed, 78 insertions(+), 30 deletions(-) diff --git a/lib/ui/text/paragraph_builder.cc b/lib/ui/text/paragraph_builder.cc index eb01511772d49..a53ed88750548 100644 --- a/lib/ui/text/paragraph_builder.cc +++ b/lib/ui/text/paragraph_builder.cc @@ -300,8 +300,10 @@ ParagraphBuilder::ParagraphBuilder( ->client() ->GetFontCollection(); + auto impeller = UIDartState::Current()->GetIOManager()->GetImpellerContext(); + m_paragraphBuilder = txt::ParagraphBuilder::CreateSkiaBuilder( - style, font_collection.GetFontCollection()); + style, font_collection.GetFontCollection(), impeller != nullptr); } ParagraphBuilder::~ParagraphBuilder() = default; diff --git a/third_party/txt/src/skia/paragraph_builder_skia.cc b/third_party/txt/src/skia/paragraph_builder_skia.cc index 641725ec6ccfb..7c0c73e48cd11 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.cc +++ b/third_party/txt/src/skia/paragraph_builder_skia.cc @@ -46,8 +46,9 @@ SkFontStyle MakeSkFontStyle(txt::FontWeight font_weight, ParagraphBuilderSkia::ParagraphBuilderSkia( const ParagraphStyle& style, - std::shared_ptr font_collection) - : base_style_(style.GetTextStyle()) { + std::shared_ptr font_collection, + const bool impeller_enabled) + : base_style_(style.GetTextStyle()), impeller_enabled_(impeller_enabled) { builder_ = skt::ParagraphBuilder::make( TxtToSkia(style), font_collection->CreateSktFontCollection()); } diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h index e08e4610f42af..c0f0fc63df502 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.h +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -28,10 +28,13 @@ namespace txt { class ParagraphBuilderSkia : public ParagraphBuilder { public: ParagraphBuilderSkia(const ParagraphStyle& style, - std::shared_ptr font_collection); + std::shared_ptr font_collection, + const bool impeller_enabled); virtual ~ParagraphBuilderSkia(); + bool IsImpellerEnabled() const { return impeller_enabled_; } + virtual void PushStyle(const TextStyle& style) override; virtual void Pop() override; virtual const TextStyle& PeekStyle() override; @@ -47,6 +50,7 @@ class ParagraphBuilderSkia : public ParagraphBuilder { std::shared_ptr builder_; TextStyle base_style_; + const bool impeller_enabled_; std::stack txt_style_stack_; std::vector dl_paints_; }; diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index c909a34daef6a..04ad4491890df 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -45,27 +45,25 @@ txt::FontStyle GetTxtFontStyle(SkFontStyle::Slant font_slant) { class DisplayListParagraphPainter : public skt::ParagraphPainter { public: + //---------------------------------------------------------------------------- + /// @brief Creates a |skt::ParagraphPainter| that draws to DisplayList. + /// + /// @param builder The display list builder. + /// @param[in] dlPaints The paints referenced by ID in the `drawX` methods. + /// @param[in] drawPathEffectNaively If true, draw path effects naively by + /// drawing multiple lines instead of + /// providing a path effect to the paint. + /// + /// @note Impeller does not support path effects, so this is a stop-gap + /// API (see https://github.com/flutter/flutter/issues/126673) + /// that probably deserves refactoring in the future (and/or usage + /// of #ifdefs). DisplayListParagraphPainter(DisplayListBuilder* builder, - const std::vector& dl_paints) - : builder_(builder), dl_paints_(dl_paints) {} - - DlPaint toDlPaint(const DecorationStyle& decor_style, - DlDrawStyle draw_style = DlDrawStyle::kStroke) { - DlPaint paint; - paint.setDrawStyle(draw_style); - paint.setAntiAlias(true); - paint.setColor(decor_style.getColor()); - paint.setStrokeWidth(decor_style.getStrokeWidth()); - std::optional dash_path_effect = - decor_style.getDashPathEffect(); - if (dash_path_effect) { - std::array intervals{dash_path_effect->fOnLength, - dash_path_effect->fOffLength}; - paint.setPathEffect( - DlDashPathEffect::Make(intervals.data(), intervals.size(), 0)); - } - return paint; - } + const std::vector& dl_paints, + bool draw_path_effect_naively) + : builder_(builder), + dl_paints_(dl_paints), + draw_path_effect_naively_(draw_path_effect_naively) {} void drawTextBlob(const sk_sp& blob, SkScalar x, @@ -118,8 +116,29 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { SkScalar x1, SkScalar y1, const DecorationStyle& decor_style) override { - builder_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), - toDlPaint(decor_style)); + auto dash_path_effect = decor_style.getDashPathEffect(); + if (!draw_path_effect_naively_ || !dash_path_effect) { + DlPaint paint = toDlPaint(decor_style); + builder_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), paint); + return; + } + + // Draw the text decoration (i.e. dashed line) by drawing multiple lines. + auto dx = 0.0; + auto path = SkPath(); + auto on = true; + while (dx < x1 - x0) { + if (on) { + path.moveTo(x0 + dx, y0); + + dx += dash_path_effect->fOnLength; + path.lineTo(x0 + dx, y0); + path.close(); + } else { + dx += dash_path_effect->fOffLength; + } + on = !on; + } } void clipRect(const SkRect& rect) override { @@ -135,8 +154,26 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { void restore() override { builder_->Restore(); } private: + DlPaint toDlPaint(const DecorationStyle& decor_style, + DlDrawStyle draw_style = DlDrawStyle::kStroke) { + DlPaint paint; + paint.setDrawStyle(draw_style); + paint.setAntiAlias(true); + paint.setColor(decor_style.getColor()); + paint.setStrokeWidth(decor_style.getStrokeWidth()); + auto dash_path_effect = decor_style.getDashPathEffect(); + if (!draw_path_effect_naively_ && dash_path_effect) { + std::array intervals{dash_path_effect->fOnLength, + dash_path_effect->fOffLength}; + paint.setPathEffect( + DlDashPathEffect::Make(intervals.data(), intervals.size(), 0)); + } + return paint; + } + DisplayListBuilder* builder_; const std::vector& dl_paints_; + bool draw_path_effect_naively_; }; } // anonymous namespace @@ -223,7 +260,7 @@ void ParagraphSkia::Layout(double width) { } bool ParagraphSkia::Paint(DisplayListBuilder* builder, double x, double y) { - DisplayListParagraphPainter painter(builder, dl_paints_); + DisplayListParagraphPainter painter(builder, dl_paints_, impeller_enabled_); paragraph_->paint(&painter, x, y); return true; } diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index 8fa1314209049..d04b865feb54c 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -75,6 +75,7 @@ class ParagraphSkia : public Paragraph { std::vector dl_paints_; std::optional> line_metrics_; std::vector line_metrics_styles_; + bool impeller_enabled_; }; } // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder.cc b/third_party/txt/src/txt/paragraph_builder.cc index ac1f7dc1b859f..471ea28babcde 100644 --- a/third_party/txt/src/txt/paragraph_builder.cc +++ b/third_party/txt/src/txt/paragraph_builder.cc @@ -24,8 +24,10 @@ namespace txt { std::unique_ptr ParagraphBuilder::CreateSkiaBuilder( const ParagraphStyle& style, - std::shared_ptr font_collection) { - return std::make_unique(style, font_collection); + std::shared_ptr font_collection, + const bool impeller_enabled) { + return std::make_unique(style, font_collection, + impeller_enabled); } } // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder.h b/third_party/txt/src/txt/paragraph_builder.h index 67376940031e0..acd5e952c2fce 100644 --- a/third_party/txt/src/txt/paragraph_builder.h +++ b/third_party/txt/src/txt/paragraph_builder.h @@ -33,7 +33,8 @@ class ParagraphBuilder { public: static std::unique_ptr CreateSkiaBuilder( const ParagraphStyle& style, - std::shared_ptr font_collection); + std::shared_ptr font_collection, + const bool impeller_enabled); virtual ~ParagraphBuilder() = default; From 9656ec58cbfedb8bcfb06b7f3cac66a0f555aed8 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 23 Aug 2023 17:57:56 -0700 Subject: [PATCH 02/17] Its working... Its working. --- lib/ui/text/paragraph_builder.cc | 5 ++--- third_party/txt/src/skia/paragraph_builder_skia.cc | 4 ++-- third_party/txt/src/skia/paragraph_builder_skia.h | 2 -- third_party/txt/src/skia/paragraph_skia.cc | 10 ++++++++-- third_party/txt/src/skia/paragraph_skia.h | 3 ++- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/lib/ui/text/paragraph_builder.cc b/lib/ui/text/paragraph_builder.cc index a53ed88750548..1748bf91ff9da 100644 --- a/lib/ui/text/paragraph_builder.cc +++ b/lib/ui/text/paragraph_builder.cc @@ -300,10 +300,9 @@ ParagraphBuilder::ParagraphBuilder( ->client() ->GetFontCollection(); - auto impeller = UIDartState::Current()->GetIOManager()->GetImpellerContext(); - + auto impeller_enabled = UIDartState::Current()->IsImpellerEnabled(); m_paragraphBuilder = txt::ParagraphBuilder::CreateSkiaBuilder( - style, font_collection.GetFontCollection(), impeller != nullptr); + style, font_collection.GetFontCollection(), impeller_enabled); } ParagraphBuilder::~ParagraphBuilder() = default; diff --git a/third_party/txt/src/skia/paragraph_builder_skia.cc b/third_party/txt/src/skia/paragraph_builder_skia.cc index 7c0c73e48cd11..2028e80353c50 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.cc +++ b/third_party/txt/src/skia/paragraph_builder_skia.cc @@ -86,8 +86,8 @@ void ParagraphBuilderSkia::AddPlaceholder(PlaceholderRun& span) { } std::unique_ptr ParagraphBuilderSkia::Build() { - return std::make_unique(builder_->Build(), - std::move(dl_paints_)); + return std::make_unique( + builder_->Build(), std::move(dl_paints_), impeller_enabled_); } skt::ParagraphPainter::PaintID ParagraphBuilderSkia::CreatePaintID( diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h index c0f0fc63df502..161ea26c8fa06 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.h +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -33,8 +33,6 @@ class ParagraphBuilderSkia : public ParagraphBuilder { virtual ~ParagraphBuilderSkia(); - bool IsImpellerEnabled() const { return impeller_enabled_; } - virtual void PushStyle(const TextStyle& style) override; virtual void Pop() override; virtual const TextStyle& PeekStyle() override; diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index 04ad4491890df..f0215581fef05 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -139,6 +139,8 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { } on = !on; } + + builder_->DrawPath(path, toDlPaint(decor_style)); } void clipRect(const SkRect& rect) override { @@ -179,8 +181,11 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { } // anonymous namespace ParagraphSkia::ParagraphSkia(std::unique_ptr paragraph, - std::vector&& dl_paints) - : paragraph_(std::move(paragraph)), dl_paints_(dl_paints) {} + std::vector&& dl_paints, + const bool impeller_enabled) + : paragraph_(std::move(paragraph)), + dl_paints_(dl_paints), + impeller_enabled_(impeller_enabled) {} double ParagraphSkia::GetMaxWidth() { return SkScalarToDouble(paragraph_->getMaxWidth()); @@ -260,6 +265,7 @@ void ParagraphSkia::Layout(double width) { } bool ParagraphSkia::Paint(DisplayListBuilder* builder, double x, double y) { + FML_LOG(ERROR) << "impeller_enabled_: " << impeller_enabled_; DisplayListParagraphPainter painter(builder, dl_paints_, impeller_enabled_); paragraph_->paint(&painter, x, y); return true; diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index d04b865feb54c..73b21d23fc7b0 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -29,7 +29,8 @@ namespace txt { class ParagraphSkia : public Paragraph { public: ParagraphSkia(std::unique_ptr paragraph, - std::vector&& dl_paints); + std::vector&& dl_paints, + const bool impeller_enabled); virtual ~ParagraphSkia() = default; From bd3a6cecc45785b006a60589cc8d76c99d1214a3 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Wed, 23 Aug 2023 17:59:47 -0700 Subject: [PATCH 03/17] Remove log. --- third_party/txt/src/skia/paragraph_skia.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index f0215581fef05..563ea0ee94eda 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -265,7 +265,6 @@ void ParagraphSkia::Layout(double width) { } bool ParagraphSkia::Paint(DisplayListBuilder* builder, double x, double y) { - FML_LOG(ERROR) << "impeller_enabled_: " << impeller_enabled_; DisplayListParagraphPainter painter(builder, dl_paints_, impeller_enabled_); paragraph_->paint(&painter, x, y); return true; From 9df6760de213470ea3f2e5e85120ca26023e2c3a Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Thu, 24 Aug 2023 09:26:28 -0700 Subject: [PATCH 04/17] Cleanup the code a bit and add comments. --- .../txt/src/skia/paragraph_builder_skia.h | 13 ++- third_party/txt/src/skia/paragraph_skia.cc | 105 +++++++++++------- third_party/txt/src/skia/paragraph_skia.h | 2 +- third_party/txt/src/txt/paragraph_builder.cc | 6 + 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/third_party/txt/src/skia/paragraph_builder_skia.h b/third_party/txt/src/skia/paragraph_builder_skia.h index 161ea26c8fa06..f14f7fe41f591 100644 --- a/third_party/txt/src/skia/paragraph_builder_skia.h +++ b/third_party/txt/src/skia/paragraph_builder_skia.h @@ -24,7 +24,11 @@ namespace txt { -// Implementation of ParagraphBuilder based on Skia's text layout module. +//------------------------------------------------------------------------------ +/// @brief ParagraphBuilder implementation using Skia's text layout module. +/// +/// @note Despite the suffix "Skia", this class is not specific to Skia +/// and is also used with the Impeller backend. class ParagraphBuilderSkia : public ParagraphBuilder { public: ParagraphBuilderSkia(const ParagraphStyle& style, @@ -48,6 +52,13 @@ class ParagraphBuilderSkia : public ParagraphBuilder { std::shared_ptr builder_; TextStyle base_style_; + + /// @brief Whether Impeller is enabled in the runtime. + /// + /// @note As of the time of this writing, this is used to draw text + /// decorations (i.e. dashed and dotted lines) directly using the + /// `drawLine` API, because Impeller's path rendering does not + /// support dashed and dotted lines (but Skia's does). const bool impeller_enabled_; std::stack txt_style_stack_; std::vector dl_paints_; diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index 563ea0ee94eda..76d737224aa79 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -18,6 +18,7 @@ #include #include +#include "fml/logging.h" namespace txt { @@ -49,21 +50,25 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { /// @brief Creates a |skt::ParagraphPainter| that draws to DisplayList. /// /// @param builder The display list builder. - /// @param[in] dlPaints The paints referenced by ID in the `drawX` methods. - /// @param[in] drawPathEffectNaively If true, draw path effects naively by - /// drawing multiple lines instead of - /// providing a path effect to the paint. + /// @param[in] dl_paints The paints referenced by ID in the `drawX` methods. + /// @param[in] draw_path_effect If true, draw path effects directly by + /// drawing multiple lines instead of providing + // a path effect to the paint. /// - /// @note Impeller does not support path effects, so this is a stop-gap - /// API (see https://github.com/flutter/flutter/issues/126673) - /// that probably deserves refactoring in the future (and/or usage - /// of #ifdefs). + /// @note Impeller does not (and will not) support path effects, but the + /// Skia backend does. That means that if we want to draw dashed + /// and dotted lines, we need to draw them directly using the + /// `drawLine` API instead of using a path effect. + /// + /// See https://github.com/flutter/flutter/issues/126673. It + /// probably makes sense to eventually make this a compile-time + /// decision (i.e. with `#ifdef`) instead of a runtime option. DisplayListParagraphPainter(DisplayListBuilder* builder, const std::vector& dl_paints, - bool draw_path_effect_naively) + bool draw_path_effect) : builder_(builder), dl_paints_(dl_paints), - draw_path_effect_naively_(draw_path_effect_naively) {} + draw_path_effect_(draw_path_effect) {} void drawTextBlob(const sk_sp& blob, SkScalar x, @@ -116,31 +121,25 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { SkScalar x1, SkScalar y1, const DecorationStyle& decor_style) override { + // We only support horizontal lines. + FML_DCHECK(y0 == y1); + + // This function is called for both solid and dashed lines. If we're drawing + // a dashed line, and we're using the Impeller backend, then we need to draw + // the line directly using the `drawLine` API instead of using a path effect + // (because Impeller does not support path effects). auto dash_path_effect = decor_style.getDashPathEffect(); - if (!draw_path_effect_naively_ || !dash_path_effect) { - DlPaint paint = toDlPaint(decor_style); - builder_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), paint); + if (draw_path_effect_ && dash_path_effect) { + auto path = dashedLine(x0, x1, y0, *dash_path_effect); + builder_->DrawPath(path, toDlPaint(decor_style)); return; } - // Draw the text decoration (i.e. dashed line) by drawing multiple lines. - auto dx = 0.0; - auto path = SkPath(); - auto on = true; - while (dx < x1 - x0) { - if (on) { - path.moveTo(x0 + dx, y0); - - dx += dash_path_effect->fOnLength; - path.lineTo(x0 + dx, y0); - path.close(); - } else { - dx += dash_path_effect->fOffLength; - } - on = !on; + auto paint = toDlPaint(decor_style); + if (dash_path_effect) { + setPathEffect(paint, *dash_path_effect); } - - builder_->DrawPath(path, toDlPaint(decor_style)); + builder_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), paint); } void clipRect(const SkRect& rect) override { @@ -156,6 +155,31 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { void restore() override { builder_->Restore(); } private: + SkPath dashedLine(SkScalar x0, + SkScalar x1, + SkScalar y0, + const DashPathEffect& dash_path_effect) { + auto dx = 0.0; + auto path = SkPath(); + auto on = true; + auto length = x1 - x0; + while (dx < length) { + if (on) { + // Draw the on part of the dash. + path.moveTo(x0 + dx, y0); + dx += dash_path_effect.fOnLength; + path.lineTo(x0 + dx, y0); + } else { + // Skip the off part of the dash. + dx += dash_path_effect.fOffLength; + } + on = !on; + } + + path.close(); + return path; + } + DlPaint toDlPaint(const DecorationStyle& decor_style, DlDrawStyle draw_style = DlDrawStyle::kStroke) { DlPaint paint; @@ -163,26 +187,29 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { paint.setAntiAlias(true); paint.setColor(decor_style.getColor()); paint.setStrokeWidth(decor_style.getStrokeWidth()); - auto dash_path_effect = decor_style.getDashPathEffect(); - if (!draw_path_effect_naively_ && dash_path_effect) { - std::array intervals{dash_path_effect->fOnLength, - dash_path_effect->fOffLength}; - paint.setPathEffect( - DlDashPathEffect::Make(intervals.data(), intervals.size(), 0)); - } return paint; } + void setPathEffect(DlPaint& paint, const DashPathEffect& dash_path_effect) { + // Impeller does not support path effects, so we should never be setting. + FML_DCHECK(!draw_path_effect_); + + std::array intervals{dash_path_effect.fOnLength, + dash_path_effect.fOffLength}; + auto effect = DlDashPathEffect::Make(intervals.data(), intervals.size(), 0); + paint.setPathEffect(effect); + } + DisplayListBuilder* builder_; const std::vector& dl_paints_; - bool draw_path_effect_naively_; + bool draw_path_effect_; }; } // anonymous namespace ParagraphSkia::ParagraphSkia(std::unique_ptr paragraph, std::vector&& dl_paints, - const bool impeller_enabled) + bool impeller_enabled) : paragraph_(std::move(paragraph)), dl_paints_(dl_paints), impeller_enabled_(impeller_enabled) {} diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index 73b21d23fc7b0..323674d675e50 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -76,7 +76,7 @@ class ParagraphSkia : public Paragraph { std::vector dl_paints_; std::optional> line_metrics_; std::vector line_metrics_styles_; - bool impeller_enabled_; + const bool impeller_enabled_; }; } // namespace txt diff --git a/third_party/txt/src/txt/paragraph_builder.cc b/third_party/txt/src/txt/paragraph_builder.cc index 471ea28babcde..41dd9b1a8958a 100644 --- a/third_party/txt/src/txt/paragraph_builder.cc +++ b/third_party/txt/src/txt/paragraph_builder.cc @@ -22,6 +22,12 @@ namespace txt { +//------------------------------------------------------------------------------ +/// @brief Creates a |ParagraphBuilder| based on Skia's text layout module. +/// +/// @param[in] style The style to use for the paragraph. +/// @param[in] font_collection The font collection to use for the paragraph. +/// @param[in] impeller_enabled Whether Impeller is enabled in the runtime. std::unique_ptr ParagraphBuilder::CreateSkiaBuilder( const ParagraphStyle& style, std::shared_ptr font_collection, From 8303c5c18c25a6e1d5f5f072e0e590abad84bf2e Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Thu, 24 Aug 2023 10:02:23 -0700 Subject: [PATCH 05/17] Revert const that has no semantics. --- third_party/txt/src/skia/paragraph_skia.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index 323674d675e50..5779445e09a71 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -30,7 +30,7 @@ class ParagraphSkia : public Paragraph { public: ParagraphSkia(std::unique_ptr paragraph, std::vector&& dl_paints, - const bool impeller_enabled); + bool impeller_enabled); virtual ~ParagraphSkia() = default; From 7fe82cf4ac753c8d09b51feea7b5b9ab7bfcb923 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Thu, 24 Aug 2023 17:37:55 -0700 Subject: [PATCH 06/17] Start on some not-yet-functional unittests. --- third_party/txt/BUILD.gn | 3 ++ third_party/txt/tests/paragraph_unittests.cc | 56 ++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 third_party/txt/tests/paragraph_unittests.cc diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index 1f57ef313a84e..3cf7198a20b3a 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -143,6 +143,7 @@ if (enable_unittests) { sources = [ "tests/font_collection_tests.cc", + "tests/paragraph_unittests.cc", "tests/txt_run_all_unittests.cc", ] @@ -154,7 +155,9 @@ if (enable_unittests) { ":txt", ":txt_fixtures", "//flutter/fml", + "//flutter/testing:skia", "//flutter/testing:testing_lib", + "//third_party/skia/modules/skparagraph:skparagraph", ] # This is needed for //third_party/googletest for linking zircon symbols. diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc new file mode 100644 index 0000000000000..c256180a5a155 --- /dev/null +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -0,0 +1,56 @@ +// 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 +#include "display_list/dl_builder.h" +#include "display_list/dl_paint.h" +#include "flutter/fml/macros.h" +#include "gtest/gtest.h" +#include "skia/paragraph_builder_skia.h" +#include "skia/paragraph_skia.h" +#include "testing/canvas_test.h" +#include "testing/display_list_testing.h" +#include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" +#include "txt/paragraph.h" + +namespace flutter { +namespace testing { + +template +class PainterTestBase : public CanvasTestBase { + public: + PainterTestBase() = default; + + void PretendImpellerIsEnabled(bool impeller) { impeller_ = impeller; } + + bool impeller_ = false; +}; + +using PainterTest = PainterTestBase<::testing::Test>; + +TEST_F(PainterTest, RendersSolidLine) { + // Test that, irrespective of backend, we render a solid line. + PretendImpellerIsEnabled(false); + + auto p_style = txt::ParagraphStyle(); + auto f_collection = std::make_shared(); + f_collection->SetDefaultFontManager(0); + auto pb_skia = txt::ParagraphBuilderSkia(p_style, f_collection, false); + + pb_skia.AddText(u"Hello, world!"); + + auto t_style = txt::TextStyle(); + t_style.decoration_style = txt::TextDecorationStyle::kSolid; + pb_skia.PushStyle(t_style); + auto builder = flutter::DisplayListBuilder(); + pb_skia.Build()->Paint(&builder, 0, 0); + + DisplayListBuilder expected; + expected.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(0, 0), + DlPaint(DlColor::kBlack())); + EXPECT_TRUE(DisplayListsEQ_Verbose(builder.Build(), expected.Build())); +} + +} // namespace testing +} // namespace flutter From fb8ea2c25e4e1497ed1e1f4eddf73a0bc2da3a77 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 12:18:54 -0700 Subject: [PATCH 07/17] Commit what I have so far. --- third_party/txt/tests/paragraph_unittests.cc | 67 ++++++++++++++------ 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index c256180a5a155..75923302275eb 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -13,6 +13,7 @@ #include "testing/display_list_testing.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" #include "txt/paragraph.h" +#include "txt/text_decoration.h" namespace flutter { namespace testing { @@ -24,33 +25,59 @@ class PainterTestBase : public CanvasTestBase { void PretendImpellerIsEnabled(bool impeller) { impeller_ = impeller; } - bool impeller_ = false; -}; + protected: + void AssertDrawsSolidLine() { + auto t_style = makeDecoratedStyle(txt::TextDecorationStyle::kSolid); + auto pb_skia = makeParagraphBuilder(); + pb_skia.PushStyle(t_style); + pb_skia.AddText(u"Hello World!"); + pb_skia.Pop(); -using PainterTest = PainterTestBase<::testing::Test>; + auto builder = flutter::DisplayListBuilder(); + auto paragraph = pb_skia.Build(); + paragraph->Layout(10000); + paragraph->Paint(&builder, 0, 0); -TEST_F(PainterTest, RendersSolidLine) { - // Test that, irrespective of backend, we render a solid line. - PretendImpellerIsEnabled(false); + DisplayListBuilder expected; + expected.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(0, 0), + DlPaint(DlColor::kBlack())); + EXPECT_TRUE(DisplayListsEQ_Verbose(builder.Build(), expected.Build())); + } - auto p_style = txt::ParagraphStyle(); - auto f_collection = std::make_shared(); - f_collection->SetDefaultFontManager(0); - auto pb_skia = txt::ParagraphBuilderSkia(p_style, f_collection, false); + private: + txt::ParagraphBuilderSkia makeParagraphBuilder() { + auto p_style = txt::ParagraphStyle(); + auto f_collection = std::make_shared(); + /* Doesn't appear to do anything. + auto sk_f_collection = f_collection->CreateSktFontCollection(); + f_collection->SetDefaultFontManager(sk_f_collection->getFallbackManager()); + */ + return txt::ParagraphBuilderSkia(p_style, f_collection, impeller_); + } - pb_skia.AddText(u"Hello, world!"); + txt::TextStyle makeDecoratedStyle(txt::TextDecorationStyle style) { + auto t_style = txt::TextStyle(); + t_style.font_weight = txt::FontWeight::w400; // normal + t_style.font_size = 14; + t_style.decoration_style = style; + return t_style; + } - auto t_style = txt::TextStyle(); - t_style.decoration_style = txt::TextDecorationStyle::kSolid; - pb_skia.PushStyle(t_style); - auto builder = flutter::DisplayListBuilder(); - pb_skia.Build()->Paint(&builder, 0, 0); + bool impeller_ = false; +}; + +using PainterTest = PainterTestBase<::testing::Test>; + +TEST_F(PainterTest, DrawsSolidLineSkia) { + AssertDrawsSolidLine(); +} - DisplayListBuilder expected; - expected.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(0, 0), - DlPaint(DlColor::kBlack())); - EXPECT_TRUE(DisplayListsEQ_Verbose(builder.Build(), expected.Build())); +/* +TEST_F(PainterTest, DrawsSolidLineImpeller) { + PretendImpellerIsEnabled(true); + AssertDrawsSolidLine(); } +*/ } // namespace testing } // namespace flutter From 8a8c798a3ba6de48bbce46fe47255a3878c1122e Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 15:47:32 -0700 Subject: [PATCH 08/17] Tests are passing. --- third_party/txt/BUILD.gn | 1 + third_party/txt/src/skia/paragraph_skia.cc | 5 +- third_party/txt/tests/paragraph_unittests.cc | 121 +++++++++++++++--- .../txt/tests/txt_run_all_unittests.cc | 3 - 4 files changed, 109 insertions(+), 21 deletions(-) diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index 3cf7198a20b3a..b799bc5dd46d5 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -155,6 +155,7 @@ if (enable_unittests) { ":txt", ":txt_fixtures", "//flutter/fml", + "//flutter/runtime:test_font", "//flutter/testing:skia", "//flutter/testing:testing_lib", "//third_party/skia/modules/skparagraph:skparagraph", diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index 76d737224aa79..c0c7a1587dc3c 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -68,7 +68,10 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { bool draw_path_effect) : builder_(builder), dl_paints_(dl_paints), - draw_path_effect_(draw_path_effect) {} + draw_path_effect_(draw_path_effect) { + FML_LOG(ERROR) << "DisplayListParagraphPainter draw_path_effect_: " + << draw_path_effect_; + } void drawTextBlob(const sk_sp& blob, SkScalar x, diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 75923302275eb..5f1fef7770b7e 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -3,21 +3,65 @@ // found in the LICENSE file. #include +#include "display_list/display_list.h" #include "display_list/dl_builder.h" +#include "display_list/dl_op_records.h" #include "display_list/dl_paint.h" +#include "display_list/effects/dl_path_effect.h" #include "flutter/fml/macros.h" +#include "fml/command_line.h" +#include "fml/icu_util.h" #include "gtest/gtest.h" +#include "include/core/SkColor.h" +#include "include/core/SkRefCnt.h" +#include "include/core/SkTextBlob.h" +#include "runtime/test_font_data.h" +#include "shell/common/dl_op_spy.h" #include "skia/paragraph_builder_skia.h" #include "skia/paragraph_skia.h" #include "testing/canvas_test.h" #include "testing/display_list_testing.h" #include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" +#include "txt/font_collection.h" #include "txt/paragraph.h" #include "txt/text_decoration.h" +#include "txt/typeface_font_asset_provider.h" namespace flutter { namespace testing { +//------------------------------------------------------------------------------ +/// @brief A custom |DlOpReceiver| that records some |DlOps| it receives. +class DlOpRecorder final : public virtual DlOpReceiver, + private IgnoreAttributeDispatchHelper, + private IgnoreClipDispatchHelper, + private IgnoreDrawDispatchHelper, + private IgnoreTransformDispatchHelper { + public: + int lineCount() const { return lines_.size(); } + int rectCount() const { return rects_.size(); } + int pathCount() const { return paths_.size(); } + bool hasPathEffect() const { return path_effect_ != nullptr; } + + private: + void drawLine(const SkPoint& p0, const SkPoint& p1) override { + lines_.emplace_back(p0, p1); + } + + void drawRect(const SkRect& rect) override { rects_.push_back(rect); } + + void drawPath(const SkPath& path) override { paths_.push_back(path); } + + void setPathEffect(const DlPathEffect* effect) override { + path_effect_ = effect; + } + + std::vector> lines_; + std::vector rects_; + std::vector paths_; + const DlPathEffect* path_effect_; +}; + template class PainterTestBase : public CanvasTestBase { public: @@ -26,40 +70,48 @@ class PainterTestBase : public CanvasTestBase { void PretendImpellerIsEnabled(bool impeller) { impeller_ = impeller; } protected: - void AssertDrawsSolidLine() { - auto t_style = makeDecoratedStyle(txt::TextDecorationStyle::kSolid); + sk_sp draw(txt::TextDecorationStyle style) { + auto t_style = makeDecoratedStyle(style); auto pb_skia = makeParagraphBuilder(); pb_skia.PushStyle(t_style); pb_skia.AddText(u"Hello World!"); pb_skia.Pop(); - auto builder = flutter::DisplayListBuilder(); + auto builder = DisplayListBuilder(); auto paragraph = pb_skia.Build(); paragraph->Layout(10000); paragraph->Paint(&builder, 0, 0); - DisplayListBuilder expected; - expected.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(0, 0), - DlPaint(DlColor::kBlack())); - EXPECT_TRUE(DisplayListsEQ_Verbose(builder.Build(), expected.Build())); + return builder.Build(); } private: + std::shared_ptr makeFontCollection() { + auto f_collection = std::make_shared(); + auto font_provider = std::make_unique(); + for (auto& font : GetTestFontData()) { + font_provider->RegisterTypeface(font); + } + auto manager = sk_make_sp(std::move(font_provider)); + f_collection->SetAssetFontManager(manager); + return f_collection; + } + txt::ParagraphBuilderSkia makeParagraphBuilder() { auto p_style = txt::ParagraphStyle(); - auto f_collection = std::make_shared(); - /* Doesn't appear to do anything. - auto sk_f_collection = f_collection->CreateSktFontCollection(); - f_collection->SetDefaultFontManager(sk_f_collection->getFallbackManager()); - */ + auto f_collection = makeFontCollection(); return txt::ParagraphBuilderSkia(p_style, f_collection, impeller_); } txt::TextStyle makeDecoratedStyle(txt::TextDecorationStyle style) { auto t_style = txt::TextStyle(); + t_style.color = SK_ColorBLACK; // default t_style.font_weight = txt::FontWeight::w400; // normal - t_style.font_size = 14; + t_style.font_size = 14; // default + t_style.decoration = txt::TextDecoration::kUnderline; t_style.decoration_style = style; + t_style.decoration_color = SK_ColorBLACK; + t_style.font_families.push_back("ahem"); return t_style; } @@ -69,15 +121,50 @@ class PainterTestBase : public CanvasTestBase { using PainterTest = PainterTestBase<::testing::Test>; TEST_F(PainterTest, DrawsSolidLineSkia) { - AssertDrawsSolidLine(); + PretendImpellerIsEnabled(false); + + auto recorder = DlOpRecorder(); + draw(txt::TextDecorationStyle::kSolid)->Dispatch(recorder); + + // Skia may draw a solid underline as a filled rectangle: + // https://skia.googlesource.com/skia/+/refs/heads/main/modules/skparagraph/src/Decorations.cpp#91 + EXPECT_EQ(recorder.rectCount(), 1); + EXPECT_FALSE(recorder.hasPathEffect()); } -/* TEST_F(PainterTest, DrawsSolidLineImpeller) { PretendImpellerIsEnabled(true); - AssertDrawsSolidLine(); + + auto recorder = DlOpRecorder(); + draw(txt::TextDecorationStyle::kSolid)->Dispatch(recorder); + + // Skia may draw a solid underline as a filled rectangle: + // https://skia.googlesource.com/skia/+/refs/heads/main/modules/skparagraph/src/Decorations.cpp#91 + EXPECT_EQ(recorder.rectCount(), 1); + EXPECT_FALSE(recorder.hasPathEffect()); +} + +TEST_F(PainterTest, DrawDashedLineSkia) { + PretendImpellerIsEnabled(false); + + auto recorder = DlOpRecorder(); + draw(txt::TextDecorationStyle::kDashed)->Dispatch(recorder); + + // Skia draws a dashed underline as a filled rectangle with a path effect. + EXPECT_EQ(recorder.lineCount(), 1); + EXPECT_TRUE(recorder.hasPathEffect()); +} + +TEST_F(PainterTest, DrawDashedLineImpeller) { + PretendImpellerIsEnabled(true); + + auto recorder = DlOpRecorder(); + draw(txt::TextDecorationStyle::kDashed)->Dispatch(recorder); + + // Impeller draws a dashed underline as a path. + EXPECT_EQ(recorder.pathCount(), 1); + EXPECT_FALSE(recorder.hasPathEffect()); } -*/ } // namespace testing } // namespace flutter diff --git a/third_party/txt/tests/txt_run_all_unittests.cc b/third_party/txt/tests/txt_run_all_unittests.cc index bc1629fe42ba9..7a20fa6b99f9a 100644 --- a/third_party/txt/tests/txt_run_all_unittests.cc +++ b/third_party/txt/tests/txt_run_all_unittests.cc @@ -15,13 +15,10 @@ */ #include "flutter/fml/backtrace.h" -#include "flutter/fml/command_line.h" -#include "flutter/fml/logging.h" #include "flutter/testing/testing.h" int main(int argc, char** argv) { fml::InstallCrashHandler(); - fml::CommandLine cmd = fml::CommandLineFromPlatformOrArgcArgv(argc, argv); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } From 54d3acbd107cf65efc0dba4e5a1cf5edf1b0786d Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 15:49:17 -0700 Subject: [PATCH 09/17] Remove log. --- third_party/txt/src/skia/paragraph_skia.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index c0c7a1587dc3c..76d737224aa79 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -68,10 +68,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { bool draw_path_effect) : builder_(builder), dl_paints_(dl_paints), - draw_path_effect_(draw_path_effect) { - FML_LOG(ERROR) << "DisplayListParagraphPainter draw_path_effect_: " - << draw_path_effect_; - } + draw_path_effect_(draw_path_effect) {} void drawTextBlob(const sk_sp& blob, SkScalar x, From 5a505309a54f9847227c7428d1cc938c2d69448d Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 15:57:36 -0700 Subject: [PATCH 10/17] Fix GN dependency warning. --- third_party/txt/BUILD.gn | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index b799bc5dd46d5..47ad19bc9d422 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -156,6 +156,7 @@ if (enable_unittests) { ":txt_fixtures", "//flutter/fml", "//flutter/runtime:test_font", + "//flutter/shell/common:common", "//flutter/testing:skia", "//flutter/testing:testing_lib", "//third_party/skia/modules/skparagraph:skparagraph", From d2e1675a7094fb0cc7a391c3e58b080c701aa26e Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 16:21:51 -0700 Subject: [PATCH 11/17] Remove unused #include. --- third_party/txt/BUILD.gn | 1 - third_party/txt/tests/paragraph_unittests.cc | 20 +------------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/third_party/txt/BUILD.gn b/third_party/txt/BUILD.gn index 47ad19bc9d422..b799bc5dd46d5 100644 --- a/third_party/txt/BUILD.gn +++ b/third_party/txt/BUILD.gn @@ -156,7 +156,6 @@ if (enable_unittests) { ":txt_fixtures", "//flutter/fml", "//flutter/runtime:test_font", - "//flutter/shell/common:common", "//flutter/testing:skia", "//flutter/testing:testing_lib", "//third_party/skia/modules/skparagraph:skparagraph", diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 5f1fef7770b7e..3e7f143a27efb 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -3,29 +3,11 @@ // found in the LICENSE file. #include -#include "display_list/display_list.h" -#include "display_list/dl_builder.h" -#include "display_list/dl_op_records.h" -#include "display_list/dl_paint.h" -#include "display_list/effects/dl_path_effect.h" -#include "flutter/fml/macros.h" -#include "fml/command_line.h" -#include "fml/icu_util.h" +#include "display_list/utils/dl_receiver_utils.h" #include "gtest/gtest.h" -#include "include/core/SkColor.h" -#include "include/core/SkRefCnt.h" -#include "include/core/SkTextBlob.h" #include "runtime/test_font_data.h" -#include "shell/common/dl_op_spy.h" #include "skia/paragraph_builder_skia.h" -#include "skia/paragraph_skia.h" #include "testing/canvas_test.h" -#include "testing/display_list_testing.h" -#include "third_party/skia/modules/skparagraph/include/ParagraphBuilder.h" -#include "txt/font_collection.h" -#include "txt/paragraph.h" -#include "txt/text_decoration.h" -#include "txt/typeface_font_asset_provider.h" namespace flutter { namespace testing { From 60051e6554dd157885244757d984ff9eeba191d4 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Fri, 25 Aug 2023 16:27:55 -0700 Subject: [PATCH 12/17] Add some const. --- third_party/txt/tests/paragraph_unittests.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 3e7f143a27efb..ec06ce702512e 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -52,7 +52,7 @@ class PainterTestBase : public CanvasTestBase { void PretendImpellerIsEnabled(bool impeller) { impeller_ = impeller; } protected: - sk_sp draw(txt::TextDecorationStyle style) { + sk_sp draw(txt::TextDecorationStyle style) const { auto t_style = makeDecoratedStyle(style); auto pb_skia = makeParagraphBuilder(); pb_skia.PushStyle(t_style); @@ -68,7 +68,7 @@ class PainterTestBase : public CanvasTestBase { } private: - std::shared_ptr makeFontCollection() { + std::shared_ptr makeFontCollection() const { auto f_collection = std::make_shared(); auto font_provider = std::make_unique(); for (auto& font : GetTestFontData()) { @@ -79,13 +79,13 @@ class PainterTestBase : public CanvasTestBase { return f_collection; } - txt::ParagraphBuilderSkia makeParagraphBuilder() { + txt::ParagraphBuilderSkia makeParagraphBuilder() const { auto p_style = txt::ParagraphStyle(); auto f_collection = makeFontCollection(); return txt::ParagraphBuilderSkia(p_style, f_collection, impeller_); } - txt::TextStyle makeDecoratedStyle(txt::TextDecorationStyle style) { + txt::TextStyle makeDecoratedStyle(txt::TextDecorationStyle style) const { auto t_style = txt::TextStyle(); t_style.color = SK_ColorBLACK; // default t_style.font_weight = txt::FontWeight::w400; // normal From 9cf3b19613308a0685d9a517729faabafe1a1552 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 26 Aug 2023 12:01:38 -0700 Subject: [PATCH 13/17] Fix imports. --- third_party/txt/tests/paragraph_unittests.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index ec06ce702512e..9e13492bcc1fc 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include +#include "display_list/display_list_builder.h" #include "display_list/utils/dl_receiver_utils.h" #include "gtest/gtest.h" #include "runtime/test_font_data.h" From 842bba2b62a94501e14568c5b423e80f85fcb99b Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 26 Aug 2023 17:51:17 -0700 Subject: [PATCH 14/17] Revert "Fix imports." This reverts commit 9cf3b19613308a0685d9a517729faabafe1a1552. --- third_party/txt/tests/paragraph_unittests.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/txt/tests/paragraph_unittests.cc b/third_party/txt/tests/paragraph_unittests.cc index 9e13492bcc1fc..ec06ce702512e 100644 --- a/third_party/txt/tests/paragraph_unittests.cc +++ b/third_party/txt/tests/paragraph_unittests.cc @@ -3,7 +3,6 @@ // found in the LICENSE file. #include -#include "display_list/display_list_builder.h" #include "display_list/utils/dl_receiver_utils.h" #include "gtest/gtest.h" #include "runtime/test_font_data.h" From b2b6cb125e2566bc2b2e6896e0f403fbef02a02c Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 26 Aug 2023 17:52:12 -0700 Subject: [PATCH 15/17] Revert "Merge with Dan's PR." This reverts commit 17b8e8eadeba0404068e5f74e9c3db2e3391097b, reversing changes made to 60051e6554dd157885244757d984ff9eeba191d4. --- DEPS | 4 +- ci/licenses_golden/excluded_files | 3 +- ci/licenses_golden/licenses_flutter | 16 +- ci/licenses_golden/licenses_skia | 6 +- display_list/BUILD.gn | 3 - display_list/display_list.cc | 2 +- display_list/display_list.h | 6 +- display_list/display_list_unittests.cc | 2 +- display_list/dl_canvas.h | 14 +- display_list/dl_canvas_to_receiver.cc | 6 - display_list/dl_canvas_to_receiver.h | 8 - display_list/geometry/dl_rtree.h | 2 +- display_list/skia/dl_sk_canvas.cc | 7 - display_list/skia/dl_sk_canvas.h | 3 - display_list/utils/dl_bounds_accumulator.cc | 7 +- display_list/utils/dl_bounds_accumulator.h | 6 +- flow/BUILD.gn | 7 - flow/embedded_views.cc | 46 +- flow/embedded_views.h | 28 +- flow/layers/aiks_layer.cc | 67 - flow/layers/aiks_layer.h | 44 - flow/layers/aiks_layer_unittests.cc | 49 - flow/layers/layer.h | 2 - flow/layers/layer_tree.cc | 63 - flow/layers/layer_tree.h | 4 - flow/raster_cache.cc | 6 +- flow/raster_cache.h | 8 +- flow/surface_frame.cc | 22 +- flow/surface_frame.h | 12 +- flow/surface_frame_unittests.cc | 2 - impeller/aiks/BUILD.gn | 1 - impeller/aiks/canvas.cc | 19 +- impeller/aiks/canvas.h | 4 +- impeller/aiks/picture.h | 2 - impeller/display_list/BUILD.gn | 2 - impeller/display_list/dl_aiks_canvas.cc | 1203 ----------------- impeller/display_list/dl_aiks_canvas.h | 242 ---- impeller/display_list/skia_conversions.h | 27 - impeller/entity/entity_pass.cc | 3 - impeller/entity/entity_pass.h | 1 + impeller/entity/geometry/geometry.cc | 9 +- impeller/entity/geometry/geometry.h | 5 +- .../entity/geometry/point_field_geometry.cc | 4 +- .../entity/geometry/point_field_geometry.h | 4 +- impeller/geometry/rect.h | 5 - impeller/geometry/sigma.h | 6 +- lib/ui/compositing/scene.cc | 7 +- lib/ui/compositing/scene_builder.cc | 10 - lib/ui/painting/canvas.cc | 197 ++- lib/ui/painting/canvas.h | 6 +- ...isplay_list_deferred_image_gpu_impeller.cc | 143 +- ...display_list_deferred_image_gpu_impeller.h | 32 +- lib/ui/painting/paint.cc | 8 +- lib/ui/painting/picture.cc | 164 +-- lib/ui/painting/picture.h | 69 +- lib/ui/painting/picture_recorder.cc | 33 +- lib/ui/painting/picture_recorder.h | 15 +- lib/ui/snapshot_delegate.h | 4 - lib/ui/text/paragraph.cc | 6 +- shell/common/BUILD.gn | 3 + {display_list => shell/common}/dl_op_spy.cc | 2 +- {display_list => shell/common}/dl_op_spy.h | 5 +- .../common}/dl_op_spy_unittests.cc | 2 +- shell/common/rasterizer.cc | 6 - shell/common/rasterizer.h | 5 - shell/common/snapshot_controller.h | 4 - shell/common/snapshot_controller_impeller.cc | 25 +- shell/common/snapshot_controller_impeller.h | 7 - shell/common/snapshot_controller_skia.cc | 7 - shell/common/snapshot_controller_skia.h | 4 - shell/gpu/gpu_surface_gl_impeller.cc | 24 +- shell/gpu/gpu_surface_metal_impeller.mm | 33 +- shell/gpu/gpu_surface_vulkan_impeller.cc | 19 +- .../external_view_embedder.cc | 12 +- .../external_view_embedder.h | 5 +- .../external_view_embedder_unittests.cc | 41 +- .../platform/android/platform_view_android.cc | 3 +- shell/platform/embedder/embedder.cc | 2 +- .../embedder/embedder_external_view.cc | 50 +- .../embedder/embedder_external_view.h | 8 +- .../embedder_external_view_embedder.cc | 11 +- .../embedder_external_view_embedder.h | 4 +- testing/mock_canvas.cc | 18 - testing/mock_canvas.h | 15 +- third_party/txt/src/skia/paragraph_skia.cc | 32 +- third_party/txt/src/skia/paragraph_skia.h | 2 +- third_party/txt/src/txt/paragraph.h | 8 +- 87 files changed, 424 insertions(+), 2619 deletions(-) delete mode 100644 flow/layers/aiks_layer.cc delete mode 100644 flow/layers/aiks_layer.h delete mode 100644 flow/layers/aiks_layer_unittests.cc delete mode 100644 impeller/display_list/dl_aiks_canvas.cc delete mode 100644 impeller/display_list/dl_aiks_canvas.h rename {display_list => shell/common}/dl_op_spy.cc (99%) rename {display_list => shell/common}/dl_op_spy.h (97%) rename {display_list => shell/common}/dl_op_spy_unittests.cc (99%) diff --git a/DEPS b/DEPS index 48e8945406ab5..79ee05b4d3d6c 100644 --- a/DEPS +++ b/DEPS @@ -18,7 +18,7 @@ vars = { 'llvm_git': 'https://llvm.googlesource.com', # OCMock is for testing only so there is no google clone 'ocmock_git': 'https://github.com/erikdoe/ocmock.git', - 'skia_revision': 'e64e8f4094b2c8610fd19310674cb75a94c62b05', + 'skia_revision': 'e67d9439a8c450df2e174b090e9eb2370e63d0e1', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. @@ -896,7 +896,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': 'IYiIm4zYdKPYfpOIGDmC5EC7pO8dSsV4PIaZNWJ0NU0C' + 'version': 'u8ovJYTk3nN78xF4XDkt21AoQvutv5bbMKVQwMUs40AC' } ], 'condition': 'host_os == "linux" and not download_fuchsia_sdk', diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 5ef382077f075..b1781c393291f 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -32,7 +32,6 @@ ../../../flutter/display_list/benchmarking/dl_complexity_unittests.cc ../../../flutter/display_list/display_list_unittests.cc ../../../flutter/display_list/dl_color_unittests.cc -../../../flutter/display_list/dl_op_spy_unittests.cc ../../../flutter/display_list/dl_paint_unittests.cc ../../../flutter/display_list/dl_vertices_unittests.cc ../../../flutter/display_list/effects/dl_color_filter_unittests.cc @@ -55,7 +54,6 @@ ../../../flutter/flow/frame_timings_recorder_unittests.cc ../../../flutter/flow/gl_context_switch_unittests.cc ../../../flutter/flow/instrumentation_unittests.cc -../../../flutter/flow/layers/aiks_layer_unittests.cc ../../../flutter/flow/layers/backdrop_filter_layer_unittests.cc ../../../flutter/flow/layers/checkerboard_layertree_unittests.cc ../../../flutter/flow/layers/clip_path_layer_unittests.cc @@ -221,6 +219,7 @@ ../../../flutter/runtime/type_conversions_unittests.cc ../../../flutter/shell/common/animator_unittests.cc ../../../flutter/shell/common/context_options_unittests.cc +../../../flutter/shell/common/dl_op_spy_unittests.cc ../../../flutter/shell/common/engine_unittests.cc ../../../flutter/shell/common/fixtures ../../../flutter/shell/common/input_events_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 5f6393dcc9ce2..c8bfff45c3ed1 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -735,8 +735,6 @@ ORIGIN: ../../../flutter/display_list/dl_op_recorder.cc + ../../../flutter/LICEN ORIGIN: ../../../flutter/display_list/dl_op_recorder.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_op_records.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_op_records.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/display_list/dl_op_spy.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/display_list/dl_op_spy.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_paint.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_paint.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/display_list/dl_sampling_options.h + ../../../flutter/LICENSE @@ -793,8 +791,6 @@ ORIGIN: ../../../flutter/flow/instrumentation.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/instrumentation.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layer_snapshot_store.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layer_snapshot_store.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/flow/layers/aiks_layer.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/flow/layers/aiks_layer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/backdrop_filter_layer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/backdrop_filter_layer.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/layers/cacheable_layer.cc + ../../../flutter/LICENSE @@ -1167,8 +1163,6 @@ ORIGIN: ../../../flutter/impeller/core/texture_descriptor.cc + ../../../flutter/ ORIGIN: ../../../flutter/impeller/core/texture_descriptor.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/vertex_buffer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/core/vertex_buffer.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/display_list/dl_aiks_canvas.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/display_list/dl_aiks_canvas.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/display_list/dl_image_impeller.cc + ../../../flutter/LICENSE @@ -2249,6 +2243,8 @@ ORIGIN: ../../../flutter/shell/common/display.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/display.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/display_manager.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/display_manager.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/common/dl_op_spy.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/common/dl_op_spy.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/engine.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/engine.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/pipeline.cc + ../../../flutter/LICENSE @@ -3485,8 +3481,6 @@ FILE: ../../../flutter/display_list/dl_op_recorder.cc FILE: ../../../flutter/display_list/dl_op_recorder.h FILE: ../../../flutter/display_list/dl_op_records.cc FILE: ../../../flutter/display_list/dl_op_records.h -FILE: ../../../flutter/display_list/dl_op_spy.cc -FILE: ../../../flutter/display_list/dl_op_spy.h FILE: ../../../flutter/display_list/dl_paint.cc FILE: ../../../flutter/display_list/dl_paint.h FILE: ../../../flutter/display_list/dl_sampling_options.h @@ -3543,8 +3537,6 @@ FILE: ../../../flutter/flow/instrumentation.cc FILE: ../../../flutter/flow/instrumentation.h FILE: ../../../flutter/flow/layer_snapshot_store.cc FILE: ../../../flutter/flow/layer_snapshot_store.h -FILE: ../../../flutter/flow/layers/aiks_layer.cc -FILE: ../../../flutter/flow/layers/aiks_layer.h FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h FILE: ../../../flutter/flow/layers/cacheable_layer.cc @@ -3917,8 +3909,6 @@ FILE: ../../../flutter/impeller/core/texture_descriptor.cc FILE: ../../../flutter/impeller/core/texture_descriptor.h FILE: ../../../flutter/impeller/core/vertex_buffer.cc FILE: ../../../flutter/impeller/core/vertex_buffer.h -FILE: ../../../flutter/impeller/display_list/dl_aiks_canvas.cc -FILE: ../../../flutter/impeller/display_list/dl_aiks_canvas.h FILE: ../../../flutter/impeller/display_list/dl_dispatcher.cc FILE: ../../../flutter/impeller/display_list/dl_dispatcher.h FILE: ../../../flutter/impeller/display_list/dl_image_impeller.cc @@ -5004,6 +4994,8 @@ FILE: ../../../flutter/shell/common/display.cc FILE: ../../../flutter/shell/common/display.h FILE: ../../../flutter/shell/common/display_manager.cc FILE: ../../../flutter/shell/common/display_manager.h +FILE: ../../../flutter/shell/common/dl_op_spy.cc +FILE: ../../../flutter/shell/common/dl_op_spy.h FILE: ../../../flutter/shell/common/engine.cc FILE: ../../../flutter/shell/common/engine.h FILE: ../../../flutter/shell/common/pipeline.cc diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index cbe0ded7483a0..840f15ee946d8 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: b6d0d7fd2120e02aee1fa651f8bae9a0 +Signature: 2c4e89e154faa6701e9c20f1b300d13c ==================================================================================================== LIBRARY: etc1 @@ -1897,8 +1897,6 @@ ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.cpp + ../../../thi ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrSurface.cpp + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrSurface.h + ../../../third_party/skia/LICENSE -ORIGIN: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.cpp + ../../../third_party/skia/LICENSE -ORIGIN: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLProgramDataManager.cpp + ../../../third_party/skia/LICENSE @@ -2057,8 +2055,6 @@ FILE: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.h FILE: ../../../third_party/skia/src/gpu/ganesh/GrSurface.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/GrSurface.h -FILE: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.cpp -FILE: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.h FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.h FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLProgramDataManager.cpp diff --git a/display_list/BUILD.gn b/display_list/BUILD.gn index d4b21754a8fb0..b115f3d24d963 100644 --- a/display_list/BUILD.gn +++ b/display_list/BUILD.gn @@ -43,8 +43,6 @@ source_set("display_list") { "dl_op_recorder.h", "dl_op_records.cc", "dl_op_records.h", - "dl_op_spy.cc", - "dl_op_spy.h", "dl_paint.cc", "dl_paint.h", "dl_sampling_options.h", @@ -113,7 +111,6 @@ if (enable_unittests) { "benchmarking/dl_complexity_unittests.cc", "display_list_unittests.cc", "dl_color_unittests.cc", - "dl_op_spy_unittests.cc", "dl_paint_unittests.cc", "dl_vertices_unittests.cc", "effects/dl_color_filter_unittests.cc", diff --git a/display_list/display_list.cc b/display_list/display_list.cc index cee978dd56536..9879a1a41dde4 100644 --- a/display_list/display_list.cc +++ b/display_list/display_list.cc @@ -33,7 +33,7 @@ DisplayList::DisplayList(DlStorage&& storage, bool can_apply_group_opacity, bool is_ui_thread_safe, bool modifies_transparent_black, - std::shared_ptr rtree) + sk_sp rtree) : storage_(std::move(storage)), op_count_(op_count), nested_byte_count_(nested_byte_count), diff --git a/display_list/display_list.h b/display_list/display_list.h index b5fdc8c5c8a26..3655e539ec82e 100644 --- a/display_list/display_list.h +++ b/display_list/display_list.h @@ -234,7 +234,7 @@ class DisplayList : public SkRefCnt { const SkRect& bounds() const { return bounds_; } bool has_rtree() const { return rtree_ != nullptr; } - std::shared_ptr rtree() const { return rtree_; } + sk_sp rtree() const { return rtree_; } bool Equals(const DisplayList* other) const; bool Equals(const DisplayList& other) const { return Equals(&other); } @@ -300,7 +300,7 @@ class DisplayList : public SkRefCnt { bool can_apply_group_opacity, bool is_ui_thread_safe, bool modifies_transparent_black, - std::shared_ptr rtree); + sk_sp rtree); static uint32_t next_unique_id(); @@ -317,7 +317,7 @@ class DisplayList : public SkRefCnt { const bool is_ui_thread_safe_; const bool modifies_transparent_black_; - const std::shared_ptr rtree_; + const sk_sp rtree_; void Dispatch(DlOpReceiver& ctx, uint8_t* ptr, diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc index e9df415abb2dd..8d2665a51802f 100644 --- a/display_list/display_list_unittests.cc +++ b/display_list/display_list_unittests.cc @@ -1932,7 +1932,7 @@ TEST_F(DisplayListTest, FlatDrawPointsProducesBounds) { } } -static void test_rtree(const std::shared_ptr& rtree, +static void test_rtree(const sk_sp& rtree, const SkRect& query, std::vector expected_rects, const std::vector& expected_indices) { diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h index af2c5a7e732de..8fad40d23466f 100644 --- a/display_list/dl_canvas.h +++ b/display_list/dl_canvas.h @@ -18,10 +18,6 @@ #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkTextBlob.h" -namespace impeller { -struct Picture; -} // namespace impeller - namespace flutter { // The primary class used to express rendering operations in the @@ -63,12 +59,7 @@ class DlCanvas { const DlImageFilter* backdrop = nullptr) = 0; virtual void Restore() = 0; virtual int GetSaveCount() const = 0; - virtual void RestoreToCount(int restore_count) { - FML_DCHECK(restore_count <= GetSaveCount()); - while (restore_count < GetSaveCount() && GetSaveCount() > 1) { - Restore(); - } - } + virtual void RestoreToCount(int restore_count) = 0; virtual void Translate(SkScalar tx, SkScalar ty) = 0; virtual void Scale(SkScalar sx, SkScalar sy) = 0; @@ -208,9 +199,6 @@ class DlCanvas { const DlPaint* paint = nullptr) = 0; virtual void DrawDisplayList(const sk_sp display_list, SkScalar opacity = SK_Scalar1) = 0; - virtual void DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity = SK_Scalar1) = 0; virtual void DrawTextBlob(const sk_sp& blob, SkScalar x, SkScalar y, diff --git a/display_list/dl_canvas_to_receiver.cc b/display_list/dl_canvas_to_receiver.cc index aed34a62c189d..c1cdac1fe9b2e 100644 --- a/display_list/dl_canvas_to_receiver.cc +++ b/display_list/dl_canvas_to_receiver.cc @@ -811,12 +811,6 @@ void DlCanvasToReceiver::DrawDisplayList(const sk_sp display_list, : OpResult::kPreservesTransparency, display_list->can_apply_group_opacity()); } -void DlCanvasToReceiver::DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity) { - FML_LOG(ERROR) << "Cannot draw Impeller Picture in to a a display list."; - FML_DCHECK(false); -} void DlCanvasToReceiver::DrawTextBlob(const sk_sp& blob, SkScalar x, SkScalar y, diff --git a/display_list/dl_canvas_to_receiver.h b/display_list/dl_canvas_to_receiver.h index ea8acfaffad4c..fdd499cea993d 100644 --- a/display_list/dl_canvas_to_receiver.h +++ b/display_list/dl_canvas_to_receiver.h @@ -10,10 +10,6 @@ #include "flutter/display_list/dl_op_receiver.h" #include "flutter/fml/macros.h" -namespace impeller { -struct Picture; -} - namespace flutter { class DlCanvasReceiver : public DlOpReceiver { @@ -341,10 +337,6 @@ class DlCanvasToReceiver : public virtual DlCanvas, // void DrawDisplayList(const sk_sp display_list, SkScalar opacity = SK_Scalar1) override; // |DlCanvas| - void DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity = SK_Scalar1) override; - // |DlCanvas| void DrawTextBlob(const sk_sp& blob, SkScalar x, SkScalar y, diff --git a/display_list/geometry/dl_rtree.h b/display_list/geometry/dl_rtree.h index 31f22ee477104..f12486edcce76 100644 --- a/display_list/geometry/dl_rtree.h +++ b/display_list/geometry/dl_rtree.h @@ -25,7 +25,7 @@ namespace flutter { /// - Query for a set of non-overlapping rectangles that are joined /// from the original rectangles that intersect a query rect /// @see |searchAndConsolidateRects| -class DlRTree { +class DlRTree : public SkRefCnt { private: static constexpr int kMaxChildren = 11; diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc index 0c46912813b02..9299c9a6ff9d7 100644 --- a/display_list/skia/dl_sk_canvas.cc +++ b/display_list/skia/dl_sk_canvas.cc @@ -294,13 +294,6 @@ void DlSkCanvasAdapter::DrawAtlas(const sk_sp& atlas, ToSk(sampling), cullRect, sk_paint()); } -void DlSkCanvasAdapter::DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity) { - FML_LOG(ERROR) << "Cannot draw Impeller Picture in to a Skia canvas."; - FML_DCHECK(false); -} - void DlSkCanvasAdapter::DrawDisplayList(const sk_sp display_list, SkScalar opacity) { const int restore_count = delegate_->getSaveCount(); diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h index f253d0a918b10..af774b74342f0 100644 --- a/display_list/skia/dl_sk_canvas.h +++ b/display_list/skia/dl_sk_canvas.h @@ -136,9 +136,6 @@ class DlSkCanvasAdapter final : public virtual DlCanvas { DlImageSampling sampling, const SkRect* cullRect, const DlPaint* paint = nullptr) override; - void DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity = SK_Scalar1) override; void DrawDisplayList(const sk_sp display_list, SkScalar opacity = SK_Scalar1) override; void DrawTextBlob(const sk_sp& blob, diff --git a/display_list/utils/dl_bounds_accumulator.cc b/display_list/utils/dl_bounds_accumulator.cc index e609dc43baf4d..34750ed4bd529 100644 --- a/display_list/utils/dl_bounds_accumulator.cc +++ b/display_list/utils/dl_bounds_accumulator.cc @@ -125,11 +125,10 @@ SkRect RTreeBoundsAccumulator::bounds() const { return accumulator.bounds(); } -std::shared_ptr RTreeBoundsAccumulator::rtree() const { +sk_sp RTreeBoundsAccumulator::rtree() const { FML_DCHECK(saved_offsets_.empty()); - return std::make_shared(rects_.data(), rects_.size(), - rect_indices_.data(), - [](int id) { return id >= 0; }); + return sk_make_sp(rects_.data(), rects_.size(), rect_indices_.data(), + [](int id) { return id >= 0; }); } } // namespace flutter diff --git a/display_list/utils/dl_bounds_accumulator.h b/display_list/utils/dl_bounds_accumulator.h index e741f11277c7e..674f5e120c44a 100644 --- a/display_list/utils/dl_bounds_accumulator.h +++ b/display_list/utils/dl_bounds_accumulator.h @@ -87,7 +87,7 @@ class BoundsAccumulator { virtual SkRect bounds() const = 0; - virtual std::shared_ptr rtree() const = 0; + virtual sk_sp rtree() const = 0; }; class RectBoundsAccumulator final : public virtual BoundsAccumulator { @@ -111,7 +111,7 @@ class RectBoundsAccumulator final : public virtual BoundsAccumulator { Type type() const override { return Type::kRect; } - std::shared_ptr rtree() const override { return nullptr; } + sk_sp rtree() const override { return nullptr; } private: class AccumulationRect { @@ -150,7 +150,7 @@ class RTreeBoundsAccumulator final : public virtual BoundsAccumulator { SkRect bounds() const override; - std::shared_ptr rtree() const override; + sk_sp rtree() const override; Type type() const override { return Type::kRTree; } diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 0832fedad79c8..a394ea08d9406 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -22,8 +22,6 @@ source_set("flow") { "instrumentation.h", "layer_snapshot_store.cc", "layer_snapshot_store.h", - "layers/aiks_layer.cc", - "layers/aiks_layer.h", "layers/backdrop_filter_layer.cc", "layers/backdrop_filter_layer.h", "layers/cacheable_layer.cc", @@ -189,11 +187,6 @@ if (enable_unittests) { "//third_party/skia", ] - if (impeller_supports_rendering) { - sources += [ "layers/aiks_layer_unittests.cc" ] - deps += [ "//flutter/impeller" ] - } - if (!defined(defines)) { defines = [] } diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index 90ba06b73e9f5..086882b76adf4 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -3,45 +3,9 @@ // found in the LICENSE file. #include "flutter/flow/embedded_views.h" -#include "flutter/display_list/dl_op_spy.h" namespace flutter { -#if IMPELLER_SUPPORTS_RENDERING -ImpellerEmbedderViewSlice::ImpellerEmbedderViewSlice(SkRect view_bounds) { - canvas_ = std::make_unique( - /*bounds=*/view_bounds); -} - -DlCanvas* ImpellerEmbedderViewSlice::canvas() { - return canvas_ ? canvas_.get() : nullptr; -} - -void ImpellerEmbedderViewSlice::end_recording() { - picture_ = - std::make_shared(canvas_->EndRecordingAsPicture()); - canvas_.reset(); -} - -std::list ImpellerEmbedderViewSlice::searchNonOverlappingDrawnRects( - const SkRect& query) const { - FML_DCHECK(picture_); - return picture_->rtree->searchAndConsolidateRects(query); -} - -void ImpellerEmbedderViewSlice::render_into(DlCanvas* canvas) { - canvas->DrawImpellerPicture(picture_); -} - -bool ImpellerEmbedderViewSlice::recording_ended() { - return canvas_ == nullptr; -} - -bool ImpellerEmbedderViewSlice::renders_anything() { - return !picture_->rtree->bounds().isEmpty(); -} -#endif // IMPELLER_SUPPORTS_RENDERING - DisplayListEmbedderViewSlice::DisplayListEmbedderViewSlice(SkRect view_bounds) { builder_ = std::make_unique( /*bounds=*/view_bounds, @@ -66,6 +30,10 @@ void DisplayListEmbedderViewSlice::render_into(DlCanvas* canvas) { canvas->DrawDisplayList(display_list_); } +void DisplayListEmbedderViewSlice::dispatch(DlOpReceiver& receiver) { + display_list_->Dispatch(receiver); +} + bool DisplayListEmbedderViewSlice::is_empty() { return display_list_->bounds().isEmpty(); } @@ -74,12 +42,6 @@ bool DisplayListEmbedderViewSlice::recording_ended() { return builder_ == nullptr; } -bool DisplayListEmbedderViewSlice::renders_anything() { - DlOpSpy dl_op_spy; - display_list_->Dispatch(dl_op_spy); - return dl_op_spy.did_draw() && !is_empty(); -} - void ExternalViewEmbedder::SubmitFrame( GrDirectContext* context, const std::shared_ptr& aiks_context, diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 9e0f2291743e7..d6292f13ec034 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -340,33 +340,11 @@ class EmbedderViewSlice { virtual std::list searchNonOverlappingDrawnRects( const SkRect& query) const = 0; virtual void render_into(DlCanvas* canvas) = 0; - virtual bool recording_ended() = 0; - virtual bool renders_anything() = 0; }; -#if IMPELLER_SUPPORTS_RENDERING -class ImpellerEmbedderViewSlice : public EmbedderViewSlice { - public: - explicit ImpellerEmbedderViewSlice(SkRect view_bounds); - ~ImpellerEmbedderViewSlice() override = default; - - DlCanvas* canvas() override; - void end_recording() override; - std::list searchNonOverlappingDrawnRects( - const SkRect& query) const override; - void render_into(DlCanvas* canvas) override; - bool recording_ended() override; - bool renders_anything() override; - - private: - std::unique_ptr canvas_; - std::shared_ptr picture_; -}; -#endif - class DisplayListEmbedderViewSlice : public EmbedderViewSlice { public: - explicit DisplayListEmbedderViewSlice(SkRect view_bounds); + DisplayListEmbedderViewSlice(SkRect view_bounds); ~DisplayListEmbedderViewSlice() override = default; DlCanvas* canvas() override; @@ -374,9 +352,9 @@ class DisplayListEmbedderViewSlice : public EmbedderViewSlice { std::list searchNonOverlappingDrawnRects( const SkRect& query) const override; void render_into(DlCanvas* canvas) override; + void dispatch(DlOpReceiver& receiver); bool is_empty(); - bool recording_ended() override; - bool renders_anything() override; + bool recording_ended(); private: std::unique_ptr builder_; diff --git a/flow/layers/aiks_layer.cc b/flow/layers/aiks_layer.cc deleted file mode 100644 index 27fa2855c42a1..0000000000000 --- a/flow/layers/aiks_layer.cc +++ /dev/null @@ -1,67 +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 "flutter/flow/layers/aiks_layer.h" - -#include - -namespace flutter { - -AiksLayer::AiksLayer(const SkPoint& offset, - const std::shared_ptr& picture) - : offset_(offset), picture_(picture) { -#if IMPELLER_SUPPORTS_RENDERING - if (picture_) { - auto bounds = picture_->pass->GetElementsCoverage(std::nullopt) - .value_or(impeller::Rect()) - .Shift({offset_.x(), offset_.y()}); - bounds_ = SkRect::MakeLTRB(bounds.GetLeft(), bounds.GetTop(), - bounds.GetRight(), bounds.GetBottom()); - } -#endif -} - -bool AiksLayer::IsReplacing(DiffContext* context, const Layer* layer) const { - auto old_layer = layer->as_aiks_layer(); - return old_layer != nullptr && offset_ == old_layer->offset_ && - old_layer->picture_ == picture_; -} - -void AiksLayer::Diff(DiffContext* context, const Layer* old_layer) { - DiffContext::AutoSubtreeRestore subtree(context); - context->PushTransform(SkMatrix::Translate(offset_.x(), offset_.y())); - context->AddLayerBounds(bounds_); - context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion()); -} - -void AiksLayer::Preroll(PrerollContext* frame) { - // There is no opacity peepholing to do here because Impeller handles that - // in the Entities, and this layer will never participate in raster caching. - FML_DCHECK(!frame->raster_cache); - set_paint_bounds(bounds_); -} - -void AiksLayer::Paint(PaintContext& context) const { - FML_DCHECK(needs_painting(context)); - - auto mutator = context.state_stack.save(); - mutator.translate(offset_.x(), offset_.y()); - - FML_DCHECK(!context.raster_cache); - - SkScalar opacity = context.state_stack.outstanding_opacity(); - - if (context.enable_leaf_layer_tracing) { - // TODO(dnfield): Decide if we need to capture this for Impeller. - // We can't do this the same way as on the Skia backend, because Impeller - // does not expose primitives for flushing things down to the GPU without - // also allocating a texture. - // https://github.com/flutter/flutter/issues/131941 - FML_LOG(ERROR) << "Leaf layer tracing unsupported for Impeller."; - } - - context.canvas->DrawImpellerPicture(picture_, opacity); -} - -} // namespace flutter diff --git a/flow/layers/aiks_layer.h b/flow/layers/aiks_layer.h deleted file mode 100644 index eda42fc5e63cd..0000000000000 --- a/flow/layers/aiks_layer.h +++ /dev/null @@ -1,44 +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. - -#pragma once - -#include - -#include "flutter/flow/layers/layer.h" - -#if IMPELLER_SUPPORTS_RENDERING -#include "impeller/aiks/picture.h" // nogncheck -#else // IMPELLER_SUPPORTS_RENDERING -namespace impeller { -struct Picture; -} // namespace impeller -#endif // !IMPELLER_SUPPORTS_RENDERING - -namespace flutter { - -class AiksLayer : public Layer { - public: - AiksLayer(const SkPoint& offset, - const std::shared_ptr& picture); - - const AiksLayer* as_aiks_layer() const override { return this; } - - bool IsReplacing(DiffContext* context, const Layer* layer) const override; - - void Diff(DiffContext* context, const Layer* old_layer) override; - - void Preroll(PrerollContext* frame) override; - - void Paint(PaintContext& context) const override; - - private: - SkPoint offset_; - SkRect bounds_; - std::shared_ptr picture_; - - FML_DISALLOW_COPY_AND_ASSIGN(AiksLayer); -}; - -} // namespace flutter diff --git a/flow/layers/aiks_layer_unittests.cc b/flow/layers/aiks_layer_unittests.cc deleted file mode 100644 index 10b56073773de..0000000000000 --- a/flow/layers/aiks_layer_unittests.cc +++ /dev/null @@ -1,49 +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. - -#define FML_USED_ON_EMBEDDER - -#include "flow/layers/layer.h" -#include "flutter/flow/layers/aiks_layer.h" -#include "flutter/flow/layers/layer_tree.h" -#include "flutter/flow/testing/layer_test.h" -#include "impeller/aiks/canvas.h" - -namespace flutter { -namespace testing { - -using AiksLayerTest = LayerTest; - -TEST_F(AiksLayerTest, InfiniteBounds) { - impeller::Canvas canvas; - canvas.DrawPaint(impeller::Paint{.color = impeller::Color::Red()}); - auto picture = - std::make_shared(canvas.EndRecordingAsPicture()); - AiksLayer layer(SkPoint::Make(0.0f, 0.0f), picture); - - const FixedRefreshRateStopwatch unused_stopwatch; - LayerStateStack state_stack; - state_stack.set_preroll_delegate(kGiantRect, SkMatrix::I()); - PrerollContext preroll_context{ - .state_stack = state_stack, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = nullptr, - }; - PaintContext context{ - // clang-format off - .state_stack = state_stack, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = nullptr, - // clang-format on - }; - - EXPECT_FALSE(layer.needs_painting(context)); - layer.Preroll(&preroll_context); - EXPECT_TRUE(layer.needs_painting(context)); -} - -} // namespace testing -} // namespace flutter diff --git a/flow/layers/layer.h b/flow/layers/layer.h index da8bddcb23e99..eaae9d4279a23 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -41,7 +41,6 @@ class MockLayer; } // namespace testing class ContainerLayer; -class AiksLayer; class DisplayListLayer; class PerformanceOverlayLayer; class TextureLayer; @@ -256,7 +255,6 @@ class Layer { return RasterCacheKeyID(unique_id_, RasterCacheKeyType::kLayer); } virtual const ContainerLayer* as_container_layer() const { return nullptr; } - virtual const AiksLayer* as_aiks_layer() const { return nullptr; } virtual const DisplayListLayer* as_display_list_layer() const { return nullptr; } diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 68ca2bdc6091d..e8aea74efd78b 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -155,69 +155,6 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, } } -std::shared_ptr LayerTree::FlattenToImpellerPicture( - const SkRect& bounds, - const std::shared_ptr& texture_registry) { -#if IMPELLER_SUPPORTS_RENDERING - TRACE_EVENT0("flutter", "LayerTree::FlattenToImpellerPicture"); - - impeller::DlAiksCanvas canvas(bounds); - - const FixedRefreshRateStopwatch unused_stopwatch; - - LayerStateStack preroll_state_stack; - // No root surface transformation. So assume identity. - preroll_state_stack.set_preroll_delegate(bounds); - PrerollContext preroll_context{ - // clang-format off - .raster_cache = nullptr, - .gr_context = nullptr, - .view_embedder = nullptr, - .state_stack = preroll_state_stack, - .dst_color_space = nullptr, - .surface_needs_readback = false, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = texture_registry, - // clang-format on - }; - - LayerStateStack paint_state_stack; - paint_state_stack.set_delegate(&canvas); - PaintContext paint_context = { - // clang-format off - .state_stack = paint_state_stack, - .canvas = &canvas, - .gr_context = nullptr, - .dst_color_space = nullptr, - .view_embedder = nullptr, - .raster_time = unused_stopwatch, - .ui_time = unused_stopwatch, - .texture_registry = texture_registry, - .raster_cache = nullptr, - .layer_snapshot_store = nullptr, - .enable_leaf_layer_tracing = false, - // clang-format on - }; - - // Even if we don't have a root layer, we still need to create an empty - // picture. - if (root_layer_) { - root_layer_->Preroll(&preroll_context); - - // The needs painting flag may be set after the preroll. So check it after. - if (root_layer_->needs_painting(paint_context)) { - root_layer_->Paint(paint_context); - } - } - - return std::make_shared( - canvas.EndRecordingAsPicture()); -#else // IMPELLER_SUPPORTS_RENDERING - return nullptr; -#endif // !IMPELLER_SUPPORTS_RENDERING -} - sk_sp LayerTree::Flatten( const SkRect& bounds, const std::shared_ptr& texture_registry, diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index c4f204afae117..5f573da2099a0 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -54,10 +54,6 @@ class LayerTree { const std::shared_ptr& texture_registry = nullptr, GrDirectContext* gr_context = nullptr); - std::shared_ptr FlattenToImpellerPicture( - const SkRect& bounds, - const std::shared_ptr& texture_registry); - Layer* root_layer() const { return root_layer_.get(); } const SkISize& frame_size() const { return frame_size_; } diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index 9932ac5f966b4..92f22f8123cfc 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -27,7 +27,7 @@ namespace flutter { RasterCacheResult::RasterCacheResult(sk_sp image, const SkRect& logical_rect, const char* type, - std::shared_ptr rtree) + sk_sp rtree) : image_(std::move(image)), logical_rect_(logical_rect), flow_(type), @@ -77,7 +77,7 @@ RasterCache::RasterCache(size_t access_threshold, /// @note Procedure doesn't copy all closures. std::unique_ptr RasterCache::Rasterize( const RasterCache::Context& context, - std::shared_ptr rtree, + sk_sp rtree, const std::function& draw_function, const std::function& draw_checkerboard) const { @@ -119,7 +119,7 @@ bool RasterCache::UpdateCacheEntry( const RasterCacheKeyID& id, const Context& raster_cache_context, const std::function& render_function, - std::shared_ptr rtree) const { + sk_sp rtree) const { RasterCacheKey key = RasterCacheKey(id, raster_cache_context.matrix); Entry& entry = cache_[key]; if (!entry.image) { diff --git a/flow/raster_cache.h b/flow/raster_cache.h index acda6269f15e6..a00508f84d0af 100644 --- a/flow/raster_cache.h +++ b/flow/raster_cache.h @@ -29,7 +29,7 @@ class RasterCacheResult { RasterCacheResult(sk_sp image, const SkRect& logical_rect, const char* type, - std::shared_ptr rtree = nullptr); + sk_sp rtree = nullptr); virtual ~RasterCacheResult() = default; @@ -49,7 +49,7 @@ class RasterCacheResult { sk_sp image_; SkRect logical_rect_; fml::tracing::TraceFlow flow_; - std::shared_ptr rtree_; + sk_sp rtree_; }; class Layer; @@ -129,7 +129,7 @@ class RasterCache { std::unique_ptr Rasterize( const RasterCache::Context& context, - std::shared_ptr rtree, + sk_sp rtree, const std::function& draw_function, const std::function& draw_checkerboard) const; @@ -244,7 +244,7 @@ class RasterCache { bool UpdateCacheEntry(const RasterCacheKeyID& id, const Context& raster_cache_context, const std::function& render_function, - std::shared_ptr rtree = nullptr) const; + sk_sp rtree = nullptr) const; private: struct Entry { diff --git a/flow/surface_frame.cc b/flow/surface_frame.cc index 874152571a119..dd1b98d33b8b2 100644 --- a/flow/surface_frame.cc +++ b/flow/surface_frame.cc @@ -5,7 +5,6 @@ #include "flutter/flow/surface_frame.h" #include -#include #include #include "flutter/fml/logging.h" @@ -32,13 +31,9 @@ SurfaceFrame::SurfaceFrame(sk_sp surface, canvas_ = &adapter_; } else if (display_list_fallback) { FML_DCHECK(!frame_size.isEmpty()); -#if IMPELLER_SUPPORTS_RENDERING - aiks_canvas_ = - std::make_shared(SkRect::Make(frame_size)); - canvas_ = aiks_canvas_.get(); -#else - FML_DCHECK(false); -#endif // IMPELLER_SUPPORTS_RENDERING + dl_builder_ = + sk_make_sp(SkRect::Make(frame_size), true); + canvas_ = dl_builder_.get(); } } @@ -77,14 +72,9 @@ bool SurfaceFrame::PerformSubmit() { return false; } -std::shared_ptr SurfaceFrame::GetImpellerPicture() { -#if IMPELLER_SUPPORTS_RENDERING - return std::make_shared( - aiks_canvas_->EndRecordingAsPicture()); -#else - FML_DCHECK(false); - return nullptr; -#endif // IMPELLER_SUPPORTS_RENDERING +sk_sp SurfaceFrame::BuildDisplayList() { + TRACE_EVENT0("impeller", "SurfaceFrame::BuildDisplayList"); + return dl_builder_ ? dl_builder_->Build() : nullptr; } } // namespace flutter diff --git a/flow/surface_frame.h b/flow/surface_frame.h index c1187588465eb..a3d6d1e523efa 100644 --- a/flow/surface_frame.h +++ b/flow/surface_frame.h @@ -14,14 +14,6 @@ #include "flutter/fml/macros.h" #include "flutter/fml/time/time_point.h" -#if IMPELLER_SUPPORTS_RENDERING -#include "impeller/display_list/dl_aiks_canvas.h" // nogncheck -#else // IMPELLER_SUPPORTS_RENDERINGÆ’ -namespace impeller { -class DlAiksCanvas; -} // namespace impeller -#endif // !IMPELLER_SUPPORTS_RENDERING - #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" @@ -105,14 +97,14 @@ class SurfaceFrame { } const SubmitInfo& submit_info() const { return submit_info_; } - std::shared_ptr GetImpellerPicture(); + sk_sp BuildDisplayList(); private: bool submitted_ = false; DlSkCanvasAdapter adapter_; + sk_sp dl_builder_; sk_sp surface_; - std::shared_ptr aiks_canvas_; DlCanvas* canvas_ = nullptr; FramebufferInfo framebuffer_info_; SubmitInfo submit_info_; diff --git a/flow/surface_frame_unittests.cc b/flow/surface_frame_unittests.cc index 540981bfaf8f9..0f6f9ba3081fc 100644 --- a/flow/surface_frame_unittests.cc +++ b/flow/surface_frame_unittests.cc @@ -22,7 +22,6 @@ TEST(FlowTest, SurfaceFrameDoesNotSubmitInDtor) { surface_frame.reset(); } -#if IMPELLER_SUPPORTS_RENDERING TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) { SurfaceFrame::FramebufferInfo framebuffer_info; SurfaceFrame frame( @@ -34,6 +33,5 @@ TEST(FlowTest, SurfaceFrameDoesNotHaveEmptyCanvas) { EXPECT_FALSE(frame.Canvas()->GetLocalClipBounds().isEmpty()); EXPECT_FALSE(frame.Canvas()->QuickReject(SkRect::MakeLTRB(10, 10, 50, 50))); } -#endif // IMPELLER_SUPPORTS_RENDERING } // namespace flutter diff --git a/impeller/aiks/BUILD.gn b/impeller/aiks/BUILD.gn index 2f63caa31faf5..5761cab4a7c1a 100644 --- a/impeller/aiks/BUILD.gn +++ b/impeller/aiks/BUILD.gn @@ -30,7 +30,6 @@ impeller_component("aiks") { "../base", "../entity", "../geometry", - "//flutter/display_list", ] deps = [ "//flutter/fml" ] diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 822b1073f8023..99d03ed5779e9 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -8,7 +8,6 @@ #include #include -#include "display_list/geometry/dl_rtree.h" #include "flutter/fml/logging.h" #include "impeller/aiks/paint_pass_delegate.h" #include "impeller/entity/contents/atlas_contents.h" @@ -20,7 +19,6 @@ #include "impeller/entity/contents/vertices_contents.h" #include "impeller/entity/geometry/geometry.h" #include "impeller/geometry/path_builder.h" -#include "include/core/SkRect.h" namespace impeller { @@ -405,7 +403,7 @@ void Canvas::RestoreClip() { GetCurrentPass().AddEntity(entity); } -void Canvas::DrawPoints(const std::vector& points, +void Canvas::DrawPoints(std::vector points, Scalar radius, const Paint& paint, PointStyle point_style) { @@ -418,7 +416,7 @@ void Canvas::DrawPoints(const std::vector& points, entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); entity.SetContents(paint.WithFilters(paint.CreateContentsForGeometry( - Geometry::MakePointField(points, radius, + Geometry::MakePointField(std::move(points), radius, /*round=*/point_style == PointStyle::kRound)))); GetCurrentPass().AddEntity(entity); @@ -504,19 +502,6 @@ Picture Canvas::EndRecordingAsPicture() { Picture picture; picture.pass = std::move(base_pass_); - std::vector rects; - picture.pass->IterateAllEntities([&rects](const Entity& entity) { - auto coverage = entity.GetCoverage(); - if (coverage.has_value()) { - rects.push_back(SkRect::MakeLTRB(coverage->GetLeft(), coverage->GetTop(), - coverage->GetRight(), - coverage->GetBottom())); - } - return true; - }); - picture.rtree = - std::make_shared(rects.data(), rects.size()); - Reset(); Initialize(initial_cull_rect_); diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 0d31d02d34363..84f1c486bc30f 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -64,8 +64,6 @@ class Canvas { ~Canvas(); - std::optional BaseCullRect() const { return initial_cull_rect_; } - void Save(); void SaveLayer(const Paint& paint, @@ -110,7 +108,7 @@ class Canvas { void DrawCircle(Point center, Scalar radius, const Paint& paint); - void DrawPoints(const std::vector&, + void DrawPoints(std::vector, Scalar radius, const Paint& paint, PointStyle point_style); diff --git a/impeller/aiks/picture.h b/impeller/aiks/picture.h index bb769000a10ae..f4e8a640efa9a 100644 --- a/impeller/aiks/picture.h +++ b/impeller/aiks/picture.h @@ -8,7 +8,6 @@ #include #include -#include "display_list/geometry/dl_rtree.h" #include "flutter/fml/macros.h" #include "impeller/aiks/aiks_context.h" #include "impeller/aiks/image.h" @@ -19,7 +18,6 @@ namespace impeller { struct Picture { std::unique_ptr pass; - std::shared_ptr rtree; std::optional Snapshot(AiksContext& context); diff --git a/impeller/display_list/BUILD.gn b/impeller/display_list/BUILD.gn index 0f7e5c42f3cf4..24a1980f59aac 100644 --- a/impeller/display_list/BUILD.gn +++ b/impeller/display_list/BUILD.gn @@ -22,8 +22,6 @@ impeller_component("skia_conversions") { impeller_component("display_list") { sources = [ - "dl_aiks_canvas.cc", - "dl_aiks_canvas.h", "dl_dispatcher.cc", "dl_dispatcher.h", "dl_image_impeller.cc", diff --git a/impeller/display_list/dl_aiks_canvas.cc b/impeller/display_list/dl_aiks_canvas.cc deleted file mode 100644 index d916a5eb28ba8..0000000000000 --- a/impeller/display_list/dl_aiks_canvas.cc +++ /dev/null @@ -1,1203 +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/dl_aiks_canvas.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "display_list/dl_paint.h" -#include "flutter/fml/logging.h" -#include "flutter/fml/trace_event.h" -#include "impeller/aiks/color_filter.h" -#include "impeller/core/formats.h" -#include "impeller/display_list/dl_image_impeller.h" -#include "impeller/display_list/dl_vertices_geometry.h" -#include "impeller/display_list/nine_patch_converter.h" -#include "impeller/display_list/skia_conversions.h" -#include "impeller/entity/contents/conical_gradient_contents.h" -#include "impeller/entity/contents/filters/filter_contents.h" -#include "impeller/entity/contents/filters/inputs/filter_input.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/sweep_gradient_contents.h" -#include "impeller/entity/contents/tiled_texture_contents.h" -#include "impeller/entity/entity.h" -#include "impeller/entity/geometry/geometry.h" -#include "impeller/geometry/path.h" -#include "impeller/geometry/path_builder.h" -#include "impeller/geometry/scalar.h" -#include "impeller/geometry/sigma.h" -#include "impeller/typographer/backends/skia/text_frame_skia.h" - -#if IMPELLER_ENABLE_3D -#include "impeller/entity/contents/scene_contents.h" // nogncheck -#endif // IMPELLER_ENABLE_3D - -namespace impeller { - -#define UNIMPLEMENTED \ - FML_DLOG(ERROR) << "Unimplemented detail in " << __FUNCTION__; - -DlAiksCanvas::DlAiksCanvas(const SkRect& cull_rect, bool prepare_rtree) - : canvas_(skia_conversions::ToRect(cull_rect)) { - if (prepare_rtree) { - accumulator_ = std::make_unique(); - } -} - -DlAiksCanvas::DlAiksCanvas(const SkIRect& cull_rect, bool prepare_rtree) - : DlAiksCanvas(SkRect::Make(cull_rect), prepare_rtree) {} - -DlAiksCanvas::~DlAiksCanvas() = default; - -static Paint::Style ToStyle(flutter::DlDrawStyle style) { - switch (style) { - case flutter::DlDrawStyle::kFill: - return Paint::Style::kFill; - case flutter::DlDrawStyle::kStroke: - return Paint::Style::kStroke; - case flutter::DlDrawStyle::kStrokeAndFill: - UNIMPLEMENTED; - break; - } - return Paint::Style::kFill; -} - -static Cap ToStrokeCap(flutter::DlStrokeCap cap) { - switch (cap) { - case flutter::DlStrokeCap::kButt: - return Cap::kButt; - case flutter::DlStrokeCap::kRound: - return Cap::kRound; - case flutter::DlStrokeCap::kSquare: - return Cap::kSquare; - } - FML_UNREACHABLE(); -} - -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 - }; -} - -static Matrix ToMatrix(const SkM44& m) { - return Matrix{ - // clang-format off - m.rc(0, 0), m.rc(1, 0), m.rc(2, 0), m.rc(3, 0), - m.rc(0, 1), m.rc(1, 1), m.rc(2, 1), m.rc(3, 1), - m.rc(0, 2), m.rc(1, 2), m.rc(2, 2), m.rc(3, 2), - m.rc(0, 3), m.rc(1, 3), m.rc(2, 3), m.rc(3, 3), - // clang-format on - }; -} - -static Join ToStrokeJoin(flutter::DlStrokeJoin join) { - switch (join) { - case flutter::DlStrokeJoin::kMiter: - return Join::kMiter; - case flutter::DlStrokeJoin::kRound: - return Join::kRound; - case flutter::DlStrokeJoin::kBevel: - return Join::kBevel; - } - FML_UNREACHABLE(); -} - -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.label = "Nearest Sampler"; - break; - case flutter::DlImageSampling::kLinear: - // Impeller doesn't support cubic sampling, but linear is closer to correct - // than nearest for this case. - case flutter::DlImageSampling::kCubic: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; - desc.label = "Linear Sampler"; - break; - 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; - switch (options) { - case flutter::DlFilterMode::kNearest: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kNearest; - desc.label = "Nearest Sampler"; - break; - case flutter::DlFilterMode::kLinear: - desc.min_filter = desc.mag_filter = impeller::MinMagFilter::kLinear; - desc.label = "Linear Sampler"; - break; - default: - break; - } - return desc; -} - -static FilterContents::BlurStyle ToBlurStyle(flutter::DlBlurStyle blur_style) { - switch (blur_style) { - case flutter::DlBlurStyle::kNormal: - return FilterContents::BlurStyle::kNormal; - case flutter::DlBlurStyle::kSolid: - return FilterContents::BlurStyle::kSolid; - case flutter::DlBlurStyle::kOuter: - return FilterContents::BlurStyle::kOuter; - case flutter::DlBlurStyle::kInner: - return FilterContents::BlurStyle::kInner; - } -} - -static std::optional ToMaskBlurDescriptor( - const flutter::DlMaskFilter* filter) { - if (filter == nullptr) { - return std::nullopt; - } - switch (filter->type()) { - case flutter::DlMaskFilterType::kBlur: { - auto blur = filter->asBlur(); - - return Paint::MaskBlurDescriptor{ - .style = ToBlurStyle(blur->style()), - .sigma = Sigma(blur->sigma()), - }; - } - } - - return std::nullopt; -} - -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 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 Color ToColor(const flutter::DlColor& color) { - return { - color.getRedF(), - color.getGreenF(), - color.getBlueF(), - color.getAlphaF(), - }; -} - -static std::vector ToColors(const flutter::DlColor colors[], int count) { - auto result = std::vector(); - if (colors == nullptr) { - return result; - } - for (int i = 0; i < count; i++) { - result.push_back(skia_conversions::ToColor(colors[i])); - } - return result; -} - -// Convert display list colors + stops into impeller colors and stops, taking -// care to ensure that the stops always start with 0.0 and end with 1.0. -template -static void ConvertStops(T* gradient, - std::vector* colors, - std::vector* stops) { - FML_DCHECK(gradient->stop_count() >= 2); - - auto* dl_colors = gradient->colors(); - auto* dl_stops = gradient->stops(); - if (dl_stops[0] != 0.0) { - colors->emplace_back(skia_conversions::ToColor(dl_colors[0])); - stops->emplace_back(0); - } - for (auto i = 0; i < gradient->stop_count(); i++) { - colors->emplace_back(skia_conversions::ToColor(dl_colors[i])); - stops->emplace_back(dl_stops[i]); - } - if (stops->back() != 1.0) { - colors->emplace_back(colors->back()); - stops->emplace_back(1.0); - } -} - -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; -#ifdef IMPELLER_ENABLE_3D - case flutter::DlColorSourceType::kScene: - return ColorSource::Type::kScene; -#endif // IMPELLER_ENABLE_3D - } -} - -ColorSource ToColorSource(const flutter::DlColorSource* source, Paint* paint) { - if (!source) { - return ColorSource::MakeColor(); - } - - std::optional type = ToColorSourceType(source->type()); - - if (!type.has_value()) { - FML_LOG(ERROR) << "Requested ColorSourceType::kUnknown"; - return ColorSource::MakeColor(); - } - - switch (type.value()) { - case ColorSource::Type::kColor: { - const flutter::DlColorColorSource* color = source->asColor(); - FML_DCHECK(color); - FML_DCHECK(paint); - paint->color = ToColor(color->color()); - return ColorSource::MakeColor(); - } - 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; - ConvertStops(linear, &colors, &stops); - - auto tile_mode = ToTileMode(linear->tile_mode()); - auto matrix = ToMatrix(linear->matrix()); - - return ColorSource::MakeLinearGradient( - start_point, end_point, std::move(colors), std::move(stops), - tile_mode, matrix); - } - case ColorSource::Type::kConicalGradient: { - const flutter::DlConicalGradientColorSource* conical_gradient = - source->asConicalGradient(); - FML_DCHECK(conical_gradient); - Point center = skia_conversions::ToPoint(conical_gradient->end_center()); - SkScalar radius = conical_gradient->end_radius(); - Point focus_center = - skia_conversions::ToPoint(conical_gradient->start_center()); - SkScalar focus_radius = conical_gradient->start_radius(); - std::vector colors; - std::vector stops; - ConvertStops(conical_gradient, &colors, &stops); - - auto tile_mode = ToTileMode(conical_gradient->tile_mode()); - auto matrix = ToMatrix(conical_gradient->matrix()); - - return ColorSource::MakeConicalGradient(center, radius, std::move(colors), - std::move(stops), focus_center, - focus_radius, tile_mode, matrix); - } - 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; - ConvertStops(radialGradient, &colors, &stops); - - auto tile_mode = ToTileMode(radialGradient->tile_mode()); - auto matrix = ToMatrix(radialGradient->matrix()); - return ColorSource::MakeRadialGradient(center, radius, std::move(colors), - std::move(stops), tile_mode, - matrix); - } - 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; - ConvertStops(sweepGradient, &colors, &stops); - - auto tile_mode = ToTileMode(sweepGradient->tile_mode()); - auto matrix = ToMatrix(sweepGradient->matrix()); - return ColorSource::MakeSweepGradient(center, start_angle, end_angle, - std::move(colors), std::move(stops), - tile_mode, matrix); - } - 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()); - return ColorSource::MakeImage(texture, x_tile_mode, y_tile_mode, desc, - matrix); - } - 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 ColorSource::MakeColor(); - } - auto* image = sampler->asImage(); - if (!sampler->asImage()) { - UNIMPLEMENTED; - return ColorSource::MakeColor(); - } - FML_DCHECK(image->image()->impeller_texture()); - texture_inputs.push_back({ - .sampler_descriptor = ToSamplerDescriptor(image->sampling()), - .texture = image->image()->impeller_texture(), - }); - } - - return ColorSource::MakeRuntimeEffect(runtime_stage, uniform_data, - texture_inputs); - } - case ColorSource::Type::kScene: { -#ifdef IMPELLER_ENABLE_3D - const flutter::DlSceneColorSource* scene_color_source = source->asScene(); - std::shared_ptr scene_node = - scene_color_source->scene_node(); - Matrix camera_transform = scene_color_source->camera_matrix(); - - return ColorSource::MakeScene(scene_node, camera_transform); -#else // IMPELLER_ENABLE_3D - FML_LOG(ERROR) << "ColorSourceType::kScene can only be used if Impeller " - "Scene is enabled."; - return ColorSource::MakeColor(); -#endif // IMPELLER_ENABLE_3D - } - } -} - -static std::shared_ptr 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; -} - -static Paint::ImageFilterProc ToImageFilterProc( - 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 = ToTileMode(blur->tile_mode()); - - return [sigma_x, sigma_y, tile_mode](const FilterInput::Ref& input, - const Matrix& effect_transform, - bool is_subpass) { - return FilterContents::MakeGaussianBlur( - input, sigma_x, sigma_y, FilterContents::BlurStyle::kNormal, - tile_mode, effect_transform); - }; - } - 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 [radius_x, radius_y](FilterInput::Ref input, - const Matrix& effect_transform, - bool is_subpass) { - return FilterContents::MakeMorphology( - std::move(input), radius_x, radius_y, - FilterContents::MorphType::kDilate, effect_transform); - }; - } - 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 [radius_x, radius_y](FilterInput::Ref input, - const Matrix& effect_transform, - bool is_subpass) { - return FilterContents::MakeMorphology( - std::move(input), radius_x, radius_y, - FilterContents::MorphType::kErode, effect_transform); - }; - } - 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()); - return [matrix, desc](FilterInput::Ref input, - const Matrix& effect_transform, bool is_subpass) { - return FilterContents::MakeMatrixFilter(std::move(input), matrix, desc, - effect_transform, is_subpass); - }; - } - case flutter::DlImageFilterType::kCompose: { - auto compose = filter->asCompose(); - FML_DCHECK(compose); - auto outer = compose->outer(); - auto inner = compose->inner(); - auto outer_proc = ToImageFilterProc(outer.get()); - auto inner_proc = ToImageFilterProc(inner.get()); - if (!outer_proc) { - return inner_proc; - } - if (!inner_proc) { - return outer_proc; - } - FML_DCHECK(outer_proc && inner_proc); - return [outer_filter = outer_proc, inner_filter = inner_proc]( - FilterInput::Ref input, const Matrix& effect_transform, - bool is_subpass) { - auto contents = - inner_filter(std::move(input), effect_transform, is_subpass); - contents = outer_filter(FilterInput::Make(contents), effect_transform, - is_subpass); - return contents; - }; - } - 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; - } - return [color_filter](FilterInput::Ref input, - const Matrix& effect_transform, bool is_subpass) { - // 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 color_filter->WrapWithGPUColorFilter(std::move(input), false); - }; - } - 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_proc = ToImageFilterProc(internal_filter.get()); - if (!image_filter_proc) { - return nullptr; - } - - auto matrix = ToMatrix(local_matrix_filter->matrix()); - - return [matrix, filter_proc = image_filter_proc]( - FilterInput::Ref input, const Matrix& effect_transform, - bool is_subpass) { - std::shared_ptr filter = - filter_proc(std::move(input), effect_transform, is_subpass); - return FilterContents::MakeLocalMatrixFilter(FilterInput::Make(filter), - matrix); - }; - } - } -} - -static Paint ToPaint(const flutter::DlPaint& dl_paint) { - Paint paint; - paint.style = ToStyle(dl_paint.getDrawStyle()); - paint.color = ToColor(dl_paint.getColor()); - paint.stroke_width = dl_paint.getStrokeWidth(); - paint.stroke_miter = dl_paint.getStrokeMiter(); - paint.stroke_cap = ToStrokeCap(dl_paint.getStrokeCap()); - paint.stroke_join = ToStrokeJoin(dl_paint.getStrokeJoin()); - paint.color_source = ToColorSource(dl_paint.getColorSourcePtr(), &paint); - paint.color_filter = ToColorFilter(dl_paint.getColorFilterPtr()); - paint.invert_colors = dl_paint.isInvertColors(); - paint.blend_mode = ToBlendMode(dl_paint.getBlendMode()); - if (dl_paint.getPathEffect()) { - UNIMPLEMENTED; - } - paint.mask_blur_descriptor = - ToMaskBlurDescriptor(dl_paint.getMaskFilterPtr()); - paint.image_filter = ToImageFilterProc(dl_paint.getImageFilterPtr()); - return paint; -} - -static Paint ToPaint(const flutter::DlPaint* dl_paint) { - if (!dl_paint) { - return Paint(); - } - return ToPaint(*dl_paint); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Save() { - canvas_.Save(); - if (accumulator_) { - accumulator_->save(); - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::SaveLayer(const SkRect* bounds, - const flutter::DlPaint* paint, - const flutter::DlImageFilter* backdrop) { - Paint impeller_paint = paint ? ToPaint(paint) : Paint(); - std::optional impeller_bounds = - bounds ? skia_conversions::ToRect(bounds) : std::nullopt; - Paint::ImageFilterProc proc = - backdrop ? ToImageFilterProc(backdrop) : nullptr; - - canvas_.SaveLayer(impeller_paint, impeller_bounds, proc); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Restore() { - canvas_.Restore(); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Translate(SkScalar tx, SkScalar ty) { - canvas_.Translate({tx, ty, 0.0}); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Scale(SkScalar sx, SkScalar sy) { - canvas_.Scale({sx, sy, 1.0}); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Rotate(SkScalar degrees) { - canvas_.Rotate(Degrees{degrees}); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Skew(SkScalar sx, SkScalar sy) { - canvas_.Skew(sx, sy); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Transform2DAffine(SkScalar mxx, - SkScalar mxy, - SkScalar mxt, - SkScalar myx, - SkScalar myy, - SkScalar myt) { - // clang-format off - TransformFullPerspective( - mxx, mxy, 0, mxt, - myx, myy, 0, myt, - 0 , 0, 1, 0, - 0 , 0, 0, 1 - ); - // clang-format on -} - -// |flutter::DlCanvas| -void DlAiksCanvas::TransformFullPerspective(SkScalar mxx, - SkScalar mxy, - SkScalar mxz, - SkScalar mxt, - SkScalar myx, - SkScalar myy, - SkScalar myz, - SkScalar myt, - SkScalar mzx, - SkScalar mzy, - SkScalar mzz, - SkScalar mzt, - SkScalar mwx, - SkScalar mwy, - SkScalar mwz, - SkScalar mwt) { - // The order of arguments is row-major but Impeller matrices are - // column-major. - // clang-format off - auto xformation = Matrix{ - mxx, myx, mzx, mwx, - mxy, myy, mzy, mwy, - mxz, myz, mzz, mwz, - mxt, myt, mzt, mwt - }; - // clang-format on - canvas_.Transform(xformation); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::TransformReset() { - canvas_.ResetTransform(); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::Transform(const SkMatrix* matrix) { - if (!matrix) { - return; - } - canvas_.Transform(ToMatrix(*matrix)); -} - -void DlAiksCanvas::Transform(const SkM44* matrix44) { - if (!matrix44) { - return; - } - canvas_.Transform(ToMatrix(*matrix44)); -} - -static Entity::ClipOperation ToClipOperation( - flutter::DlCanvas::ClipOp clip_op) { - switch (clip_op) { - case flutter::DlCanvas::ClipOp::kDifference: - return Entity::ClipOperation::kDifference; - case flutter::DlCanvas::ClipOp::kIntersect: - return Entity::ClipOperation::kIntersect; - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) { - canvas_.ClipRect(skia_conversions::ToRect(rect), ToClipOperation(clip_op)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { - if (rrect.isSimple()) { - canvas_.ClipRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, ToClipOperation(clip_op)); - } else { - canvas_.ClipPath(skia_conversions::ToPath(rrect), ToClipOperation(clip_op)); - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) { - canvas_.ClipPath(skia_conversions::ToPath(path), ToClipOperation(clip_op)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawColor(flutter::DlColor color, - flutter::DlBlendMode dl_mode) { - Paint paint; - paint.color = skia_conversions::ToColor(color); - paint.blend_mode = ToBlendMode(dl_mode); - canvas_.DrawPaint(paint); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawPaint(const flutter::DlPaint& paint) { - canvas_.DrawPaint(ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawLine(const SkPoint& p0, - const SkPoint& p1, - const flutter::DlPaint& paint) { - auto path = - PathBuilder{} - .AddLine(skia_conversions::ToPoint(p0), skia_conversions::ToPoint(p1)) - .SetConvexity(Convexity::kConvex) - .TakePath(); - auto aiks_paint = ToPaint(paint); - aiks_paint.style = Paint::Style::kStroke; - canvas_.DrawPath(path, aiks_paint); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawRect(const SkRect& rect, const flutter::DlPaint& paint) { - canvas_.DrawRect(skia_conversions::ToRect(rect), ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawOval(const SkRect& bounds, - const flutter::DlPaint& paint) { - if (bounds.width() == bounds.height()) { - canvas_.DrawCircle(skia_conversions::ToPoint(bounds.center()), - bounds.width() * 0.5, ToPaint(paint)); - } else { - auto path = PathBuilder{} - .AddOval(skia_conversions::ToRect(bounds)) - .SetConvexity(Convexity::kConvex) - .TakePath(); - canvas_.DrawPath(path, ToPaint(paint)); - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawCircle(const SkPoint& center, - SkScalar radius, - const flutter::DlPaint& paint) { - canvas_.DrawCircle(skia_conversions::ToPoint(center), radius, ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawRRect(const SkRRect& rrect, - const flutter::DlPaint& paint) { - if (rrect.isSimple()) { - canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, ToPaint(paint)); - } else { - canvas_.DrawPath(skia_conversions::ToPath(rrect), ToPaint(paint)); - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawDRRect(const SkRRect& outer, - const SkRRect& inner, - const flutter::DlPaint& paint) { - PathBuilder builder; - builder.AddPath(skia_conversions::ToPath(outer)); - builder.AddPath(skia_conversions::ToPath(inner)); - canvas_.DrawPath(builder.TakePath(FillType::kOdd), ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawPath(const SkPath& path, const flutter::DlPaint& paint) { - SkRect rect; - SkRRect rrect; - SkRect oval; - if (path.isRect(&rect)) { - canvas_.DrawRect(skia_conversions::ToRect(rect), ToPaint(paint)); - } else if (path.isRRect(&rrect) && rrect.isSimple()) { - canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, ToPaint(paint)); - } else if (path.isOval(&oval) && oval.width() == oval.height()) { - canvas_.DrawCircle(skia_conversions::ToPoint(oval.center()), - oval.width() * 0.5, ToPaint(paint)); - } else { - canvas_.DrawPath(skia_conversions::ToPath(path), ToPaint(paint)); - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawArc(const SkRect& oval_bounds, - SkScalar start_degrees, - SkScalar sweep_degrees, - bool use_center, - const flutter::DlPaint& paint) { - PathBuilder builder; - builder.AddArc(skia_conversions::ToRect(oval_bounds), Degrees(start_degrees), - Degrees(sweep_degrees), use_center); - canvas_.DrawPath(builder.TakePath(), ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawPoints(PointMode mode, - uint32_t count, - const SkPoint points[], - const flutter::DlPaint& paint) { - auto aiks_paint = ToPaint(paint); - switch (mode) { - case flutter::DlCanvas::PointMode::kPoints: { - // Cap::kButt is also treated as a square. - auto point_style = aiks_paint.stroke_cap == Cap::kRound - ? PointStyle::kRound - : PointStyle::kSquare; - auto radius = aiks_paint.stroke_width; - if (radius > 0) { - radius /= 2.0; - } - canvas_.DrawPoints(skia_conversions::ToPoints(points, count), radius, - aiks_paint, point_style); - } break; - case flutter::DlCanvas::PointMode::kLines: - for (uint32_t i = 1; i < count; i += 2) { - Point p0 = skia_conversions::ToPoint(points[i - 1]); - Point p1 = skia_conversions::ToPoint(points[i]); - auto path = PathBuilder{}.AddLine(p0, p1).TakePath(); - canvas_.DrawPath(path, aiks_paint); - } - break; - case flutter::DlCanvas::PointMode::kPolygon: - if (count > 1) { - Point p0 = skia_conversions::ToPoint(points[0]); - for (uint32_t i = 1; i < count; i++) { - Point p1 = skia_conversions::ToPoint(points[i]); - auto path = PathBuilder{}.AddLine(p0, p1).TakePath(); - canvas_.DrawPath(path, aiks_paint); - p0 = p1; - } - } - break; - } -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawVertices(const flutter::DlVertices* vertices, - flutter::DlBlendMode dl_mode, - const flutter::DlPaint& paint) { - canvas_.DrawVertices(DlVerticesGeometry::MakeVertices(vertices), - ToBlendMode(dl_mode), ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawImage(const sk_sp& image, - const SkPoint point, - flutter::DlImageSampling sampling, - const flutter::DlPaint* paint) { - if (!image) { - return; - } - - auto texture = image->impeller_texture(); - if (!texture) { - return; - } - - const auto size = texture->GetSize(); - const auto src = SkRect::MakeWH(size.width, size.height); - const auto dest = - SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height); - - DrawImageRect(image, // image - src, // source rect - dest, // destination rect - sampling, // sampling options - paint, // paint - SrcRectConstraint::kStrict // constraint - ); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawImageRect(const sk_sp& image, - const SkRect& src, - const SkRect& dst, - flutter::DlImageSampling sampling, - const flutter::DlPaint* paint, - SrcRectConstraint constraint) { - canvas_.DrawImageRect( - std::make_shared(image->impeller_texture()), // image - skia_conversions::ToRect(src), // source rect - skia_conversions::ToRect(dst), // destination rect - ToPaint(paint), // paint - ToSamplerDescriptor(sampling) // sampling - ); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawImageNine(const sk_sp& image, - const SkIRect& center, - const SkRect& dst, - flutter::DlFilterMode filter, - const flutter::DlPaint* paint) { - NinePatchConverter converter = {}; - auto aiks_paint = ToPaint(paint); - converter.DrawNinePatch( - std::make_shared(image->impeller_texture()), - Rect::MakeLTRB(center.fLeft, center.fTop, center.fRight, center.fBottom), - skia_conversions::ToRect(dst), ToSamplerDescriptor(filter), &canvas_, - &aiks_paint); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawAtlas(const sk_sp& atlas, - const SkRSXform xform[], - const SkRect tex[], - const flutter::DlColor colors[], - int count, - flutter::DlBlendMode mode, - flutter::DlImageSampling sampling, - const SkRect* cull_rect, - const flutter::DlPaint* paint) { - canvas_.DrawAtlas(std::make_shared(atlas->impeller_texture()), - skia_conversions::ToRSXForms(xform, count), - skia_conversions::ToRects(tex, count), - ToColors(colors, count), ToBlendMode(mode), - ToSamplerDescriptor(sampling), - skia_conversions::ToRect(cull_rect), ToPaint(paint)); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawDisplayList( - const sk_sp display_list, - SkScalar opacity) { - FML_DCHECK(false); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity) { - if (!picture) { - return; - } - FML_DCHECK(opacity == 1); - canvas_.DrawPicture(*picture); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawTextBlob(const sk_sp& blob, - SkScalar x, - SkScalar y, - const flutter::DlPaint& paint) { - const auto text_frame = MakeTextFrameFromTextBlobSkia(blob); - if (paint.getDrawStyle() == flutter::DlDrawStyle::kStroke) { - auto path = skia_conversions::PathDataFromTextBlob(blob); - auto bounds = text_frame.GetBounds(); - if (!bounds.has_value()) { - return; - } - canvas_.Save(); - canvas_.Translate({x + bounds->origin.x, y + bounds->origin.y, 0.0}); - canvas_.DrawPath(path, ToPaint(paint)); - canvas_.Restore(); - return; - } - - canvas_.DrawTextFrame(text_frame, // - impeller::Point{x, y}, // - ToPaint(paint) // - ); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::DrawShadow(const SkPath& path, - const flutter::DlColor color, - const SkScalar elevation, - bool transparent_occluder, - SkScalar dpr) { - Color spot_color = skia_conversions::ToColor(color); - spot_color.alpha *= 0.25; - - // Compute the spot color -- ported from SkShadowUtils::ComputeTonalColors. - { - Scalar max = - std::max(std::max(spot_color.red, spot_color.green), spot_color.blue); - Scalar min = - std::min(std::min(spot_color.red, spot_color.green), spot_color.blue); - Scalar luminance = (min + max) * 0.5; - - Scalar alpha_adjust = - (2.6f + (-2.66667f + 1.06667f * spot_color.alpha) * spot_color.alpha) * - spot_color.alpha; - Scalar color_alpha = - (3.544762f + (-4.891428f + 2.3466f * luminance) * luminance) * - luminance; - color_alpha = std::clamp(alpha_adjust * color_alpha, 0.0f, 1.0f); - - Scalar greyscale_alpha = - std::clamp(spot_color.alpha * (1 - 0.4f * luminance), 0.0f, 1.0f); - - Scalar color_scale = color_alpha * (1 - greyscale_alpha); - Scalar tonal_alpha = color_scale + greyscale_alpha; - Scalar unpremul_scale = tonal_alpha != 0 ? color_scale / tonal_alpha : 0; - spot_color = Color(unpremul_scale * spot_color.red, - unpremul_scale * spot_color.green, - unpremul_scale * spot_color.blue, tonal_alpha); - } - - Vector3 light_position(0, -1, 1); - Scalar occluder_z = dpr * elevation; - - constexpr Scalar kLightRadius = 800 / 600; // Light radius / light height - - Paint paint; - paint.style = Paint::Style::kFill; - paint.color = spot_color; - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Radius{kLightRadius * occluder_z / - canvas_.GetCurrentTransformation().GetScale().y}, - }; - - canvas_.Save(); - canvas_.PreConcat( - Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y))); - - SkRect rect; - SkRRect rrect; - SkRect oval; - if (path.isRect(&rect)) { - canvas_.DrawRect(skia_conversions::ToRect(rect), paint); - } else if (path.isRRect(&rrect) && rrect.isSimple()) { - canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, paint); - } else if (path.isOval(&oval) && oval.width() == oval.height()) { - canvas_.DrawCircle(skia_conversions::ToPoint(oval.center()), - oval.width() * 0.5, paint); - } else { - canvas_.DrawPath(skia_conversions::ToPath(path), paint); - } - - canvas_.Restore(); -} - -// |flutter::DlCanvas| -bool DlAiksCanvas::QuickReject(const SkRect& bounds) const { - auto maybe_cull_rect = canvas_.GetCurrentLocalCullingBounds(); - if (!maybe_cull_rect.has_value()) { - return false; - } - auto cull_rect = maybe_cull_rect.value(); - if (cull_rect.IsEmpty() || bounds.isEmpty()) { - return true; - } - auto transform = canvas_.GetCurrentTransformation(); - // There are no fast paths right now to checking whther impeller::Matrix can - // be inverted. Skip that check. - if (transform.HasPerspective()) { - return false; - } - - return !skia_conversions::ToRect(bounds).IntersectsWithRect(cull_rect); -} - -// |flutter::DlCanvas| -void DlAiksCanvas::RestoreToCount(int restore_count) { - canvas_.RestoreToCount(restore_count); -} - -// |flutter::DlCanvas| -SkISize DlAiksCanvas::GetBaseLayerSize() const { - auto size = canvas_.BaseCullRect().value_or(Rect::Giant()).size.Round(); - return SkISize::Make(size.width, size.height); -} - -// |flutter::DlCanvas| -SkImageInfo DlAiksCanvas::GetImageInfo() const { - SkISize size = GetBaseLayerSize(); - return SkImageInfo::MakeUnknown(size.width(), size.height()); -} - -Picture DlAiksCanvas::EndRecordingAsPicture() { - return canvas_.EndRecordingAsPicture(); -} - -} // namespace impeller diff --git a/impeller/display_list/dl_aiks_canvas.h b/impeller/display_list/dl_aiks_canvas.h deleted file mode 100644 index e4878c521fa0c..0000000000000 --- a/impeller/display_list/dl_aiks_canvas.h +++ /dev/null @@ -1,242 +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. - -#pragma once - -#include "flutter/display_list/dl_canvas.h" -#include "flutter/display_list/geometry/dl_rtree.h" -#include "flutter/display_list/utils/dl_bounds_accumulator.h" -#include "flutter/fml/macros.h" -#include "impeller/aiks/canvas.h" -#include "impeller/aiks/paint.h" -#include "impeller/display_list/skia_conversions.h" - -namespace impeller { - -class DlAiksCanvas final : public flutter::DlCanvas { - public: - DlAiksCanvas(); - - explicit DlAiksCanvas(const SkRect& cull_rect, bool prepare_tree = false); - - explicit DlAiksCanvas(const SkIRect& cull_rect, bool prepare_rtree = false); - - ~DlAiksCanvas(); - - Picture EndRecordingAsPicture(); - - // |DlCanvas| - SkISize GetBaseLayerSize() const override; - // |DlCanvas| - SkImageInfo GetImageInfo() const override; - - // |DlCanvas| - void Save() override; - - // |DlCanvas| - void SaveLayer(const SkRect* bounds, - const flutter::DlPaint* paint = nullptr, - const flutter::DlImageFilter* backdrop = nullptr) override; - // |DlCanvas| - void Restore() override; - // |DlCanvas| - int GetSaveCount() const override { return canvas_.GetSaveCount(); } - // |DlCanvas| - void RestoreToCount(int restore_count) override; - - // |DlCanvas| - void Translate(SkScalar tx, SkScalar ty) override; - // |DlCanvas| - void Scale(SkScalar sx, SkScalar sy) override; - // |DlCanvas| - void Rotate(SkScalar degrees) override; - // |DlCanvas| - void Skew(SkScalar sx, SkScalar sy) override; - - // clang-format off - // 2x3 2D affine subset of a 4x4 transform in row major order - // |DlCanvas| - void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, - SkScalar myx, SkScalar myy, SkScalar myt) override; - // full 4x4 transform in row major order - // |DlCanvas| - void TransformFullPerspective( - SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, - SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, - SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, - SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override; - // clang-format on - // |DlCanvas| - void TransformReset() override; - // |DlCanvas| - void Transform(const SkMatrix* matrix) override; - // |DlCanvas| - void Transform(const SkM44* matrix44) override; - // |DlCanvas| - void SetTransform(const SkMatrix* matrix) override { - TransformReset(); - Transform(matrix); - } - // |DlCanvas| - void SetTransform(const SkM44* matrix44) override { - TransformReset(); - Transform(matrix44); - } - using flutter::DlCanvas::Transform; - - /// Returns the 4x4 full perspective transform representing all transform - /// operations executed so far in this DisplayList within the enclosing - /// save stack. - // |DlCanvas| - SkM44 GetTransformFullPerspective() const override { - return skia_conversions::ToSkM44(canvas_.GetCurrentTransformation()); - } - /// Returns the 3x3 partial perspective transform representing all transform - /// operations executed so far in this DisplayList within the enclosing - /// save stack. - // |DlCanvas| - SkMatrix GetTransform() const override { - return skia_conversions::ToSkMatrix(canvas_.GetCurrentTransformation()); - } - - // |DlCanvas| - void ClipRect(const SkRect& rect, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) override; - // |DlCanvas| - void ClipRRect(const SkRRect& rrect, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) override; - // |DlCanvas| - void ClipPath(const SkPath& path, - ClipOp clip_op = ClipOp::kIntersect, - bool is_aa = false) override; - - /// Conservative estimate of the bounds of all outstanding clip operations - /// measured in the coordinate space within which this DisplayList will - /// be rendered. - // |DlCanvas| - SkRect GetDestinationClipBounds() const override { - auto rect = canvas_.GetCurrentLocalCullingBounds().value_or(Rect::Giant()); - return SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), - rect.GetBottom()); - } - /// Conservative estimate of the bounds of all outstanding clip operations - /// transformed into the local coordinate space in which currently - /// recorded rendering operations are interpreted. - // |DlCanvas| - SkRect GetLocalClipBounds() const override { - auto rect = canvas_.GetCurrentLocalCullingBounds().value_or(Rect::Giant()); - return SkRect::MakeLTRB(rect.GetLeft(), rect.GetTop(), rect.GetRight(), - rect.GetBottom()); - } - - /// Return true iff the supplied bounds are easily shown to be outside - /// of the current clip bounds. This method may conservatively return - /// false if it cannot make the determination. - // |DlCanvas| - bool QuickReject(const SkRect& bounds) const override; - - // |DlCanvas| - void DrawPaint(const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawColor(flutter::DlColor color, flutter::DlBlendMode mode) override; - // |DlCanvas| - void DrawLine(const SkPoint& p0, - const SkPoint& p1, - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawRect(const SkRect& rect, const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawOval(const SkRect& bounds, const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawCircle(const SkPoint& center, - SkScalar radius, - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawRRect(const SkRRect& rrect, const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawDRRect(const SkRRect& outer, - const SkRRect& inner, - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawPath(const SkPath& path, const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawArc(const SkRect& bounds, - SkScalar start, - SkScalar sweep, - bool useCenter, - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawPoints(PointMode mode, - uint32_t count, - const SkPoint pts[], - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawVertices(const flutter::DlVertices* vertices, - flutter::DlBlendMode mode, - const flutter::DlPaint& paint) override; - using flutter::DlCanvas::DrawVertices; - // |DlCanvas| - void DrawImage(const sk_sp& image, - const SkPoint point, - flutter::DlImageSampling sampling, - const flutter::DlPaint* paint = nullptr) override; - // |DlCanvas| - void DrawImageRect( - const sk_sp& image, - const SkRect& src, - const SkRect& dst, - flutter::DlImageSampling sampling, - const flutter::DlPaint* paint = nullptr, - SrcRectConstraint constraint = SrcRectConstraint::kFast) override; - using flutter::DlCanvas::DrawImageRect; - // |DlCanvas| - void DrawImageNine(const sk_sp& image, - const SkIRect& center, - const SkRect& dst, - flutter::DlFilterMode filter, - const flutter::DlPaint* paint = nullptr) override; - // |DlCanvas| - void DrawAtlas(const sk_sp& atlas, - const SkRSXform xform[], - const SkRect tex[], - const flutter::DlColor colors[], - int count, - flutter::DlBlendMode mode, - flutter::DlImageSampling sampling, - const SkRect* cullRect, - const flutter::DlPaint* paint = nullptr) override; - // |DlCanvas| - void DrawDisplayList(const sk_sp display_list, - SkScalar opacity = SK_Scalar1) override; - - // |DlCanvas| - void DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity = SK_Scalar1) override; - - // |DlCanvas| - void DrawTextBlob(const sk_sp& blob, - SkScalar x, - SkScalar y, - const flutter::DlPaint& paint) override; - // |DlCanvas| - void DrawShadow(const SkPath& path, - const flutter::DlColor color, - const SkScalar elevation, - bool transparent_occluder, - SkScalar dpr) override; - - // |DlCanvas| - void Flush() override {} - - private: - Canvas canvas_; - std::unique_ptr accumulator_; - - FML_DISALLOW_COPY_AND_ASSIGN(DlAiksCanvas); -}; - -} // namespace impeller diff --git a/impeller/display_list/skia_conversions.h b/impeller/display_list/skia_conversions.h index 286edaa569fb8..c56cf298a932f 100644 --- a/impeller/display_list/skia_conversions.h +++ b/impeller/display_list/skia_conversions.h @@ -7,15 +7,12 @@ #include "display_list/dl_color.h" #include "impeller/core/formats.h" #include "impeller/geometry/color.h" -#include "impeller/geometry/matrix.h" #include "impeller/geometry/path.h" #include "impeller/geometry/path_builder.h" #include "impeller/geometry/point.h" #include "impeller/geometry/rect.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColorType.h" -#include "third_party/skia/include/core/SkM44.h" -#include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPoint.h" #include "third_party/skia/include/core/SkRRect.h" @@ -49,29 +46,5 @@ Path PathDataFromTextBlob(const sk_sp& blob); std::optional ToPixelFormat(SkColorType type); -constexpr SkM44 ToSkM44(const Matrix& matrix) { - // SkM44 construction is in row major order (even though it stores the data in - // column major). - // clang-format off - return SkM44( - matrix.vec[0].x, matrix.vec[1].x, matrix.vec[2].x, matrix.vec[3].x, - matrix.vec[0].y, matrix.vec[1].y, matrix.vec[2].y, matrix.vec[3].y, - matrix.vec[0].z, matrix.vec[1].z, matrix.vec[2].z, matrix.vec[3].z, - matrix.vec[0].w, matrix.vec[1].w, matrix.vec[2].w, matrix.vec[3].w - ); - // clang-format on -} - -constexpr SkMatrix ToSkMatrix(const Matrix& matrix) { - // SkMatrix is in row major order. - // clang-format off - return SkMatrix::MakeAll( - matrix.vec[0].x, matrix.vec[1].x, matrix.vec[3].x, - matrix.vec[0].y, matrix.vec[1].y, matrix.vec[3].y, - matrix.vec[0].w, matrix.vec[1].w, matrix.vec[3].w - ); - /// clang-format on -} - } // namespace skia_conversions } // namespace impeller diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index e926cd997236b..f770165215f40 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -127,9 +127,6 @@ std::optional EntityPass::GetElementsCoverage( if (!coverage.has_value()) { continue; } - if (coverage->IsMaximum()) { - return coverage; - } result = result->Union(coverage.value()); } return result; diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h index 423e0e6498509..31db5d2324ce5 100644 --- a/impeller/entity/entity_pass.h +++ b/impeller/entity/entity_pass.h @@ -31,6 +31,7 @@ class EntityPass { /// When the element is a child `EntityPass`, it may be rendered to an /// offscreen texture and converted into an `Entity` that draws the texture /// into the current pass, or its children may be collapsed into the current + /// /// `EntityPass`. Elements are converted to Entities in /// `GetEntityForElement()`. using Element = std::variant>; diff --git a/impeller/entity/geometry/geometry.cc b/impeller/entity/geometry/geometry.cc index 85f2d80cf2b5a..36267c51c2331 100644 --- a/impeller/entity/geometry/geometry.cc +++ b/impeller/entity/geometry/geometry.cc @@ -116,11 +116,10 @@ std::unique_ptr Geometry::MakeFillPath( return std::make_unique(path, inner_rect); } -std::unique_ptr Geometry::MakePointField( - const std::vector& points, - Scalar radius, - bool round) { - return std::make_unique(points, radius, round); +std::unique_ptr Geometry::MakePointField(std::vector points, + Scalar radius, + bool round) { + return std::make_unique(std::move(points), radius, round); } std::unique_ptr Geometry::MakeStrokePath(const Path& path, diff --git a/impeller/entity/geometry/geometry.h b/impeller/entity/geometry/geometry.h index 43b91aa5054d7..6a8861d120e6e 100644 --- a/impeller/entity/geometry/geometry.h +++ b/impeller/entity/geometry/geometry.h @@ -72,8 +72,9 @@ class Geometry { static std::unique_ptr MakeRect(Rect rect); - static std::unique_ptr - MakePointField(const std::vector& points, Scalar radius, bool round); + static std::unique_ptr MakePointField(std::vector points, + Scalar radius, + bool round); virtual GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, diff --git a/impeller/entity/geometry/point_field_geometry.cc b/impeller/entity/geometry/point_field_geometry.cc index 50c43e5858bcf..81fe3885d916b 100644 --- a/impeller/entity/geometry/point_field_geometry.cc +++ b/impeller/entity/geometry/point_field_geometry.cc @@ -9,10 +9,10 @@ namespace impeller { -PointFieldGeometry::PointFieldGeometry(const std::vector& points, +PointFieldGeometry::PointFieldGeometry(std::vector points, Scalar radius, bool round) - : points_(points), radius_(radius), round_(round) {} + : points_(std::move(points)), radius_(radius), round_(round) {} PointFieldGeometry::~PointFieldGeometry() = default; diff --git a/impeller/entity/geometry/point_field_geometry.h b/impeller/entity/geometry/point_field_geometry.h index bbd69d8fe99f1..deb0ce8dd342d 100644 --- a/impeller/entity/geometry/point_field_geometry.h +++ b/impeller/entity/geometry/point_field_geometry.h @@ -10,9 +10,7 @@ namespace impeller { class PointFieldGeometry : public Geometry { public: - PointFieldGeometry(const std::vector& points, - Scalar radius, - bool round); + PointFieldGeometry(std::vector points, Scalar radius, bool round); ~PointFieldGeometry(); diff --git a/impeller/geometry/rect.h b/impeller/geometry/rect.h index 03c7874774b3c..0bda6140d95b9 100644 --- a/impeller/geometry/rect.h +++ b/impeller/geometry/rect.h @@ -72,11 +72,6 @@ struct TRect { return TRect::MakeLTRB(left, top, right, bottom); } - constexpr static TRect Giant() { - // See flutter::kGiantRect. - return TRect::MakeLTRB(-1E9, -1E9, 1E9, 1E9); - } - constexpr static TRect MakeMaximum() { return TRect::MakeLTRB(-std::numeric_limits::infinity(), -std::numeric_limits::infinity(), diff --git a/impeller/geometry/sigma.h b/impeller/geometry/sigma.h index c66b570e77eb9..c909128be4baa 100644 --- a/impeller/geometry/sigma.h +++ b/impeller/geometry/sigma.h @@ -20,7 +20,7 @@ namespace impeller { /// quality blurs (with exponentially diminishing returns for the same sigma /// input). Making this value any lower results in a noticable loss of /// quality in the blur. -constexpr static float kKernelRadiusPerSigma = 1.73205080757f; +constexpr static float kKernelRadiusPerSigma = 1.73205080757; struct Radius; @@ -29,7 +29,7 @@ struct Radius; /// the filter input. In other words, this determines how wide the /// distribution stretches. struct Sigma { - Scalar sigma = 0.0f; + Scalar sigma = 0.0; constexpr Sigma() = default; @@ -45,7 +45,7 @@ struct Sigma { /// relationship with `Sigma`. See `kKernelRadiusPerSigma` for /// details on how this relationship works. struct Radius { - Scalar radius = 0.0f; + Scalar radius = 0.0; constexpr Radius() = default; diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index d0647e3e6bfc6..5e44f3fcc27bf 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -88,13 +88,13 @@ static sk_sp CreateDeferredImage( bool impeller, std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner, + fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { #if IMPELLER_SUPPORTS_RENDERING if (impeller) { return DlDeferredImageGPUImpeller::Make(std::move(layer_tree), std::move(snapshot_delegate), - raster_task_runner); + std::move(raster_task_runner)); } #endif // IMPELLER_SUPPORTS_RENDERING @@ -121,7 +121,8 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), BuildLayerTree(width, height), - std::move(snapshot_delegate), raster_task_runner, std::move(unref_queue)); + std::move(snapshot_delegate), std::move(raster_task_runner), + std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index e47a42944c73d..ec0d59cb0d4e0 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -4,7 +4,6 @@ #include "flutter/lib/ui/compositing/scene_builder.h" -#include "flutter/flow/layers/aiks_layer.h" #include "flutter/flow/layers/backdrop_filter_layer.h" #include "flutter/flow/layers/clip_path_layer.h" #include "flutter/flow/layers/clip_rect_layer.h" @@ -227,15 +226,6 @@ void SceneBuilder::addPicture(double dx, SkPoint::Make(SafeNarrow(dx), SafeNarrow(dy)), picture->display_list(), !!(hints & 1), !!(hints & 2)); AddLayer(std::move(layer)); - return; - } - - auto impeller_picture = picture->impeller_picture(); - if (impeller_picture) { - auto layer = std::make_unique( - SkPoint::Make(SafeNarrow(dx), SafeNarrow(dy)), - std::move(impeller_picture)); - AddLayer(std::move(layer)); } } diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc index a0000967fef18..de6363e4f4e9d 100644 --- a/lib/ui/painting/canvas.cc +++ b/lib/ui/painting/canvas.cc @@ -6,7 +6,7 @@ #include -#include "flutter/display_list/dl_canvas.h" +#include "flutter/display_list/display_list_builder.h" #include "flutter/lib/ui/floating_point.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/lib/ui/painting/image_filter.h" @@ -38,18 +38,18 @@ void Canvas::Create(Dart_Handle wrapper, fml::MakeRefCounted(recorder->BeginRecording( SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), SafeNarrow(bottom)))); - FML_DCHECK(canvas->dl_canvas_); recorder->set_canvas(canvas); canvas->AssociateWithDartWrapper(wrapper); } -Canvas::Canvas(DlCanvas* canvas) : dl_canvas_(canvas) {} +Canvas::Canvas(sk_sp builder) + : display_list_builder_(std::move(builder)) {} Canvas::~Canvas() {} void Canvas::save() { - if (dl_canvas_) { - dl_canvas_->Save(); + if (display_list_builder_) { + builder()->Save(); } } @@ -58,12 +58,12 @@ void Canvas::saveLayerWithoutBounds(Dart_Handle paint_objects, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; const DlPaint* save_paint = paint.paint(dl_paint, kSaveLayerWithPaintFlags); FML_DCHECK(save_paint); TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)"); - dl_canvas_->SaveLayer(nullptr, save_paint); + builder()->SaveLayer(nullptr, save_paint); } } @@ -78,65 +78,65 @@ void Canvas::saveLayer(double left, FML_DCHECK(paint.isNotNull()); SkRect bounds = SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), SafeNarrow(bottom)); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; const DlPaint* save_paint = paint.paint(dl_paint, kSaveLayerWithPaintFlags); FML_DCHECK(save_paint); TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)"); - dl_canvas_->SaveLayer(&bounds, save_paint); + builder()->SaveLayer(&bounds, save_paint); } } void Canvas::restore() { - if (dl_canvas_) { - dl_canvas_->Restore(); + if (display_list_builder_) { + builder()->Restore(); } } int Canvas::getSaveCount() { - if (dl_canvas_) { - return dl_canvas_->GetSaveCount(); + if (display_list_builder_) { + return builder()->GetSaveCount(); } else { return 0; } } void Canvas::restoreToCount(int count) { - if (dl_canvas_ && count < getSaveCount()) { - dl_canvas_->RestoreToCount(count); + if (display_list_builder_ && count < getSaveCount()) { + builder()->RestoreToCount(count); } } void Canvas::translate(double dx, double dy) { - if (dl_canvas_) { - dl_canvas_->Translate(SafeNarrow(dx), SafeNarrow(dy)); + if (display_list_builder_) { + builder()->Translate(SafeNarrow(dx), SafeNarrow(dy)); } } void Canvas::scale(double sx, double sy) { - if (dl_canvas_) { - dl_canvas_->Scale(SafeNarrow(sx), SafeNarrow(sy)); + if (display_list_builder_) { + builder()->Scale(SafeNarrow(sx), SafeNarrow(sy)); } } void Canvas::rotate(double radians) { - if (dl_canvas_) { - dl_canvas_->Rotate(SafeNarrow(radians) * 180.0f / static_cast(M_PI)); + if (display_list_builder_) { + builder()->Rotate(SafeNarrow(radians) * 180.0f / static_cast(M_PI)); } } void Canvas::skew(double sx, double sy) { - if (dl_canvas_) { - dl_canvas_->Skew(SafeNarrow(sx), SafeNarrow(sy)); + if (display_list_builder_) { + builder()->Skew(SafeNarrow(sx), SafeNarrow(sy)); } } void Canvas::transform(const tonic::Float64List& matrix4) { // The Float array stored by Dart Matrix4 is in column-major order // Both DisplayList and SkM44 constructor take row-major matrix order - if (dl_canvas_) { + if (display_list_builder_) { // clang-format off - dl_canvas_->TransformFullPerspective( + builder()->TransformFullPerspective( SafeNarrow(matrix4[ 0]), SafeNarrow(matrix4[ 4]), SafeNarrow(matrix4[ 8]), SafeNarrow(matrix4[12]), SafeNarrow(matrix4[ 1]), SafeNarrow(matrix4[ 5]), SafeNarrow(matrix4[ 9]), SafeNarrow(matrix4[13]), SafeNarrow(matrix4[ 2]), SafeNarrow(matrix4[ 6]), SafeNarrow(matrix4[10]), SafeNarrow(matrix4[14]), @@ -146,8 +146,8 @@ void Canvas::transform(const tonic::Float64List& matrix4) { } void Canvas::getTransform(Dart_Handle matrix4_handle) { - if (dl_canvas_) { - SkM44 sk_m44 = dl_canvas_->GetTransformFullPerspective(); + if (display_list_builder_) { + SkM44 sk_m44 = builder()->GetTransformFullPerspective(); SkScalar m44_values[16]; // The Float array stored by Dart Matrix4 is in column-major order sk_m44.getColMajor(m44_values); @@ -164,18 +164,17 @@ void Canvas::clipRect(double left, double bottom, DlCanvas::ClipOp clipOp, bool doAntiAlias) { - if (dl_canvas_) { - dl_canvas_->ClipRect( - SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), - SafeNarrow(bottom)), - clipOp, doAntiAlias); + if (display_list_builder_) { + builder()->ClipRect(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), + SafeNarrow(right), SafeNarrow(bottom)), + clipOp, doAntiAlias); } } void Canvas::clipRRect(const RRect& rrect, bool doAntiAlias) { - if (dl_canvas_) { - dl_canvas_->ClipRRect(rrect.sk_rrect, DlCanvas::ClipOp::kIntersect, - doAntiAlias); + if (display_list_builder_) { + builder()->ClipRRect(rrect.sk_rrect, DlCanvas::ClipOp::kIntersect, + doAntiAlias); } } @@ -185,16 +184,16 @@ void Canvas::clipPath(const CanvasPath* path, bool doAntiAlias) { ToDart("Canvas.clipPath called with non-genuine Path.")); return; } - if (dl_canvas_) { - dl_canvas_->ClipPath(path->path(), DlCanvas::ClipOp::kIntersect, - doAntiAlias); + if (display_list_builder_) { + builder()->ClipPath(path->path(), DlCanvas::ClipOp::kIntersect, + doAntiAlias); } } void Canvas::getDestinationClipBounds(Dart_Handle rect_handle) { - if (dl_canvas_) { + if (display_list_builder_) { auto rect = tonic::Float64List(rect_handle); - SkRect bounds = dl_canvas_->GetDestinationClipBounds(); + SkRect bounds = builder()->GetDestinationClipBounds(); rect[0] = bounds.fLeft; rect[1] = bounds.fTop; rect[2] = bounds.fRight; @@ -203,9 +202,9 @@ void Canvas::getDestinationClipBounds(Dart_Handle rect_handle) { } void Canvas::getLocalClipBounds(Dart_Handle rect_handle) { - if (dl_canvas_) { + if (display_list_builder_) { auto rect = tonic::Float64List(rect_handle); - SkRect bounds = dl_canvas_->GetLocalClipBounds(); + SkRect bounds = builder()->GetLocalClipBounds(); rect[0] = bounds.fLeft; rect[1] = bounds.fTop; rect[2] = bounds.fRight; @@ -214,8 +213,8 @@ void Canvas::getLocalClipBounds(Dart_Handle rect_handle) { } void Canvas::drawColor(SkColor color, DlBlendMode blend_mode) { - if (dl_canvas_) { - dl_canvas_->DrawColor(color, blend_mode); + if (display_list_builder_) { + builder()->DrawColor(color, blend_mode); } } @@ -228,12 +227,12 @@ void Canvas::drawLine(double x1, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawLineFlags); - dl_canvas_->DrawLine(SkPoint::Make(SafeNarrow(x1), SafeNarrow(y1)), - SkPoint::Make(SafeNarrow(x2), SafeNarrow(y2)), - dl_paint); + builder()->DrawLine(SkPoint::Make(SafeNarrow(x1), SafeNarrow(y1)), + SkPoint::Make(SafeNarrow(x2), SafeNarrow(y2)), + dl_paint); } } @@ -241,7 +240,7 @@ void Canvas::drawPaint(Dart_Handle paint_objects, Dart_Handle paint_data) { Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawPaintFlags); std::shared_ptr filter = dl_paint.getImageFilter(); @@ -250,7 +249,7 @@ void Canvas::drawPaint(Dart_Handle paint_objects, Dart_Handle paint_data) { // present that cannot be replaced by an SkColorFilter. TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)"); } - dl_canvas_->DrawPaint(dl_paint); + builder()->DrawPaint(dl_paint); } } @@ -263,13 +262,12 @@ void Canvas::drawRect(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawRectFlags); - dl_canvas_->DrawRect( - SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), - SafeNarrow(bottom)), - dl_paint); + builder()->DrawRect(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), + SafeNarrow(right), SafeNarrow(bottom)), + dl_paint); } } @@ -279,10 +277,10 @@ void Canvas::drawRRect(const RRect& rrect, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawRRectFlags); - dl_canvas_->DrawRRect(rrect.sk_rrect, dl_paint); + builder()->DrawRRect(rrect.sk_rrect, dl_paint); } } @@ -293,10 +291,10 @@ void Canvas::drawDRRect(const RRect& outer, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawDRRectFlags); - dl_canvas_->DrawDRRect(outer.sk_rrect, inner.sk_rrect, dl_paint); + builder()->DrawDRRect(outer.sk_rrect, inner.sk_rrect, dl_paint); } } @@ -309,13 +307,12 @@ void Canvas::drawOval(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawOvalFlags); - dl_canvas_->DrawOval( - SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), - SafeNarrow(bottom)), - dl_paint); + builder()->DrawOval(SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), + SafeNarrow(right), SafeNarrow(bottom)), + dl_paint); } } @@ -327,11 +324,11 @@ void Canvas::drawCircle(double x, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawCircleFlags); - dl_canvas_->DrawCircle(SkPoint::Make(SafeNarrow(x), SafeNarrow(y)), - SafeNarrow(radius), dl_paint); + builder()->DrawCircle(SkPoint::Make(SafeNarrow(x), SafeNarrow(y)), + SafeNarrow(radius), dl_paint); } } @@ -347,12 +344,12 @@ void Canvas::drawArc(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, useCenter // ? kDrawArcWithCenterFlags : kDrawArcNoCenterFlags); - dl_canvas_->DrawArc( + builder()->DrawArc( SkRect::MakeLTRB(SafeNarrow(left), SafeNarrow(top), SafeNarrow(right), SafeNarrow(bottom)), SafeNarrow(startAngle) * 180.0f / static_cast(M_PI), @@ -372,10 +369,10 @@ void Canvas::drawPath(const CanvasPath* path, ToDart("Canvas.drawPath called with non-genuine Path.")); return; } - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawPathFlags); - dl_canvas_->DrawPath(path->path(), dl_paint); + builder()->DrawPath(path->path(), dl_paint); } } @@ -402,11 +399,11 @@ Dart_Handle Canvas::drawImage(const CanvasImage* image, } auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; const DlPaint* opt_paint = paint.paint(dl_paint, kDrawImageWithPaintFlags); - dl_canvas_->DrawImage(dl_image, SkPoint::Make(SafeNarrow(x), SafeNarrow(y)), - sampling, opt_paint); + builder()->DrawImage(dl_image, SkPoint::Make(SafeNarrow(x), SafeNarrow(y)), + sampling, opt_paint); } return Dart_Null(); } @@ -444,12 +441,12 @@ Dart_Handle Canvas::drawImageRect(const CanvasImage* image, SkRect dst = SkRect::MakeLTRB(SafeNarrow(dst_left), SafeNarrow(dst_top), SafeNarrow(dst_right), SafeNarrow(dst_bottom)); auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; const DlPaint* opt_paint = paint.paint(dl_paint, kDrawImageRectWithPaintFlags); - dl_canvas_->DrawImageRect(dl_image, src, dst, sampling, opt_paint, - DlCanvas::SrcRectConstraint::kFast); + builder()->DrawImageRect(dl_image, src, dst, sampling, opt_paint, + DlCanvas::SrcRectConstraint::kFast); } return Dart_Null(); } @@ -489,11 +486,11 @@ Dart_Handle Canvas::drawImageNine(const CanvasImage* image, SkRect dst = SkRect::MakeLTRB(SafeNarrow(dst_left), SafeNarrow(dst_top), SafeNarrow(dst_right), SafeNarrow(dst_bottom)); auto filter = ImageFilter::FilterModeFromIndex(bitmapSamplingIndex); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; const DlPaint* opt_paint = paint.paint(dl_paint, kDrawImageNineWithPaintFlags); - dl_canvas_->DrawImageNine(dl_image, icenter, dst, filter, opt_paint); + builder()->DrawImageNine(dl_image, icenter, dst, filter, opt_paint); } return Dart_Null(); } @@ -504,20 +501,12 @@ void Canvas::drawPicture(Picture* picture) { ToDart("Canvas.drawPicture called with non-genuine Picture.")); return; } - - if (!dl_canvas_) { - return; - } - if (picture->display_list()) { - dl_canvas_->DrawDisplayList(picture->display_list()); - } else { - auto impeller_picture = picture->impeller_picture(); - if (impeller_picture) { - dl_canvas_->DrawImpellerPicture(impeller_picture); - } else { - FML_DCHECK(false); + if (display_list_builder_) { + builder()->DrawDisplayList(picture->display_list()); } + } else { + FML_DCHECK(false); } } @@ -531,7 +520,7 @@ void Canvas::drawPoints(Dart_Handle paint_objects, "SkPoint doesn't use floats."); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; switch (point_mode) { case DlCanvas::PointMode::kPoints: @@ -544,10 +533,10 @@ void Canvas::drawPoints(Dart_Handle paint_objects, paint.paint(dl_paint, kDrawPointsAsPolygonFlags); break; } - dl_canvas_->DrawPoints(point_mode, - points.num_elements() / 2, // SkPoints have 2 floats - reinterpret_cast(points.data()), - dl_paint); + builder()->DrawPoints(point_mode, + points.num_elements() / 2, // SkPoints have 2 floats + reinterpret_cast(points.data()), + dl_paint); } } @@ -563,10 +552,10 @@ void Canvas::drawVertices(const Vertices* vertices, return; } FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { DlPaint dl_paint; paint.paint(dl_paint, kDrawVerticesFlags); - dl_canvas_->DrawVertices(vertices->vertices(), blend_mode, dl_paint); + builder()->DrawVertices(vertices->vertices(), blend_mode, dl_paint); } } @@ -601,7 +590,7 @@ Dart_Handle Canvas::drawAtlas(Dart_Handle paint_objects, auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); FML_DCHECK(paint.isNotNull()); - if (dl_canvas_) { + if (display_list_builder_) { tonic::Float32List transforms(transforms_handle); tonic::Float32List rects(rects_handle); tonic::Int32List colors(colors_handle); @@ -609,7 +598,7 @@ Dart_Handle Canvas::drawAtlas(Dart_Handle paint_objects, DlPaint dl_paint; const DlPaint* opt_paint = paint.paint(dl_paint, kDrawAtlasWithPaintFlags); - dl_canvas_->DrawAtlas( + builder()->DrawAtlas( dl_image, reinterpret_cast(transforms.data()), reinterpret_cast(rects.data()), reinterpret_cast(colors.data()), @@ -641,7 +630,7 @@ void Canvas::drawShadow(const CanvasPath* path, } else { dpr = static_cast(metrics->device_pixel_ratio); } - if (dl_canvas_) { + if (display_list_builder_) { // The DrawShadow mechanism results in non-public operations to be // performed on the canvas involving an SkDrawShadowRec. Since we // cannot include the header that defines that structure, we cannot @@ -649,13 +638,13 @@ void Canvas::drawShadow(const CanvasPath* path, // that situation we bypass the canvas interface and inject the // shadow parameters directly into the underlying DisplayList. // See: https://bugs.chromium.org/p/skia/issues/detail?id=12125 - dl_canvas_->DrawShadow(path->path(), color, SafeNarrow(elevation), - transparentOccluder, dpr); + builder()->DrawShadow(path->path(), color, SafeNarrow(elevation), + transparentOccluder, dpr); } } void Canvas::Invalidate() { - dl_canvas_ = nullptr; + display_list_builder_ = nullptr; if (dart_wrapper()) { ClearDartWrapper(); } diff --git a/lib/ui/painting/canvas.h b/lib/ui/painting/canvas.h index d735e875c840f..20ab1c9eafa9d 100644 --- a/lib/ui/painting/canvas.h +++ b/lib/ui/painting/canvas.h @@ -186,12 +186,12 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { void Invalidate(); - DlCanvas* dl_canvas() { return dl_canvas_; } + DisplayListBuilder* builder() { return display_list_builder_.get(); } private: - explicit Canvas(DlCanvas* canvas); + explicit Canvas(sk_sp builder); - DlCanvas* dl_canvas_; + sk_sp display_list_builder_; }; } // namespace flutter diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc index 11692cd711860..0c2a7de57cca4 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc @@ -6,7 +6,6 @@ #include -#include "display_list_deferred_image_gpu_impeller.h" #include "flutter/fml/make_copyable.h" namespace flutter { @@ -14,33 +13,22 @@ namespace flutter { sk_sp DlDeferredImageGPUImpeller::Make( std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { + fml::RefPtr raster_task_runner) { return sk_sp(new DlDeferredImageGPUImpeller( DlDeferredImageGPUImpeller::ImageWrapper::Make( std::move(layer_tree), std::move(snapshot_delegate), - raster_task_runner))); + std::move(raster_task_runner)))); } sk_sp DlDeferredImageGPUImpeller::Make( sk_sp display_list, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { + fml::RefPtr raster_task_runner) { return sk_sp(new DlDeferredImageGPUImpeller( DlDeferredImageGPUImpeller::ImageWrapper::Make( std::move(display_list), size, std::move(snapshot_delegate), - raster_task_runner))); -} - -sk_sp DlDeferredImageGPUImpeller::Make( - const std::shared_ptr& impeller_picture, - const SkISize& size, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { - return sk_sp(new DlDeferredImageGPUImpeller( - DlDeferredImageGPUImpeller::ImageWrapper::Make( - impeller_picture, size, std::move(snapshot_delegate), - raster_task_runner))); + std::move(raster_task_runner)))); } DlDeferredImageGPUImpeller::DlDeferredImageGPUImpeller( @@ -108,41 +96,22 @@ DlDeferredImageGPUImpeller::ImageWrapper::Make( sk_sp display_list, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { - auto wrapper = std::shared_ptr( - new ImageWrapper(std::move(display_list), size, - std::move(snapshot_delegate), raster_task_runner)); + fml::RefPtr raster_task_runner) { + auto wrapper = std::shared_ptr(new ImageWrapper( + std::move(display_list), size, std::move(snapshot_delegate), + std::move(raster_task_runner))); wrapper->SnapshotDisplayList(); return wrapper; } -std::shared_ptr -DlDeferredImageGPUImpeller::ImageWrapper::Make( - const std::shared_ptr& impeller_picture, - const SkISize& size, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { - auto wrapper = std::shared_ptr(new ImageWrapper(size)); - wrapper->SnapshotPicture(impeller_picture, std::move(snapshot_delegate), - raster_task_runner); - return wrapper; -} - std::shared_ptr DlDeferredImageGPUImpeller::ImageWrapper::Make( std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { - if (layer_tree) { - auto wrapper = std::shared_ptr( - new ImageWrapper(layer_tree->frame_size())); - wrapper->SnapshotLayer(std::move(layer_tree), std::move(snapshot_delegate), - raster_task_runner); - return wrapper; - } - auto wrapper = std::shared_ptr( - new ImageWrapper(sk_sp(), layer_tree->frame_size(), - std::move(snapshot_delegate), raster_task_runner)); + fml::RefPtr raster_task_runner) { + auto wrapper = std::shared_ptr(new ImageWrapper( + nullptr, layer_tree->frame_size(), std::move(snapshot_delegate), + std::move(raster_task_runner))); wrapper->SnapshotDisplayList(std::move(layer_tree)); return wrapper; } @@ -157,84 +126,14 @@ DlDeferredImageGPUImpeller::ImageWrapper::ImageWrapper( snapshot_delegate_(std::move(snapshot_delegate)), raster_task_runner_(std::move(raster_task_runner)) {} -DlDeferredImageGPUImpeller::ImageWrapper::ImageWrapper(const SkISize& size) - : size_(size) {} - -void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotPicture( - const std::shared_ptr& impeller_picture, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { - fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, - fml::MakeCopyable([weak_this = weak_from_this(), impeller_picture, - snapshot_delegate = std::move(snapshot_delegate)]() { - TRACE_EVENT0("flutter", "SnapshotPicture (impeller)"); - auto wrapper = weak_this.lock(); - if (!wrapper) { - return; - } - if (!snapshot_delegate) { - return; - } - - wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry(); - - auto snapshot = snapshot_delegate->MakeRasterSnapshot(impeller_picture, - wrapper->size_); - if (!snapshot) { - std::scoped_lock lock(wrapper->error_mutex_); - wrapper->error_ = "Failed to create snapshot."; - return; - } - wrapper->texture_ = snapshot->impeller_texture(); - })); -} - -void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotLayer( - std::unique_ptr layer_tree, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner) { +DlDeferredImageGPUImpeller::ImageWrapper::~ImageWrapper() { fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, - fml::MakeCopyable([weak_this = weak_from_this(), - layer_tree = std::move(layer_tree), - snapshot_delegate = std::move(snapshot_delegate)]() { - TRACE_EVENT0("flutter", "SnapshotLayer (impeller)"); - auto wrapper = weak_this.lock(); - if (!wrapper) { - return; - } - if (!snapshot_delegate) { - return; + raster_task_runner_, [id = reinterpret_cast(this), + texture_registry = std::move(texture_registry_)]() { + if (texture_registry) { + texture_registry->UnregisterContextListener(id); } - - wrapper->texture_registry_ = snapshot_delegate->GetTextureRegistry(); - - auto impeller_picture = layer_tree->FlattenToImpellerPicture( - SkRect::MakeWH(wrapper->size_.width(), wrapper->size_.height()), - wrapper->texture_registry_); - auto snapshot = snapshot_delegate->MakeRasterSnapshot(impeller_picture, - wrapper->size_); - if (!snapshot) { - std::scoped_lock lock(wrapper->error_mutex_); - wrapper->error_ = "Failed to create snapshot."; - return; - } - wrapper->texture_ = snapshot->impeller_texture(); - })); -} - -DlDeferredImageGPUImpeller::ImageWrapper::~ImageWrapper() { - if (display_list_) { - fml::TaskRunner::RunNowOrPostTask( - raster_task_runner_, - [id = reinterpret_cast(this), - texture_registry = std::move(texture_registry_)]() { - if (texture_registry) { - texture_registry->UnregisterContextListener(id); - } - }); - } + }); } void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextCreated() { @@ -243,9 +142,8 @@ void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextCreated() { } void DlDeferredImageGPUImpeller::ImageWrapper::OnGrContextDestroyed() { - if (display_list_) { - texture_.reset(); - } + // Impeller textures do not have threading requirements for deletion, and + texture_.reset(); } bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const { @@ -254,7 +152,6 @@ bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const { void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList( std::unique_ptr layer_tree) { - FML_DCHECK(display_list_ || layer_tree); fml::TaskRunner::RunNowOrPostTask( raster_task_runner_, fml::MakeCopyable([weak_this = weak_from_this(), diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h index 2e57f1ba7ce12..caed73a7c86f8 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h @@ -20,19 +20,13 @@ class DlDeferredImageGPUImpeller final : public DlImage { static sk_sp Make( std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); + fml::RefPtr raster_task_runner); static sk_sp Make( sk_sp display_list, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); - - static sk_sp Make( - const std::shared_ptr& impeller_picture, - const SkISize& size, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); + fml::RefPtr raster_task_runner); // |DlImage| ~DlDeferredImageGPUImpeller() override; @@ -73,18 +67,12 @@ class DlDeferredImageGPUImpeller final : public DlImage { sk_sp display_list, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); - - static std::shared_ptr Make( - const std::shared_ptr& impeller_picture, - const SkISize& size, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); + fml::RefPtr raster_task_runner); static std::shared_ptr Make( std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); + fml::RefPtr raster_task_runner); bool isTextureBacked() const; @@ -113,18 +101,6 @@ class DlDeferredImageGPUImpeller final : public DlImage { fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); - explicit ImageWrapper(const SkISize& size); - - void SnapshotPicture( - const std::shared_ptr& impeller_picture, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); - - void SnapshotLayer( - std::unique_ptr layer_tree, - fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner); - // If a layer tree is provided, it will be flattened during the raster // thread task spawned by this method. After being flattened into a display // list, the image wrapper will be updated to hold this display list and the diff --git a/lib/ui/painting/paint.cc b/lib/ui/painting/paint.cc index 57ebd4d52f732..2c72fb90b05e8 100644 --- a/lib/ui/painting/paint.cc +++ b/lib/ui/painting/paint.cc @@ -145,10 +145,10 @@ const DlPaint* Paint::paint(DlPaint& paint, paint.setBlendMode(static_cast(blend_mode)); } - // if (flags.applies_style()) { - uint32_t style = uint_data[kStyleIndex]; - paint.setDrawStyle(static_cast(style)); - // } + if (flags.applies_style()) { + uint32_t style = uint_data[kStyleIndex]; + paint.setDrawStyle(static_cast(style)); + } if (flags.is_stroked(paint.getDrawStyle())) { float stroke_width = float_data[kStrokeWidthIndex]; diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 08c1ceb553497..74c7b0dc78141 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -16,6 +16,9 @@ #endif // IMPELLER_SUPPORTS_RENDERING #include "flutter/lib/ui/painting/display_list_image_gpu.h" #include "third_party/tonic/converter/dart_converter.h" +#include "third_party/tonic/dart_args.h" +#include "third_party/tonic/dart_binding_macros.h" +#include "third_party/tonic/dart_library_natives.h" #include "third_party/tonic/dart_persistent_value.h" #include "third_party/tonic/logging/dart_invoke.h" @@ -24,53 +27,48 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Picture); fml::RefPtr Picture::Create(Dart_Handle dart_handle, - DisplayListOrPicture picture) { - auto canvas_picture = fml::MakeRefCounted(std::move(picture)); + sk_sp display_list) { + FML_DCHECK(display_list->isUIThreadSafe()); + auto canvas_picture = fml::MakeRefCounted(std::move(display_list)); canvas_picture->AssociateWithDartWrapper(dart_handle); return canvas_picture; } -Picture::Picture(DisplayListOrPicture picture) : picture_(std::move(picture)) {} +Picture::Picture(sk_sp display_list) + : display_list_(std::move(display_list)) {} Picture::~Picture() = default; Dart_Handle Picture::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - if (!impeller_picture() && !display_list()) { + if (!display_list_) { return tonic::ToDart("Picture is null"); } - return RasterizeToImage(width, height, raw_image_callback); + return RasterizeToImage(display_list_, width, height, raw_image_callback); } void Picture::toImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { - FML_DCHECK(impeller_picture() || display_list()); - RasterizeToImageSync(width, height, raw_image_handle); + FML_DCHECK(display_list_); + RasterizeToImageSync(display_list_, width, height, raw_image_handle); } static sk_sp CreateDeferredImage( bool impeller, sk_sp display_list, - const std::shared_ptr& impeller_picture, uint32_t width, uint32_t height, fml::TaskRunnerAffineWeakPtr snapshot_delegate, - const fml::RefPtr& raster_task_runner, + fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { #if IMPELLER_SUPPORTS_RENDERING if (impeller) { - if (display_list) { - return DlDeferredImageGPUImpeller::Make( - std::move(display_list), SkISize::Make(width, height), - std::move(snapshot_delegate), raster_task_runner); - } - FML_DCHECK(impeller_picture); return DlDeferredImageGPUImpeller::Make( - impeller_picture, SkISize::Make(width, height), - std::move(snapshot_delegate), raster_task_runner); + std::move(display_list), SkISize::Make(width, height), + std::move(snapshot_delegate), std::move(raster_task_runner)); } #endif // IMPELLER_SUPPORTS_RENDERING @@ -81,126 +79,66 @@ static sk_sp CreateDeferredImage( raster_task_runner, std::move(unref_queue)); } -void Picture::RasterizeToImageSync(uint32_t width, +// static +void Picture::RasterizeToImageSync(sk_sp display_list, + uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { auto* dart_state = UIDartState::Current(); if (!dart_state) { return; } - auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto snapshot_delegate = dart_state->GetSnapshotDelegate(); + auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( - dart_state->IsImpellerEnabled(), display_list(), impeller_picture(), - width, height, std::move(snapshot_delegate), raster_task_runner, + dart_state->IsImpellerEnabled(), std::move(display_list), width, height, + std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); - image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } void Picture::dispose() { - picture_ = sk_sp(nullptr); + display_list_.reset(); ClearDartWrapper(); } size_t Picture::GetAllocationSize() const { - auto size = sizeof(Picture); - if (display_list()) { - size += display_list()->bytes(); + if (display_list_) { + return display_list_->bytes() + sizeof(Picture); + } else { + return sizeof(Picture); } - // TODO(dnfield): Add support to EntityPass to get its allocation size. - return size; } -Dart_Handle Picture::RasterizeToImage(uint32_t width, +Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, + uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - return DoRasterizeToImage(width, height, raw_image_callback); + return DoRasterizeToImage(display_list, nullptr, width, height, + raw_image_callback); } Dart_Handle Picture::RasterizeLayerTreeToImage( std::unique_ptr layer_tree, Dart_Handle raw_image_callback) { FML_DCHECK(layer_tree != nullptr); - auto* dart_state = UIDartState::Current(); - auto image_callback = std::make_unique( - dart_state, raw_image_callback); - auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); - auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); - - auto unref_queue = dart_state->GetSkiaUnrefQueue(); - auto snapshot_delegate = dart_state->GetSnapshotDelegate(); - - // We can't create an image on this task runner because we don't have a - // graphics context. Even if we did, it would be slow anyway. Also, this - // thread owns the sole reference to the layer tree. So we do it in the - // raster thread. - - auto ui_task = - // The static leak checker gets confused by the use of - // fml::MakeCopyable. - // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - fml::MakeCopyable([image_callback = std::move(image_callback), - unref_queue](sk_sp image) mutable { - auto dart_state = image_callback->dart_state().lock(); - if (!dart_state) { - // The root isolate could have died in the meantime. - return; - } - tonic::DartState::Scope scope(dart_state); - - if (!image) { - tonic::DartInvoke(image_callback->Get(), {Dart_Null()}); - return; - } - - if (!image->isUIThreadSafe()) { - // All images with impeller textures should already be safe. - FML_DCHECK(image->impeller_texture() == nullptr); - image = - DlImageGPU::Make({image->skia_image(), std::move(unref_queue)}); - } - - auto dart_image = CanvasImage::Create(); - dart_image->set_image(image); - auto* raw_dart_image = tonic::ToDart(dart_image); - - // All done! - tonic::DartInvoke(image_callback->Get(), {raw_dart_image}); - - // image_callback is associated with the Dart isolate and must be - // deleted on the UI thread. - image_callback.reset(); - }); - - // Kick things off on the raster rask runner. - fml::TaskRunner::RunNowOrPostTask( - raster_task_runner, - fml::MakeCopyable([ui_task_runner, snapshot_delegate, ui_task, - layer_tree = std::move(layer_tree)]() mutable { - sk_sp image; - auto display_list = layer_tree->Flatten( - SkRect::MakeXYWH(0, 0, layer_tree->frame_size().width(), - layer_tree->frame_size().height()), - snapshot_delegate->GetTextureRegistry(), - snapshot_delegate->GetGrContext()); - - image = snapshot_delegate->MakeRasterSnapshot(display_list, - layer_tree->frame_size()); - fml::TaskRunner::RunNowOrPostTask( - ui_task_runner, [ui_task, image]() { ui_task(image); }); - })); - - return Dart_Null(); + auto frame_size = layer_tree->frame_size(); + return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(), + frame_size.height(), raw_image_callback); } -Dart_Handle Picture::DoRasterizeToImage(uint32_t width, +Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { + // Either display_list or layer_tree should be provided. + FML_DCHECK((display_list == nullptr) != (layer_tree == nullptr)); + if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) { return tonic::ToDart("Image callback was invalid"); } @@ -212,10 +150,9 @@ Dart_Handle Picture::DoRasterizeToImage(uint32_t width, auto* dart_state = UIDartState::Current(); auto image_callback = std::make_unique( dart_state, raw_image_callback); + auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto ui_task_runner = dart_state->GetTaskRunners().GetUITaskRunner(); auto raster_task_runner = dart_state->GetTaskRunners().GetRasterTaskRunner(); - - auto unref_queue = dart_state->GetSkiaUnrefQueue(); auto snapshot_delegate = dart_state->GetSnapshotDelegate(); // We can't create an image on this task runner because we don't have a @@ -224,8 +161,7 @@ Dart_Handle Picture::DoRasterizeToImage(uint32_t width, // raster thread. auto ui_task = - // The static leak checker gets confused by the use of - // fml::MakeCopyable. + // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) fml::MakeCopyable([image_callback = std::move(image_callback), unref_queue](sk_sp image) mutable { @@ -263,18 +199,22 @@ Dart_Handle Picture::DoRasterizeToImage(uint32_t width, // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - fml::MakeCopyable([ui_task_runner, snapshot_delegate, - display_list = display_list(), - impeller_picture = impeller_picture(), width, height, - ui_task]() mutable { + fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, width, + height, ui_task, + layer_tree = std::move(layer_tree)]() mutable { auto picture_bounds = SkISize::Make(width, height); sk_sp image; - if (display_list) { + if (layer_tree) { + FML_DCHECK(picture_bounds == layer_tree->frame_size()); + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(width, height), + snapshot_delegate->GetTextureRegistry(), + snapshot_delegate->GetGrContext()); + image = snapshot_delegate->MakeRasterSnapshot(display_list, picture_bounds); } else { - FML_DCHECK(impeller_picture); - image = snapshot_delegate->MakeRasterSnapshot(impeller_picture, + image = snapshot_delegate->MakeRasterSnapshot(display_list, picture_bounds); } diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 696de61b2230c..6d41cbe8dad68 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -5,29 +5,15 @@ #ifndef FLUTTER_LIB_UI_PAINTING_PICTURE_H_ #define FLUTTER_LIB_UI_PAINTING_PICTURE_H_ -#include - #include "flutter/display_list/display_list.h" #include "flutter/flow/layers/layer_tree.h" #include "flutter/lib/ui/dart_wrapper.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/lib/ui/ui_dart_state.h" -#include "third_party/skia/include/core/SkPicture.h" - -#if IMPELLER_SUPPORTS_RENDERING -#include "impeller/aiks/picture.h" // nogncheck -#else // IMPELLER_SUPPORTS_RENDERING -namespace impeller { -struct Picture; -} // namespace impeller -#endif // !IMPELLER_SUPPORTS_RENDERING namespace flutter { class Canvas; -using DisplayListOrPicture = - std::variant, std::shared_ptr>; - class Picture : public RefCountedDartWrappable { DEFINE_WRAPPERTYPEINFO(); FML_FRIEND_MAKE_REF_COUNTED(Picture); @@ -35,22 +21,9 @@ class Picture : public RefCountedDartWrappable { public: ~Picture() override; static fml::RefPtr Create(Dart_Handle dart_handle, - DisplayListOrPicture picture); - - const sk_sp display_list() const { - if (std::holds_alternative>(picture_)) { - return std::get>(picture_); - } - return nullptr; - } - - std::shared_ptr impeller_picture() const { - if (std::holds_alternative>( - picture_)) { - return std::get>(picture_); - } - return nullptr; - } + sk_sp display_list); + + sk_sp display_list() const { return display_list_; } Dart_Handle toImage(uint32_t width, uint32_t height, @@ -64,26 +37,34 @@ class Picture : public RefCountedDartWrappable { size_t GetAllocationSize() const; + static void RasterizeToImageSync(sk_sp display_list, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_handle); + + static Dart_Handle RasterizeToImage(const sk_sp& display_list, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); + static Dart_Handle RasterizeLayerTreeToImage( std::unique_ptr layer_tree, Dart_Handle raw_image_callback); - private: - explicit Picture(DisplayListOrPicture picture); - - DisplayListOrPicture picture_; + // Callers may provide either a display list or a layer tree, but not both. + // + // If a layer tree is provided, it will be flattened on the raster thread, and + // picture_bounds should be the layer tree's frame_size(). + static Dart_Handle DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); - void RasterizeToImageSync(uint32_t width, - uint32_t height, - Dart_Handle raw_image_handle); - - Dart_Handle RasterizeToImage(uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback); + private: + explicit Picture(sk_sp display_list); - Dart_Handle DoRasterizeToImage(uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback); + sk_sp display_list_; }; } // namespace flutter diff --git a/lib/ui/painting/picture_recorder.cc b/lib/ui/painting/picture_recorder.cc index 88e1e6844ee5a..a99b5e5855e40 100644 --- a/lib/ui/painting/picture_recorder.cc +++ b/lib/ui/painting/picture_recorder.cc @@ -6,7 +6,6 @@ #include "flutter/lib/ui/painting/canvas.h" #include "flutter/lib/ui/painting/picture.h" -#include "impeller/display_list/skia_conversions.h" // nogncheck #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" @@ -26,39 +25,21 @@ PictureRecorder::PictureRecorder() {} PictureRecorder::~PictureRecorder() {} -DlCanvas* PictureRecorder::BeginRecording(SkRect bounds) { -#if IMPELLER_SUPPORTS_RENDERING - if (UIDartState::Current()->IsImpellerEnabled()) { - dl_aiks_canvas_ = std::make_shared(bounds); - return dl_aiks_canvas_.get(); - } else { -#endif // IMPELLER_SUPPORTS_RENDERING - builder_ = sk_make_sp(bounds, /*prepare_rtree=*/true); - return builder_.get(); -#if IMPELLER_SUPPORTS_RENDERING - } -#endif // IMPELLER_SUPPORTS_RENDERING +sk_sp PictureRecorder::BeginRecording(SkRect bounds) { + display_list_builder_ = + sk_make_sp(bounds, /*prepare_rtree=*/true); + return display_list_builder_; } fml::RefPtr PictureRecorder::endRecording(Dart_Handle dart_picture) { if (!canvas_) { return nullptr; } + fml::RefPtr picture; -#if IMPELLER_SUPPORTS_RENDERING - if (UIDartState::Current()->IsImpellerEnabled()) { - picture = Picture::Create(dart_picture, - std::make_shared( - dl_aiks_canvas_->EndRecordingAsPicture())); - dl_aiks_canvas_ = nullptr; - } else { -#endif - picture = Picture::Create(dart_picture, builder_->Build()); - builder_ = nullptr; -#if IMPELLER_SUPPORTS_RENDERING - } -#endif // IMPELLER_SUPPORTS_RENDERING + picture = Picture::Create(dart_picture, display_list_builder_->Build()); + display_list_builder_ = nullptr; canvas_->Invalidate(); canvas_ = nullptr; diff --git a/lib/ui/painting/picture_recorder.h b/lib/ui/painting/picture_recorder.h index 079294b86314d..34a11fe0cc192 100644 --- a/lib/ui/painting/picture_recorder.h +++ b/lib/ui/painting/picture_recorder.h @@ -5,19 +5,9 @@ #ifndef FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_ #define FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_ -#include - #include "flutter/display_list/display_list_builder.h" #include "flutter/lib/ui/dart_wrapper.h" -#if IMPELLER_SUPPORTS_RENDERING -#include "impeller/display_list/dl_aiks_canvas.h" // nogncheck -#else // IMPELLER_SUPPORTS_RENDERING -namespace impeller { -class DlAiksCanvas; -} // namespace impeller -#endif // !IMPELLER_SUPPORTS_RENDERING - namespace flutter { class Canvas; class Picture; @@ -31,7 +21,7 @@ class PictureRecorder : public RefCountedDartWrappable { ~PictureRecorder() override; - DlCanvas* BeginRecording(SkRect bounds); + sk_sp BeginRecording(SkRect bounds); fml::RefPtr endRecording(Dart_Handle dart_picture); void set_canvas(fml::RefPtr canvas) { canvas_ = std::move(canvas); } @@ -39,8 +29,7 @@ class PictureRecorder : public RefCountedDartWrappable { private: PictureRecorder(); - std::shared_ptr dl_aiks_canvas_; - sk_sp builder_; + sk_sp display_list_builder_; fml::RefPtr canvas_; }; diff --git a/lib/ui/snapshot_delegate.h b/lib/ui/snapshot_delegate.h index d82f39e66cf56..2c3677d8551a8 100644 --- a/lib/ui/snapshot_delegate.h +++ b/lib/ui/snapshot_delegate.h @@ -70,10 +70,6 @@ class SnapshotDelegate { virtual sk_sp MakeRasterSnapshot(sk_sp display_list, SkISize picture_size) = 0; - virtual sk_sp MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize picture_size) = 0; - virtual sk_sp ConvertToRasterImage(sk_sp image) = 0; }; diff --git a/lib/ui/text/paragraph.cc b/lib/ui/text/paragraph.cc index 4c75bdef96d93..624ed145dcf38 100644 --- a/lib/ui/text/paragraph.cc +++ b/lib/ui/text/paragraph.cc @@ -64,9 +64,9 @@ void Paragraph::paint(Canvas* canvas, double x, double y) { return; } - DlCanvas* dl_canvas = canvas->dl_canvas(); - if (dl_canvas) { - m_paragraph->Paint(dl_canvas, x, y); + DisplayListBuilder* builder = canvas->builder(); + if (builder) { + m_paragraph->Paint(builder, x, y); } } diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 978aaa7d1e690..c5a4db91e4333 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -85,6 +85,8 @@ source_set("common") { "context_options.h", "display_manager.cc", "display_manager.h", + "dl_op_spy.cc", + "dl_op_spy.h", "engine.cc", "engine.h", "pipeline.cc", @@ -292,6 +294,7 @@ if (enable_unittests) { sources = [ "animator_unittests.cc", "context_options_unittests.cc", + "dl_op_spy_unittests.cc", "engine_unittests.cc", "input_events_unittests.cc", "persistent_cache_unittests.cc", diff --git a/display_list/dl_op_spy.cc b/shell/common/dl_op_spy.cc similarity index 99% rename from display_list/dl_op_spy.cc rename to shell/common/dl_op_spy.cc index 993fd09c17ced..006ca10adcdd2 100644 --- a/display_list/dl_op_spy.cc +++ b/shell/common/dl_op_spy.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/display_list/dl_op_spy.h" +#include "flutter/shell/common/dl_op_spy.h" namespace flutter { diff --git a/display_list/dl_op_spy.h b/shell/common/dl_op_spy.h similarity index 97% rename from display_list/dl_op_spy.h rename to shell/common/dl_op_spy.h index 501fe37dbc262..f81ca435fca7d 100644 --- a/display_list/dl_op_spy.h +++ b/shell/common/dl_op_spy.h @@ -2,7 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#pragma once +#ifndef FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_ +#define FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_ #include "flutter/display_list/dl_op_receiver.h" #include "flutter/display_list/utils/dl_receiver_utils.h" @@ -104,3 +105,5 @@ class DlOpSpy final : public virtual DlOpReceiver, }; } // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_ diff --git a/display_list/dl_op_spy_unittests.cc b/shell/common/dl_op_spy_unittests.cc similarity index 99% rename from display_list/dl_op_spy_unittests.cc rename to shell/common/dl_op_spy_unittests.cc index a976e2cde80a6..dcdddd6162ca2 100644 --- a/display_list/dl_op_spy_unittests.cc +++ b/shell/common/dl_op_spy_unittests.cc @@ -4,7 +4,7 @@ #include "flutter/display_list/display_list.h" #include "flutter/display_list/display_list_builder.h" -#include "flutter/display_list/dl_op_spy.h" +#include "flutter/shell/common/dl_op_spy.h" #include "flutter/testing/testing.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkRSXform.h" diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 7ccf4aee73c50..03e7c4e7a59d8 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -379,12 +379,6 @@ sk_sp Rasterizer::MakeRasterSnapshot(sk_sp display_list, return snapshot_controller_->MakeRasterSnapshot(display_list, picture_size); } -sk_sp Rasterizer::MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize picture_size) { - return snapshot_controller_->MakeRasterSnapshot(picture, picture_size); -} - sk_sp Rasterizer::ConvertToRasterImage(sk_sp image) { TRACE_EVENT0("flutter", __FUNCTION__); return snapshot_controller_->ConvertToRasterImage(image); diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 8d0b0a2271411..a54dd677a2fdb 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -534,11 +534,6 @@ class Rasterizer final : public SnapshotDelegate, sk_sp MakeRasterSnapshot(sk_sp display_list, SkISize picture_size) override; - // |SnapshotDelegate| - sk_sp MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize picture_size) override; - // |SnapshotDelegate| sk_sp ConvertToRasterImage(sk_sp image) override; diff --git a/shell/common/snapshot_controller.h b/shell/common/snapshot_controller.h index a5709f9d2d226..c402c3ec709fa 100644 --- a/shell/common/snapshot_controller.h +++ b/shell/common/snapshot_controller.h @@ -42,10 +42,6 @@ class SnapshotController { virtual sk_sp MakeRasterSnapshot(sk_sp display_list, SkISize size) = 0; - virtual sk_sp MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize size) = 0; - virtual sk_sp ConvertToRasterImage(sk_sp image) = 0; protected: diff --git a/shell/common/snapshot_controller_impeller.cc b/shell/common/snapshot_controller_impeller.cc index 79c3bf5c65095..ea68bd91188a4 100644 --- a/shell/common/snapshot_controller_impeller.cc +++ b/shell/common/snapshot_controller_impeller.cc @@ -30,36 +30,13 @@ sk_sp SnapshotControllerImpeller::MakeRasterSnapshot( return result; } -sk_sp SnapshotControllerImpeller::MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize size) { - sk_sp result; - if (!picture) { - return result; - } - GetDelegate().GetIsGpuDisabledSyncSwitch()->Execute( - fml::SyncSwitch::Handlers() - .SetIfTrue([&] { - // Do nothing. - }) - .SetIfFalse([&] { result = DoMakeRasterSnapshot(*picture, size); })); - - return result; -} - sk_sp SnapshotControllerImpeller::DoMakeRasterSnapshot( const sk_sp& display_list, SkISize size) { TRACE_EVENT0("flutter", __FUNCTION__); impeller::DlDispatcher dispatcher; display_list->Dispatch(dispatcher); - return DoMakeRasterSnapshot(dispatcher.EndRecordingAsPicture(), size); -} - -sk_sp SnapshotControllerImpeller::DoMakeRasterSnapshot( - const impeller::Picture& picture, - SkISize size) { - TRACE_EVENT0("flutter", __FUNCTION__); + impeller::Picture picture = dispatcher.EndRecordingAsPicture(); auto context = GetDelegate().GetAiksContext(); if (context) { auto max_size = context->GetContext() diff --git a/shell/common/snapshot_controller_impeller.h b/shell/common/snapshot_controller_impeller.h index 5bd40a969597f..d9f1d632e3553 100644 --- a/shell/common/snapshot_controller_impeller.h +++ b/shell/common/snapshot_controller_impeller.h @@ -18,19 +18,12 @@ class SnapshotControllerImpeller : public SnapshotController { sk_sp MakeRasterSnapshot(sk_sp display_list, SkISize size) override; - sk_sp MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize size) override; - sk_sp ConvertToRasterImage(sk_sp image) override; private: sk_sp DoMakeRasterSnapshot(const sk_sp& display_list, SkISize size); - sk_sp DoMakeRasterSnapshot(const impeller::Picture& picture, - SkISize size); - FML_DISALLOW_COPY_AND_ASSIGN(SnapshotControllerImpeller); }; diff --git a/shell/common/snapshot_controller_skia.cc b/shell/common/snapshot_controller_skia.cc index 096dfac614666..fe7897f38d178 100644 --- a/shell/common/snapshot_controller_skia.cc +++ b/shell/common/snapshot_controller_skia.cc @@ -137,13 +137,6 @@ sk_sp SnapshotControllerSkia::MakeRasterSnapshot( }); } -sk_sp SnapshotControllerSkia::MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize size) { - FML_DCHECK(false); - return sk_sp(); -} - sk_sp SnapshotControllerSkia::ConvertToRasterImage( sk_sp image) { // If the rasterizer does not have a surface with a GrContext, then it will diff --git a/shell/common/snapshot_controller_skia.h b/shell/common/snapshot_controller_skia.h index 09a48a4251a36..8be1d8e1ec274 100644 --- a/shell/common/snapshot_controller_skia.h +++ b/shell/common/snapshot_controller_skia.h @@ -18,10 +18,6 @@ class SnapshotControllerSkia : public SnapshotController { sk_sp MakeRasterSnapshot(sk_sp display_list, SkISize size) override; - sk_sp MakeRasterSnapshot( - const std::shared_ptr& picture, - SkISize size) override; - virtual sk_sp ConvertToRasterImage(sk_sp image) override; private: diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index 9bea5b0cd082c..19e2669c997a2 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -5,9 +5,10 @@ #include "flutter/shell/gpu/gpu_surface_gl_impeller.h" #include "flutter/fml/make_copyable.h" -#include "flutter/impeller/renderer/backend/gles/surface_gles.h" -#include "flutter/impeller/renderer/renderer.h" -#include "flutter/impeller/typographer/backends/skia/typographer_context_skia.h" +#include "impeller/display_list/dl_dispatcher.h" +#include "impeller/renderer/backend/gles/surface_gles.h" +#include "impeller/renderer/renderer.h" +#include "impeller/typographer/backends/skia/typographer_context_skia.h" namespace flutter { @@ -101,14 +102,27 @@ std::unique_ptr GPUSurfaceGLImpeller::AcquireFrame( return false; } - auto picture = surface_frame.GetImpellerPicture(); + auto display_list = surface_frame.BuildDisplayList(); + if (!display_list) { + FML_LOG(ERROR) << "Could not build display list for surface frame."; + return false; + } + + auto cull_rect = + surface->GetTargetRenderPassDescriptor().GetRenderTargetSize(); + impeller::Rect dl_cull_rect = impeller::Rect::MakeSize(cull_rect); + impeller::DlDispatcher impeller_dispatcher(dl_cull_rect); + display_list->Dispatch( + impeller_dispatcher, + SkIRect::MakeWH(cull_rect.width, cull_rect.height)); + auto picture = impeller_dispatcher.EndRecordingAsPicture(); return renderer->Render( std::move(surface), fml::MakeCopyable( [aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(*picture, render_target); + return aiks_context->Render(picture, render_target); })); }); diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 4c2b117a80592..d76b13824c86e 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -11,8 +11,9 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/mapping.h" #include "flutter/fml/trace_event.h" -#include "flutter/impeller/renderer/backend/metal/surface_mtl.h" -#include "flutter/impeller/typographer/backends/skia/typographer_context_skia.h" +#include "impeller/display_list/dl_dispatcher.h" +#include "impeller/renderer/backend/metal/surface_mtl.h" +#include "impeller/typographer/backends/skia/typographer_context_skia.h" static_assert(!__has_feature(objc_arc), "ARC must be disabled."); @@ -114,6 +115,12 @@ return false; } + auto display_list = surface_frame.BuildDisplayList(); + if (!display_list) { + FML_LOG(ERROR) << "Could not build display list for surface frame."; + return false; + } + if (!disable_partial_repaint_) { uintptr_t texture = reinterpret_cast(last_texture); @@ -143,13 +150,17 @@ return surface->Present(); } - auto picture = surface_frame.GetImpellerPicture(); + impeller::IRect cull_rect = surface->coverage(); + SkIRect sk_cull_rect = SkIRect::MakeWH(cull_rect.size.width, cull_rect.size.height); + impeller::DlDispatcher impeller_dispatcher(cull_rect); + display_list->Dispatch(impeller_dispatcher, sk_cull_rect); + auto picture = impeller_dispatcher.EndRecordingAsPicture(); return renderer->Render( std::move(surface), fml::MakeCopyable([aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(*picture, render_target); + return aiks_context->Render(picture, render_target); })); }); @@ -202,6 +213,12 @@ return false; } + auto display_list = surface_frame.BuildDisplayList(); + if (!display_list) { + FML_LOG(ERROR) << "Could not build display list for surface frame."; + return false; + } + if (!disable_partial_repaint_) { uintptr_t texture_ptr = reinterpret_cast(mtl_texture); @@ -231,13 +248,17 @@ return surface->Present(); } - auto picture = surface_frame.GetImpellerPicture(); + impeller::IRect cull_rect = surface->coverage(); + SkIRect sk_cull_rect = SkIRect::MakeWH(cull_rect.size.width, cull_rect.size.height); + impeller::DlDispatcher impeller_dispatcher(cull_rect); + display_list->Dispatch(impeller_dispatcher, sk_cull_rect); + auto picture = impeller_dispatcher.EndRecordingAsPicture(); bool render_result = renderer->Render(std::move(surface), fml::MakeCopyable([aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(*picture, render_target); + return aiks_context->Render(picture, render_target); })); if (!render_result) { FML_LOG(ERROR) << "Failed to render Impeller frame"; diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 5c798bbca3732..3b6ec9d876ec0 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -5,7 +5,7 @@ #include "flutter/shell/gpu/gpu_surface_vulkan_impeller.h" #include "flutter/fml/make_copyable.h" -#include "flutter/impeller/renderer/renderer.h" +#include "impeller/display_list/dl_dispatcher.h" #include "impeller/renderer/backend/vulkan/surface_context_vk.h" #include "impeller/renderer/renderer.h" #include "impeller/renderer/surface.h" @@ -69,14 +69,27 @@ std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( return false; } - auto picture = surface_frame.GetImpellerPicture(); + auto display_list = surface_frame.BuildDisplayList(); + if (!display_list) { + FML_LOG(ERROR) << "Could not build display list for surface frame."; + return false; + } + + auto cull_rect = + surface->GetTargetRenderPassDescriptor().GetRenderTargetSize(); + impeller::Rect dl_cull_rect = impeller::Rect::MakeSize(cull_rect); + impeller::DlDispatcher impeller_dispatcher(dl_cull_rect); + display_list->Dispatch( + impeller_dispatcher, + SkIRect::MakeWH(cull_rect.width, cull_rect.height)); + auto picture = impeller_dispatcher.EndRecordingAsPicture(); return renderer->Render( std::move(surface), fml::MakeCopyable( [aiks_context, picture = std::move(picture)]( impeller::RenderTarget& render_target) -> bool { - return aiks_context->Render(*picture, render_target); + return aiks_context->Render(picture, render_target); })); }); diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc index 10fc5fc4d27a8..d29a80eb16a8c 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -12,15 +12,13 @@ AndroidExternalViewEmbedder::AndroidExternalViewEmbedder( const AndroidContext& android_context, std::shared_ptr jni_facade, std::shared_ptr surface_factory, - const TaskRunners& task_runners, - bool enable_impeller) + const TaskRunners& task_runners) : ExternalViewEmbedder(), android_context_(android_context), jni_facade_(std::move(jni_facade)), surface_factory_(std::move(surface_factory)), surface_pool_(std::make_unique()), - task_runners_(task_runners), - enable_impeller_(enable_impeller) {} + task_runners_(task_runners) {} // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView( @@ -31,11 +29,7 @@ void AndroidExternalViewEmbedder::PrerollCompositeEmbeddedView( SkRect view_bounds = SkRect::Make(frame_size_); std::unique_ptr view; - if (enable_impeller_) { - view = std::make_unique(view_bounds); - } else { - view = std::make_unique(view_bounds); - } + view = std::make_unique(view_bounds); slices_.insert_or_assign(view_id, std::move(view)); composition_order_.push_back(view_id); diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.h b/shell/platform/android/external_view_embedder/external_view_embedder.h index 0f1d69e955d48..400b43fb91a89 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -32,8 +32,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { const AndroidContext& android_context, std::shared_ptr jni_facade, std::shared_ptr surface_factory, - const TaskRunners& task_runners, - bool enable_impeller); + const TaskRunners& task_runners); // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( @@ -124,8 +123,6 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // The number of platform views in the previous frame. int64_t previous_frame_view_count_; - bool enable_impeller_ = false; - // Destroys the surfaces created from the surface factory. // This method schedules a task on the platform thread, and waits for // the task until it completes. diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc index 40d9e9fd526b5..e6417a08f0800 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc @@ -107,7 +107,7 @@ TaskRunners GetTaskRunnersForFixture() { TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) { auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, nullptr, nullptr, GetTaskRunnersForFixture(), false); + android_context, nullptr, nullptr, GetTaskRunnersForFixture()); ASSERT_EQ(nullptr, embedder->CompositeEmbeddedView(0)); embedder->PrerollCompositeEmbeddedView( @@ -123,7 +123,7 @@ TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) { TEST(AndroidExternalViewEmbedder, CancelFrame) { auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, nullptr, nullptr, GetTaskRunnersForFixture(), false); + android_context, nullptr, nullptr, GetTaskRunnersForFixture()); embedder->PrerollCompositeEmbeddedView( 0, std::make_unique()); @@ -136,7 +136,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) { auto jni_mock = std::make_shared(); auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = @@ -170,7 +170,7 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnRasterizerThread) { auto jni_mock = std::make_shared(); auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = @@ -191,7 +191,7 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRect) { auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); @@ -219,7 +219,7 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRectChangedParams) { auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); @@ -295,8 +295,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { return android_surface_mock; }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); auto raster_thread_merger = GetThreadMergerFromPlatformThread(); @@ -495,8 +494,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { return android_surface_mock; }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); auto raster_thread_merger = GetThreadMergerFromPlatformThread(); @@ -594,8 +592,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { return android_surface_mock; }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); auto raster_thread_merger = GetThreadMergerFromPlatformThread(); @@ -698,8 +695,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { return android_surface_mock; }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); auto raster_thread_merger = GetThreadMergerFromPlatformThread(); @@ -739,7 +735,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) { auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); // While on the raster thread, don't make JNI calls as these methods can only // run on the platform thread. @@ -788,8 +784,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); @@ -877,8 +872,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); // ------------------ First frame ------------------ // { @@ -936,7 +930,7 @@ TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) { auto jni_mock = std::make_shared(); auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); ASSERT_TRUE(embedder->SupportsDynamicThreadMerging()); } @@ -944,7 +938,7 @@ TEST(AndroidExternalViewEmbedder, DisableThreadMerger) { auto jni_mock = std::make_shared(); auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); fml::Thread platform_thread("platform"); auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread); @@ -1000,8 +994,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) { }); auto embedder = std::make_unique( - *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture(), - false); + *android_context, jni_mock, surface_factory, GetTaskRunnersForFixture()); fml::Thread rasterizer_thread("rasterizer"); auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); @@ -1044,7 +1037,7 @@ TEST(AndroidExternalViewEmbedder, TeardownDoesNotCallJNIMethod) { auto android_context = std::make_shared(AndroidRenderingAPI::kSoftware); auto embedder = std::make_unique( - *android_context, jni_mock, nullptr, GetTaskRunnersForFixture(), false); + *android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()).Times(0); embedder->Teardown(); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index dabad16e3e4a5..ac6111c343ada 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -363,8 +363,7 @@ std::unique_ptr PlatformViewAndroid::CreateRenderingSurface() { std::shared_ptr PlatformViewAndroid::CreateExternalViewEmbedder() { return std::make_shared( - *android_context_, jni_facade_, surface_factory_, task_runners_, - delegate_.OnPlatformViewGetSettings().enable_impeller); + *android_context_, jni_facade_, surface_factory_, task_runners_); } // |PlatformView| diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 7b259d4a054c8..e571001a26588 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -1310,7 +1310,7 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor, return {std::make_unique( avoid_backing_store_cache, create_render_target_callback, - present_callback, enable_impeller), + present_callback), false}; } diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index fcb436865a74b..4261366efa235 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -4,8 +4,13 @@ #include "flutter/shell/platform/embedder/embedder_external_view.h" -#include "flow/embedded_views.h" +#include "flutter/display_list/display_list_builder.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/common/dl_op_spy.h" + +#ifdef IMPELLER_SUPPORTS_RENDERING +#include "impeller/display_list/dl_dispatcher.h" // nogncheck +#endif // IMPELLER_SUPPORTS_RENDERING namespace flutter { @@ -18,37 +23,21 @@ static SkISize TransformedSurfaceSize(const SkISize& size, EmbedderExternalView::EmbedderExternalView( const SkISize& frame_size, - const SkMatrix& surface_transformation, - bool enable_impeller) - : EmbedderExternalView(frame_size, - surface_transformation, - {}, - nullptr, - enable_impeller) {} + const SkMatrix& surface_transformation) + : EmbedderExternalView(frame_size, surface_transformation, {}, nullptr) {} EmbedderExternalView::EmbedderExternalView( const SkISize& frame_size, const SkMatrix& surface_transformation, ViewIdentifier view_identifier, - std::unique_ptr params, - bool enable_impeller) + std::unique_ptr params) : render_surface_size_( TransformedSurfaceSize(frame_size, surface_transformation)), surface_transformation_(surface_transformation), view_identifier_(view_identifier), - embedded_view_params_(std::move(params)) { -#if IMPELLER_SUPPORTS_RENDERING - if (enable_impeller) { - slice_ = - std::make_unique(SkRect::Make(frame_size)); - } else { -#endif // IMPELLER_SUPPORTS_RENDERING - slice_ = std::make_unique( - SkRect::Make(frame_size)); -#if IMPELLER_SUPPORTS_RENDERING - } -#endif // IMPELLER_SUPPORTS_RENDERING -} + embedded_view_params_(std::move(params)), + slice_(std::make_unique( + SkRect::Make(frame_size))) {} EmbedderExternalView::~EmbedderExternalView() = default; @@ -78,7 +67,9 @@ bool EmbedderExternalView::HasEngineRenderedContents() { return has_engine_rendered_contents_.value(); } TryEndRecording(); - has_engine_rendered_contents_ = slice_->renders_anything(); + DlOpSpy dl_op_spy; + slice_->dispatch(dl_op_spy); + has_engine_rendered_contents_ = dl_op_spy.did_draw() && !slice_->is_empty(); return has_engine_rendered_contents_.value(); } @@ -103,12 +94,13 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { if (impeller_target) { auto aiks_context = render_target.GetAiksContext(); - impeller::DlAiksCanvas dl_canvas( - SkRect::Make(render_target.GetRenderTargetSize())); - dl_canvas.SetTransform(&surface_transformation_); - slice_->render_into(&dl_canvas); + auto dl_builder = DisplayListBuilder(); + dl_builder.SetTransform(&surface_transformation_); + slice_->render_into(&dl_builder); - return aiks_context->Render(dl_canvas.EndRecordingAsPicture(), + auto dispatcher = impeller::DlDispatcher(); + dispatcher.drawDisplayList(dl_builder.Build(), 1); + return aiks_context->Render(dispatcher.EndRecordingAsPicture(), *impeller_target); } #endif // IMPELLER_SUPPORTS_RENDERING diff --git a/shell/platform/embedder/embedder_external_view.h b/shell/platform/embedder/embedder_external_view.h index e4187b4edffee..2b8e26d200155 100644 --- a/shell/platform/embedder/embedder_external_view.h +++ b/shell/platform/embedder/embedder_external_view.h @@ -82,14 +82,12 @@ class EmbedderExternalView { ViewIdentifier::Equal>; EmbedderExternalView(const SkISize& frame_size, - const SkMatrix& surface_transformation, - bool enable_impeller); + const SkMatrix& surface_transformation); EmbedderExternalView(const SkISize& frame_size, const SkMatrix& surface_transformation, ViewIdentifier view_identifier, - std::unique_ptr params, - bool enable_impeller); + std::unique_ptr params); ~EmbedderExternalView(); @@ -120,7 +118,7 @@ class EmbedderExternalView { const SkMatrix surface_transformation_; ViewIdentifier view_identifier_; std::unique_ptr embedded_view_params_; - std::unique_ptr slice_; + std::unique_ptr slice_; std::optional has_engine_rendered_contents_; FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalView); diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index 1b328ff84fa8d..f87d451a6af26 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -16,10 +16,8 @@ namespace flutter { EmbedderExternalViewEmbedder::EmbedderExternalViewEmbedder( bool avoid_backing_store_cache, const CreateRenderTargetCallback& create_render_target_callback, - const PresentCallback& present_callback, - bool enable_impeller) - : enable_impeller_(enable_impeller), - avoid_backing_store_cache_(avoid_backing_store_cache), + const PresentCallback& present_callback) + : avoid_backing_store_cache_(avoid_backing_store_cache), create_render_target_callback_(create_render_target_callback), present_callback_(present_callback) { FML_DCHECK(create_render_target_callback_); @@ -67,7 +65,7 @@ void EmbedderExternalViewEmbedder::BeginFrame( EmbedderExternalView::ViewIdentifier{}; pending_views_[kRootViewIdentifier] = std::make_unique( - pending_frame_size_, pending_surface_transformation_, enable_impeller_); + pending_frame_size_, pending_surface_transformation_); composition_order_.push_back(kRootViewIdentifier); } @@ -82,8 +80,7 @@ void EmbedderExternalViewEmbedder::PrerollCompositeEmbeddedView( pending_frame_size_, // frame size pending_surface_transformation_, // surface xformation vid, // view identifier - std::move(params), // embedded view params - enable_impeller_ // enable_impeller + std::move(params) // embedded view params ); composition_order_.push_back(vid); } diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 6446fa085cefc..014f7393c416e 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -58,8 +58,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { EmbedderExternalViewEmbedder( bool avoid_backing_store_cache, const CreateRenderTargetCallback& create_render_target_callback, - const PresentCallback& present_callback, - bool enable_impeller); + const PresentCallback& present_callback); //---------------------------------------------------------------------------- /// @brief Collects the external view embedder. @@ -105,7 +104,6 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { DlCanvas* GetRootCanvas() override; private: - bool enable_impeller_ = false; const bool avoid_backing_store_cache_; const CreateRenderTargetCallback create_render_target_callback_; const PresentCallback present_callback_; diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index bd9d321fc2500..75b03107e2a75 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -193,14 +193,6 @@ void MockCanvas::DrawImage(const sk_sp& image, } } -void MockCanvas::DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity) { - draw_calls_.emplace_back( - DrawCall{.layer = current_layer_, - .data = DrawImpellerPictureData{picture, opacity}}); -} - void MockCanvas::DrawDisplayList(const sk_sp display_list, SkScalar opacity) { draw_calls_.emplace_back( @@ -470,16 +462,6 @@ std::ostream& operator<<(std::ostream& os, << data.options; } -bool operator==(const MockCanvas::DrawImpellerPictureData& a, - const MockCanvas::DrawImpellerPictureData& b) { - return a.picture == b.picture && a.opacity == b.opacity; -} - -std::ostream& operator<<(std::ostream& os, - const MockCanvas::DrawImpellerPictureData& data) { - return os << "[Impeller picture] " << data.opacity; -} - bool operator==(const MockCanvas::DrawDisplayListData& a, const MockCanvas::DrawDisplayListData& b) { return a.display_list->Equals(b.display_list) && a.opacity == b.opacity; diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h index b24918d10fa55..4f27ddb75b483 100644 --- a/testing/mock_canvas.h +++ b/testing/mock_canvas.h @@ -95,11 +95,6 @@ class MockCanvas final : public DlCanvas { DlPaint paint; }; - struct DrawImpellerPictureData { - std::shared_ptr picture; - SkScalar opacity; - }; - struct DrawDisplayListData { sk_sp display_list; SkScalar opacity; @@ -147,7 +142,6 @@ class MockCanvas final : public DlCanvas { DrawTextData, DrawImageDataNoPaint, DrawImageData, - DrawImpellerPictureData, DrawDisplayListData, DrawShadowData, ClipRectData, @@ -272,9 +266,7 @@ class MockCanvas final : public DlCanvas { DlImageSampling sampling, const SkRect* cullRect, const DlPaint* paint = nullptr) override; - void DrawImpellerPicture( - const std::shared_ptr& picture, - SkScalar opacity = SK_Scalar1) override; + void DrawDisplayList(const sk_sp display_list, SkScalar opacity) override; void DrawTextBlob(const sk_sp& blob, @@ -335,11 +327,6 @@ extern bool operator==(const MockCanvas::DrawImageDataNoPaint& a, const MockCanvas::DrawImageDataNoPaint& b); extern std::ostream& operator<<(std::ostream& os, const MockCanvas::DrawImageDataNoPaint& data); -extern std::ostream& operator<<( - std::ostream& os, - const MockCanvas::DrawImpellerPictureData& data); -extern bool operator==(const MockCanvas::DrawImpellerPictureData& a, - const MockCanvas::DrawImpellerPictureData& b); extern bool operator==(const MockCanvas::DrawDisplayListData& a, const MockCanvas::DrawDisplayListData& b); extern std::ostream& operator<<(std::ostream& os, diff --git a/third_party/txt/src/skia/paragraph_skia.cc b/third_party/txt/src/skia/paragraph_skia.cc index e941d93881273..76d737224aa79 100644 --- a/third_party/txt/src/skia/paragraph_skia.cc +++ b/third_party/txt/src/skia/paragraph_skia.cc @@ -49,7 +49,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { //---------------------------------------------------------------------------- /// @brief Creates a |skt::ParagraphPainter| that draws to DisplayList. /// - /// @param canvas The display list canvas. + /// @param builder The display list builder. /// @param[in] dl_paints The paints referenced by ID in the `drawX` methods. /// @param[in] draw_path_effect If true, draw path effects directly by /// drawing multiple lines instead of providing @@ -63,10 +63,10 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { /// See https://github.com/flutter/flutter/issues/126673. It /// probably makes sense to eventually make this a compile-time /// decision (i.e. with `#ifdef`) instead of a runtime option. - DisplayListParagraphPainter(DlCanvas* canvas, + DisplayListParagraphPainter(DisplayListBuilder* builder, const std::vector& dl_paints, bool draw_path_effect) - : canvas_(canvas), + : builder_(builder), dl_paints_(dl_paints), draw_path_effect_(draw_path_effect) {} @@ -79,7 +79,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { } size_t paint_id = std::get(paint); FML_DCHECK(paint_id < dl_paints_.size()); - canvas_->DrawTextBlob(blob, x, y, dl_paints_[paint_id]); + builder_->DrawTextBlob(blob, x, y, dl_paints_[paint_id]); } void drawTextShadow(const sk_sp& blob, @@ -96,24 +96,24 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { DlBlurMaskFilter filter(DlBlurStyle::kNormal, blur_sigma, false); paint.setMaskFilter(&filter); } - canvas_->DrawTextBlob(blob, x, y, paint); + builder_->DrawTextBlob(blob, x, y, paint); } void drawRect(const SkRect& rect, const SkPaintOrID& paint) override { size_t paint_id = std::get(paint); FML_DCHECK(paint_id < dl_paints_.size()); - canvas_->DrawRect(rect, dl_paints_[paint_id]); + builder_->DrawRect(rect, dl_paints_[paint_id]); } void drawFilledRect(const SkRect& rect, const DecorationStyle& decor_style) override { DlPaint paint = toDlPaint(decor_style, DlDrawStyle::kFill); - canvas_->DrawRect(rect, paint); + builder_->DrawRect(rect, paint); } void drawPath(const SkPath& path, const DecorationStyle& decor_style) override { - canvas_->DrawPath(path, toDlPaint(decor_style)); + builder_->DrawPath(path, toDlPaint(decor_style)); } void drawLine(SkScalar x0, @@ -131,7 +131,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { auto dash_path_effect = decor_style.getDashPathEffect(); if (draw_path_effect_ && dash_path_effect) { auto path = dashedLine(x0, x1, y0, *dash_path_effect); - canvas_->DrawPath(path, toDlPaint(decor_style)); + builder_->DrawPath(path, toDlPaint(decor_style)); return; } @@ -139,20 +139,20 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { if (dash_path_effect) { setPathEffect(paint, *dash_path_effect); } - canvas_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), paint); + builder_->DrawLine(SkPoint::Make(x0, y0), SkPoint::Make(x1, y1), paint); } void clipRect(const SkRect& rect) override { - canvas_->ClipRect(rect, DlCanvas::ClipOp::kIntersect, false); + builder_->ClipRect(rect, DlCanvas::ClipOp::kIntersect, false); } void translate(SkScalar dx, SkScalar dy) override { - canvas_->Translate(dx, dy); + builder_->Translate(dx, dy); } - void save() override { canvas_->Save(); } + void save() override { builder_->Save(); } - void restore() override { canvas_->Restore(); } + void restore() override { builder_->Restore(); } private: SkPath dashedLine(SkScalar x0, @@ -200,7 +200,7 @@ class DisplayListParagraphPainter : public skt::ParagraphPainter { paint.setPathEffect(effect); } - DlCanvas* canvas_; + DisplayListBuilder* builder_; const std::vector& dl_paints_; bool draw_path_effect_; }; @@ -291,7 +291,7 @@ void ParagraphSkia::Layout(double width) { paragraph_->layout(width); } -bool ParagraphSkia::Paint(DlCanvas* builder, double x, double y) { +bool ParagraphSkia::Paint(DisplayListBuilder* builder, double x, double y) { DisplayListParagraphPainter painter(builder, dl_paints_, impeller_enabled_); paragraph_->paint(&painter, x, y); return true; diff --git a/third_party/txt/src/skia/paragraph_skia.h b/third_party/txt/src/skia/paragraph_skia.h index 6126ac605be6d..5779445e09a71 100644 --- a/third_party/txt/src/skia/paragraph_skia.h +++ b/third_party/txt/src/skia/paragraph_skia.h @@ -54,7 +54,7 @@ class ParagraphSkia : public Paragraph { void Layout(double width) override; - bool Paint(flutter::DlCanvas* canvas, double x, double y) override; + bool Paint(flutter::DisplayListBuilder* builder, double x, double y) override; std::vector GetRectsForRange( size_t start, diff --git a/third_party/txt/src/txt/paragraph.h b/third_party/txt/src/txt/paragraph.h index 5c4e374ddc585..2bc726c9a6e19 100644 --- a/third_party/txt/src/txt/paragraph.h +++ b/third_party/txt/src/txt/paragraph.h @@ -18,7 +18,7 @@ #ifndef LIB_TXT_SRC_PARAGRAPH_H_ #define LIB_TXT_SRC_PARAGRAPH_H_ -#include "flutter/display_list/dl_canvas.h" +#include "flutter/display_list/display_list_builder.h" #include "line_metrics.h" #include "paragraph_style.h" #include "third_party/skia/include/core/SkRect.h" @@ -143,9 +143,11 @@ class Paragraph { // before Painting and getting any statistics from this class. virtual void Layout(double width) = 0; - // Paints the laid out text onto the supplied DlCanvas at + // Paints the laid out text onto the supplied DisplayListBuilder at // (x, y) offset from the origin. Only valid after Layout() is called. - virtual bool Paint(flutter::DlCanvas* canvas, double x, double y) = 0; + virtual bool Paint(flutter::DisplayListBuilder* builder, + double x, + double y) = 0; // Returns a vector of bounding boxes that enclose all text between start and // end glyph indexes, including start and excluding end. From 775477eb8e2e8335dd1eaebd0b5caaaea4f0df4e Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sat, 26 Aug 2023 20:35:01 -0700 Subject: [PATCH 16/17] Reset DEPS. --- DEPS | 4 ---- 1 file changed, 4 deletions(-) diff --git a/DEPS b/DEPS index 8408e59763ae1..f7ef0db4d0bcb 100644 --- a/DEPS +++ b/DEPS @@ -896,11 +896,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', -<<<<<<< HEAD - 'version': 'u8ovJYTk3nN78xF4XDkt21AoQvutv5bbMKVQwMUs40AC' -======= 'version': 'xYHxghcipvy5XZAK6Dhuqz6xZsL0JF6J4LKFXRUyDbgC' ->>>>>>> upstream/main } ], 'condition': 'host_os == "linux" and not download_fuchsia_sdk', From 62a75bbd15d9e7163e11f9dd2f4c4f6da1261ecb Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Sun, 27 Aug 2023 13:25:44 -0700 Subject: [PATCH 17/17] Revert licenses change due to merge. --- ci/licenses_golden/licenses_skia | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 840f15ee946d8..cbe0ded7483a0 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 2c4e89e154faa6701e9c20f1b300d13c +Signature: b6d0d7fd2120e02aee1fa651f8bae9a0 ==================================================================================================== LIBRARY: etc1 @@ -1897,6 +1897,8 @@ ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.cpp + ../../../thi ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrSurface.cpp + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/GrSurface.h + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.cpp + ../../../third_party/skia/LICENSE +ORIGIN: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.h + ../../../third_party/skia/LICENSE ORIGIN: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLProgramDataManager.cpp + ../../../third_party/skia/LICENSE @@ -2055,6 +2057,8 @@ FILE: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/GrShaderCaps.h FILE: ../../../third_party/skia/src/gpu/ganesh/GrSurface.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/GrSurface.h +FILE: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.cpp +FILE: ../../../third_party/skia/src/gpu/ganesh/effects/GrGaussianConvolutionFragmentProcessor.h FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.cpp FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLCaps.h FILE: ../../../third_party/skia/src/gpu/ganesh/gl/GrGLProgramDataManager.cpp