| // 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 = 256, local_size_y = 1) in; | |
| layout(std430) buffer; | |
| layout(binding = 0) buffer Polyline { | |
| uint count; | |
| vec2 data[]; | |
| } | |
| polyline; | |
| layout(binding = 1) buffer VertexBuffer { | |
| vec2 position[]; | |
| } | |
| vertex_buffer; | |
| layout(binding = 2) buffer VertexBufferCount { | |
| uint count; | |
| } | |
| vertex_buffer_count; | |
| uniform Config { | |
| float width; | |
| uint cap; | |
| uint join; | |
| float miter_limit; | |
| } | |
| config; | |
| vec2 compute_offset(uint index) { | |
| vec2 direction = normalize(polyline.data[index + 1] - polyline.data[index]); | |
| return vec2(-direction.y, direction.x) * config.width * .5; | |
| } | |
| void main() { | |
| uint ident = gl_GlobalInvocationID.x; | |
| if (ident >= polyline.count || ident == 0) { | |
| // This is ok because there is no barrier() below. | |
| return; | |
| } | |
| atomicAdd(vertex_buffer_count.count, 4); | |
| uint index = ident - 1; | |
| vec2 offset = compute_offset(index); | |
| vertex_buffer.position[index * 4 + 0] = polyline.data[ident - 1] + offset; | |
| vertex_buffer.position[index * 4 + 1] = polyline.data[ident - 1] - offset; | |
| vertex_buffer.position[index * 4 + 2] = polyline.data[ident] + offset; | |
| vertex_buffer.position[index * 4 + 3] = polyline.data[ident] - offset; | |
| // TODO(dnfield): Implement other cap/join mechanisms. | |
| if (ident == polyline.count - 1) { | |
| vertex_buffer.position[index * 4 + 4] = polyline.data[ident] + offset; | |
| vertex_buffer.position[index * 4 + 5] = polyline.data[ident] - offset; | |
| atomicAdd(vertex_buffer_count.count, 2); | |
| } | |
| } |