diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index b2e65c0317906..31747ca84b5ff 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1218,8 +1218,6 @@ FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.cc FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.h -FILE: ../../../flutter/impeller/entity/contents/solid_stroke_contents.cc -FILE: ../../../flutter/impeller/entity/contents/solid_stroke_contents.h FILE: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.cc FILE: ../../../flutter/impeller/entity/contents/sweep_gradient_contents.h FILE: ../../../flutter/impeller/entity/contents/text_contents.cc diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index cc1b17fac6720..26aadbeee8ca6 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -1497,6 +1497,101 @@ TEST_P(AiksTest, SolidStrokesRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST_P(AiksTest, GradientStrokesRenderCorrectly) { + // Compare with https://fiddle.skia.org/c/027392122bec8ac2b5d5de00a4b9bbe2 + bool first_frame = true; + auto callback = [&](AiksContext& renderer, RenderTarget& render_target) { + if (first_frame) { + first_frame = false; + ImGui::SetNextWindowSize({480, 100}); + ImGui::SetNextWindowPos({100, 550}); + } + + static float scale = 3; + static bool add_circle_clip = true; + const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"}; + const Entity::TileMode tile_modes[] = { + Entity::TileMode::kClamp, Entity::TileMode::kRepeat, + Entity::TileMode::kMirror, Entity::TileMode::kDecal}; + static int selected_tile_mode = 0; + static float alpha = 1; + + ImGui::Begin("Controls"); + ImGui::SliderFloat("Scale", &scale, 0, 6); + ImGui::Checkbox("Circle clip", &add_circle_clip); + ImGui::SliderFloat("Alpha", &alpha, 0, 1); + ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names, + sizeof(tile_mode_names) / sizeof(char*)); + ImGui::End(); + + Canvas canvas; + canvas.Scale(GetContentScale()); + Paint paint; + paint.color = Color::White(); + canvas.DrawPaint(paint); + + paint.style = Paint::Style::kStroke; + paint.color = Color(1.0, 1.0, 1.0, alpha); + paint.stroke_width = 10; + auto tile_mode = tile_modes[selected_tile_mode]; + paint.color_source = [tile_mode]() { + std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, + Color{0.1294, 0.5882, 0.9529, 1.0}}; + std::vector stops = {0.0, 1.0}; + Matrix matrix = { + 1, 0, 0, 0, // + 0, 1, 0, 0, // + 0, 0, 1, 0, // + 0, 0, 0, 1 // + }; + auto contents = std::make_shared(); + contents->SetEndPoints({0, 0}, {50, 50}); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetTileMode(tile_mode); + contents->SetMatrix(matrix); + return contents; + }; + + Path path = PathBuilder{} + .MoveTo({20, 20}) + .QuadraticCurveTo({60, 20}, {60, 60}) + .Close() + .MoveTo({60, 20}) + .QuadraticCurveTo({60, 60}, {20, 60}) + .TakePath(); + + canvas.Scale(Vector2(scale, scale)); + + if (add_circle_clip) { + auto [handle_a, handle_b] = IMPELLER_PLAYGROUND_LINE( + Point(60, 300), Point(600, 300), 20, Color::Red(), Color::Red()); + + auto screen_to_canvas = canvas.GetCurrentTransformation().Invert(); + Point point_a = screen_to_canvas * handle_a * GetContentScale(); + Point point_b = screen_to_canvas * handle_b * GetContentScale(); + + Point middle = (point_a + point_b) / 2; + auto radius = point_a.GetDistance(middle); + canvas.ClipPath(PathBuilder{}.AddCircle(middle, radius).TakePath()); + } + + for (auto join : {Join::kBevel, Join::kRound, Join::kMiter}) { + paint.stroke_join = join; + for (auto cap : {Cap::kButt, Cap::kSquare, Cap::kRound}) { + paint.stroke_cap = cap; + canvas.DrawPath(path, paint); + canvas.Translate({80, 0}); + } + canvas.Translate({-240, 60}); + } + + return renderer.Render(canvas.EndRecordingAsPicture(), render_target); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) { auto callback = [&](AiksContext& renderer, RenderTarget& render_target) { Canvas canvas; diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index d5982a521c502..c55edb70df72d 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -355,16 +355,26 @@ void Canvas::DrawTextFrame(TextFrame text_frame, Point position, Paint paint) { void Canvas::DrawVertices(Vertices vertices, BlendMode blend_mode, Paint paint) { - std::shared_ptr contents = - std::make_shared(); - contents->SetColor(paint.color); - contents->SetBlendMode(blend_mode); - contents->SetGeometry(Geometry::MakeVertices(std::move(vertices))); + auto geometry = Geometry::MakeVertices(std::move(vertices)); + Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); - entity.SetContents(paint.WithFilters(std::move(contents), true)); + + if (paint.color_source.has_value()) { + auto& source = paint.color_source.value(); + auto contents = source(); + contents->SetGeometry(std::move(geometry)); + contents->SetAlpha(paint.color.alpha); + entity.SetContents(paint.WithFilters(std::move(contents), true)); + } else { + std::shared_ptr contents = + std::make_shared(); + contents->SetColor(paint.color); + contents->SetBlendMode(blend_mode); + entity.SetContents(paint.WithFilters(std::move(contents), true)); + } GetCurrentPass().AddEntity(std::move(entity)); } diff --git a/impeller/aiks/paint.cc b/impeller/aiks/paint.cc index 7f7788f3d73da..e413266256403 100644 --- a/impeller/aiks/paint.cc +++ b/impeller/aiks/paint.cc @@ -4,41 +4,37 @@ #include "impeller/aiks/paint.h" #include "impeller/entity/contents/solid_color_contents.h" -#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/geometry.h" namespace impeller { std::shared_ptr Paint::CreateContentsForEntity(Path path, bool cover) const { + std::unique_ptr geometry; + switch (style) { + case Style::kFill: + geometry = cover ? Geometry::MakeCover() + : Geometry::MakeFillPath(std::move(path)); + break; + case Style::kStroke: + geometry = cover ? Geometry::MakeCover() + : Geometry::MakeStrokePath(std::move(path), stroke_width, + stroke_miter, stroke_cap, + stroke_join); + break; + } + if (color_source.has_value()) { auto& source = color_source.value(); auto contents = source(); - contents->SetGeometry(cover ? Geometry::MakeCover() - : Geometry::MakeFillPath(std::move(path))); + contents->SetGeometry(std::move(geometry)); contents->SetAlpha(color.alpha); return contents; } - - switch (style) { - case Style::kFill: { - auto solid_color = std::make_shared(); - solid_color->SetGeometry(cover ? Geometry::MakeCover() - : Geometry::MakeFillPath(std::move(path))); - solid_color->SetColor(color); - return solid_color; - } - case Style::kStroke: { - auto solid_stroke = std::make_shared(); - solid_stroke->SetGeometry( - Geometry::MakeStrokePath(std::move(path), stroke_width, stroke_miter, - stroke_cap, stroke_join)); - solid_stroke->SetColor(color); - return solid_stroke; - } - } - - return nullptr; + auto solid_color = std::make_shared(); + solid_color->SetGeometry(std::move(geometry)); + solid_color->SetColor(color); + return solid_color; } std::shared_ptr Paint::WithFilters( diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h index 025eb9a7213bd..7a9f0b55bf2ba 100644 --- a/impeller/aiks/paint.h +++ b/impeller/aiks/paint.h @@ -12,7 +12,6 @@ #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/linear_gradient_contents.h" #include "impeller/entity/contents/radial_gradient_contents.h" -#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/contents/sweep_gradient_contents.h" #include "impeller/entity/entity.h" #include "impeller/entity/geometry.h" diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 83b26c381b867..adca2ab0057cf 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -25,7 +25,6 @@ #include "impeller/entity/contents/linear_gradient_contents.h" #include "impeller/entity/contents/radial_gradient_contents.h" #include "impeller/entity/contents/runtime_effect_contents.h" -#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/contents/sweep_gradient_contents.h" #include "impeller/entity/contents/tiled_texture_contents.h" #include "impeller/entity/entity.h" diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 3c6c42e07c09e..821d8e12ad78c 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -118,8 +118,6 @@ impeller_component("entity") { "contents/runtime_effect_contents.h", "contents/solid_color_contents.cc", "contents/solid_color_contents.h", - "contents/solid_stroke_contents.cc", - "contents/solid_stroke_contents.h", "contents/sweep_gradient_contents.cc", "contents/sweep_gradient_contents.h", "contents/text_contents.cc", diff --git a/impeller/entity/contents/linear_gradient_contents.cc b/impeller/entity/contents/linear_gradient_contents.cc index 59d52b02dd712..0c1488383d8c3 100644 --- a/impeller/entity/contents/linear_gradient_contents.cc +++ b/impeller/entity/contents/linear_gradient_contents.cc @@ -5,6 +5,7 @@ #include "linear_gradient_contents.h" #include "flutter/fml/logging.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" #include "impeller/entity/entity.h" @@ -72,13 +73,17 @@ bool LinearGradientContents::Render(const ContentContext& renderer, Command cmd; cmd.label = "LinearGradientFill"; - cmd.pipeline = renderer.GetLinearGradientFillPipeline( - OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + cmd.pipeline = renderer.GetLinearGradientFillPipeline(options); + cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( @@ -90,7 +95,15 @@ bool LinearGradientContents::Render(const ContentContext& renderer, cmd, std::move(gradient_texture), renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); - return pass.AddCommand(std::move(cmd)); + + if (!pass.AddCommand(std::move(cmd))) { + return false; + } + + if (geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } + return true; } } // namespace impeller diff --git a/impeller/entity/contents/radial_gradient_contents.cc b/impeller/entity/contents/radial_gradient_contents.cc index 84f809e301d80..f5528a7330813 100644 --- a/impeller/entity/contents/radial_gradient_contents.cc +++ b/impeller/entity/contents/radial_gradient_contents.cc @@ -5,6 +5,7 @@ #include "radial_gradient_contents.h" #include "flutter/fml/logging.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" #include "impeller/entity/entity.h" @@ -72,13 +73,17 @@ bool RadialGradientContents::Render(const ContentContext& renderer, Command cmd; cmd.label = "RadialGradientFill"; - cmd.pipeline = renderer.GetRadialGradientFillPipeline( - OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + cmd.pipeline = renderer.GetRadialGradientFillPipeline(options); + cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( @@ -90,7 +95,15 @@ bool RadialGradientContents::Render(const ContentContext& renderer, cmd, gradient_texture, renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); VS::BindFrameInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); - return pass.AddCommand(std::move(cmd)); + + if (!pass.AddCommand(std::move(cmd))) { + return false; + } + + if (geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } + return true; } } // namespace impeller diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 4a01fe1456468..b78f365feaf77 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -4,6 +4,7 @@ #include "solid_color_contents.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" #include "impeller/geometry/path.h" @@ -55,11 +56,17 @@ bool SolidColorContents::Render(const ContentContext& renderer, Command cmd; cmd.label = "Solid Fill"; - cmd.pipeline = - renderer.GetSolidFillPipeline(OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass); + + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + + cmd.pipeline = renderer.GetSolidFillPipeline(options); cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; @@ -76,6 +83,9 @@ bool SolidColorContents::Render(const ContentContext& renderer, return false; } + if (geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } return true; } diff --git a/impeller/entity/contents/solid_stroke_contents.cc b/impeller/entity/contents/solid_stroke_contents.cc deleted file mode 100644 index 1707c07bee5f9..0000000000000 --- a/impeller/entity/contents/solid_stroke_contents.cc +++ /dev/null @@ -1,82 +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 "solid_stroke_contents.h" - -#include - -#include "impeller/entity/contents/clip_contents.h" -#include "impeller/entity/contents/content_context.h" -#include "impeller/entity/entity.h" -#include "impeller/entity/solid_fill.frag.h" -#include "impeller/entity/solid_fill.vert.h" -#include "impeller/geometry/path_builder.h" -#include "impeller/renderer/render_pass.h" - -namespace impeller { - -SolidStrokeContents::SolidStrokeContents(){}; - -SolidStrokeContents::~SolidStrokeContents() = default; - -void SolidStrokeContents::SetColor(Color color) { - color_ = color; -} - -const Color& SolidStrokeContents::GetColor() const { - return color_; -} - -void SolidStrokeContents::SetGeometry(std::unique_ptr geometry) { - geometry_ = std::move(geometry); -} - -std::optional SolidStrokeContents::GetCoverage( - const Entity& entity) const { - if (color_.IsTransparent()) { - return std::nullopt; - } - return geometry_->GetCoverage(entity.GetTransformation()); -} - -bool SolidStrokeContents::Render(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const { - using VS = SolidFillVertexShader; - using FS = SolidFillFragmentShader; - VS::VertInfo vert_info; - vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); - - FS::FragInfo frag_info; - frag_info.color = color_.Premultiply(); - - Command cmd; - cmd.label = "Solid Stroke"; - cmd.stencil_reference = entity.GetStencilDepth(); - - auto geometry_result = geometry_->GetPositionBuffer(renderer, entity, pass); - - auto options = OptionsFromPassAndEntity(pass, entity); - if (geometry_result.prevent_overdraw) { - options.stencil_compare = CompareFunction::kEqual; - options.stencil_operation = StencilOperation::kIncrementClamp; - } - cmd.pipeline = renderer.GetSolidFillPipeline(options); - - cmd.BindVertices(geometry_result.vertex_buffer); - cmd.primitive_type = geometry_result.type; - VS::BindVertInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(vert_info)); - FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); - - pass.AddCommand(cmd); - - if (geometry_result.prevent_overdraw) { - return ClipRestoreContents().Render(renderer, entity, pass); - } - - return true; -} - -} // namespace impeller diff --git a/impeller/entity/contents/solid_stroke_contents.h b/impeller/entity/contents/solid_stroke_contents.h deleted file mode 100644 index ac341965c398b..0000000000000 --- a/impeller/entity/contents/solid_stroke_contents.h +++ /dev/null @@ -1,48 +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 -#include - -#include "flutter/fml/macros.h" -#include "impeller/entity/contents/content_context.h" -#include "impeller/entity/contents/contents.h" -#include "impeller/entity/geometry.h" -#include "impeller/geometry/color.h" -#include "impeller/geometry/path_component.h" -#include "impeller/geometry/point.h" - -namespace impeller { - -class SolidStrokeContents final : public Contents { - public: - SolidStrokeContents(); - - ~SolidStrokeContents() override; - - void SetGeometry(std::unique_ptr geometry); - - void SetColor(Color color); - - const Color& GetColor() const; - - // |Contents| - std::optional GetCoverage(const Entity& entity) const override; - - // |Contents| - bool Render(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const override; - - private: - std::unique_ptr geometry_; - Color color_; - - FML_DISALLOW_COPY_AND_ASSIGN(SolidStrokeContents); -}; - -} // namespace impeller diff --git a/impeller/entity/contents/sweep_gradient_contents.cc b/impeller/entity/contents/sweep_gradient_contents.cc index e5f2c756265bf..c225a6ac9dd5a 100644 --- a/impeller/entity/contents/sweep_gradient_contents.cc +++ b/impeller/entity/contents/sweep_gradient_contents.cc @@ -5,6 +5,7 @@ #include "sweep_gradient_contents.h" #include "flutter/fml/logging.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/contents/gradient_generator.h" #include "impeller/entity/entity.h" @@ -78,13 +79,17 @@ bool SweepGradientContents::Render(const ContentContext& renderer, Command cmd; cmd.label = "SweepGradientFill"; - cmd.pipeline = renderer.GetSweepGradientFillPipeline( - OptionsFromPassAndEntity(pass, entity)); cmd.stencil_reference = entity.GetStencilDepth(); - - auto allocator = renderer.GetContext()->GetResourceAllocator(); auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); + + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + cmd.pipeline = renderer.GetSweepGradientFillPipeline(options); + cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; FS::BindGradientInfo( @@ -96,7 +101,15 @@ bool SweepGradientContents::Render(const ContentContext& renderer, FS::BindTextureSampler( cmd, gradient_texture, renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc)); - return pass.AddCommand(std::move(cmd)); + + if (!pass.AddCommand(std::move(cmd))) { + return false; + } + + if (geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } + return true; } } // namespace impeller diff --git a/impeller/entity/contents/tiled_texture_contents.cc b/impeller/entity/contents/tiled_texture_contents.cc index abc7b2cb609a4..0bf7566055a20 100644 --- a/impeller/entity/contents/tiled_texture_contents.cc +++ b/impeller/entity/contents/tiled_texture_contents.cc @@ -4,6 +4,7 @@ #include "impeller/entity/contents/tiled_texture_contents.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/geometry.h" #include "impeller/entity/tiled_texture_fill.frag.h" @@ -70,6 +71,14 @@ bool TiledTextureContents::Render(const ContentContext& renderer, auto geometry_result = GetGeometry()->GetPositionBuffer(renderer, entity, pass); + + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + cmd.pipeline = renderer.GetTiledTexturePipeline(options); + cmd.BindVertices(geometry_result.vertex_buffer); cmd.primitive_type = geometry_result.type; VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); @@ -77,8 +86,14 @@ bool TiledTextureContents::Render(const ContentContext& renderer, FS::BindTextureSampler(cmd, texture_, renderer.GetContext()->GetSamplerLibrary()->GetSampler( sampler_descriptor_)); - pass.AddCommand(std::move(cmd)); + if (!pass.AddCommand(std::move(cmd))) { + return false; + } + + if (geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } return true; } diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index debae6cbce813..92578db0409a7 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -20,10 +20,10 @@ #include "impeller/entity/contents/filters/color_filter_contents.h" #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/filters/inputs/filter_input.h" +#include "impeller/entity/contents/linear_gradient_contents.h" #include "impeller/entity/contents/rrect_shadow_contents.h" #include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/contents/solid_color_contents.h" -#include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/contents/text_contents.h" #include "impeller/entity/contents/texture_contents.h" #include "impeller/entity/contents/vertices_contents.h" @@ -199,7 +199,7 @@ TEST_P(EntityTest, ThreeStrokesInOnePath) { Entity entity; entity.SetTransformation(Matrix::MakeScale(GetContentScale())); - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry(Geometry::MakeStrokePath(std::move(path), 5.0)); contents->SetColor(Color::Red()); entity.SetContents(std::move(contents)); @@ -238,7 +238,7 @@ TEST_P(EntityTest, TriangleInsideASquare) { Entity entity; entity.SetTransformation(Matrix::MakeScale(GetContentScale())); - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry(Geometry::MakeStrokePath(std::move(path), 20.0)); contents->SetColor(Color::Red()); entity.SetContents(std::move(contents)); @@ -281,7 +281,7 @@ TEST_P(EntityTest, StrokeCapAndJoinTest) { auto world_matrix = Matrix::MakeScale(GetContentScale()); auto render_path = [width = width, &context, &pass, &world_matrix]( Path path, Cap cap, Join join) { - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry( Geometry::MakeStrokePath(path, width, miter_limit, cap, join)); contents->SetColor(Color::Red()); @@ -628,7 +628,7 @@ TEST_P(EntityTest, CubicCurveAndOverlapTest) { ASSERT_TRUE(OpenPlaygroundHere(entity)); } -TEST_P(EntityTest, SolidStrokeContentsSetStrokeCapsAndJoins) { +TEST_P(EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins) { { auto geometry = Geometry::MakeStrokePath(Path{}); auto path_geometry = static_cast(geometry.get()); @@ -650,7 +650,7 @@ TEST_P(EntityTest, SolidStrokeContentsSetStrokeCapsAndJoins) { } } -TEST_P(EntityTest, SolidStrokeContentsSetMiterLimit) { +TEST_P(EntityTest, SolidColorContentsStrokeSetMiterLimit) { { auto geometry = Geometry::MakeStrokePath(Path{}); auto path_geometry = static_cast(geometry.get()); @@ -1146,7 +1146,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { Cap::kButt, Join::kBevel); Entity entity; - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry(std::move(geometry)); contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); @@ -1163,7 +1163,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { Cap::kSquare, Join::kBevel); Entity entity; - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry(std::move(geometry)); contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); @@ -1181,7 +1181,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { Cap::kSquare, Join::kMiter); Entity entity; - auto contents = std::make_unique(); + auto contents = std::make_unique(); contents->SetGeometry(std::move(geometry)); contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); @@ -1240,6 +1240,37 @@ TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndices) { ASSERT_TRUE(OpenPlaygroundHere(e)); } +TEST_P(EntityTest, DrawVerticesLinearGradientWithoutIndices) { + std::vector positions = {Point(100, 300), Point(200, 100), + Point(300, 300)}; + + Vertices vertices = Vertices(positions, {} /* indices */, {} /* colors */, + VertexMode::kTriangle, Rect(100, 100, 300, 300)); + + std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, + Color{0.1294, 0.5882, 0.9529, 1.0}}; + std::vector stops = {0.0, 1.0}; + Matrix matrix = { + 1, 0, 0, 0, // + 0, 1, 0, 0, // + 0, 0, 1, 0, // + 0, 0, 0, 1 // + }; + auto contents = std::make_shared(); + contents->SetEndPoints({100, 100}, {300, 300}); + contents->SetColors(std::move(colors)); + contents->SetStops(std::move(stops)); + contents->SetTileMode(Entity::TileMode::kRepeat); + contents->SetMatrix(matrix); + contents->SetGeometry(Geometry::MakeVertices(vertices)); + + Entity e; + e.SetTransformation(Matrix::MakeScale(GetContentScale())); + e.SetContents(contents); + + ASSERT_TRUE(OpenPlaygroundHere(e)); +} + TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithIndices) { std::vector positions = {Point(100, 300), Point(200, 100), Point(300, 300), Point(200, 500)};