Skip to content

Commit

Permalink
[Impeller] Make transparent fills have no coverage (flutter#34055)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdero authored Jun 15, 2022
1 parent fb80e86 commit 1edc350
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
7 changes: 3 additions & 4 deletions impeller/entity/contents/solid_color_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ void SolidColorContents::SetCover(bool cover) {

std::optional<Rect> SolidColorContents::GetCoverage(
const Entity& entity) const {
if (color_.IsTransparent()) {
return std::nullopt;
}
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};

Expand All @@ -60,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;
Expand Down
6 changes: 5 additions & 1 deletion impeller/entity/contents/solid_stroke_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ void SolidStrokeContents::SetPath(Path path) {

std::optional<Rect> 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;
Expand Down Expand Up @@ -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;
}

Expand Down
5 changes: 5 additions & 0 deletions impeller/entity/contents/texture_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "texture_contents.h"

#include <optional>

#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/texture_fill.frag.h"
Expand Down Expand Up @@ -35,6 +37,9 @@ void TextureContents::SetOpacity(Scalar opacity) {
}

std::optional<Rect> TextureContents::GetCoverage(const Entity& entity) const {
if (opacity_ == 0) {
return std::nullopt;
}
return path_.GetTransformedBoundingBox(entity.GetTransformation());
};

Expand Down
45 changes: 45 additions & 0 deletions impeller/entity/entity_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,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);
Expand All @@ -940,6 +941,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 =
Expand All @@ -957,6 +959,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);
Expand Down Expand Up @@ -1011,5 +1014,47 @@ TEST_P(EntityTest, DrawVerticesSolidColorTrianglesWithoutIndex) {
ASSERT_TRUE(OpenPlaygroundHere(e));
}

TEST_P(EntityTest, SolidFillCoverageIsCorrect) {
// No transform
{
auto fill = std::make_shared<SolidColorContents>();
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<SolidColorContents>();
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<SolidColorContents>();
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

0 comments on commit 1edc350

Please sign in to comment.