Flutter Impeller
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. 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< SnapshotRenderToSnapshot (const ContentContext &renderer, const Entity &entity, std::optional< Rect > coverage_limit=std::nullopt, const std::optional< SamplerDescriptor > &sampler_descriptor=std::nullopt, bool msaa_enabled=true, int32_t mip_count=1, std::string_view label="Snapshot") 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< SizeGetColorSourceSize () 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< 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. 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< 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
Definition: line_contents.h:17
static bool ComputeCorners(Point corners[4], const Matrix &transform, bool extend_endpoints, Point p0, Point p1, Scalar width)
float Scalar
Definition: scalar.h:19
TPoint< Scalar > Point
Definition: point.h:327

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& host_buffer = renderer.GetTransientsBuffer();
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, &host_buffer](RenderPass& pass) {
182  FS::BindFragInfo(pass, 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::GetTransientsBuffer(), 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: