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

#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;

layout(binding = 2) buffer Lines {
  uint count;
  LineData data[];
}
lines;

layout(binding = 3) buffer Components {
  uint count;
  PathComponent data[];
}
components;

layout(binding = 4) buffer Polyline {
  uint count;
  vec2 data[];
}
polyline;

uniform Config {
  float cubic_accuracy;
  float quad_tolerance;
}
config;

shared uvec2 cubic_ranges[512];
shared uvec2 quad_ranges[512];
shared uint scratch_count[512];
shared uint scratch_sum[512];

uint ComputePosition(uint index) {
  uint sum = scratch_sum[index];
  for (uint position = gl_SubgroupSize - 1; position < index;
       position += gl_SubgroupSize) {
    sum += scratch_sum[position] + scratch_count[position];
  }
  return sum;
}

void ProcessCubic(uint ident) {
  CubicData cubic;
  uint quad_count = 0;
  if (ident < cubics.count) {
    cubic = cubics.data[ident];
    quad_count = EstimateQuadraticCount(cubic, config.cubic_accuracy);
    scratch_count[ident] = quad_count;
  }

  barrier();

  uint offset = 0;
  if (quad_count > 0) {
    scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]);

    offset = ComputePosition(ident) + quads.count;
  }
  barrier();
  if (quad_count > 0) {
    atomicAdd(quads.count, quad_count);

    cubic_ranges[ident] = uvec2(offset, quad_count);
    for (uint i = 0; i < quad_count; i++) {
      quads.data[offset + i] = GenerateQuadraticFromCubic(cubic, i, quad_count);
    }
  }
}

void ProcessQuad(uint ident) {
  QuadData quad;
  QuadDecomposition decomposition;
  if (ident < quads.count) {
    quad = quads.data[ident];
    decomposition = DecomposeQuad(quad, config.quad_tolerance);
    scratch_count[ident] = decomposition.line_count;
  }

  barrier();

  uint offset = 0;
  if (decomposition.line_count > 0) {
    scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]);
    offset = ComputePosition(ident) + lines.count;
  }
  barrier();

  if (decomposition.line_count > 0) {
    atomicAdd(lines.count, decomposition.line_count);
    quad_ranges[ident] = uvec2(offset, decomposition.line_count);

    vec2 last_point = quad.p1;
    for (uint i = 1; i < decomposition.line_count; i++) {
      LineData line =
          LineData(last_point, GenerateLineFromQuad(quad, i, decomposition));
      last_point = line.p2;
      lines.data[offset + i - 1] = line;
    }
    lines.data[offset + decomposition.line_count - 1] =
        LineData(last_point, quad.p2);
  }
}

void ProcessLine(uint ident) {
  if (ident == 0) {
    polyline.count = lines.count + 1;
  }

  PathComponent component;
  uvec2 range = uvec2(0, 0);
  if (ident < components.count) {
    component = components.data[ident];
    if (component.count == 4) {
      // Determine location in quads
      uvec2 quad_range = cubic_ranges[component.index];
      uvec2 end_range = quad_ranges[quad_range.x + quad_range.y - 1];
      range.x = quad_ranges[quad_range.x].x;
      range.y = end_range.x + end_range.y - range.x;
    } else if (component.count == 3) {
      range = quad_ranges[component.index];
    } else if (component.count == 2) {
      range = uvec2(component.index, 1);
    }

    scratch_count[ident] = range.y;
  }
  barrier();

  if (ident < components.count) {
    scratch_sum[ident] = subgroupExclusiveAdd(scratch_count[ident]);
    uint offset = ComputePosition(ident);
    polyline.data[offset] = lines.data[range.x].p1;
    for (uint i = 0; i < range.y; i++) {
      polyline.data[offset + i + 1] = lines.data[range.x + i].p2;
    }
  }
}

void main() {
  uint ident = gl_GlobalInvocationID.x;
  // Turn each cubic into quads.
  ProcessCubic(ident);
  barrier();

  // Turn each quad into lines.
  ProcessQuad(ident);
  barrier();

  // Copy lines to the output buffer.
  ProcessLine(ident);
}
