Flutter Impeller
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 ()
 
ComputeTessellatorSetStyle (Style value)
 
ComputeTessellatorSetStrokeWidth (Scalar value)
 
ComputeTessellatorSetStrokeJoin (Join value)
 
ComputeTessellatorSetStrokeCap (Cap value)
 
ComputeTessellatorSetMiterLimit (Scalar value)
 
ComputeTessellatorSetCubicAccuracy (Scalar value)
 
ComputeTessellatorSetQuadraticTolerance (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

Enumerator
kCommandInvalid 
kTooManyComponents 
kOk 

Definition at line 32 of file compute_tessellator.h.

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

◆ Style

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) {
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()) {
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 }

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
staticconstexpr
Initial value:

Definition at line 29 of file compute_tessellator.h.

◆ kMaxCubicCount

constexpr size_t impeller::ComputeTessellator::kMaxCubicCount = 512
staticconstexpr

Definition at line 26 of file compute_tessellator.h.

Referenced by Tessellate().

◆ kMaxLineCount

constexpr size_t impeller::ComputeTessellator::kMaxLineCount = 4096
staticconstexpr

Definition at line 28 of file compute_tessellator.h.

Referenced by Tessellate().

◆ kMaxQuadCount

constexpr size_t impeller::ComputeTessellator::kMaxQuadCount = 2048
staticconstexpr

Definition at line 27 of file compute_tessellator.h.

Referenced by Tessellate().


The documentation for this class was generated from the following files:
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