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 
8 #include "impeller/renderer/path_polyline.comp.h"
10 #include "impeller/renderer/stroke.comp.h"
11 
12 namespace impeller {
13 
16 
17 template <typename T>
18 static std::shared_ptr<DeviceBuffer> CreateDeviceBuffer(
19  const std::shared_ptr<Context>& context,
20  const std::string& label,
23  desc.storage_mode = storage_mode;
24  desc.size = sizeof(T);
25  auto buffer = context->GetResourceAllocator()->CreateBuffer(desc);
26  buffer->SetLabel(label);
27  return buffer;
28 }
29 
31  style_ = value;
32  return *this;
33 }
34 
36  stroke_width_ = value;
37  return *this;
38 }
39 
41  stroke_join_ = value;
42  return *this;
43 }
45  stroke_cap_ = value;
46  return *this;
47 }
49  miter_limit_ = value;
50  return *this;
51 }
53  cubic_accuracy_ = value;
54  return *this;
55 }
57  quad_tolerance_ = value;
58  return *this;
59 }
60 
62  const Path& path,
63  const std::shared_ptr<Context>& context,
64  BufferView vertex_buffer,
65  BufferView vertex_buffer_count,
66  const CommandBuffer::CompletionCallback& callback) const {
67  FML_DCHECK(style_ == Style::kStroke);
68  using PS = PathPolylineComputeShader;
69  using SS = StrokeComputeShader;
70 
71  auto cubic_count = path.GetComponentCount(Path::ComponentType::kCubic);
72  auto quad_count = path.GetComponentCount(Path::ComponentType::kQuadratic) +
73  (cubic_count * 6);
74  auto line_count =
75  path.GetComponentCount(Path::ComponentType::kLinear) + (quad_count * 6);
76  if (cubic_count > kMaxCubicCount || quad_count > kMaxQuadCount ||
77  line_count > kMaxLineCount) {
79  }
80  PS::Cubics<kMaxCubicCount> cubics{.count = 0};
81  PS::Quads<kMaxQuadCount> quads{.count = 0};
82  PS::Lines<kMaxLineCount> lines{.count = 0};
83  PS::Components<kMaxComponentCount> components{.count = 0};
84  PS::Config config{.cubic_accuracy = cubic_accuracy_,
85  .quad_tolerance = quad_tolerance_};
86 
88  [&lines, &components](size_t index, const LinearPathComponent& linear) {
89  ::memcpy(&lines.data[lines.count], &linear,
90  sizeof(LinearPathComponent));
91  components.data[components.count++] = {lines.count++, 2};
92  },
93  [&quads, &components](size_t index, const QuadraticPathComponent& quad) {
94  ::memcpy(&quads.data[quads.count], &quad,
95  sizeof(QuadraticPathComponent));
96  components.data[components.count++] = {quads.count++, 3};
97  },
98  [&cubics, &components](size_t index, const CubicPathComponent& cubic) {
99  ::memcpy(&cubics.data[cubics.count], &cubic,
100  sizeof(CubicPathComponent));
101  components.data[components.count++] = {cubics.count++, 4};
102  },
103  [](size_t index, const ContourComponent& contour) {});
104 
105  auto polyline_buffer =
106  CreateDeviceBuffer<PS::Polyline<2048>>(context, "Polyline");
107 
108  auto cmd_buffer = context->CreateCommandBuffer();
109  auto pass = cmd_buffer->CreateComputePass();
110  FML_DCHECK(pass && pass->IsValid());
111 
112  {
113  using PathPolylinePipelineBuilder = ComputePipelineBuilder<PS>;
114  auto pipeline_desc =
115  PathPolylinePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
116  FML_DCHECK(pipeline_desc.has_value());
117  auto compute_pipeline =
118  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
119  FML_DCHECK(compute_pipeline);
120 
121  pass->SetGridSize(ISize(line_count, 1));
122  pass->SetThreadGroupSize(ISize(line_count, 1));
123 
124  ComputeCommand cmd;
125  DEBUG_COMMAND_INFO(cmd, "Generate Polyline");
126  cmd.pipeline = compute_pipeline;
127 
128  PS::BindConfig(cmd, pass->GetTransientsBuffer().EmplaceUniform(config));
129  PS::BindCubics(cmd,
130  pass->GetTransientsBuffer().EmplaceStorageBuffer(cubics));
131  PS::BindQuads(cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(quads));
132  PS::BindLines(cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(lines));
133  PS::BindComponents(
134  cmd, pass->GetTransientsBuffer().EmplaceStorageBuffer(components));
135  PS::BindPolyline(cmd, polyline_buffer->AsBufferView());
136 
137  if (!pass->AddCommand(std::move(cmd))) {
139  }
140  }
141 
142  {
143  using StrokePipelineBuilder = ComputePipelineBuilder<SS>;
144  auto pipeline_desc =
145  StrokePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
146  FML_DCHECK(pipeline_desc.has_value());
147  auto compute_pipeline =
148  context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
149  FML_DCHECK(compute_pipeline);
150 
151  pass->SetGridSize(ISize(line_count, 1));
152  pass->SetThreadGroupSize(ISize(line_count, 1));
153 
154  ComputeCommand cmd;
155  DEBUG_COMMAND_INFO(cmd, "Compute Stroke");
156  cmd.pipeline = compute_pipeline;
157 
158  SS::Config config{
159  .width = stroke_width_,
160  .cap = static_cast<uint32_t>(stroke_cap_),
161  .join = static_cast<uint32_t>(stroke_join_),
162  .miter_limit = miter_limit_,
163  };
164  SS::BindConfig(cmd, pass->GetTransientsBuffer().EmplaceUniform(config));
165 
166  SS::BindPolyline(cmd, polyline_buffer->AsBufferView());
167  SS::BindVertexBufferCount(cmd, std::move(vertex_buffer_count));
168  SS::BindVertexBuffer(cmd, std::move(vertex_buffer));
169 
170  if (!pass->AddCommand(std::move(cmd))) {
172  }
173  }
174 
175  if (!pass->EncodeCommands()) {
177  }
178 
179  if (!cmd_buffer->SubmitCommands(callback)) {
181  }
182 
183  return Status::kOk;
184 }
185 
186 } // namespace impeller
impeller::ComputeTessellator::Status::kCommandInvalid
@ kCommandInvalid
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:31
impeller::LinearPathComponent
Definition: path_component.h:27
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::ComputeTessellator::Status::kTooManyComponents
@ kTooManyComponents
impeller::Path::ComponentType::kLinear
@ kLinear
impeller::DeviceBufferDescriptor
Definition: device_buffer_descriptor.h:13
impeller::ComputeTessellator::Status
Status
Definition: compute_tessellator.h:31
impeller::ComputeCommand::pipeline
std::shared_ptr< Pipeline< ComputePipelineDescriptor > > pipeline
Definition: compute_command.h:47
impeller::Path::ComponentType::kCubic
@ kCubic
impeller::ComputeTessellator::SetStrokeCap
ComputeTessellator & SetStrokeCap(Cap value)
Definition: compute_tessellator.cc:44
impeller::Path::ComponentType::kQuadratic
@ kQuadratic
impeller::DeviceBufferDescriptor::size
size_t size
Definition: device_buffer_descriptor.h:15
impeller::ComputeTessellator::SetQuadraticTolerance
ComputeTessellator & SetQuadraticTolerance(Scalar value)
Definition: compute_tessellator.cc:56
compute_tessellator.h
impeller::ComputeTessellator::kMaxCubicCount
static constexpr size_t kMaxCubicCount
Definition: compute_tessellator.h:25
impeller::ComputeTessellator::SetMiterLimit
ComputeTessellator & SetMiterLimit(Scalar value)
Definition: compute_tessellator.cc:48
impeller::CommandBuffer::CompletionCallback
std::function< void(Status)> CompletionCallback
Definition: command_buffer.h:54
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:18
impeller::ComputeTessellator
A utility that generates triangles of the specified fill type given a path.
Definition: compute_tessellator.h:19
impeller::ComputeTessellator::SetStrokeJoin
ComputeTessellator & SetStrokeJoin(Join value)
Definition: compute_tessellator.cc:40
impeller::ComputeTessellator::Style::kStroke
@ kStroke
impeller::ComputeTessellator::Status::kOk
@ kOk
impeller::ComputeTessellator::SetCubicAccuracy
ComputeTessellator & SetCubicAccuracy(Scalar value)
Definition: compute_tessellator.cc:52
impeller::StorageMode
StorageMode
Specified where the allocation resides and how it is used.
Definition: formats.h:27
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:125
impeller::ComputeTessellator::Style
Style
Definition: compute_tessellator.h:37
impeller::Path
Paths are lightweight objects that describe a collection of linear, quadratic, or cubic segments....
Definition: path.h:54
impeller::ComputeTessellator::SetStrokeWidth
ComputeTessellator & SetStrokeWidth(Scalar value)
Definition: compute_tessellator.cc:35
impeller::StorageMode::kDevicePrivate
@ kDevicePrivate
impeller::DeviceBufferDescriptor::storage_mode
StorageMode storage_mode
Definition: device_buffer_descriptor.h:14
impeller::ComputeTessellator::Tessellate
Status Tessellate(const Path &path, 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:61
impeller::ComputeTessellator::kMaxQuadCount
static constexpr size_t kMaxQuadCount
Definition: compute_tessellator.h:26
pipeline_library.h
impeller::ComputeTessellator::SetStyle
ComputeTessellator & SetStyle(Style value)
Definition: compute_tessellator.cc:30
impeller::CubicPathComponent
Definition: path_component.h:90
impeller::ISize
TSize< int64_t > ISize
Definition: size.h:136
command_buffer.h
impeller::ComputeCommand
An object used to specify compute work to the GPU along with references to resources the GPU will use...
Definition: compute_command.h:43
impeller::BufferView
Definition: buffer_view.h:13
impeller::Join
Join
Definition: path.h:23
impeller::Path::GetComponentCount
size_t GetComponentCount(std::optional< ComponentType > type={}) const
Definition: path.cc:32
impeller::ComputeTessellator::kMaxLineCount
static constexpr size_t kMaxLineCount
Definition: compute_tessellator.h:27
impeller::ContourComponent
Definition: path_component.h:137
impeller::ComputeTessellator::~ComputeTessellator
~ComputeTessellator()
impeller::ComputeTessellator::ComputeTessellator
ComputeTessellator()
impeller
Definition: aiks_context.cc:10
impeller::QuadraticPathComponent
Definition: path_component.h:50
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:28