| Flutter Impeller |

compute_subgroup_unittests.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
5 #include <future>
6 #include <numeric>
7
8 #include "compute_tessellator.h"
9 #include "flutter/fml/synchronization/waitable_event.h"
10 #include "flutter/fml/time/time_point.h"
11 #include "flutter/testing/testing.h"
12 #include "gmock/gmock.h"
13 #include "impeller/base/strings.h"
14 #include "impeller/core/formats.h"
15 #include "impeller/display_list/skia_conversions.h"
16 #include "impeller/entity/contents/content_context.h"
17 #include "impeller/fixtures/golden_paths.h"
18 #include "impeller/fixtures/sample.comp.h"
19 #include "impeller/fixtures/stage1.comp.h"
20 #include "impeller/fixtures/stage2.comp.h"
21 #include "impeller/geometry/path.h"
22 #include "impeller/geometry/path_builder.h"
23 #include "impeller/geometry/path_component.h"
24 #include "impeller/playground/compute_playground_test.h"
25 #include "impeller/renderer/command_buffer.h"
26 #include "impeller/renderer/compute_command.h"
27 #include "impeller/renderer/compute_pipeline_builder.h"
28 #include "impeller/renderer/compute_tessellator.h"
29 #include "impeller/renderer/path_polyline.comp.h"
30 #include "impeller/renderer/pipeline_library.h"
31 #include "impeller/renderer/render_pass.h"
32 #include "impeller/renderer/stroke.comp.h"
33 #include "third_party/imgui/imgui.h"
34 #include "third_party/skia/include/utils/SkParsePath.h"
35
36 namespace impeller {
37 namespace testing {
38
39 using ComputeSubgroupTest = ComputePlaygroundTest;
40 INSTANTIATE_COMPUTE_SUITE(ComputeSubgroupTest);
41
42 TEST_P(ComputeSubgroupTest, CapabilitiesSuportSubgroups) {
43 auto context = GetContext();
44 ASSERT_TRUE(context);
45 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
46 }
47
48 TEST_P(ComputeSubgroupTest, PathPlayground) {
49 // Renders stroked SVG paths in an interactive playground.
50 using SS = StrokeComputeShader;
51
52 auto context = GetContext();
53 ASSERT_TRUE(context);
54 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
55 char svg_path_data[16384] =
56 "M140 20 "
57 "C73 20 20 74 20 140 "
58 "c0 135 136 170 228 303 "
59 "88-132 229-173 229-303 "
60 "0-66-54-120-120-120 "
61 "-48 0-90 28-109 69 "
62 "-19-41-60-69-108-69z";
63 size_t vertex_count = 0;
64 Scalar stroke_width = 1.0;
65
66 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
67 context, "VertexBuffer");
68 auto vertex_buffer_count =
69 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
70 "VertexCount");
71
72 auto callback = [&](RenderPass& pass) -> bool {
73 ::memset(vertex_buffer_count->AsBufferView().contents, 0,
74 sizeof(SS::VertexBufferCount));
75 ::memset(vertex_buffer->AsBufferView().contents, 0,
76 sizeof(SS::VertexBuffer<2048>));
77 const auto* main_viewport = ImGui::GetMainViewport();
78 ImGui::SetNextWindowPos(
79 ImVec2(main_viewport->WorkPos.x + 650, main_viewport->WorkPos.y + 20));
80 ImGui::Begin("Path data", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
81 ImGui::InputTextMultiline("Path", svg_path_data,
82 IM_ARRAYSIZE(svg_path_data));
83 ImGui::DragFloat("Stroke width", &stroke_width, .1, 0.0, 25.0);
84
85 SkPath sk_path;
86 if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) {
87 std::promise<bool> promise;
88 auto future = promise.get_future();
89
90 auto path = skia_conversions::ToPath(sk_path);
91 auto status =
92 ComputeTessellator{}
93 .SetStrokeWidth(stroke_width)
94 .Tessellate(
95 path, context, vertex_buffer->AsBufferView(),
96 vertex_buffer_count->AsBufferView(),
97 [vertex_buffer_count, &vertex_count,
98 &promise](CommandBuffer::Status status) {
99 vertex_count =
100 reinterpret_cast<SS::VertexBufferCount*>(
101 vertex_buffer_count->AsBufferView().contents)
102 ->count;
103 promise.set_value(status ==
104 CommandBuffer::Status::kCompleted);
105 });
106 switch (status) {
107 case ComputeTessellator::Status::kCommandInvalid:
108 ImGui::Text("Failed to submit compute job (invalid command)");
109 break;
110 case ComputeTessellator::Status::kTooManyComponents:
111 ImGui::Text("Failed to submit compute job (too many components) ");
112 break;
113 case ComputeTessellator::Status::kOk:
114 break;
115 }
116 if (!future.get()) {
117 ImGui::Text("Failed to submit compute job.");
118 return false;
119 }
120 if (vertex_count > 0) {
121 ImGui::Text("Vertex count: %zu", vertex_count);
122 }
123 } else {
124 ImGui::Text("Failed to parse path data");
125 }
126 ImGui::End();
127
128 ContentContext renderer(context, nullptr);
129 if (!renderer.IsValid()) {
130 return false;
131 }
132
133 using VS = SolidFillPipeline::VertexShader;
134
135 Command cmd;
136 DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
137 cmd.stencil_reference = 0;
138
139 ContentContextOptions options;
140 options.sample_count = pass.GetRenderTarget().GetSampleCount();
141 options.color_attachment_pixel_format =
142 pass.GetRenderTarget().GetRenderTargetPixelFormat();
143 options.has_stencil_attachment =
144 pass.GetRenderTarget().GetStencilAttachment().has_value();
145 options.blend_mode = BlendMode::kSourceIn;
146 options.primitive_type = PrimitiveType::kTriangleStrip;
147 options.stencil_compare = CompareFunction::kEqual;
148 options.stencil_operation = StencilOperation::kIncrementClamp;
149
150 cmd.pipeline = renderer.GetSolidFillPipeline(options);
151
152 auto count = reinterpret_cast<SS::VertexBufferCount*>(
153 vertex_buffer_count->AsBufferView().contents)
154 ->count;
155
156 VertexBuffer render_vertex_buffer{
157 .vertex_buffer = vertex_buffer->AsBufferView(),
158 .vertex_count = count,
159 .index_type = IndexType::kNone};
160 cmd.BindVertices(render_vertex_buffer);
161
162 VS::FrameInfo frame_info;
163 auto world_matrix = Matrix::MakeScale(GetContentScale());
164 frame_info.mvp =
165 Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
166 frame_info.color = Color::Red().Premultiply();
167 VS::BindFrameInfo(cmd,
168 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
169
170 if (!pass.AddCommand(std::move(cmd))) {
171 return false;
172 }
173
174 return true;
175 };
176 ASSERT_TRUE(OpenPlaygroundHere(callback));
177 }
178
179 TEST_P(ComputeSubgroupTest, LargePath) {
180 // The path in here is large enough to highlight issues around exceeding
181 // subgroup size.
182 using SS = StrokeComputeShader;
183
184 auto context = GetContext();
185 ASSERT_TRUE(context);
186 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
187 size_t vertex_count = 0;
188 Scalar stroke_width = 1.0;
189
190 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
191 context, "VertexBuffer");
192 auto vertex_buffer_count =
193 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
194 "VertexCount");
195
196 auto complex_path =
197 PathBuilder{}
198 .MoveTo({359.934, 96.6335})
199 .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
200 {354.673, 96.8895})
201 .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
202 {354.367, 96.9075})
203 .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
204 {349.259, 97.2355})
205 .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
206 {348.625, 97.2834})
207 .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
208 {343.789, 97.6722})
209 .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
210 {342.703, 97.7734})
211 .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
212 {338.246, 98.207})
213 .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
214 {336.612, 98.3894})
215 .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
216 {332.623, 98.8476})
217 .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
218 {332.237, 98.8982})
219 .LineTo({332.237, 102.601})
220 .LineTo({321.778, 102.601})
221 .LineTo({321.778, 100.382})
222 .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
223 {321.161, 100.476})
224 .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
225 {315.332, 101.479})
226 .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
227 {315.301, 101.484})
228 .LineTo({310.017, 105.94})
229 .LineTo({309.779, 105.427})
230 .LineTo({314.403, 101.651})
231 .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
232 {314.368, 101.658})
233 .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
234 {308.846, 102.748})
235 .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
236 .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
237 {303.425, 103.936})
238 .LineTo({299.105, 107.578})
239 .LineTo({298.867, 107.065})
240 .LineTo({302.394, 104.185})
241 .LineTo({302.412, 104.171})
242 .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
243 {299.344, 104.921})
244 .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
245 .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
246 {291.462, 106.979})
247 .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
248 {290.471, 107.257})
249 .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
250 {287.449, 108.139})
251 .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
252 {284.536, 109.035})
253 .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
254 {281.952, 109.859})
255 .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
256 {279.633, 110.638})
257 .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
258 {276.803, 111.607})
259 .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
260 {276.672, 111.653})
261 .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
262 {271.721, 113.463})
263 .LineTo({271.717, 113.449})
264 .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
265 {270.963, 113.628})
266 .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
267 {270.748, 113.682})
268 .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
269 {269.839, 113.926})
270 .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
271 {269.681, 113.972})
272 .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
273 {268.756, 114.239})
274 .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
275 {268.367, 114.354})
276 .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
277 {267.752, 114.54})
278 .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
279 {253.564, 119.252})
280 .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
281 {253.538, 119.261})
282 .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
283 {248.189, 121.131})
284 .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
285 .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
286 {245.975, 121.912})
287 .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
288 {244.698, 122.364})
289 .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
290 {242.794, 123.04})
291 .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
292 {240.961, 123.693})
293 .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
294 {240.052, 124.018})
295 .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
296 .LineTo({237.164, 125.003})
297 .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
298 {235.81, 125.538})
299 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
300 {234.592, 125.977})
301 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
302 {234.59, 125.977})
303 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
304 {192.381, 141.429})
305 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
306 .LineTo({360, 160})
307 .LineTo({360, 119.256})
308 .LineTo({360, 106.332})
309 .LineTo({360, 96.6307})
310 .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
311 {359.934, 96.6335})
312 .Close()
313 .TakePath();
314
315 auto callback = [&](RenderPass& pass) -> bool {
316 ::memset(vertex_buffer_count->AsBufferView().contents, 0,
317 sizeof(SS::VertexBufferCount));
318 ::memset(vertex_buffer->AsBufferView().contents, 0,
319 sizeof(SS::VertexBuffer<2048>));
320
321 ComputeTessellator{}
322 .SetStrokeWidth(stroke_width)
323 .Tessellate(
324 complex_path, context, vertex_buffer->AsBufferView(),
325 vertex_buffer_count->AsBufferView(),
326 [vertex_buffer_count, &vertex_count](CommandBuffer::Status status) {
327 vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
328 vertex_buffer_count->AsBufferView().contents)
329 ->count;
330 });
331
332 ContentContext renderer(context, nullptr);
333 if (!renderer.IsValid()) {
334 return false;
335 }
336
337 using VS = SolidFillPipeline::VertexShader;
338
339 Command cmd;
340 DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
341 cmd.stencil_reference = 0;
342
343 ContentContextOptions options;
344 options.sample_count = pass.GetRenderTarget().GetSampleCount();
345 options.color_attachment_pixel_format =
346 pass.GetRenderTarget().GetRenderTargetPixelFormat();
347 options.has_stencil_attachment =
348 pass.GetRenderTarget().GetStencilAttachment().has_value();
349 options.blend_mode = BlendMode::kSourceIn;
350 options.primitive_type = PrimitiveType::kTriangleStrip;
351 options.stencil_compare = CompareFunction::kEqual;
352 options.stencil_operation = StencilOperation::kIncrementClamp;
353
354 cmd.pipeline = renderer.GetSolidFillPipeline(options);
355
356 auto count = reinterpret_cast<SS::VertexBufferCount*>(
357 vertex_buffer_count->AsBufferView().contents)
358 ->count;
359
360 VertexBuffer render_vertex_buffer{
361 .vertex_buffer = vertex_buffer->AsBufferView(),
362 .vertex_count = count,
363 .index_type = IndexType::kNone};
364 cmd.BindVertices(render_vertex_buffer);
365
366 VS::FrameInfo frame_info;
367 auto world_matrix = Matrix::MakeScale(GetContentScale());
368 frame_info.mvp =
369 Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
370 frame_info.color = Color::Red().Premultiply();
371 VS::BindFrameInfo(cmd,
372 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
373
374 if (!pass.AddCommand(std::move(cmd))) {
375 return false;
376 }
377
378 return true;
379 };
380 ASSERT_TRUE(OpenPlaygroundHere(callback));
381 }
382
383 TEST_P(ComputeSubgroupTest, QuadAndCubicInOnePath) {
384 using SS = StrokeComputeShader;
385
386 auto context = GetContext();
387 ASSERT_TRUE(context);
388 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
389
390 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
391 context, "VertexBuffer");
392 auto vertex_buffer_count =
393 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
394 "VertexBufferCount");
395
396 auto path = PathBuilder{}
397 .AddCubicCurve({140, 20}, {73, 20}, {20, 74}, {20, 140})
398 .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42})
399 .TakePath();
400
401 auto tessellator = ComputeTessellator{};
402
403 fml::AutoResetWaitableEvent latch;
404
405 auto status = tessellator.Tessellate(
406 path, context, vertex_buffer->AsBufferView(),
407 vertex_buffer_count->AsBufferView(),
408 [&latch](CommandBuffer::Status status) {
409 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
410 latch.Signal();
411 });
412
413 ASSERT_EQ(status, ComputeTessellator::Status::kOk);
414
415 auto callback = [&](RenderPass& pass) -> bool {
416 ContentContext renderer(context, nullptr);
417 if (!renderer.IsValid()) {
418 return false;
419 }
420
421 using VS = SolidFillPipeline::VertexShader;
422
423 Command cmd;
424 DEBUG_COMMAND_INFO(cmd, "Draw Stroke");
425 cmd.stencil_reference = 0;
426
427 ContentContextOptions options;
428 options.sample_count = pass.GetRenderTarget().GetSampleCount();
429 options.color_attachment_pixel_format =
430 pass.GetRenderTarget().GetRenderTargetPixelFormat();
431 options.has_stencil_attachment =
432 pass.GetRenderTarget().GetStencilAttachment().has_value();
433 options.blend_mode = BlendMode::kSourceIn;
434 options.primitive_type = PrimitiveType::kTriangleStrip;
435 options.stencil_compare = CompareFunction::kEqual;
436 options.stencil_operation = StencilOperation::kIncrementClamp;
437
438 cmd.pipeline = renderer.GetSolidFillPipeline(options);
439
440 auto count = reinterpret_cast<SS::VertexBufferCount*>(
441 vertex_buffer_count->AsBufferView().contents)
442 ->count;
443
444 VertexBuffer render_vertex_buffer{
445 .vertex_buffer = vertex_buffer->AsBufferView(),
446 .vertex_count = count,
447 .index_type = IndexType::kNone};
448 cmd.BindVertices(render_vertex_buffer);
449
450 VS::FrameInfo frame_info;
451 auto world_matrix = Matrix::MakeScale(GetContentScale());
452 frame_info.mvp =
453 Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * world_matrix;
454 frame_info.color = Color::Red().Premultiply();
455 VS::BindFrameInfo(cmd,
456 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
457
458 if (!pass.AddCommand(std::move(cmd))) {
459 return false;
460 }
461
462 return true;
463 };
464 ASSERT_TRUE(OpenPlaygroundHere(callback));
465
466 // The latch is down here because it's expected that on Metal the backend
467 // will take care of synchronizing the buffer between the compute and render
468 // pass usages, since it's not MTLHeap allocated. However, if playgrounds
469 // are disabled, no render pass actually gets submitted and we need to do a
470 // CPU latch here.
471 latch.Wait();
472
473 auto vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
474 vertex_buffer_count->AsBufferView().contents)
475 ->count;
476 EXPECT_EQ(vertex_count, golden_cubic_and_quad_points.size());
477 auto vertex_buffer_data = reinterpret_cast<SS::VertexBuffer<2048>*>(
478 vertex_buffer->AsBufferView().contents);
479 for (size_t i = 0; i < vertex_count; i++) {
480 EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].x -
481 vertex_buffer_data->position[i].x),
482 1e-3);
483 EXPECT_LT(std::abs(golden_cubic_and_quad_points[i].y -
484 vertex_buffer_data->position[i].y),
485 1e-3);
486 }
487 }
488
489 } // namespace testing
490 } // namespace impeller
golden_paths.h
impeller::ComputeTessellator::Status::kCommandInvalid
@ kCommandInvalid
path.h
impeller::Command
An object used to specify work to the GPU along with references to resources the GPU will used when d...
Definition: command.h:99
DEBUG_COMMAND_INFO
#define DEBUG_COMMAND_INFO(obj, arg)
Definition: command.h:31
impeller::Scalar
float Scalar
Definition: scalar.h:15
impeller::ComputeTessellator::Status::kTooManyComponents
@ kTooManyComponents
impeller::Color::Red
static constexpr Color Red()
Definition: color.h:262
impeller::VertexBuffer
Definition: vertex_buffer.h:12
formats.h
impeller::PathBuilder
Definition: path_builder.h:13
impeller::BlendMode::kSourceIn
@ kSourceIn
impeller::ContentContextOptions::blend_mode
BlendMode blend_mode
Definition: content_context.h:304
impeller::ComputePlaygroundTest
Definition: compute_playground_test.h:18
impeller::testing::golden_cubic_and_quad_points
std::vector< Point > golden_cubic_and_quad_points
Definition: golden_paths.h:15
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:13
compute_tessellator.h
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::ComputeTessellator
A utility that generates triangles of the specified fill type given a path.
Definition: compute_tessellator.h:19
impeller::ContentContextOptions::stencil_compare
CompareFunction stencil_compare
Definition: content_context.h:305
path_builder.h
impeller::testing::TEST_P
TEST_P(AiksTest, RotateColorFilteredPath)
Definition: aiks_unittests.cc:56
impeller::ComputeTessellator::Status::kOk
@ kOk
impeller::ContentContextOptions::color_attachment_pixel_format
PixelFormat color_attachment_pixel_format
Definition: content_context.h:308
render_pass.h
skia_conversions.h
impeller::ComputeTessellator::SetStrokeWidth
ComputeTessellator & SetStrokeWidth(Scalar value)
Definition: compute_tessellator.cc:35
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::ContentContext::GetSolidFillPipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > GetSolidFillPipeline(ContentContextOptions opts) const
Definition: content_context.h:417
impeller::PathBuilder::AddCubicCurve
PathBuilder & AddCubicCurve(Point p1, Point cp1, Point cp2, Point p2)
Move to point p1, then insert a cubic curve from p1 to p2 with control points cp1 and cp2.
Definition: path_builder.cc:172
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
impeller::ContentContextOptions::has_stencil_attachment
bool has_stencil_attachment
Definition: content_context.h:309
compute_pipeline_builder.h
impeller::testing::INSTANTIATE_COMPUTE_SUITE
INSTANTIATE_COMPUTE_SUITE(ComputeSubgroupTest)
strings.h
impeller::StencilOperation::kIncrementClamp
@ kIncrementClamp
Increment the current stencil value by 1. Clamp it to the maximum.
impeller::ContentContextOptions::primitive_type
PrimitiveType primitive_type
Definition: content_context.h:307
pipeline_library.h
impeller::Close
void Close(PathBuilder *builder)
Definition: tessellator.cc:36
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:27
command_buffer.h
impeller::Command::stencil_reference
uint32_t stencil_reference
Definition: command.h:152
content_context.h
impeller::LineTo
void LineTo(PathBuilder *builder, Scalar x, Scalar y)
Definition: tessellator.cc:22
impeller::ContentContextOptions::sample_count
SampleCount sample_count
Definition: content_context.h:303
impeller::PathBuilder::MoveTo
PathBuilder & MoveTo(Point point, bool relative=false)
Definition: path_builder.cc:32
compute_playground_test.h
compute_command.h
impeller::Matrix::MakeOrthographic
static constexpr Matrix MakeOrthographic(TSize< T > size)
Definition: matrix.h:448
impeller::CompareFunction::kEqual
@ kEqual
Comparison test passes if new_value == current_value.
impeller::CommandBuffer::Status
Status
Definition: command_buffer.h:48
impeller::Command::BindVertices
bool BindVertices(const VertexBuffer &buffer)
Specify the vertex and index buffer to use for this command.
Definition: command.cc:15
impeller::Command::pipeline
std::shared_ptr< Pipeline< PipelineDescriptor > > pipeline
Definition: command.h:103
path_component.h
impeller::RenderPipelineT::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:90
impeller::ContentContextOptions
Definition: content_context.h:302
impeller
Definition: aiks_context.cc:10
impeller::ContentContext::IsValid
bool IsValid() const
Definition: content_context.cc:369
impeller::Matrix::MakeScale
static constexpr Matrix MakeScale(const Vector3 &s)
Definition: matrix.h:103
impeller::ContentContext
Definition: content_context.h:344
impeller::skia_conversions::ToPath
Path ToPath(const SkPath &path, Point shift)
Definition: skia_conversions.cc:49
impeller::Color::Premultiply
constexpr Color Premultiply() const
Definition: color.h:212
impeller::ContentContextOptions::stencil_operation
StencilOperation stencil_operation
Definition: content_context.h:306