//
// Copyright 2014 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.
//
// ShaderVars.cpp:
//  Methods for GL variable types (varyings, uniforms, etc)
//

#include <GLSLANG/ShaderLang.h>
#include "common/unsafe_buffers.h"

#include "common/debug.h"
#include "common/utilities.h"

namespace sh
{

namespace
{

InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
{
    return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
}
}  // namespace
// The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
// on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
// but auxiliary qualifier mismatch (centroid) does not.
bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
{
    return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
}

ShaderVariable::ShaderVariable() : ShaderVariable(GL_NONE) {}

ShaderVariable::ShaderVariable(GLenum typeIn)
    : type(typeIn),
      precision(0),
      staticUse(false),
      active(false),
      isRowMajorLayout(false),
      location(-1),
      hasImplicitLocation(false),
      binding(-1),
      imageUnitFormat(GL_NONE),
      offset(-1),
      rasterOrdered(false),
      readonly(false),
      writeonly(false),
      isFragmentInOut(false),
      index(-1),
      yuv(false),
      interpolation(INTERPOLATION_SMOOTH),
      isInvariant(false),
      isShaderIOBlock(false),
      isPatch(false),
      texelFetchStaticUse(false),
      id(0),
      isFloat16(false),
      flattenedOffsetInParentArrays(-1)
{}

ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) : ShaderVariable(typeIn)
{
    ASSERT(arraySizeIn != 0);
    arraySizes.push_back(arraySizeIn);
}

ShaderVariable::~ShaderVariable() {}

ShaderVariable::ShaderVariable(const ShaderVariable &other)
    : type(other.type),
      precision(other.precision),
      name(other.name),
      mappedName(other.mappedName),
      arraySizes(other.arraySizes),
      staticUse(other.staticUse),
      active(other.active),
      fields(other.fields),
      structOrBlockName(other.structOrBlockName),
      mappedStructOrBlockName(other.mappedStructOrBlockName),
      isRowMajorLayout(other.isRowMajorLayout),
      location(other.location),
      hasImplicitLocation(other.hasImplicitLocation),
      binding(other.binding),
      imageUnitFormat(other.imageUnitFormat),
      offset(other.offset),
      rasterOrdered(other.rasterOrdered),
      readonly(other.readonly),
      writeonly(other.writeonly),
      isFragmentInOut(other.isFragmentInOut),
      index(other.index),
      yuv(other.yuv),
      interpolation(other.interpolation),
      isInvariant(other.isInvariant),
      isShaderIOBlock(other.isShaderIOBlock),
      isPatch(other.isPatch),
      texelFetchStaticUse(other.texelFetchStaticUse),
      id(other.id),
      isFloat16(other.isFloat16),
      flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays)
{}

ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
{
    type                          = other.type;
    precision                     = other.precision;
    name                          = other.name;
    mappedName                    = other.mappedName;
    arraySizes                    = other.arraySizes;
    staticUse                     = other.staticUse;
    active                        = other.active;
    fields                        = other.fields;
    structOrBlockName             = other.structOrBlockName;
    mappedStructOrBlockName       = other.mappedStructOrBlockName;
    isRowMajorLayout              = other.isRowMajorLayout;
    flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
    location                      = other.location;
    hasImplicitLocation           = other.hasImplicitLocation;
    binding                       = other.binding;
    imageUnitFormat               = other.imageUnitFormat;
    offset                        = other.offset;
    rasterOrdered                 = other.rasterOrdered;
    readonly                      = other.readonly;
    writeonly                     = other.writeonly;
    isFragmentInOut               = other.isFragmentInOut;
    index                         = other.index;
    yuv                           = other.yuv;
    interpolation                 = other.interpolation;
    isInvariant                   = other.isInvariant;
    isShaderIOBlock               = other.isShaderIOBlock;
    isPatch                       = other.isPatch;
    texelFetchStaticUse           = other.texelFetchStaticUse;
    id                            = other.id;
    isFloat16                     = other.isFloat16;
    return *this;
}

