7 #include "fml/logging.h"
16 std::optional<Rect> inner_rect)
17 : path_(path), inner_rect_(inner_rect) {}
26 if (bounding_box.has_value() && bounding_box->IsEmpty()) {
39 VertexBuffer vertex_buffer;
44 [&vertex_buffer, &host_buffer](
45 const float* vertices,
size_t vertices_count,
46 const uint16_t* indices,
size_t indices_count) {
47 vertex_buffer.vertex_buffer = host_buffer.Emplace(
48 vertices, vertices_count * sizeof(float) * 2, alignof(float));
49 if (indices != nullptr) {
50 vertex_buffer.index_buffer = host_buffer.Emplace(
51 indices, indices_count * sizeof(uint16_t), alignof(uint16_t));
52 vertex_buffer.vertex_count = indices_count;
53 vertex_buffer.index_type = IndexType::k16bit;
55 vertex_buffer.index_buffer = {};
56 vertex_buffer.vertex_count = vertices_count;
64 return GeometryResult{
66 .vertex_buffer = vertex_buffer,
75 vertex_buffer.vertex_buffer = host_buffer.Emplace(
76 points.data(), points.size() *
sizeof(
Point),
alignof(
Point));
77 vertex_buffer.index_buffer = {}, vertex_buffer.vertex_count = points.size();
78 vertex_buffer.index_type = IndexType::kNone;
80 return GeometryResult{
81 .type = PrimitiveType::kTriangleStrip,
82 .vertex_buffer = vertex_buffer,
84 .mode = GetResultMode(),
89 GeometryResult FillPathGeometry::GetPositionUVBuffer(
90 Rect texture_coverage,
91 Matrix effect_transform,
92 const ContentContext& renderer,
94 RenderPass& pass)
const {
95 using VS = TextureFillVertexShader;
97 const auto& bounding_box = path_.GetBoundingBox();
98 if (bounding_box.has_value() && bounding_box->IsEmpty()) {
99 return GeometryResult{
100 .type = PrimitiveType::kTriangle,
105 .index_type = IndexType::k16bit,
107 .transform = pass.GetOrthographicTransform() * entity.GetTransform(),
112 texture_coverage.GetNormalizingTransform() * effect_transform;
114 if constexpr (!ContentContext::kEnableStencilThenCover) {
115 if (!path_.IsConvex()) {
116 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
117 auto tesselation_result = renderer.GetTessellator()->Tessellate(
118 path_, entity.GetTransform().GetMaxBasisLength(),
119 [&vertex_builder, &uv_transform](
120 const float* vertices,
size_t vertices_count,
121 const uint16_t* indices,
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]};
126 data.texture_coords = uv_transform * vtx;
127 vertex_builder.AppendVertex(data);
129 FML_DCHECK(vertex_builder.GetVertexCount() == vertices_count);
130 if (indices !=
nullptr) {
131 for (
auto i = 0u; i < indices_count; i++) {
132 vertex_builder.AppendIndex(indices[i]);
137 if (tesselation_result != Tessellator::Result::kSuccess) {
140 return GeometryResult{
141 .type = PrimitiveType::kTriangle,
143 vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()),
144 .transform = entity.GetShaderTransform(pass),
149 auto points = renderer.GetTessellator()->TessellateConvex(
150 path_, entity.GetTransform().GetMaxBasisLength());
152 VertexBufferBuilder<VS::PerVertexData> vertex_builder;
153 vertex_builder.Reserve(points.size());
154 for (
auto i = 0u; i < points.size(); i++) {
155 VS::PerVertexData data;
156 data.position = points[i];
157 data.texture_coords = uv_transform * points[i];
158 vertex_builder.AppendVertex(data);
161 return GeometryResult{
162 .type = PrimitiveType::kTriangleStrip,
164 vertex_builder.CreateVertexBuffer(renderer.GetTransientsBuffer()),
165 .transform = entity.GetShaderTransform(pass),
166 .mode = GetResultMode(),
170 GeometryResult::Mode FillPathGeometry::GetResultMode()
const {
171 const auto& bounding_box = path_.GetBoundingBox();
172 if (!ContentContext::kEnableStencilThenCover || path_.IsConvex() ||
173 (bounding_box.has_value() && bounding_box->IsEmpty())) {
174 return GeometryResult::Mode::kNormal;
177 switch (path_.GetFillType()) {
178 case FillType::kNonZero:
179 return GeometryResult::Mode::kNonZero;
181 return GeometryResult::Mode::kEvenOdd;
191 std::optional<Rect> FillPathGeometry::GetCoverage(
192 const Matrix& transform)
const {
193 return path_.GetTransformedBoundingBox(transform);
196 bool FillPathGeometry::CoversArea(
const Matrix& transform,
197 const Rect& rect)
const {
198 if (!inner_rect_.has_value()) {