| 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
5 #include "impeller/entity/geometry/fill_path_geometry.h"
6 #include "impeller/core/formats.h"
7
8 namespace impeller {
9
10 FillPathGeometry::FillPathGeometry(const Path& path,
11 std::optional<Rect> inner_rect)
12 : path_(path), inner_rect_(inner_rect) {}
13
14 FillPathGeometry::~FillPathGeometry() = default;
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(
26 path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()));
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{
36 .type = PrimitiveType::kTriangle,
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(),
46 path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()),
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 {
153 return GeometryVertexType::kPosition;
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