bool ShaderVariable::operator==(const ShaderVariable &other) const
{
    if (type != other.type || precision != other.precision || name != other.name ||
        mappedName != other.mappedName || arraySizes != other.arraySizes ||
        staticUse != other.staticUse || active != other.active ||
        fields.size() != other.fields.size() || structOrBlockName != other.structOrBlockName ||
        mappedStructOrBlockName != other.mappedStructOrBlockName ||
        isRowMajorLayout != other.isRowMajorLayout || location != other.location ||
        hasImplicitLocation != other.hasImplicitLocation || binding != other.binding ||
        imageUnitFormat != other.imageUnitFormat || offset != other.offset ||
        rasterOrdered != other.rasterOrdered || readonly != other.readonly ||
        writeonly != other.writeonly || index != other.index || yuv != other.yuv ||
        interpolation != other.interpolation || isInvariant != other.isInvariant ||
        isShaderIOBlock != other.isShaderIOBlock || isPatch != other.isPatch ||
        texelFetchStaticUse != other.texelFetchStaticUse ||
        isFragmentInOut != other.isFragmentInOut || isFloat16 != other.isFloat16)
    {
        return false;
    }
    for (size_t ii = 0; ii < fields.size(); ++ii)
    {
        if (fields[ii] != other.fields[ii])
            return false;
    }
    return true;
}

void ShaderVariable::setArraySize(unsigned int size)
{
    arraySizes.clear();
    if (size != 0)
    {
        arraySizes.push_back(size);
    }
}

unsigned int ShaderVariable::getInnerArraySizeProduct() const
{
    return gl::InnerArraySizeProduct(arraySizes);
}

unsigned int ShaderVariable::getArraySizeProduct() const
{
    return gl::ArraySizeProduct(arraySizes);
}

void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
{
    ASSERT(isArray());
    flattenedOffsetInParentArrays = arrayIndex + getOutermostArraySize() * parentArrayIndex();
    arraySizes.pop_back();
}

unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
{
    ASSERT(arraySizes.size() > arrayNestingIndex);
    unsigned int arraySize = arraySizes[arraySizes.size() - 1u - arrayNestingIndex];

    if (arraySize == 0)
    {
        // Unsized array, so give it at least 1 entry
        arraySize = 1;
    }

    return arraySize;
}

unsigned int ShaderVariable::getBasicTypeElementCount() const
{
    // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
    // for each array element when dealing with an array of arrays or an array of structs.
    ASSERT(!isArrayOfArrays());
    ASSERT(!isStruct() || !isArray());

    // GLES 3.1 Nov 2016 page 82.
    if (isArray())
    {
        return getOutermostArraySize();
    }
    return 1u;
}

unsigned int ShaderVariable::getExternalSize() const
{
    unsigned int memorySize = 0;

    if (isStruct())
    {
        // Have a structure, need to compute the structure size.
        for (const auto &field : fields)
        {
            memorySize += field.getExternalSize();
        }
    }
    else
    {
        memorySize += gl::VariableExternalSize(type);
    }

    // multiply by array size to get total memory size of this variable / struct.
    memorySize *= getArraySizeProduct();

    return memorySize;
}

bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
                                          const ShaderVariable **leafVar,
                                          std::string *originalFullName) const
{
    ASSERT(leafVar && originalFullName);
    // There are three cases:
    // 1) the top variable is of struct type;
    // 2) the top variable is an array;
    // 3) otherwise.
    size_t pos = mappedFullName.find_first_of(".[");

    if (pos == std::string::npos)
    {
        // Case 3.
        if (mappedFullName != this->mappedName)
            return false;
        *originalFullName = this->name;
        *leafVar          = this;
        return true;
    }
    else
    {
        std::string topName = mappedFullName.substr(0, pos);
        if (topName != this->mappedName)
            return false;
        std::string originalName = this->name;
        std::string remaining;
        if (mappedFullName[pos] == '[')
        {
            // Case 2.
            size_t closePos = mappedFullName.find_first_of(']');
            if (closePos < pos || closePos == std::string::npos)
                return false;
            // Append '[index]'.
            originalName += mappedFullName.substr(pos, closePos - pos + 1);
            if (closePos + 1 == mappedFullName.size())
            {
                *originalFullName = originalName;
                *leafVar          = this;
                return true;
            }
            else
            {
                // In the form of 'a[0].b', so after ']', '.' is expected.
                if (mappedFullName[closePos + 1] != '.')
                    return false;
                remaining = mappedFullName.substr(closePos + 2);  // Skip "]."
            }
        }
        else
        {
            // Case 1.
            remaining = mappedFullName.substr(pos + 1);  // Skip "."
        }
        for (size_t ii = 0; ii < this->fields.size(); ++ii)
        {
            const ShaderVariable *fieldVar = nullptr;
            std::string originalFieldName;
            bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName);
            if (found)
            {
                *originalFullName = originalName + "." + originalFieldName;
                *leafVar          = fieldVar;
                return true;
            }
        }
        return false;
    }
}

