From 0082b6d75f3a44ea8e791e64b8ec87930f01b46d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 14 Jun 2022 17:36:43 -0700 Subject: [PATCH 1/2] Make transparent fills have no coverage --- .../entity/contents/solid_color_contents.cc | 3 ++ impeller/entity/entity_unittests.cc | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index 0fe07b756c73a..efa95b711d295 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -35,6 +35,9 @@ void SolidColorContents::SetCover(bool cover) { std::optional SolidColorContents::GetCoverage( const Entity& entity) const { + if (color_.IsTransparent()) { + return std::nullopt; + } return path_.GetTransformedBoundingBox(entity.GetTransformation()); }; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 1517bbd486fa2..b253673905862 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -983,5 +983,47 @@ TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndex) { ASSERT_TRUE(OpenPlaygroundHere(e)); } +TEST_P(EntityTest, SolidFillCoverageIsCorrect) { + // No transform + { + auto fill = std::make_shared(); + fill->SetColor(Color::CornflowerBlue()); + auto expected = Rect::MakeLTRB(100, 110, 200, 220); + fill->SetPath(PathBuilder{}.AddRect(expected).TakePath()); + + auto coverage = fill->GetCoverage({}); + ASSERT_TRUE(coverage.has_value()); + ASSERT_RECT_NEAR(coverage.value(), expected); + } + + // Entity transform + { + auto fill = std::make_shared(); + fill->SetColor(Color::CornflowerBlue()); + fill->SetPath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + + Entity entity; + entity.SetTransformation(Matrix::MakeTranslation(Vector2(4, 5))); + entity.SetContents(std::move(fill)); + + auto coverage = entity.GetCoverage(); + auto expected = Rect::MakeLTRB(104, 115, 204, 225); + ASSERT_TRUE(coverage.has_value()); + ASSERT_RECT_NEAR(coverage.value(), expected); + } + + // No coverage for fully transparent colors + { + auto fill = std::make_shared(); + fill->SetColor(Color::WhiteTransparent()); + fill->SetPath( + PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()); + + auto coverage = fill->GetCoverage({}); + ASSERT_FALSE(coverage.has_value()); + } +} + } // namespace testing } // namespace impeller From 3e0d9cca6e427985feddc7c3cf267a14220d16e4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 15 Jun 2022 10:39:18 -0700 Subject: [PATCH 2/2] Don't skip transparent draw calls --- impeller/entity/contents/solid_color_contents.cc | 4 ---- impeller/entity/contents/solid_stroke_contents.cc | 6 +++++- impeller/entity/contents/texture_contents.cc | 5 +++++ impeller/entity/entity_unittests.cc | 3 +++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/impeller/entity/contents/solid_color_contents.cc b/impeller/entity/contents/solid_color_contents.cc index efa95b711d295..b0009af71890b 100644 --- a/impeller/entity/contents/solid_color_contents.cc +++ b/impeller/entity/contents/solid_color_contents.cc @@ -63,10 +63,6 @@ VertexBuffer SolidColorContents::CreateSolidFillVertices(const Path& path, bool SolidColorContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (color_.IsTransparent()) { - return true; - } - using VS = SolidFillPipeline::VertexShader; Command cmd; diff --git a/impeller/entity/contents/solid_stroke_contents.cc b/impeller/entity/contents/solid_stroke_contents.cc index 20a76652bf276..201f7ad6cd722 100644 --- a/impeller/entity/contents/solid_stroke_contents.cc +++ b/impeller/entity/contents/solid_stroke_contents.cc @@ -35,6 +35,10 @@ void SolidStrokeContents::SetPath(Path path) { std::optional SolidStrokeContents::GetCoverage( const Entity& entity) const { + if (color_.IsTransparent()) { + return std::nullopt; + } + auto path_bounds = path_.GetBoundingBox(); if (!path_bounds.has_value()) { return std::nullopt; @@ -173,7 +177,7 @@ static VertexBuffer CreateSolidStrokeVertices( bool SolidStrokeContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (color_.IsTransparent() || stroke_size_ <= 0.0) { + if (stroke_size_ <= 0.0) { return true; } diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc index 560ab9a89584d..cc9b883870fe6 100644 --- a/impeller/entity/contents/texture_contents.cc +++ b/impeller/entity/contents/texture_contents.cc @@ -4,6 +4,8 @@ #include "texture_contents.h" +#include + #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" #include "impeller/entity/texture_fill.frag.h" @@ -35,6 +37,9 @@ void TextureContents::SetOpacity(Scalar opacity) { } std::optional TextureContents::GetCoverage(const Entity& entity) const { + if (opacity_ == 0) { + return std::nullopt; + } return path_.GetTransformedBoundingBox(entity.GetTransformation()); }; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index b253673905862..a0bbc3d7811b0 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -897,6 +897,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeCap(SolidStrokeContents::Cap::kButt); contents->SetStrokeJoin(SolidStrokeContents::Join::kBevel); contents->SetStrokeSize(4); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = Rect::MakeLTRB(-2, -2, 12, 12); @@ -912,6 +913,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeCap(SolidStrokeContents::Cap::kSquare); contents->SetStrokeJoin(SolidStrokeContents::Join::kBevel); contents->SetStrokeSize(4); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = @@ -929,6 +931,7 @@ TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) { contents->SetStrokeJoin(SolidStrokeContents::Join::kMiter); contents->SetStrokeSize(4); contents->SetStrokeMiter(2); + contents->SetColor(Color::Black()); entity.SetContents(std::move(contents)); auto actual = entity.GetCoverage(); auto expected = Rect::MakeLTRB(-4, -4, 14, 14);