| 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(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{
31 .type = PrimitiveType::kTriangleStrip,
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 {
137 return GeometryVertexType::kPosition;
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