const sh::ShaderVariable *ShaderVariable::findField(const std::string &fullName,
                                                    uint32_t *fieldIndexOut) const
{
    if (fields.empty())
    {
        return nullptr;
    }
    size_t pos = fullName.find_first_of(".");
    std::string topName, fieldName;
    if (pos == std::string::npos)
    {
        // If this is a shader I/O block without an instance name, return the field given only the
        // field name.
        if (!isShaderIOBlock || !name.empty())
        {
            return nullptr;
        }

        fieldName = fullName;
    }
    else
    {
        std::string baseName = isShaderIOBlock ? structOrBlockName : name;
        topName              = fullName.substr(0, pos);
        if (topName != baseName)
        {
            return nullptr;
        }
        fieldName = fullName.substr(pos + 1);
    }
    if (fieldName.empty())
    {
        return nullptr;
    }
    for (size_t field = 0; field < fields.size(); ++field)
    {
        if (fields[field].name == fieldName)
        {
            *fieldIndexOut = static_cast<GLuint>(field);
            return &fields[field];
        }
    }
    return nullptr;
}

bool ShaderVariable::isBuiltIn() const
{
    return gl::IsBuiltInName(name);
}

bool ShaderVariable::isEmulatedBuiltIn() const
{
    return isBuiltIn() && name != mappedName;
}

bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
                                              bool matchPrecision,
                                              bool matchName) const
{
    if (type != other.type)
        return false;
    if (matchPrecision && precision != other.precision)
        return false;
    if (matchName && name != other.name)
        return false;
    ASSERT(!matchName || mappedName == other.mappedName);
    if (arraySizes != other.arraySizes)
        return false;
    if (isRowMajorLayout != other.isRowMajorLayout)
        return false;
    if (fields.size() != other.fields.size())
        return false;

    // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
    // Variables declared as structures are considered to match in type if and only if structure
    // members match in name, type, qualification, and declaration order.
    for (size_t ii = 0; ii < fields.size(); ++ii)
    {
        if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true))
        {
            return false;
        }
    }
    if (structOrBlockName != other.structOrBlockName ||
        mappedStructOrBlockName != other.mappedStructOrBlockName)
        return false;
    return true;
}

void ShaderVariable::updateEffectiveLocation(const sh::ShaderVariable &parent)
{
    if ((location < 0 || hasImplicitLocation) && !parent.hasImplicitLocation)
    {
        location = parent.location;
    }
}

void ShaderVariable::resetEffectiveLocation()
{
    if (hasImplicitLocation)
    {
        location = -1;
    }
}

bool ShaderVariable::isSameUniformAtLinkTime(const ShaderVariable &other) const
{
    // Enforce a consistent match.
    // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
    if (binding != -1 && other.binding != -1 && binding != other.binding)
    {
        return false;
    }
    if (imageUnitFormat != other.imageUnitFormat)
    {
        return false;
    }
    if (location != -1 && other.location != -1 && location != other.location)
    {
        return false;
    }
    if (offset != other.offset)
    {
        return false;
    }
    if (rasterOrdered != other.rasterOrdered)
    {
        return false;
    }
    if (readonly != other.readonly || writeonly != other.writeonly)
    {
        return false;
    }
    return ShaderVariable::isSameVariableAtLinkTime(other, true, true);
}

bool ShaderVariable::isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const
{
    return (ShaderVariable::isSameVariableAtLinkTime(other, true, true));
}

bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other) const
{
    return isSameVaryingAtLinkTime(other, 100);
}

bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const
{
    return ShaderVariable::isSameVariableAtLinkTime(other, false, false) &&
           InterpolationTypesMatch(interpolation, other.interpolation) &&
           (shaderVersion >= 300 || isInvariant == other.isInvariant) &&
           (isPatch == other.isPatch) && location == other.location &&
           (isSameNameAtLinkTime(other) || (shaderVersion >= 310 && location >= 0));
}

