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"
18 #include "impeller/fixtures/sample.comp.h"
19 #include "impeller/fixtures/stage1.comp.h"
20 #include "impeller/fixtures/stage2.comp.h"
29 #include "impeller/renderer/path_polyline.comp.h"
32 #include "impeller/renderer/stroke.comp.h"
33 #include "third_party/imgui/imgui.h"
34 #include "third_party/skia/include/utils/SkParsePath.h"
43 auto context = GetContext();
45 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
50 using SS = StrokeComputeShader;
52 auto context = GetContext();
54 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
55 char svg_path_data[16384] =
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 "
62 "-19-41-60-69-108-69z";
63 size_t vertex_count = 0;
66 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
67 context,
"VertexBuffer");
68 auto vertex_buffer_count =
69 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
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);
86 if (SkParsePath::FromSVGString(svg_path_data, &sk_path)) {
87 std::promise<bool> promise;
88 auto future = promise.get_future();
95 path, context, vertex_buffer->AsBufferView(),
96 vertex_buffer_count->AsBufferView(),
97 [vertex_buffer_count, &vertex_count,
100 reinterpret_cast<SS::VertexBufferCount*>(
101 vertex_buffer_count->AsBufferView().contents)
103 promise.set_value(status ==
104 CommandBuffer::Status::kCompleted);
108 ImGui::Text(
"Failed to submit compute job (invalid command)");
111 ImGui::Text(
"Failed to submit compute job (too many components) ");
117 ImGui::Text(
"Failed to submit compute job.");
120 if (vertex_count > 0) {
121 ImGui::Text(
"Vertex count: %zu", vertex_count);
124 ImGui::Text(
"Failed to parse path data");
140 options.
sample_count = pass.GetRenderTarget().GetSampleCount();
142 pass.GetRenderTarget().GetRenderTargetPixelFormat();
144 pass.GetRenderTarget().GetStencilAttachment().has_value();
152 auto count =
reinterpret_cast<SS::VertexBufferCount*
>(
153 vertex_buffer_count->AsBufferView().contents)
158 .vertex_count = count,
162 VS::FrameInfo frame_info;
167 VS::BindFrameInfo(cmd,
168 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
170 if (!pass.AddCommand(std::move(cmd))) {
176 ASSERT_TRUE(OpenPlaygroundHere(callback));
182 using SS = StrokeComputeShader;
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;
190 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
191 context,
"VertexBuffer");
192 auto vertex_buffer_count =
193 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
198 .
MoveTo({359.934, 96.6335})
199 .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
201 .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
203 .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
205 .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
207 .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
209 .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
211 .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
213 .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
215 .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
217 .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
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},
224 .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
226 .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
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},
233 .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
235 .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
236 .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
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},
244 .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
245 .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
247 .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
249 .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
251 .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
253 .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
255 .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
257 .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
259 .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
261 .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
263 .
LineTo({271.717, 113.449})
264 .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
266 .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
268 .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
270 .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
272 .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
274 .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
276 .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
278 .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
280 .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
282 .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
284 .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
285 .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
287 .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
289 .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
291 .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
293 .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
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},
299 .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
301 .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
303 .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
305 .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
310 .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
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>));
324 complex_path, context, vertex_buffer->AsBufferView(),
325 vertex_buffer_count->AsBufferView(),
327 vertex_count = reinterpret_cast<SS::VertexBufferCount*>(
328 vertex_buffer_count->AsBufferView().contents)
344 options.
sample_count = pass.GetRenderTarget().GetSampleCount();
346 pass.GetRenderTarget().GetRenderTargetPixelFormat();
348 pass.GetRenderTarget().GetStencilAttachment().has_value();
356 auto count =
reinterpret_cast<SS::VertexBufferCount*
>(
357 vertex_buffer_count->AsBufferView().contents)
362 .vertex_count = count,
366 VS::FrameInfo frame_info;
371 VS::BindFrameInfo(cmd,
372 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
374 if (!pass.AddCommand(std::move(cmd))) {
380 ASSERT_TRUE(OpenPlaygroundHere(callback));
384 using SS = StrokeComputeShader;
386 auto context = GetContext();
387 ASSERT_TRUE(context);
388 ASSERT_TRUE(context->GetCapabilities()->SupportsComputeSubgroups());
390 auto vertex_buffer = CreateHostVisibleDeviceBuffer<SS::VertexBuffer<2048>>(
391 context,
"VertexBuffer");
392 auto vertex_buffer_count =
393 CreateHostVisibleDeviceBuffer<SS::VertexBufferCount>(context,
394 "VertexBufferCount");
398 .AddQuadraticCurve({20, 140}, {93, 90}, {100, 42})
403 fml::AutoResetWaitableEvent latch;
406 path, context, vertex_buffer->AsBufferView(),
407 vertex_buffer_count->AsBufferView(),
409 EXPECT_EQ(status, CommandBuffer::Status::kCompleted);
415 auto callback = [&](
RenderPass& pass) ->
bool {
428 options.
sample_count = pass.GetRenderTarget().GetSampleCount();
430 pass.GetRenderTarget().GetRenderTargetPixelFormat();
432 pass.GetRenderTarget().GetStencilAttachment().has_value();
440 auto count =
reinterpret_cast<SS::VertexBufferCount*
>(
441 vertex_buffer_count->AsBufferView().contents)
446 .vertex_count = count,
450 VS::FrameInfo frame_info;
455 VS::BindFrameInfo(cmd,
456 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
458 if (!pass.AddCommand(std::move(cmd))) {
464 ASSERT_TRUE(OpenPlaygroundHere(callback));
473 auto vertex_count =
reinterpret_cast<SS::VertexBufferCount*
>(
474 vertex_buffer_count->AsBufferView().contents)
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++) {
481 vertex_buffer_data->position[i].x),
484 vertex_buffer_data->position[i].y),