| Flutter Impeller |

Public Types | Public Member Functions | Static Public Attributes | List of all members
impeller::ComputeTessellator Class Reference

A utility that generates triangles of the specified fill type given a path. More...

`#include <compute_tessellator.h>`

## Public Types
enum | Status { Status::kCommandInvalid, Status::kTooManyComponents, Status::kOk }
enum | Style { Style::kStroke }

## Public Member Functions
| ComputeTessellator ()
| ~ComputeTessellator ()
ComputeTessellator & | SetStyle (Style value)
ComputeTessellator & | SetStrokeWidth (Scalar value)
ComputeTessellator & | SetStrokeJoin (Join value)
ComputeTessellator & | SetStrokeCap (Cap value)
ComputeTessellator & | SetMiterLimit (Scalar value)
ComputeTessellator & | SetCubicAccuracy (Scalar value)
ComputeTessellator & | SetQuadraticTolerance (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, e.g. because one of the buffer views are host visible and will be used without creating a blit pass to copy them back, the callback is used to determine when the GPU calculation is complete and its status. On Metal, no additional synchronization is needed as long as the buffers are not heap allocated, so no additional synchronization mechanism is provided. More...

## Static Public Attributes
static constexpr size_t | kMaxCubicCount = 512
static constexpr size_t | kMaxQuadCount = 2048
static constexpr size_t | kMaxLineCount = 4096
static constexpr size_t | kMaxComponentCount

## Detailed Description

A utility that generates triangles of the specified fill type given a path.

Definition at line 20 of file compute_tessellator.h.

## Member Enumeration Documentation

## ◆ Status

enum impeller::ComputeTessellator::Status
| strong

Enumerator
kCommandInvalid |
kTooManyComponents |
kOk |

Definition at line 32 of file compute_tessellator.h.

32 {
33 kCommandInvalid,
34 kTooManyComponents,
35 kOk,
36 };

## ◆ Style

enum impeller::ComputeTessellator::Style
| strong

Enumerator
kStroke |

Definition at line 38 of file compute_tessellator.h.

38 {
39 kStroke,
40 // TODO(dnfield): Implement kFill.
41 };

## Constructor & Destructor Documentation

## ◆ ComputeTessellator()

impeller::ComputeTessellator::ComputeTessellator | ( |  | ) |
| default

## ◆ ~ComputeTessellator()

impeller::ComputeTessellator::~ComputeTessellator | ( |  | ) |
| default

## Member Function Documentation

## ◆ SetCubicAccuracy()

ComputeTessellator & impeller::ComputeTessellator::SetCubicAccuracy | ( | Scalar | value | ) |

Definition at line 55 of file compute_tessellator.cc.

55 {
56 cubic_accuracy_ = value;
57 return *this;
58 }

## ◆ SetMiterLimit()

ComputeTessellator & impeller::ComputeTessellator::SetMiterLimit | ( | Scalar | value | ) |

Definition at line 51 of file compute_tessellator.cc.

51 {
52 miter_limit_ = value;
53 return *this;
54 }

## ◆ SetQuadraticTolerance()

ComputeTessellator & impeller::ComputeTessellator::SetQuadraticTolerance | ( | Scalar | value | ) |

Definition at line 59 of file compute_tessellator.cc.

59 {
60 quad_tolerance_ = value;
61 return *this;
62 }

## ◆ SetStrokeCap()

ComputeTessellator & impeller::ComputeTessellator::SetStrokeCap | ( | Cap | value | ) |

Definition at line 47 of file compute_tessellator.cc.

47 {
48 stroke_cap_ = value;
49 return *this;
50 }

## ◆ SetStrokeJoin()

ComputeTessellator & impeller::ComputeTessellator::SetStrokeJoin | ( | Join | value | ) |

Definition at line 43 of file compute_tessellator.cc.

43 {
44 stroke_join_ = value;
45 return *this;
46 }

## ◆ SetStrokeWidth()

ComputeTessellator & impeller::ComputeTessellator::SetStrokeWidth | ( | Scalar | value | ) |

Definition at line 38 of file compute_tessellator.cc.

38 {
39 stroke_width_ = value;
40 return *this;
41 }

Referenced by impeller::testing::TEST_P().

## ◆ SetStyle()

ComputeTessellator & impeller::ComputeTessellator::SetStyle | ( | Style | value | ) |

Definition at line 33 of file compute_tessellator.cc.

33 {
34 style_ = value;
35 return *this;
36 }

## ◆ Tessellate()

ComputeTessellator::Status impeller::ComputeTessellator::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, e.g. because one of the buffer views are host visible and will be used without creating a blit pass to copy them back, the callback is used to determine when the GPU calculation is complete and its status. On Metal, no additional synchronization is needed as long as the buffers are not heap allocated, so no additional synchronization mechanism is provided.

Returns
  A |Status| value indicating success or failure of the submission.

Definition at line 64 of file compute_tessellator.cc.

70 {
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) {
82 return Status::kTooManyComponents;
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,
99 sizeof(QuadraticPathComponent));
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()) {
136 return Status::kCommandInvalid;
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()) {
166 return Status::kCommandInvalid;
167 }
168 }
169
170 if (!pass->EncodeCommands()) {
171 return Status::kCommandInvalid;
172 }
173
174 if (!context->GetCommandQueue()->Submit({cmd_buffer}, callback).ok()) {
175 return Status::kCommandInvalid;
176 }
177
178 return Status::kOk;
179 }

