Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c0d03be

Browse files
authored
[Impeller] Document ColorSourceContents (#43590)
Someday all the things will be documented and explained intuitively.
1 parent 29c5c41 commit c0d03be

12 files changed

+129
-48
lines changed

impeller/aiks/color_source.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ ColorSource ColorSource::MakeLinearGradient(Point start_point,
5050
stops = std::move(stops), tile_mode,
5151
effect_transform](const Paint& paint) {
5252
auto contents = std::make_shared<LinearGradientContents>();
53-
contents->SetOpacity(paint.color.alpha);
53+
contents->SetOpacityFactor(paint.color.alpha);
5454
contents->SetColors(colors);
5555
contents->SetStops(stops);
5656
contents->SetEndPoints(start_point, end_point);
@@ -82,7 +82,7 @@ ColorSource ColorSource::MakeConicalGradient(Point center,
8282
tile_mode, effect_transform](const Paint& paint) {
8383
std::shared_ptr<ConicalGradientContents> contents =
8484
std::make_shared<ConicalGradientContents>();
85-
contents->SetOpacity(paint.color.alpha);
85+
contents->SetOpacityFactor(paint.color.alpha);
8686
contents->SetColors(colors);
8787
contents->SetStops(stops);
8888
contents->SetCenterAndRadius(center, radius);
@@ -113,7 +113,7 @@ ColorSource ColorSource::MakeRadialGradient(Point center,
113113
stops = std::move(stops), tile_mode,
114114
effect_transform](const Paint& paint) {
115115
auto contents = std::make_shared<RadialGradientContents>();
116-
contents->SetOpacity(paint.color.alpha);
116+
contents->SetOpacityFactor(paint.color.alpha);
117117
contents->SetColors(colors);
118118
contents->SetStops(stops);
119119
contents->SetCenterAndRadius(center, radius);
@@ -144,7 +144,7 @@ ColorSource ColorSource::MakeSweepGradient(Point center,
144144
stops = std::move(stops), tile_mode,
145145
effect_transform](const Paint& paint) {
146146
auto contents = std::make_shared<SweepGradientContents>();
147-
contents->SetOpacity(paint.color.alpha);
147+
contents->SetOpacityFactor(paint.color.alpha);
148148
contents->SetCenterAndAngles(center, start_angle, end_angle);
149149
contents->SetColors(colors);
150150
contents->SetStops(stops);
@@ -167,7 +167,7 @@ ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture,
167167
sampler_descriptor = std::move(sampler_descriptor),
168168
effect_transform](const Paint& paint) {
169169
auto contents = std::make_shared<TiledTextureContents>();
170-
contents->SetOpacity(paint.color.alpha);
170+
contents->SetOpacityFactor(paint.color.alpha);
171171
contents->SetTexture(texture);
172172
contents->SetTileModes(x_tile_mode, y_tile_mode);
173173
contents->SetSamplerDescriptor(sampler_descriptor);
@@ -197,7 +197,7 @@ ColorSource ColorSource::MakeRuntimeEffect(
197197
texture_inputs =
198198
std::move(texture_inputs)](const Paint& paint) {
199199
auto contents = std::make_shared<RuntimeEffectContents>();
200-
contents->SetOpacity(paint.color.alpha);
200+
contents->SetOpacityFactor(paint.color.alpha);
201201
contents->SetRuntimeStage(runtime_stage);
202202
contents->SetUniformData(uniform_data);
203203
contents->SetTextureInputs(texture_inputs);
@@ -213,7 +213,7 @@ ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node,
213213
result.proc_ = [scene_node = std::move(scene_node),
214214
camera_transform](const Paint& paint) {
215215
auto contents = std::make_shared<SceneContents>();
216-
contents->SetOpacity(paint.color.alpha);
216+
contents->SetOpacityFactor(paint.color.alpha);
217217
contents->SetNode(scene_node);
218218
contents->SetCameraTransform(camera_transform);
219219
return contents;

impeller/entity/contents/color_source_contents.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,19 @@ const std::shared_ptr<Geometry>& ColorSourceContents::GetGeometry() const {
2222
return geometry_;
2323
}
2424

25-
void ColorSourceContents::SetOpacity(Scalar alpha) {
25+
void ColorSourceContents::SetOpacityFactor(Scalar alpha) {
2626
opacity_ = alpha;
2727
}
2828

29-
Scalar ColorSourceContents::GetOpacity() const {
29+
Scalar ColorSourceContents::GetOpacityFactor() const {
3030
return opacity_ * inherited_opacity_;
3131
}
3232

3333
void ColorSourceContents::SetEffectTransform(Matrix matrix) {
3434
inverse_matrix_ = matrix.Invert();
3535
}
3636

37-
const Matrix& ColorSourceContents::GetInverseMatrix() const {
37+
const Matrix& ColorSourceContents::GetInverseEffectTransform() const {
3838
return inverse_matrix_;
3939
}
4040

impeller/entity/contents/color_source_contents.h

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,83 @@
1212

1313
namespace impeller {
1414

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

1937
~ColorSourceContents() override;
2038

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

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

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

27-
void SetOpacity(Scalar opacity);
61+
//----------------------------------------------------------------------------
62+
/// @brief Set the inverted effect transform for this color source.
63+
///
64+
/// When the effect transform is set via `SetEffectTransform`, the
65+
/// value is inverted upon storage. The reason for this is that most
66+
/// color sources internally use the inverted transform.
67+
///
68+
/// @return The inverse of the transform set by `SetEffectTransform`.
69+
///
70+
/// @see `SetEffectTransform`
71+
///
72+
const Matrix& GetInverseEffectTransform() const;
73+
74+
//----------------------------------------------------------------------------
75+
/// @brief Set the opacity factor for this color source.
76+
///
77+
void SetOpacityFactor(Scalar opacity);
78+
79+
//----------------------------------------------------------------------------
80+
/// @brief Get the opacity factor for this color source.
81+
///
82+
/// This value is is factored into the output of the color source in
83+
/// addition to opacity information that may be supplied any other
84+
/// inputs.
85+
///
86+
/// @note If set, the output of this method factors factors in the inherited
87+
/// opacity of this `Contents`.
88+
///
89+
/// @see `Contents::CanInheritOpacity`
90+
///
91+
Scalar GetOpacityFactor() const;
2892

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

42-
Scalar GetOpacity() const;
43-
44-
const std::shared_ptr<Geometry>& GetGeometry() const;
45-
46106
private:
47107
std::shared_ptr<Geometry> geometry_;
48108
Matrix inverse_matrix_;

impeller/entity/contents/color_source_text_contents.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ bool ColorSourceTextContents::Render(const ContentContext& renderer,
5555
// offset the color source so it behaves as if it were drawn in the original
5656
// position.
5757
auto effect_transform =
58-
color_source_contents_->GetInverseMatrix().Invert().Translate(-position_);
58+
color_source_contents_->GetInverseEffectTransform().Invert().Translate(
59+
-position_);
5960
color_source_contents_->SetEffectTransform(effect_transform);
6061

6162
auto new_texture = renderer.MakeSubpass(

impeller/entity/contents/conical_gradient_contents.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
7171
frag_info.radius = radius_;
7272
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
7373
frag_info.decal_border_color = decal_border_color_;
74-
frag_info.alpha = GetOpacity();
74+
frag_info.alpha = GetOpacityFactor();
7575
if (focus_) {
7676
frag_info.focus = focus_.value();
7777
frag_info.focus_radius = focus_radius_;
@@ -91,7 +91,7 @@ bool ConicalGradientContents::RenderSSBO(const ContentContext& renderer,
9191
VS::FrameInfo frame_info;
9292
frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
9393
entity.GetTransformation();
94-
frame_info.matrix = GetInverseMatrix();
94+
frame_info.matrix = GetInverseEffectTransform();
9595

9696
Command cmd;
9797
cmd.label = "ConicalGradientSSBOFill";
@@ -143,7 +143,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
143143
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
144144
frag_info.decal_border_color = decal_border_color_;
145145
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
146-
frag_info.alpha = GetOpacity();
146+
frag_info.alpha = GetOpacityFactor();
147147
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
148148
0.5 / gradient_texture->GetSize().height);
149149
if (focus_) {
@@ -159,7 +159,7 @@ bool ConicalGradientContents::RenderTexture(const ContentContext& renderer,
159159

160160
VS::FrameInfo frame_info;
161161
frame_info.mvp = geometry_result.transform;
162-
frame_info.matrix = GetInverseMatrix();
162+
frame_info.matrix = GetInverseEffectTransform();
163163

164164
Command cmd;
165165
cmd.label = "ConicalGradientFill";

impeller/entity/contents/contents.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,35 +63,45 @@ class Contents {
6363
const Entity& entity,
6464
RenderPass& pass) const = 0;
6565

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

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

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

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

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

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

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

113125
void SetColorSourceSize(Size size);
114126

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

139+
//----------------------------------------------------------------------------
125140
/// @brief Inherit the provided opacity.
126141
///
127142
/// Use of this method is invalid if CanAcceptOpacity returns false.
143+
///
128144
virtual void SetInheritedOpacity(Scalar opacity);
129145

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

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

impeller/entity/contents/linear_gradient_contents.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ void LinearGradientContents::SetTileMode(Entity::TileMode tile_mode) {
4545
}
4646

4747
bool LinearGradientContents::IsOpaque() const {
48-
if (GetOpacity() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
48+
if (GetOpacityFactor() < 1 || tile_mode_ == Entity::TileMode::kDecal) {
4949
return false;
5050
}
5151
for (auto color : colors_) {
@@ -84,7 +84,7 @@ bool LinearGradientContents::RenderTexture(const ContentContext& renderer,
8484
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
8585
frag_info.decal_border_color = decal_border_color_;
8686
frag_info.texture_sampler_y_coord_scale = gradient_texture->GetYCoordScale();
87-
frag_info.alpha = GetOpacity();
87+
frag_info.alpha = GetOpacityFactor();
8888
frag_info.half_texel = Vector2(0.5 / gradient_texture->GetSize().width,
8989
0.5 / gradient_texture->GetSize().height);
9090

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

9494
VS::FrameInfo frame_info;
9595
frame_info.mvp = geometry_result.transform;
96-
frame_info.matrix = GetInverseMatrix();
96+
frame_info.matrix = GetInverseEffectTransform();
9797

9898
Command cmd;
9999
cmd.label = "LinearGradientFill";
@@ -140,7 +140,7 @@ bool LinearGradientContents::RenderSSBO(const ContentContext& renderer,
140140
frag_info.end_point = end_point_;
141141
frag_info.tile_mode = static_cast<Scalar>(tile_mode_);
142142
frag_info.decal_border_color = decal_border_color_;
143-
frag_info.alpha = GetOpacity();
143+
frag_info.alpha = GetOpacityFactor();
144144

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

158158
Command cmd;
159159
cmd.label = "LinearGradientSSBOFill";

0 commit comments

Comments
 (0)