| Flutter Impeller |

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/geometry.h"
6
7 #include <memory>
8 #include <optional>
9
10 #include "impeller/entity/geometry/circle_geometry.h"
11 #include "impeller/entity/geometry/cover_geometry.h"
12 #include "impeller/entity/geometry/ellipse_geometry.h"
13 #include "impeller/entity/geometry/fill_path_geometry.h"
14 #include "impeller/entity/geometry/line_geometry.h"
15 #include "impeller/entity/geometry/point_field_geometry.h"
16 #include "impeller/entity/geometry/rect_geometry.h"
17 #include "impeller/entity/geometry/round_rect_geometry.h"
18 #include "impeller/entity/geometry/stroke_path_geometry.h"
19 #include "impeller/geometry/rect.h"
20
21 namespace impeller {
22
23 GeometryResult Geometry::ComputePositionGeometry(
24 const Tessellator::VertexGenerator& generator,
25 const Entity& entity,
26 RenderPass& pass) {
27 using VT = SolidFillVertexShader::PerVertexData;
28
29 size_t count = generator.GetVertexCount();
30
31 return GeometryResult{
32 .type = generator.GetTriangleType(),
33 .vertex_buffer =
34 {
35 .vertex_buffer = pass.GetTransientsBuffer().Emplace(
36 count * sizeof(VT), alignof(VT),
37 [&generator](uint8_t* buffer) {
38 auto vertices = reinterpret_cast<VT*>(buffer);
39 generator.GenerateVertices([&vertices](const Point& p) {
40 *vertices++ = {
41 .position = p,
42 };
43 });
44 FML_DCHECK(vertices == reinterpret_cast<VT*>(buffer) +
45 generator.GetVertexCount());
46 }),
47 .vertex_count = count,
48 .index_type = IndexType::kNone,
49 },
50 .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
51 .prevent_overdraw = false,
52 };
53 }
54
55 GeometryResult Geometry::ComputePositionUVGeometry(
56 const Tessellator::VertexGenerator& generator,
57 const Matrix& uv_transform,
58 const Entity& entity,
59 RenderPass& pass) {
60 using VT = TextureFillVertexShader::PerVertexData;
61
62 size_t count = generator.GetVertexCount();
63
64 return GeometryResult{
65 .type = generator.GetTriangleType(),
66 .vertex_buffer =
67 {
68 .vertex_buffer = pass.GetTransientsBuffer().Emplace(
69 count * sizeof(VT), alignof(VT),
70 [&generator, &uv_transform](uint8_t* buffer) {
71 auto vertices = reinterpret_cast<VT*>(buffer);
72 generator.GenerateVertices(
73 [&vertices, &uv_transform](const Point& p) { //
74 *vertices++ = {
75 .position = p,
76 .texture_coords = uv_transform * p,
77 };
78 });
79 FML_DCHECK(vertices == reinterpret_cast<VT*>(buffer) +
80 generator.GetVertexCount());
81 }),
82 .vertex_count = count,
83 .index_type = IndexType::kNone,
84 },
85 .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
86 .prevent_overdraw = false,
87 };
88 }
89
90 VertexBufferBuilder<TextureFillVertexShader::PerVertexData>
91 ComputeUVGeometryCPU(
92 VertexBufferBuilder<SolidFillVertexShader::PerVertexData>& input,
93 Point texture_origin,
94 Size texture_coverage,
95 Matrix effect_transform) {
96 VertexBufferBuilder<TextureFillVertexShader::PerVertexData> vertex_builder;
97 vertex_builder.Reserve(input.GetVertexCount());
98 input.IterateVertices(
99 [&vertex_builder, &texture_coverage, &effect_transform,
100 &texture_origin](SolidFillVertexShader::PerVertexData old_vtx) {
101 TextureFillVertexShader::PerVertexData data;
102 data.position = old_vtx.position;
103 data.texture_coords = effect_transform *
104 (old_vtx.position - texture_origin) /
105 texture_coverage;
106 vertex_builder.AppendVertex(data);
107 });
108 return vertex_builder;
109 }
110
111 GeometryResult ComputeUVGeometryForRect(Rect source_rect,
112 Rect texture_coverage,
113 Matrix effect_transform,
114 const ContentContext& renderer,
115 const Entity& entity,
116 RenderPass& pass) {
117 auto& host_buffer = pass.GetTransientsBuffer();
118
119 auto uv_transform =
120 texture_coverage.GetNormalizingTransform() * effect_transform;
121 std::vector<Point> data(8);
122 auto points = source_rect.GetPoints();
123 for (auto i = 0u, j = 0u; i < 8; i += 2, j++) {
124 data[i] = points[j];
125 data[i + 1] = uv_transform * points[j];
126 }
127
128 return GeometryResult{
129 .type = PrimitiveType::kTriangleStrip,
130 .vertex_buffer =
131 {
132 .vertex_buffer = host_buffer.Emplace(
133 data.data(), 16 * sizeof(float), alignof(float)),
134 .vertex_count = 4,
135 .index_type = IndexType::kNone,
136 },
137 .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
138 .prevent_overdraw = false,
139 };
140 }
141
142 GeometryResult Geometry::GetPositionUVBuffer(Rect texture_coverage,
143 Matrix effect_transform,
144 const ContentContext& renderer,
145 const Entity& entity,
146 RenderPass& pass) const {
147 return {};
148 }
149
150 std::shared_ptr<Geometry> Geometry::MakeFillPath(
151 Path path,
152 std::optional<Rect> inner_rect) {
153 return std::make_shared<FillPathGeometry>(std::move(path), inner_rect);
154 }
155
156 std::shared_ptr<Geometry> Geometry::MakePointField(std::vector<Point> points,
157 Scalar radius,
158 bool round) {
159 return std::make_shared<PointFieldGeometry>(std::move(points), radius, round);
160 }
161
162 std::shared_ptr<Geometry> Geometry::MakeStrokePath(Path path,
163 Scalar stroke_width,
164 Scalar miter_limit,
165 Cap stroke_cap,
166 Join stroke_join) {
167 // Skia behaves like this.
168 if (miter_limit < 0) {
169 miter_limit = 4.0;
170 }
171 return std::make_shared<StrokePathGeometry>(
172 std::move(path), stroke_width, miter_limit, stroke_cap, stroke_join);
173 }
174
175 std::shared_ptr<Geometry> Geometry::MakeCover() {
176 return std::make_shared<CoverGeometry>();
177 }
178
179 std::shared_ptr<Geometry> Geometry::MakeRect(const Rect& rect) {
180 return std::make_shared<RectGeometry>(rect);
181 }
182
183 std::shared_ptr<Geometry> Geometry::MakeOval(const Rect& rect) {
184 return std::make_shared<EllipseGeometry>(rect);
185 }
186
187 std::shared_ptr<Geometry> Geometry::MakeLine(const Point& p0,
188 const Point& p1,
189 Scalar width,
190 Cap cap) {
191 return std::make_shared<LineGeometry>(p0, p1, width, cap);
192 }
193
194 std::shared_ptr<Geometry> Geometry::MakeCircle(const Point& center,
195 Scalar radius) {
196 return std::make_shared<CircleGeometry>(center, radius);
197 }
198
199 std::shared_ptr<Geometry> Geometry::MakeStrokedCircle(const Point& center,
200 Scalar radius,
201 Scalar stroke_width) {
202 return std::make_shared<CircleGeometry>(center, radius, stroke_width);
203 }
204
205 std::shared_ptr<Geometry> Geometry::MakeRoundRect(const Rect& rect,
206 const Size& radii) {
207 return std::make_shared<RoundRectGeometry>(rect, radii);
208 }
209
210 bool Geometry::CoversArea(const Matrix& transform, const Rect& rect) const {
211 return false;
212 }
213
214 bool Geometry::IsAxisAlignedRect() const {
215 return false;
216 }
217
218 } // namespace impeller
impeller::Geometry::MakePointField
static std::shared_ptr< Geometry > MakePointField(std::vector< Point > points, Scalar radius, bool round)
Definition: geometry.cc:156
impeller::Geometry::MakeStrokedCircle
static std::shared_ptr< Geometry > MakeStrokedCircle(const Point &center, Scalar radius, Scalar stroke_width)
Definition: geometry.cc:199
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:49
stroke_path_geometry.h
impeller::Geometry::MakeRoundRect
static std::shared_ptr< Geometry > MakeRoundRect(const Rect &rect, const Size &radii)
Definition: geometry.cc:205
impeller::VertexBufferBuilder::GetVertexCount
size_t GetVertexCount() const
Definition: vertex_buffer_builder.h:54
cover_geometry.h
point_field_geometry.h
impeller::HostBuffer::Emplace
BufferView Emplace(const BufferType &buffer)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
Definition: host_buffer.h:85
impeller::TRect::GetNormalizingTransform
constexpr Matrix GetNormalizingTransform() const
Constructs a Matrix that will map all points in the coordinate space of the rectangle into a new norm...
Definition: rect.h:280
rect_geometry.h
impeller::Geometry::IsAxisAlignedRect
virtual bool IsAxisAlignedRect() const
Definition: geometry.cc:214
impeller::Geometry::CoversArea
virtual bool CoversArea(const Matrix &transform, const Rect &rect) const
Determines if this geometry, transformed by the given transform, will completely cover all surface ar...
Definition: geometry.cc:210
impeller::Tessellator::VertexGenerator::GenerateVertices
virtual void GenerateVertices(const TessellatedVertexProc &proc) const =0
Generate the vertices and deliver them in the necessary order (as required by the PrimitiveType) to t...
impeller::RenderPass::GetOrthographicTransform
const Matrix & GetOrthographicTransform() const
Definition: render_pass.cc:51
impeller::ComputeUVGeometryCPU
VertexBufferBuilder< TextureFillVertexShader::PerVertexData > ComputeUVGeometryCPU(VertexBufferBuilder< SolidFillVertexShader::PerVertexData > &input, Point texture_origin, Size texture_coverage, Matrix effect_transform)
Compute UV geometry for a VBB that contains only position geometry.
Definition: geometry.cc:91
impeller::Geometry::MakeStrokePath
static std::shared_ptr< Geometry > MakeStrokePath(Path path, Scalar stroke_width=0.0, Scalar miter_limit=4.0, Cap stroke_cap=Cap::kButt, Join stroke_join=Join::kMiter)
Definition: geometry.cc:162
impeller::TRect::GetPoints
constexpr std::array< TPoint< T >, 4 > GetPoints() const
Get the points that represent the 4 corners of this rectangle. The order is: Top left,...
Definition: rect.h:247
impeller::Geometry::MakeOval
static std::shared_ptr< Geometry > MakeOval(const Rect &rect)
Definition: geometry.cc:183
impeller::Entity
Definition: entity.h:21
impeller::TSize< Scalar >
impeller::Tessellator::VertexGenerator
An object which produces a list of vertices as |Point|s that tessellate a previously provided shape a...
Definition: tessellator.h:99
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::GeometryResult::type
PrimitiveType type
Definition: geometry.h:21
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:55
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:24
geometry.h
impeller::Geometry::GetPositionUVBuffer
virtual GeometryResult GetPositionUVBuffer(Rect texture_coverage, Matrix effect_transform, const ContentContext &renderer, const Entity &entity, RenderPass &pass) const =0
Definition: geometry.cc:142
impeller::GeometryResult
Definition: geometry.h:20
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
ellipse_geometry.h
impeller::Geometry::ComputePositionGeometry
static GeometryResult ComputePositionGeometry(const Tessellator::VertexGenerator &generator, const Entity &entity, RenderPass &pass)
Definition: geometry.cc:23
fill_path_geometry.h
impeller::VertexBufferBuilder::IterateVertices
void IterateVertices(const std::function< void(VertexType &)> &iterator)
Definition: vertex_buffer_builder.h:103
impeller::Geometry::MakeFillPath
static std::shared_ptr< Geometry > MakeFillPath(Path path, std::optional< Rect > inner_rect=std::nullopt)
Definition: geometry.cc:150
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:29
impeller::Geometry::MakeRect
static std::shared_ptr< Geometry > MakeRect(const Rect &rect)
Definition: geometry.cc:179
impeller::Join
Join
Definition: path.h:24
rect.h
impeller::Tessellator::VertexGenerator::GetTriangleType
virtual PrimitiveType GetTriangleType() const =0
Returns the |PrimitiveType| that describes the relationship among the list of vertices produced by th...
impeller::TPoint< Scalar >
impeller::VertexBufferBuilder::AppendVertex
VertexBufferBuilder & AppendVertex(VertexType_ vertex)
Definition: vertex_buffer_builder.h:65
impeller::Tessellator::VertexGenerator::GetVertexCount
virtual size_t GetVertexCount() const =0
Returns the number of vertices that the generator plans to produce, if known.
line_geometry.h
impeller::Geometry::MakeCircle
static std::shared_ptr< Geometry > MakeCircle(const Point &center, Scalar radius)
Definition: geometry.cc:194
circle_geometry.h
impeller::VertexBufferBuilder::Reserve
void Reserve(size_t count)
Definition: vertex_buffer_builder.h:48
round_rect_geometry.h
impeller::ComputeUVGeometryForRect
GeometryResult ComputeUVGeometryForRect(Rect source_rect, Rect texture_coverage, Matrix effect_transform, const ContentContext &renderer, const Entity &entity, RenderPass &pass)
Definition: geometry.cc:111
impeller
Definition: aiks_context.cc:10
impeller::Geometry::ComputePositionUVGeometry
static GeometryResult ComputePositionUVGeometry(const Tessellator::VertexGenerator &generator, const Matrix &uv_transform, const Entity &entity, RenderPass &pass)
Definition: geometry.cc:55
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::Cap
Cap
Definition: path.h:18
impeller::Geometry::MakeCover
static std::shared_ptr< Geometry > MakeCover()
Definition: geometry.cc:175
impeller::Geometry::MakeLine
static std::shared_ptr< Geometry > MakeLine(const Point &p0, const Point &p1, Scalar width, Cap cap)
Definition: geometry.cc:187