//
// Copyright 2019 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// OverlayDraw.comp: Draw overlay widgets.  A maximum of 32 text widgets and 32 graph widgets is
// supported simultaneously.

#version 450 core

#extension GL_EXT_samplerless_texture_functions : require

#if Is8x4
#define BLOCK_WIDTH 8
#define BLOCK_HEIGHT 4
#elif Is8x8
#define BLOCK_WIDTH 8
#define BLOCK_HEIGHT 8
#else
#error "Not all subgroup sizes are accounted for"
#endif

// Limits:
// Note that max length and size is defined such that each buffer length is below 16KB, the minimum
// guaranteed supported size for uniform buffers.
#define MAX_TEXT_WIDGETS 32
#define MAX_GRAPH_WIDGETS 32
#define MAX_TEXT_LENGTH 256
#define MAX_GRAPH_SIZE 64

// Font information:
#define FONT_GLYPHS_PER_ROW 32
#define FONT_GLYPHS_ROWS 3
#define FONT_CHARACTERS (FONT_GLYPHS_PER_ROW * FONT_GLYPHS_ROWS)

layout (local_size_x = BLOCK_WIDTH, local_size_y = BLOCK_HEIGHT, local_size_z = 1) in;

struct TextWidgetData
{
    uvec4 coordinates;
    vec4 color;
    uvec4 fontSize;     // w unused.  xy has the font glyph width/height.  z has the layer.
    uvec4 text[MAX_TEXT_LENGTH / 16];
};

struct GraphWidgetData
{
    uvec4 coordinates;
    vec4 color;
    uvec4 valueWidth;   // yzw unused.  x should necessarily divide coordinate's z-x
    uvec4 values[MAX_GRAPH_SIZE / 4];
};

layout(set = 0, binding = 0, rgba32f) uniform image2D blendOutput;

layout (set = 0, binding = 1) uniform TextWidgets
{
    TextWidgetData textWidgetsData[MAX_TEXT_WIDGETS];
};

layout (set = 0, binding = 2) uniform GraphWidgets
{
    GraphWidgetData graphWidgetsData[MAX_GRAPH_WIDGETS];
};

layout(set = 0, binding = 3) uniform utexture2D culledWidgets;
layout(set = 0, binding = 4) uniform texture2DArray font;

layout (push_constant) uniform PushConstants
{
    uvec2 outputSize;
} params;

bool intersects(const uvec2 imageCoords, const uvec4 widgetCoords)
{
    return all(greaterThanEqual(imageCoords, widgetCoords.xy)) &&
           all(lessThan(imageCoords, widgetCoords.zw));
}

uint getChar(const uint textWidget, const uvec2 coordInWidget, const uint fontGlyphWidth)
{
    const uint charIndex = coordInWidget.x / fontGlyphWidth;
    const uint packIndex = charIndex / 4;
    const uint packedChars = textWidgetsData[textWidget].text[packIndex / 4][packIndex % 4];
    const uint shift = (charIndex % 4) * 8;

#if IsBigEndian
    return (packedChars >> (24 - shift)) & 0xFF;
#else
    return (packedChars >> shift) & 0xFF;
#endif
}

float sampleFont(const uint textChar,
                 const uvec2 coordInWidget,
                 const uvec2 fontGlyphSize,
                 const uint fontLayer)
{
    const uvec2 coordInGlyph = coordInWidget % fontGlyphSize;
    const uvec2 glyphOffset = fontGlyphSize *
        uvec2(textChar % FONT_GLYPHS_PER_ROW, textChar / FONT_GLYPHS_PER_ROW);

    return texelFetch(font, ivec3(glyphOffset + coordInGlyph, fontLayer), 0).x;
}

uint getValue(const uint graphWidget, const uvec2 coordInWidget, const uint valueWidth)
{
    const uint valueIndex = coordInWidget.x / valueWidth.x;
    return graphWidgetsData[graphWidget].values[valueIndex / 4][valueIndex % 4];
}

