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 
10 FillPathGeometry::FillPathGeometry(Path path, std::optional<Rect> inner_rect)
11  : path_(std::move(path)), inner_rect_(inner_rect) {}
12 
13 GeometryResult FillPathGeometry::GetPositionBuffer(
14  const ContentContext& renderer,
15  const Entity& entity,
16  RenderPass& pass) const {
17  auto& host_buffer = pass.GetTransientsBuffer();
18  VertexBuffer vertex_buffer;
19 
20  if (path_.GetFillType() == FillType::kNonZero && //
21  path_.IsConvex()) {
22  auto points = renderer.GetTessellator()->TessellateConvex(
23  path_, entity.GetTransform().GetMaxBasisLength());
24 
25  vertex_buffer.vertex_buffer = host_buffer.Emplace(
26  points.data(), points.size() * sizeof(Point), alignof(Point));
27  vertex_buffer.index_buffer = {}, vertex_buffer.vertex_count = points.size();
28  vertex_buffer.index_type = IndexType::kNone;
29 
30  return GeometryResult{
32  .vertex_buffer = vertex_buffer,
33  .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
34  .prevent_overdraw = false,
35  };
36  }
37 
38  auto tesselation_result = renderer.GetTessellator()->Tessellate(
39  path_, entity.GetTransform().GetMaxBasisLength(),
40  [&vertex_buffer, &host_buffer](
41  const float* vertices, size_t vertices_count, const uint16_t* indices,
42  size_t indices_count) {
43  vertex_buffer.vertex_buffer = host_buffer.Emplace(
44  vertices, vertices_count * sizeof(float) * 2, alignof(float));
45  if (indices != nullptr) {
46  vertex_buffer.index_buffer = host_buffer.Emplace(
47  indices, indices_count * sizeof(uint16_t), alignof(uint16_t));
48  vertex_buffer.vertex_count = indices_count;
49  vertex_buffer.index_type = IndexType::k16bit;
50  } else {
51  vertex_buffer.index_buffer = {};
52  vertex_buffer.vertex_count = vertices_count;
53  vertex_buffer.index_type = IndexType::kNone;
54  }
55  return true;
56  });
57  if (tesselation_result != Tessellator::Result::kSuccess) {
58  return {};
59  }
60  return GeometryResult{
61  .type = PrimitiveType::kTriangle,
62  .vertex_buffer = vertex_buffer,
63  .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
64  .prevent_overdraw = false,
65  };
66 }
67 
68 // |Geometry|
69 GeometryResult FillPathGeometry::GetPositionUVBuffer(
70  Rect texture_coverage,
71  Matrix effect_transform,
72  const ContentContext& renderer,
73  const Entity& entity,
74  RenderPass& pass) const {
75  using VS = TextureFillVertexShader;
76 
77  auto uv_transform =
78  texture_coverage.GetNormalizingTransform() * effect_transform;
79 
80  if (path_.GetFillType() == FillType::kNonZero && //
81  path_.IsConvex()) {
82  auto points = renderer.GetTessellator()->TessellateConvex(
83  path_, entity.GetTransform().GetMaxBasisLength());
84 
85  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
86  vertex_builder.Reserve(points.size());
87  for (auto i = 0u; i < points.size(); i++) {
88  VS::PerVertexData data;
89  data.position = points[i];
90  data.texture_coords = uv_transform * points[i];
91  vertex_builder.AppendVertex(data);
92  }
93 
94  return GeometryResult{
95  .type = PrimitiveType::kTriangleStrip,
96  .vertex_buffer =
97  vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
98  .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
99  .prevent_overdraw = false,
100  };
101  }
102 
103  VertexBufferBuilder<VS::PerVertexData> vertex_builder;
104  auto tesselation_result = renderer.GetTessellator()->Tessellate(
105  path_, entity.GetTransform().GetMaxBasisLength(),
106  [&vertex_builder, &uv_transform](
107  const float* vertices, size_t vertices_count, const uint16_t* indices,
108  size_t indices_count) {
109  for (auto i = 0u; i < vertices_count * 2; i += 2) {
110  VS::PerVertexData data;
111  Point vtx = {vertices[i], vertices[i + 1]};
112  data.position = vtx;
113  data.texture_coords = uv_transform * vtx;
114  vertex_builder.AppendVertex(data);
115  }
116  FML_DCHECK(vertex_builder.GetVertexCount() == vertices_count);
117  if (indices != nullptr) {
118  for (auto i = 0u; i < indices_count; i++) {
119  vertex_builder.AppendIndex(indices[i]);
120  }
121  }
122  return true;
123  });
124  if (tesselation_result != Tessellator::Result::kSuccess) {
125  return {};
126  }
127  return GeometryResult{
128  .type = PrimitiveType::kTriangle,
129  .vertex_buffer =
130  vertex_builder.CreateVertexBuffer(pass.GetTransientsBuffer()),
131  .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
132  .prevent_overdraw = false,
133  };
134 }
135 
136 GeometryVertexType FillPathGeometry::GetVertexType() const {
138 }
139 
140 std::optional<Rect> FillPathGeometry::GetCoverage(
141  const Matrix& transform) const {
142  return path_.GetTransformedBoundingBox(transform);
143 }
144 
145 bool FillPathGeometry::CoversArea(const Matrix& transform,
146  const Rect& rect) const {
147  if (!inner_rect_.has_value()) {
148  return false;
149  }
150  if (!transform.IsTranslationScaleOnly()) {
151  return false;
152  }
153  Rect coverage = inner_rect_->TransformBounds(transform);
154  return coverage.Contains(rect);
155 }
156 
157 } // namespace impeller
impeller::VertexBuffer::index_type
IndexType index_type
Definition: vertex_buffer.h:29
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:49
impeller::VertexBuffer
Definition: vertex_buffer.h:13
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:264
formats.h
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:14
impeller::VertexBuffer::vertex_count
size_t vertex_count
Definition: vertex_buffer.h:23
impeller::RenderPass::GetOrthographicTransform
const Matrix & GetOrthographicTransform() const
Definition: render_pass.cc:51
impeller::FillPathGeometry::FillPathGeometry
FillPathGeometry(Path path, std::optional< Rect > inner_rect=std::nullopt)
Definition: fill_path_geometry.cc:10
impeller::GeometryVertexType
GeometryVertexType
Definition: geometry.h:34
impeller::Entity
Definition: entity.h:21
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:55
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:360
impeller::GeometryResult
Definition: geometry.h:20
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:488
impeller::ContentContext::GetTessellator
std::shared_ptr< Tessellator > GetTessellator() const
Definition: content_context.cc:475
fill_path_geometry.h
impeller::FillType::kNonZero
@ kNonZero
impeller::TRect::Contains
constexpr bool Contains(const TPoint< Type > &p) const
Definition: rect.h:127
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:29
impeller::VertexBuffer::index_buffer
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition: vertex_buffer.h:18
std
Definition: comparable.h:95
impeller::TPoint
Definition: point.h:22
impeller::Path::IsConvex
bool IsConvex() const
Definition: path.cc:59
impeller
Definition: aiks_context.cc:10
impeller::kPosition
@ kPosition
Definition: geometry.h:35
impeller::ContentContext
Definition: content_context.h:332
impeller::TRect
Definition: rect.h:22
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::RenderPass::GetTransientsBuffer
HostBuffer & GetTransientsBuffer()
Definition: render_pass.cc:55
impeller::Path::GetFillType
FillType GetFillType() const
Definition: path.cc:55