// 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);
  }
}