References impeller::DeviceBuffer::AsBufferView(), impeller::HostBuffer::EmplaceStorageBuffer(), impeller::HostBuffer::EmplaceUniform(), impeller::Path::EnumerateComponents(), impeller::Path::GetComponentCount(), kCommandInvalid, impeller::Path::kCubic, impeller::Path::kLinear, kMaxCubicCount, kMaxLineCount, kMaxQuadCount, kOk, impeller::Path::kQuadratic, kStroke, and kTooManyComponents.

Referenced by impeller::testing::TEST_P().

## Member Data Documentation

## ◆ kMaxComponentCount

constexpr size_t impeller::ComputeTessellator::kMaxComponentCount
| static constexpr

Initial value:
=
kMaxCubicCount + kMaxQuadCount + kMaxLineCount

Definition at line 29 of file compute_tessellator.h.

## ◆ kMaxCubicCount

constexpr size_t impeller::ComputeTessellator::kMaxCubicCount = 512
| static constexpr

Definition at line 26 of file compute_tessellator.h.

Referenced by Tessellate().

## ◆ kMaxLineCount

constexpr size_t impeller::ComputeTessellator::kMaxLineCount = 4096
| static constexpr

Definition at line 28 of file compute_tessellator.h.

Referenced by Tessellate().

## ◆ kMaxQuadCount

constexpr size_t impeller::ComputeTessellator::kMaxQuadCount = 2048
| static constexpr

Definition at line 27 of file compute_tessellator.h.

Referenced by Tessellate().

The documentation for this class was generated from the following files:

- impeller/renderer/compute_tessellator.h
- impeller/renderer/compute_tessellator.cc

impeller::DeviceBuffer::AsBufferView
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
Definition: device_buffer.cc:18
impeller::ComputeTessellator::Status::kCommandInvalid
@ kCommandInvalid
impeller::ComputeTessellator::Status::kTooManyComponents
@ kTooManyComponents
impeller::Path::ComponentType::kLinear
@ kLinear
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::ComputeTessellator::kMaxCubicCount
static constexpr size_t kMaxCubicCount
Definition: compute_tessellator.h:26
impeller::ComputeTessellator::Style::kStroke
@ kStroke
impeller::ComputeTessellator::Status::kOk
@ kOk
impeller::ComputeTessellator::kMaxQuadCount
static constexpr size_t kMaxQuadCount
Definition: compute_tessellator.h:27
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:138
impeller::ComputeTessellator::kMaxLineCount
static constexpr size_t kMaxLineCount
Definition: compute_tessellator.h:28