Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion impeller/aiks/aiks_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,9 @@ TEST_P(AiksTest, OpaqueEntitiesGetCoercedToSource) {
return true;
});

Matrix matrix;
ASSERT_TRUE(entity.size() >= 1);
ASSERT_TRUE(contents->IsOpaque());
ASSERT_TRUE(contents->IsOpaque(matrix));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super minor nit: Just IsOpaque({})?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource);
}

Expand Down
2 changes: 1 addition & 1 deletion impeller/aiks/experimental_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ void ExperimentalCanvas::AddRenderEntityToCurrentPass(Entity entity,
entity.GetTransform());
entity.SetInheritedOpacity(transform_stack_.back().distributed_opacity);
if (entity.GetBlendMode() == BlendMode::kSourceOver &&
entity.GetContents()->IsOpaque()) {
entity.GetContents()->IsOpaque(entity.GetTransform())) {
entity.SetBlendMode(BlendMode::kSource);
}

Expand Down
5 changes: 5 additions & 0 deletions impeller/entity/contents/color_source_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,9 @@ void ColorSourceContents::SetInheritedOpacity(Scalar opacity) {
inherited_opacity_ = opacity;
}

bool ColorSourceContents::AppliesAlphaForStrokeCoverage(
const Matrix& transform) const {
return GetGeometry() && GetGeometry()->ComputeAlphaCoverage(transform) < 1.0;
}

} // namespace impeller
4 changes: 4 additions & 0 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ class ColorSourceContents : public Contents {
return geom.GetPositionBuffer(renderer, entity, pass);
}

/// @brief Whether the entity should be treated as non-opaque due to stroke
/// geometry requiring alpha for coverage.
bool AppliesAlphaForStrokeCoverage(const Matrix& transform) const;