bool ShaderVariable::isSameNameAtLinkTime(const ShaderVariable &other) const
{
    if (isShaderIOBlock != other.isShaderIOBlock)
    {
        return false;
    }

    if (isShaderIOBlock)
    {
        // Shader I/O blocks match by block name.
        return structOrBlockName == other.structOrBlockName;
    }

    // Otherwise match by name.
    return name == other.name;
}

InterfaceBlock::InterfaceBlock()
    : arraySize(0),
      layout(BLOCKLAYOUT_PACKED),
      binding(-1),
      staticUse(false),
      active(false),
      isReadOnly(false),
      blockType(BlockType::kBlockUniform),
      id(0)
{}

InterfaceBlock::~InterfaceBlock() {}

InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
    : name(other.name),
      mappedName(other.mappedName),
      instanceName(other.instanceName),
      arraySize(other.arraySize),
      layout(other.layout),
      binding(other.binding),
      staticUse(other.staticUse),
      active(other.active),
      isReadOnly(other.isReadOnly),
      blockType(other.blockType),
      fields(other.fields),
      id(other.id)
{}

InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
{
    name             = other.name;
    mappedName       = other.mappedName;
    instanceName     = other.instanceName;
    arraySize        = other.arraySize;
    layout           = other.layout;
    binding          = other.binding;
    staticUse        = other.staticUse;
    active           = other.active;
    isReadOnly       = other.isReadOnly;
    blockType        = other.blockType;
    id               = other.id;
    fields           = other.fields;
    return *this;
}

std::string InterfaceBlock::fieldPrefix() const
{
    return instanceName.empty() ? "" : name;
}

std::string InterfaceBlock::fieldMappedPrefix() const
{
    return instanceName.empty() ? "" : mappedName;
}

bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const
{
    if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize ||
        layout != other.layout || binding != other.binding || blockType != other.blockType ||
        fields.size() != other.fields.size())
    {
        return false;
    }

    for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
    {
        if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex]))
        {
            return false;
        }
    }

    return true;
}

bool InterfaceBlock::isBuiltIn() const
{
    return gl::IsBuiltInName(name);
}

void WorkGroupSize::fill(int fillValue)
{
    localSizeQualifiers[0] = fillValue;
    localSizeQualifiers[1] = fillValue;
    localSizeQualifiers[2] = fillValue;
}

void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ)
{
    localSizeQualifiers[0] = localSizeX;
    localSizeQualifiers[1] = localSizeY;
    localSizeQualifiers[2] = localSizeZ;
}

// check that if one of them is less than 1, then all of them are.
// Or if one is positive, then all of them are positive.
bool WorkGroupSize::isLocalSizeValid() const
{
    return (
        (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) ||
        (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0));
}

bool WorkGroupSize::isAnyValueSet() const
{
    return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0;
}

bool WorkGroupSize::isDeclared() const
{
    bool localSizeDeclared = localSizeQualifiers[0] > 0;
    ASSERT(isLocalSizeValid());
    return localSizeDeclared;
}

bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const
{
    for (size_t i = 0u; i < size(); ++i)
    {
        bool result = (ANGLE_UNSAFE_TODO(localSizeQualifiers[i]) ==
                           ANGLE_UNSAFE_TODO(right.localSizeQualifiers[i]) ||
                       (ANGLE_UNSAFE_TODO(localSizeQualifiers[i]) == 1 &&
                        ANGLE_UNSAFE_TODO(right.localSizeQualifiers[i]) == -1) ||
                       (ANGLE_UNSAFE_TODO(localSizeQualifiers[i]) == -1 &&
                        ANGLE_UNSAFE_TODO(right.localSizeQualifiers[i]) == 1));
        if (!result)
        {
            return false;
        }
    }
    return true;
}

int &WorkGroupSize::operator[](size_t index)
{
    ASSERT(index < size());
    return ANGLE_UNSAFE_TODO(localSizeQualifiers[index]);
}

int WorkGroupSize::operator[](size_t index) const
{
    ASSERT(index < size());
    return ANGLE_UNSAFE_TODO(localSizeQualifiers[index]);
}

size_t WorkGroupSize::size() const
{
    return 3u;
}

}  // namespace sh