vec4 blend(const vec4 blendedSoFar, const vec4 color)
{
    // Assuming colors (C1, a1), (C2, a2) ... (Cn, an) have been so far blended, blendedSoFar will
    // contain:
    //
    //     .rgb = Cn*an + ... + C2*a2*(1-a3)*...*(1-an) + C1*a1*(1-a2)*...*(1-an)
    //     .a = (1-a1)*(1-a2)*...*(1-an)
    //
    // Blending with (Cn+1, an+1) is simply:
    //
    //     .rgb = Cn+1*an+1 + .rgb*(1-an+1)
    //     .a = .a*(1-an+1)
    //
    // Note that finally, the background color will be multipled by .a and added with .rgb.

    return vec4(blendedSoFar.rgb * (1 - color.a) + color.rgb * color.a,
                blendedSoFar.a * (1 - color.a));
}

void main()
{
    const uvec2 imageCoords = gl_GlobalInvocationID.xy;
    if (any(greaterThanEqual(imageCoords, params.outputSize)))
    {
        return;
    }

    vec4 blendedWidgets = vec4(0, 0, 0, 1);

    const uvec2 subgroupWidgets = texelFetch(culledWidgets, ivec2(gl_WorkGroupID.xy), 0).xy;
    uint textWidgets = subgroupWidgets.x;
    uint graphWidgets = subgroupWidgets.y;

    // Loop through possible graph widgets that can intersect with this block.
    while (graphWidgets != 0)
    {
        const uint graphWidget = findLSB(graphWidgets);
        graphWidgets ^= 1 << graphWidget;

        const uvec4 widgetCoords = graphWidgetsData[graphWidget].coordinates;
        if (!intersects(imageCoords, widgetCoords))
        {
            continue;
        }

        if (imageCoords.x == widgetCoords.x || imageCoords.y == widgetCoords.y ||
            imageCoords.x + 1 == widgetCoords.z || imageCoords.y + 1 == widgetCoords.w)
        {
            // Use a black border around the graph to mark the area.
            blendedWidgets = vec4(0);
            continue;
        }

        const uvec2 coordInWidget = imageCoords - widgetCoords.xy;
        const uint valueWidth = graphWidgetsData[graphWidget].valueWidth.x;

        // Find the value corresponding to this pixel.
        const uint value = getValue(graphWidget, coordInWidget, valueWidth);

        vec4 color = vec4(0);
        const uint widgetHeight = widgetCoords.w - widgetCoords.y;

        // If the graph value overflows the designated area, have the last four rows show a
        // checkerboard pattern to signify that there is an overflow.
        bool indicateOverflow = value > widgetHeight && coordInWidget.y + 4 >= widgetHeight
                && ((coordInWidget.x ^ coordInWidget.y) & 1) == 0;

        if ((widgetHeight - coordInWidget.y) < value && !indicateOverflow)
        {
            color = graphWidgetsData[graphWidget].color;
            blendedWidgets = blend(blendedWidgets, color);
        }
    }

    // Loop through possible text widgets that can intersect with this block.
    while (textWidgets != 0)
    {
        const uint textWidget = findLSB(textWidgets);
        textWidgets ^= 1 << textWidget;

        const uvec4 widgetCoords = textWidgetsData[textWidget].coordinates;
        if (!intersects(imageCoords, widgetCoords))
        {
            continue;
        }

        const uvec2 coordInWidget = imageCoords - widgetCoords.xy;
        const uvec4 fontSizePacked = textWidgetsData[textWidget].fontSize;
        const uvec2 fontGlyphSize = fontSizePacked.xy;
        const uint fontLayer = fontSizePacked.z;

        // Find the character corresponding to this pixel.
        const uint textChar = getChar(textWidget, coordInWidget, fontGlyphSize.x);

        // The FONT_CHARACTERS value is a value filled where there is no character, so we don't add
        // a background to it.
        if (textChar < FONT_CHARACTERS)
        {
            // Sample the font based on this character.
            const float sampleValue = sampleFont(textChar, coordInWidget, fontGlyphSize, fontLayer);

            vec4 color = vec4(0, 0, 0, 0.4);
            color = mix(color, textWidgetsData[textWidget].color, sampleValue);

            blendedWidgets = blend(blendedWidgets, color);
        }
    }

    if (blendedWidgets.a < 1)
    {
        vec3 blendedColor = blendedWidgets.rgb;
        if (blendedWidgets.a > 0)
        {
            const vec4 color = imageLoad(blendOutput, ivec2(imageCoords));
            blendedColor += color.rgb * color.a * blendedWidgets.a;
        }
        imageStore(blendOutput, ivec2(imageCoords), vec4(blendedColor, 1));
    }
}
