tor-browser

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

Shader.cpp (42625B)


      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 // Shader.cpp: Implements the gl::Shader class and its  derived classes
      8 // VertexShader and FragmentShader. Implements GL shader objects and related
      9 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
     10 
     11 #include "libANGLE/Shader.h"
     12 
     13 #include <functional>
     14 #include <sstream>
     15 
     16 #include "GLSLANG/ShaderLang.h"
     17 #include "common/utilities.h"
     18 #include "libANGLE/Caps.h"
     19 #include "libANGLE/Compiler.h"
     20 #include "libANGLE/Constants.h"
     21 #include "libANGLE/Context.h"
     22 #include "libANGLE/Display.h"
     23 #include "libANGLE/MemoryShaderCache.h"
     24 #include "libANGLE/Program.h"
     25 #include "libANGLE/ResourceManager.h"
     26 #include "libANGLE/renderer/GLImplFactory.h"
     27 #include "libANGLE/renderer/ShaderImpl.h"
     28 #include "platform/FrontendFeatures_autogen.h"
     29 
     30 namespace gl
     31 {
     32 
     33 namespace
     34 {
     35 constexpr uint32_t kShaderCacheIdentifier = 0x12345678;
     36 
     37 template <typename VarT>
     38 std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
     39 {
     40    ASSERT(variableList);
     41    std::vector<VarT> result;
     42    for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
     43    {
     44        const VarT &var = variableList->at(varIndex);
     45        if (var.active)
     46        {
     47            result.push_back(var);
     48        }
     49    }
     50    return result;
     51 }
     52 
     53 template <typename VarT>
     54 const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
     55 {
     56    ASSERT(variableList);
     57    return *variableList;
     58 }
     59 
     60 void WriteInterfaceBlock(gl::BinaryOutputStream *stream, const sh::InterfaceBlock &block)
     61 {
     62    stream->writeString(block.name);
     63    stream->writeString(block.mappedName);
     64    stream->writeString(block.instanceName);
     65    stream->writeInt(block.arraySize);
     66    stream->writeEnum(block.layout);
     67    stream->writeBool(block.isRowMajorLayout);
     68    stream->writeInt(block.binding);
     69    stream->writeBool(block.staticUse);
     70    stream->writeBool(block.active);
     71    stream->writeEnum(block.blockType);
     72 
     73    stream->writeInt(block.fields.size());
     74    for (const sh::ShaderVariable &shaderVariable : block.fields)
     75    {
     76        WriteShaderVar(stream, shaderVariable);
     77    }
     78 }
     79 
     80 void LoadInterfaceBlock(gl::BinaryInputStream *stream, sh::InterfaceBlock &block)
     81 {
     82    stream->readString(&block.name);
     83    stream->readString(&block.mappedName);
     84    stream->readString(&block.instanceName);
     85    stream->readInt(&block.arraySize);
     86    stream->readEnum(&block.layout);
     87    stream->readBool(&block.isRowMajorLayout);
     88    stream->readInt(&block.binding);
     89    stream->readBool(&block.staticUse);
     90    stream->readBool(&block.active);
     91    stream->readEnum(&block.blockType);
     92 
     93    size_t size = stream->readInt<size_t>();
     94    block.fields.resize(size);
     95    for (sh::ShaderVariable &shaderVariable : block.fields)
     96    {
     97        LoadShaderVar(stream, &shaderVariable);
     98    }
     99 }
    100 }  // anonymous namespace
    101 
    102 // true if varying x has a higher priority in packing than y
    103 bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
    104 {
    105    if (x.type == y.type)
    106    {
    107        return x.getArraySizeProduct() > y.getArraySizeProduct();
    108    }
    109 
    110    // Special case for handling structs: we sort these to the end of the list
    111    if (x.type == GL_NONE)
    112    {
    113        return false;
    114    }
    115 
    116    if (y.type == GL_NONE)
    117    {
    118        return true;
    119    }
    120 
    121    return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
    122 }
    123 
    124 const char *GetShaderTypeString(ShaderType type)
    125 {
    126    switch (type)
    127    {
    128        case ShaderType::Vertex:
    129            return "VERTEX";
    130 
    131        case ShaderType::Fragment:
    132            return "FRAGMENT";
    133 
    134        case ShaderType::Compute:
    135            return "COMPUTE";
    136 
    137        case ShaderType::Geometry:
    138            return "GEOMETRY";
    139 
    140        case ShaderType::TessControl:
    141            return "TESS_CONTROL";
    142 
    143        case ShaderType::TessEvaluation:
    144            return "TESS_EVALUATION";
    145 
    146        default:
    147            UNREACHABLE();
    148            return "";
    149    }
    150 }
    151 
    152 class [[nodiscard]] ScopedExit final : angle::NonCopyable
    153 {
    154  public:
    155    ScopedExit(std::function<void()> exit) : mExit(exit) {}
    156    ~ScopedExit() { mExit(); }
    157 
    158  private:
    159    std::function<void()> mExit;
    160 };
    161 
    162 struct Shader::CompilingState
    163 {
    164    std::shared_ptr<rx::WaitableCompileEvent> compileEvent;
    165    ShCompilerInstance shCompilerInstance;
    166    egl::BlobCache::Key shaderHash;
    167 };
    168 
    169 ShaderState::ShaderState(ShaderType shaderType)
    170    : mLabel(),
    171      mShaderType(shaderType),
    172      mShaderVersion(100),
    173      mNumViews(-1),
    174      mGeometryShaderInvocations(1),
    175      mCompileStatus(CompileStatus::NOT_COMPILED)
    176 {
    177    mLocalSize.fill(-1);
    178 }
    179 
    180 ShaderState::~ShaderState() {}
    181 
    182 Shader::Shader(ShaderProgramManager *manager,
    183               rx::GLImplFactory *implFactory,
    184               const gl::Limitations &rendererLimitations,
    185               ShaderType type,
    186               ShaderProgramID handle)
    187    : mState(type),
    188      mImplementation(implFactory->createShader(mState)),
    189      mRendererLimitations(rendererLimitations),
    190      mHandle(handle),
    191      mType(type),
    192      mRefCount(0),
    193      mDeleteStatus(false),
    194      mResourceManager(manager),
    195      mCurrentMaxComputeWorkGroupInvocations(0u)
    196 {
    197    ASSERT(mImplementation);
    198 }
    199 
    200 void Shader::onDestroy(const gl::Context *context)
    201 {
    202    resolveCompile(context);
    203    mImplementation->destroy();
    204    mBoundCompiler.set(context, nullptr);
    205    mImplementation.reset(nullptr);
    206    delete this;
    207 }
    208 
    209 Shader::~Shader()
    210 {
    211    ASSERT(!mImplementation);
    212 }
    213 
    214 angle::Result Shader::setLabel(const Context *context, const std::string &label)
    215 {
    216    mState.mLabel = label;
    217 
    218    if (mImplementation)
    219    {
    220        return mImplementation->onLabelUpdate(context);
    221    }
    222    return angle::Result::Continue;
    223 }
    224 
    225 const std::string &Shader::getLabel() const
    226 {
    227    return mState.mLabel;
    228 }
    229 
    230 ShaderProgramID Shader::getHandle() const
    231 {
    232    return mHandle;
    233 }
    234 
    235 void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
    236 {
    237    std::ostringstream stream;
    238 
    239    for (int i = 0; i < count; i++)
    240    {
    241        if (length == nullptr || length[i] < 0)
    242        {
    243            stream.write(string[i], strlen(string[i]));
    244        }
    245        else
    246        {
    247            stream.write(string[i], length[i]);
    248        }
    249    }
    250 
    251    mState.mSource = stream.str();
    252 }
    253 
    254 int Shader::getInfoLogLength(const Context *context)
    255 {
    256    resolveCompile(context);
    257    if (mInfoLog.empty())
    258    {
    259        return 0;
    260    }
    261 
    262    return (static_cast<int>(mInfoLog.length()) + 1);
    263 }
    264 
    265 void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
    266 {
    267    resolveCompile(context);
    268 
    269    int index = 0;
    270 
    271    if (bufSize > 0)
    272    {
    273        index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
    274        memcpy(infoLog, mInfoLog.c_str(), index);
    275 
    276        infoLog[index] = '\0';
    277    }
    278 
    279    if (length)
    280    {
    281        *length = index;
    282    }
    283 }
    284 
    285 int Shader::getSourceLength() const
    286 {
    287    return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
    288 }
    289 
    290 int Shader::getTranslatedSourceLength(const Context *context)
    291 {
    292    resolveCompile(context);
    293 
    294    if (mState.mTranslatedSource.empty())
    295    {
    296        return 0;
    297    }
    298 
    299    return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
    300 }
    301 
    302 int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
    303 {
    304    resolveCompile(context);
    305 
    306    const std::string &debugInfo = mImplementation->getDebugInfo();
    307    if (debugInfo.empty())
    308    {
    309        return 0;
    310    }
    311 
    312    return (static_cast<int>(debugInfo.length()) + 1);
    313 }
    314 
    315 // static
    316 void Shader::GetSourceImpl(const std::string &source,
    317                           GLsizei bufSize,
    318                           GLsizei *length,
    319                           char *buffer)
    320 {
    321    int index = 0;
    322 
    323    if (bufSize > 0)
    324    {
    325        index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
    326        memcpy(buffer, source.c_str(), index);
    327 
    328        buffer[index] = '\0';
    329    }
    330 
    331    if (length)
    332    {
    333        *length = index;
    334    }
    335 }
    336 
    337 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
    338 {
    339    GetSourceImpl(mState.mSource, bufSize, length, buffer);
    340 }
    341 
    342 void Shader::getTranslatedSource(const Context *context,
    343                                 GLsizei bufSize,
    344                                 GLsizei *length,
    345                                 char *buffer)
    346 {
    347    GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
    348 }
    349 
    350 const std::string &Shader::getTranslatedSource(const Context *context)
    351 {
    352    resolveCompile(context);
    353    return mState.mTranslatedSource;
    354 }
    355 
    356 const sh::BinaryBlob &Shader::getCompiledBinary(const Context *context)
    357 {
    358    resolveCompile(context);
    359    return mState.mCompiledBinary;
    360 }
    361 
    362 void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
    363                                              GLsizei bufSize,
    364                                              GLsizei *length,
    365                                              char *buffer)
    366 {
    367    resolveCompile(context);
    368    const std::string &debugInfo = mImplementation->getDebugInfo();
    369    GetSourceImpl(debugInfo, bufSize, length, buffer);
    370 }
    371 
    372 void Shader::compile(const Context *context)
    373 {
    374    resolveCompile(context);
    375 
    376    mState.mTranslatedSource.clear();
    377    mState.mCompiledBinary.clear();
    378    mInfoLog.clear();
    379    mState.mShaderVersion = 100;
    380    mState.mInputVaryings.clear();
    381    mState.mOutputVaryings.clear();
    382    mState.mUniforms.clear();
    383    mState.mUniformBlocks.clear();
    384    mState.mShaderStorageBlocks.clear();
    385    mState.mActiveAttributes.clear();
    386    mState.mActiveOutputVariables.clear();
    387    mState.mNumViews = -1;
    388    mState.mGeometryShaderInputPrimitiveType.reset();
    389    mState.mGeometryShaderOutputPrimitiveType.reset();
    390    mState.mGeometryShaderMaxVertices.reset();
    391    mState.mGeometryShaderInvocations = 1;
    392    mState.mTessControlShaderVertices = 0;
    393    mState.mTessGenMode               = 0;
    394    mState.mTessGenSpacing            = 0;
    395    mState.mTessGenVertexOrder        = 0;
    396    mState.mTessGenPointMode          = 0;
    397    mState.mAdvancedBlendEquations.reset();
    398    mState.mHasDiscard              = false;
    399    mState.mEnablesPerSampleShading = false;
    400    mState.mSpecConstUsageBits.reset();
    401 
    402    mCurrentMaxComputeWorkGroupInvocations =
    403        static_cast<GLuint>(context->getCaps().maxComputeWorkGroupInvocations);
    404    mMaxComputeSharedMemory = context->getCaps().maxComputeSharedMemorySize;
    405 
    406    ShCompileOptions options = {};
    407    options.objectCode       = true;
    408    options.variables        = true;
    409    options.emulateGLDrawID  = true;
    410 
    411    // Add default options to WebGL shaders to prevent unexpected behavior during
    412    // compilation.
    413    if (context->isWebGL())
    414    {
    415        options.initGLPosition             = true;
    416        options.limitCallStackDepth        = true;
    417        options.limitExpressionComplexity  = true;
    418        options.enforcePackingRestrictions = true;
    419        options.initSharedVariables        = true;
    420    }
    421    else
    422    {
    423        // Per https://github.com/KhronosGroup/WebGL/pull/3278 gl_BaseVertex/gl_BaseInstance are
    424        // removed from WebGL
    425        options.emulateGLBaseVertexBaseInstance = true;
    426    }
    427 
    428    // Some targets (e.g. D3D11 Feature Level 9_3 and below) do not support non-constant loop
    429    // indexes in fragment shaders. Shader compilation will fail. To provide a better error
    430    // message we can instruct the compiler to pre-validate.
    431    if (mRendererLimitations.shadersRequireIndexedLoopValidation)
    432    {
    433        options.validateLoopIndexing = true;
    434    }
    435 
    436    if (context->getFrontendFeatures().scalarizeVecAndMatConstructorArgs.enabled)
    437    {
    438        options.scalarizeVecAndMatConstructorArgs = true;
    439    }
    440 
    441    if (context->getFrontendFeatures().forceInitShaderVariables.enabled)
    442    {
    443        options.initOutputVariables           = true;
    444        options.initializeUninitializedLocals = true;
    445    }
    446 
    447    mBoundCompiler.set(context, context->getCompiler());
    448 
    449    ASSERT(mBoundCompiler.get());
    450    ShCompilerInstance compilerInstance = mBoundCompiler->getInstance(mState.mShaderType);
    451    ShHandle compilerHandle             = compilerInstance.getHandle();
    452    ASSERT(compilerHandle);
    453    mCompilerResourcesString = compilerInstance.getBuiltinResourcesString();
    454 
    455    // Find a shader in Blob Cache
    456    egl::BlobCache::Key shaderHash = {0};
    457    MemoryShaderCache *shaderCache = context->getMemoryShaderCache();
    458    if (shaderCache)
    459    {
    460        angle::Result cacheResult =
    461            shaderCache->getShader(context, this, options, compilerInstance, &shaderHash);
    462 
    463        if (cacheResult == angle::Result::Continue)
    464        {
    465            compilerInstance.destroy();
    466            return;
    467        }
    468    }
    469 
    470    // Cache load failed, fall through normal compiling.
    471    mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
    472    mCompilingState.reset(new CompilingState());
    473    mCompilingState->shCompilerInstance = std::move(compilerInstance);
    474    mCompilingState->shaderHash         = shaderHash;
    475    mCompilingState->compileEvent =
    476        mImplementation->compile(context, &(mCompilingState->shCompilerInstance), &options);
    477 }
    478 
    479 void Shader::resolveCompile(const Context *context)
    480 {
    481    if (!mState.compilePending())
    482    {
    483        return;
    484    }
    485 
    486    ASSERT(mCompilingState.get());
    487 
    488    mCompilingState->compileEvent->wait();
    489 
    490    mInfoLog += mCompilingState->compileEvent->getInfoLog();
    491 
    492    ScopedExit exit([this]() {
    493        mBoundCompiler->putInstance(std::move(mCompilingState->shCompilerInstance));
    494        mCompilingState->compileEvent.reset();
    495        mCompilingState.reset();
    496    });
    497 
    498    ShHandle compilerHandle = mCompilingState->shCompilerInstance.getHandle();
    499    if (!mCompilingState->compileEvent->getResult())
    500    {
    501        mInfoLog += sh::GetInfoLog(compilerHandle);
    502        INFO() << std::endl << mInfoLog;
    503        mState.mCompileStatus = CompileStatus::NOT_COMPILED;
    504        return;
    505    }
    506 
    507    const ShShaderOutput outputType = mCompilingState->shCompilerInstance.getShaderOutputType();
    508    const bool isBinaryOutput =
    509        outputType == SH_SPIRV_VULKAN_OUTPUT || outputType == SH_SPIRV_METAL_OUTPUT;
    510 
    511    if (isBinaryOutput)
    512    {
    513        mState.mCompiledBinary = sh::GetObjectBinaryBlob(compilerHandle);
    514    }
    515    else
    516    {
    517        mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
    518 
    519 #if !defined(NDEBUG)
    520        // Prefix translated shader with commented out un-translated shader.
    521        // Useful in diagnostics tools which capture the shader source.
    522        std::ostringstream shaderStream;
    523        shaderStream << "// GLSL\n";
    524        shaderStream << "//\n";
    525 
    526        std::istringstream inputSourceStream(mState.mSource);
    527        std::string line;
    528        while (std::getline(inputSourceStream, line))
    529        {
    530            // Remove null characters from the source line
    531            line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
    532 
    533            shaderStream << "// " << line;
    534 
    535            // glslang complains if a comment ends with backslash
    536            if (!line.empty() && line.back() == '\\')
    537            {
    538                shaderStream << "\\";
    539            }
    540 
    541            shaderStream << std::endl;
    542        }
    543        shaderStream << "\n\n";
    544        shaderStream << mState.mTranslatedSource;
    545        mState.mTranslatedSource = shaderStream.str();
    546 #endif  // !defined(NDEBUG)
    547    }
    548 
    549    // Gather the shader information
    550    mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
    551 
    552    mState.mUniforms            = GetShaderVariables(sh::GetUniforms(compilerHandle));
    553    mState.mUniformBlocks       = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
    554    mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
    555    mState.mSpecConstUsageBits =
    556        rx::SpecConstUsageBits(sh::GetShaderSpecConstUsageBits(compilerHandle));
    557 
    558    switch (mState.mShaderType)
    559    {
    560        case ShaderType::Compute:
    561        {
    562            mState.mAllAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
    563            mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
    564            mState.mLocalSize        = sh::GetComputeShaderLocalGroupSize(compilerHandle);
    565            if (mState.mLocalSize.isDeclared())
    566            {
    567                angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]);
    568                checked_local_size_product *= mState.mLocalSize[1];
    569                checked_local_size_product *= mState.mLocalSize[2];
    570 
    571                if (!checked_local_size_product.IsValid())
    572                {
    573                    WARN() << std::endl
    574                           << "Integer overflow when computing the product of local_size_x, "
    575                           << "local_size_y and local_size_z.";
    576                    mState.mCompileStatus = CompileStatus::NOT_COMPILED;
    577                    return;
    578                }
    579                if (checked_local_size_product.ValueOrDie() >
    580                    mCurrentMaxComputeWorkGroupInvocations)
    581                {
    582                    WARN() << std::endl
    583                           << "The total number of invocations within a work group exceeds "
    584                           << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS.";
    585                    mState.mCompileStatus = CompileStatus::NOT_COMPILED;
    586                    return;
    587                }
    588            }
    589 
    590            unsigned int sharedMemSize = sh::GetShaderSharedMemorySize(compilerHandle);
    591            if (sharedMemSize > mMaxComputeSharedMemory)
    592            {
    593                WARN() << std::endl << "Exceeded maximum shared memory size";
    594                mState.mCompileStatus = CompileStatus::NOT_COMPILED;
    595                return;
    596            }
    597            break;
    598        }
    599        case ShaderType::Vertex:
    600        {
    601            mState.mOutputVaryings   = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
    602            mState.mAllAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
    603            mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
    604            mState.mNumViews         = sh::GetVertexShaderNumViews(compilerHandle);
    605            break;
    606        }
    607        case ShaderType::Fragment:
    608        {
    609            mState.mAllAttributes    = GetShaderVariables(sh::GetAttributes(compilerHandle));
    610            mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
    611            mState.mInputVaryings    = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
    612            // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
    613            std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
    614            mState.mActiveOutputVariables =
    615                GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
    616            mState.mHasDiscard              = sh::HasDiscardInFragmentShader(compilerHandle);
    617            mState.mEnablesPerSampleShading = sh::EnablesPerSampleShading(compilerHandle);
    618            mState.mAdvancedBlendEquations =
    619                BlendEquationBitSet(sh::GetAdvancedBlendEquations(compilerHandle));
    620            break;
    621        }
    622        case ShaderType::Geometry:
    623        {
    624            mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
    625            mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
    626 
    627            if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
    628            {
    629                mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>(
    630                    sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
    631            }
    632            if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
    633            {
    634                mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>(
    635                    sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
    636            }
    637            if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
    638            {
    639                mState.mGeometryShaderMaxVertices =
    640                    sh::GetGeometryShaderMaxVertices(compilerHandle);
    641            }
    642            mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
    643            break;
    644        }
    645        case ShaderType::TessControl:
    646        {
    647            mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
    648            mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
    649            mState.mTessControlShaderVertices = sh::GetTessControlShaderVertices(compilerHandle);
    650            break;
    651        }
    652        case ShaderType::TessEvaluation:
    653        {
    654            mState.mInputVaryings  = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
    655            mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
    656            if (sh::HasValidTessGenMode(compilerHandle))
    657            {
    658                mState.mTessGenMode = sh::GetTessGenMode(compilerHandle);
    659            }
    660            if (sh::HasValidTessGenSpacing(compilerHandle))
    661            {
    662                mState.mTessGenSpacing = sh::GetTessGenSpacing(compilerHandle);
    663            }
    664            if (sh::HasValidTessGenVertexOrder(compilerHandle))
    665            {
    666                mState.mTessGenVertexOrder = sh::GetTessGenVertexOrder(compilerHandle);
    667            }
    668            if (sh::HasValidTessGenPointMode(compilerHandle))
    669            {
    670                mState.mTessGenPointMode = sh::GetTessGenPointMode(compilerHandle);
    671            }
    672            break;
    673        }
    674 
    675        default:
    676            UNREACHABLE();
    677    }
    678 
    679    ASSERT(!mState.mTranslatedSource.empty() || !mState.mCompiledBinary.empty());
    680 
    681    bool success          = mCompilingState->compileEvent->postTranslate(&mInfoLog);
    682    mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
    683 
    684    MemoryShaderCache *shaderCache = context->getMemoryShaderCache();
    685    if (success && shaderCache)
    686    {
    687        // Save to the shader cache.
    688        if (shaderCache->putShader(context, mCompilingState->shaderHash, this) !=
    689            angle::Result::Continue)
    690        {
    691            ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
    692                               "Failed to save compiled shader to memory shader cache.");
    693        }
    694    }
    695 }
    696 
    697 void Shader::addRef()
    698 {
    699    mRefCount++;
    700 }
    701 
    702 void Shader::release(const Context *context)
    703 {
    704    mRefCount--;
    705 
    706    if (mRefCount == 0 && mDeleteStatus)
    707    {
    708        mResourceManager->deleteShader(context, mHandle);
    709    }
    710 }
    711 
    712 unsigned int Shader::getRefCount() const
    713 {
    714    return mRefCount;
    715 }
    716 
    717 bool Shader::isFlaggedForDeletion() const
    718 {
    719    return mDeleteStatus;
    720 }
    721 
    722 void Shader::flagForDeletion()
    723 {
    724    mDeleteStatus = true;
    725 }
    726 
    727 bool Shader::isCompiled(const Context *context)
    728 {
    729    resolveCompile(context);
    730    return mState.mCompileStatus == CompileStatus::COMPILED;
    731 }
    732 
    733 bool Shader::isCompleted()
    734 {
    735    return (!mState.compilePending() || mCompilingState->compileEvent->isReady());
    736 }
    737 
    738 int Shader::getShaderVersion(const Context *context)
    739 {
    740    resolveCompile(context);
    741    return mState.mShaderVersion;
    742 }
    743 
    744 const std::vector<sh::ShaderVariable> &Shader::getInputVaryings(const Context *context)
    745 {
    746    resolveCompile(context);
    747    return mState.getInputVaryings();
    748 }
    749 
    750 const std::vector<sh::ShaderVariable> &Shader::getOutputVaryings(const Context *context)
    751 {
    752    resolveCompile(context);
    753    return mState.getOutputVaryings();
    754 }
    755 
    756 const std::vector<sh::ShaderVariable> &Shader::getUniforms(const Context *context)
    757 {
    758    resolveCompile(context);
    759    return mState.getUniforms();
    760 }
    761 
    762 const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
    763 {
    764    resolveCompile(context);
    765    return mState.getUniformBlocks();
    766 }
    767 
    768 const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
    769 {
    770    resolveCompile(context);
    771    return mState.getShaderStorageBlocks();
    772 }
    773 
    774 const std::vector<sh::ShaderVariable> &Shader::getActiveAttributes(const Context *context)
    775 {
    776    resolveCompile(context);
    777    return mState.getActiveAttributes();
    778 }
    779 
    780 const std::vector<sh::ShaderVariable> &Shader::getAllAttributes(const Context *context)
    781 {
    782    resolveCompile(context);
    783    return mState.getAllAttributes();
    784 }
    785 
    786 const std::vector<sh::ShaderVariable> &Shader::getActiveOutputVariables(const Context *context)
    787 {
    788    resolveCompile(context);
    789    return mState.getActiveOutputVariables();
    790 }
    791 
    792 std::string Shader::getTransformFeedbackVaryingMappedName(const Context *context,
    793                                                          const std::string &tfVaryingName)
    794 {
    795    ASSERT(mState.getShaderType() != ShaderType::Fragment &&
    796           mState.getShaderType() != ShaderType::Compute);
    797    const auto &varyings = getOutputVaryings(context);
    798    auto bracketPos      = tfVaryingName.find("[");
    799    if (bracketPos != std::string::npos)
    800    {
    801        auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
    802        for (const auto &varying : varyings)
    803        {
    804            if (varying.name == tfVaryingBaseName)
    805            {
    806                std::string mappedNameWithArrayIndex =
    807                    varying.mappedName + tfVaryingName.substr(bracketPos);
    808                return mappedNameWithArrayIndex;
    809            }
    810        }
    811    }
    812    else
    813    {
    814        for (const auto &varying : varyings)
    815        {
    816            if (varying.name == tfVaryingName)
    817            {
    818                return varying.mappedName;
    819            }
    820            else if (varying.isStruct())
    821            {
    822                GLuint fieldIndex = 0;
    823                const auto *field = varying.findField(tfVaryingName, &fieldIndex);
    824                if (field == nullptr)
    825                {
    826                    continue;
    827                }
    828                ASSERT(field != nullptr && !field->isStruct() &&
    829                       (!field->isArray() || varying.isShaderIOBlock));
    830                std::string mappedName;
    831                // If it's an I/O block without an instance name, don't include the block name.
    832                if (!varying.isShaderIOBlock || !varying.name.empty())
    833                {
    834                    mappedName = varying.isShaderIOBlock ? varying.mappedStructOrBlockName
    835                                                         : varying.mappedName;
    836                    mappedName += '.';
    837                }
    838                return mappedName + field->mappedName;
    839            }
    840        }
    841    }
    842    UNREACHABLE();
    843    return std::string();
    844 }
    845 
    846 const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
    847 {
    848    resolveCompile(context);
    849    return mState.mLocalSize;
    850 }
    851 
    852 int Shader::getNumViews(const Context *context)
    853 {
    854    resolveCompile(context);
    855    return mState.mNumViews;
    856 }
    857 
    858 Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType(const Context *context)
    859 {
    860    resolveCompile(context);
    861    return mState.mGeometryShaderInputPrimitiveType;
    862 }
    863 
    864 Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType(const Context *context)
    865 {
    866    resolveCompile(context);
    867    return mState.mGeometryShaderOutputPrimitiveType;
    868 }
    869 
    870 int Shader::getGeometryShaderInvocations(const Context *context)
    871 {
    872    resolveCompile(context);
    873    return mState.mGeometryShaderInvocations;
    874 }
    875 
    876 Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context)
    877 {
    878    resolveCompile(context);
    879    return mState.mGeometryShaderMaxVertices;
    880 }
    881 
    882 int Shader::getTessControlShaderVertices(const Context *context)
    883 {
    884    resolveCompile(context);
    885    return mState.mTessControlShaderVertices;
    886 }
    887 
    888 GLenum Shader::getTessGenMode(const Context *context)
    889 {
    890    resolveCompile(context);
    891    return mState.mTessGenMode;
    892 }
    893 
    894 GLenum Shader::getTessGenSpacing(const Context *context)
    895 {
    896    resolveCompile(context);
    897    return mState.mTessGenSpacing;
    898 }
    899 
    900 GLenum Shader::getTessGenVertexOrder(const Context *context)
    901 {
    902    resolveCompile(context);
    903    return mState.mTessGenVertexOrder;
    904 }
    905 
    906 GLenum Shader::getTessGenPointMode(const Context *context)
    907 {
    908    resolveCompile(context);
    909    return mState.mTessGenPointMode;
    910 }
    911 
    912 const std::string &Shader::getCompilerResourcesString() const
    913 {
    914    return mCompilerResourcesString;
    915 }
    916 
    917 angle::Result Shader::serialize(const Context *context, angle::MemoryBuffer *binaryOut) const
    918 {
    919    BinaryOutputStream stream;
    920 
    921    stream.writeInt(kShaderCacheIdentifier);
    922    stream.writeString(mState.mLabel);
    923    stream.writeInt(mState.mShaderVersion);
    924    stream.writeString(mCompilerResourcesString);
    925 
    926    stream.writeInt(mState.mUniforms.size());
    927    for (const sh::ShaderVariable &shaderVariable : mState.mUniforms)
    928    {
    929        WriteShaderVar(&stream, shaderVariable);
    930    }
    931 
    932    stream.writeInt(mState.mUniformBlocks.size());
    933    for (const sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks)
    934    {
    935        WriteInterfaceBlock(&stream, interfaceBlock);
    936    }
    937 
    938    stream.writeInt(mState.mShaderStorageBlocks.size());
    939    for (const sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks)
    940    {
    941        WriteInterfaceBlock(&stream, interfaceBlock);
    942    }
    943 
    944    stream.writeInt(mState.mSpecConstUsageBits.bits());
    945 
    946    switch (mType)
    947    {
    948        case ShaderType::Compute:
    949        {
    950            stream.writeInt(mState.mAllAttributes.size());
    951            for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
    952            {
    953                WriteShaderVar(&stream, shaderVariable);
    954            }
    955            stream.writeInt(mState.mActiveAttributes.size());
    956            for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
    957            {
    958                WriteShaderVar(&stream, shaderVariable);
    959            }
    960            stream.writeInt(mState.mLocalSize[0]);
    961            stream.writeInt(mState.mLocalSize[1]);
    962            stream.writeInt(mState.mLocalSize[2]);
    963            break;
    964        }
    965 
    966        case ShaderType::Vertex:
    967        {
    968            stream.writeInt(mState.mOutputVaryings.size());
    969            for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
    970            {
    971                WriteShaderVar(&stream, shaderVariable);
    972            }
    973            stream.writeInt(mState.mAllAttributes.size());
    974            for (const sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
    975            {
    976                WriteShaderVar(&stream, shaderVariable);
    977            }
    978            stream.writeInt(mState.mActiveAttributes.size());
    979            for (const sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
    980            {
    981                WriteShaderVar(&stream, shaderVariable);
    982            }
    983            stream.writeInt(mState.mNumViews);
    984            break;
    985        }
    986        case ShaderType::Fragment:
    987        {
    988            stream.writeInt(mState.mInputVaryings.size());
    989            for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
    990            {
    991                WriteShaderVar(&stream, shaderVariable);
    992            }
    993            stream.writeInt(mState.mActiveOutputVariables.size());
    994            for (const sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables)
    995            {
    996                WriteShaderVar(&stream, shaderVariable);
    997            }
    998            stream.writeBool(mState.mEnablesPerSampleShading);
    999            stream.writeInt(mState.mAdvancedBlendEquations.bits());
   1000            break;
   1001        }
   1002        case ShaderType::Geometry:
   1003        {
   1004            bool valid;
   1005 
   1006            stream.writeInt(mState.mInputVaryings.size());
   1007            for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1008            {
   1009                WriteShaderVar(&stream, shaderVariable);
   1010            }
   1011            stream.writeInt(mState.mOutputVaryings.size());
   1012            for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1013            {
   1014                WriteShaderVar(&stream, shaderVariable);
   1015            }
   1016 
   1017            valid = (bool)mState.mGeometryShaderInputPrimitiveType.valid();
   1018            stream.writeBool(valid);
   1019            if (valid)
   1020            {
   1021                unsigned char value =
   1022                    (unsigned char)mState.mGeometryShaderInputPrimitiveType.value();
   1023                stream.writeBytes(&value, 1);
   1024            }
   1025            valid = (bool)mState.mGeometryShaderOutputPrimitiveType.valid();
   1026            stream.writeBool(valid);
   1027            if (valid)
   1028            {
   1029                unsigned char value =
   1030                    (unsigned char)mState.mGeometryShaderOutputPrimitiveType.value();
   1031                stream.writeBytes(&value, 1);
   1032            }
   1033            valid = mState.mGeometryShaderMaxVertices.valid();
   1034            stream.writeBool(valid);
   1035            if (valid)
   1036            {
   1037                int value = (int)mState.mGeometryShaderMaxVertices.value();
   1038                stream.writeInt(value);
   1039            }
   1040 
   1041            stream.writeInt(mState.mGeometryShaderInvocations);
   1042            break;
   1043        }
   1044        case ShaderType::TessControl:
   1045        {
   1046            stream.writeInt(mState.mInputVaryings.size());
   1047            for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1048            {
   1049                WriteShaderVar(&stream, shaderVariable);
   1050            }
   1051            stream.writeInt(mState.mOutputVaryings.size());
   1052            for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1053            {
   1054                WriteShaderVar(&stream, shaderVariable);
   1055            }
   1056            stream.writeInt(mState.mTessControlShaderVertices);
   1057            break;
   1058        }
   1059        case ShaderType::TessEvaluation:
   1060        {
   1061            unsigned int value;
   1062 
   1063            stream.writeInt(mState.mInputVaryings.size());
   1064            for (const sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1065            {
   1066                WriteShaderVar(&stream, shaderVariable);
   1067            }
   1068            stream.writeInt(mState.mOutputVaryings.size());
   1069            for (const sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1070            {
   1071                WriteShaderVar(&stream, shaderVariable);
   1072            }
   1073 
   1074            value = (unsigned int)(mState.mTessGenMode);
   1075            stream.writeInt(value);
   1076 
   1077            value = (unsigned int)mState.mTessGenSpacing;
   1078            stream.writeInt(value);
   1079 
   1080            value = (unsigned int)mState.mTessGenVertexOrder;
   1081            stream.writeInt(value);
   1082 
   1083            value = (unsigned int)mState.mTessGenPointMode;
   1084            stream.writeInt(value);
   1085            break;
   1086        }
   1087        default:
   1088            UNREACHABLE();
   1089    }
   1090 
   1091    stream.writeIntVector(mState.mCompiledBinary);
   1092    stream.writeEnum(mState.mCompileStatus);
   1093 
   1094    ASSERT(binaryOut);
   1095    if (!binaryOut->resize(stream.length()))
   1096    {
   1097        std::stringstream sstream;
   1098        sstream << "Failed to allocate enough memory to serialize a shader. (" << stream.length()
   1099                << " bytes )";
   1100        ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_LOW,
   1101                           sstream.str().c_str());
   1102        return angle::Result::Incomplete;
   1103    }
   1104 
   1105    memcpy(binaryOut->data(), stream.data(), stream.length());
   1106 
   1107    return angle::Result::Continue;
   1108 }
   1109 
   1110 angle::Result Shader::deserialize(const Context *context, BinaryInputStream &stream)
   1111 {
   1112    size_t size;
   1113 
   1114    if (stream.readInt<uint32_t>() != kShaderCacheIdentifier)
   1115    {
   1116        return angle::Result::Stop;
   1117    }
   1118 
   1119    stream.readString(&mState.mLabel);
   1120    stream.readInt(&mState.mShaderVersion);
   1121    stream.readString(&mCompilerResourcesString);
   1122 
   1123    size = stream.readInt<size_t>();
   1124    mState.mUniforms.resize(size);
   1125    for (sh::ShaderVariable &shaderVariable : mState.mUniforms)
   1126    {
   1127        LoadShaderVar(&stream, &shaderVariable);
   1128    }
   1129 
   1130    size = stream.readInt<size_t>();
   1131    mState.mUniformBlocks.resize(size);
   1132    for (sh::InterfaceBlock &interfaceBlock : mState.mUniformBlocks)
   1133    {
   1134        LoadInterfaceBlock(&stream, interfaceBlock);
   1135    }
   1136 
   1137    size = stream.readInt<size_t>();
   1138    mState.mShaderStorageBlocks.resize(size);
   1139    for (sh::InterfaceBlock &interfaceBlock : mState.mShaderStorageBlocks)
   1140    {
   1141        LoadInterfaceBlock(&stream, interfaceBlock);
   1142    }
   1143 
   1144    mState.mSpecConstUsageBits = rx::SpecConstUsageBits(stream.readInt<uint32_t>());
   1145 
   1146    switch (mType)
   1147    {
   1148        case ShaderType::Compute:
   1149        {
   1150            size = stream.readInt<size_t>();
   1151            mState.mAllAttributes.resize(size);
   1152            for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
   1153            {
   1154                LoadShaderVar(&stream, &shaderVariable);
   1155            }
   1156            size = stream.readInt<size_t>();
   1157            mState.mActiveAttributes.resize(size);
   1158            for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
   1159            {
   1160                LoadShaderVar(&stream, &shaderVariable);
   1161            }
   1162            stream.readInt(&mState.mLocalSize[0]);
   1163            stream.readInt(&mState.mLocalSize[1]);
   1164            stream.readInt(&mState.mLocalSize[2]);
   1165            break;
   1166        }
   1167        case ShaderType::Vertex:
   1168        {
   1169            size = stream.readInt<size_t>();
   1170            mState.mOutputVaryings.resize(size);
   1171            for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1172            {
   1173                LoadShaderVar(&stream, &shaderVariable);
   1174            }
   1175            size = stream.readInt<size_t>();
   1176            mState.mAllAttributes.resize(size);
   1177            for (sh::ShaderVariable &shaderVariable : mState.mAllAttributes)
   1178            {
   1179                LoadShaderVar(&stream, &shaderVariable);
   1180            }
   1181            size = stream.readInt<size_t>();
   1182            mState.mActiveAttributes.resize(size);
   1183            for (sh::ShaderVariable &shaderVariable : mState.mActiveAttributes)
   1184            {
   1185                LoadShaderVar(&stream, &shaderVariable);
   1186            }
   1187            stream.readInt(&mState.mNumViews);
   1188            break;
   1189        }
   1190        case ShaderType::Fragment:
   1191        {
   1192            size = stream.readInt<size_t>();
   1193            mState.mInputVaryings.resize(size);
   1194            for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1195            {
   1196                LoadShaderVar(&stream, &shaderVariable);
   1197            }
   1198            size = stream.readInt<size_t>();
   1199            mState.mActiveOutputVariables.resize(size);
   1200            for (sh::ShaderVariable &shaderVariable : mState.mActiveOutputVariables)
   1201            {
   1202                LoadShaderVar(&stream, &shaderVariable);
   1203            }
   1204            stream.readBool(&mState.mEnablesPerSampleShading);
   1205            int advancedBlendEquationBits;
   1206            stream.readInt(&advancedBlendEquationBits);
   1207            mState.mAdvancedBlendEquations = BlendEquationBitSet(advancedBlendEquationBits);
   1208            break;
   1209        }
   1210        case ShaderType::Geometry:
   1211        {
   1212            bool valid;
   1213 
   1214            size = stream.readInt<size_t>();
   1215            mState.mInputVaryings.resize(size);
   1216            for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1217            {
   1218                LoadShaderVar(&stream, &shaderVariable);
   1219            }
   1220            size = stream.readInt<size_t>();
   1221            mState.mOutputVaryings.resize(size);
   1222            for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1223            {
   1224                LoadShaderVar(&stream, &shaderVariable);
   1225            }
   1226 
   1227            stream.readBool(&valid);
   1228            if (valid)
   1229            {
   1230                unsigned char value;
   1231                stream.readBytes(&value, 1);
   1232                mState.mGeometryShaderInputPrimitiveType = static_cast<PrimitiveMode>(value);
   1233            }
   1234            else
   1235            {
   1236                mState.mGeometryShaderInputPrimitiveType.reset();
   1237            }
   1238 
   1239            stream.readBool(&valid);
   1240            if (valid)
   1241            {
   1242                unsigned char value;
   1243                stream.readBytes(&value, 1);
   1244                mState.mGeometryShaderOutputPrimitiveType = static_cast<PrimitiveMode>(value);
   1245            }
   1246            else
   1247            {
   1248                mState.mGeometryShaderOutputPrimitiveType.reset();
   1249            }
   1250 
   1251            stream.readBool(&valid);
   1252            if (valid)
   1253            {
   1254                int value;
   1255                stream.readInt(&value);
   1256                mState.mGeometryShaderMaxVertices = static_cast<GLint>(value);
   1257            }
   1258            else
   1259            {
   1260                mState.mGeometryShaderMaxVertices.reset();
   1261            }
   1262 
   1263            stream.readInt(&mState.mGeometryShaderInvocations);
   1264            break;
   1265        }
   1266        case ShaderType::TessControl:
   1267        {
   1268            size = stream.readInt<size_t>();
   1269            mState.mInputVaryings.resize(size);
   1270            for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1271            {
   1272                LoadShaderVar(&stream, &shaderVariable);
   1273            }
   1274            size = stream.readInt<size_t>();
   1275            mState.mOutputVaryings.resize(size);
   1276            for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1277            {
   1278                LoadShaderVar(&stream, &shaderVariable);
   1279            }
   1280            stream.readInt(&mState.mTessControlShaderVertices);
   1281            break;
   1282        }
   1283        case ShaderType::TessEvaluation:
   1284        {
   1285            unsigned int value;
   1286 
   1287            size = stream.readInt<size_t>();
   1288            mState.mInputVaryings.resize(size);
   1289            for (sh::ShaderVariable &shaderVariable : mState.mInputVaryings)
   1290            {
   1291                LoadShaderVar(&stream, &shaderVariable);
   1292            }
   1293            size = stream.readInt<size_t>();
   1294            mState.mOutputVaryings.resize(size);
   1295            for (sh::ShaderVariable &shaderVariable : mState.mOutputVaryings)
   1296            {
   1297                LoadShaderVar(&stream, &shaderVariable);
   1298            }
   1299 
   1300            stream.readInt(&value);
   1301            mState.mTessGenMode = (GLenum)value;
   1302 
   1303            stream.readInt(&value);
   1304            mState.mTessGenSpacing = (GLenum)value;
   1305 
   1306            stream.readInt(&value);
   1307            mState.mTessGenVertexOrder = (GLenum)value;
   1308 
   1309            stream.readInt(&value);
   1310            mState.mTessGenPointMode = (GLenum)value;
   1311            break;
   1312        }
   1313        default:
   1314            UNREACHABLE();
   1315    }
   1316 
   1317    stream.readIntVector<unsigned int>(&mState.mCompiledBinary);
   1318    mState.mCompileStatus = stream.readEnum<CompileStatus>();
   1319 
   1320    return angle::Result::Continue;
   1321 }
   1322 
   1323 angle::Result Shader::loadBinary(const Context *context, const void *binary, GLsizei length)
   1324 {
   1325    BinaryInputStream stream(binary, length);
   1326    ANGLE_TRY(deserialize(context, stream));
   1327 
   1328    return angle::Result::Continue;
   1329 }
   1330 
   1331 }  // namespace gl