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, 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< 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:426

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 197 of file line_contents.cc.

199  {
200  std::vector<uint8_t> curve_data;
201  curve_data.reserve(kCurveResolution);
202  // More simply written as rise / run:
203  // double slope = 1.0 / ((radius * 2) / (scale * width + radius));
204  double slope = (scale * width + radius) / (radius * 2);
205  slope = std::max(slope, 1.0);
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 193 of file line_contents.cc.

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

References impeller::Entity::GetTransform().

◆ Make()

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

Definition at line 135 of file line_contents.cc.

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

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 145 of file line_contents.cc.

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

References impeller::ContentContext::GetContext(), impeller::ContentContext::GetLinePipeline(), impeller::Matrix::GetMaxBasisLengthXY(), impeller::Entity::GetTransform(), impeller::ContentContext::GetTransientsDataBuffer(), impeller::kLinear, impeller::kRound, 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: