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 all 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
14 changes: 7 additions & 7 deletions impeller/aiks/color_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ColorSource ColorSource::MakeLinearGradient(Point start_point,
stops = std::move(stops), tile_mode,
effect_transform](const Paint& paint) {
auto contents = std::make_shared<LinearGradientContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetColors(colors);
contents->SetStops(stops);
contents->SetEndPoints(start_point, end_point);
Expand Down Expand Up @@ -82,7 +82,7 @@ ColorSource ColorSource::MakeConicalGradient(Point center,
tile_mode, effect_transform](const Paint& paint) {
std::shared_ptr<ConicalGradientContents> contents =
std::make_shared<ConicalGradientContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetColors(colors);
contents->SetStops(stops);
contents->SetCenterAndRadius(center, radius);
Expand Down Expand Up @@ -113,7 +113,7 @@ ColorSource ColorSource::MakeRadialGradient(Point center,
stops = std::move(stops), tile_mode,
effect_transform](const Paint& paint) {
auto contents = std::make_shared<RadialGradientContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetColors(colors);
contents->SetStops(stops);
contents->SetCenterAndRadius(center, radius);
Expand Down Expand Up @@ -144,7 +144,7 @@ ColorSource ColorSource::MakeSweepGradient(Point center,
stops = std::move(stops), tile_mode,
effect_transform](const Paint& paint) {
auto contents = std::make_shared<SweepGradientContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetCenterAndAngles(center, start_angle, end_angle);
contents->SetColors(colors);
contents->SetStops(stops);
Expand All @@ -167,7 +167,7 @@ ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture,
sampler_descriptor = std::move(sampler_descriptor),
effect_transform](const Paint& paint) {
auto contents = std::make_shared<TiledTextureContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetTexture(texture);
contents->SetTileModes(x_tile_mode, y_tile_mode);
contents->SetSamplerDescriptor(sampler_descriptor);
Expand Down Expand Up @@ -197,7 +197,7 @@ ColorSource ColorSource::MakeRuntimeEffect(
texture_inputs =
std::move(texture_inputs)](const Paint& paint) {
auto contents = std::make_shared<RuntimeEffectContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetRuntimeStage(runtime_stage);
contents->SetUniformData(uniform_data);
contents->SetTextureInputs(texture_inputs);
Expand All @@ -213,7 +213,7 @@ ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node,
result.proc_ = [scene_node = std::move(scene_node),
camera_transform](const Paint& paint) {
auto contents = std::make_shared<SceneContents>();
contents->SetOpacity(paint.color.alpha);
contents->SetOpacityFactor(paint.color.alpha);
contents->SetNode(scene_node);
contents->SetCameraTransform(camera_transform);
return contents;
Expand Down
6 changes: 3 additions & 3 deletions impeller/entity/contents/color_source_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ const std::shared_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
return geometry_;
}

void ColorSourceContents::SetOpacity(Scalar alpha) {
void ColorSourceContents::SetOpacityFactor(Scalar alpha) {
opacity_ = alpha;
}

Scalar ColorSourceContents::GetOpacity() const {
Scalar ColorSourceContents::GetOpacityFactor() const {
return opacity_ * inherited_opacity_;
}

void ColorSourceContents::SetEffectTransform(Matrix matrix) {
inverse_matrix_ = matrix.Invert();
}

const Matrix& ColorSourceContents::GetInverseMatrix() const {
const Matrix& ColorSourceContents::GetInverseEffectTransform() const {
return inverse_matrix_;
}

Expand Down
74 changes: 67 additions & 7 deletions impeller/entity/contents/color_source_contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,83 @@

namespace impeller {

//------------------------------------------------------------------------------
/// Color sources are geometry-ignostic `Contents` capable of shading any area
/// defined by an `impeller::Geometry`. Conceptually,
/// `impeller::ColorSourceContents` implement a particular color shading
/// behavior.
///
/// This separation of concerns between geometry and color source output allows
/// Impeller to handle most possible draw combinations in a consistent way.
/// For example: There are color sources for handling solid colors, gradients,
/// textures, custom runtime effects, and even 3D scenes.
///
/// There are some special rendering exceptions that deviate from this pattern
/// and cross geometry and color source concerns, such as text atlas and image
/// atlas rendering. Special `Contents` exist for rendering these behaviors
/// which don't implement `ColorSourceContents`.
///
/// @see `impeller::Geometry`
///
class ColorSourceContents : public Contents {
public:
ColorSourceContents();

~ColorSourceContents() override;

//----------------------------------------------------------------------------
/// @brief Set the geometry that this contents will use to render.
///
void SetGeometry(std::shared_ptr<Geometry> geometry);

void SetEffectTransform(Matrix matrix);
//----------------------------------------------------------------------------
/// @brief Get the geometry that this contents will use to render.
///
const std::shared_ptr<Geometry>& GetGeometry() const;

const Matrix& GetInverseMatrix() const;
//----------------------------------------------------------------------------
/// @brief Set the effect transform for this color source.
///
/// The effect transform is a transformation matrix that is applied to
/// the shaded color output and does not impact geometry in any way.
///
/// For example: With repeat tiling, any gradient or
/// `TiledTextureContents` could be used with an effect transform to
/// inexpensively draw an infinite scrolling background pattern.
///
void SetEffectTransform(Matrix matrix);

void SetOpacity(Scalar opacity);
//----------------------------------------------------------------------------
/// @brief Set the inverted effect transform for this color source.
///
/// When the effect transform is set via `SetEffectTransform`, the
/// value is inverted upon storage. The reason for this is that most
/// color sources internally use the inverted transform.
///
/// @return The inverse of the transform set by `SetEffectTransform`.
///
/// @see `SetEffectTransform`
///
const Matrix& GetInverseEffectTransform() const;

//----------------------------------------------------------------------------
/// @brief Set the opacity factor for this color source.
///
void SetOpacityFactor(Scalar opacity);

//----------------------------------------------------------------------------
/// @brief Get the opacity factor for this color source.
///
/// This value is is factored into the output of the color source in
/// addition to opacity information that may be supplied any other
/// inputs.
///
/// @note If set, the output of this method factors factors in the inherited
/// opacity of this `Contents`.
///
/// @see `Contents::CanInheritOpacity`
///
Scalar GetOpacityFactor() const;

// |Contents|
std::optional<Rect> GetCoverage(const Entity& entity) const override;
Expand All @@ -39,10 +103,6 @@ class ColorSourceContents : public Contents {
// |Contents|
void SetInheritedOpacity(Scalar opacity) override;

Scalar GetOpacity() const;

const std::shared_ptr<Geometry>& GetGeometry() const;

private:
std::shared_ptr<Geometry> geometry_;
Matrix inverse_matrix_;
Expand Down
3 changes: 2 additions & 1 deletion impeller/entity/contents/color_source_text_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ bool ColorSourceTextContents::Render(const ContentContext& renderer,
// offset the color source so it behaves as if it were drawn in the original
// position.
auto effect_transform =
color_source_contents_->GetInverseMatrix().Invert().Translate(-position_);
color_source_contents_->GetInverseEffectTransform().Invert().Translate(
-position_);
color_source_contents_->SetEffectTransform(effect_transform);

auto new_texture = renderer.MakeSubpass(
Expand Down
8 changes: 4 additions & 4 deletions impeller/entity/contents/conical_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.radius = radius_;
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha = GetOpacity();
frag_info.alpha = GetOpacityFactor();
if (focus_) {
frag_info.focus = focus_.value();
frag_info.focus_radius = focus_radius_;
Expand All @@ -91,7 +91,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
frame_info.matrix = GetInverseMatrix();
frame_info.matrix = GetInverseEffectTransform();

Command cmd;
cmd.label = "ConicalGradientSSBOFill";
Expand Down Expand Up @@ -143,7 +143,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
frag_info.alpha = GetOpacity();
frag_info.alpha = GetOpacityFactor();
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
0.5 / gradient_texture->GetSize().height);
if (focus_) {
Expand All @@ -159,7 +159,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,

VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
frame_info.matrix = GetInverseMatrix();
frame_info.matrix = GetInverseEffectTransform();

Command cmd;
cmd.label = "ConicalGradientFill";
Expand Down
20 changes: 20 additions & 0 deletions impeller/entity/contents/contents.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,35 +63,45 @@ class Contents {
const Entity& entity,
RenderPass& pass) const = 0;

//----------------------------------------------------------------------------
/// @brief Get the screen space bounding rectangle that this contents affects.
///
virtual std::optional<Rect> GetCoverage(const Entity& entity) const = 0;

//----------------------------------------------------------------------------
/// @brief Hint that specifies the coverage area of this Contents that will
/// actually be used during rendering. This is for optimization
/// purposes only and can not be relied on as a clip. May optionally
/// affect the result of `GetCoverage()`.
///
void SetCoverageHint(std::optional<Rect> coverage_hint);

const std::optional<Rect>& GetCoverageHint() const;

//----------------------------------------------------------------------------
/// @brief Whether this Contents only emits opaque source colors from the
/// fragment stage. This value does not account for any entity
/// properties (e.g. the blend mode), clips/visibility culling, or
/// inherited opacity.
///
virtual bool IsOpaque() const;

//----------------------------------------------------------------------------
/// @brief Given the current screen space bounding rectangle of the stencil,
/// return the expected stencil coverage after this draw call. This
/// should only be implemented for contents that may write to the
/// stencil buffer.
///
virtual StencilCoverage GetStencilCoverage(
const Entity& entity,
const std::optional<Rect>& current_stencil_coverage) const;

//----------------------------------------------------------------------------
/// @brief Render this contents to a snapshot, respecting the entity's
/// transform, path, stencil depth, and blend mode.
/// The result texture size is always the size of
/// `GetCoverage(entity)`.
///
virtual std::optional<Snapshot> RenderToSnapshot(
const ContentContext& renderer,
const Entity& entity,
Expand All @@ -103,15 +113,18 @@ class Contents {
virtual bool ShouldRender(const Entity& entity,
const std::optional<Rect>& stencil_coverage) const;

//----------------------------------------------------------------------------
/// @brief Return the color source's intrinsic size, if available.
///
/// For example, a gradient has a size based on its end and beginning
/// points, ignoring any tiling. Solid colors and runtime effects have
/// no size.
///
std::optional<Size> GetColorSourceSize() const;

void SetColorSourceSize(Size size);

//----------------------------------------------------------------------------
/// @brief Whether or not this contents can accept the opacity peephole
/// optimization.
///
Expand All @@ -120,22 +133,28 @@ class Contents {
/// a way that makes accepting opacity impossible. It is always safe
/// to return false, especially if computing overlap would be
/// computationally expensive.
///
virtual bool CanInheritOpacity(const Entity& entity) const;

//----------------------------------------------------------------------------
/// @brief Inherit the provided opacity.
///
/// Use of this method is invalid if CanAcceptOpacity returns false.
///
virtual void SetInheritedOpacity(Scalar opacity);

//----------------------------------------------------------------------------
/// @brief Returns a color if this Contents will flood the given `target_size`
/// with a color. This output color is the "Source" color that will be
/// used for the Entity's blend operation.
///
/// This is useful for absorbing full screen solid color draws into
/// subpass clear colors.
///
virtual std::optional<Color> AsBackgroundColor(const Entity& entity,
ISize target_size) const;

//----------------------------------------------------------------------------
/// @brief If possible, applies a color filter to this contents inputs on
/// the CPU.
///
Expand All @@ -150,6 +169,7 @@ class Contents {
/// @return True if the color filter was able to be fully applied to all
/// all relevant inputs. Otherwise, this operation is a no-op and
/// false is returned.
///
[[nodiscard]] virtual bool ApplyColorFilter(
const ColorFilterProc& color_filter_proc);

Expand Down
10 changes: 5 additions & 5 deletions impeller/entity/contents/linear_gradient_contents.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ void LinearGradientContents::SetTileMode(Entity::TileMode tile_mode) {
}

bool LinearGradientContents::IsOpaque() const {
if (GetOpacity() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
if (GetOpacityFactor() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
return false;
}
for (auto color : colors_) {
Expand Down Expand Up @@ -84,7 +84,7 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
frag_info.alpha = GetOpacity();
frag_info.alpha = GetOpacityFactor();
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
0.5 / gradient_texture->GetSize().height);

Expand All @@ -93,7 +93,7 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,

VS::FrameInfo frame_info;
frame_info.mvp = geometry_result.transform;
frame_info.matrix = GetInverseMatrix();
frame_info.matrix = GetInverseEffectTransform();

Command cmd;
cmd.label = "LinearGradientFill";
Expand Down Expand Up @@ -140,7 +140,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
frag_info.end_point = end_point_;
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
frag_info.decal_border_color = decal_border_color_;
frag_info.alpha = GetOpacity();
frag_info.alpha = GetOpacityFactor();

auto& host_buffer = pass.GetTransientsBuffer();
auto colors = CreateGradientColors(colors_, stops_);
Expand All @@ -153,7 +153,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
VS::FrameInfo frame_info;
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
entity.GetTransformation();
frame_info.matrix = GetInverseMatrix();
frame_info.matrix = GetInverseEffectTransform();

Command cmd;
cmd.label = "LinearGradientSSBOFill";
Expand Down
Loading