[Impeller] Make transparent fills have no coverage (flutter/engine#34055)

This commit is contained in:
Brandon DeRosier 2022-06-15 12:23:06 -07:00 committed by GitHub
parent 7a50e60ae6
commit 0e64722d2a
4 changed files with 58 additions and 5 deletions

View File

@ -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());
};
@ -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;

View File

@ -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;
@ -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;
}

View File

@ -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"
@ -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());
};

View File

@ -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);
@ -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 =
@ -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);
@ -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