| Flutter Impeller |

Classes | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
impeller::LineContents Class Reference

`#include <line_contents.h>`

Inheritance diagram for impeller::LineContents:

## Classes
struct | EffectiveLineParameters

## Public Member Functions
bool | Render (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
std::optional< Rect > | GetCoverage (const Entity &entity) const override
| Get the area of the render pass that will be affected when this contents is rendered. More...
Public Member Functions inherited from impeller::Contents
| Contents ()
virtual | ~Contents ()
void | SetCoverageHint (std::optional< Rect > coverage_hint)
| 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()`. More...
const std::optional< Rect > & | GetCoverageHint () const
virtual bool | IsOpaque (const Matrix &transform) const
| 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. More...
virtual std::optional< Snapshot > | RenderToSnapshot (const ContentContext &renderer, const Entity &entity, const SnapshotOptions &options) const
| Render this contents to a snapshot, respecting the entity's transform, path, clip depth, and blend mode. The result texture size is always the size of `GetCoverage(entity)`. More...
std::optional< Size > | GetColorSourceSize () const
| Return the color source's intrinsic size, if available. More...
void | SetColorSourceSize (Size size)
virtual void | SetInheritedOpacity (Scalar opacity)
| Inherit the provided opacity. More...
virtual std::optional< Color > | AsBackgroundColor (const Entity &entity, ISize target_size) const
| 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. More...
virtual bool | ApplyColorFilter (const ColorFilterProc &color_filter_proc)
| If possible, applies a color filter to this contents inputs on the CPU. More...

## Static Public Member Functions
static std::vector< uint8_t > | CreateCurveData (Scalar width, Scalar radius, Scalar scale)
static fml::StatusOr< EffectiveLineParameters > | CalculatePerVertex (LineVertexShader::PerVertexData *per_vertex, const LineGeometry *geometry, const Matrix &entity_transform)
static std::unique_ptr< LineContents > | Make (std::unique_ptr< LineGeometry > geometry, Color color)
Static Public Member Functions inherited from impeller::Contents
static std::shared_ptr< Contents > | MakeAnonymous (RenderProc render_proc, CoverageProc coverage_proc)

## Static Public Attributes
static const Scalar | kSampleRadius = 1.f

## Additional Inherited Members
Public Types inherited from impeller::Contents
using | ColorFilterProc = std::function< Color(Color)>
using | RenderProc = std::function< bool(const ContentContext &renderer, const Entity &entity, RenderPass &pass)>
using | CoverageProc = std::function< std::optional< Rect >(const Entity &entity)>

## Detailed Description

Definition at line 15 of file line_contents.h.

## Member Function Documentation

## ◆ CalculatePerVertex()

fml::StatusOr< LineContents::EffectiveLineParameters > impeller::LineContents::CalculatePerVertex | ( | LineVertexShader::PerVertexData * | per_vertex,
|  | const LineGeometry * | geometry,
|  | const Matrix & | entity_transform
| ) |  |
| static

Calculates the values needed for the vertex shader, per vertex. Returns the effective line parameters that are used. These differ from the ones provided by `geometry` when the line gets clamped for being too thin.

Definition at line 227 of file line_contents.cc.

229 {
230 Scalar scale = entity_transform.GetMaxBasisLengthXY();
231
232 // Transform the line into unrotated space by rotating p1 to be horizontal
233 // with p0. We do this because there seems to be a flaw in the eN calculations
234 // where they create thinner lines for diagonal lines.
235 Point diff = geometry->GetP1() - geometry->GetP0();
236 Scalar magnitude = diff.GetLength();
237 Point p1_prime = Point(geometry->GetP0().x + magnitude, geometry->GetP0().y);
238
239 std::array<Point, 4> corners;
240 // Make sure we get kSampleRadius pixels to sample from.
241 Scalar expand_size = std::max(kSampleRadius / scale, kSampleRadius);
242 if (!LineGeometry::ComputeCorners(
243 corners.data(), entity_transform,
244 /*extend_endpoints=*/geometry->GetCap() != Cap::kButt,
245 geometry->GetP0(), p1_prime, geometry->GetWidth())) {
246 return fml::Status(fml::StatusCode::kAborted, "No valid corners");
247 }
248 Scalar effective_line_width = std::fabsf((corners[2] - corners[0]).y);
249 ExpandLine(corners, Point(expand_size, expand_size));
250 Scalar padded_line_width = std::fabsf((corners[2] - corners[0]).y);
251 Scalar effective_sample_radius =
252 (padded_line_width - effective_line_width) / 2.f;
253 LineInfo line_info =
254 CalculateLineInfo(geometry->GetP0(), p1_prime, effective_line_width,
255 effective_sample_radius);
256 for (auto& corner : corners) {
257 *per_vertex++ = {
258 .position = corner,
259 .e0 = line_info.e0,
260 .e1 = line_info.e1,
261 .e2 = line_info.e2,
262 .e3 = line_info.e3,
263 };
264 }
265
266 return EffectiveLineParameters{.width = effective_line_width,
267 .radius = effective_sample_radius};
268 }
impeller::LineContents::kSampleRadius
static const Scalar kSampleRadius
Definition: line_contents.h:17
impeller::LineGeometry::ComputeCorners
static bool ComputeCorners(Point corners[4], const Matrix &transform, bool extend_endpoints, Point p0, Point p1, Scalar width)
Definition: line_geometry.cc:52
impeller::Scalar
float Scalar
Definition: scalar.h:19
impeller::Point
TPoint< Scalar > Point
Definition: point.h:425
impeller::Cap::kButt
@ kButt

References impeller::LineGeometry::ComputeCorners(), impeller::LineGeometry::GetCap(), impeller::TPoint< T >::GetLength(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::LineGeometry::GetP0(), impeller::LineGeometry::GetP1(), impeller::LineGeometry::GetWidth(), impeller::kButt, kSampleRadius, impeller::LineContents::EffectiveLineParameters::width, impeller::TPoint< T >::x, and impeller::TPoint< T >::y.

Referenced by impeller::testing::TEST().

## ◆ CreateCurveData()

std::vector< uint8_t > impeller::LineContents::CreateCurveData | ( | Scalar | width,
|  | Scalar | radius,
|  | Scalar | scale
| ) |  |
| static

Definition at line 198 of file line_contents.cc.

200 {
201 std::vector<uint8_t> curve_data;
202 curve_data.reserve(kCurveResolution);
203 // More simply written as rise / run:
204 // double slope = 1.0 / ((radius * 2) / (scale * width + radius));
205 double slope = (scale * width + radius) / (radius * 2);
206 for (int i = 0; i < kCurveResolution; ++i) {
207 double norm =
208 (static_cast<double>(i)) / static_cast<double>(kCurveResolution - 1);
209 double scaled = slope * norm;
210 curve_data.push_back(DoubleToUint8(scaled));
211 }
212 return curve_data;
213 }

Referenced by impeller::testing::TEST().

## ◆ GetCoverage()

std::optional< Rect > impeller::LineContents::GetCoverage | ( | const Entity & | entity | ) | const
| overridevirtual

Get the area of the render pass that will be affected when this contents is rendered.

During rendering, coverage coordinates count pixels from the top left corner of the framebuffer.

Returns
  The coverage rectangle. An `std::nullopt` result means that rendering this contents has no effect on the output color.

Implements impeller::Contents.

Definition at line 194 of file line_contents.cc.

194 {
195 return geometry_->GetCoverage(entity.GetTransform());
196 }

References impeller::Entity::GetTransform().

## ◆ Make()

std::unique_ptr< LineContents > impeller::LineContents::Make | ( | std::unique_ptr< LineGeometry > | geometry,
|  | Color | color
| ) |  |
| static

Definition at line 137 of file line_contents.cc.

139 {
140 return std::unique_ptr<LineContents>(
141 new LineContents(std::move(geometry), color));
142 }

Referenced by impeller::Canvas::DrawLine(), and impeller::testing::TEST().

## ◆ Render()

bool impeller::LineContents::Render | ( | const ContentContext & | renderer,
|  | const Entity & | entity,
|  | RenderPass & | pass
| ) |  | const
| overridevirtual

Implements impeller::Contents.

Definition at line 147 of file line_contents.cc.

149 {
150 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
151
152 VS::FrameInfo frame_info;
153 FS::FragInfo frag_info;
154 frag_info.color = color_;
155
156 Scalar scale = entity.GetTransform().GetMaxBasisLengthXY();
157
158 auto geometry_result =
159 CreateGeometry(renderer, entity, pass, geometry_.get());
160
161 std::shared_ptr<Texture> curve_texture = CreateCurveTexture(
162 geometry_->GetWidth(), kSampleRadius, scale, renderer.GetContext());
163
164 SamplerDescriptor sampler_desc;
165 sampler_desc.min_filter = MinMagFilter::kLinear;
166 sampler_desc.mag_filter = MinMagFilter::kLinear;
167
168 FS::BindCurve(
169 pass, curve_texture,
170 renderer.GetContext()->GetSamplerLibrary()->GetSampler(sampler_desc));
171
172 PipelineBuilderCallback pipeline_callback =
173 [&renderer](ContentContextOptions options) {
174 return renderer.GetLinePipeline(options);
175 };
176
177 return ColorSourceContents::DrawGeometry<VS>(
178 this, geometry_.get(), renderer, entity, pass, pipeline_callback,
179 frame_info,
180 /*bind_fragment_callback=*/
181 [&frag_info, &data_host_buffer](RenderPass& pass) {
182 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
183 pass.SetCommandLabel("Line");
184 return true;
185 },
186 /*force_stencil=*/false,
187 /*create_geom_callback=*/
188 [geometry_result = std::move(geometry_result)](
189 const ContentContext& renderer, const Entity& entity,
190 RenderPass& pass,
191 const Geometry* geometry) { return geometry_result.second; });
192 }
impeller::MinMagFilter::kLinear
@ kLinear

References impeller::ContentContext::GetContext(), impeller::ContentContext::GetLinePipeline(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::Entity::GetTransform(), impeller::ContentContext::GetTransientsDataBuffer(), impeller::kLinear, kSampleRadius, impeller::SamplerDescriptor::mag_filter, and impeller::SamplerDescriptor::min_filter.

## Member Data Documentation

## ◆ kSampleRadius

const Scalar impeller::LineContents::kSampleRadius = 1.f
| static

Definition at line 17 of file line_contents.h.

Referenced by CalculatePerVertex(), Render(), and impeller::testing::TEST().

The documentation for this class was generated from the following files:

- impeller/entity/contents/line_contents.h
- impeller/entity/contents/line_contents.cc