Flutter Engine
 
Loading...
Searching...
No Matches
impeller::LineContents Class Reference

#include <line_contents.h>

Inheritance diagram for impeller::LineContents:
impeller::Contents

Classes

struct  EffectiveLineParameters
 

Public Member Functions

bool Render (const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
 
std::optional< RectGetCoverage (const Entity &entity) const override
 Get the area of the render pass that will be affected when this contents is rendered.
 
- 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().
 
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.
 
virtual std::optional< SnapshotRenderToSnapshot (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).
 
std::optional< SizeGetColorSourceSize () const
 Return the color source's intrinsic size, if available.
 
void SetColorSourceSize (Size size)
 
virtual void SetInheritedOpacity (Scalar opacity)
 Inherit the provided opacity.
 
virtual std::optional< ColorAsBackgroundColor (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.
 
virtual bool ApplyColorFilter (const ColorFilterProc &color_filter_proc)
 If possible, applies a color filter to this contents inputs on the CPU.
 

Static Public Member Functions

static std::vector< uint8_t > CreateCurveData (Scalar width, Scalar radius, Scalar scale)
 
static fml::StatusOr< EffectiveLineParametersCalculatePerVertex (LineVertexShader::PerVertexData *per_vertex, const LineGeometry *geometry, const Matrix &entity_transform)
 
static std::unique_ptr< LineContentsMake (std::unique_ptr< LineGeometry > geometry, Color color)
 
- Static Public Member Functions inherited from impeller::Contents
static std::shared_ptr< ContentsMakeAnonymous (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);
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}
static const Scalar kSampleRadius
static bool ComputeCorners(Point corners[4], const Matrix &transform, bool extend_endpoints, Point p0, Point p1, Scalar width)
double y
float Scalar
Definition scalar.h:19
TPoint< Scalar > Point
Definition point.h:327
constexpr Type GetLength() const
Definition point.h:206

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

Referenced by impeller::testing::TEST(), and 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}
int32_t width

References i, and width.

Referenced by impeller::testing::TEST(), and 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}

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

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