Flutter Impeller
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 
15 namespace impeller {
16 
19 
20 template <typename T>
21 static 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,
70  const CommandBuffer::CompletionCallback& callback) const {
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 
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 }
180 
181 } // namespace impeller
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
host_buffer.h
impeller::LinearPathComponent
Definition: path_component.h:29
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::ComputeTessellator::Status::kTooManyComponents
@ kTooManyComponents
impeller::Path::ComponentType::kLinear
@ kLinear
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:14
impeller::ComputeTessellator::Status
Status
Definition: compute_tessellator.h:32
impeller::HostBuffer
Definition: host_buffer.h:28
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::ComputeTessellator::SetStrokeCap
ComputeTessellator & SetStrokeCap(Cap value)
Definition: compute_tessellator.cc:47
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::DeviceBufferDescriptor::size
size_t size
Definition: device_buffer_descriptor.h:16
impeller::ComputeTessellator::SetQuadraticTolerance
ComputeTessellator & SetQuadraticTolerance(Scalar value)
Definition: compute_tessellator.cc:59
compute_tessellator.h
impeller::ComputeTessellator::kMaxCubicCount
static constexpr size_t kMaxCubicCount
Definition: compute_tessellator.h:26
impeller::ComputeTessellator::SetMiterLimit
ComputeTessellator & SetMiterLimit(Scalar value)
Definition: compute_tessellator.cc:51
impeller::CommandBuffer::CompletionCallback
std::function< void(Status)> CompletionCallback
Definition: command_buffer.h:55
impeller::CreateDeviceBuffer
static std::shared_ptr< DeviceBuffer > CreateDeviceBuffer(const std::shared_ptr< Context > &context, const std::string &label, StorageMode storage_mode=StorageMode::kDevicePrivate)
Definition: compute_tessellator.cc:21
impeller::ComputeTessellator
A utility that generates triangles of the specified fill type given a path.
Definition: compute_tessellator.h:20
impeller::ComputeTessellator::SetStrokeJoin
ComputeTessellator & SetStrokeJoin(Join value)
Definition: compute_tessellator.cc:43
impeller::ComputeTessellator::Style::kStroke
@ kStroke
impeller::TSize< int64_t >
impeller::ComputeTessellator::Status::kOk
@ kOk
impeller::ComputeTessellator::SetCubicAccuracy
ComputeTessellator & SetCubicAccuracy(Scalar value)
Definition: compute_tessellator.cc:55
impeller::StorageMode
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:33
impeller::Path::EnumerateComponents
void EnumerateComponents(const Applier< LinearPathComponent > &linear_applier, const Applier< QuadraticPathComponent > &quad_applier, const Applier< CubicPathComponent > &cubic_applier, const Applier< ContourComponent > &contour_applier) const
Definition: path.cc:63
impeller::ComputeTessellator::Style
Style
Definition: compute_tessellator.h:38
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:51
impeller::ComputeTessellator::SetStrokeWidth
ComputeTessellator & SetStrokeWidth(Scalar value)
Definition: compute_tessellator.cc:38
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::DeviceBufferDescriptor::storage_mode
StorageMode storage_mode
Definition: device_buffer_descriptor.h:15
impeller::ComputeTessellator::kMaxQuadCount
static constexpr size_t kMaxQuadCount
Definition: compute_tessellator.h:27
pipeline_library.h
impeller::ComputeTessellator::SetStyle
ComputeTessellator & SetStyle(Style value)
Definition: compute_tessellator.cc:33
impeller::CubicPathComponent
Definition: path_component.h:99
command_buffer.h
impeller::BufferView
Definition: buffer_view.h:15
impeller::Join
Join
Definition: path.h:23
impeller::ComputeTessellator::Tessellate
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,...
Definition: compute_tessellator.cc:64
impeller::Path::GetComponentCount
size_t GetComponentCount(std::optional< ComponentType > type={}) const
Definition: path.cc:34
impeller::ComputeTessellator::kMaxLineCount
static constexpr size_t kMaxLineCount
Definition: compute_tessellator.h:28
impeller::HostBuffer::EmplaceUniform
BufferView EmplaceUniform(const UniformType &uniform)
Emplace uniform data onto the host buffer. Ensure that backend specific uniform alignment requirement...
Definition: host_buffer.h:50
impeller::HostBuffer::EmplaceStorageBuffer
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
impeller::ContourComponent
Definition: path_component.h:152
impeller::ComputeTessellator::~ComputeTessellator
~ComputeTessellator()
impeller::ComputeTessellator::ComputeTessellator
ComputeTessellator()
impeller
Definition: aiks_blur_unittests.cc:20
impeller::QuadraticPathComponent
Definition: path_component.h:53
impeller::Cap
Cap
Definition: path.h:17
impeller::ComputePipelineBuilder
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
Definition: compute_pipeline_builder.h:25