template <typename VertexShaderT>
bool DrawGeometry(const ContentContext& renderer,
const Entity& entity,
Expand Down
6 changes: 4 additions & 2 deletions impeller/entity/contents/conical_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
if (focus_) {
frag_info.focus = focus_.value();
frag_info.focus_radius = focus_radius_;
Expand Down Expand Up @@ -137,7 +138,8 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.texture_sampler_y_coord_scale =
gradient_texture->GetYCoordScale();
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
frag_info.half_texel =
Vector2(0.5 / gradient_texture->GetSize().width,
0.5 / gradient_texture->GetSize().height);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Contents::Contents() = default;

Contents::~Contents() = default;

bool Contents::IsOpaque() const {
bool Contents::IsOpaque(const Matrix& transform) const {
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion impeller/entity/contents/contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ class Contents {
/// properties (e.g. the blend mode), clips/visibility culling, or
/// inherited opacity.
///
virtual bool IsOpaque() const;
/// @param transform The current transform matrix of the entity that will
/// render this contents.
virtual bool IsOpaque(const Matrix& transform) const;

//----------------------------------------------------------------------------
/// @brief Given the current pass space bounding rectangle of the clip
Expand Down
13 changes: 8 additions & 5 deletions impeller/entity/contents/linear_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void LinearGradientContents::SetTileMode(Entity::TileMode tile_mode) {
tile_mode_ = tile_mode;
}

bool LinearGradientContents::IsOpaque() const {
bool LinearGradientContents::IsOpaque(const Matrix& transform) const {
if (GetOpacityFactor() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
return false;
}
Expand All @@ -53,7 +53,7 @@ bool LinearGradientContents::IsOpaque() const {
return false;
}
}
return true;
return !AppliesAlphaForStrokeCoverage(transform);
}

bool LinearGradientContents::CanApplyFastGradient() const {
Expand Down Expand Up @@ -176,7 +176,8 @@ bool LinearGradientContents::FastLinearGradient(const ContentContext& renderer,

FS::FragInfo frag_info;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());

FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));

Expand Down Expand Up @@ -231,7 +232,8 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.texture_sampler_y_coord_scale =
gradient_texture->GetYCoordScale();
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
;
frag_info.half_texel =
Vector2(0.5 / gradient_texture->GetSize().width,
Expand Down Expand Up @@ -284,7 +286,8 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
frag_info.start_to_end = end_point_ - start_point_;
frag_info.inverse_dot_start_to_end =
CalculateInverseDotStartToEnd(start_point_, end_point_);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/linear_gradient_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class LinearGradientContents final : public ColorSourceContents {
~LinearGradientContents() override;

// |Contents|
bool IsOpaque() const override;
bool IsOpaque(const Matrix& transform) const override;

// |Contents|
bool Render(const ContentContext& renderer,
Expand Down
10 changes: 6 additions & 4 deletions impeller/entity/contents/radial_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const std::vector<Scalar>& RadialGradientContents::GetStops() const {
return stops_;
}

bool RadialGradientContents::IsOpaque() const {
bool RadialGradientContents::IsOpaque(const Matrix& transform) const {
if (GetOpacityFactor() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
return false;
}
Expand All @@ -52,7 +52,7 @@ bool RadialGradientContents::IsOpaque() const {
return false;
}
}
return true;
return !AppliesAlphaForStrokeCoverage(transform);
}

bool RadialGradientContents::Render(const ContentContext& renderer,
Expand Down Expand Up @@ -86,7 +86,8 @@ bool RadialGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());

auto& host_buffer = renderer.GetTransientsBuffer();
auto colors = CreateGradientColors(colors_, stops_);
Expand Down Expand Up @@ -136,7 +137,8 @@ bool RadialGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.texture_sampler_y_coord_scale =
gradient_texture->GetYCoordScale();
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
frag_info.half_texel =
Vector2(0.5 / gradient_texture->GetSize().width,
0.5 / gradient_texture->GetSize().height);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/radial_gradient_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class RadialGradientContents final : public ColorSourceContents {
~RadialGradientContents() override;

// |Contents|
bool IsOpaque() const override;
bool IsOpaque(const Matrix& transform) const override;

// |Contents|
bool Render(const ContentContext& renderer,
Expand Down
8 changes: 4 additions & 4 deletions impeller/entity/contents/solid_color_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ bool SolidColorContents::IsSolidColor() const {
return true;
}

bool SolidColorContents::IsOpaque() const {
return GetColor().IsOpaque();
bool SolidColorContents::IsOpaque(const Matrix& transform) const {
return GetColor().IsOpaque() && !AppliesAlphaForStrokeCoverage(transform);
}

std::optional<Rect> SolidColorContents::GetCoverage(
Expand All @@ -54,8 +54,8 @@ bool SolidColorContents::Render(const ContentContext& renderer,

VS::FrameInfo frame_info;
FS::FragInfo frag_info;
frag_info.color =
GetColor().Premultiply() * GetGeometry()->ComputeAlphaCoverage(entity);
frag_info.color = GetColor().Premultiply() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());

PipelineBuilderCallback pipeline_callback =
[&renderer](ContentContextOptions options) {
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/solid_color_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SolidColorContents final : public ColorSourceContents {
bool IsSolidColor() const override;

// |Contents|
bool IsOpaque() const override;
bool IsOpaque(const Matrix& transform) const override;

// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
Expand Down
10 changes: 6 additions & 4 deletions impeller/entity/contents/sweep_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const std::vector<Scalar>& SweepGradientContents::GetStops() const {
return stops_;
}

bool SweepGradientContents::IsOpaque() const {
bool SweepGradientContents::IsOpaque(const Matrix& transform) const {
if (GetOpacityFactor() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
return false;
}
Expand All @@ -58,7 +58,7 @@ bool SweepGradientContents::IsOpaque() const {
return false;
}
}
return true;
return !AppliesAlphaForStrokeCoverage(transform);
}

bool SweepGradientContents::Render(const ContentContext& renderer,
Expand Down Expand Up @@ -95,7 +95,8 @@ bool SweepGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());

auto& host_buffer = renderer.GetTransientsBuffer();
auto colors = CreateGradientColors(colors_, stops_);
Expand Down Expand Up @@ -147,7 +148,8 @@ bool SweepGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
frag_info.half_texel =
Vector2(0.5 / gradient_texture->GetSize().width,
0.5 / gradient_texture->GetSize().height);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/sweep_gradient_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class SweepGradientContents final : public ColorSourceContents {
~SweepGradientContents() override;

// |Contents|
bool IsOpaque() const override;
bool IsOpaque(const Matrix& transform) const override;

// |Contents|
bool Render(const ContentContext& renderer,
Expand Down
10 changes: 6 additions & 4 deletions impeller/entity/contents/tiled_texture_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ bool TiledTextureContents::UsesEmulatedTileMode(
}

// |Contents|
bool TiledTextureContents::IsOpaque() const {
bool TiledTextureContents::IsOpaque(const Matrix& transform) const {
if (GetOpacityFactor() < 1 || x_tile_mode_ == Entity::TileMode::kDecal ||
y_tile_mode_ == Entity::TileMode::kDecal) {
return false;
}
if (color_filter_) {
return false;
}
return texture_->IsOpaque();
return texture_->IsOpaque() && !AppliesAlphaForStrokeCoverage(transform);
}

bool TiledTextureContents::Render(const ContentContext& renderer,
Expand Down Expand Up @@ -160,14 +160,16 @@ bool TiledTextureContents::Render(const ContentContext& renderer,
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
FSExternal::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
} else {
FS::FragInfo frag_info;
frag_info.x_tile_mode = static_cast<Scalar>(x_tile_mode_);
frag_info.y_tile_mode = static_cast<Scalar>(y_tile_mode_);
frag_info.alpha =
GetOpacityFactor() * GetGeometry()->ComputeAlphaCoverage(entity);
GetOpacityFactor() *
GetGeometry()->ComputeAlphaCoverage(entity.GetTransform());
FS::BindFragInfo(pass, host_buffer.EmplaceUniform(frag_info));
}

Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/contents/tiled_texture_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class TiledTextureContents final : public ColorSourceContents {
std::function<std::shared_ptr<ColorFilterContents>(FilterInput::Ref)>;

// |Contents|
bool IsOpaque() const override;
bool IsOpaque(const Matrix& transform) const override;

// |Contents|
bool Render(const ContentContext& renderer,
Expand Down
6 changes: 4 additions & 2 deletions impeller/entity/entity.cc
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ bool Entity::CanInheritOpacity() const {
if (!contents_) {
return false;
}
if (!((blend_mode_ == BlendMode::kSource && contents_->IsOpaque()) ||
if (!((blend_mode_ == BlendMode::kSource &&
contents_->IsOpaque(GetTransform())) ||
blend_mode_ == BlendMode::kSourceOver)) {
return false;
}
Expand All @@ -137,7 +138,8 @@ bool Entity::SetInheritedOpacity(Scalar alpha) {
if (!CanInheritOpacity()) {
return false;
}
if (blend_mode_ == BlendMode::kSource && contents_->IsOpaque()) {
if (blend_mode_ == BlendMode::kSource &&
contents_->IsOpaque(GetTransform())) {
blend_mode_ = BlendMode::kSourceOver;
}
contents_->SetInheritedOpacity(alpha);
Expand Down
2 changes: 1 addition & 1 deletion impeller/entity/entity_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ bool EntityPass::GetBoundsLimitIsSnug() const {

void EntityPass::AddEntity(Entity entity) {
if (entity.GetBlendMode() == BlendMode::kSourceOver &&
entity.GetContents()->IsOpaque()) {
entity.GetContents()->IsOpaque(entity.GetTransform())) {
entity.SetBlendMode(BlendMode::kSource);
}

Expand Down
Loading