tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

Program.cpp (126745B)


      1 //
      2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // Program.cpp: Implements the gl::Program class. Implements GL program objects
      8 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
      9 
     10 #include "libANGLE/Program.h"
     11 
     12 #include <algorithm>
     13 #include <utility>
     14 
     15 #include "common/angle_version_info.h"
     16 #include "common/bitset_utils.h"
     17 #include "common/debug.h"
     18 #include "common/platform.h"
     19 #include "common/string_utils.h"
     20 #include "common/utilities.h"
     21 #include "compiler/translator/blocklayout.h"
     22 #include "libANGLE/Context.h"
     23 #include "libANGLE/ErrorStrings.h"
     24 #include "libANGLE/MemoryProgramCache.h"
     25 #include "libANGLE/ProgramLinkedResources.h"
     26 #include "libANGLE/ResourceManager.h"
     27 #include "libANGLE/Uniform.h"
     28 #include "libANGLE/VaryingPacking.h"
     29 #include "libANGLE/Version.h"
     30 #include "libANGLE/capture/FrameCapture.h"
     31 #include "libANGLE/features.h"
     32 #include "libANGLE/histogram_macros.h"
     33 #include "libANGLE/queryconversions.h"
     34 #include "libANGLE/renderer/GLImplFactory.h"
     35 #include "libANGLE/renderer/ProgramImpl.h"
     36 #include "platform/FrontendFeatures_autogen.h"
     37 #include "platform/PlatformMethods.h"
     38 
     39 namespace gl
     40 {
     41 
     42 namespace
     43 {
     44 
     45 // This simplified cast function doesn't need to worry about advanced concepts like
     46 // depth range values, or casting to bool.
     47 template <typename DestT, typename SrcT>
     48 DestT UniformStateQueryCast(SrcT value);
     49 
     50 // From-Float-To-Integer Casts
     51 template <>
     52 GLint UniformStateQueryCast(GLfloat value)
     53 {
     54    return clampCast<GLint>(roundf(value));
     55 }
     56 
     57 template <>
     58 GLuint UniformStateQueryCast(GLfloat value)
     59 {
     60    return clampCast<GLuint>(roundf(value));
     61 }
     62 
     63 // From-Integer-to-Integer Casts
     64 template <>
     65 GLint UniformStateQueryCast(GLuint value)
     66 {
     67    return clampCast<GLint>(value);
     68 }
     69 
     70 template <>
     71 GLuint UniformStateQueryCast(GLint value)
     72 {
     73    return clampCast<GLuint>(value);
     74 }
     75 
     76 // From-Boolean-to-Anything Casts
     77 template <>
     78 GLfloat UniformStateQueryCast(GLboolean value)
     79 {
     80    return (ConvertToBool(value) ? 1.0f : 0.0f);
     81 }
     82 
     83 template <>
     84 GLint UniformStateQueryCast(GLboolean value)
     85 {
     86    return (ConvertToBool(value) ? 1 : 0);
     87 }
     88 
     89 template <>
     90 GLuint UniformStateQueryCast(GLboolean value)
     91 {
     92    return (ConvertToBool(value) ? 1u : 0u);
     93 }
     94 
     95 // Default to static_cast
     96 template <typename DestT, typename SrcT>
     97 DestT UniformStateQueryCast(SrcT value)
     98 {
     99    return static_cast<DestT>(value);
    100 }
    101 
    102 template <typename SrcT, typename DestT>
    103 void UniformStateQueryCastLoop(DestT *dataOut, const uint8_t *srcPointer, int components)
    104 {
    105    for (int comp = 0; comp < components; ++comp)
    106    {
    107        // We only work with strides of 4 bytes for uniform components. (GLfloat/GLint)
    108        // Don't use SrcT stride directly since GLboolean has a stride of 1 byte.
    109        size_t offset               = comp * 4;
    110        const SrcT *typedSrcPointer = reinterpret_cast<const SrcT *>(&srcPointer[offset]);
    111        dataOut[comp]               = UniformStateQueryCast<DestT>(*typedSrcPointer);
    112    }
    113 }
    114 
    115 template <typename VarT>
    116 GLuint GetResourceIndexFromName(const std::vector<VarT> &list, const std::string &name)
    117 {
    118    std::string nameAsArrayName = name + "[0]";
    119    for (size_t index = 0; index < list.size(); index++)
    120    {
    121        const VarT &resource = list[index];
    122        if (resource.name == name || (resource.isArray() && resource.name == nameAsArrayName))
    123        {
    124            return static_cast<GLuint>(index);
    125        }
    126    }
    127 
    128    return GL_INVALID_INDEX;
    129 }
    130 
    131 GLint GetVariableLocation(const std::vector<sh::ShaderVariable> &list,
    132                          const std::vector<VariableLocation> &locationList,
    133                          const std::string &name)
    134 {
    135    size_t nameLengthWithoutArrayIndex;
    136    unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
    137 
    138    for (size_t location = 0u; location < locationList.size(); ++location)
    139    {
    140        const VariableLocation &variableLocation = locationList[location];
    141        if (!variableLocation.used())
    142        {
    143            continue;
    144        }
    145 
    146        const sh::ShaderVariable &variable = list[variableLocation.index];
    147 
    148        // Array output variables may be bound out of order, so we need to ensure we only pick the
    149        // first element if given the base name.
    150        if ((variable.name == name) && (variableLocation.arrayIndex == 0))
    151        {
    152            return static_cast<GLint>(location);
    153        }
    154        if (variable.isArray() && variableLocation.arrayIndex == arrayIndex &&
    155            angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex))
    156        {
    157            return static_cast<GLint>(location);
    158        }
    159    }
    160 
    161    return -1;
    162 }
    163 
    164 GLint GetVariableLocation(const std::vector<LinkedUniform> &list,
    165                          const std::vector<VariableLocation> &locationList,
    166                          const std::string &name)
    167 {
    168    size_t nameLengthWithoutArrayIndex;
    169    unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
    170 
    171    for (size_t location = 0u; location < locationList.size(); ++location)
    172    {
    173        const VariableLocation &variableLocation = locationList[location];
    174        if (!variableLocation.used())
    175        {
    176            continue;
    177        }
    178 
    179        const LinkedUniform &variable = list[variableLocation.index];
    180 
    181        // Array output variables may be bound out of order, so we need to ensure we only pick the
    182        // first element if given the base name. Uniforms don't allow this behavior and some code
    183        // seemingly depends on the opposite behavior, so only enable it for output variables.
    184        if (angle::BeginsWith(variable.name, name) && (variableLocation.arrayIndex == 0))
    185        {
    186            if (name.length() == variable.name.length())
    187            {
    188                ASSERT(name == variable.name);
    189                // GLES 3.1 November 2016 page 87.
    190                // The string exactly matches the name of the active variable.
    191                return static_cast<GLint>(location);
    192            }
    193            if (name.length() + 3u == variable.name.length() && variable.isArray())
    194            {
    195                ASSERT(name + "[0]" == variable.name);
    196                // The string identifies the base name of an active array, where the string would
    197                // exactly match the name of the variable if the suffix "[0]" were appended to the
    198                // string.
    199                return static_cast<GLint>(location);
    200            }
    201        }
    202        if (variable.isArray() && variableLocation.arrayIndex == arrayIndex &&
    203            nameLengthWithoutArrayIndex + 3u == variable.name.length() &&
    204            angle::BeginsWith(variable.name, name, nameLengthWithoutArrayIndex))
    205        {
    206            ASSERT(name.substr(0u, nameLengthWithoutArrayIndex) + "[0]" == variable.name);
    207            // The string identifies an active element of the array, where the string ends with the
    208            // concatenation of the "[" character, an integer (with no "+" sign, extra leading
    209            // zeroes, or whitespace) identifying an array element, and the "]" character, the
    210            // integer is less than the number of active elements of the array variable, and where
    211            // the string would exactly match the enumerated name of the array if the decimal
    212            // integer were replaced with zero.
    213            return static_cast<GLint>(location);
    214        }
    215    }
    216 
    217    return -1;
    218 }
    219 
    220 void CopyStringToBuffer(GLchar *buffer,
    221                        const std::string &string,
    222                        GLsizei bufSize,
    223                        GLsizei *lengthOut)
    224 {
    225    ASSERT(bufSize > 0);
    226    size_t length = std::min<size_t>(bufSize - 1, string.length());
    227    memcpy(buffer, string.c_str(), length);
    228    buffer[length] = '\0';
    229 
    230    if (lengthOut)
    231    {
    232        *lengthOut = static_cast<GLsizei>(length);
    233    }
    234 }
    235 
    236 GLuint GetInterfaceBlockIndex(const std::vector<InterfaceBlock> &list, const std::string &name)
    237 {
    238    std::vector<unsigned int> subscripts;
    239    std::string baseName = ParseResourceName(name, &subscripts);
    240 
    241    unsigned int numBlocks = static_cast<unsigned int>(list.size());
    242    for (unsigned int blockIndex = 0; blockIndex < numBlocks; blockIndex++)
    243    {
    244        const auto &block = list[blockIndex];
    245        if (block.name == baseName)
    246        {
    247            const bool arrayElementZero =
    248                (subscripts.empty() && (!block.isArray || block.arrayElement == 0));
    249            const bool arrayElementMatches =
    250                (subscripts.size() == 1 && subscripts[0] == block.arrayElement);
    251            if (arrayElementMatches || arrayElementZero)
    252            {
    253                return blockIndex;
    254            }
    255        }
    256    }
    257 
    258    return GL_INVALID_INDEX;
    259 }
    260 
    261 void GetInterfaceBlockName(const UniformBlockIndex index,
    262                           const std::vector<InterfaceBlock> &list,
    263                           GLsizei bufSize,
    264                           GLsizei *length,
    265                           GLchar *name)
    266 {
    267    ASSERT(index.value < list.size());
    268 
    269    const auto &block = list[index.value];
    270 
    271    if (bufSize > 0)
    272    {
    273        std::string blockName = block.name;
    274 
    275        if (block.isArray)
    276        {
    277            blockName += ArrayString(block.arrayElement);
    278        }
    279        CopyStringToBuffer(name, blockName, bufSize, length);
    280    }
    281 }
    282 
    283 void InitUniformBlockLinker(const Context *context,
    284                            const ProgramState &state,
    285                            UniformBlockLinker *blockLinker)
    286 {
    287    for (ShaderType shaderType : AllShaderTypes())
    288    {
    289        Shader *shader = state.getAttachedShader(shaderType);
    290        if (shader)
    291        {
    292            blockLinker->addShaderBlocks(shaderType, &shader->getUniformBlocks(context));
    293        }
    294    }
    295 }
    296 
    297 void InitShaderStorageBlockLinker(const Context *context,
    298                                  const ProgramState &state,
    299                                  ShaderStorageBlockLinker *blockLinker)
    300 {
    301    for (ShaderType shaderType : AllShaderTypes())
    302    {
    303        Shader *shader = state.getAttachedShader(shaderType);
    304        if (shader != nullptr)
    305        {
    306            blockLinker->addShaderBlocks(shaderType, &shader->getShaderStorageBlocks(context));
    307        }
    308    }
    309 }
    310 }  // anonymous namespace
    311 
    312 const char *GetLinkMismatchErrorString(LinkMismatchError linkError)
    313 {
    314    switch (linkError)
    315    {
    316        case LinkMismatchError::TYPE_MISMATCH:
    317            return "Type";
    318        case LinkMismatchError::ARRAYNESS_MISMATCH:
    319            return "Array-ness";
    320        case LinkMismatchError::ARRAY_SIZE_MISMATCH:
    321            return "Array size";
    322        case LinkMismatchError::PRECISION_MISMATCH:
    323            return "Precision";
    324        case LinkMismatchError::STRUCT_NAME_MISMATCH:
    325            return "Structure name";
    326        case LinkMismatchError::FIELD_NUMBER_MISMATCH:
    327            return "Field number";
    328        case LinkMismatchError::FIELD_NAME_MISMATCH:
    329            return "Field name";
    330 
    331        case LinkMismatchError::INTERPOLATION_TYPE_MISMATCH:
    332            return "Interpolation type";
    333        case LinkMismatchError::INVARIANCE_MISMATCH:
    334            return "Invariance";
    335 
    336        case LinkMismatchError::BINDING_MISMATCH:
    337            return "Binding layout qualifier";
    338        case LinkMismatchError::LOCATION_MISMATCH:
    339            return "Location layout qualifier";
    340        case LinkMismatchError::OFFSET_MISMATCH:
    341            return "Offset layout qualifier";
    342        case LinkMismatchError::INSTANCE_NAME_MISMATCH:
    343            return "Instance name qualifier";
    344        case LinkMismatchError::FORMAT_MISMATCH:
    345            return "Format qualifier";
    346 
    347        case LinkMismatchError::LAYOUT_QUALIFIER_MISMATCH:
    348            return "Layout qualifier";
    349        case LinkMismatchError::MATRIX_PACKING_MISMATCH:
    350            return "Matrix Packing";
    351 
    352        case LinkMismatchError::FIELD_LOCATION_MISMATCH:
    353            return "Field location";
    354        case LinkMismatchError::FIELD_STRUCT_NAME_MISMATCH:
    355            return "Field structure name";
    356        default:
    357            UNREACHABLE();
    358            return "";
    359    }
    360 }
    361 
    362 void UpdateInterfaceVariable(std::vector<sh::ShaderVariable> *block, const sh::ShaderVariable &var)
    363 {
    364    if (!var.isStruct())
    365    {
    366        block->emplace_back(var);
    367        block->back().resetEffectiveLocation();
    368    }
    369 
    370    for (const sh::ShaderVariable &field : var.fields)
    371    {
    372        ASSERT(!var.name.empty() || var.isShaderIOBlock);
    373 
    374        // Shader I/O block naming is similar to UBOs and SSBOs:
    375        //
    376        //     in Block
    377        //     {
    378        //         type field;  // produces "field"
    379        //     };
    380        //
    381        //     in Block2
    382        //     {
    383        //         type field;  // produces "Block2.field"
    384        //     } block2;
    385        //
    386        const std::string &baseName = var.isShaderIOBlock ? var.structOrBlockName : var.name;
    387        const std::string prefix    = var.name.empty() ? "" : baseName + ".";
    388 
    389        if (!field.isStruct())
    390        {
    391            sh::ShaderVariable fieldCopy = field;
    392            fieldCopy.updateEffectiveLocation(var);
    393            fieldCopy.name = prefix + field.name;
    394            block->emplace_back(fieldCopy);
    395        }
    396 
    397        for (const sh::ShaderVariable &nested : field.fields)
    398        {
    399            sh::ShaderVariable nestedCopy = nested;
    400            nestedCopy.updateEffectiveLocation(field);
    401            nestedCopy.name = prefix + field.name + "." + nested.name;
    402            block->emplace_back(nestedCopy);
    403        }
    404    }
    405 }
    406 
    407 void WriteShaderVariableBuffer(BinaryOutputStream *stream, const ShaderVariableBuffer &var)
    408 {
    409    stream->writeInt(var.binding);
    410    stream->writeInt(var.dataSize);
    411 
    412    for (ShaderType shaderType : AllShaderTypes())
    413    {
    414        stream->writeBool(var.isActive(shaderType));
    415    }
    416 
    417    stream->writeInt(var.memberIndexes.size());
    418    for (unsigned int memberCounterIndex : var.memberIndexes)
    419    {
    420        stream->writeInt(memberCounterIndex);
    421    }
    422 }
    423 
    424 void LoadShaderVariableBuffer(BinaryInputStream *stream, ShaderVariableBuffer *var)
    425 {
    426    var->binding  = stream->readInt<int>();
    427    var->dataSize = stream->readInt<unsigned int>();
    428 
    429    for (ShaderType shaderType : AllShaderTypes())
    430    {
    431        var->setActive(shaderType, stream->readBool());
    432    }
    433 
    434    size_t numMembers = stream->readInt<size_t>();
    435    for (size_t blockMemberIndex = 0; blockMemberIndex < numMembers; blockMemberIndex++)
    436    {
    437        var->memberIndexes.push_back(stream->readInt<unsigned int>());
    438    }
    439 }
    440 
    441 void WriteBufferVariable(BinaryOutputStream *stream, const BufferVariable &var)
    442 {
    443    WriteShaderVar(stream, var);
    444 
    445    stream->writeInt(var.bufferIndex);
    446    WriteBlockMemberInfo(stream, var.blockInfo);
    447    stream->writeInt(var.topLevelArraySize);
    448 
    449    for (ShaderType shaderType : AllShaderTypes())
    450    {
    451        stream->writeBool(var.isActive(shaderType));
    452    }
    453 }
    454 
    455 void LoadBufferVariable(BinaryInputStream *stream, BufferVariable *var)
    456 {
    457    LoadShaderVar(stream, var);
    458 
    459    var->bufferIndex = stream->readInt<int>();
    460    LoadBlockMemberInfo(stream, &var->blockInfo);
    461    var->topLevelArraySize = stream->readInt<int>();
    462 
    463    for (ShaderType shaderType : AllShaderTypes())
    464    {
    465        var->setActive(shaderType, stream->readBool());
    466    }
    467 }
    468 
    469 void WriteInterfaceBlock(BinaryOutputStream *stream, const InterfaceBlock &block)
    470 {
    471    stream->writeString(block.name);
    472    stream->writeString(block.mappedName);
    473    stream->writeBool(block.isArray);
    474    stream->writeInt(block.arrayElement);
    475 
    476    WriteShaderVariableBuffer(stream, block);
    477 }
    478 
    479 void LoadInterfaceBlock(BinaryInputStream *stream, InterfaceBlock *block)
    480 {
    481    block->name         = stream->readString();
    482    block->mappedName   = stream->readString();
    483    block->isArray      = stream->readBool();
    484    block->arrayElement = stream->readInt<unsigned int>();
    485 
    486    LoadShaderVariableBuffer(stream, block);
    487 }
    488 
    489 void WriteShInterfaceBlock(BinaryOutputStream *stream, const sh::InterfaceBlock &block)
    490 {
    491    stream->writeString(block.name);
    492    stream->writeString(block.mappedName);
    493    stream->writeString(block.instanceName);
    494    stream->writeInt(block.arraySize);
    495    stream->writeEnum(block.layout);
    496    stream->writeBool(block.isRowMajorLayout);
    497    stream->writeInt(block.binding);
    498    stream->writeBool(block.staticUse);
    499    stream->writeBool(block.active);
    500    stream->writeEnum(block.blockType);
    501 
    502    stream->writeInt<size_t>(block.fields.size());
    503    for (const sh::ShaderVariable &shaderVariable : block.fields)
    504    {
    505        WriteShaderVar(stream, shaderVariable);
    506    }
    507 }
    508 
    509 void LoadShInterfaceBlock(BinaryInputStream *stream, sh::InterfaceBlock *block)
    510 {
    511    block->name             = stream->readString();
    512    block->mappedName       = stream->readString();
    513    block->instanceName     = stream->readString();
    514    block->arraySize        = stream->readInt<unsigned int>();
    515    block->layout           = stream->readEnum<sh::BlockLayoutType>();
    516    block->isRowMajorLayout = stream->readBool();
    517    block->binding          = stream->readInt<int>();
    518    block->staticUse        = stream->readBool();
    519    block->active           = stream->readBool();
    520    block->blockType        = stream->readEnum<sh::BlockType>();
    521 
    522    block->fields.resize(stream->readInt<size_t>());
    523    for (sh::ShaderVariable &variable : block->fields)
    524    {
    525        LoadShaderVar(stream, &variable);
    526    }
    527 }
    528 
    529 // Saves the linking context for later use in resolveLink().
    530 struct Program::LinkingState
    531 {
    532    std::shared_ptr<ProgramExecutable> linkedExecutable;
    533    ProgramLinkedResources resources;
    534    egl::BlobCache::Key programHash;
    535    std::unique_ptr<rx::LinkEvent> linkEvent;
    536    bool linkingFromBinary;
    537 };
    538 
    539 const char *const g_fakepath = "C:\\fakepath";
    540 
    541 // InfoLog implementation.
    542 InfoLog::InfoLog() : mLazyStream(nullptr) {}
    543 
    544 InfoLog::~InfoLog() {}
    545 
    546 size_t InfoLog::getLength() const
    547 {
    548    if (!mLazyStream)
    549    {
    550        return 0;
    551    }
    552 
    553    const std::string &logString = mLazyStream->str();
    554    return logString.empty() ? 0 : logString.length() + 1;
    555 }
    556 
    557 void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
    558 {
    559    size_t index = 0;
    560 
    561    if (bufSize > 0)
    562    {
    563        const std::string logString(str());
    564 
    565        if (!logString.empty())
    566        {
    567            index = std::min(static_cast<size_t>(bufSize) - 1, logString.length());
    568            memcpy(infoLog, logString.c_str(), index);
    569        }
    570 
    571        infoLog[index] = '\0';
    572    }
    573 
    574    if (length)
    575    {
    576        *length = static_cast<GLsizei>(index);
    577    }
    578 }
    579 
    580 // append a sanitized message to the program info log.
    581 // The D3D compiler includes a fake file path in some of the warning or error
    582 // messages, so lets remove all occurrences of this fake file path from the log.
    583 void InfoLog::appendSanitized(const char *message)
    584 {
    585    ensureInitialized();
    586 
    587    std::string msg(message);
    588 
    589    size_t found;
    590    do
    591    {
    592        found = msg.find(g_fakepath);
    593        if (found != std::string::npos)
    594        {
    595            msg.erase(found, strlen(g_fakepath));
    596        }
    597    } while (found != std::string::npos);
    598 
    599    if (!msg.empty())
    600    {
    601        *mLazyStream << message << std::endl;
    602    }
    603 }
    604 
    605 void InfoLog::reset()
    606 {
    607    if (mLazyStream)
    608    {
    609        mLazyStream.reset(nullptr);
    610    }
    611 }
    612 
    613 bool InfoLog::empty() const
    614 {
    615    if (!mLazyStream)
    616    {
    617        return true;
    618    }
    619 
    620    return mLazyStream->rdbuf()->in_avail() == 0;
    621 }
    622 
    623 void LogLinkMismatch(InfoLog &infoLog,
    624                     const std::string &variableName,
    625                     const char *variableType,
    626                     LinkMismatchError linkError,
    627                     const std::string &mismatchedStructOrBlockFieldName,
    628                     ShaderType shaderType1,
    629                     ShaderType shaderType2)
    630 {
    631    std::ostringstream stream;
    632    stream << GetLinkMismatchErrorString(linkError) << "s of " << variableType << " '"
    633           << variableName;
    634 
    635    if (!mismatchedStructOrBlockFieldName.empty())
    636    {
    637        stream << "' member '" << variableName << "." << mismatchedStructOrBlockFieldName;
    638    }
    639 
    640    stream << "' differ between " << GetShaderTypeString(shaderType1) << " and "
    641           << GetShaderTypeString(shaderType2) << " shaders.";
    642 
    643    infoLog << stream.str();
    644 }
    645 
    646 bool IsActiveInterfaceBlock(const sh::InterfaceBlock &interfaceBlock)
    647 {
    648    // Only 'packed' blocks are allowed to be considered inactive.
    649    return interfaceBlock.active || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED;
    650 }
    651 
    652 void WriteBlockMemberInfo(BinaryOutputStream *stream, const sh::BlockMemberInfo &var)
    653 {
    654    stream->writeInt(var.arrayStride);
    655    stream->writeBool(var.isRowMajorMatrix);
    656    stream->writeInt(var.matrixStride);
    657    stream->writeInt(var.offset);
    658    stream->writeInt(var.topLevelArrayStride);
    659 }
    660 
    661 void LoadBlockMemberInfo(BinaryInputStream *stream, sh::BlockMemberInfo *var)
    662 {
    663    var->arrayStride         = stream->readInt<int>();
    664    var->isRowMajorMatrix    = stream->readBool();
    665    var->matrixStride        = stream->readInt<int>();
    666    var->offset              = stream->readInt<int>();
    667    var->topLevelArrayStride = stream->readInt<int>();
    668 }
    669 
    670 void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
    671 {
    672    stream->writeInt(var.type);
    673    stream->writeInt(var.precision);
    674    stream->writeString(var.name);
    675    stream->writeString(var.mappedName);
    676    stream->writeIntVector(var.arraySizes);
    677    stream->writeBool(var.staticUse);
    678    stream->writeBool(var.active);
    679    stream->writeInt<size_t>(var.fields.size());
    680    for (const sh::ShaderVariable &shaderVariable : var.fields)
    681    {
    682        WriteShaderVar(stream, shaderVariable);
    683    }
    684    stream->writeString(var.structOrBlockName);
    685    stream->writeString(var.mappedStructOrBlockName);
    686    stream->writeBool(var.isRowMajorLayout);
    687    stream->writeInt(var.location);
    688    stream->writeBool(var.hasImplicitLocation);
    689    stream->writeInt(var.binding);
    690    stream->writeInt(var.imageUnitFormat);
    691    stream->writeInt(var.offset);
    692    stream->writeBool(var.rasterOrdered);
    693    stream->writeBool(var.readonly);
    694    stream->writeBool(var.writeonly);
    695    stream->writeBool(var.isFragmentInOut);
    696    stream->writeInt(var.index);
    697    stream->writeBool(var.yuv);
    698    stream->writeEnum(var.interpolation);
    699    stream->writeBool(var.isInvariant);
    700    stream->writeBool(var.isShaderIOBlock);
    701    stream->writeBool(var.isPatch);
    702    stream->writeBool(var.texelFetchStaticUse);
    703    stream->writeInt(var.getFlattenedOffsetInParentArrays());
    704 }
    705 
    706 void LoadShaderVar(gl::BinaryInputStream *stream, sh::ShaderVariable *var)
    707 {
    708    var->type      = stream->readInt<GLenum>();
    709    var->precision = stream->readInt<GLenum>();
    710    stream->readString(&var->name);
    711    stream->readString(&var->mappedName);
    712    stream->readIntVector<unsigned int>(&var->arraySizes);
    713    var->staticUse      = stream->readBool();
    714    var->active         = stream->readBool();
    715    size_t elementCount = stream->readInt<size_t>();
    716    var->fields.resize(elementCount);
    717    for (sh::ShaderVariable &variable : var->fields)
    718    {
    719        LoadShaderVar(stream, &variable);
    720    }
    721    stream->readString(&var->structOrBlockName);
    722    stream->readString(&var->mappedStructOrBlockName);
    723    var->isRowMajorLayout    = stream->readBool();
    724    var->location            = stream->readInt<int>();
    725    var->hasImplicitLocation = stream->readBool();
    726    var->binding             = stream->readInt<int>();
    727    var->imageUnitFormat     = stream->readInt<GLenum>();
    728    var->offset              = stream->readInt<int>();
    729    var->rasterOrdered       = stream->readBool();
    730    var->readonly            = stream->readBool();
    731    var->writeonly           = stream->readBool();
    732    var->isFragmentInOut     = stream->readBool();
    733    var->index               = stream->readInt<int>();
    734    var->yuv                 = stream->readBool();
    735    var->interpolation       = stream->readEnum<sh::InterpolationType>();
    736    var->isInvariant         = stream->readBool();
    737    var->isShaderIOBlock     = stream->readBool();
    738    var->isPatch             = stream->readBool();
    739    var->texelFetchStaticUse = stream->readBool();
    740    var->setParentArrayIndex(stream->readInt<int>());
    741 }
    742 
    743 // VariableLocation implementation.
    744 VariableLocation::VariableLocation() : arrayIndex(0), index(kUnused), ignored(false) {}
    745 
    746 VariableLocation::VariableLocation(unsigned int arrayIndex, unsigned int index)
    747    : arrayIndex(arrayIndex), index(index), ignored(false)
    748 {
    749    ASSERT(arrayIndex != GL_INVALID_INDEX);
    750 }
    751 
    752 // SamplerBindings implementation.
    753 SamplerBinding::SamplerBinding(TextureType textureTypeIn,
    754                               GLenum samplerTypeIn,
    755                               SamplerFormat formatIn,
    756                               size_t elementCount)
    757    : textureType(textureTypeIn),
    758      samplerType(samplerTypeIn),
    759      format(formatIn),
    760      boundTextureUnits(elementCount, 0)
    761 {}
    762 
    763 SamplerBinding::SamplerBinding(const SamplerBinding &other) = default;
    764 
    765 SamplerBinding::~SamplerBinding() = default;
    766 
    767 // ProgramBindings implementation.
    768 ProgramBindings::ProgramBindings() {}
    769 
    770 ProgramBindings::~ProgramBindings() {}
    771 
    772 void ProgramBindings::bindLocation(GLuint index, const std::string &name)
    773 {
    774    mBindings[name] = index;
    775 }
    776 
    777 int ProgramBindings::getBindingByName(const std::string &name) const
    778 {
    779    auto iter = mBindings.find(name);
    780    return (iter != mBindings.end()) ? iter->second : -1;
    781 }
    782 
    783 int ProgramBindings::getBinding(const sh::ShaderVariable &variable) const
    784 {
    785    return getBindingByName(variable.name);
    786 }
    787 
    788 ProgramBindings::const_iterator ProgramBindings::begin() const
    789 {
    790    return mBindings.begin();
    791 }
    792 
    793 ProgramBindings::const_iterator ProgramBindings::end() const
    794 {
    795    return mBindings.end();
    796 }
    797 
    798 std::map<std::string, GLuint> ProgramBindings::getStableIterationMap() const
    799 {
    800    return std::map<std::string, GLuint>(mBindings.begin(), mBindings.end());
    801 }
    802 
    803 // ProgramAliasedBindings implementation.
    804 ProgramAliasedBindings::ProgramAliasedBindings() {}
    805 
    806 ProgramAliasedBindings::~ProgramAliasedBindings() {}
    807 
    808 void ProgramAliasedBindings::bindLocation(GLuint index, const std::string &name)
    809 {
    810    mBindings[name] = ProgramBinding(index);
    811 
    812    // EXT_blend_func_extended spec: "If it specifies the base name of an array,
    813    // it identifies the resources associated with the first element of the array."
    814    //
    815    // Normalize array bindings so that "name" and "name[0]" map to the same entry.
    816    // If this binding is of the form "name[0]", then mark the "name" binding as
    817    // aliased but do not update it yet in case "name" is not actually an array.
    818    size_t nameLengthWithoutArrayIndex;
    819    unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
    820    if (arrayIndex == 0)
    821    {
    822        std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
    823        auto iter            = mBindings.find(baseName);
    824        if (iter != mBindings.end())
    825        {
    826            iter->second.aliased = true;
    827        }
    828    }
    829 }
    830 
    831 int ProgramAliasedBindings::getBindingByName(const std::string &name) const
    832 {
    833    auto iter = mBindings.find(name);
    834    return (iter != mBindings.end()) ? iter->second.location : -1;
    835 }
    836 
    837 int ProgramAliasedBindings::getBindingByLocation(GLuint location) const
    838 {
    839    for (const auto &iter : mBindings)
    840    {
    841        if (iter.second.location == location)
    842        {
    843            return iter.second.location;
    844        }
    845    }
    846    return -1;
    847 }
    848 
    849 int ProgramAliasedBindings::getBinding(const sh::ShaderVariable &variable) const
    850 {
    851    const std::string &name = variable.name;
    852 
    853    // Check with the normalized array name if applicable.
    854    if (variable.isArray())
    855    {
    856        size_t nameLengthWithoutArrayIndex;
    857        unsigned int arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
    858        if (arrayIndex == 0)
    859        {
    860            std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
    861            auto iter            = mBindings.find(baseName);
    862            // If "name" exists and is not aliased, that means it was modified more
    863            // recently than its "name[0]" form and should be used instead of that.
    864            if (iter != mBindings.end() && !iter->second.aliased)
    865            {
    866                return iter->second.location;
    867            }
    868        }
    869        else if (arrayIndex == GL_INVALID_INDEX)
    870        {
    871            auto iter = mBindings.find(variable.name);
    872            // If "name" exists and is not aliased, that means it was modified more
    873            // recently than its "name[0]" form and should be used instead of that.
    874            if (iter != mBindings.end() && !iter->second.aliased)
    875            {
    876                return iter->second.location;
    877            }
    878            // The base name was aliased, so use the name with the array notation.
    879            return getBindingByName(name + "[0]");
    880        }
    881    }
    882 
    883    return getBindingByName(name);
    884 }
    885 
    886 ProgramAliasedBindings::const_iterator ProgramAliasedBindings::begin() const
    887 {
    888    return mBindings.begin();
    889 }
    890 
    891 ProgramAliasedBindings::const_iterator ProgramAliasedBindings::end() const
    892 {
    893    return mBindings.end();
    894 }
    895 
    896 std::map<std::string, ProgramBinding> ProgramAliasedBindings::getStableIterationMap() const
    897 {
    898    return std::map<std::string, ProgramBinding>(mBindings.begin(), mBindings.end());
    899 }
    900 
    901 // ImageBinding implementation.
    902 ImageBinding::ImageBinding(size_t count, TextureType textureTypeIn)
    903    : textureType(textureTypeIn), boundImageUnits(count, 0)
    904 {}
    905 ImageBinding::ImageBinding(GLuint imageUnit, size_t count, TextureType textureTypeIn)
    906    : textureType(textureTypeIn)
    907 {
    908    for (size_t index = 0; index < count; ++index)
    909    {
    910        boundImageUnits.push_back(imageUnit + static_cast<GLuint>(index));
    911    }
    912 }
    913 
    914 ImageBinding::ImageBinding(const ImageBinding &other) = default;
    915 
    916 ImageBinding::~ImageBinding() = default;
    917 
    918 // ProgramState implementation.
    919 ProgramState::ProgramState()
    920    : mLabel(),
    921      mAttachedShaders{},
    922      mLocationsUsedForXfbExtension(0),
    923      mBinaryRetrieveableHint(false),
    924      mSeparable(false),
    925      mNumViews(-1),
    926      mDrawIDLocation(-1),
    927      mBaseVertexLocation(-1),
    928      mBaseInstanceLocation(-1),
    929      mCachedBaseVertex(0),
    930      mCachedBaseInstance(0),
    931      mExecutable(new ProgramExecutable())
    932 {
    933    mComputeShaderLocalSize.fill(1);
    934 }
    935 
    936 ProgramState::~ProgramState()
    937 {
    938    ASSERT(!hasAttachedShader());
    939 }
    940 
    941 const std::string &ProgramState::getLabel()
    942 {
    943    return mLabel;
    944 }
    945 
    946 Shader *ProgramState::getAttachedShader(ShaderType shaderType) const
    947 {
    948    ASSERT(shaderType != ShaderType::InvalidEnum);
    949    return mAttachedShaders[shaderType];
    950 }
    951 
    952 GLuint ProgramState::getUniformIndexFromName(const std::string &name) const
    953 {
    954    return GetResourceIndexFromName(mExecutable->mUniforms, name);
    955 }
    956 
    957 GLuint ProgramState::getBufferVariableIndexFromName(const std::string &name) const
    958 {
    959    return GetResourceIndexFromName(mBufferVariables, name);
    960 }
    961 
    962 GLuint ProgramState::getUniformIndexFromLocation(UniformLocation location) const
    963 {
    964    ASSERT(location.value >= 0 && static_cast<size_t>(location.value) < mUniformLocations.size());
    965    return mUniformLocations[location.value].index;
    966 }
    967 
    968 Optional<GLuint> ProgramState::getSamplerIndex(UniformLocation location) const
    969 {
    970    GLuint index = getUniformIndexFromLocation(location);
    971    if (!isSamplerUniformIndex(index))
    972    {
    973        return Optional<GLuint>::Invalid();
    974    }
    975 
    976    return getSamplerIndexFromUniformIndex(index);
    977 }
    978 
    979 bool ProgramState::isSamplerUniformIndex(GLuint index) const
    980 {
    981    return mExecutable->mSamplerUniformRange.contains(index);
    982 }
    983 
    984 GLuint ProgramState::getSamplerIndexFromUniformIndex(GLuint uniformIndex) const
    985 {
    986    ASSERT(isSamplerUniformIndex(uniformIndex));
    987    return uniformIndex - mExecutable->mSamplerUniformRange.low();
    988 }
    989 
    990 GLuint ProgramState::getUniformIndexFromSamplerIndex(GLuint samplerIndex) const
    991 {
    992    return mExecutable->getUniformIndexFromSamplerIndex(samplerIndex);
    993 }
    994 
    995 bool ProgramState::isImageUniformIndex(GLuint index) const
    996 {
    997    return mExecutable->mImageUniformRange.contains(index);
    998 }
    999 
   1000 GLuint ProgramState::getImageIndexFromUniformIndex(GLuint uniformIndex) const
   1001 {
   1002    ASSERT(isImageUniformIndex(uniformIndex));
   1003    return uniformIndex - mExecutable->mImageUniformRange.low();
   1004 }
   1005 
   1006 GLuint ProgramState::getAttributeLocation(const std::string &name) const
   1007 {
   1008    for (const sh::ShaderVariable &attribute : mExecutable->mProgramInputs)
   1009    {
   1010        if (attribute.name == name)
   1011        {
   1012            return attribute.location;
   1013        }
   1014    }
   1015 
   1016    return static_cast<GLuint>(-1);
   1017 }
   1018 
   1019 bool ProgramState::hasAttachedShader() const
   1020 {
   1021    for (const Shader *shader : mAttachedShaders)
   1022    {
   1023        if (shader)
   1024        {
   1025            return true;
   1026        }
   1027    }
   1028    return false;
   1029 }
   1030 
   1031 ShaderType ProgramState::getFirstAttachedShaderStageType() const
   1032 {
   1033    const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
   1034    if (linkedStages.none())
   1035    {
   1036        return ShaderType::InvalidEnum;
   1037    }
   1038 
   1039    return linkedStages.first();
   1040 }
   1041 
   1042 ShaderType ProgramState::getLastAttachedShaderStageType() const
   1043 {
   1044    const ShaderBitSet linkedStages = mExecutable->getLinkedShaderStages();
   1045    if (linkedStages.none())
   1046    {
   1047        return ShaderType::InvalidEnum;
   1048    }
   1049 
   1050    return linkedStages.last();
   1051 }
   1052 
   1053 ShaderType ProgramState::getAttachedTransformFeedbackStage() const
   1054 {
   1055    if (mAttachedShaders[ShaderType::Geometry])
   1056    {
   1057        return ShaderType::Geometry;
   1058    }
   1059    if (mAttachedShaders[ShaderType::TessEvaluation])
   1060    {
   1061        return ShaderType::TessEvaluation;
   1062    }
   1063    return ShaderType::Vertex;
   1064 }
   1065 
   1066 Program::Program(rx::GLImplFactory *factory, ShaderProgramManager *manager, ShaderProgramID handle)
   1067    : mSerial(factory->generateSerial()),
   1068      mProgram(factory->createProgram(mState)),
   1069      mValidated(false),
   1070      mLinked(false),
   1071      mDeleteStatus(false),
   1072      mRefCount(0),
   1073      mResourceManager(manager),
   1074      mHandle(handle)
   1075 {
   1076    ASSERT(mProgram);
   1077 
   1078    unlink();
   1079 }
   1080 
   1081 Program::~Program()
   1082 {
   1083    ASSERT(!mProgram);
   1084 }
   1085 
   1086 void Program::onDestroy(const Context *context)
   1087 {
   1088    resolveLink(context);
   1089    for (ShaderType shaderType : AllShaderTypes())
   1090    {
   1091        if (mState.mAttachedShaders[shaderType])
   1092        {
   1093            mState.mAttachedShaders[shaderType]->release(context);
   1094            mState.mAttachedShaders[shaderType] = nullptr;
   1095        }
   1096    }
   1097 
   1098    mProgram->destroy(context);
   1099 
   1100    ASSERT(!mState.hasAttachedShader());
   1101    SafeDelete(mProgram);
   1102 
   1103    delete this;
   1104 }
   1105 ShaderProgramID Program::id() const
   1106 {
   1107    ASSERT(!mLinkingState);
   1108    return mHandle;
   1109 }
   1110 
   1111 angle::Result Program::setLabel(const Context *context, const std::string &label)
   1112 {
   1113    ASSERT(!mLinkingState);
   1114    mState.mLabel = label;
   1115 
   1116    if (mProgram)
   1117    {
   1118        return mProgram->onLabelUpdate(context);
   1119    }
   1120    return angle::Result::Continue;
   1121 }
   1122 
   1123 const std::string &Program::getLabel() const
   1124 {
   1125    ASSERT(!mLinkingState);
   1126    return mState.mLabel;
   1127 }
   1128 
   1129 void Program::attachShader(Shader *shader)
   1130 {
   1131    ShaderType shaderType = shader->getType();
   1132    ASSERT(shaderType != ShaderType::InvalidEnum);
   1133 
   1134    mState.mAttachedShaders[shaderType] = shader;
   1135    mState.mAttachedShaders[shaderType]->addRef();
   1136 }
   1137 
   1138 void Program::detachShader(const Context *context, Shader *shader)
   1139 {
   1140    resolveLink(context);
   1141    ShaderType shaderType = shader->getType();
   1142    ASSERT(shaderType != ShaderType::InvalidEnum);
   1143 
   1144    ASSERT(mState.mAttachedShaders[shaderType] == shader);
   1145    shader->release(context);
   1146    mState.mAttachedShaders[shaderType] = nullptr;
   1147 }
   1148 
   1149 int Program::getAttachedShadersCount() const
   1150 {
   1151    ASSERT(!mLinkingState);
   1152    int numAttachedShaders = 0;
   1153    for (const Shader *shader : mState.mAttachedShaders)
   1154    {
   1155        if (shader)
   1156        {
   1157            ++numAttachedShaders;
   1158        }
   1159    }
   1160 
   1161    return numAttachedShaders;
   1162 }
   1163 
   1164 Shader *Program::getAttachedShader(ShaderType shaderType) const
   1165 {
   1166    ASSERT(!mLinkingState);
   1167    return mState.getAttachedShader(shaderType);
   1168 }
   1169 
   1170 void Program::bindAttributeLocation(GLuint index, const char *name)
   1171 {
   1172    ASSERT(!mLinkingState);
   1173    mAttributeBindings.bindLocation(index, name);
   1174 }
   1175 
   1176 void Program::bindUniformLocation(UniformLocation location, const char *name)
   1177 {
   1178    ASSERT(!mLinkingState);
   1179    mState.mUniformLocationBindings.bindLocation(location.value, name);
   1180 }
   1181 
   1182 void Program::bindFragmentOutputLocation(GLuint index, const char *name)
   1183 {
   1184    mFragmentOutputLocations.bindLocation(index, name);
   1185 }
   1186 
   1187 void Program::bindFragmentOutputIndex(GLuint index, const char *name)
   1188 {
   1189    mFragmentOutputIndexes.bindLocation(index, name);
   1190 }
   1191 
   1192 angle::Result Program::link(const Context *context)
   1193 {
   1194    angle::Result result = linkImpl(context);
   1195 
   1196    // Avoid having two ProgramExecutables if the link failed and the Program had successfully
   1197    // linked previously.
   1198    if (mLinkingState && mLinkingState->linkedExecutable)
   1199    {
   1200        mState.mExecutable = mLinkingState->linkedExecutable;
   1201    }
   1202 
   1203    return result;
   1204 }
   1205 
   1206 // The attached shaders are checked for linking errors by matching up their variables.
   1207 // Uniform, input and output variables get collected.
   1208 // The code gets compiled into binaries.
   1209 angle::Result Program::linkImpl(const Context *context)
   1210 {
   1211    ASSERT(!mLinkingState);
   1212    // Don't make any local variables pointing to anything within the ProgramExecutable, since
   1213    // unlink() could make a new ProgramExecutable making any references/pointers invalid.
   1214    auto *platform   = ANGLEPlatformCurrent();
   1215    double startTime = platform->currentTime(platform);
   1216 
   1217    // Unlink the program, but do not clear the validation-related caching yet, since we can still
   1218    // use the previously linked program if linking the shaders fails.
   1219    mLinked = false;
   1220 
   1221    mState.mExecutable->resetInfoLog();
   1222 
   1223    // Validate we have properly attached shaders before checking the cache.
   1224    if (!linkValidateShaders(context, mState.mExecutable->getInfoLog()))
   1225    {
   1226        return angle::Result::Continue;
   1227    }
   1228 
   1229    egl::BlobCache::Key programHash = {0};
   1230    MemoryProgramCache *cache       = context->getMemoryProgramCache();
   1231 
   1232    // TODO: http://anglebug.com/4530: Enable program caching for separable programs
   1233    if (cache && !isSeparable())
   1234    {
   1235        std::lock_guard<std::mutex> cacheLock(context->getProgramCacheMutex());
   1236        angle::Result cacheResult = cache->getProgram(context, this, &programHash);
   1237        ANGLE_TRY(cacheResult);
   1238 
   1239        // Check explicitly for Continue, Incomplete means a cache miss
   1240        if (cacheResult == angle::Result::Continue)
   1241        {
   1242            std::scoped_lock lock(mHistogramMutex);
   1243            // Succeeded in loading the binaries in the front-end, back end may still be loading
   1244            // asynchronously
   1245            double delta = platform->currentTime(platform) - startTime;
   1246            int us       = static_cast<int>(delta * 1000000.0);
   1247            ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.ProgramCache.ProgramCacheHitTimeUS", us);
   1248            return angle::Result::Continue;
   1249        }
   1250    }
   1251 
   1252    // Cache load failed, fall through to normal linking.
   1253    unlink();
   1254    InfoLog &infoLog = mState.mExecutable->getInfoLog();
   1255 
   1256    // Re-link shaders after the unlink call.
   1257    bool result = linkValidateShaders(context, infoLog);
   1258    ASSERT(result);
   1259 
   1260    std::unique_ptr<LinkingState> linkingState(new LinkingState());
   1261    ProgramMergedVaryings mergedVaryings;
   1262    LinkingVariables linkingVariables(context, mState);
   1263    ProgramLinkedResources &resources = linkingState->resources;
   1264 
   1265    resources.init(&mState.mExecutable->mUniformBlocks, &mState.mExecutable->mUniforms,
   1266                   &mState.mExecutable->mShaderStorageBlocks, &mState.mBufferVariables,
   1267                   &mState.mExecutable->mAtomicCounterBuffers);
   1268 
   1269    // TODO: Fix incomplete linking. http://anglebug.com/6358
   1270    updateLinkedShaderStages();
   1271 
   1272    InitUniformBlockLinker(context, mState, &resources.uniformBlockLinker);
   1273    InitShaderStorageBlockLinker(context, mState, &resources.shaderStorageBlockLinker);
   1274 
   1275    if (mState.mAttachedShaders[ShaderType::Compute])
   1276    {
   1277        GLuint combinedImageUniforms = 0;
   1278        if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog))
   1279        {
   1280            return angle::Result::Continue;
   1281        }
   1282 
   1283        GLuint combinedShaderStorageBlocks = 0u;
   1284        if (!LinkValidateProgramInterfaceBlocks(context,
   1285                                                mState.mExecutable->getLinkedShaderStages(),
   1286                                                resources, infoLog, &combinedShaderStorageBlocks))
   1287        {
   1288            return angle::Result::Continue;
   1289        }
   1290 
   1291        // [OpenGL ES 3.1] Chapter 8.22 Page 203:
   1292        // A link error will be generated if the sum of the number of active image uniforms used in
   1293        // all shaders, the number of active shader storage blocks, and the number of active
   1294        // fragment shader outputs exceeds the implementation-dependent value of
   1295        // MAX_COMBINED_SHADER_OUTPUT_RESOURCES.
   1296        if (combinedImageUniforms + combinedShaderStorageBlocks >
   1297            static_cast<GLuint>(context->getCaps().maxCombinedShaderOutputResources))
   1298        {
   1299            infoLog
   1300                << "The sum of the number of active image uniforms, active shader storage blocks "
   1301                   "and active fragment shader outputs exceeds "
   1302                   "MAX_COMBINED_SHADER_OUTPUT_RESOURCES ("
   1303                << context->getCaps().maxCombinedShaderOutputResources << ")";
   1304            return angle::Result::Continue;
   1305        }
   1306    }
   1307    else
   1308    {
   1309        if (!linkAttributes(context, infoLog))
   1310        {
   1311            return angle::Result::Continue;
   1312        }
   1313 
   1314        if (!linkVaryings(context, infoLog))
   1315        {
   1316            return angle::Result::Continue;
   1317        }
   1318 
   1319        GLuint combinedImageUniforms = 0;
   1320        if (!linkUniforms(context, &resources.unusedUniforms, &combinedImageUniforms, infoLog))
   1321        {
   1322            return angle::Result::Continue;
   1323        }
   1324 
   1325        GLuint combinedShaderStorageBlocks = 0u;
   1326        if (!LinkValidateProgramInterfaceBlocks(context,
   1327                                                mState.mExecutable->getLinkedShaderStages(),
   1328                                                resources, infoLog, &combinedShaderStorageBlocks))
   1329        {
   1330            return angle::Result::Continue;
   1331        }
   1332 
   1333        if (!LinkValidateProgramGlobalNames(infoLog, getExecutable(), linkingVariables))
   1334        {
   1335            return angle::Result::Continue;
   1336        }
   1337 
   1338        gl::Shader *vertexShader = mState.mAttachedShaders[ShaderType::Vertex];
   1339        if (vertexShader)
   1340        {
   1341            mState.mNumViews = vertexShader->getNumViews(context);
   1342            mState.mSpecConstUsageBits |= vertexShader->getSpecConstUsageBits();
   1343        }
   1344 
   1345        gl::Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
   1346        if (fragmentShader)
   1347        {
   1348            if (!mState.mExecutable->linkValidateOutputVariables(
   1349                    context->getCaps(), context->getExtensions(), context->getClientVersion(),
   1350                    combinedImageUniforms, combinedShaderStorageBlocks,
   1351                    fragmentShader->getActiveOutputVariables(context),
   1352                    fragmentShader->getShaderVersion(context), mFragmentOutputLocations,
   1353                    mFragmentOutputIndexes))
   1354            {
   1355                return angle::Result::Continue;
   1356            }
   1357 
   1358            mState.mExecutable->mHasDiscard = fragmentShader->hasDiscard();
   1359            mState.mExecutable->mEnablesPerSampleShading =
   1360                fragmentShader->enablesPerSampleShading();
   1361            mState.mExecutable->mAdvancedBlendEquations =
   1362                fragmentShader->getAdvancedBlendEquations();
   1363            mState.mSpecConstUsageBits |= fragmentShader->getSpecConstUsageBits();
   1364        }
   1365 
   1366        mergedVaryings = GetMergedVaryingsFromLinkingVariables(linkingVariables);
   1367        if (!mState.mExecutable->linkMergedVaryings(
   1368                context, mergedVaryings, mState.mTransformFeedbackVaryingNames, linkingVariables,
   1369                isSeparable(), &resources.varyingPacking))
   1370        {
   1371            return angle::Result::Continue;
   1372        }
   1373    }
   1374 
   1375    mState.mExecutable->saveLinkedStateInfo(context, mState);
   1376 
   1377    mLinkingState                    = std::move(linkingState);
   1378    mLinkingState->linkingFromBinary = false;
   1379    mLinkingState->programHash       = programHash;
   1380    mLinkingState->linkEvent         = mProgram->link(context, resources, infoLog, mergedVaryings);
   1381 
   1382    // Must be after mProgram->link() to avoid misleading the linker about output variables.
   1383    mState.updateProgramInterfaceInputs(context);
   1384    mState.updateProgramInterfaceOutputs(context);
   1385 
   1386    if (mState.mSeparable)
   1387    {
   1388        mLinkingState->linkedExecutable = mState.mExecutable;
   1389    }
   1390 
   1391    return angle::Result::Continue;
   1392 }
   1393 
   1394 bool Program::isLinking() const
   1395 {
   1396    return (mLinkingState.get() && mLinkingState->linkEvent &&
   1397            mLinkingState->linkEvent->isLinking());
   1398 }
   1399 
   1400 void Program::resolveLinkImpl(const Context *context)
   1401 {
   1402    ASSERT(mLinkingState.get());
   1403 
   1404    angle::Result result = mLinkingState->linkEvent->wait(context);
   1405 
   1406    mLinked                                    = result == angle::Result::Continue;
   1407    std::unique_ptr<LinkingState> linkingState = std::move(mLinkingState);
   1408    if (!mLinked)
   1409    {
   1410        mState.mExecutable->reset(false);
   1411        return;
   1412    }
   1413 
   1414    if (linkingState->linkingFromBinary)
   1415    {
   1416        // All internal Program state is already loaded from the binary.
   1417        return;
   1418    }
   1419 
   1420    initInterfaceBlockBindings();
   1421 
   1422    // According to GLES 3.0/3.1 spec for LinkProgram and UseProgram,
   1423    // Only successfully linked program can replace the executables.
   1424    ASSERT(mLinked);
   1425 
   1426    // Mark implementation-specific unreferenced uniforms as ignored.
   1427    std::vector<ImageBinding> *imageBindings = getExecutable().getImageBindings();
   1428    mProgram->markUnusedUniformLocations(&mState.mUniformLocations,
   1429                                         &mState.mExecutable->mSamplerBindings, imageBindings);
   1430 
   1431    // Must be called after markUnusedUniformLocations.
   1432    postResolveLink(context);
   1433 
   1434    // Save to the program cache.
   1435    std::lock_guard<std::mutex> cacheLock(context->getProgramCacheMutex());
   1436    MemoryProgramCache *cache = context->getMemoryProgramCache();
   1437    // TODO: http://anglebug.com/4530: Enable program caching for separable programs
   1438    if (cache && !isSeparable() &&
   1439        (mState.mExecutable->mLinkedTransformFeedbackVaryings.empty() ||
   1440         !context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled))
   1441    {
   1442        if (cache->putProgram(linkingState->programHash, context, this) == angle::Result::Stop)
   1443        {
   1444            // Don't fail linking if putting the program binary into the cache fails, the program is
   1445            // still usable.
   1446            ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
   1447                               "Failed to save linked program to memory program cache.");
   1448        }
   1449    }
   1450 }
   1451 
   1452 void Program::updateLinkedShaderStages()
   1453 {
   1454    mState.mExecutable->resetLinkedShaderStages();
   1455 
   1456    for (const Shader *shader : mState.mAttachedShaders)
   1457    {
   1458        if (shader)
   1459        {
   1460            mState.mExecutable->setLinkedShaderStages(shader->getType());
   1461        }
   1462    }
   1463 }
   1464 
   1465 void ProgramState::updateActiveSamplers()
   1466 {
   1467    mExecutable->mActiveSamplerRefCounts.fill(0);
   1468    mExecutable->updateActiveSamplers(*this);
   1469 }
   1470 
   1471 void ProgramState::updateProgramInterfaceInputs(const Context *context)
   1472 {
   1473    const ShaderType firstAttachedShaderType = getFirstAttachedShaderStageType();
   1474 
   1475    if (firstAttachedShaderType == ShaderType::Vertex)
   1476    {
   1477        // Vertex attributes are already what we need, so nothing to do
   1478        return;
   1479    }
   1480 
   1481    Shader *shader = getAttachedShader(firstAttachedShaderType);
   1482    ASSERT(shader);
   1483 
   1484    // Copy over each input varying, since the Shader could go away
   1485    if (shader->getType() == ShaderType::Compute)
   1486    {
   1487        for (const sh::ShaderVariable &attribute : shader->getAllAttributes(context))
   1488        {
   1489            // Compute Shaders have the following built-in input variables.
   1490            //
   1491            // in uvec3 gl_NumWorkGroups;
   1492            // in uvec3 gl_WorkGroupID;
   1493            // in uvec3 gl_LocalInvocationID;
   1494            // in uvec3 gl_GlobalInvocationID;
   1495            // in uint  gl_LocalInvocationIndex;
   1496            // They are all vecs or uints, so no special handling is required.
   1497            mExecutable->mProgramInputs.emplace_back(attribute);
   1498        }
   1499    }
   1500    else
   1501    {
   1502        for (const sh::ShaderVariable &varying : shader->getInputVaryings(context))
   1503        {
   1504            UpdateInterfaceVariable(&mExecutable->mProgramInputs, varying);
   1505        }
   1506    }
   1507 }
   1508 
   1509 void ProgramState::updateProgramInterfaceOutputs(const Context *context)
   1510 {
   1511    const ShaderType lastAttachedShaderType = getLastAttachedShaderStageType();
   1512 
   1513    if (lastAttachedShaderType == ShaderType::Fragment)
   1514    {
   1515        // Fragment outputs are already what we need, so nothing to do
   1516        return;
   1517    }
   1518    if (lastAttachedShaderType == ShaderType::Compute)
   1519    {
   1520        // If the program only contains a Compute Shader, then there are no user-defined outputs.
   1521        return;
   1522    }
   1523 
   1524    Shader *shader = getAttachedShader(lastAttachedShaderType);
   1525    ASSERT(shader);
   1526 
   1527    // Copy over each output varying, since the Shader could go away
   1528    for (const sh::ShaderVariable &varying : shader->getOutputVaryings(context))
   1529    {
   1530        UpdateInterfaceVariable(&mExecutable->mOutputVariables, varying);
   1531    }
   1532 }
   1533 
   1534 // Returns the program object to an unlinked state, before re-linking, or at destruction
   1535 void Program::unlink()
   1536 {
   1537    if (mLinkingState && mLinkingState->linkedExecutable)
   1538    {
   1539        // The new ProgramExecutable that we'll attempt to link with needs to start from a copy of
   1540        // the last successfully linked ProgramExecutable, so we don't lose any state information.
   1541        mState.mExecutable.reset(new ProgramExecutable(*mLinkingState->linkedExecutable));
   1542    }
   1543    mState.mExecutable->reset(true);
   1544 
   1545    mState.mUniformLocations.clear();
   1546    mState.mBufferVariables.clear();
   1547    mState.mComputeShaderLocalSize.fill(1);
   1548    mState.mNumViews             = -1;
   1549    mState.mDrawIDLocation       = -1;
   1550    mState.mBaseVertexLocation   = -1;
   1551    mState.mBaseInstanceLocation = -1;
   1552    mState.mCachedBaseVertex     = 0;
   1553    mState.mCachedBaseInstance   = 0;
   1554    mState.mSpecConstUsageBits.reset();
   1555 
   1556    mValidated = false;
   1557 
   1558    mLinked = false;
   1559 }
   1560 
   1561 angle::Result Program::loadBinary(const Context *context,
   1562                                  GLenum binaryFormat,
   1563                                  const void *binary,
   1564                                  GLsizei length)
   1565 {
   1566    ASSERT(!mLinkingState);
   1567    unlink();
   1568    InfoLog &infoLog = mState.mExecutable->getInfoLog();
   1569 
   1570    if (!angle::GetANGLEHasBinaryLoading())
   1571    {
   1572        return angle::Result::Incomplete;
   1573    }
   1574 
   1575    ASSERT(binaryFormat == GL_PROGRAM_BINARY_ANGLE);
   1576    if (binaryFormat != GL_PROGRAM_BINARY_ANGLE)
   1577    {
   1578        infoLog << "Invalid program binary format.";
   1579        return angle::Result::Incomplete;
   1580    }
   1581 
   1582    BinaryInputStream stream(binary, length);
   1583    ANGLE_TRY(deserialize(context, stream, infoLog));
   1584    // Currently we require the full shader text to compute the program hash.
   1585    // We could also store the binary in the internal program cache.
   1586 
   1587    for (size_t uniformBlockIndex = 0;
   1588         uniformBlockIndex < mState.mExecutable->getActiveUniformBlockCount(); ++uniformBlockIndex)
   1589    {
   1590        mDirtyBits.set(uniformBlockIndex);
   1591    }
   1592 
   1593    // The rx::LinkEvent returned from ProgramImpl::load is a base class with multiple
   1594    // implementations. In some implementations, a background thread is used to compile the
   1595    // shaders. Any calls to the LinkEvent object, therefore, are racy and may interfere with
   1596    // the operation.
   1597 
   1598    // We do not want to call LinkEvent::wait because that will cause the background thread
   1599    // to finish its task before returning, thus defeating the purpose of background compilation.
   1600    // We need to defer waiting on background compilation until the very last minute when we
   1601    // absolutely need the results, such as when the developer binds the program or queries
   1602    // for the completion status.
   1603 
   1604    // If load returns nullptr, we know for sure that the binary is not compatible with the backend.
   1605    // The loaded binary could have been read from the on-disk shader cache and be corrupted or
   1606    // serialized with different revision and subsystem id than the currently loaded backend.
   1607    // Returning 'Incomplete' to the caller results in link happening using the original shader
   1608    // sources.
   1609    angle::Result result;
   1610    std::unique_ptr<LinkingState> linkingState;
   1611    std::unique_ptr<rx::LinkEvent> linkEvent = mProgram->load(context, &stream, infoLog);
   1612    if (linkEvent)
   1613    {
   1614        linkingState                    = std::make_unique<LinkingState>();
   1615        linkingState->linkingFromBinary = true;
   1616        linkingState->linkEvent         = std::move(linkEvent);
   1617        result                          = angle::Result::Continue;
   1618    }
   1619    else
   1620    {
   1621        result = angle::Result::Incomplete;
   1622    }
   1623    mLinkingState = std::move(linkingState);
   1624 
   1625    return result;
   1626 }
   1627 
   1628 angle::Result Program::saveBinary(Context *context,
   1629                                  GLenum *binaryFormat,
   1630                                  void *binary,
   1631                                  GLsizei bufSize,
   1632                                  GLsizei *length) const
   1633 {
   1634    ASSERT(!mLinkingState);
   1635    if (binaryFormat)
   1636    {
   1637        *binaryFormat = GL_PROGRAM_BINARY_ANGLE;
   1638    }
   1639 
   1640    angle::MemoryBuffer memoryBuf;
   1641    ANGLE_TRY(serialize(context, &memoryBuf));
   1642 
   1643    GLsizei streamLength       = static_cast<GLsizei>(memoryBuf.size());
   1644    const uint8_t *streamState = memoryBuf.data();
   1645 
   1646    if (streamLength > bufSize)
   1647    {
   1648        if (length)
   1649        {
   1650            *length = 0;
   1651        }
   1652 
   1653        // TODO: This should be moved to the validation layer but computing the size of the binary
   1654        // before saving it causes the save to happen twice.  It may be possible to write the binary
   1655        // to a separate buffer, validate sizes and then copy it.
   1656        ANGLE_CHECK(context, false, "Insufficient buffer size", GL_INVALID_OPERATION);
   1657    }
   1658 
   1659    if (binary)
   1660    {
   1661        char *ptr = reinterpret_cast<char *>(binary);
   1662 
   1663        memcpy(ptr, streamState, streamLength);
   1664        ptr += streamLength;
   1665 
   1666        ASSERT(ptr - streamLength == binary);
   1667    }
   1668 
   1669    if (length)
   1670    {
   1671        *length = streamLength;
   1672    }
   1673 
   1674    return angle::Result::Continue;
   1675 }
   1676 
   1677 GLint Program::getBinaryLength(Context *context) const
   1678 {
   1679    ASSERT(!mLinkingState);
   1680    if (!mLinked)
   1681    {
   1682        return 0;
   1683    }
   1684 
   1685    GLint length;
   1686    angle::Result result =
   1687        saveBinary(context, nullptr, nullptr, std::numeric_limits<GLint>::max(), &length);
   1688    if (result != angle::Result::Continue)
   1689    {
   1690        return 0;
   1691    }
   1692 
   1693    return length;
   1694 }
   1695 
   1696 void Program::setBinaryRetrievableHint(bool retrievable)
   1697 {
   1698    ASSERT(!mLinkingState);
   1699    // TODO(jmadill) : replace with dirty bits
   1700    mProgram->setBinaryRetrievableHint(retrievable);
   1701    mState.mBinaryRetrieveableHint = retrievable;
   1702 }
   1703 
   1704 bool Program::getBinaryRetrievableHint() const
   1705 {
   1706    ASSERT(!mLinkingState);
   1707    return mState.mBinaryRetrieveableHint;
   1708 }
   1709 
   1710 void Program::setSeparable(bool separable)
   1711 {
   1712    ASSERT(!mLinkingState);
   1713    // TODO(yunchao) : replace with dirty bits
   1714    if (mState.mSeparable != separable)
   1715    {
   1716        mProgram->setSeparable(separable);
   1717        mState.mSeparable = separable;
   1718    }
   1719 }
   1720 
   1721 bool Program::isSeparable() const
   1722 {
   1723    ASSERT(!mLinkingState);
   1724    return mState.mSeparable;
   1725 }
   1726 
   1727 void Program::deleteSelf(const Context *context)
   1728 {
   1729    ASSERT(mRefCount == 0 && mDeleteStatus);
   1730    mResourceManager->deleteProgram(context, mHandle);
   1731 }
   1732 
   1733 unsigned int Program::getRefCount() const
   1734 {
   1735    return mRefCount;
   1736 }
   1737 
   1738 void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, ShaderProgramID *shaders) const
   1739 {
   1740    ASSERT(!mLinkingState);
   1741    int total = 0;
   1742 
   1743    for (const Shader *shader : mState.mAttachedShaders)
   1744    {
   1745        if (shader && (total < maxCount))
   1746        {
   1747            shaders[total] = shader->getHandle();
   1748            ++total;
   1749        }
   1750    }
   1751 
   1752    if (count)
   1753    {
   1754        *count = total;
   1755    }
   1756 }
   1757 
   1758 GLuint Program::getAttributeLocation(const std::string &name) const
   1759 {
   1760    ASSERT(!mLinkingState);
   1761    return mState.getAttributeLocation(name);
   1762 }
   1763 
   1764 void Program::getActiveAttribute(GLuint index,
   1765                                 GLsizei bufsize,
   1766                                 GLsizei *length,
   1767                                 GLint *size,
   1768                                 GLenum *type,
   1769                                 GLchar *name) const
   1770 {
   1771    ASSERT(!mLinkingState);
   1772    if (!mLinked)
   1773    {
   1774        if (bufsize > 0)
   1775        {
   1776            name[0] = '\0';
   1777        }
   1778 
   1779        if (length)
   1780        {
   1781            *length = 0;
   1782        }
   1783 
   1784        *type = GL_NONE;
   1785        *size = 1;
   1786        return;
   1787    }
   1788 
   1789    ASSERT(index < mState.mExecutable->getProgramInputs().size());
   1790    const sh::ShaderVariable &attrib = mState.mExecutable->getProgramInputs()[index];
   1791 
   1792    if (bufsize > 0)
   1793    {
   1794        CopyStringToBuffer(name, attrib.name, bufsize, length);
   1795    }
   1796 
   1797    // Always a single 'type' instance
   1798    *size = 1;
   1799    *type = attrib.type;
   1800 }
   1801 
   1802 GLint Program::getActiveAttributeCount() const
   1803 {
   1804    ASSERT(!mLinkingState);
   1805    if (!mLinked)
   1806    {
   1807        return 0;
   1808    }
   1809 
   1810    return static_cast<GLint>(mState.mExecutable->getProgramInputs().size());
   1811 }
   1812 
   1813 GLint Program::getActiveAttributeMaxLength() const
   1814 {
   1815    ASSERT(!mLinkingState);
   1816    if (!mLinked)
   1817    {
   1818        return 0;
   1819    }
   1820 
   1821    size_t maxLength = 0;
   1822 
   1823    for (const sh::ShaderVariable &attrib : mState.mExecutable->getProgramInputs())
   1824    {
   1825        maxLength = std::max(attrib.name.length() + 1, maxLength);
   1826    }
   1827 
   1828    return static_cast<GLint>(maxLength);
   1829 }
   1830 
   1831 const std::vector<sh::ShaderVariable> &Program::getAttributes() const
   1832 {
   1833    ASSERT(!mLinkingState);
   1834    return mState.mExecutable->getProgramInputs();
   1835 }
   1836 
   1837 const sh::WorkGroupSize &Program::getComputeShaderLocalSize() const
   1838 {
   1839    ASSERT(!mLinkingState);
   1840    return mState.mComputeShaderLocalSize;
   1841 }
   1842 
   1843 PrimitiveMode Program::getGeometryShaderInputPrimitiveType() const
   1844 {
   1845    ASSERT(!mLinkingState && mState.mExecutable);
   1846    return mState.mExecutable->getGeometryShaderInputPrimitiveType();
   1847 }
   1848 PrimitiveMode Program::getGeometryShaderOutputPrimitiveType() const
   1849 {
   1850    ASSERT(!mLinkingState && mState.mExecutable);
   1851    return mState.mExecutable->getGeometryShaderOutputPrimitiveType();
   1852 }
   1853 GLint Program::getGeometryShaderInvocations() const
   1854 {
   1855    ASSERT(!mLinkingState && mState.mExecutable);
   1856    return mState.mExecutable->getGeometryShaderInvocations();
   1857 }
   1858 GLint Program::getGeometryShaderMaxVertices() const
   1859 {
   1860    ASSERT(!mLinkingState && mState.mExecutable);
   1861    return mState.mExecutable->getGeometryShaderMaxVertices();
   1862 }
   1863 
   1864 GLint Program::getTessControlShaderVertices() const
   1865 {
   1866    ASSERT(!mLinkingState && mState.mExecutable);
   1867    return mState.mExecutable->mTessControlShaderVertices;
   1868 }
   1869 
   1870 GLenum Program::getTessGenMode() const
   1871 {
   1872    ASSERT(!mLinkingState && mState.mExecutable);
   1873    return mState.mExecutable->mTessGenMode;
   1874 }
   1875 
   1876 GLenum Program::getTessGenPointMode() const
   1877 {
   1878    ASSERT(!mLinkingState && mState.mExecutable);
   1879    return mState.mExecutable->mTessGenPointMode;
   1880 }
   1881 
   1882 GLenum Program::getTessGenSpacing() const
   1883 {
   1884    ASSERT(!mLinkingState && mState.mExecutable);
   1885    return mState.mExecutable->mTessGenSpacing;
   1886 }
   1887 
   1888 GLenum Program::getTessGenVertexOrder() const
   1889 {
   1890    ASSERT(!mLinkingState && mState.mExecutable);
   1891    return mState.mExecutable->mTessGenVertexOrder;
   1892 }
   1893 
   1894 const sh::ShaderVariable &Program::getInputResource(size_t index) const
   1895 {
   1896    ASSERT(!mLinkingState);
   1897    ASSERT(index < mState.mExecutable->getProgramInputs().size());
   1898    return mState.mExecutable->getProgramInputs()[index];
   1899 }
   1900 
   1901 GLuint Program::getInputResourceIndex(const GLchar *name) const
   1902 {
   1903    ASSERT(!mLinkingState);
   1904    const std::string nameString = StripLastArrayIndex(name);
   1905 
   1906    for (size_t index = 0; index < mState.mExecutable->getProgramInputs().size(); index++)
   1907    {
   1908        sh::ShaderVariable resource = getInputResource(index);
   1909        if (resource.name == nameString)
   1910        {
   1911            return static_cast<GLuint>(index);
   1912        }
   1913    }
   1914 
   1915    return GL_INVALID_INDEX;
   1916 }
   1917 
   1918 GLuint Program::getResourceMaxNameSize(const sh::ShaderVariable &resource, GLint max) const
   1919 {
   1920    if (resource.isArray())
   1921    {
   1922        return std::max(max, clampCast<GLint>((resource.name + "[0]").size()));
   1923    }
   1924    else
   1925    {
   1926        return std::max(max, clampCast<GLint>((resource.name).size()));
   1927    }
   1928 }
   1929 
   1930 GLuint Program::getInputResourceMaxNameSize() const
   1931 {
   1932    GLint max = 0;
   1933 
   1934    for (const sh::ShaderVariable &resource : mState.mExecutable->getProgramInputs())
   1935    {
   1936        max = getResourceMaxNameSize(resource, max);
   1937    }
   1938 
   1939    return max;
   1940 }
   1941 
   1942 GLuint Program::getOutputResourceMaxNameSize() const
   1943 {
   1944    GLint max = 0;
   1945 
   1946    for (const sh::ShaderVariable &resource : mState.mExecutable->getOutputVariables())
   1947    {
   1948        max = getResourceMaxNameSize(resource, max);
   1949    }
   1950 
   1951    return max;
   1952 }
   1953 
   1954 GLuint Program::getResourceLocation(const GLchar *name, const sh::ShaderVariable &variable) const
   1955 {
   1956    if (variable.isBuiltIn())
   1957    {
   1958        return GL_INVALID_INDEX;
   1959    }
   1960 
   1961    GLint location = variable.location;
   1962    if (variable.isArray())
   1963    {
   1964        size_t nameLengthWithoutArrayIndexOut;
   1965        size_t arrayIndex = ParseArrayIndex(name, &nameLengthWithoutArrayIndexOut);
   1966        // The 'name' string may not contain the array notation "[0]"
   1967        if (arrayIndex != GL_INVALID_INDEX)
   1968        {
   1969            location += arrayIndex;
   1970        }
   1971    }
   1972 
   1973    return location;
   1974 }
   1975 
   1976 GLuint Program::getInputResourceLocation(const GLchar *name) const
   1977 {
   1978    const GLuint index = getInputResourceIndex(name);
   1979    if (index == GL_INVALID_INDEX)
   1980    {
   1981        return index;
   1982    }
   1983 
   1984    const sh::ShaderVariable &variable = getInputResource(index);
   1985 
   1986    return getResourceLocation(name, variable);
   1987 }
   1988 
   1989 GLuint Program::getOutputResourceLocation(const GLchar *name) const
   1990 {
   1991    const GLuint index = getOutputResourceIndex(name);
   1992    if (index == GL_INVALID_INDEX)
   1993    {
   1994        return index;
   1995    }
   1996 
   1997    const sh::ShaderVariable &variable = getOutputResource(index);
   1998 
   1999    return getResourceLocation(name, variable);
   2000 }
   2001 
   2002 GLuint Program::getOutputResourceIndex(const GLchar *name) const
   2003 {
   2004    ASSERT(!mLinkingState);
   2005    const std::string nameString = StripLastArrayIndex(name);
   2006 
   2007    for (size_t index = 0; index < mState.mExecutable->getOutputVariables().size(); index++)
   2008    {
   2009        sh::ShaderVariable resource = getOutputResource(index);
   2010        if (resource.name == nameString)
   2011        {
   2012            return static_cast<GLuint>(index);
   2013        }
   2014    }
   2015 
   2016    return GL_INVALID_INDEX;
   2017 }
   2018 
   2019 size_t Program::getOutputResourceCount() const
   2020 {
   2021    ASSERT(!mLinkingState);
   2022    return (mLinked ? mState.mExecutable->getOutputVariables().size() : 0);
   2023 }
   2024 
   2025 void Program::getResourceName(const std::string name,
   2026                              GLsizei bufSize,
   2027                              GLsizei *length,
   2028                              GLchar *dest) const
   2029 {
   2030    if (length)
   2031    {
   2032        *length = 0;
   2033    }
   2034 
   2035    if (!mLinked)
   2036    {
   2037        if (bufSize > 0)
   2038        {
   2039            dest[0] = '\0';
   2040        }
   2041        return;
   2042    }
   2043 
   2044    if (bufSize > 0)
   2045    {
   2046        CopyStringToBuffer(dest, name, bufSize, length);
   2047    }
   2048 }
   2049 
   2050 void Program::getInputResourceName(GLuint index,
   2051                                   GLsizei bufSize,
   2052                                   GLsizei *length,
   2053                                   GLchar *name) const
   2054 {
   2055    ASSERT(!mLinkingState);
   2056    getResourceName(getInputResourceName(index), bufSize, length, name);
   2057 }
   2058 
   2059 void Program::getOutputResourceName(GLuint index,
   2060                                    GLsizei bufSize,
   2061                                    GLsizei *length,
   2062                                    GLchar *name) const
   2063 {
   2064    ASSERT(!mLinkingState);
   2065    getResourceName(getOutputResourceName(index), bufSize, length, name);
   2066 }
   2067 
   2068 void Program::getUniformResourceName(GLuint index,
   2069                                     GLsizei bufSize,
   2070                                     GLsizei *length,
   2071                                     GLchar *name) const
   2072 {
   2073    ASSERT(!mLinkingState);
   2074    ASSERT(index < mState.mExecutable->getUniforms().size());
   2075    getResourceName(mState.mExecutable->getUniforms()[index].name, bufSize, length, name);
   2076 }
   2077 
   2078 void Program::getBufferVariableResourceName(GLuint index,
   2079                                            GLsizei bufSize,
   2080                                            GLsizei *length,
   2081                                            GLchar *name) const
   2082 {
   2083    ASSERT(!mLinkingState);
   2084    ASSERT(index < mState.mBufferVariables.size());
   2085    getResourceName(mState.mBufferVariables[index].name, bufSize, length, name);
   2086 }
   2087 
   2088 const std::string Program::getResourceName(const sh::ShaderVariable &resource) const
   2089 {
   2090    std::string resourceName = resource.name;
   2091 
   2092    if (resource.isArray())
   2093    {
   2094        resourceName += "[0]";
   2095    }
   2096 
   2097    return resourceName;
   2098 }
   2099 
   2100 const std::string Program::getInputResourceName(GLuint index) const
   2101 {
   2102    ASSERT(!mLinkingState);
   2103    const sh::ShaderVariable &resource = getInputResource(index);
   2104 
   2105    return getResourceName(resource);
   2106 }
   2107 
   2108 const std::string Program::getOutputResourceName(GLuint index) const
   2109 {
   2110    ASSERT(!mLinkingState);
   2111    const sh::ShaderVariable &resource = getOutputResource(index);
   2112 
   2113    return getResourceName(resource);
   2114 }
   2115 
   2116 const sh::ShaderVariable &Program::getOutputResource(size_t index) const
   2117 {
   2118    ASSERT(!mLinkingState);
   2119    ASSERT(index < mState.mExecutable->getOutputVariables().size());
   2120    return mState.mExecutable->getOutputVariables()[index];
   2121 }
   2122 
   2123 const ProgramBindings &Program::getAttributeBindings() const
   2124 {
   2125    ASSERT(!mLinkingState);
   2126    return mAttributeBindings;
   2127 }
   2128 const ProgramAliasedBindings &Program::getUniformLocationBindings() const
   2129 {
   2130    ASSERT(!mLinkingState);
   2131    return mState.mUniformLocationBindings;
   2132 }
   2133 
   2134 const gl::ProgramAliasedBindings &Program::getFragmentOutputLocations() const
   2135 {
   2136    ASSERT(!mLinkingState);
   2137    return mFragmentOutputLocations;
   2138 }
   2139 
   2140 const gl::ProgramAliasedBindings &Program::getFragmentOutputIndexes() const
   2141 {
   2142    ASSERT(!mLinkingState);
   2143    return mFragmentOutputIndexes;
   2144 }
   2145 
   2146 const std::vector<GLsizei> &Program::getTransformFeedbackStrides() const
   2147 {
   2148    ASSERT(!mLinkingState);
   2149    return mState.mExecutable->getTransformFeedbackStrides();
   2150 }
   2151 
   2152 GLint Program::getFragDataLocation(const std::string &name) const
   2153 {
   2154    ASSERT(!mLinkingState);
   2155    GLint primaryLocation = GetVariableLocation(mState.mExecutable->getOutputVariables(),
   2156                                                mState.mExecutable->getOutputLocations(), name);
   2157    if (primaryLocation != -1)
   2158    {
   2159        return primaryLocation;
   2160    }
   2161    return GetVariableLocation(mState.mExecutable->getOutputVariables(),
   2162                               mState.mExecutable->getSecondaryOutputLocations(), name);
   2163 }
   2164 
   2165 GLint Program::getFragDataIndex(const std::string &name) const
   2166 {
   2167    ASSERT(!mLinkingState);
   2168    if (GetVariableLocation(mState.mExecutable->getOutputVariables(),
   2169                            mState.mExecutable->getOutputLocations(), name) != -1)
   2170    {
   2171        return 0;
   2172    }
   2173    if (GetVariableLocation(mState.mExecutable->getOutputVariables(),
   2174                            mState.mExecutable->getSecondaryOutputLocations(), name) != -1)
   2175    {
   2176        return 1;
   2177    }
   2178    return -1;
   2179 }
   2180 
   2181 void Program::getActiveUniform(GLuint index,
   2182                               GLsizei bufsize,
   2183                               GLsizei *length,
   2184                               GLint *size,
   2185                               GLenum *type,
   2186                               GLchar *name) const
   2187 {
   2188    ASSERT(!mLinkingState);
   2189    if (mLinked)
   2190    {
   2191        // index must be smaller than getActiveUniformCount()
   2192        ASSERT(index < mState.mExecutable->getUniforms().size());
   2193        const LinkedUniform &uniform = mState.mExecutable->getUniforms()[index];
   2194 
   2195        if (bufsize > 0)
   2196        {
   2197            std::string string = uniform.name;
   2198            CopyStringToBuffer(name, string, bufsize, length);
   2199        }
   2200 
   2201        *size = clampCast<GLint>(uniform.getBasicTypeElementCount());
   2202        *type = uniform.type;
   2203    }
   2204    else
   2205    {
   2206        if (bufsize > 0)
   2207        {
   2208            name[0] = '\0';
   2209        }
   2210 
   2211        if (length)
   2212        {
   2213            *length = 0;
   2214        }
   2215 
   2216        *size = 0;
   2217        *type = GL_NONE;
   2218    }
   2219 }
   2220 
   2221 GLint Program::getActiveUniformCount() const
   2222 {
   2223    ASSERT(!mLinkingState);
   2224    if (mLinked)
   2225    {
   2226        return static_cast<GLint>(mState.mExecutable->getUniforms().size());
   2227    }
   2228    else
   2229    {
   2230        return 0;
   2231    }
   2232 }
   2233 
   2234 size_t Program::getActiveBufferVariableCount() const
   2235 {
   2236    ASSERT(!mLinkingState);
   2237    return mLinked ? mState.mBufferVariables.size() : 0;
   2238 }
   2239 
   2240 GLint Program::getActiveUniformMaxLength() const
   2241 {
   2242    ASSERT(!mLinkingState);
   2243    size_t maxLength = 0;
   2244 
   2245    if (mLinked)
   2246    {
   2247        for (const LinkedUniform &uniform : mState.mExecutable->getUniforms())
   2248        {
   2249            if (!uniform.name.empty())
   2250            {
   2251                size_t length = uniform.name.length() + 1u;
   2252                if (uniform.isArray())
   2253                {
   2254                    length += 3;  // Counting in "[0]".
   2255                }
   2256                maxLength = std::max(length, maxLength);
   2257            }
   2258        }
   2259    }
   2260 
   2261    return static_cast<GLint>(maxLength);
   2262 }
   2263 
   2264 bool Program::isValidUniformLocation(UniformLocation location) const
   2265 {
   2266    ASSERT(!mLinkingState);
   2267    ASSERT(angle::IsValueInRangeForNumericType<GLint>(mState.mUniformLocations.size()));
   2268    return (location.value >= 0 &&
   2269            static_cast<size_t>(location.value) < mState.mUniformLocations.size() &&
   2270            mState.mUniformLocations[static_cast<size_t>(location.value)].used());
   2271 }
   2272 
   2273 const LinkedUniform &Program::getUniformByLocation(UniformLocation location) const
   2274 {
   2275    ASSERT(!mLinkingState);
   2276    ASSERT(location.value >= 0 &&
   2277           static_cast<size_t>(location.value) < mState.mUniformLocations.size());
   2278    return mState.mExecutable->getUniforms()[mState.getUniformIndexFromLocation(location)];
   2279 }
   2280 
   2281 const VariableLocation &Program::getUniformLocation(UniformLocation location) const
   2282 {
   2283    ASSERT(!mLinkingState);
   2284    ASSERT(location.value >= 0 &&
   2285           static_cast<size_t>(location.value) < mState.mUniformLocations.size());
   2286    return mState.mUniformLocations[location.value];
   2287 }
   2288 
   2289 const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
   2290 {
   2291    ASSERT(!mLinkingState);
   2292    ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
   2293    return mState.mBufferVariables[index];
   2294 }
   2295 
   2296 UniformLocation Program::getUniformLocation(const std::string &name) const
   2297 {
   2298    ASSERT(!mLinkingState);
   2299    return {GetVariableLocation(mState.mExecutable->getUniforms(), mState.mUniformLocations, name)};
   2300 }
   2301 
   2302 GLuint Program::getUniformIndex(const std::string &name) const
   2303 {
   2304    ASSERT(!mLinkingState);
   2305    return mState.getUniformIndexFromName(name);
   2306 }
   2307 
   2308 bool Program::shouldIgnoreUniform(UniformLocation location) const
   2309 {
   2310    if (location.value == -1)
   2311    {
   2312        return true;
   2313    }
   2314 
   2315    if (mState.mUniformLocations[static_cast<size_t>(location.value)].ignored)
   2316    {
   2317        return true;
   2318    }
   2319 
   2320    return false;
   2321 }
   2322 
   2323 template <typename UniformT,
   2324          GLint UniformSize,
   2325          void (rx::ProgramImpl::*SetUniformFunc)(GLint, GLsizei, const UniformT *)>
   2326 void Program::setUniformGeneric(UniformLocation location, GLsizei count, const UniformT *v)
   2327 {
   2328    ASSERT(!mLinkingState);
   2329    if (shouldIgnoreUniform(location))
   2330    {
   2331        return;
   2332    }
   2333 
   2334    const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
   2335    GLsizei clampedCount                 = clampUniformCount(locationInfo, count, UniformSize, v);
   2336    (mProgram->*SetUniformFunc)(location.value, clampedCount, v);
   2337    onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
   2338 }
   2339 
   2340 void Program::setUniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
   2341 {
   2342    setUniformGeneric<GLfloat, 1, &rx::ProgramImpl::setUniform1fv>(location, count, v);
   2343 }
   2344 
   2345 void Program::setUniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
   2346 {
   2347    setUniformGeneric<GLfloat, 2, &rx::ProgramImpl::setUniform2fv>(location, count, v);
   2348 }
   2349 
   2350 void Program::setUniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
   2351 {
   2352    setUniformGeneric<GLfloat, 3, &rx::ProgramImpl::setUniform3fv>(location, count, v);
   2353 }
   2354 
   2355 void Program::setUniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
   2356 {
   2357    setUniformGeneric<GLfloat, 4, &rx::ProgramImpl::setUniform4fv>(location, count, v);
   2358 }
   2359 
   2360 void Program::setUniform1iv(Context *context,
   2361                            UniformLocation location,
   2362                            GLsizei count,
   2363                            const GLint *v)
   2364 {
   2365    ASSERT(!mLinkingState);
   2366    if (shouldIgnoreUniform(location))
   2367    {
   2368        return;
   2369    }
   2370 
   2371    const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
   2372    GLsizei clampedCount                 = clampUniformCount(locationInfo, count, 1, v);
   2373 
   2374    mProgram->setUniform1iv(location.value, clampedCount, v);
   2375 
   2376    if (mState.isSamplerUniformIndex(locationInfo.index))
   2377    {
   2378        updateSamplerUniform(context, locationInfo, clampedCount, v);
   2379    }
   2380    else
   2381    {
   2382        onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
   2383    }
   2384 }
   2385 
   2386 void Program::setUniform2iv(UniformLocation location, GLsizei count, const GLint *v)
   2387 {
   2388    setUniformGeneric<GLint, 2, &rx::ProgramImpl::setUniform2iv>(location, count, v);
   2389 }
   2390 
   2391 void Program::setUniform3iv(UniformLocation location, GLsizei count, const GLint *v)
   2392 {
   2393    setUniformGeneric<GLint, 3, &rx::ProgramImpl::setUniform3iv>(location, count, v);
   2394 }
   2395 
   2396 void Program::setUniform4iv(UniformLocation location, GLsizei count, const GLint *v)
   2397 {
   2398    setUniformGeneric<GLint, 4, &rx::ProgramImpl::setUniform4iv>(location, count, v);
   2399 }
   2400 
   2401 void Program::setUniform1uiv(UniformLocation location, GLsizei count, const GLuint *v)
   2402 {
   2403    setUniformGeneric<GLuint, 1, &rx::ProgramImpl::setUniform1uiv>(location, count, v);
   2404 }
   2405 
   2406 void Program::setUniform2uiv(UniformLocation location, GLsizei count, const GLuint *v)
   2407 {
   2408    setUniformGeneric<GLuint, 2, &rx::ProgramImpl::setUniform2uiv>(location, count, v);
   2409 }
   2410 
   2411 void Program::setUniform3uiv(UniformLocation location, GLsizei count, const GLuint *v)
   2412 {
   2413    setUniformGeneric<GLuint, 3, &rx::ProgramImpl::setUniform3uiv>(location, count, v);
   2414 }
   2415 
   2416 void Program::setUniform4uiv(UniformLocation location, GLsizei count, const GLuint *v)
   2417 {
   2418    setUniformGeneric<GLuint, 4, &rx::ProgramImpl::setUniform4uiv>(location, count, v);
   2419 }
   2420 
   2421 template <
   2422    typename UniformT,
   2423    GLint MatrixC,
   2424    GLint MatrixR,
   2425    void (rx::ProgramImpl::*SetUniformMatrixFunc)(GLint, GLsizei, GLboolean, const UniformT *)>
   2426 void Program::setUniformMatrixGeneric(UniformLocation location,
   2427                                      GLsizei count,
   2428                                      GLboolean transpose,
   2429                                      const UniformT *v)
   2430 {
   2431    ASSERT(!mLinkingState);
   2432    if (shouldIgnoreUniform(location))
   2433    {
   2434        return;
   2435    }
   2436 
   2437    GLsizei clampedCount = clampMatrixUniformCount<MatrixC, MatrixR>(location, count, transpose, v);
   2438    (mProgram->*SetUniformMatrixFunc)(location.value, clampedCount, transpose, v);
   2439    onStateChange(angle::SubjectMessage::ProgramUniformUpdated);
   2440 }
   2441 
   2442 void Program::setUniformMatrix2fv(UniformLocation location,
   2443                                  GLsizei count,
   2444                                  GLboolean transpose,
   2445                                  const GLfloat *v)
   2446 {
   2447    setUniformMatrixGeneric<GLfloat, 2, 2, &rx::ProgramImpl::setUniformMatrix2fv>(location, count,
   2448                                                                                  transpose, v);
   2449 }
   2450 
   2451 void Program::setUniformMatrix3fv(UniformLocation location,
   2452                                  GLsizei count,
   2453                                  GLboolean transpose,
   2454                                  const GLfloat *v)
   2455 {
   2456    setUniformMatrixGeneric<GLfloat, 3, 3, &rx::ProgramImpl::setUniformMatrix3fv>(location, count,
   2457                                                                                  transpose, v);
   2458 }
   2459 
   2460 void Program::setUniformMatrix4fv(UniformLocation location,
   2461                                  GLsizei count,
   2462                                  GLboolean transpose,
   2463                                  const GLfloat *v)
   2464 {
   2465    setUniformMatrixGeneric<GLfloat, 4, 4, &rx::ProgramImpl::setUniformMatrix4fv>(location, count,
   2466                                                                                  transpose, v);
   2467 }
   2468 
   2469 void Program::setUniformMatrix2x3fv(UniformLocation location,
   2470                                    GLsizei count,
   2471                                    GLboolean transpose,
   2472                                    const GLfloat *v)
   2473 {
   2474    setUniformMatrixGeneric<GLfloat, 2, 3, &rx::ProgramImpl::setUniformMatrix2x3fv>(location, count,
   2475                                                                                    transpose, v);
   2476 }
   2477 
   2478 void Program::setUniformMatrix2x4fv(UniformLocation location,
   2479                                    GLsizei count,
   2480                                    GLboolean transpose,
   2481                                    const GLfloat *v)
   2482 {
   2483    setUniformMatrixGeneric<GLfloat, 2, 4, &rx::ProgramImpl::setUniformMatrix2x4fv>(location, count,
   2484                                                                                    transpose, v);
   2485 }
   2486 
   2487 void Program::setUniformMatrix3x2fv(UniformLocation location,
   2488                                    GLsizei count,
   2489                                    GLboolean transpose,
   2490                                    const GLfloat *v)
   2491 {
   2492    setUniformMatrixGeneric<GLfloat, 3, 2, &rx::ProgramImpl::setUniformMatrix3x2fv>(location, count,
   2493                                                                                    transpose, v);
   2494 }
   2495 
   2496 void Program::setUniformMatrix3x4fv(UniformLocation location,
   2497                                    GLsizei count,
   2498                                    GLboolean transpose,
   2499                                    const GLfloat *v)
   2500 {
   2501    setUniformMatrixGeneric<GLfloat, 3, 4, &rx::ProgramImpl::setUniformMatrix3x4fv>(location, count,
   2502                                                                                    transpose, v);
   2503 }
   2504 
   2505 void Program::setUniformMatrix4x2fv(UniformLocation location,
   2506                                    GLsizei count,
   2507                                    GLboolean transpose,
   2508                                    const GLfloat *v)
   2509 {
   2510    setUniformMatrixGeneric<GLfloat, 4, 2, &rx::ProgramImpl::setUniformMatrix4x2fv>(location, count,
   2511                                                                                    transpose, v);
   2512 }
   2513 
   2514 void Program::setUniformMatrix4x3fv(UniformLocation location,
   2515                                    GLsizei count,
   2516                                    GLboolean transpose,
   2517                                    const GLfloat *v)
   2518 {
   2519    setUniformMatrixGeneric<GLfloat, 4, 3, &rx::ProgramImpl::setUniformMatrix4x3fv>(location, count,
   2520                                                                                    transpose, v);
   2521 }
   2522 
   2523 GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation) const
   2524 {
   2525    ASSERT(!mLinkingState);
   2526    GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(uniformLocation.index);
   2527    const std::vector<GLuint> &boundTextureUnits =
   2528        mState.mExecutable->mSamplerBindings[samplerIndex].boundTextureUnits;
   2529    return (uniformLocation.arrayIndex < boundTextureUnits.size())
   2530               ? boundTextureUnits[uniformLocation.arrayIndex]
   2531               : 0;
   2532 }
   2533 
   2534 GLuint Program::getImageUniformBinding(const VariableLocation &uniformLocation) const
   2535 {
   2536    ASSERT(!mLinkingState);
   2537    GLuint imageIndex = mState.getImageIndexFromUniformIndex(uniformLocation.index);
   2538 
   2539    const std::vector<ImageBinding> &imageBindings = getExecutable().getImageBindings();
   2540    const std::vector<GLuint> &boundImageUnits     = imageBindings[imageIndex].boundImageUnits;
   2541    return boundImageUnits[uniformLocation.arrayIndex];
   2542 }
   2543 
   2544 void Program::getUniformfv(const Context *context, UniformLocation location, GLfloat *v) const
   2545 {
   2546    ASSERT(!mLinkingState);
   2547    const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
   2548    const LinkedUniform &uniform            = mState.getUniforms()[uniformLocation.index];
   2549 
   2550    if (uniform.isSampler())
   2551    {
   2552        *v = static_cast<GLfloat>(getSamplerUniformBinding(uniformLocation));
   2553        return;
   2554    }
   2555    else if (uniform.isImage())
   2556    {
   2557        *v = static_cast<GLfloat>(getImageUniformBinding(uniformLocation));
   2558        return;
   2559    }
   2560 
   2561    const GLenum nativeType = gl::VariableComponentType(uniform.type);
   2562    if (nativeType == GL_FLOAT)
   2563    {
   2564        mProgram->getUniformfv(context, location.value, v);
   2565    }
   2566    else
   2567    {
   2568        getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
   2569    }
   2570 }
   2571 
   2572 void Program::getUniformiv(const Context *context, UniformLocation location, GLint *v) const
   2573 {
   2574    ASSERT(!mLinkingState);
   2575    const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
   2576    const LinkedUniform &uniform            = mState.getUniforms()[uniformLocation.index];
   2577 
   2578    if (uniform.isSampler())
   2579    {
   2580        *v = static_cast<GLint>(getSamplerUniformBinding(uniformLocation));
   2581        return;
   2582    }
   2583    else if (uniform.isImage())
   2584    {
   2585        *v = static_cast<GLint>(getImageUniformBinding(uniformLocation));
   2586        return;
   2587    }
   2588 
   2589    const GLenum nativeType = gl::VariableComponentType(uniform.type);
   2590    if (nativeType == GL_INT || nativeType == GL_BOOL)
   2591    {
   2592        mProgram->getUniformiv(context, location.value, v);
   2593    }
   2594    else
   2595    {
   2596        getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
   2597    }
   2598 }
   2599 
   2600 void Program::getUniformuiv(const Context *context, UniformLocation location, GLuint *v) const
   2601 {
   2602    ASSERT(!mLinkingState);
   2603    const VariableLocation &uniformLocation = mState.getUniformLocations()[location.value];
   2604    const LinkedUniform &uniform            = mState.getUniforms()[uniformLocation.index];
   2605 
   2606    if (uniform.isSampler())
   2607    {
   2608        *v = getSamplerUniformBinding(uniformLocation);
   2609        return;
   2610    }
   2611    else if (uniform.isImage())
   2612    {
   2613        *v = getImageUniformBinding(uniformLocation);
   2614        return;
   2615    }
   2616 
   2617    const GLenum nativeType = VariableComponentType(uniform.type);
   2618    if (nativeType == GL_UNSIGNED_INT)
   2619    {
   2620        mProgram->getUniformuiv(context, location.value, v);
   2621    }
   2622    else
   2623    {
   2624        getUniformInternal(context, v, location, nativeType, VariableComponentCount(uniform.type));
   2625    }
   2626 }
   2627 
   2628 void Program::flagForDeletion()
   2629 {
   2630    ASSERT(!mLinkingState);
   2631    mDeleteStatus = true;
   2632 }
   2633 
   2634 bool Program::isFlaggedForDeletion() const
   2635 {
   2636    ASSERT(!mLinkingState);
   2637    return mDeleteStatus;
   2638 }
   2639 
   2640 void Program::validate(const Caps &caps)
   2641 {
   2642    ASSERT(!mLinkingState);
   2643    mState.mExecutable->resetInfoLog();
   2644    InfoLog &infoLog = mState.mExecutable->getInfoLog();
   2645 
   2646    if (mLinked)
   2647    {
   2648        mValidated = ConvertToBool(mProgram->validate(caps, &infoLog));
   2649    }
   2650    else
   2651    {
   2652        infoLog << "Program has not been successfully linked.";
   2653    }
   2654 }
   2655 
   2656 bool Program::isValidated() const
   2657 {
   2658    ASSERT(!mLinkingState);
   2659    return mValidated;
   2660 }
   2661 
   2662 void Program::getActiveUniformBlockName(const Context *context,
   2663                                        const UniformBlockIndex blockIndex,
   2664                                        GLsizei bufSize,
   2665                                        GLsizei *length,
   2666                                        GLchar *blockName) const
   2667 {
   2668    ASSERT(!mLinkingState);
   2669    GetInterfaceBlockName(blockIndex, mState.mExecutable->getUniformBlocks(), bufSize, length,
   2670                          blockName);
   2671 }
   2672 
   2673 void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
   2674                                              GLsizei bufSize,
   2675                                              GLsizei *length,
   2676                                              GLchar *blockName) const
   2677 {
   2678    ASSERT(!mLinkingState);
   2679    GetInterfaceBlockName({blockIndex}, mState.mExecutable->getShaderStorageBlocks(), bufSize,
   2680                          length, blockName);
   2681 }
   2682 
   2683 template <typename T>
   2684 GLint Program::getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resources) const
   2685 {
   2686    int maxLength = 0;
   2687 
   2688    if (mLinked)
   2689    {
   2690        for (const T &resource : resources)
   2691        {
   2692            if (!resource.name.empty())
   2693            {
   2694                int length = static_cast<int>(resource.nameWithArrayIndex().length());
   2695                maxLength  = std::max(length + 1, maxLength);
   2696            }
   2697        }
   2698    }
   2699 
   2700    return maxLength;
   2701 }
   2702 
   2703 GLint Program::getActiveUniformBlockMaxNameLength() const
   2704 {
   2705    ASSERT(!mLinkingState);
   2706    return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getUniformBlocks());
   2707 }
   2708 
   2709 GLint Program::getActiveShaderStorageBlockMaxNameLength() const
   2710 {
   2711    ASSERT(!mLinkingState);
   2712    return getActiveInterfaceBlockMaxNameLength(mState.mExecutable->getShaderStorageBlocks());
   2713 }
   2714 
   2715 GLuint Program::getUniformBlockIndex(const std::string &name) const
   2716 {
   2717    ASSERT(!mLinkingState);
   2718    return GetInterfaceBlockIndex(mState.mExecutable->getUniformBlocks(), name);
   2719 }
   2720 
   2721 GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
   2722 {
   2723    ASSERT(!mLinkingState);
   2724    return GetInterfaceBlockIndex(mState.mExecutable->getShaderStorageBlocks(), name);
   2725 }
   2726 
   2727 const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
   2728 {
   2729    ASSERT(!mLinkingState);
   2730    ASSERT(index < static_cast<GLuint>(mState.mExecutable->getActiveUniformBlockCount()));
   2731    return mState.mExecutable->getUniformBlocks()[index];
   2732 }
   2733 
   2734 const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
   2735 {
   2736    ASSERT(!mLinkingState);
   2737    ASSERT(index < static_cast<GLuint>(mState.mExecutable->getActiveShaderStorageBlockCount()));
   2738    return mState.mExecutable->getShaderStorageBlocks()[index];
   2739 }
   2740 
   2741 void Program::bindUniformBlock(UniformBlockIndex uniformBlockIndex, GLuint uniformBlockBinding)
   2742 {
   2743    ASSERT(!mLinkingState);
   2744    mState.mExecutable->mUniformBlocks[uniformBlockIndex.value].binding = uniformBlockBinding;
   2745    mState.mExecutable->mActiveUniformBlockBindings.set(uniformBlockIndex.value,
   2746                                                        uniformBlockBinding != 0);
   2747    mDirtyBits.set(DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + uniformBlockIndex.value);
   2748 }
   2749 
   2750 GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
   2751 {
   2752    ASSERT(!mLinkingState);
   2753    return mState.getUniformBlockBinding(uniformBlockIndex);
   2754 }
   2755 
   2756 GLuint Program::getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const
   2757 {
   2758    ASSERT(!mLinkingState);
   2759    return mState.getShaderStorageBlockBinding(shaderStorageBlockIndex);
   2760 }
   2761 
   2762 void Program::setTransformFeedbackVaryings(GLsizei count,
   2763                                           const GLchar *const *varyings,
   2764                                           GLenum bufferMode)
   2765 {
   2766    ASSERT(!mLinkingState);
   2767    mState.mTransformFeedbackVaryingNames.resize(count);
   2768    for (GLsizei i = 0; i < count; i++)
   2769    {
   2770        mState.mTransformFeedbackVaryingNames[i] = varyings[i];
   2771    }
   2772 
   2773    mState.mExecutable->mTransformFeedbackBufferMode = bufferMode;
   2774 }
   2775 
   2776 void Program::getTransformFeedbackVarying(GLuint index,
   2777                                          GLsizei bufSize,
   2778                                          GLsizei *length,
   2779                                          GLsizei *size,
   2780                                          GLenum *type,
   2781                                          GLchar *name) const
   2782 {
   2783    ASSERT(!mLinkingState);
   2784    if (mLinked)
   2785    {
   2786        ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
   2787        const auto &var     = mState.mExecutable->mLinkedTransformFeedbackVaryings[index];
   2788        std::string varName = var.nameWithArrayIndex();
   2789        GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varName.length()));
   2790        if (length)
   2791        {
   2792            *length = lastNameIdx;
   2793        }
   2794        if (size)
   2795        {
   2796            *size = var.size();
   2797        }
   2798        if (type)
   2799        {
   2800            *type = var.type;
   2801        }
   2802        if (name)
   2803        {
   2804            memcpy(name, varName.c_str(), lastNameIdx);
   2805            name[lastNameIdx] = '\0';
   2806        }
   2807    }
   2808 }
   2809 
   2810 GLsizei Program::getTransformFeedbackVaryingCount() const
   2811 {
   2812    ASSERT(!mLinkingState);
   2813    if (mLinked)
   2814    {
   2815        return static_cast<GLsizei>(mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
   2816    }
   2817    else
   2818    {
   2819        return 0;
   2820    }
   2821 }
   2822 
   2823 GLsizei Program::getTransformFeedbackVaryingMaxLength() const
   2824 {
   2825    ASSERT(!mLinkingState);
   2826    if (mLinked)
   2827    {
   2828        GLsizei maxSize = 0;
   2829        for (const auto &var : mState.mExecutable->mLinkedTransformFeedbackVaryings)
   2830        {
   2831            maxSize =
   2832                std::max(maxSize, static_cast<GLsizei>(var.nameWithArrayIndex().length() + 1));
   2833        }
   2834 
   2835        return maxSize;
   2836    }
   2837    else
   2838    {
   2839        return 0;
   2840    }
   2841 }
   2842 
   2843 GLenum Program::getTransformFeedbackBufferMode() const
   2844 {
   2845    ASSERT(!mLinkingState);
   2846    return mState.mExecutable->getTransformFeedbackBufferMode();
   2847 }
   2848 
   2849 bool Program::linkValidateShaders(const Context *context, InfoLog &infoLog)
   2850 {
   2851    const ShaderMap<Shader *> &shaders = mState.mAttachedShaders;
   2852 
   2853    bool isComputeShaderAttached  = shaders[ShaderType::Compute] != nullptr;
   2854    bool isGraphicsShaderAttached = shaders[ShaderType::Vertex] ||
   2855                                    shaders[ShaderType::TessControl] ||
   2856                                    shaders[ShaderType::TessEvaluation] ||
   2857                                    shaders[ShaderType::Geometry] || shaders[ShaderType::Fragment];
   2858    // Check whether we both have a compute and non-compute shaders attached.
   2859    // If there are of both types attached, then linking should fail.
   2860    // OpenGL ES 3.10, 7.3 Program Objects, under LinkProgram
   2861    if (isComputeShaderAttached && isGraphicsShaderAttached)
   2862    {
   2863        infoLog << "Both compute and graphics shaders are attached to the same program.";
   2864        return false;
   2865    }
   2866 
   2867    Optional<int> version;
   2868    for (ShaderType shaderType : kAllGraphicsShaderTypes)
   2869    {
   2870        Shader *shader = shaders[shaderType];
   2871        ASSERT(!shader || shader->getType() == shaderType);
   2872        if (!shader)
   2873        {
   2874            continue;
   2875        }
   2876 
   2877        if (!shader->isCompiled(context))
   2878        {
   2879            infoLog << ShaderTypeToString(shaderType) << " shader is not compiled.";
   2880            return false;
   2881        }
   2882 
   2883        if (!version.valid())
   2884        {
   2885            version = shader->getShaderVersion(context);
   2886        }
   2887        else if (version != shader->getShaderVersion(context))
   2888        {
   2889            infoLog << ShaderTypeToString(shaderType)
   2890                    << " shader version does not match other shader versions.";
   2891            return false;
   2892        }
   2893    }
   2894 
   2895    if (isComputeShaderAttached)
   2896    {
   2897        ASSERT(shaders[ShaderType::Compute]->getType() == ShaderType::Compute);
   2898 
   2899        mState.mComputeShaderLocalSize = shaders[ShaderType::Compute]->getWorkGroupSize(context);
   2900 
   2901        // GLSL ES 3.10, 4.4.1.1 Compute Shader Inputs
   2902        // If the work group size is not specified, a link time error should occur.
   2903        if (!mState.mComputeShaderLocalSize.isDeclared())
   2904        {
   2905            infoLog << "Work group size is not specified.";
   2906            return false;
   2907        }
   2908    }
   2909    else
   2910    {
   2911        if (!isGraphicsShaderAttached)
   2912        {
   2913            infoLog << "No compiled shaders.";
   2914            return false;
   2915        }
   2916 
   2917        bool hasVertex   = shaders[ShaderType::Vertex] != nullptr;
   2918        bool hasFragment = shaders[ShaderType::Fragment] != nullptr;
   2919        if (!isSeparable() && (!hasVertex || !hasFragment))
   2920        {
   2921            infoLog
   2922                << "The program must contain objects to form both a vertex and fragment shader.";
   2923            return false;
   2924        }
   2925 
   2926        bool hasTessControl    = shaders[ShaderType::TessControl] != nullptr;
   2927        bool hasTessEvaluation = shaders[ShaderType::TessEvaluation] != nullptr;
   2928        if (!isSeparable() && (hasTessControl != hasTessEvaluation))
   2929        {
   2930            infoLog << "Tessellation control and evaluation shaders must be specified together.";
   2931            return false;
   2932        }
   2933 
   2934        Shader *geometryShader = shaders[ShaderType::Geometry];
   2935        if (shaders[ShaderType::Geometry])
   2936        {
   2937            // [GL_EXT_geometry_shader] Chapter 7
   2938            // Linking can fail for a variety of reasons as specified in the OpenGL ES Shading
   2939            // Language Specification, as well as any of the following reasons:
   2940            // * One or more of the shader objects attached to <program> are not compiled
   2941            //   successfully.
   2942            // * The shaders do not use the same shader language version.
   2943            // * <program> contains objects to form a geometry shader, and
   2944            //   - <program> is not separable and contains no objects to form a vertex shader; or
   2945            //   - the input primitive type, output primitive type, or maximum output vertex count
   2946            //     is not specified in the compiled geometry shader object.
   2947            ASSERT(geometryShader->getType() == ShaderType::Geometry);
   2948 
   2949            Optional<PrimitiveMode> inputPrimitive =
   2950                geometryShader->getGeometryShaderInputPrimitiveType(context);
   2951            if (!inputPrimitive.valid())
   2952            {
   2953                infoLog << "Input primitive type is not specified in the geometry shader.";
   2954                return false;
   2955            }
   2956 
   2957            Optional<PrimitiveMode> outputPrimitive =
   2958                geometryShader->getGeometryShaderOutputPrimitiveType(context);
   2959            if (!outputPrimitive.valid())
   2960            {
   2961                infoLog << "Output primitive type is not specified in the geometry shader.";
   2962                return false;
   2963            }
   2964 
   2965            Optional<GLint> maxVertices = geometryShader->getGeometryShaderMaxVertices(context);
   2966            if (!maxVertices.valid())
   2967            {
   2968                infoLog << "'max_vertices' is not specified in the geometry shader.";
   2969                return false;
   2970            }
   2971 
   2972            mState.mExecutable->mGeometryShaderInputPrimitiveType  = inputPrimitive.value();
   2973            mState.mExecutable->mGeometryShaderOutputPrimitiveType = outputPrimitive.value();
   2974            mState.mExecutable->mGeometryShaderMaxVertices         = maxVertices.value();
   2975            mState.mExecutable->mGeometryShaderInvocations =
   2976                geometryShader->getGeometryShaderInvocations(context);
   2977        }
   2978 
   2979        Shader *tessControlShader = shaders[ShaderType::TessControl];
   2980        if (tessControlShader)
   2981        {
   2982            int tcsShaderVertices = tessControlShader->getTessControlShaderVertices(context);
   2983            if (tcsShaderVertices == 0)
   2984            {
   2985                // In tessellation control shader, output vertices should be specified at least
   2986                // once.
   2987                // > GLSL ES Version 3.20.6 spec:
   2988                // > 4.4.2. Output Layout Qualifiers
   2989                // > Tessellation Control Outputs
   2990                // > ...
   2991                // > There must be at least one layout qualifier specifying an output patch vertex
   2992                // > count in any program containing a tessellation control shader.
   2993                infoLog << "In Tessellation Control Shader, at least one layout qualifier "
   2994                           "specifying an output patch vertex count must exist.";
   2995                return false;
   2996            }
   2997 
   2998            mState.mExecutable->mTessControlShaderVertices = tcsShaderVertices;
   2999        }
   3000 
   3001        Shader *tessEvaluationShader = shaders[ShaderType::TessEvaluation];
   3002        if (tessEvaluationShader)
   3003        {
   3004            GLenum tesPrimitiveMode = tessEvaluationShader->getTessGenMode(context);
   3005            if (tesPrimitiveMode == 0)
   3006            {
   3007                // In tessellation evaluation shader, a primitive mode should be specified at least
   3008                // once.
   3009                // > GLSL ES Version 3.20.6 spec:
   3010                // > 4.4.1. Input Layout Qualifiers
   3011                // > Tessellation Evaluation Inputs
   3012                // > ...
   3013                // > The tessellation evaluation shader object in a program must declare a primitive
   3014                // > mode in its input layout. Declaring vertex spacing, ordering, or point mode
   3015                // > identifiers is optional.
   3016                infoLog << "The Tessellation Evaluation Shader object in a program must declare a "
   3017                           "primitive mode in its input layout.";
   3018                return false;
   3019            }
   3020 
   3021            mState.mExecutable->mTessGenMode    = tesPrimitiveMode;
   3022            mState.mExecutable->mTessGenSpacing = tessEvaluationShader->getTessGenSpacing(context);
   3023            mState.mExecutable->mTessGenVertexOrder =
   3024                tessEvaluationShader->getTessGenVertexOrder(context);
   3025            mState.mExecutable->mTessGenPointMode =
   3026                tessEvaluationShader->getTessGenPointMode(context);
   3027        }
   3028    }
   3029 
   3030    return true;
   3031 }
   3032 
   3033 GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const
   3034 {
   3035    ASSERT(!mLinkingState);
   3036    for (GLuint tfIndex = 0; tfIndex < mState.mExecutable->mLinkedTransformFeedbackVaryings.size();
   3037         ++tfIndex)
   3038    {
   3039        const auto &tf = mState.mExecutable->mLinkedTransformFeedbackVaryings[tfIndex];
   3040        if (tf.nameWithArrayIndex() == name)
   3041        {
   3042            return tfIndex;
   3043        }
   3044    }
   3045    return GL_INVALID_INDEX;
   3046 }
   3047 
   3048 const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const
   3049 {
   3050    ASSERT(!mLinkingState);
   3051    ASSERT(index < mState.mExecutable->mLinkedTransformFeedbackVaryings.size());
   3052    return mState.mExecutable->mLinkedTransformFeedbackVaryings[index];
   3053 }
   3054 
   3055 bool Program::hasDrawIDUniform() const
   3056 {
   3057    ASSERT(!mLinkingState);
   3058    return mState.mDrawIDLocation >= 0;
   3059 }
   3060 
   3061 void Program::setDrawIDUniform(GLint drawid)
   3062 {
   3063    ASSERT(!mLinkingState);
   3064    ASSERT(mState.mDrawIDLocation >= 0);
   3065    mProgram->setUniform1iv(mState.mDrawIDLocation, 1, &drawid);
   3066 }
   3067 
   3068 bool Program::hasBaseVertexUniform() const
   3069 {
   3070    ASSERT(!mLinkingState);
   3071    return mState.mBaseVertexLocation >= 0;
   3072 }
   3073 
   3074 void Program::setBaseVertexUniform(GLint baseVertex)
   3075 {
   3076    ASSERT(!mLinkingState);
   3077    ASSERT(mState.mBaseVertexLocation >= 0);
   3078    if (baseVertex == mState.mCachedBaseVertex)
   3079    {
   3080        return;
   3081    }
   3082    mState.mCachedBaseVertex = baseVertex;
   3083    mProgram->setUniform1iv(mState.mBaseVertexLocation, 1, &baseVertex);
   3084 }
   3085 
   3086 bool Program::hasBaseInstanceUniform() const
   3087 {
   3088    ASSERT(!mLinkingState);
   3089    return mState.mBaseInstanceLocation >= 0;
   3090 }
   3091 
   3092 void Program::setBaseInstanceUniform(GLuint baseInstance)
   3093 {
   3094    ASSERT(!mLinkingState);
   3095    ASSERT(mState.mBaseInstanceLocation >= 0);
   3096    if (baseInstance == mState.mCachedBaseInstance)
   3097    {
   3098        return;
   3099    }
   3100    mState.mCachedBaseInstance = baseInstance;
   3101    GLint baseInstanceInt      = baseInstance;
   3102    mProgram->setUniform1iv(mState.mBaseInstanceLocation, 1, &baseInstanceInt);
   3103 }
   3104 
   3105 bool Program::linkVaryings(const Context *context, InfoLog &infoLog) const
   3106 {
   3107    ShaderType previousShaderType = ShaderType::InvalidEnum;
   3108    for (ShaderType shaderType : kAllGraphicsShaderTypes)
   3109    {
   3110        Shader *currentShader = mState.mAttachedShaders[shaderType];
   3111        if (!currentShader)
   3112        {
   3113            continue;
   3114        }
   3115 
   3116        if (previousShaderType != ShaderType::InvalidEnum)
   3117        {
   3118            Shader *previousShader = mState.mAttachedShaders[previousShaderType];
   3119            const std::vector<sh::ShaderVariable> &outputVaryings =
   3120                previousShader->getOutputVaryings(context);
   3121 
   3122            if (!LinkValidateShaderInterfaceMatching(
   3123                    outputVaryings, currentShader->getInputVaryings(context), previousShaderType,
   3124                    currentShader->getType(), previousShader->getShaderVersion(context),
   3125                    currentShader->getShaderVersion(context), isSeparable(), infoLog))
   3126            {
   3127                return false;
   3128            }
   3129        }
   3130        previousShaderType = currentShader->getType();
   3131    }
   3132 
   3133    // TODO: http://anglebug.com/3571 and http://anglebug.com/3572
   3134    // Need to move logic of validating builtin varyings inside the for-loop above.
   3135    // This is because the built-in symbols `gl_ClipDistance` and `gl_CullDistance`
   3136    // can be redeclared in Geometry or Tessellation shaders as well.
   3137    Shader *vertexShader   = mState.mAttachedShaders[ShaderType::Vertex];
   3138    Shader *fragmentShader = mState.mAttachedShaders[ShaderType::Fragment];
   3139    if (vertexShader && fragmentShader &&
   3140        !LinkValidateBuiltInVaryings(vertexShader->getOutputVaryings(context),
   3141                                     fragmentShader->getInputVaryings(context),
   3142                                     vertexShader->getType(), fragmentShader->getType(),
   3143                                     vertexShader->getShaderVersion(context),
   3144                                     fragmentShader->getShaderVersion(context), infoLog))
   3145    {
   3146        return false;
   3147    }
   3148 
   3149    return true;
   3150 }
   3151 
   3152 bool Program::linkUniforms(const Context *context,
   3153                           std::vector<UnusedUniform> *unusedUniformsOutOrNull,
   3154                           GLuint *combinedImageUniformsOut,
   3155                           InfoLog &infoLog)
   3156 {
   3157    // Initialize executable shader map.
   3158    ShaderMap<std::vector<sh::ShaderVariable>> shaderUniforms;
   3159    for (Shader *shader : mState.mAttachedShaders)
   3160    {
   3161        if (shader)
   3162        {
   3163            shaderUniforms[shader->getType()] = shader->getUniforms(context);
   3164        }
   3165    }
   3166 
   3167    if (!mState.mExecutable->linkUniforms(context, shaderUniforms, infoLog,
   3168                                          mState.mUniformLocationBindings, combinedImageUniformsOut,
   3169                                          unusedUniformsOutOrNull, &mState.mUniformLocations))
   3170    {
   3171        return false;
   3172    }
   3173 
   3174    if (context->getClientVersion() >= Version(3, 1))
   3175    {
   3176        GLint locationSize = static_cast<GLint>(mState.getUniformLocations().size());
   3177 
   3178        if (locationSize > context->getCaps().maxUniformLocations)
   3179        {
   3180            infoLog << "Exceeded maximum uniform location size";
   3181            return false;
   3182        }
   3183    }
   3184 
   3185    return true;
   3186 }
   3187 
   3188 // Assigns locations to all attributes (except built-ins) from the bindings and program locations.
   3189 bool Program::linkAttributes(const Context *context, InfoLog &infoLog)
   3190 {
   3191    const Caps &caps               = context->getCaps();
   3192    const Limitations &limitations = context->getLimitations();
   3193    bool webglCompatibility        = context->isWebGL();
   3194    int shaderVersion              = -1;
   3195    unsigned int usedLocations     = 0;
   3196 
   3197    Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
   3198 
   3199    if (!vertexShader)
   3200    {
   3201        // No vertex shader, so no attributes, so nothing to do
   3202        return true;
   3203    }
   3204 
   3205    shaderVersion = vertexShader->getShaderVersion(context);
   3206    if (shaderVersion >= 300)
   3207    {
   3208        // In GLSL ES 3.00.6, aliasing checks should be done with all declared attributes -
   3209        // see GLSL ES 3.00.6 section 12.46. Inactive attributes will be pruned after
   3210        // aliasing checks.
   3211        mState.mExecutable->mProgramInputs = vertexShader->getAllAttributes(context);
   3212    }
   3213    else
   3214    {
   3215        // In GLSL ES 1.00.17 we only do aliasing checks for active attributes.
   3216        mState.mExecutable->mProgramInputs = vertexShader->getActiveAttributes(context);
   3217    }
   3218 
   3219    GLuint maxAttribs = static_cast<GLuint>(caps.maxVertexAttributes);
   3220    std::vector<sh::ShaderVariable *> usedAttribMap(maxAttribs, nullptr);
   3221 
   3222    // Assign locations to attributes that have a binding location and check for attribute aliasing.
   3223    for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
   3224    {
   3225        // GLSL ES 3.10 January 2016 section 4.3.4: Vertex shader inputs can't be arrays or
   3226        // structures, so we don't need to worry about adjusting their names or generating entries
   3227        // for each member/element (unlike uniforms for example).
   3228        ASSERT(!attribute.isArray() && !attribute.isStruct());
   3229 
   3230        int bindingLocation = mAttributeBindings.getBinding(attribute);
   3231        if (attribute.location == -1 && bindingLocation != -1)
   3232        {
   3233            attribute.location = bindingLocation;
   3234        }
   3235 
   3236        if (attribute.location != -1)
   3237        {
   3238            // Location is set by glBindAttribLocation or by location layout qualifier
   3239            const int regs = VariableRegisterCount(attribute.type);
   3240 
   3241            if (static_cast<GLuint>(regs + attribute.location) > maxAttribs)
   3242            {
   3243                infoLog << "Attribute (" << attribute.name << ") at location " << attribute.location
   3244                        << " is too big to fit";
   3245 
   3246                return false;
   3247            }
   3248 
   3249            for (int reg = 0; reg < regs; reg++)
   3250            {
   3251                const int regLocation               = attribute.location + reg;
   3252                sh::ShaderVariable *linkedAttribute = usedAttribMap[regLocation];
   3253 
   3254                // In GLSL ES 3.00.6 and in WebGL, attribute aliasing produces a link error.
   3255                // In non-WebGL GLSL ES 1.00.17, attribute aliasing is allowed with some
   3256                // restrictions - see GLSL ES 1.00.17 section 2.10.4, but ANGLE currently has a bug.
   3257                // In D3D 9 and 11, aliasing is not supported, so check a limitation.
   3258                if (linkedAttribute)
   3259                {
   3260                    if (shaderVersion >= 300 || webglCompatibility ||
   3261                        limitations.noVertexAttributeAliasing)
   3262                    {
   3263                        infoLog << "Attribute '" << attribute.name << "' aliases attribute '"
   3264                                << linkedAttribute->name << "' at location " << regLocation;
   3265                        return false;
   3266                    }
   3267                }
   3268                else
   3269                {
   3270                    usedAttribMap[regLocation] = &attribute;
   3271                }
   3272 
   3273                usedLocations |= 1 << regLocation;
   3274            }
   3275        }
   3276    }
   3277 
   3278    // Assign locations to attributes that don't have a binding location.
   3279    for (sh::ShaderVariable &attribute : mState.mExecutable->mProgramInputs)
   3280    {
   3281        // Not set by glBindAttribLocation or by location layout qualifier
   3282        if (attribute.location == -1)
   3283        {
   3284            int regs           = VariableRegisterCount(attribute.type);
   3285            int availableIndex = AllocateFirstFreeBits(&usedLocations, regs, maxAttribs);
   3286 
   3287            if (availableIndex == -1 || static_cast<GLuint>(availableIndex + regs) > maxAttribs)
   3288            {
   3289                infoLog << "Too many attributes (" << attribute.name << ")";
   3290                return false;
   3291            }
   3292 
   3293            attribute.location = availableIndex;
   3294        }
   3295    }
   3296 
   3297    ASSERT(mState.mExecutable->mAttributesTypeMask.none());
   3298    ASSERT(mState.mExecutable->mAttributesMask.none());
   3299 
   3300    // Prune inactive attributes. This step is only needed on shaderVersion >= 300 since on earlier
   3301    // shader versions we're only processing active attributes to begin with.
   3302    if (shaderVersion >= 300)
   3303    {
   3304        for (auto attributeIter = mState.mExecutable->getProgramInputs().begin();
   3305             attributeIter != mState.mExecutable->getProgramInputs().end();)
   3306        {
   3307            if (attributeIter->active)
   3308            {
   3309                ++attributeIter;
   3310            }
   3311            else
   3312            {
   3313                attributeIter = mState.mExecutable->mProgramInputs.erase(attributeIter);
   3314            }
   3315        }
   3316    }
   3317 
   3318    for (const sh::ShaderVariable &attribute : mState.mExecutable->getProgramInputs())
   3319    {
   3320        ASSERT(attribute.active);
   3321        ASSERT(attribute.location != -1);
   3322        unsigned int regs = static_cast<unsigned int>(VariableRegisterCount(attribute.type));
   3323 
   3324        unsigned int location = static_cast<unsigned int>(attribute.location);
   3325        for (unsigned int r = 0; r < regs; r++)
   3326        {
   3327            // Built-in active program inputs don't have a bound attribute.
   3328            if (!attribute.isBuiltIn())
   3329            {
   3330                mState.mExecutable->mActiveAttribLocationsMask.set(location);
   3331                mState.mExecutable->mMaxActiveAttribLocation =
   3332                    std::max(mState.mExecutable->mMaxActiveAttribLocation, location + 1);
   3333 
   3334                ComponentType componentType =
   3335                    GLenumToComponentType(VariableComponentType(attribute.type));
   3336 
   3337                SetComponentTypeMask(componentType, location,
   3338                                     &mState.mExecutable->mAttributesTypeMask);
   3339                mState.mExecutable->mAttributesMask.set(location);
   3340 
   3341                location++;
   3342            }
   3343        }
   3344    }
   3345 
   3346    return true;
   3347 }
   3348 
   3349 void Program::setUniformValuesFromBindingQualifiers()
   3350 {
   3351    for (unsigned int samplerIndex : mState.mExecutable->getSamplerUniformRange())
   3352    {
   3353        const auto &samplerUniform = mState.mExecutable->getUniforms()[samplerIndex];
   3354        if (samplerUniform.binding != -1)
   3355        {
   3356            UniformLocation location = getUniformLocation(samplerUniform.name);
   3357            ASSERT(location.value != -1);
   3358            std::vector<GLint> boundTextureUnits;
   3359            for (unsigned int elementIndex = 0;
   3360                 elementIndex < samplerUniform.getBasicTypeElementCount(); ++elementIndex)
   3361            {
   3362                boundTextureUnits.push_back(samplerUniform.binding + elementIndex);
   3363            }
   3364 
   3365            // Here we pass nullptr to avoid a large chain of calls that need a non-const Context.
   3366            // We know it's safe not to notify the Context because this is only called after link.
   3367            setUniform1iv(nullptr, location, static_cast<GLsizei>(boundTextureUnits.size()),
   3368                          boundTextureUnits.data());
   3369        }
   3370    }
   3371 }
   3372 
   3373 void Program::initInterfaceBlockBindings()
   3374 {
   3375    // Set initial bindings from shader.
   3376    for (unsigned int blockIndex = 0; blockIndex < mState.mExecutable->getActiveUniformBlockCount();
   3377         blockIndex++)
   3378    {
   3379        InterfaceBlock &uniformBlock = mState.mExecutable->mUniformBlocks[blockIndex];
   3380        bindUniformBlock({blockIndex}, uniformBlock.binding);
   3381    }
   3382 }
   3383 
   3384 void Program::updateSamplerUniform(Context *context,
   3385                                   const VariableLocation &locationInfo,
   3386                                   GLsizei clampedCount,
   3387                                   const GLint *v)
   3388 {
   3389    ASSERT(mState.isSamplerUniformIndex(locationInfo.index));
   3390    GLuint samplerIndex            = mState.getSamplerIndexFromUniformIndex(locationInfo.index);
   3391    SamplerBinding &samplerBinding = mState.mExecutable->mSamplerBindings[samplerIndex];
   3392    std::vector<GLuint> &boundTextureUnits = samplerBinding.boundTextureUnits;
   3393 
   3394    if (locationInfo.arrayIndex >= boundTextureUnits.size())
   3395    {
   3396        return;
   3397    }
   3398    GLsizei safeUniformCount = std::min(
   3399        clampedCount, static_cast<GLsizei>(boundTextureUnits.size() - locationInfo.arrayIndex));
   3400 
   3401    // Update the sampler uniforms.
   3402    for (GLsizei arrayIndex = 0; arrayIndex < safeUniformCount; ++arrayIndex)
   3403    {
   3404        GLint oldTextureUnit = boundTextureUnits[arrayIndex + locationInfo.arrayIndex];
   3405        GLint newTextureUnit = v[arrayIndex];
   3406 
   3407        if (oldTextureUnit == newTextureUnit)
   3408        {
   3409            continue;
   3410        }
   3411 
   3412        // Update sampler's bound textureUnit
   3413        boundTextureUnits[arrayIndex + locationInfo.arrayIndex] = newTextureUnit;
   3414 
   3415        // Update the reference counts.
   3416        uint32_t &oldRefCount = mState.mExecutable->mActiveSamplerRefCounts[oldTextureUnit];
   3417        uint32_t &newRefCount = mState.mExecutable->mActiveSamplerRefCounts[newTextureUnit];
   3418        ASSERT(oldRefCount > 0);
   3419        ASSERT(newRefCount < std::numeric_limits<uint32_t>::max());
   3420        oldRefCount--;
   3421        newRefCount++;
   3422 
   3423        // Check for binding type change.
   3424        TextureType newSamplerType     = mState.mExecutable->mActiveSamplerTypes[newTextureUnit];
   3425        TextureType oldSamplerType     = mState.mExecutable->mActiveSamplerTypes[oldTextureUnit];
   3426        SamplerFormat newSamplerFormat = mState.mExecutable->mActiveSamplerFormats[newTextureUnit];
   3427        SamplerFormat oldSamplerFormat = mState.mExecutable->mActiveSamplerFormats[oldTextureUnit];
   3428        bool newSamplerYUV             = mState.mExecutable->mActiveSamplerYUV.test(newTextureUnit);
   3429 
   3430        if (newRefCount == 1)
   3431        {
   3432            mState.mExecutable->setActive(newTextureUnit, samplerBinding,
   3433                                          mState.mExecutable->getUniforms()[locationInfo.index]);
   3434        }
   3435        else
   3436        {
   3437            if (newSamplerType != samplerBinding.textureType ||
   3438                newSamplerYUV != IsSamplerYUVType(samplerBinding.samplerType))
   3439            {
   3440                mState.mExecutable->hasSamplerTypeConflict(newTextureUnit);
   3441            }
   3442 
   3443            if (newSamplerFormat != samplerBinding.format)
   3444            {
   3445                mState.mExecutable->hasSamplerFormatConflict(newTextureUnit);
   3446            }
   3447        }
   3448 
   3449        // Unset previously active sampler.
   3450        if (oldRefCount == 0)
   3451        {
   3452            mState.mExecutable->setInactive(oldTextureUnit);
   3453        }
   3454        else
   3455        {
   3456            if (oldSamplerType == TextureType::InvalidEnum ||
   3457                oldSamplerFormat == SamplerFormat::InvalidEnum)
   3458            {
   3459                // Previous conflict. Check if this new change fixed the conflict.
   3460                mState.setSamplerUniformTextureTypeAndFormat(oldTextureUnit);
   3461            }
   3462        }
   3463 
   3464        // Update the observing PPO's executable, if any.
   3465        // Do this before any of the Context work, since that uses the current ProgramExecutable,
   3466        // which will be the PPO's if this Program is bound to it, rather than this Program's.
   3467        if (isSeparable())
   3468        {
   3469            onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
   3470        }
   3471 
   3472        // Notify context.
   3473        if (context)
   3474        {
   3475            context->onSamplerUniformChange(newTextureUnit);
   3476            context->onSamplerUniformChange(oldTextureUnit);
   3477        }
   3478    }
   3479 
   3480    // Invalidate the validation cache.
   3481    getExecutable().resetCachedValidateSamplersResult();
   3482    // Inform any PPOs this Program may be bound to.
   3483    onStateChange(angle::SubjectMessage::SamplerUniformsUpdated);
   3484 }
   3485 
   3486 void ProgramState::setSamplerUniformTextureTypeAndFormat(size_t textureUnitIndex)
   3487 {
   3488    mExecutable->setSamplerUniformTextureTypeAndFormat(textureUnitIndex,
   3489                                                       mExecutable->mSamplerBindings);
   3490 }
   3491 
   3492 template <typename T>
   3493 GLsizei Program::clampUniformCount(const VariableLocation &locationInfo,
   3494                                   GLsizei count,
   3495                                   int vectorSize,
   3496                                   const T *v)
   3497 {
   3498    if (count == 1)
   3499        return 1;
   3500 
   3501    const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index];
   3502 
   3503    // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
   3504    // element index used, as reported by GetActiveUniform, will be ignored by the GL."
   3505    unsigned int remainingElements =
   3506        linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
   3507    GLsizei maxElementCount =
   3508        static_cast<GLsizei>(remainingElements * linkedUniform.getElementComponents());
   3509 
   3510    if (count * vectorSize > maxElementCount)
   3511    {
   3512        return maxElementCount / vectorSize;
   3513    }
   3514 
   3515    return count;
   3516 }
   3517 
   3518 template <size_t cols, size_t rows, typename T>
   3519 GLsizei Program::clampMatrixUniformCount(UniformLocation location,
   3520                                         GLsizei count,
   3521                                         GLboolean transpose,
   3522                                         const T *v)
   3523 {
   3524    const VariableLocation &locationInfo = mState.mUniformLocations[location.value];
   3525 
   3526    if (!transpose)
   3527    {
   3528        return clampUniformCount(locationInfo, count, cols * rows, v);
   3529    }
   3530 
   3531    const LinkedUniform &linkedUniform = mState.mExecutable->getUniforms()[locationInfo.index];
   3532 
   3533    // OpenGL ES 3.0.4 spec pg 67: "Values for any array element that exceeds the highest array
   3534    // element index used, as reported by GetActiveUniform, will be ignored by the GL."
   3535    unsigned int remainingElements =
   3536        linkedUniform.getBasicTypeElementCount() - locationInfo.arrayIndex;
   3537    return std::min(count, static_cast<GLsizei>(remainingElements));
   3538 }
   3539 
   3540 // Driver differences mean that doing the uniform value cast ourselves gives consistent results.
   3541 // EG: on NVIDIA drivers, it was observed that getUniformi for MAX_INT+1 returned MIN_INT.
   3542 template <typename DestT>
   3543 void Program::getUniformInternal(const Context *context,
   3544                                 DestT *dataOut,
   3545                                 UniformLocation location,
   3546                                 GLenum nativeType,
   3547                                 int components) const
   3548 {
   3549    switch (nativeType)
   3550    {
   3551        case GL_BOOL:
   3552        {
   3553            GLint tempValue[16] = {0};
   3554            mProgram->getUniformiv(context, location.value, tempValue);
   3555            UniformStateQueryCastLoop<GLboolean>(
   3556                dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
   3557            break;
   3558        }
   3559        case GL_INT:
   3560        {
   3561            GLint tempValue[16] = {0};
   3562            mProgram->getUniformiv(context, location.value, tempValue);
   3563            UniformStateQueryCastLoop<GLint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
   3564                                             components);
   3565            break;
   3566        }
   3567        case GL_UNSIGNED_INT:
   3568        {
   3569            GLuint tempValue[16] = {0};
   3570            mProgram->getUniformuiv(context, location.value, tempValue);
   3571            UniformStateQueryCastLoop<GLuint>(dataOut, reinterpret_cast<const uint8_t *>(tempValue),
   3572                                              components);
   3573            break;
   3574        }
   3575        case GL_FLOAT:
   3576        {
   3577            GLfloat tempValue[16] = {0};
   3578            mProgram->getUniformfv(context, location.value, tempValue);
   3579            UniformStateQueryCastLoop<GLfloat>(
   3580                dataOut, reinterpret_cast<const uint8_t *>(tempValue), components);
   3581            break;
   3582        }
   3583        default:
   3584            UNREACHABLE();
   3585            break;
   3586    }
   3587 }
   3588 
   3589 angle::Result Program::syncState(const Context *context)
   3590 {
   3591    if (mDirtyBits.any())
   3592    {
   3593        ASSERT(!mLinkingState);
   3594        ANGLE_TRY(mProgram->syncState(context, mDirtyBits));
   3595        mDirtyBits.reset();
   3596    }
   3597 
   3598    return angle::Result::Continue;
   3599 }
   3600 
   3601 angle::Result Program::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const
   3602 {
   3603    BinaryOutputStream stream;
   3604 
   3605    stream.writeBytes(reinterpret_cast<const unsigned char *>(angle::GetANGLECommitHash()),
   3606                      angle::GetANGLECommitHashSize());
   3607 
   3608    // nullptr context is supported when computing binary length.
   3609    if (context)
   3610    {
   3611        stream.writeInt(context->getClientVersion().major);
   3612        stream.writeInt(context->getClientVersion().minor);
   3613    }
   3614    else
   3615    {
   3616        stream.writeInt(2);
   3617        stream.writeInt(0);
   3618    }
   3619 
   3620    // Must be before mExecutable->save(), since it uses the value.
   3621    stream.writeBool(mState.mSeparable);
   3622 
   3623    mState.mExecutable->save(mState.mSeparable, &stream);
   3624 
   3625    const auto &computeLocalSize = mState.getComputeShaderLocalSize();
   3626 
   3627    stream.writeInt(computeLocalSize[0]);
   3628    stream.writeInt(computeLocalSize[1]);
   3629    stream.writeInt(computeLocalSize[2]);
   3630 
   3631    stream.writeInt(mState.mNumViews);
   3632    stream.writeInt(mState.mSpecConstUsageBits.bits());
   3633 
   3634    stream.writeInt(mState.getUniformLocations().size());
   3635    for (const auto &variable : mState.getUniformLocations())
   3636    {
   3637        stream.writeInt(variable.arrayIndex);
   3638        stream.writeIntOrNegOne(variable.index);
   3639        stream.writeBool(variable.ignored);
   3640    }
   3641 
   3642    stream.writeInt(mState.getBufferVariables().size());
   3643    for (const BufferVariable &bufferVariable : mState.getBufferVariables())
   3644    {
   3645        WriteBufferVariable(&stream, bufferVariable);
   3646    }
   3647 
   3648    // Warn the app layer if saving a binary with unsupported transform feedback.
   3649    if (!mState.getLinkedTransformFeedbackVaryings().empty() &&
   3650        context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled)
   3651    {
   3652        ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
   3653                           "Saving program binary with transform feedback, which is not supported "
   3654                           "on this driver.");
   3655    }
   3656 
   3657    if (context->getShareGroup()->getFrameCaptureShared()->enabled())
   3658    {
   3659        // Serialize the source for each stage for re-use during capture
   3660        for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
   3661        {
   3662            gl::Shader *shader = getAttachedShader(shaderType);
   3663            if (shader)
   3664            {
   3665                stream.writeString(shader->getSourceString());
   3666            }
   3667            else
   3668            {
   3669                // If we don't have an attached shader, which would occur if this program was
   3670                // created via glProgramBinary, pull from our cached copy
   3671                const angle::ProgramSources &cachedLinkedSources =
   3672                    context->getShareGroup()->getFrameCaptureShared()->getProgramSources(id());
   3673                const std::string &cachedSourceString = cachedLinkedSources[shaderType];
   3674                ASSERT(!cachedSourceString.empty());
   3675                stream.writeString(cachedSourceString.c_str());
   3676            }
   3677        }
   3678    }
   3679 
   3680    mProgram->save(context, &stream);
   3681 
   3682    ASSERT(binaryOut);
   3683    if (!binaryOut->resize(stream.length()))
   3684    {
   3685        std::stringstream sstream;
   3686        sstream << "Failed to allocate enough memory to serialize a program. (" << stream.length()
   3687                << " bytes )";
   3688        ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
   3689                           sstream.str().c_str());
   3690        return angle::Result::Incomplete;
   3691    }
   3692    memcpy(binaryOut->data(), stream.data(), stream.length());
   3693    return angle::Result::Continue;
   3694 }
   3695 
   3696 angle::Result Program::deserialize(const Context *context,
   3697                                   BinaryInputStream &stream,
   3698                                   InfoLog &infoLog)
   3699 {
   3700    std::vector<uint8_t> commitString(angle::GetANGLECommitHashSize(), 0);
   3701    stream.readBytes(commitString.data(), commitString.size());
   3702    if (memcmp(commitString.data(), angle::GetANGLECommitHash(), commitString.size()) != 0)
   3703    {
   3704        infoLog << "Invalid program binary version.";
   3705        return angle::Result::Stop;
   3706    }
   3707 
   3708    int majorVersion = stream.readInt<int>();
   3709    int minorVersion = stream.readInt<int>();
   3710    if (majorVersion != context->getClientMajorVersion() ||
   3711        minorVersion != context->getClientMinorVersion())
   3712    {
   3713        infoLog << "Cannot load program binaries across different ES context versions.";
   3714        return angle::Result::Stop;
   3715    }
   3716 
   3717    // Must be before mExecutable->load(), since it uses the value.
   3718    mState.mSeparable = stream.readBool();
   3719 
   3720    mState.mExecutable->load(mState.mSeparable, &stream);
   3721 
   3722    mState.mComputeShaderLocalSize[0] = stream.readInt<int>();
   3723    mState.mComputeShaderLocalSize[1] = stream.readInt<int>();
   3724    mState.mComputeShaderLocalSize[2] = stream.readInt<int>();
   3725 
   3726    mState.mNumViews = stream.readInt<int>();
   3727 
   3728    static_assert(sizeof(mState.mSpecConstUsageBits.bits()) == sizeof(uint32_t));
   3729    mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>());
   3730 
   3731    const size_t uniformIndexCount = stream.readInt<size_t>();
   3732    ASSERT(mState.mUniformLocations.empty());
   3733    for (size_t uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; ++uniformIndexIndex)
   3734    {
   3735        VariableLocation variable;
   3736        stream.readInt(&variable.arrayIndex);
   3737        stream.readInt(&variable.index);
   3738        stream.readBool(&variable.ignored);
   3739 
   3740        mState.mUniformLocations.push_back(variable);
   3741    }
   3742 
   3743    size_t bufferVariableCount = stream.readInt<size_t>();
   3744    ASSERT(mState.mBufferVariables.empty());
   3745    for (size_t bufferVarIndex = 0; bufferVarIndex < bufferVariableCount; ++bufferVarIndex)
   3746    {
   3747        BufferVariable bufferVariable;
   3748        LoadBufferVariable(&stream, &bufferVariable);
   3749        mState.mBufferVariables.push_back(bufferVariable);
   3750    }
   3751 
   3752    static_assert(static_cast<unsigned long>(ShaderType::EnumCount) <= sizeof(unsigned long) * 8,
   3753                  "Too many shader types");
   3754 
   3755    // Reject programs that use transform feedback varyings if the hardware cannot support them.
   3756    if (mState.mExecutable->getLinkedTransformFeedbackVaryings().size() > 0 &&
   3757        context->getFrontendFeatures().disableProgramCachingForTransformFeedback.enabled)
   3758    {
   3759        infoLog << "Current driver does not support transform feedback in binary programs.";
   3760        return angle::Result::Stop;
   3761    }
   3762 
   3763    if (!mState.mAttachedShaders[ShaderType::Compute])
   3764    {
   3765        mState.mExecutable->updateTransformFeedbackStrides();
   3766    }
   3767 
   3768    postResolveLink(context);
   3769    mState.mExecutable->updateCanDrawWith();
   3770 
   3771    if (context->getShareGroup()->getFrameCaptureShared()->enabled())
   3772    {
   3773        // Extract the source for each stage from the program binary
   3774        angle::ProgramSources sources;
   3775 
   3776        for (ShaderType shaderType : mState.mExecutable->getLinkedShaderStages())
   3777        {
   3778            std::string shaderSource = stream.readString();
   3779            ASSERT(shaderSource.length() > 0);
   3780            sources[shaderType] = std::move(shaderSource);
   3781        }
   3782 
   3783        // Store it for use during mid-execution capture
   3784        context->getShareGroup()->getFrameCaptureShared()->setProgramSources(id(),
   3785                                                                             std::move(sources));
   3786    }
   3787 
   3788    return angle::Result::Continue;
   3789 }
   3790 
   3791 void Program::postResolveLink(const gl::Context *context)
   3792 {
   3793    mState.updateActiveSamplers();
   3794    mState.mExecutable->mActiveImageShaderBits.fill({});
   3795    mState.mExecutable->updateActiveImages(getExecutable());
   3796 
   3797    setUniformValuesFromBindingQualifiers();
   3798 
   3799    if (context->getExtensions().multiDrawANGLE)
   3800    {
   3801        mState.mDrawIDLocation = getUniformLocation("gl_DrawID").value;
   3802    }
   3803 
   3804    if (context->getExtensions().baseVertexBaseInstanceShaderBuiltinANGLE)
   3805    {
   3806        mState.mBaseVertexLocation   = getUniformLocation("gl_BaseVertex").value;
   3807        mState.mBaseInstanceLocation = getUniformLocation("gl_BaseInstance").value;
   3808    }
   3809 }
   3810 }  // namespace gl