| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| #extension GL_KHR_shader_subgroup_arithmetic : enable |
| |
| layout(local_size_x = 512, local_size_y = 1) in; |
| layout(std430) buffer; |
| |
| #include <impeller/path.glsl> |
| |
| layout(binding = 0) readonly buffer Cubics { |
| uint count; |
| CubicData data[]; |
| } |
| cubics; |
| |
| layout(binding = 1) buffer Quads { |
| uint count; |
| QuadData data[]; |
| } |
| quads; |
| |
| uniform Config { |
| float accuracy; |
| } |
| config; |
| |
| shared uint quad_counts[512]; |
| shared uint count_sums[512]; |
| |
| uint ComputePosition(uint index) { |
| if (index < gl_SubgroupSize) { |
| return count_sums[index]; |
| } |
| int position = -1; |
| uint count_sum = count_sums[index]; |
| do { |
| position += int(gl_SubgroupSize); |
| count_sum += count_sums[position]; |
| } while (position < index); |
| return count_sum; |
| } |
| |
| void main() { |
| uint ident = gl_GlobalInvocationID.x; |
| CubicData cubic; |
| uint quad_count = 0; |
| if (ident < cubics.count) { |
| cubic = cubics.data[ident]; |
| quad_count = EstimateQuadraticCount(cubic, config.accuracy); |
| quad_counts[ident] = quad_count; |
| } |
| |
| barrier(); |
| if (quad_count == 0) { |
| return; |
| } |
| |
| count_sums[ident] = subgroupInclusiveAdd(quad_counts[ident]); |
| |
| quads.count = ComputePosition(cubics.count - 1); |
| uint offset = ComputePosition(ident) - quad_count; |
| for (uint i = 0; i < quad_count; i++) { |
| quads.data[offset + i] = GenerateQuadraticFromCubic(cubic, i, quad_count); |
| } |
| } |