Flutter Impeller
fill_path_geometry.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
7 
8 namespace impeller {
9 
11  std::optional<Rect> inner_rect)
12  : path_(path), inner_rect_(inner_rect) {}
13 
15 
16 GeometryResult FillPathGeometry::GetPositionBuffer(
17  const ContentContext& renderer,
18  const Entity& entity,
19  RenderPass& pass) {
20  auto& host_buffer = pass.GetTransientsBuffer();
21  VertexBuffer vertex_buffer;
22 
23  if (path_.GetFillType() == FillType::kNonZero && //
24  path_.IsConvex()) {
25  auto [points, indices] = TessellateConvex(
27 
28  vertex_buffer.vertex_buffer = host_buffer.Emplace(
29  points.data(), points.size() * sizeof(Point), alignof(Point));
30  vertex_buffer.index_buffer = host_buffer.Emplace(
31  indices.data(), indices.size() * sizeof(uint16_t), alignof(uint16_t));
32  vertex_buffer.vertex_count = indices.size();
33  vertex_buffer.index_type = IndexType::k16bit;
34 
35  return GeometryResult{
37  .vertex_buffer = vertex_buffer,
38  .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
39  entity.GetTransformation(),
40  .prevent_overdraw = false,
41  };
42  }
43 
44  auto tesselation_result = renderer.GetTessellator()->Tessellate(
45  path_.GetFillType(),
47  [&vertex_buffer, &host_buffer](
48  const float* vertices, size_t vertices_count, const uint16_t* indices,
49  size_t indices_count) {
50  vertex_buffer.vertex_buffer = host_buffer.Emplace(
51  vertices, vertices_count * sizeof(float) * 2, alignof(float));
52  if (indices != nullptr) {
53  vertex_buffer.index_buffer = host_buffer.Emplace(
54  indices, indices_count * sizeof(uint16_t), alignof(uint16_t));
55  vertex_buffer.vertex_count = indices_count;
56  vertex_buffer.index_type = IndexType::k16bit;
57  } else {
58  vertex_buffer.index_buffer = {};
59  vertex_buffer.vertex_count = vertices_count;
60  vertex_buffer.index_type = IndexType::kNone;
61  }
62  return true;
63  });
64  if (tesselation_result != Tessellator::Result::kSuccess) {
65  return {};
66  }
67  return GeometryResult{
68  .type = PrimitiveType::kTriangle,
69  .vertex_buffer = vertex_buffer,
70  .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
71  entity.GetTransformation(),
72  .prevent_overdraw = false,
73  };
74 }
75 
76 // |Geometry|
77 GeometryResult FillPathGeometry::GetPositionUVBuffer(
78  Rect texture_coverage,
79  Matrix effect_transform,
80  const ContentContext& renderer,
81  const Entity& entity,
82  RenderPass& pass) {
83  using VS = TextureFillVertexShader;
84 
85  if (path_.GetFillType() == FillType::kNonZero && //
86  path_.IsConvex()) {
87  auto [points, indices] = TessellateConvex(
88  path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()));
89 
90  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
91  vertex_builder.Reserve(points.size());
92  vertex_builder.ReserveIndices(indices.size());
93  for (auto i = 0u; i < points.size(); i++) {
94  VS::PerVertexData data;
95  data.position = points[i];
96  data.texture_coords = effect_transform *
97  (points[i] - texture_coverage.origin) /
98  texture_coverage.size;
99  vertex_builder.AppendVertex(data);
100  }
101  for (auto i = 0u; i < indices.size(); i++) {
102  vertex_builder.AppendIndex(indices[i]);
103  }
104 
105  return GeometryResult{
106  .type = PrimitiveType::kTriangle,
107  .vertex_buffer =
108  vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
109  .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
110  entity.GetTransformation(),
111  .prevent_overdraw = false,
112  };
113  }
114 
115  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
116  auto tesselation_result = renderer.GetTessellator()->Tessellate(
117  path_.GetFillType(),
118  path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()),
119  [&vertex_builder, &texture_coverage, &effect_transform](
120  const float* vertices, size_t vertices_count, const uint16_t* indices,
121  size_t indices_count) {
122  for (auto i = 0u; i < vertices_count * 2; i += 2) {
123  VS::PerVertexData data;
124  Point vtx = {vertices[i], vertices[i + 1]};
125  data.position = vtx;
126  data.texture_coords = effect_transform *
127  (vtx - texture_coverage.origin) /
128  texture_coverage.size;
129  vertex_builder.AppendVertex(data);
130  }
131  FML_DCHECK(vertex_builder.GetVertexCount() == vertices_count);
132  if (indices != nullptr) {
133  for (auto i = 0u; i < indices_count; i++) {
134  vertex_builder.AppendIndex(indices[i]);
135  }
136  }
137  return true;
138  });
139  if (tesselation_result != Tessellator::Result::kSuccess) {
140  return {};
141  }
142  return GeometryResult{
143  .type = PrimitiveType::kTriangle,
144  .vertex_buffer =
145  vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
146  .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) *
147  entity.GetTransformation(),
148  .prevent_overdraw = false,
149  };
150 }
151 
152 GeometryVertexType FillPathGeometry::GetVertexType() const {
154 }
155 
156 std::optional<Rect> FillPathGeometry::GetCoverage(
157  const Matrix& transform) const {
158  return path_.GetTransformedBoundingBox(transform);
159 }
160 
161 bool FillPathGeometry::CoversArea(const Matrix& transform,
162  const Rect& rect) const {
163  if (!inner_rect_.has_value()) {
164  return false;
165  }
166  if (!transform.IsTranslationScaleOnly()) {
167  return false;
168  }
169  Rect coverage = inner_rect_->TransformBounds(transform);
170  return coverage.Contains(rect);
171 }
172 
173 } // namespace impeller
impeller::VertexBuffer::index_type
IndexType index_type
Definition: vertex_buffer.h:18
impeller::IndexType::k16bit
@ k16bit
impeller::FillPathGeometry::~FillPathGeometry
~FillPathGeometry()
impeller::VertexBuffer
Definition: vertex_buffer.h:12
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:204
formats.h
impeller::TessellateConvex
std::pair< std::vector< Point >, std::vector< uint16_t > > TessellateConvex(Path::Polyline polyline)
Given a convex polyline, create a triangle fan structure.
Definition: geometry.cc:19
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:13
impeller::VertexBuffer::vertex_count
size_t vertex_count
Definition: vertex_buffer.h:17
impeller::GeometryVertexType
GeometryVertexType
Definition: geometry.h:25
impeller::Entity::GetTransformation
const Matrix & GetTransformation() const
Definition: entity.cc:49
impeller::Entity
Definition: entity.h:21
impeller::RenderPass::GetRenderTargetSize
ISize GetRenderTargetSize() const
Definition: render_pass.cc:30
impeller::Point
TPoint< Scalar > Point
Definition: point.h:306
impeller::GeometryResult::type
PrimitiveType type
Definition: geometry.h:19
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:54
impeller::Matrix::GetMaxBasisLength
Scalar GetMaxBasisLength() const
Definition: matrix.cc:196
impeller::Matrix::IsTranslationScaleOnly
constexpr bool IsTranslationScaleOnly() const
Returns true if the matrix has a scale-only basis and is non-projective. Note that an identity matrix...
Definition: matrix.h:358
impeller::GeometryResult
Definition: geometry.h:18
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:306
impeller::ContentContext::GetTessellator
std::shared_ptr< Tessellator > GetTessellator() const
Definition: content_context.cc:436
fill_path_geometry.h
impeller::FillType::kNonZero
@ kNonZero
impeller::TRect::Contains
constexpr bool Contains(const TPoint< Type > &p) const
Definition: rect.h:122
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:27
impeller::VertexBuffer::index_buffer
BufferView index_buffer
Definition: vertex_buffer.h:14
impeller::TPoint< Scalar >
impeller::Matrix::MakeOrthographic
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition: matrix.h:448
impeller::PrimitiveType::kTriangle
@ kTriangle
impeller::Path::IsConvex
bool IsConvex() const
Definition: path.cc:56
impeller
Definition: aiks_context.cc:10
impeller::kPosition
@ kPosition
Definition: geometry.h:26
impeller::ContentContext
Definition: content_context.h:344
impeller::TRect
Definition: rect.h:20
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:36
impeller::RenderPass::GetTransientsBuffer
HostBuffer & GetTransientsBuffer()
Definition: render_pass.cc:34
impeller::Path::GetFillType
FillType GetFillType() const
Definition: path.cc:52
impeller::FillPathGeometry::FillPathGeometry
FillPathGeometry(const Path &path, std::optional< Rect > inner_rect=std::nullopt)
Definition: fill_path_geometry.cc:10
impeller::Path::CreatePolyline
Polyline CreatePolyline(Scalar scale) const
Definition: path.cc:272