Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
compute_tessellator.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
6
7#include <cstdint>
8
11#include "impeller/renderer/path_polyline.comp.h"
13#include "impeller/renderer/stroke.comp.h"
14
15namespace impeller {
16
19
20template <typename T>
21static std::shared_ptr<DeviceBuffer> CreateDeviceBuffer(
22 const std::shared_ptr<Context>& context,
23 const std::string& label,
26 desc.storage_mode = storage_mode;
27 desc.size = sizeof(T);
28 auto buffer = context->GetResourceAllocator()->CreateBuffer(desc);
29 buffer->SetLabel(label);
30 return buffer;
31}
32
34 style_ = value;
35 return *this;
36}
37
39 stroke_width_ = value;
40 return *this;
41}
42
44 stroke_join_ = value;
45 return *this;
46}
48 stroke_cap_ = value;
49 return *this;
50}
52 miter_limit_ = value;
53 return *this;
54}
56 cubic_accuracy_ = value;
57 return *this;
58}
60 quad_tolerance_ = value;
61 return *this;
62}
63
65 const Path& path,
66 HostBuffer& host_buffer,
67 const std::shared_ptr<Context>& context,
68 BufferView vertex_buffer,
69 BufferView vertex_buffer_count,
71 FML_DCHECK(style_ == Style::kStroke);
72 using PS = PathPolylineComputeShader;
73 using SS = StrokeComputeShader;
74
75 auto cubic_count = path.GetComponentCount(Path::ComponentType::kCubic);
76 auto quad_count = path.GetComponentCount(Path::ComponentType::kQuadratic) +
77 (cubic_count * 6);
78 auto line_count =
79 path.GetComponentCount(Path::ComponentType::kLinear) + (quad_count * 6);
80 if (cubic_count > kMaxCubicCount || quad_count > kMaxQuadCount ||
81 line_count > kMaxLineCount) {
83 }
84 PS::Cubics<kMaxCubicCount> cubics{.count = 0};
85 PS::Quads<kMaxQuadCount> quads{.count = 0};
86 PS::Lines<kMaxLineCount> lines{.count = 0};
87 PS::Components<kMaxComponentCount> components{.count = 0};
88 PS::Config config{.cubic_accuracy = cubic_accuracy_,
89 .quad_tolerance = quad_tolerance_};
90
91 path.EnumerateComponents(
92 [&lines, &components](size_t index, const LinearPathComponent& linear) {
93 ::memcpy(&lines.data[lines.count], &linear,
94 sizeof(LinearPathComponent));
95 components.data[components.count++] = {lines.count++, 2};
96 },
97 [&quads, &components](size_t index, const QuadraticPathComponent& quad) {
98 ::memcpy(&quads.data[quads.count], &quad,
100 components.data[components.count++] = {quads.count++, 3};
101 },
102 [&cubics, &components](size_t index, const CubicPathComponent& cubic) {
103 ::memcpy(&cubics.data[cubics.count], &cubic,
104 sizeof(CubicPathComponent));
105 components.data[components.count++] = {cubics.count++, 4};
106 },
107 [](size_t index, const ContourComponent& contour) {});
108
109 auto polyline_buffer =
110 CreateDeviceBuffer<PS::Polyline<2048>>(context, "Polyline");
111
112 auto cmd_buffer = context->CreateCommandBuffer();
113 auto pass = cmd_buffer->CreateComputePass();
114 FML_DCHECK(pass && pass->IsValid());
115
116 {
117 using PathPolylinePipelineBuilder = ComputePipelineBuilder<PS>;
118 auto pipeline_desc =
119 PathPolylinePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
120 FML_DCHECK(pipeline_desc.has_value());
121 auto compute_pipeline =
122 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
123 FML_DCHECK(compute_pipeline);
124
125 pass->SetPipeline(compute_pipeline);
126 pass->SetCommandLabel("Generate Polyline");
127
128 PS::BindConfig(*pass, host_buffer.EmplaceUniform(config));
129 PS::BindCubics(*pass, host_buffer.EmplaceStorageBuffer(cubics));
130 PS::BindQuads(*pass, host_buffer.EmplaceStorageBuffer(quads));
131 PS::BindLines(*pass, host_buffer.EmplaceStorageBuffer(lines));
132 PS::BindComponents(*pass, host_buffer.EmplaceStorageBuffer(components));
133 PS::BindPolyline(*pass, DeviceBuffer::AsBufferView(polyline_buffer));
134
135 if (!pass->Compute(ISize(line_count, 1)).ok()) {
137 }
138 }
139
140 {
141 using StrokePipelineBuilder = ComputePipelineBuilder<SS>;
142 auto pipeline_desc =
143 StrokePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
144 FML_DCHECK(pipeline_desc.has_value());
145 auto compute_pipeline =
146 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
147 FML_DCHECK(compute_pipeline);
148
149 pass->AddBufferMemoryBarrier();
150 pass->SetPipeline(compute_pipeline);
151 pass->SetCommandLabel("Compute Stroke");
152
153 SS::Config config{
154 .width = stroke_width_,
155 .cap = static_cast<uint32_t>(stroke_cap_),
156 .join = static_cast<uint32_t>(stroke_join_),
157 .miter_limit = miter_limit_,
158 };
159 SS::BindConfig(*pass, host_buffer.EmplaceUniform(config));
160
161 SS::BindPolyline(*pass, DeviceBuffer::AsBufferView(polyline_buffer));
162 SS::BindVertexBufferCount(*pass, std::move(vertex_buffer_count));
163 SS::BindVertexBuffer(*pass, std::move(vertex_buffer));
164
165 if (!pass->Compute(ISize(line_count, 1)).ok()) {
167 }
168 }
169
170 if (!pass->EncodeCommands()) {
172 }
173
174 if (!context->GetCommandQueue()->Submit({cmd_buffer}, callback).ok()) {
176 }
177
178 return Status::kOk;
179}
180
181} // namespace impeller
static bool ok(int result)
std::function< void(Status)> CompletionCallback
A utility that generates triangles of the specified fill type given a path.
static constexpr size_t kMaxCubicCount
ComputeTessellator & SetStrokeJoin(Join value)
ComputeTessellator & SetStrokeCap(Cap value)
static constexpr size_t kMaxQuadCount
ComputeTessellator & SetMiterLimit(Scalar value)
static constexpr size_t kMaxLineCount
ComputeTessellator & SetStrokeWidth(Scalar value)
ComputeTessellator & SetStyle(Style value)
ComputeTessellator & SetQuadraticTolerance(Scalar value)
ComputeTessellator & SetCubicAccuracy(Scalar value)
Status Tessellate(const Path &path, HostBuffer &host_buffer, const std::shared_ptr< Context > &context, BufferView vertex_buffer, BufferView vertex_buffer_count, const CommandBuffer::CompletionCallback &callback=nullptr) const
Generates triangles from the path. If the data needs to be synchronized back to the CPU,...
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition host_buffer.h:50
BufferView EmplaceStorageBuffer(const StorageBufferType &buffer)
Emplace storage buffer data onto the host buffer. Ensure that backend specific uniform alignment requ...
Definition host_buffer.h:72
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition path.h:51
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
static const uint8_t buffer[]
uint8_t value
#define FML_DCHECK(condition)
Definition logging.h:103
float Scalar
Definition scalar.h:18
StorageMode
Specified where the allocation resides and how it is used.
Definition formats.h:33
static std::shared_ptr< DeviceBuffer > CreateDeviceBuffer(const std::shared_ptr< Context > &context, const std::string &label, StorageMode storage_mode=StorageMode::kDevicePrivate)
#define T
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
static sk_sp< SkShader > linear(sk_sp< SkShader > shader)