tor-browser

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

Context.cpp (375217B)


      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 // Context.cpp: Implements the gl::Context class, managing all GL state and performing
      8 // rendering operations. It is the GLES2 specific implementation of EGLContext.
      9 #include "libANGLE/Context.inl.h"
     10 
     11 #include <stdarg.h>
     12 #include <stdio.h>
     13 #include <string.h>
     14 
     15 #include <iterator>
     16 #include <sstream>
     17 #include <vector>
     18 
     19 #include "common/PackedEnums.h"
     20 #include "common/angle_version_info.h"
     21 #include "common/matrix_utils.h"
     22 #include "common/platform.h"
     23 #include "common/system_utils.h"
     24 #include "common/utilities.h"
     25 #include "libANGLE/Buffer.h"
     26 #include "libANGLE/Compiler.h"
     27 #include "libANGLE/Display.h"
     28 #include "libANGLE/Fence.h"
     29 #include "libANGLE/FramebufferAttachment.h"
     30 #include "libANGLE/MemoryObject.h"
     31 #include "libANGLE/PixelLocalStorage.h"
     32 #include "libANGLE/Program.h"
     33 #include "libANGLE/ProgramPipeline.h"
     34 #include "libANGLE/Query.h"
     35 #include "libANGLE/Renderbuffer.h"
     36 #include "libANGLE/ResourceManager.h"
     37 #include "libANGLE/Sampler.h"
     38 #include "libANGLE/Semaphore.h"
     39 #include "libANGLE/Surface.h"
     40 #include "libANGLE/Texture.h"
     41 #include "libANGLE/TransformFeedback.h"
     42 #include "libANGLE/VertexArray.h"
     43 #include "libANGLE/capture/FrameCapture.h"
     44 #include "libANGLE/capture/frame_capture_utils.h"
     45 #include "libANGLE/formatutils.h"
     46 #include "libANGLE/queryconversions.h"
     47 #include "libANGLE/queryutils.h"
     48 #include "libANGLE/renderer/DisplayImpl.h"
     49 #include "libANGLE/renderer/Format.h"
     50 #include "libANGLE/validationES.h"
     51 
     52 #if defined(ANGLE_PLATFORM_APPLE)
     53 #    include <dispatch/dispatch.h>
     54 #    include "common/tls.h"
     55 #endif
     56 
     57 namespace gl
     58 {
     59 namespace
     60 {
     61 
     62 egl::ShareGroup *AllocateOrGetShareGroup(egl::Display *display, const gl::Context *shareContext)
     63 {
     64    if (shareContext)
     65    {
     66        egl::ShareGroup *shareGroup = shareContext->getState().getShareGroup();
     67        shareGroup->addRef();
     68        return shareGroup;
     69    }
     70    else
     71    {
     72        return new egl::ShareGroup(display->getImplementation());
     73    }
     74 }
     75 
     76 template <typename T>
     77 angle::Result GetQueryObjectParameter(const Context *context, Query *query, GLenum pname, T *params)
     78 {
     79    if (!query)
     80    {
     81        // Some applications call into glGetQueryObjectuiv(...) prior to calling glBeginQuery(...)
     82        // This wouldn't be an issue since the validation layer will handle such a usecases but when
     83        // the app enables EGL_KHR_create_context_no_error extension, we skip the validation layer.
     84        switch (pname)
     85        {
     86            case GL_QUERY_RESULT_EXT:
     87                *params = 0;
     88                break;
     89            case GL_QUERY_RESULT_AVAILABLE_EXT:
     90                *params = GL_FALSE;
     91                break;
     92            default:
     93                UNREACHABLE();
     94                return angle::Result::Stop;
     95        }
     96        return angle::Result::Continue;
     97    }
     98 
     99    switch (pname)
    100    {
    101        case GL_QUERY_RESULT_EXT:
    102            return query->getResult(context, params);
    103        case GL_QUERY_RESULT_AVAILABLE_EXT:
    104        {
    105            bool available = false;
    106            if (context->isContextLost())
    107            {
    108                available = true;
    109            }
    110            else
    111            {
    112                ANGLE_TRY(query->isResultAvailable(context, &available));
    113            }
    114            *params = CastFromStateValue<T>(pname, static_cast<GLuint>(available));
    115            return angle::Result::Continue;
    116        }
    117        default:
    118            UNREACHABLE();
    119            return angle::Result::Stop;
    120    }
    121 }
    122 
    123 // Attribute map queries.
    124 EGLint GetClientMajorVersion(const egl::AttributeMap &attribs)
    125 {
    126    return static_cast<EGLint>(attribs.get(EGL_CONTEXT_CLIENT_VERSION, 1));
    127 }
    128 
    129 EGLint GetClientMinorVersion(const egl::AttributeMap &attribs)
    130 {
    131    return static_cast<EGLint>(attribs.get(EGL_CONTEXT_MINOR_VERSION, 0));
    132 }
    133 
    134 bool GetBackwardCompatibleContext(const egl::AttributeMap &attribs)
    135 {
    136    return attribs.get(EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_TRUE) == EGL_TRUE;
    137 }
    138 
    139 bool GetWebGLContext(const egl::AttributeMap &attribs)
    140 {
    141    return (attribs.get(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE, EGL_FALSE) == EGL_TRUE);
    142 }
    143 
    144 Version GetClientVersion(egl::Display *display,
    145                         const egl::AttributeMap &attribs,
    146                         const EGLenum clientType)
    147 {
    148    Version requestedVersion =
    149        Version(GetClientMajorVersion(attribs), GetClientMinorVersion(attribs));
    150    if (GetBackwardCompatibleContext(attribs))
    151    {
    152        if (clientType == EGL_OPENGL_API)
    153        {
    154            Optional<gl::Version> maxSupportedDesktopVersion =
    155                display->getImplementation()->getMaxSupportedDesktopVersion();
    156            if (maxSupportedDesktopVersion.valid())
    157                return std::max(maxSupportedDesktopVersion.value(), requestedVersion);
    158            else
    159                return requestedVersion;
    160        }
    161        else if (requestedVersion.major == 1)
    162        {
    163            // If the user requests an ES1 context, we cannot return an ES 2+ context.
    164            return Version(1, 1);
    165        }
    166        else
    167        {
    168            // Always up the version to at least the max conformant version this display supports.
    169            // Only return a higher client version if requested.
    170            const Version conformantVersion = std::max(
    171                display->getImplementation()->getMaxConformantESVersion(), requestedVersion);
    172            // Limit the WebGL context to at most version 3.1
    173            const bool isWebGL = GetWebGLContext(attribs);
    174            return isWebGL ? std::min(conformantVersion, Version(3, 1)) : conformantVersion;
    175        }
    176    }
    177    else
    178    {
    179        return requestedVersion;
    180    }
    181 }
    182 
    183 EGLint GetProfileMask(const egl::AttributeMap &attribs)
    184 {
    185    return attribs.getAsInt(EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT);
    186 }
    187 
    188 GLenum GetResetStrategy(const egl::AttributeMap &attribs)
    189 {
    190    EGLAttrib resetStrategyExt =
    191        attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION);
    192    EGLAttrib resetStrategyCore =
    193        attribs.get(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY, resetStrategyExt);
    194 
    195    switch (resetStrategyCore)
    196    {
    197        case EGL_NO_RESET_NOTIFICATION:
    198            return GL_NO_RESET_NOTIFICATION_EXT;
    199        case EGL_LOSE_CONTEXT_ON_RESET:
    200            return GL_LOSE_CONTEXT_ON_RESET_EXT;
    201        default:
    202            UNREACHABLE();
    203            return GL_NONE;
    204    }
    205 }
    206 
    207 bool GetRobustAccess(const egl::AttributeMap &attribs)
    208 {
    209    EGLAttrib robustAccessExt  = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_FALSE);
    210    EGLAttrib robustAccessCore = attribs.get(EGL_CONTEXT_OPENGL_ROBUST_ACCESS, robustAccessExt);
    211 
    212    bool attribRobustAccess = (robustAccessCore == EGL_TRUE);
    213    bool contextFlagsRobustAccess =
    214        ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0);
    215 
    216    return (attribRobustAccess || contextFlagsRobustAccess);
    217 }
    218 
    219 bool GetDebug(const egl::AttributeMap &attribs)
    220 {
    221    return (attribs.get(EGL_CONTEXT_OPENGL_DEBUG, EGL_FALSE) == EGL_TRUE) ||
    222           ((attribs.get(EGL_CONTEXT_FLAGS_KHR, 0) & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0);
    223 }
    224 
    225 bool GetNoError(const egl::AttributeMap &attribs)
    226 {
    227    return (attribs.get(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, EGL_FALSE) == EGL_TRUE);
    228 }
    229 
    230 bool GetExtensionsEnabled(const egl::AttributeMap &attribs, bool webGLContext)
    231 {
    232    // If the context is WebGL, extensions are disabled by default
    233    EGLAttrib defaultValue = webGLContext ? EGL_FALSE : EGL_TRUE;
    234    return (attribs.get(EGL_EXTENSIONS_ENABLED_ANGLE, defaultValue) == EGL_TRUE);
    235 }
    236 
    237 bool GetBindGeneratesResource(const egl::AttributeMap &attribs)
    238 {
    239    return (attribs.get(EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE) == EGL_TRUE);
    240 }
    241 
    242 bool GetClientArraysEnabled(const egl::AttributeMap &attribs)
    243 {
    244    return (attribs.get(EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE) == EGL_TRUE);
    245 }
    246 
    247 bool GetRobustResourceInit(egl::Display *display, const egl::AttributeMap &attribs)
    248 {
    249    const angle::FrontendFeatures &frontendFeatures = display->getFrontendFeatures();
    250    return (frontendFeatures.forceRobustResourceInit.enabled ||
    251            attribs.get(EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE, EGL_FALSE) == EGL_TRUE);
    252 }
    253 
    254 EGLenum GetContextPriority(const egl::AttributeMap &attribs)
    255 {
    256    return static_cast<EGLenum>(
    257        attribs.getAsInt(EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_MEDIUM_IMG));
    258 }
    259 
    260 bool GetProtectedContent(const egl::AttributeMap &attribs)
    261 {
    262    return static_cast<bool>(attribs.getAsInt(EGL_PROTECTED_CONTENT_EXT, EGL_FALSE));
    263 }
    264 
    265 std::string GetObjectLabelFromPointer(GLsizei length, const GLchar *label)
    266 {
    267    std::string labelName;
    268    if (label != nullptr)
    269    {
    270        size_t labelLength = length < 0 ? strlen(label) : length;
    271        labelName          = std::string(label, labelLength);
    272    }
    273    return labelName;
    274 }
    275 
    276 void GetObjectLabelBase(const std::string &objectLabel,
    277                        GLsizei bufSize,
    278                        GLsizei *length,
    279                        GLchar *label)
    280 {
    281    size_t writeLength = objectLabel.length();
    282    if (label != nullptr && bufSize > 0)
    283    {
    284        writeLength = std::min(static_cast<size_t>(bufSize) - 1, objectLabel.length());
    285        std::copy(objectLabel.begin(), objectLabel.begin() + writeLength, label);
    286        label[writeLength] = '\0';
    287    }
    288 
    289    if (length != nullptr)
    290    {
    291        *length = static_cast<GLsizei>(writeLength);
    292    }
    293 }
    294 
    295 enum SubjectIndexes : angle::SubjectIndex
    296 {
    297    kTexture0SubjectIndex       = 0,
    298    kTextureMaxSubjectIndex     = kTexture0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
    299    kImage0SubjectIndex         = kTextureMaxSubjectIndex,
    300    kImageMaxSubjectIndex       = kImage0SubjectIndex + IMPLEMENTATION_MAX_IMAGE_UNITS,
    301    kUniformBuffer0SubjectIndex = kImageMaxSubjectIndex,
    302    kUniformBufferMaxSubjectIndex =
    303        kUniformBuffer0SubjectIndex + IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS,
    304    kAtomicCounterBuffer0SubjectIndex = kUniformBufferMaxSubjectIndex,
    305    kAtomicCounterBufferMaxSubjectIndex =
    306        kAtomicCounterBuffer0SubjectIndex + IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS,
    307    kShaderStorageBuffer0SubjectIndex = kAtomicCounterBufferMaxSubjectIndex,
    308    kShaderStorageBufferMaxSubjectIndex =
    309        kShaderStorageBuffer0SubjectIndex + IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
    310    kSampler0SubjectIndex    = kShaderStorageBufferMaxSubjectIndex,
    311    kSamplerMaxSubjectIndex  = kSampler0SubjectIndex + IMPLEMENTATION_MAX_ACTIVE_TEXTURES,
    312    kVertexArraySubjectIndex = kSamplerMaxSubjectIndex,
    313    kReadFramebufferSubjectIndex,
    314    kDrawFramebufferSubjectIndex,
    315    kProgramPipelineSubjectIndex,
    316 };
    317 
    318 bool IsClearBufferEnabled(const FramebufferState &fbState, GLenum buffer, GLint drawbuffer)
    319 {
    320    return buffer != GL_COLOR || fbState.getEnabledDrawBuffers()[drawbuffer];
    321 }
    322 
    323 bool IsEmptyScissor(const State &glState)
    324 {
    325    if (!glState.isScissorTestEnabled())
    326    {
    327        return false;
    328    }
    329 
    330    const Extents &dimensions = glState.getDrawFramebuffer()->getExtents();
    331    Rectangle framebufferArea(0, 0, dimensions.width, dimensions.height);
    332    return !ClipRectangle(framebufferArea, glState.getScissor(), nullptr);
    333 }
    334 
    335 bool IsColorMaskedOut(const BlendStateExt &blendStateExt, const GLint drawbuffer)
    336 {
    337    ASSERT(static_cast<size_t>(drawbuffer) < blendStateExt.getDrawBufferCount());
    338    return blendStateExt.getColorMaskIndexed(static_cast<size_t>(drawbuffer)) == 0;
    339 }
    340 
    341 bool GetIsExternal(const egl::AttributeMap &attribs)
    342 {
    343    return (attribs.get(EGL_EXTERNAL_CONTEXT_ANGLE, EGL_FALSE) == EGL_TRUE);
    344 }
    345 
    346 bool GetSaveAndRestoreState(const egl::AttributeMap &attribs)
    347 {
    348    return (attribs.get(EGL_EXTERNAL_CONTEXT_SAVE_STATE_ANGLE, EGL_FALSE) == EGL_TRUE);
    349 }
    350 
    351 void GetPerfMonitorString(const std::string &name,
    352                          GLsizei bufSize,
    353                          GLsizei *length,
    354                          GLchar *stringOut)
    355 {
    356    GLsizei numCharsWritten = std::min(bufSize, static_cast<GLsizei>(name.size()));
    357 
    358    if (length)
    359    {
    360        if (bufSize == 0)
    361        {
    362            *length = static_cast<GLsizei>(name.size());
    363        }
    364        else
    365        {
    366            // Excludes null terminator.
    367            ASSERT(numCharsWritten > 0);
    368            *length = numCharsWritten - 1;
    369        }
    370    }
    371 
    372    if (stringOut)
    373    {
    374        memcpy(stringOut, name.c_str(), numCharsWritten);
    375    }
    376 }
    377 
    378 bool CanSupportAEP(const gl::Version &version, const gl::Extensions &extensions)
    379 {
    380    // From the GL_ANDROID_extension_pack_es31a extension spec:
    381    // OpenGL ES 3.1 and GLSL ES 3.10 are required.
    382    // The following extensions are required:
    383    // * KHR_debug
    384    // * KHR_texture_compression_astc_ldr
    385    // * KHR_blend_equation_advanced
    386    // * OES_sample_shading
    387    // * OES_sample_variables
    388    // * OES_shader_image_atomic
    389    // * OES_shader_multisample_interpolation
    390    // * OES_texture_stencil8
    391    // * OES_texture_storage_multisample_2d_array
    392    // * EXT_copy_image
    393    // * EXT_draw_buffers_indexed
    394    // * EXT_geometry_shader
    395    // * EXT_gpu_shader5
    396    // * EXT_primitive_bounding_box
    397    // * EXT_shader_io_blocks
    398    // * EXT_tessellation_shader
    399    // * EXT_texture_border_clamp
    400    // * EXT_texture_buffer
    401    // * EXT_texture_cube_map_array
    402    // * EXT_texture_sRGB_decode
    403    return (version >= ES_3_1 && extensions.debugKHR && extensions.textureCompressionAstcLdrKHR &&
    404            extensions.blendEquationAdvancedKHR && extensions.sampleShadingOES &&
    405            extensions.sampleVariablesOES && extensions.shaderImageAtomicOES &&
    406            extensions.shaderMultisampleInterpolationOES && extensions.textureStencil8OES &&
    407            extensions.textureStorageMultisample2dArrayOES && extensions.copyImageEXT &&
    408            extensions.drawBuffersIndexedEXT && extensions.geometryShaderEXT &&
    409            extensions.gpuShader5EXT && extensions.primitiveBoundingBoxEXT &&
    410            extensions.shaderIoBlocksEXT && extensions.tessellationShaderEXT &&
    411            extensions.textureBorderClampEXT && extensions.textureBufferEXT &&
    412            extensions.textureCubeMapArrayEXT && extensions.textureSRGBDecodeEXT);
    413 }
    414 }  // anonymous namespace
    415 
    416 #if defined(ANGLE_PLATFORM_APPLE)
    417 // TODO(angleproject:6479): Due to a bug in Apple's dyld loader, `thread_local` will cause
    418 // excessive memory use. Temporarily avoid it by using pthread's thread
    419 // local storage instead.
    420 static TLSIndex GetCurrentValidContextTLSIndex()
    421 {
    422    static TLSIndex CurrentValidContextIndex = TLS_INVALID_INDEX;
    423    static dispatch_once_t once;
    424    dispatch_once(&once, ^{
    425      ASSERT(CurrentValidContextIndex == TLS_INVALID_INDEX);
    426      CurrentValidContextIndex = CreateTLSIndex(nullptr);
    427    });
    428    return CurrentValidContextIndex;
    429 }
    430 Context *GetCurrentValidContextTLS()
    431 {
    432    TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
    433    ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
    434    return static_cast<Context *>(GetTLSValue(CurrentValidContextIndex));
    435 }
    436 void SetCurrentValidContextTLS(Context *context)
    437 {
    438    TLSIndex CurrentValidContextIndex = GetCurrentValidContextTLSIndex();
    439    ASSERT(CurrentValidContextIndex != TLS_INVALID_INDEX);
    440    SetTLSValue(CurrentValidContextIndex, context);
    441 }
    442 #else
    443 thread_local Context *gCurrentValidContext = nullptr;
    444 #endif
    445 
    446 Context::Context(egl::Display *display,
    447                 const egl::Config *config,
    448                 const Context *shareContext,
    449                 TextureManager *shareTextures,
    450                 SemaphoreManager *shareSemaphores,
    451                 MemoryProgramCache *memoryProgramCache,
    452                 MemoryShaderCache *memoryShaderCache,
    453                 const EGLenum clientType,
    454                 const egl::AttributeMap &attribs,
    455                 const egl::DisplayExtensions &displayExtensions,
    456                 const egl::ClientExtensions &clientExtensions)
    457    : mState(shareContext ? &shareContext->mState : nullptr,
    458             AllocateOrGetShareGroup(display, shareContext),
    459             shareTextures,
    460             shareSemaphores,
    461             &mOverlay,
    462             clientType,
    463             GetClientVersion(display, attribs, clientType),
    464             GetProfileMask(attribs),
    465             GetDebug(attribs),
    466             GetBindGeneratesResource(attribs),
    467             GetClientArraysEnabled(attribs),
    468             GetRobustResourceInit(display, attribs),
    469             memoryProgramCache != nullptr,
    470             GetContextPriority(attribs),
    471             GetRobustAccess(attribs),
    472             GetProtectedContent(attribs)),
    473      mShared(shareContext != nullptr || shareTextures != nullptr || shareSemaphores != nullptr),
    474      mSkipValidation(GetNoError(attribs)),
    475      mDisplayTextureShareGroup(shareTextures != nullptr),
    476      mDisplaySemaphoreShareGroup(shareSemaphores != nullptr),
    477      mErrors(this),
    478      mImplementation(display->getImplementation()
    479                          ->createContext(mState, &mErrors, config, shareContext, attribs)),
    480      mLabel(nullptr),
    481      mCompiler(),
    482      mConfig(config),
    483      mHasBeenCurrent(false),
    484      mContextLost(false),
    485      mResetStatus(GraphicsResetStatus::NoError),
    486      mContextLostForced(false),
    487      mResetStrategy(GetResetStrategy(attribs)),
    488      mSurfacelessSupported(displayExtensions.surfacelessContext),
    489      mCurrentDrawSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
    490      mCurrentReadSurface(static_cast<egl::Surface *>(EGL_NO_SURFACE)),
    491      mDisplay(display),
    492      mWebGLContext(GetWebGLContext(attribs)),
    493      mBufferAccessValidationEnabled(false),
    494      mExtensionsEnabled(GetExtensionsEnabled(attribs, mWebGLContext)),
    495      mMemoryProgramCache(memoryProgramCache),
    496      mMemoryShaderCache(memoryShaderCache),
    497      mVertexArrayObserverBinding(this, kVertexArraySubjectIndex),
    498      mDrawFramebufferObserverBinding(this, kDrawFramebufferSubjectIndex),
    499      mReadFramebufferObserverBinding(this, kReadFramebufferSubjectIndex),
    500      mProgramPipelineObserverBinding(this, kProgramPipelineSubjectIndex),
    501      mSingleThreadPool(nullptr),
    502      mMultiThreadPool(nullptr),
    503      mFrameCapture(new angle::FrameCapture),
    504      mRefCount(0),
    505      mOverlay(mImplementation.get()),
    506      mIsExternal(GetIsExternal(attribs)),
    507      mSaveAndRestoreState(GetSaveAndRestoreState(attribs)),
    508      mIsDestroyed(false)
    509 {
    510    for (angle::SubjectIndex uboIndex = kUniformBuffer0SubjectIndex;
    511         uboIndex < kUniformBufferMaxSubjectIndex; ++uboIndex)
    512    {
    513        mUniformBufferObserverBindings.emplace_back(this, uboIndex);
    514    }
    515 
    516    for (angle::SubjectIndex acbIndex = kAtomicCounterBuffer0SubjectIndex;
    517         acbIndex < kAtomicCounterBufferMaxSubjectIndex; ++acbIndex)
    518    {
    519        mAtomicCounterBufferObserverBindings.emplace_back(this, acbIndex);
    520    }
    521 
    522    for (angle::SubjectIndex ssboIndex = kShaderStorageBuffer0SubjectIndex;
    523         ssboIndex < kShaderStorageBufferMaxSubjectIndex; ++ssboIndex)
    524    {
    525        mShaderStorageBufferObserverBindings.emplace_back(this, ssboIndex);
    526    }
    527 
    528    for (angle::SubjectIndex samplerIndex = kSampler0SubjectIndex;
    529         samplerIndex < kSamplerMaxSubjectIndex; ++samplerIndex)
    530    {
    531        mSamplerObserverBindings.emplace_back(this, samplerIndex);
    532    }
    533 
    534    for (angle::SubjectIndex imageIndex = kImage0SubjectIndex; imageIndex < kImageMaxSubjectIndex;
    535         ++imageIndex)
    536    {
    537        mImageObserverBindings.emplace_back(this, imageIndex);
    538    }
    539 
    540    // Implementations now require the display to be set at context creation.
    541    ASSERT(mDisplay);
    542 }
    543 
    544 egl::Error Context::initialize()
    545 {
    546    if (!mImplementation)
    547        return egl::Error(EGL_NOT_INITIALIZED, "native context creation failed");
    548    return egl::NoError();
    549 }
    550 
    551 void Context::initializeDefaultResources()
    552 {
    553    mImplementation->setMemoryProgramCache(mMemoryProgramCache);
    554 
    555    initCaps();
    556 
    557    mState.initialize(this);
    558 
    559    mDefaultFramebuffer = std::make_unique<Framebuffer>(this, mImplementation.get());
    560 
    561    mFenceNVHandleAllocator.setBaseHandle(0);
    562 
    563    // [OpenGL ES 2.0.24] section 3.7 page 83:
    564    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have two-dimensional
    565    // and cube map texture state vectors respectively associated with them.
    566    // In order that access to these initial textures not be lost, they are treated as texture
    567    // objects all of whose names are 0.
    568 
    569    Texture *zeroTexture2D = new Texture(mImplementation.get(), {0}, TextureType::_2D);
    570    mZeroTextures[TextureType::_2D].set(this, zeroTexture2D);
    571 
    572    Texture *zeroTextureCube = new Texture(mImplementation.get(), {0}, TextureType::CubeMap);
    573    mZeroTextures[TextureType::CubeMap].set(this, zeroTextureCube);
    574 
    575    if (getClientVersion() >= Version(3, 0) || mSupportedExtensions.texture3DOES)
    576    {
    577        Texture *zeroTexture3D = new Texture(mImplementation.get(), {0}, TextureType::_3D);
    578        mZeroTextures[TextureType::_3D].set(this, zeroTexture3D);
    579    }
    580    if (getClientVersion() >= Version(3, 0))
    581    {
    582        Texture *zeroTexture2DArray =
    583            new Texture(mImplementation.get(), {0}, TextureType::_2DArray);
    584        mZeroTextures[TextureType::_2DArray].set(this, zeroTexture2DArray);
    585    }
    586    if (getClientVersion() >= Version(3, 1) || mSupportedExtensions.textureMultisampleANGLE)
    587    {
    588        Texture *zeroTexture2DMultisample =
    589            new Texture(mImplementation.get(), {0}, TextureType::_2DMultisample);
    590        mZeroTextures[TextureType::_2DMultisample].set(this, zeroTexture2DMultisample);
    591    }
    592    if (getClientVersion() >= Version(3, 1))
    593    {
    594        Texture *zeroTexture2DMultisampleArray =
    595            new Texture(mImplementation.get(), {0}, TextureType::_2DMultisampleArray);
    596        mZeroTextures[TextureType::_2DMultisampleArray].set(this, zeroTexture2DMultisampleArray);
    597 
    598        for (int i = 0; i < mState.mCaps.maxAtomicCounterBufferBindings; i++)
    599        {
    600            bindBufferRange(BufferBinding::AtomicCounter, i, {0}, 0, 0);
    601        }
    602 
    603        for (int i = 0; i < mState.mCaps.maxShaderStorageBufferBindings; i++)
    604        {
    605            bindBufferRange(BufferBinding::ShaderStorage, i, {0}, 0, 0);
    606        }
    607    }
    608 
    609    if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) ||
    610        mSupportedExtensions.textureCubeMapArrayAny())
    611    {
    612        Texture *zeroTextureCubeMapArray =
    613            new Texture(mImplementation.get(), {0}, TextureType::CubeMapArray);
    614        mZeroTextures[TextureType::CubeMapArray].set(this, zeroTextureCubeMapArray);
    615    }
    616 
    617    if ((getClientType() != EGL_OPENGL_API && getClientVersion() >= Version(3, 2)) ||
    618        mSupportedExtensions.textureBufferAny())
    619    {
    620        Texture *zeroTextureBuffer = new Texture(mImplementation.get(), {0}, TextureType::Buffer);
    621        mZeroTextures[TextureType::Buffer].set(this, zeroTextureBuffer);
    622    }
    623 
    624    if (mSupportedExtensions.textureRectangleANGLE)
    625    {
    626        Texture *zeroTextureRectangle =
    627            new Texture(mImplementation.get(), {0}, TextureType::Rectangle);
    628        mZeroTextures[TextureType::Rectangle].set(this, zeroTextureRectangle);
    629    }
    630 
    631    if (mSupportedExtensions.EGLImageExternalOES ||
    632        mSupportedExtensions.EGLStreamConsumerExternalNV)
    633    {
    634        Texture *zeroTextureExternal =
    635            new Texture(mImplementation.get(), {0}, TextureType::External);
    636        mZeroTextures[TextureType::External].set(this, zeroTextureExternal);
    637    }
    638 
    639    // This may change native TEXTURE_2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE,
    640    // binding states. Ensure state manager is aware of this when binding
    641    // this texture type.
    642    if (mSupportedExtensions.videoTextureWEBGL)
    643    {
    644        Texture *zeroTextureVideoImage =
    645            new Texture(mImplementation.get(), {0}, TextureType::VideoImage);
    646        mZeroTextures[TextureType::VideoImage].set(this, zeroTextureVideoImage);
    647    }
    648 
    649    mState.initializeZeroTextures(this, mZeroTextures);
    650 
    651    ANGLE_CONTEXT_TRY(mImplementation->initialize());
    652 
    653    // Add context into the share group
    654    mState.getShareGroup()->addSharedContext(this);
    655 
    656    bindVertexArray({0});
    657 
    658    if (getClientVersion() >= Version(3, 0))
    659    {
    660        // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
    661        // In the initial state, a default transform feedback object is bound and treated as
    662        // a transform feedback object with a name of zero. That object is bound any time
    663        // BindTransformFeedback is called with id of zero
    664        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
    665    }
    666 
    667    for (auto type : angle::AllEnums<BufferBinding>())
    668    {
    669        bindBuffer(type, {0});
    670    }
    671 
    672    bindRenderbuffer(GL_RENDERBUFFER, {0});
    673 
    674    for (int i = 0; i < mState.mCaps.maxUniformBufferBindings; i++)
    675    {
    676        bindBufferRange(BufferBinding::Uniform, i, {0}, 0, -1);
    677    }
    678 
    679    // Initialize GLES1 renderer if appropriate.
    680    if (getClientVersion() < Version(2, 0))
    681    {
    682        mGLES1Renderer.reset(new GLES1Renderer());
    683    }
    684 
    685    // Initialize dirty bit masks
    686    mAllDirtyBits.set();
    687 
    688    mDrawDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES);
    689    mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
    690    mDrawDirtyObjects.set(State::DIRTY_OBJECT_VERTEX_ARRAY);
    691    mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
    692    mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
    693    mDrawDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
    694    mDrawDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
    695    mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
    696 
    697    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_STATE);
    698    mTexImageDirtyBits.set(State::DIRTY_BIT_UNPACK_BUFFER_BINDING);
    699    mTexImageDirtyBits.set(State::DIRTY_BIT_EXTENDED);
    700    // No dirty objects.
    701 
    702    // Readpixels uses the pack state and read FBO
    703    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_STATE);
    704    mReadPixelsDirtyBits.set(State::DIRTY_BIT_PACK_BUFFER_BINDING);
    705    mReadPixelsDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    706    mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
    707 
    708    mClearDirtyBits.set(State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
    709    mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
    710    mClearDirtyBits.set(State::DIRTY_BIT_SCISSOR);
    711    mClearDirtyBits.set(State::DIRTY_BIT_VIEWPORT);
    712    mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_COLOR);
    713    mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_DEPTH);
    714    mClearDirtyBits.set(State::DIRTY_BIT_CLEAR_STENCIL);
    715    mClearDirtyBits.set(State::DIRTY_BIT_COLOR_MASK);
    716    mClearDirtyBits.set(State::DIRTY_BIT_DEPTH_MASK);
    717    mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
    718    mClearDirtyBits.set(State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
    719    mClearDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    720    mClearDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
    721 
    722    // We sync the draw Framebuffer manually in prepareForClear to allow the clear calls to do
    723    // more custom handling for robust resource init.
    724 
    725    mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
    726    mBlitDirtyBits.set(State::DIRTY_BIT_SCISSOR);
    727    mBlitDirtyBits.set(State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
    728    mBlitDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    729    mBlitDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    730    mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
    731    mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
    732 
    733    mComputeDirtyBits.set(State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
    734    mComputeDirtyBits.set(State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
    735    mComputeDirtyBits.set(State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
    736    mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_BINDING);
    737    mComputeDirtyBits.set(State::DIRTY_BIT_PROGRAM_EXECUTABLE);
    738    mComputeDirtyBits.set(State::DIRTY_BIT_TEXTURE_BINDINGS);
    739    mComputeDirtyBits.set(State::DIRTY_BIT_SAMPLER_BINDINGS);
    740    mComputeDirtyBits.set(State::DIRTY_BIT_IMAGE_BINDINGS);
    741    mComputeDirtyBits.set(State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
    742    mComputeDirtyObjects.set(State::DIRTY_OBJECT_ACTIVE_TEXTURES);
    743    mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES);
    744    mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM);
    745    mComputeDirtyObjects.set(State::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
    746    mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES);
    747    mComputeDirtyObjects.set(State::DIRTY_OBJECT_SAMPLERS);
    748 
    749    mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    750    mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_FRAMEBUFFER);
    751 
    752    mReadInvalidateDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
    753    mDrawInvalidateDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
    754 
    755    mOverlay.init();
    756 }
    757 
    758 egl::Error Context::onDestroy(const egl::Display *display)
    759 {
    760    if (!mHasBeenCurrent)
    761    {
    762        // The context is never current, so default resources are not allocated.
    763        return egl::NoError();
    764    }
    765 
    766    // eglDestoryContext() must have been called for this Context and there must not be any Threads
    767    // that still have it current.
    768    ASSERT(mIsDestroyed == true && mRefCount == 0);
    769 
    770    // Dump frame capture if enabled.
    771    getShareGroup()->getFrameCaptureShared()->onDestroyContext(this);
    772 
    773    // Remove context from the capture share group
    774    getShareGroup()->removeSharedContext(this);
    775 
    776    if (mGLES1Renderer)
    777    {
    778        mGLES1Renderer->onDestroy(this, &mState);
    779    }
    780 
    781    ANGLE_TRY(unMakeCurrent(display));
    782 
    783    mDefaultFramebuffer->onDestroy(this);
    784    mDefaultFramebuffer.reset();
    785 
    786    for (auto fence : mFenceNVMap)
    787    {
    788        if (fence.second)
    789        {
    790            fence.second->onDestroy(this);
    791        }
    792        SafeDelete(fence.second);
    793    }
    794    mFenceNVMap.clear();
    795 
    796    for (auto query : mQueryMap)
    797    {
    798        if (query.second != nullptr)
    799        {
    800            query.second->release(this);
    801        }
    802    }
    803    mQueryMap.clear();
    804 
    805    for (auto vertexArray : mVertexArrayMap)
    806    {
    807        if (vertexArray.second)
    808        {
    809            vertexArray.second->onDestroy(this);
    810        }
    811    }
    812    mVertexArrayMap.clear();
    813 
    814    for (auto transformFeedback : mTransformFeedbackMap)
    815    {
    816        if (transformFeedback.second != nullptr)
    817        {
    818            transformFeedback.second->release(this);
    819        }
    820    }
    821    mTransformFeedbackMap.clear();
    822 
    823    for (BindingPointer<Texture> &zeroTexture : mZeroTextures)
    824    {
    825        if (zeroTexture.get() != nullptr)
    826        {
    827            zeroTexture.set(this, nullptr);
    828        }
    829    }
    830 
    831    releaseShaderCompiler();
    832 
    833    mState.reset(this);
    834 
    835    mState.mBufferManager->release(this);
    836    // mProgramPipelineManager must be before mShaderProgramManager to give each
    837    // PPO the chance to release any references they have to the Programs that
    838    // are bound to them before the Programs are released()'ed.
    839    mState.mProgramPipelineManager->release(this);
    840    mState.mShaderProgramManager->release(this);
    841    mState.mTextureManager->release(this);
    842    mState.mRenderbufferManager->release(this);
    843    mState.mSamplerManager->release(this);
    844    mState.mSyncManager->release(this);
    845    mState.mFramebufferManager->release(this);
    846    mState.mMemoryObjectManager->release(this);
    847    mState.mSemaphoreManager->release(this);
    848 
    849    mSingleThreadPool.reset();
    850    mMultiThreadPool.reset();
    851 
    852    mImplementation->onDestroy(this);
    853 
    854    // Backend requires implementation to be destroyed first to close down all the objects
    855    mState.mShareGroup->release(display);
    856 
    857    mOverlay.destroy(this);
    858 
    859    return egl::NoError();
    860 }
    861 
    862 Context::~Context() {}
    863 
    864 void Context::setLabel(EGLLabelKHR label)
    865 {
    866    mLabel = label;
    867 }
    868 
    869 EGLLabelKHR Context::getLabel() const
    870 {
    871    return mLabel;
    872 }
    873 
    874 egl::Error Context::makeCurrent(egl::Display *display,
    875                                egl::Surface *drawSurface,
    876                                egl::Surface *readSurface)
    877 {
    878    mDisplay = display;
    879 
    880    if (!mHasBeenCurrent)
    881    {
    882        initializeDefaultResources();
    883        initRendererString();
    884        initVersionStrings();
    885        initExtensionStrings();
    886 
    887        int width  = 0;
    888        int height = 0;
    889        if (drawSurface != nullptr)
    890        {
    891            width  = drawSurface->getWidth();
    892            height = drawSurface->getHeight();
    893        }
    894 
    895        mState.setViewportParams(0, 0, width, height);
    896        mState.setScissorParams(0, 0, width, height);
    897 
    898        mHasBeenCurrent = true;
    899    }
    900 
    901    ANGLE_TRY(unsetDefaultFramebuffer());
    902 
    903    getShareGroup()->getFrameCaptureShared()->onMakeCurrent(this, drawSurface);
    904 
    905    // TODO(jmadill): Rework this when we support ContextImpl
    906    mState.setAllDirtyBits();
    907    mState.setAllDirtyObjects();
    908 
    909    ANGLE_TRY(setDefaultFramebuffer(drawSurface, readSurface));
    910 
    911    // Notify the renderer of a context switch.
    912    angle::Result implResult = mImplementation->onMakeCurrent(this);
    913 
    914    // If the implementation fails onMakeCurrent, unset the default framebuffer.
    915    if (implResult != angle::Result::Continue)
    916    {
    917        ANGLE_TRY(unsetDefaultFramebuffer());
    918        return angle::ResultToEGL(implResult);
    919    }
    920 
    921    return egl::NoError();
    922 }
    923 
    924 egl::Error Context::unMakeCurrent(const egl::Display *display)
    925 {
    926    ANGLE_TRY(angle::ResultToEGL(mImplementation->onUnMakeCurrent(this)));
    927 
    928    ANGLE_TRY(unsetDefaultFramebuffer());
    929 
    930    // Return the scratch buffers to the display so they can be shared with other contexts while
    931    // this one is not current.
    932    if (mScratchBuffer.valid())
    933    {
    934        mDisplay->returnScratchBuffer(mScratchBuffer.release());
    935    }
    936    if (mZeroFilledBuffer.valid())
    937    {
    938        mDisplay->returnZeroFilledBuffer(mZeroFilledBuffer.release());
    939    }
    940 
    941    return egl::NoError();
    942 }
    943 
    944 BufferID Context::createBuffer()
    945 {
    946    return mState.mBufferManager->createBuffer();
    947 }
    948 
    949 GLuint Context::createProgram()
    950 {
    951    return mState.mShaderProgramManager->createProgram(mImplementation.get()).value;
    952 }
    953 
    954 GLuint Context::createShader(ShaderType type)
    955 {
    956    return mState.mShaderProgramManager
    957        ->createShader(mImplementation.get(), mState.mLimitations, type)
    958        .value;
    959 }
    960 
    961 TextureID Context::createTexture()
    962 {
    963    return mState.mTextureManager->createTexture();
    964 }
    965 
    966 RenderbufferID Context::createRenderbuffer()
    967 {
    968    return mState.mRenderbufferManager->createRenderbuffer();
    969 }
    970 
    971 // Returns an unused framebuffer name
    972 FramebufferID Context::createFramebuffer()
    973 {
    974    return mState.mFramebufferManager->createFramebuffer();
    975 }
    976 
    977 void Context::genFencesNV(GLsizei n, FenceNVID *fences)
    978 {
    979    for (int i = 0; i < n; i++)
    980    {
    981        GLuint handle = mFenceNVHandleAllocator.allocate();
    982        mFenceNVMap.assign({handle}, new FenceNV(mImplementation.get()));
    983        fences[i] = {handle};
    984    }
    985 }
    986 
    987 ProgramPipelineID Context::createProgramPipeline()
    988 {
    989    return mState.mProgramPipelineManager->createProgramPipeline();
    990 }
    991 
    992 GLuint Context::createShaderProgramv(ShaderType type, GLsizei count, const GLchar *const *strings)
    993 {
    994    const ShaderProgramID shaderID = PackParam<ShaderProgramID>(createShader(type));
    995    if (shaderID.value)
    996    {
    997        Shader *shaderObject = getShader(shaderID);
    998        ASSERT(shaderObject);
    999        shaderObject->setSource(count, strings, nullptr);
   1000        shaderObject->compile(this);
   1001        const ShaderProgramID programID = PackParam<ShaderProgramID>(createProgram());
   1002        if (programID.value)
   1003        {
   1004            gl::Program *programObject = getProgramNoResolveLink(programID);
   1005            ASSERT(programObject);
   1006 
   1007            if (shaderObject->isCompiled(this))
   1008            {
   1009                // As per Khronos issue 2261:
   1010                // https://gitlab.khronos.org/Tracker/vk-gl-cts/issues/2261
   1011                // We must wait to mark the program separable until it's successfully compiled.
   1012                programObject->setSeparable(true);
   1013 
   1014                programObject->attachShader(shaderObject);
   1015 
   1016                if (programObject->link(this) != angle::Result::Continue)
   1017                {
   1018                    deleteShader(shaderID);
   1019                    deleteProgram(programID);
   1020                    return 0u;
   1021                }
   1022                if (onProgramLink(programObject) != angle::Result::Continue)
   1023                {
   1024                    deleteShader(shaderID);
   1025                    deleteProgram(programID);
   1026                    return 0u;
   1027                }
   1028 
   1029                programObject->detachShader(this, shaderObject);
   1030            }
   1031 
   1032            InfoLog &programInfoLog = programObject->getExecutable().getInfoLog();
   1033            programInfoLog << shaderObject->getInfoLogString();
   1034        }
   1035 
   1036        deleteShader(shaderID);
   1037 
   1038        return programID.value;
   1039    }
   1040 
   1041    return 0u;
   1042 }
   1043 
   1044 MemoryObjectID Context::createMemoryObject()
   1045 {
   1046    return mState.mMemoryObjectManager->createMemoryObject(mImplementation.get());
   1047 }
   1048 
   1049 SemaphoreID Context::createSemaphore()
   1050 {
   1051    return mState.mSemaphoreManager->createSemaphore(mImplementation.get());
   1052 }
   1053 
   1054 void Context::deleteBuffer(BufferID bufferName)
   1055 {
   1056    Buffer *buffer = mState.mBufferManager->getBuffer(bufferName);
   1057    if (buffer)
   1058    {
   1059        detachBuffer(buffer);
   1060    }
   1061 
   1062    mState.mBufferManager->deleteObject(this, bufferName);
   1063 }
   1064 
   1065 void Context::deleteShader(ShaderProgramID shader)
   1066 {
   1067    mState.mShaderProgramManager->deleteShader(this, shader);
   1068 }
   1069 
   1070 void Context::deleteProgram(ShaderProgramID program)
   1071 {
   1072    mState.mShaderProgramManager->deleteProgram(this, program);
   1073 }
   1074 
   1075 void Context::deleteTexture(TextureID texture)
   1076 {
   1077    if (mState.mTextureManager->getTexture(texture))
   1078    {
   1079        detachTexture(texture);
   1080    }
   1081 
   1082    mState.mTextureManager->deleteObject(this, texture);
   1083 }
   1084 
   1085 void Context::deleteRenderbuffer(RenderbufferID renderbuffer)
   1086 {
   1087    if (mState.mRenderbufferManager->getRenderbuffer(renderbuffer))
   1088    {
   1089        detachRenderbuffer(renderbuffer);
   1090    }
   1091 
   1092    mState.mRenderbufferManager->deleteObject(this, renderbuffer);
   1093 }
   1094 
   1095 void Context::deleteSync(GLsync sync)
   1096 {
   1097    // The spec specifies the underlying Fence object is not deleted until all current
   1098    // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
   1099    // and since our API is currently designed for being called from a single thread, we can delete
   1100    // the fence immediately.
   1101    mState.mSyncManager->deleteObject(this, static_cast<GLuint>(reinterpret_cast<uintptr_t>(sync)));
   1102 }
   1103 
   1104 void Context::deleteProgramPipeline(ProgramPipelineID pipelineID)
   1105 {
   1106    ProgramPipeline *pipeline = mState.mProgramPipelineManager->getProgramPipeline(pipelineID);
   1107    if (pipeline)
   1108    {
   1109        detachProgramPipeline(pipelineID);
   1110    }
   1111 
   1112    mState.mProgramPipelineManager->deleteObject(this, pipelineID);
   1113 }
   1114 
   1115 void Context::deleteMemoryObject(MemoryObjectID memoryObject)
   1116 {
   1117    mState.mMemoryObjectManager->deleteMemoryObject(this, memoryObject);
   1118 }
   1119 
   1120 void Context::deleteSemaphore(SemaphoreID semaphore)
   1121 {
   1122    mState.mSemaphoreManager->deleteSemaphore(this, semaphore);
   1123 }
   1124 
   1125 // GL_CHROMIUM_lose_context
   1126 void Context::loseContext(GraphicsResetStatus current, GraphicsResetStatus other)
   1127 {
   1128    // TODO(geofflang): mark the rest of the share group lost. Requires access to the entire share
   1129    // group from a context. http://anglebug.com/3379
   1130    markContextLost(current);
   1131 }
   1132 
   1133 void Context::deleteFramebuffer(FramebufferID framebufferID)
   1134 {
   1135    // We are responsible for deleting the GL objects from the Framebuffer's pixel local storage.
   1136    std::unique_ptr<PixelLocalStorage> plsToDelete;
   1137 
   1138    Framebuffer *framebuffer = mState.mFramebufferManager->getFramebuffer(framebufferID);
   1139    if (framebuffer)
   1140    {
   1141        plsToDelete = framebuffer->detachPixelLocalStorage();
   1142        detachFramebuffer(framebufferID);
   1143    }
   1144 
   1145    mState.mFramebufferManager->deleteObject(this, framebufferID);
   1146 
   1147    // Delete the pixel local storage GL objects after the framebuffer, in order to avoid any
   1148    // potential trickyness with orphaning.
   1149    if (plsToDelete)
   1150    {
   1151        plsToDelete->deleteContextObjects(this);
   1152    }
   1153 }
   1154 
   1155 void Context::deleteFencesNV(GLsizei n, const FenceNVID *fences)
   1156 {
   1157    for (int i = 0; i < n; i++)
   1158    {
   1159        FenceNVID fence = fences[i];
   1160 
   1161        FenceNV *fenceObject = nullptr;
   1162        if (mFenceNVMap.erase(fence, &fenceObject))
   1163        {
   1164            mFenceNVHandleAllocator.release(fence.value);
   1165            if (fenceObject)
   1166            {
   1167                fenceObject->onDestroy(this);
   1168            }
   1169            delete fenceObject;
   1170        }
   1171    }
   1172 }
   1173 
   1174 Buffer *Context::getBuffer(BufferID handle) const
   1175 {
   1176    return mState.mBufferManager->getBuffer(handle);
   1177 }
   1178 
   1179 Renderbuffer *Context::getRenderbuffer(RenderbufferID handle) const
   1180 {
   1181    return mState.mRenderbufferManager->getRenderbuffer(handle);
   1182 }
   1183 
   1184 EGLenum Context::getContextPriority() const
   1185 {
   1186    return egl::ToEGLenum(mImplementation->getContextPriority());
   1187 }
   1188 
   1189 Sync *Context::getSync(GLsync handle) const
   1190 {
   1191    return mState.mSyncManager->getSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
   1192 }
   1193 
   1194 VertexArray *Context::getVertexArray(VertexArrayID handle) const
   1195 {
   1196    return mVertexArrayMap.query(handle);
   1197 }
   1198 
   1199 Sampler *Context::getSampler(SamplerID handle) const
   1200 {
   1201    return mState.mSamplerManager->getSampler(handle);
   1202 }
   1203 
   1204 TransformFeedback *Context::getTransformFeedback(TransformFeedbackID handle) const
   1205 {
   1206    return mTransformFeedbackMap.query(handle);
   1207 }
   1208 
   1209 ProgramPipeline *Context::getProgramPipeline(ProgramPipelineID handle) const
   1210 {
   1211    return mState.mProgramPipelineManager->getProgramPipeline(handle);
   1212 }
   1213 
   1214 gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) const
   1215 {
   1216    switch (identifier)
   1217    {
   1218        case GL_BUFFER:
   1219        case GL_BUFFER_OBJECT_EXT:
   1220            return getBuffer({name});
   1221        case GL_SHADER:
   1222        case GL_SHADER_OBJECT_EXT:
   1223            return getShader({name});
   1224        case GL_PROGRAM:
   1225        case GL_PROGRAM_OBJECT_EXT:
   1226            return getProgramNoResolveLink({name});
   1227        case GL_VERTEX_ARRAY:
   1228        case GL_VERTEX_ARRAY_OBJECT_EXT:
   1229            return getVertexArray({name});
   1230        case GL_QUERY:
   1231        case GL_QUERY_OBJECT_EXT:
   1232            return getQuery({name});
   1233        case GL_TRANSFORM_FEEDBACK:
   1234            return getTransformFeedback({name});
   1235        case GL_SAMPLER:
   1236            return getSampler({name});
   1237        case GL_TEXTURE:
   1238            return getTexture({name});
   1239        case GL_RENDERBUFFER:
   1240            return getRenderbuffer({name});
   1241        case GL_FRAMEBUFFER:
   1242            return getFramebuffer({name});
   1243        case GL_PROGRAM_PIPELINE:
   1244        case GL_PROGRAM_PIPELINE_OBJECT_EXT:
   1245            return getProgramPipeline({name});
   1246        default:
   1247            UNREACHABLE();
   1248            return nullptr;
   1249    }
   1250 }
   1251 
   1252 gl::LabeledObject *Context::getLabeledObjectFromPtr(const void *ptr) const
   1253 {
   1254    return getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr)));
   1255 }
   1256 
   1257 void Context::objectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label)
   1258 {
   1259    gl::LabeledObject *object = getLabeledObject(identifier, name);
   1260    ASSERT(object != nullptr);
   1261 
   1262    std::string labelName = GetObjectLabelFromPointer(length, label);
   1263    ANGLE_CONTEXT_TRY(object->setLabel(this, labelName));
   1264 
   1265    // TODO(jmadill): Determine if the object is dirty based on 'name'. Conservatively assume the
   1266    // specified object is active until we do this.
   1267    mState.setObjectDirty(identifier);
   1268 }
   1269 
   1270 void Context::labelObject(GLenum type, GLuint object, GLsizei length, const GLchar *label)
   1271 {
   1272    gl::LabeledObject *obj = getLabeledObject(type, object);
   1273    ASSERT(obj != nullptr);
   1274 
   1275    std::string labelName = "";
   1276    if (label != nullptr)
   1277    {
   1278        size_t labelLength = length == 0 ? strlen(label) : length;
   1279        labelName          = std::string(label, labelLength);
   1280    }
   1281    ANGLE_CONTEXT_TRY(obj->setLabel(this, labelName));
   1282    mState.setObjectDirty(type);
   1283 }
   1284 
   1285 void Context::objectPtrLabel(const void *ptr, GLsizei length, const GLchar *label)
   1286 {
   1287    gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
   1288    ASSERT(object != nullptr);
   1289 
   1290    std::string labelName = GetObjectLabelFromPointer(length, label);
   1291    ANGLE_CONTEXT_TRY(object->setLabel(this, labelName));
   1292 }
   1293 
   1294 void Context::getObjectLabel(GLenum identifier,
   1295                             GLuint name,
   1296                             GLsizei bufSize,
   1297                             GLsizei *length,
   1298                             GLchar *label)
   1299 {
   1300    gl::LabeledObject *object = getLabeledObject(identifier, name);
   1301    ASSERT(object != nullptr);
   1302 
   1303    const std::string &objectLabel = object->getLabel();
   1304    GetObjectLabelBase(objectLabel, bufSize, length, label);
   1305 }
   1306 
   1307 void Context::getObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label)
   1308 {
   1309    gl::LabeledObject *object = getLabeledObjectFromPtr(ptr);
   1310    ASSERT(object != nullptr);
   1311 
   1312    const std::string &objectLabel = object->getLabel();
   1313    GetObjectLabelBase(objectLabel, bufSize, length, label);
   1314 }
   1315 
   1316 GLboolean Context::isSampler(SamplerID samplerName) const
   1317 {
   1318    return mState.mSamplerManager->isSampler(samplerName);
   1319 }
   1320 
   1321 void Context::bindTexture(TextureType target, TextureID handle)
   1322 {
   1323    // Some apps enable KHR_create_context_no_error but pass in an invalid texture type.
   1324    // Workaround this by silently returning in such situations.
   1325    if (target == TextureType::InvalidEnum)
   1326    {
   1327        return;
   1328    }
   1329 
   1330    Texture *texture = nullptr;
   1331    if (handle.value == 0)
   1332    {
   1333        texture = mZeroTextures[target].get();
   1334    }
   1335    else
   1336    {
   1337        texture =
   1338            mState.mTextureManager->checkTextureAllocation(mImplementation.get(), handle, target);
   1339    }
   1340 
   1341    ASSERT(texture);
   1342    // Early return if rebinding the same texture
   1343    if (texture == mState.getTargetTexture(target))
   1344    {
   1345        return;
   1346    }
   1347 
   1348    mState.setSamplerTexture(this, target, texture);
   1349    mStateCache.onActiveTextureChange(this);
   1350 }
   1351 
   1352 void Context::bindReadFramebuffer(FramebufferID framebufferHandle)
   1353 {
   1354    Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
   1355        mImplementation.get(), this, framebufferHandle);
   1356    mState.setReadFramebufferBinding(framebuffer);
   1357    mReadFramebufferObserverBinding.bind(framebuffer);
   1358 }
   1359 
   1360 void Context::bindDrawFramebuffer(FramebufferID framebufferHandle)
   1361 {
   1362    Framebuffer *framebuffer = mState.mFramebufferManager->checkFramebufferAllocation(
   1363        mImplementation.get(), this, framebufferHandle);
   1364    mState.setDrawFramebufferBinding(framebuffer);
   1365    mDrawFramebufferObserverBinding.bind(framebuffer);
   1366    mStateCache.onDrawFramebufferChange(this);
   1367 }
   1368 
   1369 void Context::bindVertexArray(VertexArrayID vertexArrayHandle)
   1370 {
   1371    VertexArray *vertexArray = checkVertexArrayAllocation(vertexArrayHandle);
   1372    mState.setVertexArrayBinding(this, vertexArray);
   1373    mVertexArrayObserverBinding.bind(vertexArray);
   1374    mStateCache.onVertexArrayBindingChange(this);
   1375 }
   1376 
   1377 void Context::bindVertexBuffer(GLuint bindingIndex,
   1378                               BufferID bufferHandle,
   1379                               GLintptr offset,
   1380                               GLsizei stride)
   1381 {
   1382    Buffer *buffer =
   1383        mState.mBufferManager->checkBufferAllocation(mImplementation.get(), bufferHandle);
   1384    mState.bindVertexBuffer(this, bindingIndex, buffer, offset, stride);
   1385    mStateCache.onVertexArrayStateChange(this);
   1386 }
   1387 
   1388 void Context::bindSampler(GLuint textureUnit, SamplerID samplerHandle)
   1389 {
   1390    ASSERT(textureUnit < static_cast<GLuint>(mState.mCaps.maxCombinedTextureImageUnits));
   1391    Sampler *sampler =
   1392        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), samplerHandle);
   1393 
   1394    // Early return if rebinding the same sampler
   1395    if (sampler == mState.getSampler(textureUnit))
   1396    {
   1397        return;
   1398    }
   1399 
   1400    mState.setSamplerBinding(this, textureUnit, sampler);
   1401    mSamplerObserverBindings[textureUnit].bind(sampler);
   1402    mStateCache.onActiveTextureChange(this);
   1403 }
   1404 
   1405 void Context::bindImageTexture(GLuint unit,
   1406                               TextureID texture,
   1407                               GLint level,
   1408                               GLboolean layered,
   1409                               GLint layer,
   1410                               GLenum access,
   1411                               GLenum format)
   1412 {
   1413    Texture *tex = mState.mTextureManager->getTexture(texture);
   1414    mState.setImageUnit(this, unit, tex, level, layered, layer, access, format);
   1415    mImageObserverBindings[unit].bind(tex);
   1416 }
   1417 
   1418 void Context::useProgram(ShaderProgramID program)
   1419 {
   1420    ANGLE_CONTEXT_TRY(mState.setProgram(this, getProgramResolveLink(program)));
   1421    mStateCache.onProgramExecutableChange(this);
   1422 }
   1423 
   1424 void Context::useProgramStages(ProgramPipelineID pipeline,
   1425                               GLbitfield stages,
   1426                               ShaderProgramID program)
   1427 {
   1428    Program *shaderProgram = getProgramNoResolveLink(program);
   1429    ProgramPipeline *programPipeline =
   1430        mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
   1431                                                                       pipeline);
   1432 
   1433    ASSERT(programPipeline);
   1434    ANGLE_CONTEXT_TRY(programPipeline->useProgramStages(this, stages, shaderProgram));
   1435 }
   1436 
   1437 void Context::bindTransformFeedback(GLenum target, TransformFeedbackID transformFeedbackHandle)
   1438 {
   1439    ASSERT(target == GL_TRANSFORM_FEEDBACK);
   1440    TransformFeedback *transformFeedback =
   1441        checkTransformFeedbackAllocation(transformFeedbackHandle);
   1442    mState.setTransformFeedbackBinding(this, transformFeedback);
   1443    mStateCache.onActiveTransformFeedbackChange(this);
   1444 }
   1445 
   1446 void Context::bindProgramPipeline(ProgramPipelineID pipelineHandle)
   1447 {
   1448    ProgramPipeline *pipeline = mState.mProgramPipelineManager->checkProgramPipelineAllocation(
   1449        mImplementation.get(), pipelineHandle);
   1450    ANGLE_CONTEXT_TRY(mState.setProgramPipelineBinding(this, pipeline));
   1451    mStateCache.onProgramExecutableChange(this);
   1452    mProgramPipelineObserverBinding.bind(pipeline);
   1453 }
   1454 
   1455 void Context::beginQuery(QueryType target, QueryID query)
   1456 {
   1457    Query *queryObject = getOrCreateQuery(query, target);
   1458    ASSERT(queryObject);
   1459 
   1460    // begin query
   1461    ANGLE_CONTEXT_TRY(queryObject->begin(this));
   1462 
   1463    // set query as active for specified target only if begin succeeded
   1464    mState.setActiveQuery(this, target, queryObject);
   1465    mStateCache.onQueryChange(this);
   1466 }
   1467 
   1468 void Context::endQuery(QueryType target)
   1469 {
   1470    Query *queryObject = mState.getActiveQuery(target);
   1471    ASSERT(queryObject);
   1472 
   1473    // Intentionally don't call try here. We don't want an early return.
   1474    (void)(queryObject->end(this));
   1475 
   1476    // Always unbind the query, even if there was an error. This may delete the query object.
   1477    mState.setActiveQuery(this, target, nullptr);
   1478    mStateCache.onQueryChange(this);
   1479 }
   1480 
   1481 void Context::queryCounter(QueryID id, QueryType target)
   1482 {
   1483    ASSERT(target == QueryType::Timestamp);
   1484 
   1485    Query *queryObject = getOrCreateQuery(id, target);
   1486    ASSERT(queryObject);
   1487 
   1488    ANGLE_CONTEXT_TRY(queryObject->queryCounter(this));
   1489 }
   1490 
   1491 void Context::getQueryiv(QueryType target, GLenum pname, GLint *params)
   1492 {
   1493    switch (pname)
   1494    {
   1495        case GL_CURRENT_QUERY_EXT:
   1496            params[0] = mState.getActiveQueryId(target).value;
   1497            break;
   1498        case GL_QUERY_COUNTER_BITS_EXT:
   1499            switch (target)
   1500            {
   1501                case QueryType::TimeElapsed:
   1502                    params[0] = getCaps().queryCounterBitsTimeElapsed;
   1503                    break;
   1504                case QueryType::Timestamp:
   1505                    params[0] = getCaps().queryCounterBitsTimestamp;
   1506                    break;
   1507                default:
   1508                    UNREACHABLE();
   1509                    params[0] = 0;
   1510                    break;
   1511            }
   1512            break;
   1513        default:
   1514            UNREACHABLE();
   1515            return;
   1516    }
   1517 }
   1518 
   1519 void Context::getQueryivRobust(QueryType target,
   1520                               GLenum pname,
   1521                               GLsizei bufSize,
   1522                               GLsizei *length,
   1523                               GLint *params)
   1524 {
   1525    getQueryiv(target, pname, params);
   1526 }
   1527 
   1528 void Context::getUnsignedBytev(GLenum pname, GLubyte *data)
   1529 {
   1530    UNIMPLEMENTED();
   1531 }
   1532 
   1533 void Context::getUnsignedBytei_v(GLenum target, GLuint index, GLubyte *data)
   1534 {
   1535    UNIMPLEMENTED();
   1536 }
   1537 
   1538 void Context::getQueryObjectiv(QueryID id, GLenum pname, GLint *params)
   1539 {
   1540    ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
   1541 }
   1542 
   1543 void Context::getQueryObjectivRobust(QueryID id,
   1544                                     GLenum pname,
   1545                                     GLsizei bufSize,
   1546                                     GLsizei *length,
   1547                                     GLint *params)
   1548 {
   1549    getQueryObjectiv(id, pname, params);
   1550 }
   1551 
   1552 void Context::getQueryObjectuiv(QueryID id, GLenum pname, GLuint *params)
   1553 {
   1554    ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
   1555 }
   1556 
   1557 void Context::getQueryObjectuivRobust(QueryID id,
   1558                                      GLenum pname,
   1559                                      GLsizei bufSize,
   1560                                      GLsizei *length,
   1561                                      GLuint *params)
   1562 {
   1563    getQueryObjectuiv(id, pname, params);
   1564 }
   1565 
   1566 void Context::getQueryObjecti64v(QueryID id, GLenum pname, GLint64 *params)
   1567 {
   1568    ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
   1569 }
   1570 
   1571 void Context::getQueryObjecti64vRobust(QueryID id,
   1572                                       GLenum pname,
   1573                                       GLsizei bufSize,
   1574                                       GLsizei *length,
   1575                                       GLint64 *params)
   1576 {
   1577    getQueryObjecti64v(id, pname, params);
   1578 }
   1579 
   1580 void Context::getQueryObjectui64v(QueryID id, GLenum pname, GLuint64 *params)
   1581 {
   1582    ANGLE_CONTEXT_TRY(GetQueryObjectParameter(this, getQuery(id), pname, params));
   1583 }
   1584 
   1585 void Context::getQueryObjectui64vRobust(QueryID id,
   1586                                        GLenum pname,
   1587                                        GLsizei bufSize,
   1588                                        GLsizei *length,
   1589                                        GLuint64 *params)
   1590 {
   1591    getQueryObjectui64v(id, pname, params);
   1592 }
   1593 
   1594 Framebuffer *Context::getFramebuffer(FramebufferID handle) const
   1595 {
   1596    return mState.mFramebufferManager->getFramebuffer(handle);
   1597 }
   1598 
   1599 FenceNV *Context::getFenceNV(FenceNVID handle) const
   1600 {
   1601    return mFenceNVMap.query(handle);
   1602 }
   1603 
   1604 Query *Context::getOrCreateQuery(QueryID handle, QueryType type)
   1605 {
   1606    if (!mQueryMap.contains(handle))
   1607    {
   1608        return nullptr;
   1609    }
   1610 
   1611    Query *query = mQueryMap.query(handle);
   1612    if (!query)
   1613    {
   1614        ASSERT(type != QueryType::InvalidEnum);
   1615        query = new Query(mImplementation.get(), type, handle);
   1616        query->addRef();
   1617        mQueryMap.assign(handle, query);
   1618    }
   1619    return query;
   1620 }
   1621 
   1622 Query *Context::getQuery(QueryID handle) const
   1623 {
   1624    return mQueryMap.query(handle);
   1625 }
   1626 
   1627 Texture *Context::getTextureByType(TextureType type) const
   1628 {
   1629    ASSERT(ValidTextureTarget(this, type) || ValidTextureExternalTarget(this, type));
   1630    return mState.getTargetTexture(type);
   1631 }
   1632 
   1633 Texture *Context::getTextureByTarget(TextureTarget target) const
   1634 {
   1635    return getTextureByType(TextureTargetToType(target));
   1636 }
   1637 
   1638 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
   1639 {
   1640    return mState.getSamplerTexture(sampler, type);
   1641 }
   1642 
   1643 Compiler *Context::getCompiler() const
   1644 {
   1645    if (mCompiler.get() == nullptr)
   1646    {
   1647        mCompiler.set(this, new Compiler(mImplementation.get(), mState, mDisplay));
   1648    }
   1649    return mCompiler.get();
   1650 }
   1651 
   1652 void Context::getBooleanvImpl(GLenum pname, GLboolean *params) const
   1653 {
   1654    switch (pname)
   1655    {
   1656        case GL_SHADER_COMPILER:
   1657            *params = GL_TRUE;
   1658            break;
   1659        case GL_CONTEXT_ROBUST_ACCESS_EXT:
   1660            *params = ConvertToGLBoolean(mState.hasRobustAccess());
   1661            break;
   1662 
   1663        default:
   1664            mState.getBooleanv(pname, params);
   1665            break;
   1666    }
   1667 }
   1668 
   1669 void Context::getFloatvImpl(GLenum pname, GLfloat *params) const
   1670 {
   1671    // Queries about context capabilities and maximums are answered by Context.
   1672    // Queries about current GL state values are answered by State.
   1673    switch (pname)
   1674    {
   1675        case GL_ALIASED_LINE_WIDTH_RANGE:
   1676            params[0] = mState.mCaps.minAliasedLineWidth;
   1677            params[1] = mState.mCaps.maxAliasedLineWidth;
   1678            break;
   1679        case GL_ALIASED_POINT_SIZE_RANGE:
   1680            params[0] = mState.mCaps.minAliasedPointSize;
   1681            params[1] = mState.mCaps.maxAliasedPointSize;
   1682            break;
   1683        case GL_SMOOTH_POINT_SIZE_RANGE:
   1684            params[0] = mState.mCaps.minSmoothPointSize;
   1685            params[1] = mState.mCaps.maxSmoothPointSize;
   1686            break;
   1687        case GL_SMOOTH_LINE_WIDTH_RANGE:
   1688            params[0] = mState.mCaps.minSmoothLineWidth;
   1689            params[1] = mState.mCaps.maxSmoothLineWidth;
   1690            break;
   1691        case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1692            ASSERT(mState.mExtensions.textureFilterAnisotropicEXT);
   1693            *params = mState.mCaps.maxTextureAnisotropy;
   1694            break;
   1695        case GL_MAX_TEXTURE_LOD_BIAS:
   1696            *params = mState.mCaps.maxLODBias;
   1697            break;
   1698        case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET:
   1699            *params = mState.mCaps.minInterpolationOffset;
   1700            break;
   1701        case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET:
   1702            *params = mState.mCaps.maxInterpolationOffset;
   1703            break;
   1704        case GL_PRIMITIVE_BOUNDING_BOX:
   1705            params[0] = mState.mBoundingBoxMinX;
   1706            params[1] = mState.mBoundingBoxMinY;
   1707            params[2] = mState.mBoundingBoxMinZ;
   1708            params[3] = mState.mBoundingBoxMinW;
   1709            params[4] = mState.mBoundingBoxMaxX;
   1710            params[5] = mState.mBoundingBoxMaxY;
   1711            params[6] = mState.mBoundingBoxMaxZ;
   1712            params[7] = mState.mBoundingBoxMaxW;
   1713            break;
   1714        default:
   1715            mState.getFloatv(pname, params);
   1716            break;
   1717    }
   1718 }
   1719 
   1720 void Context::getIntegervImpl(GLenum pname, GLint *params) const
   1721 {
   1722    // Queries about context capabilities and maximums are answered by Context.
   1723    // Queries about current GL state values are answered by State.
   1724 
   1725    switch (pname)
   1726    {
   1727        case GL_MAX_VERTEX_ATTRIBS:
   1728            *params = mState.mCaps.maxVertexAttributes;
   1729            break;
   1730        case GL_MAX_VERTEX_UNIFORM_VECTORS:
   1731            *params = mState.mCaps.maxVertexUniformVectors;
   1732            break;
   1733        case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
   1734            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Vertex];
   1735            break;
   1736        case GL_MAX_VARYING_VECTORS:
   1737            *params = mState.mCaps.maxVaryingVectors;
   1738            break;
   1739        case GL_MAX_VARYING_COMPONENTS:
   1740            *params = mState.mCaps.maxVaryingVectors * 4;
   1741            break;
   1742        case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   1743            *params = mState.mCaps.maxCombinedTextureImageUnits;
   1744            break;
   1745        case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   1746            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Vertex];
   1747            break;
   1748        case GL_MAX_TEXTURE_IMAGE_UNITS:
   1749            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Fragment];
   1750            break;
   1751        case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   1752            *params = mState.mCaps.maxFragmentUniformVectors;
   1753            break;
   1754        case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
   1755            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Fragment];
   1756            break;
   1757        case GL_MAX_RENDERBUFFER_SIZE:
   1758            *params = mState.mCaps.maxRenderbufferSize;
   1759            break;
   1760        case GL_MAX_COLOR_ATTACHMENTS_EXT:
   1761            *params = mState.mCaps.maxColorAttachments;
   1762            break;
   1763        case GL_MAX_DRAW_BUFFERS_EXT:
   1764            *params = mState.mCaps.maxDrawBuffers;
   1765            break;
   1766        case GL_SUBPIXEL_BITS:
   1767            *params = mState.mCaps.subPixelBits;
   1768            break;
   1769        case GL_MAX_TEXTURE_SIZE:
   1770            *params = mState.mCaps.max2DTextureSize;
   1771            break;
   1772        case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
   1773            *params = mState.mCaps.maxRectangleTextureSize;
   1774            break;
   1775        case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   1776            *params = mState.mCaps.maxCubeMapTextureSize;
   1777            break;
   1778        case GL_MAX_3D_TEXTURE_SIZE:
   1779            *params = mState.mCaps.max3DTextureSize;
   1780            break;
   1781        case GL_MAX_ARRAY_TEXTURE_LAYERS:
   1782            *params = mState.mCaps.maxArrayTextureLayers;
   1783            break;
   1784        case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
   1785            *params = mState.mCaps.uniformBufferOffsetAlignment;
   1786            break;
   1787        case GL_MAX_UNIFORM_BUFFER_BINDINGS:
   1788            *params = mState.mCaps.maxUniformBufferBindings;
   1789            break;
   1790        case GL_MAX_VERTEX_UNIFORM_BLOCKS:
   1791            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex];
   1792            break;
   1793        case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
   1794            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment];
   1795            break;
   1796        case GL_MAX_COMBINED_UNIFORM_BLOCKS:
   1797            *params = mState.mCaps.maxCombinedUniformBlocks;
   1798            break;
   1799        case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
   1800            *params = mState.mCaps.maxVertexOutputComponents;
   1801            break;
   1802        case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
   1803            *params = mState.mCaps.maxFragmentInputComponents;
   1804            break;
   1805        case GL_MIN_PROGRAM_TEXEL_OFFSET:
   1806            *params = mState.mCaps.minProgramTexelOffset;
   1807            break;
   1808        case GL_MAX_PROGRAM_TEXEL_OFFSET:
   1809            *params = mState.mCaps.maxProgramTexelOffset;
   1810            break;
   1811        case GL_MAJOR_VERSION:
   1812            *params = getClientVersion().major;
   1813            break;
   1814        case GL_MINOR_VERSION:
   1815            *params = getClientVersion().minor;
   1816            break;
   1817        case GL_MAX_ELEMENTS_INDICES:
   1818            *params = mState.mCaps.maxElementsIndices;
   1819            break;
   1820        case GL_MAX_ELEMENTS_VERTICES:
   1821            *params = mState.mCaps.maxElementsVertices;
   1822            break;
   1823        case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
   1824            *params = mState.mCaps.maxTransformFeedbackInterleavedComponents;
   1825            break;
   1826        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
   1827            *params = mState.mCaps.maxTransformFeedbackSeparateAttributes;
   1828            break;
   1829        case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
   1830            *params = mState.mCaps.maxTransformFeedbackSeparateComponents;
   1831            break;
   1832        case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1833            *params = static_cast<GLint>(mState.mCaps.compressedTextureFormats.size());
   1834            break;
   1835        case GL_MAX_SAMPLES_ANGLE:
   1836            *params = mState.mCaps.maxSamples;
   1837            break;
   1838        case GL_MAX_VIEWPORT_DIMS:
   1839        {
   1840            params[0] = mState.mCaps.maxViewportWidth;
   1841            params[1] = mState.mCaps.maxViewportHeight;
   1842        }
   1843        break;
   1844        case GL_COMPRESSED_TEXTURE_FORMATS:
   1845            std::copy(mState.mCaps.compressedTextureFormats.begin(),
   1846                      mState.mCaps.compressedTextureFormats.end(), params);
   1847            break;
   1848        case GL_RESET_NOTIFICATION_STRATEGY_EXT:
   1849            *params = mResetStrategy;
   1850            break;
   1851        case GL_NUM_SHADER_BINARY_FORMATS:
   1852            *params = static_cast<GLint>(mState.mCaps.shaderBinaryFormats.size());
   1853            break;
   1854        case GL_SHADER_BINARY_FORMATS:
   1855            std::copy(mState.mCaps.shaderBinaryFormats.begin(),
   1856                      mState.mCaps.shaderBinaryFormats.end(), params);
   1857            break;
   1858        case GL_NUM_PROGRAM_BINARY_FORMATS:
   1859            *params = static_cast<GLint>(mState.mCaps.programBinaryFormats.size());
   1860            break;
   1861        case GL_PROGRAM_BINARY_FORMATS:
   1862            std::copy(mState.mCaps.programBinaryFormats.begin(),
   1863                      mState.mCaps.programBinaryFormats.end(), params);
   1864            break;
   1865        case GL_NUM_EXTENSIONS:
   1866            *params = static_cast<GLint>(mExtensionStrings.size());
   1867            break;
   1868 
   1869        // Desktop client flags
   1870        case GL_CONTEXT_FLAGS:
   1871        {
   1872            GLint contextFlags = 0;
   1873            if (mState.hasProtectedContent())
   1874            {
   1875                contextFlags |= GL_CONTEXT_FLAG_PROTECTED_CONTENT_BIT_EXT;
   1876            }
   1877 
   1878            if (mState.isDebugContext())
   1879            {
   1880                contextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT_KHR;
   1881            }
   1882 
   1883            if (mState.hasRobustAccess())
   1884            {
   1885                contextFlags |= GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT;
   1886            }
   1887            *params = contextFlags;
   1888        }
   1889        break;
   1890        case GL_CONTEXT_PROFILE_MASK:
   1891            ASSERT(getClientType() == EGL_OPENGL_API);
   1892            *params = mState.getProfileMask();
   1893            break;
   1894 
   1895        // GL_ANGLE_request_extension
   1896        case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
   1897            *params = static_cast<GLint>(mRequestableExtensionStrings.size());
   1898            break;
   1899 
   1900        // GL_KHR_debug
   1901        case GL_MAX_DEBUG_MESSAGE_LENGTH:
   1902            *params = mState.mCaps.maxDebugMessageLength;
   1903            break;
   1904        case GL_MAX_DEBUG_LOGGED_MESSAGES:
   1905            *params = mState.mCaps.maxDebugLoggedMessages;
   1906            break;
   1907        case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
   1908            *params = mState.mCaps.maxDebugGroupStackDepth;
   1909            break;
   1910        case GL_MAX_LABEL_LENGTH:
   1911            *params = mState.mCaps.maxLabelLength;
   1912            break;
   1913 
   1914        // GL_OVR_multiview2
   1915        case GL_MAX_VIEWS_OVR:
   1916            *params = mState.mCaps.maxViews;
   1917            break;
   1918 
   1919        // GL_EXT_disjoint_timer_query
   1920        case GL_GPU_DISJOINT_EXT:
   1921            *params = mImplementation->getGPUDisjoint();
   1922            break;
   1923        case GL_MAX_FRAMEBUFFER_WIDTH:
   1924            *params = mState.mCaps.maxFramebufferWidth;
   1925            break;
   1926        case GL_MAX_FRAMEBUFFER_HEIGHT:
   1927            *params = mState.mCaps.maxFramebufferHeight;
   1928            break;
   1929        case GL_MAX_FRAMEBUFFER_SAMPLES:
   1930            *params = mState.mCaps.maxFramebufferSamples;
   1931            break;
   1932        case GL_MAX_SAMPLE_MASK_WORDS:
   1933            *params = mState.mCaps.maxSampleMaskWords;
   1934            break;
   1935        case GL_MAX_COLOR_TEXTURE_SAMPLES:
   1936            *params = mState.mCaps.maxColorTextureSamples;
   1937            break;
   1938        case GL_MAX_DEPTH_TEXTURE_SAMPLES:
   1939            *params = mState.mCaps.maxDepthTextureSamples;
   1940            break;
   1941        case GL_MAX_INTEGER_SAMPLES:
   1942            *params = mState.mCaps.maxIntegerSamples;
   1943            break;
   1944        case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
   1945            *params = mState.mCaps.maxVertexAttribRelativeOffset;
   1946            break;
   1947        case GL_MAX_VERTEX_ATTRIB_BINDINGS:
   1948            *params = mState.mCaps.maxVertexAttribBindings;
   1949            break;
   1950        case GL_MAX_VERTEX_ATTRIB_STRIDE:
   1951            *params = mState.mCaps.maxVertexAttribStride;
   1952            break;
   1953        case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
   1954            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Vertex];
   1955            break;
   1956        case GL_MAX_VERTEX_ATOMIC_COUNTERS:
   1957            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Vertex];
   1958            break;
   1959        case GL_MAX_VERTEX_IMAGE_UNIFORMS:
   1960            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Vertex];
   1961            break;
   1962        case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
   1963            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Vertex];
   1964            break;
   1965        case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
   1966            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Fragment];
   1967            break;
   1968        case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
   1969            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Fragment];
   1970            break;
   1971        case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
   1972            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
   1973            break;
   1974        case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
   1975            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Fragment];
   1976            break;
   1977        case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
   1978            *params = mState.mCaps.minProgramTextureGatherOffset;
   1979            break;
   1980        case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
   1981            *params = mState.mCaps.maxProgramTextureGatherOffset;
   1982            break;
   1983        case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
   1984            *params = mState.mCaps.maxComputeWorkGroupInvocations;
   1985            break;
   1986        case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
   1987            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute];
   1988            break;
   1989        case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
   1990            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Compute];
   1991            break;
   1992        case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
   1993            *params = mState.mCaps.maxComputeSharedMemorySize;
   1994            break;
   1995        case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
   1996            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Compute];
   1997            break;
   1998        case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
   1999            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Compute];
   2000            break;
   2001        case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
   2002            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Compute];
   2003            break;
   2004        case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
   2005            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Compute];
   2006            break;
   2007        case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
   2008            *params = static_cast<GLint>(
   2009                mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Compute]);
   2010            break;
   2011        case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
   2012            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Compute];
   2013            break;
   2014        case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
   2015            *params = mState.mCaps.maxCombinedShaderOutputResources;
   2016            break;
   2017        case GL_MAX_UNIFORM_LOCATIONS:
   2018            *params = mState.mCaps.maxUniformLocations;
   2019            break;
   2020        case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
   2021            *params = mState.mCaps.maxAtomicCounterBufferBindings;
   2022            break;
   2023        case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
   2024            *params = mState.mCaps.maxAtomicCounterBufferSize;
   2025            break;
   2026        case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
   2027            *params = mState.mCaps.maxCombinedAtomicCounterBuffers;
   2028            break;
   2029        case GL_MAX_COMBINED_ATOMIC_COUNTERS:
   2030            *params = mState.mCaps.maxCombinedAtomicCounters;
   2031            break;
   2032        case GL_MAX_IMAGE_UNITS:
   2033            *params = mState.mCaps.maxImageUnits;
   2034            break;
   2035        case GL_MAX_COMBINED_IMAGE_UNIFORMS:
   2036            *params = mState.mCaps.maxCombinedImageUniforms;
   2037            break;
   2038        case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
   2039            *params = mState.mCaps.maxShaderStorageBufferBindings;
   2040            break;
   2041        case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
   2042            *params = mState.mCaps.maxCombinedShaderStorageBlocks;
   2043            break;
   2044        case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
   2045            *params = mState.mCaps.shaderStorageBufferOffsetAlignment;
   2046            break;
   2047 
   2048        // GL_EXT_geometry_shader
   2049        case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
   2050            *params = mState.mCaps.maxFramebufferLayers;
   2051            break;
   2052        case GL_LAYER_PROVOKING_VERTEX_EXT:
   2053            *params = mState.mCaps.layerProvokingVertex;
   2054            break;
   2055        case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
   2056            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::Geometry];
   2057            break;
   2058        case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
   2059            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry];
   2060            break;
   2061        case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
   2062            *params = static_cast<GLint>(
   2063                mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Geometry]);
   2064            break;
   2065        case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
   2066            *params = mState.mCaps.maxGeometryInputComponents;
   2067            break;
   2068        case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
   2069            *params = mState.mCaps.maxGeometryOutputComponents;
   2070            break;
   2071        case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
   2072            *params = mState.mCaps.maxGeometryOutputVertices;
   2073            break;
   2074        case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
   2075            *params = mState.mCaps.maxGeometryTotalOutputComponents;
   2076            break;
   2077        case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
   2078            *params = mState.mCaps.maxGeometryShaderInvocations;
   2079            break;
   2080        case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
   2081            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::Geometry];
   2082            break;
   2083        case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
   2084            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::Geometry];
   2085            break;
   2086        case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
   2087            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::Geometry];
   2088            break;
   2089        case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
   2090            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::Geometry];
   2091            break;
   2092        case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
   2093            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::Geometry];
   2094            break;
   2095        // GL_EXT_tessellation_shader
   2096        case GL_MAX_PATCH_VERTICES_EXT:
   2097            *params = mState.mCaps.maxPatchVertices;
   2098            break;
   2099        case GL_MAX_TESS_GEN_LEVEL_EXT:
   2100            *params = mState.mCaps.maxTessGenLevel;
   2101            break;
   2102        case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
   2103            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessControl];
   2104            break;
   2105        case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
   2106            *params = mState.mCaps.maxShaderUniformComponents[ShaderType::TessEvaluation];
   2107            break;
   2108        case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
   2109            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessControl];
   2110            break;
   2111        case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
   2112            *params = mState.mCaps.maxShaderTextureImageUnits[ShaderType::TessEvaluation];
   2113            break;
   2114        case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
   2115            *params = mState.mCaps.maxTessControlOutputComponents;
   2116            break;
   2117        case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
   2118            *params = mState.mCaps.maxTessPatchComponents;
   2119            break;
   2120        case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
   2121            *params = mState.mCaps.maxTessControlTotalOutputComponents;
   2122            break;
   2123        case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
   2124            *params = mState.mCaps.maxTessEvaluationOutputComponents;
   2125            break;
   2126        case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
   2127            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessControl];
   2128            break;
   2129        case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
   2130            *params = mState.mCaps.maxShaderUniformBlocks[ShaderType::TessEvaluation];
   2131            break;
   2132        case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
   2133            *params = mState.mCaps.maxTessControlInputComponents;
   2134            break;
   2135        case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
   2136            *params = mState.mCaps.maxTessEvaluationInputComponents;
   2137            break;
   2138        case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
   2139            *params = static_cast<GLint>(
   2140                mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessControl]);
   2141            break;
   2142        case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
   2143            *params = static_cast<GLint>(
   2144                mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::TessEvaluation]);
   2145            break;
   2146        case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
   2147            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessControl];
   2148            break;
   2149        case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
   2150            *params = mState.mCaps.maxShaderAtomicCounterBuffers[ShaderType::TessEvaluation];
   2151            break;
   2152        case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
   2153            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessControl];
   2154            break;
   2155        case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
   2156            *params = mState.mCaps.maxShaderAtomicCounters[ShaderType::TessEvaluation];
   2157            break;
   2158        case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
   2159            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessControl];
   2160            break;
   2161        case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
   2162            *params = mState.mCaps.maxShaderImageUniforms[ShaderType::TessEvaluation];
   2163            break;
   2164        case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
   2165            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessControl];
   2166            break;
   2167        case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
   2168            *params = mState.mCaps.maxShaderStorageBlocks[ShaderType::TessEvaluation];
   2169            break;
   2170        // GLES1 emulation: Caps queries
   2171        case GL_MAX_TEXTURE_UNITS:
   2172            *params = mState.mCaps.maxMultitextureUnits;
   2173            break;
   2174        case GL_MAX_MODELVIEW_STACK_DEPTH:
   2175            *params = mState.mCaps.maxModelviewMatrixStackDepth;
   2176            break;
   2177        case GL_MAX_PROJECTION_STACK_DEPTH:
   2178            *params = mState.mCaps.maxProjectionMatrixStackDepth;
   2179            break;
   2180        case GL_MAX_TEXTURE_STACK_DEPTH:
   2181            *params = mState.mCaps.maxTextureMatrixStackDepth;
   2182            break;
   2183        case GL_MAX_LIGHTS:
   2184            *params = mState.mCaps.maxLights;
   2185            break;
   2186 
   2187        // case GL_MAX_CLIP_DISTANCES_EXT:  Conflict enum value
   2188        case GL_MAX_CLIP_PLANES:
   2189            if (getClientVersion().major >= 2)
   2190            {
   2191                // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
   2192                *params = mState.mCaps.maxClipDistances;
   2193            }
   2194            else
   2195            {
   2196                *params = mState.mCaps.maxClipPlanes;
   2197            }
   2198            break;
   2199        case GL_MAX_CULL_DISTANCES_EXT:
   2200            *params = mState.mCaps.maxCullDistances;
   2201            break;
   2202        case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
   2203            *params = mState.mCaps.maxCombinedClipAndCullDistances;
   2204            break;
   2205        // GLES1 emulation: Vertex attribute queries
   2206        case GL_VERTEX_ARRAY_BUFFER_BINDING:
   2207        case GL_NORMAL_ARRAY_BUFFER_BINDING:
   2208        case GL_COLOR_ARRAY_BUFFER_BINDING:
   2209        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
   2210        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
   2211            getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, params);
   2212            break;
   2213        case GL_VERTEX_ARRAY_STRIDE:
   2214        case GL_NORMAL_ARRAY_STRIDE:
   2215        case GL_COLOR_ARRAY_STRIDE:
   2216        case GL_POINT_SIZE_ARRAY_STRIDE_OES:
   2217        case GL_TEXTURE_COORD_ARRAY_STRIDE:
   2218            getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_STRIDE, params);
   2219            break;
   2220        case GL_VERTEX_ARRAY_SIZE:
   2221        case GL_COLOR_ARRAY_SIZE:
   2222        case GL_TEXTURE_COORD_ARRAY_SIZE:
   2223            getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_SIZE, params);
   2224            break;
   2225        case GL_VERTEX_ARRAY_TYPE:
   2226        case GL_COLOR_ARRAY_TYPE:
   2227        case GL_NORMAL_ARRAY_TYPE:
   2228        case GL_POINT_SIZE_ARRAY_TYPE_OES:
   2229        case GL_TEXTURE_COORD_ARRAY_TYPE:
   2230            getIntegerVertexAttribImpl(pname, GL_VERTEX_ATTRIB_ARRAY_TYPE, params);
   2231            break;
   2232 
   2233        // GL_KHR_parallel_shader_compile
   2234        case GL_MAX_SHADER_COMPILER_THREADS_KHR:
   2235            *params = mState.getMaxShaderCompilerThreads();
   2236            break;
   2237 
   2238        // GL_EXT_blend_func_extended
   2239        case GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT:
   2240            *params = mState.mCaps.maxDualSourceDrawBuffers;
   2241            break;
   2242 
   2243        // OES_shader_multisample_interpolation
   2244        case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
   2245            *params = mState.mCaps.subPixelInterpolationOffsetBits;
   2246            break;
   2247 
   2248        // GL_OES_texture_buffer
   2249        case GL_MAX_TEXTURE_BUFFER_SIZE:
   2250            *params = mState.mCaps.maxTextureBufferSize;
   2251            break;
   2252        case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
   2253            *params = mState.mCaps.textureBufferOffsetAlignment;
   2254            break;
   2255 
   2256        // GL_EXT_clip_control
   2257        case GL_CLIP_ORIGIN_EXT:
   2258            *params = mState.mClipControlOrigin;
   2259            break;
   2260        case GL_CLIP_DEPTH_MODE_EXT:
   2261            *params = mState.mClipControlDepth;
   2262            break;
   2263 
   2264        // ANGLE_shader_pixel_local_storage
   2265        case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
   2266            *params = mState.mCaps.maxPixelLocalStoragePlanes;
   2267            break;
   2268        case GL_MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE:
   2269            *params = mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage;
   2270            break;
   2271        case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
   2272            *params = mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes;
   2273            break;
   2274 
   2275        default:
   2276            ANGLE_CONTEXT_TRY(mState.getIntegerv(this, pname, params));
   2277            break;
   2278    }
   2279 }
   2280 
   2281 void Context::getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const
   2282 {
   2283    getVertexAttribivImpl(static_cast<GLuint>(vertexArrayIndex(ParamToVertexArrayType(pname))),
   2284                          attribpname, params);
   2285 }
   2286 
   2287 void Context::getInteger64vImpl(GLenum pname, GLint64 *params) const
   2288 {
   2289    // Queries about context capabilities and maximums are answered by Context.
   2290    // Queries about current GL state values are answered by State.
   2291    switch (pname)
   2292    {
   2293        case GL_MAX_ELEMENT_INDEX:
   2294            *params = mState.mCaps.maxElementIndex;
   2295            break;
   2296        case GL_MAX_UNIFORM_BLOCK_SIZE:
   2297            *params = mState.mCaps.maxUniformBlockSize;
   2298            break;
   2299        case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   2300            *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Vertex];
   2301            break;
   2302        case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   2303            *params = mState.mCaps.maxCombinedShaderUniformComponents[ShaderType::Fragment];
   2304            break;
   2305        case GL_MAX_SERVER_WAIT_TIMEOUT:
   2306            *params = mState.mCaps.maxServerWaitTimeout;
   2307            break;
   2308 
   2309        // GL_EXT_disjoint_timer_query
   2310        case GL_TIMESTAMP_EXT:
   2311            *params = mImplementation->getTimestamp();
   2312            break;
   2313 
   2314        case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
   2315            *params = mState.mCaps.maxShaderStorageBlockSize;
   2316            break;
   2317        default:
   2318            UNREACHABLE();
   2319            break;
   2320    }
   2321 }
   2322 
   2323 void Context::getPointerv(GLenum pname, void **params)
   2324 {
   2325    mState.getPointerv(this, pname, params);
   2326 }
   2327 
   2328 void Context::getPointervRobustANGLERobust(GLenum pname,
   2329                                           GLsizei bufSize,
   2330                                           GLsizei *length,
   2331                                           void **params)
   2332 {
   2333    UNIMPLEMENTED();
   2334 }
   2335 
   2336 void Context::getIntegeri_v(GLenum target, GLuint index, GLint *data)
   2337 {
   2338    // Queries about context capabilities and maximums are answered by Context.
   2339    // Queries about current GL state values are answered by State.
   2340 
   2341    GLenum nativeType;
   2342    unsigned int numParams;
   2343    bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
   2344    ASSERT(queryStatus);
   2345 
   2346    if (nativeType == GL_INT)
   2347    {
   2348        switch (target)
   2349        {
   2350            case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
   2351                ASSERT(index < 3u);
   2352                *data = mState.mCaps.maxComputeWorkGroupCount[index];
   2353                break;
   2354            case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
   2355                ASSERT(index < 3u);
   2356                *data = mState.mCaps.maxComputeWorkGroupSize[index];
   2357                break;
   2358            default:
   2359                mState.getIntegeri_v(this, target, index, data);
   2360        }
   2361    }
   2362    else
   2363    {
   2364        CastIndexedStateValues(this, nativeType, target, index, numParams, data);
   2365    }
   2366 }
   2367 
   2368 void Context::getIntegeri_vRobust(GLenum target,
   2369                                  GLuint index,
   2370                                  GLsizei bufSize,
   2371                                  GLsizei *length,
   2372                                  GLint *data)
   2373 {
   2374    getIntegeri_v(target, index, data);
   2375 }
   2376 
   2377 void Context::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
   2378 {
   2379    // Queries about context capabilities and maximums are answered by Context.
   2380    // Queries about current GL state values are answered by State.
   2381 
   2382    GLenum nativeType;
   2383    unsigned int numParams;
   2384    bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
   2385    ASSERT(queryStatus);
   2386 
   2387    if (nativeType == GL_INT_64_ANGLEX)
   2388    {
   2389        mState.getInteger64i_v(target, index, data);
   2390    }
   2391    else
   2392    {
   2393        CastIndexedStateValues(this, nativeType, target, index, numParams, data);
   2394    }
   2395 }
   2396 
   2397 void Context::getInteger64i_vRobust(GLenum target,
   2398                                    GLuint index,
   2399                                    GLsizei bufSize,
   2400                                    GLsizei *length,
   2401                                    GLint64 *data)
   2402 {
   2403    getInteger64i_v(target, index, data);
   2404 }
   2405 
   2406 void Context::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
   2407 {
   2408    // Queries about context capabilities and maximums are answered by Context.
   2409    // Queries about current GL state values are answered by State.
   2410 
   2411    GLenum nativeType;
   2412    unsigned int numParams;
   2413    bool queryStatus = getIndexedQueryParameterInfo(target, &nativeType, &numParams);
   2414    ASSERT(queryStatus);
   2415 
   2416    if (nativeType == GL_BOOL)
   2417    {
   2418        mState.getBooleani_v(target, index, data);
   2419    }
   2420    else
   2421    {
   2422        CastIndexedStateValues(this, nativeType, target, index, numParams, data);
   2423    }
   2424 }
   2425 
   2426 void Context::getBooleani_vRobust(GLenum target,
   2427                                  GLuint index,
   2428                                  GLsizei bufSize,
   2429                                  GLsizei *length,
   2430                                  GLboolean *data)
   2431 {
   2432    getBooleani_v(target, index, data);
   2433 }
   2434 
   2435 void Context::getBufferParameteriv(BufferBinding target, GLenum pname, GLint *params)
   2436 {
   2437    Buffer *buffer = mState.getTargetBuffer(target);
   2438    QueryBufferParameteriv(buffer, pname, params);
   2439 }
   2440 
   2441 void Context::getBufferParameterivRobust(BufferBinding target,
   2442                                         GLenum pname,
   2443                                         GLsizei bufSize,
   2444                                         GLsizei *length,
   2445                                         GLint *params)
   2446 {
   2447    getBufferParameteriv(target, pname, params);
   2448 }
   2449 
   2450 void Context::getFramebufferAttachmentParameteriv(GLenum target,
   2451                                                  GLenum attachment,
   2452                                                  GLenum pname,
   2453                                                  GLint *params)
   2454 {
   2455    const Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   2456    QueryFramebufferAttachmentParameteriv(this, framebuffer, attachment, pname, params);
   2457 }
   2458 
   2459 void Context::getFramebufferAttachmentParameterivRobust(GLenum target,
   2460                                                        GLenum attachment,
   2461                                                        GLenum pname,
   2462                                                        GLsizei bufSize,
   2463                                                        GLsizei *length,
   2464                                                        GLint *params)
   2465 {
   2466    getFramebufferAttachmentParameteriv(target, attachment, pname, params);
   2467 }
   2468 
   2469 void Context::getRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params)
   2470 {
   2471    Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
   2472    QueryRenderbufferiv(this, renderbuffer, pname, params);
   2473 }
   2474 
   2475 void Context::getRenderbufferParameterivRobust(GLenum target,
   2476                                               GLenum pname,
   2477                                               GLsizei bufSize,
   2478                                               GLsizei *length,
   2479                                               GLint *params)
   2480 {
   2481    getRenderbufferParameteriv(target, pname, params);
   2482 }
   2483 
   2484 void Context::texBuffer(TextureType target, GLenum internalformat, BufferID buffer)
   2485 {
   2486    ASSERT(target == TextureType::Buffer);
   2487 
   2488    Texture *texture  = getTextureByType(target);
   2489    Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer);
   2490    ANGLE_CONTEXT_TRY(texture->setBuffer(this, bufferObj, internalformat));
   2491 }
   2492 
   2493 void Context::texBufferRange(TextureType target,
   2494                             GLenum internalformat,
   2495                             BufferID buffer,
   2496                             GLintptr offset,
   2497                             GLsizeiptr size)
   2498 {
   2499    ASSERT(target == TextureType::Buffer);
   2500 
   2501    Texture *texture  = getTextureByType(target);
   2502    Buffer *bufferObj = mState.mBufferManager->getBuffer(buffer);
   2503    ANGLE_CONTEXT_TRY(texture->setBufferRange(this, bufferObj, internalformat, offset, size));
   2504 }
   2505 
   2506 void Context::getTexParameterfv(TextureType target, GLenum pname, GLfloat *params)
   2507 {
   2508    const Texture *const texture = getTextureByType(target);
   2509    QueryTexParameterfv(this, texture, pname, params);
   2510 }
   2511 
   2512 void Context::getTexParameterfvRobust(TextureType target,
   2513                                      GLenum pname,
   2514                                      GLsizei bufSize,
   2515                                      GLsizei *length,
   2516                                      GLfloat *params)
   2517 {
   2518    getTexParameterfv(target, pname, params);
   2519 }
   2520 
   2521 void Context::getTexParameteriv(TextureType target, GLenum pname, GLint *params)
   2522 {
   2523    const Texture *const texture = getTextureByType(target);
   2524    QueryTexParameteriv(this, texture, pname, params);
   2525 }
   2526 
   2527 void Context::getTexParameterIiv(TextureType target, GLenum pname, GLint *params)
   2528 {
   2529    const Texture *const texture = getTextureByType(target);
   2530    QueryTexParameterIiv(this, texture, pname, params);
   2531 }
   2532 
   2533 void Context::getTexParameterIuiv(TextureType target, GLenum pname, GLuint *params)
   2534 {
   2535    const Texture *const texture = getTextureByType(target);
   2536    QueryTexParameterIuiv(this, texture, pname, params);
   2537 }
   2538 
   2539 void Context::getTexParameterivRobust(TextureType target,
   2540                                      GLenum pname,
   2541                                      GLsizei bufSize,
   2542                                      GLsizei *length,
   2543                                      GLint *params)
   2544 {
   2545    getTexParameteriv(target, pname, params);
   2546 }
   2547 
   2548 void Context::getTexParameterIivRobust(TextureType target,
   2549                                       GLenum pname,
   2550                                       GLsizei bufSize,
   2551                                       GLsizei *length,
   2552                                       GLint *params)
   2553 {
   2554    UNIMPLEMENTED();
   2555 }
   2556 
   2557 void Context::getTexParameterIuivRobust(TextureType target,
   2558                                        GLenum pname,
   2559                                        GLsizei bufSize,
   2560                                        GLsizei *length,
   2561                                        GLuint *params)
   2562 {
   2563    UNIMPLEMENTED();
   2564 }
   2565 
   2566 void Context::getTexLevelParameteriv(TextureTarget target, GLint level, GLenum pname, GLint *params)
   2567 {
   2568    Texture *texture = getTextureByTarget(target);
   2569    QueryTexLevelParameteriv(texture, target, level, pname, params);
   2570 }
   2571 
   2572 void Context::getTexLevelParameterivRobust(TextureTarget target,
   2573                                           GLint level,
   2574                                           GLenum pname,
   2575                                           GLsizei bufSize,
   2576                                           GLsizei *length,
   2577                                           GLint *params)
   2578 {
   2579    UNIMPLEMENTED();
   2580 }
   2581 
   2582 void Context::getTexLevelParameterfv(TextureTarget target,
   2583                                     GLint level,
   2584                                     GLenum pname,
   2585                                     GLfloat *params)
   2586 {
   2587    Texture *texture = getTextureByTarget(target);
   2588    QueryTexLevelParameterfv(texture, target, level, pname, params);
   2589 }
   2590 
   2591 void Context::getTexLevelParameterfvRobust(TextureTarget target,
   2592                                           GLint level,
   2593                                           GLenum pname,
   2594                                           GLsizei bufSize,
   2595                                           GLsizei *length,
   2596                                           GLfloat *params)
   2597 {
   2598    UNIMPLEMENTED();
   2599 }
   2600 
   2601 void Context::texParameterf(TextureType target, GLenum pname, GLfloat param)
   2602 {
   2603    Texture *const texture = getTextureByType(target);
   2604    SetTexParameterf(this, texture, pname, param);
   2605 }
   2606 
   2607 void Context::texParameterfv(TextureType target, GLenum pname, const GLfloat *params)
   2608 {
   2609    Texture *const texture = getTextureByType(target);
   2610    SetTexParameterfv(this, texture, pname, params);
   2611 }
   2612 
   2613 void Context::texParameterfvRobust(TextureType target,
   2614                                   GLenum pname,
   2615                                   GLsizei bufSize,
   2616                                   const GLfloat *params)
   2617 {
   2618    texParameterfv(target, pname, params);
   2619 }
   2620 
   2621 void Context::texParameteri(TextureType target, GLenum pname, GLint param)
   2622 {
   2623    // Some apps enable KHR_create_context_no_error but pass in an invalid texture type.
   2624    // Workaround this by silently returning in such situations.
   2625    if (target == TextureType::InvalidEnum)
   2626    {
   2627        return;
   2628    }
   2629 
   2630    Texture *const texture = getTextureByType(target);
   2631    SetTexParameteri(this, texture, pname, param);
   2632 }
   2633 
   2634 void Context::texParameteriv(TextureType target, GLenum pname, const GLint *params)
   2635 {
   2636    Texture *const texture = getTextureByType(target);
   2637    SetTexParameteriv(this, texture, pname, params);
   2638 }
   2639 
   2640 void Context::texParameterIiv(TextureType target, GLenum pname, const GLint *params)
   2641 {
   2642    Texture *const texture = getTextureByType(target);
   2643    SetTexParameterIiv(this, texture, pname, params);
   2644 }
   2645 
   2646 void Context::texParameterIuiv(TextureType target, GLenum pname, const GLuint *params)
   2647 {
   2648    Texture *const texture = getTextureByType(target);
   2649    SetTexParameterIuiv(this, texture, pname, params);
   2650 }
   2651 
   2652 void Context::texParameterivRobust(TextureType target,
   2653                                   GLenum pname,
   2654                                   GLsizei bufSize,
   2655                                   const GLint *params)
   2656 {
   2657    texParameteriv(target, pname, params);
   2658 }
   2659 
   2660 void Context::texParameterIivRobust(TextureType target,
   2661                                    GLenum pname,
   2662                                    GLsizei bufSize,
   2663                                    const GLint *params)
   2664 {
   2665    UNIMPLEMENTED();
   2666 }
   2667 
   2668 void Context::texParameterIuivRobust(TextureType target,
   2669                                     GLenum pname,
   2670                                     GLsizei bufSize,
   2671                                     const GLuint *params)
   2672 {
   2673    UNIMPLEMENTED();
   2674 }
   2675 
   2676 void Context::drawArraysInstanced(PrimitiveMode mode,
   2677                                  GLint first,
   2678                                  GLsizei count,
   2679                                  GLsizei instanceCount)
   2680 {
   2681    // No-op if count draws no primitives for given mode
   2682    if (noopDrawInstanced(mode, count, instanceCount))
   2683    {
   2684        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2685        return;
   2686    }
   2687 
   2688    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2689    ANGLE_CONTEXT_TRY(
   2690        mImplementation->drawArraysInstanced(this, mode, first, count, instanceCount));
   2691    MarkTransformFeedbackBufferUsage(this, count, instanceCount);
   2692    MarkShaderStorageUsage(this);
   2693 }
   2694 
   2695 void Context::drawElementsInstanced(PrimitiveMode mode,
   2696                                    GLsizei count,
   2697                                    DrawElementsType type,
   2698                                    const void *indices,
   2699                                    GLsizei instances)
   2700 {
   2701    // No-op if count draws no primitives for given mode
   2702    if (noopDrawInstanced(mode, count, instances))
   2703    {
   2704        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2705        return;
   2706    }
   2707 
   2708    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2709    ANGLE_CONTEXT_TRY(
   2710        mImplementation->drawElementsInstanced(this, mode, count, type, indices, instances));
   2711    MarkShaderStorageUsage(this);
   2712 }
   2713 
   2714 void Context::drawElementsBaseVertex(PrimitiveMode mode,
   2715                                     GLsizei count,
   2716                                     DrawElementsType type,
   2717                                     const void *indices,
   2718                                     GLint basevertex)
   2719 {
   2720    // No-op if count draws no primitives for given mode
   2721    if (noopDraw(mode, count))
   2722    {
   2723        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2724        return;
   2725    }
   2726 
   2727    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2728    ANGLE_CONTEXT_TRY(
   2729        mImplementation->drawElementsBaseVertex(this, mode, count, type, indices, basevertex));
   2730    MarkShaderStorageUsage(this);
   2731 }
   2732 
   2733 void Context::drawElementsInstancedBaseVertex(PrimitiveMode mode,
   2734                                              GLsizei count,
   2735                                              DrawElementsType type,
   2736                                              const void *indices,
   2737                                              GLsizei instancecount,
   2738                                              GLint basevertex)
   2739 {
   2740    // No-op if count draws no primitives for given mode
   2741    if (noopDrawInstanced(mode, count, instancecount))
   2742    {
   2743        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2744        return;
   2745    }
   2746 
   2747    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2748    ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertex(
   2749        this, mode, count, type, indices, instancecount, basevertex));
   2750    MarkShaderStorageUsage(this);
   2751 }
   2752 
   2753 void Context::drawRangeElements(PrimitiveMode mode,
   2754                                GLuint start,
   2755                                GLuint end,
   2756                                GLsizei count,
   2757                                DrawElementsType type,
   2758                                const void *indices)
   2759 {
   2760    // No-op if count draws no primitives for given mode
   2761    if (noopDraw(mode, count))
   2762    {
   2763        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2764        return;
   2765    }
   2766 
   2767    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2768    ANGLE_CONTEXT_TRY(
   2769        mImplementation->drawRangeElements(this, mode, start, end, count, type, indices));
   2770    MarkShaderStorageUsage(this);
   2771 }
   2772 
   2773 void Context::drawRangeElementsBaseVertex(PrimitiveMode mode,
   2774                                          GLuint start,
   2775                                          GLuint end,
   2776                                          GLsizei count,
   2777                                          DrawElementsType type,
   2778                                          const void *indices,
   2779                                          GLint basevertex)
   2780 {
   2781    // No-op if count draws no primitives for given mode
   2782    if (noopDraw(mode, count))
   2783    {
   2784        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   2785        return;
   2786    }
   2787 
   2788    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2789    ANGLE_CONTEXT_TRY(mImplementation->drawRangeElementsBaseVertex(this, mode, start, end, count,
   2790                                                                   type, indices, basevertex));
   2791    MarkShaderStorageUsage(this);
   2792 }
   2793 
   2794 void Context::drawArraysIndirect(PrimitiveMode mode, const void *indirect)
   2795 {
   2796    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2797    ANGLE_CONTEXT_TRY(mImplementation->drawArraysIndirect(this, mode, indirect));
   2798    MarkShaderStorageUsage(this);
   2799 }
   2800 
   2801 void Context::drawElementsIndirect(PrimitiveMode mode, DrawElementsType type, const void *indirect)
   2802 {
   2803    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   2804    ANGLE_CONTEXT_TRY(mImplementation->drawElementsIndirect(this, mode, type, indirect));
   2805    MarkShaderStorageUsage(this);
   2806 }
   2807 
   2808 void Context::flush()
   2809 {
   2810    ANGLE_CONTEXT_TRY(mImplementation->flush(this));
   2811 }
   2812 
   2813 void Context::finish()
   2814 {
   2815    ANGLE_CONTEXT_TRY(mImplementation->finish(this));
   2816 }
   2817 
   2818 void Context::insertEventMarker(GLsizei length, const char *marker)
   2819 {
   2820    ASSERT(mImplementation);
   2821    ANGLE_CONTEXT_TRY(mImplementation->insertEventMarker(length, marker));
   2822 }
   2823 
   2824 void Context::pushGroupMarker(GLsizei length, const char *marker)
   2825 {
   2826    ASSERT(mImplementation);
   2827 
   2828    if (marker == nullptr)
   2829    {
   2830        // From the EXT_debug_marker spec,
   2831        // "If <marker> is null then an empty string is pushed on the stack."
   2832        ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, ""));
   2833    }
   2834    else
   2835    {
   2836        ANGLE_CONTEXT_TRY(mImplementation->pushGroupMarker(length, marker));
   2837    }
   2838 }
   2839 
   2840 void Context::popGroupMarker()
   2841 {
   2842    ASSERT(mImplementation);
   2843    ANGLE_CONTEXT_TRY(mImplementation->popGroupMarker());
   2844 }
   2845 
   2846 void Context::bindUniformLocation(ShaderProgramID program,
   2847                                  UniformLocation location,
   2848                                  const GLchar *name)
   2849 {
   2850    Program *programObject = getProgramResolveLink(program);
   2851    ASSERT(programObject);
   2852 
   2853    programObject->bindUniformLocation(location, name);
   2854 }
   2855 
   2856 void Context::coverageModulation(GLenum components)
   2857 {
   2858    mState.setCoverageModulation(components);
   2859 }
   2860 
   2861 GLuint Context::getProgramResourceIndex(ShaderProgramID program,
   2862                                        GLenum programInterface,
   2863                                        const GLchar *name)
   2864 {
   2865    const Program *programObject = getProgramResolveLink(program);
   2866    return QueryProgramResourceIndex(programObject, programInterface, name);
   2867 }
   2868 
   2869 void Context::getProgramResourceName(ShaderProgramID program,
   2870                                     GLenum programInterface,
   2871                                     GLuint index,
   2872                                     GLsizei bufSize,
   2873                                     GLsizei *length,
   2874                                     GLchar *name)
   2875 {
   2876    const Program *programObject = getProgramResolveLink(program);
   2877    QueryProgramResourceName(this, programObject, programInterface, index, bufSize, length, name);
   2878 }
   2879 
   2880 GLint Context::getProgramResourceLocation(ShaderProgramID program,
   2881                                          GLenum programInterface,
   2882                                          const GLchar *name)
   2883 {
   2884    const Program *programObject = getProgramResolveLink(program);
   2885    return QueryProgramResourceLocation(programObject, programInterface, name);
   2886 }
   2887 
   2888 void Context::getProgramResourceiv(ShaderProgramID program,
   2889                                   GLenum programInterface,
   2890                                   GLuint index,
   2891                                   GLsizei propCount,
   2892                                   const GLenum *props,
   2893                                   GLsizei bufSize,
   2894                                   GLsizei *length,
   2895                                   GLint *params)
   2896 {
   2897    const Program *programObject = getProgramResolveLink(program);
   2898    QueryProgramResourceiv(programObject, programInterface, {index}, propCount, props, bufSize,
   2899                           length, params);
   2900 }
   2901 
   2902 void Context::getProgramInterfaceiv(ShaderProgramID program,
   2903                                    GLenum programInterface,
   2904                                    GLenum pname,
   2905                                    GLint *params)
   2906 {
   2907    const Program *programObject = getProgramResolveLink(program);
   2908    QueryProgramInterfaceiv(programObject, programInterface, pname, params);
   2909 }
   2910 
   2911 void Context::getProgramInterfaceivRobust(ShaderProgramID program,
   2912                                          GLenum programInterface,
   2913                                          GLenum pname,
   2914                                          GLsizei bufSize,
   2915                                          GLsizei *length,
   2916                                          GLint *params)
   2917 {
   2918    UNIMPLEMENTED();
   2919 }
   2920 
   2921 void Context::handleError(GLenum errorCode,
   2922                          const char *message,
   2923                          const char *file,
   2924                          const char *function,
   2925                          unsigned int line)
   2926 {
   2927    mErrors.handleError(errorCode, message, file, function, line);
   2928 }
   2929 
   2930 void Context::validationError(angle::EntryPoint entryPoint,
   2931                              GLenum errorCode,
   2932                              const char *message) const
   2933 {
   2934    const_cast<Context *>(this)->mErrors.validationError(entryPoint, errorCode, message);
   2935 }
   2936 
   2937 void Context::validationErrorF(angle::EntryPoint entryPoint,
   2938                               GLenum errorCode,
   2939                               const char *format,
   2940                               ...) const
   2941 {
   2942    va_list vargs;
   2943    va_start(vargs, format);
   2944    constexpr size_t kMessageSize = 256;
   2945    char message[kMessageSize];
   2946    int r = vsnprintf(message, kMessageSize, format, vargs);
   2947    va_end(vargs);
   2948 
   2949    if (r > 0)
   2950    {
   2951        validationError(entryPoint, errorCode, message);
   2952    }
   2953    else
   2954    {
   2955        validationError(entryPoint, errorCode, format);
   2956    }
   2957 }
   2958 
   2959 // Get one of the recorded errors and clear its flag, if any.
   2960 // [OpenGL ES 2.0.24] section 2.5 page 13.
   2961 GLenum Context::getError()
   2962 {
   2963    if (mErrors.empty())
   2964    {
   2965        return GL_NO_ERROR;
   2966    }
   2967    else
   2968    {
   2969        return mErrors.popError();
   2970    }
   2971 }
   2972 
   2973 // NOTE: this function should not assume that this context is current!
   2974 void Context::markContextLost(GraphicsResetStatus status)
   2975 {
   2976    ASSERT(status != GraphicsResetStatus::NoError);
   2977    if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
   2978    {
   2979        mResetStatus       = status;
   2980        mContextLostForced = true;
   2981    }
   2982    setContextLost();
   2983 }
   2984 
   2985 void Context::setContextLost()
   2986 {
   2987    mContextLost = true;
   2988 
   2989    // Stop skipping validation, since many implementation entrypoint assume they can't
   2990    // be called when lost, or with null object arguments, etc.
   2991    mSkipValidation = false;
   2992 
   2993    // Make sure we update TLS.
   2994 #if defined(ANGLE_PLATFORM_APPLE)
   2995    SetCurrentValidContextTLS(nullptr);
   2996 #else
   2997    gCurrentValidContext = nullptr;
   2998 #endif
   2999 }
   3000 
   3001 GLenum Context::getGraphicsResetStatus()
   3002 {
   3003    // Even if the application doesn't want to know about resets, we want to know
   3004    // as it will allow us to skip all the calls.
   3005    if (mResetStrategy == GL_NO_RESET_NOTIFICATION_EXT)
   3006    {
   3007        if (!isContextLost() && mImplementation->getResetStatus() != GraphicsResetStatus::NoError)
   3008        {
   3009            setContextLost();
   3010        }
   3011 
   3012        // EXT_robustness, section 2.6: If the reset notification behavior is
   3013        // NO_RESET_NOTIFICATION_EXT, then the implementation will never deliver notification of
   3014        // reset events, and GetGraphicsResetStatusEXT will always return NO_ERROR.
   3015        return GL_NO_ERROR;
   3016    }
   3017 
   3018    // The GL_EXT_robustness spec says that if a reset is encountered, a reset
   3019    // status should be returned at least once, and GL_NO_ERROR should be returned
   3020    // once the device has finished resetting.
   3021    if (!isContextLost())
   3022    {
   3023        ASSERT(mResetStatus == GraphicsResetStatus::NoError);
   3024        mResetStatus = mImplementation->getResetStatus();
   3025 
   3026        if (mResetStatus != GraphicsResetStatus::NoError)
   3027        {
   3028            setContextLost();
   3029        }
   3030    }
   3031    else if (!mContextLostForced && mResetStatus != GraphicsResetStatus::NoError)
   3032    {
   3033        // If markContextLost was used to mark the context lost then
   3034        // assume that is not recoverable, and continue to report the
   3035        // lost reset status for the lifetime of this context.
   3036        mResetStatus = mImplementation->getResetStatus();
   3037    }
   3038 
   3039    return ToGLenum(mResetStatus);
   3040 }
   3041 
   3042 bool Context::isResetNotificationEnabled() const
   3043 {
   3044    return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
   3045 }
   3046 
   3047 bool Context::isRobustnessEnabled() const
   3048 {
   3049    return mState.hasRobustAccess();
   3050 }
   3051 
   3052 const egl::Config *Context::getConfig() const
   3053 {
   3054    return mConfig;
   3055 }
   3056 
   3057 EGLenum Context::getClientType() const
   3058 {
   3059    return mState.getClientType();
   3060 }
   3061 
   3062 EGLenum Context::getRenderBuffer() const
   3063 {
   3064    const Framebuffer *framebuffer =
   3065        mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
   3066    if (framebuffer == nullptr)
   3067    {
   3068        return EGL_NONE;
   3069    }
   3070 
   3071    const FramebufferAttachment *backAttachment = framebuffer->getAttachment(this, GL_BACK);
   3072    ASSERT(backAttachment != nullptr);
   3073    return backAttachment->getSurface()->getRenderBuffer();
   3074 }
   3075 
   3076 VertexArray *Context::checkVertexArrayAllocation(VertexArrayID vertexArrayHandle)
   3077 {
   3078    // Only called after a prior call to Gen.
   3079    VertexArray *vertexArray = getVertexArray(vertexArrayHandle);
   3080    if (!vertexArray)
   3081    {
   3082        vertexArray =
   3083            new VertexArray(mImplementation.get(), vertexArrayHandle,
   3084                            mState.mCaps.maxVertexAttributes, mState.mCaps.maxVertexAttribBindings);
   3085        vertexArray->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
   3086 
   3087        mVertexArrayMap.assign(vertexArrayHandle, vertexArray);
   3088    }
   3089 
   3090    return vertexArray;
   3091 }
   3092 
   3093 TransformFeedback *Context::checkTransformFeedbackAllocation(
   3094    TransformFeedbackID transformFeedbackHandle)
   3095 {
   3096    // Only called after a prior call to Gen.
   3097    TransformFeedback *transformFeedback = getTransformFeedback(transformFeedbackHandle);
   3098    if (!transformFeedback)
   3099    {
   3100        transformFeedback =
   3101            new TransformFeedback(mImplementation.get(), transformFeedbackHandle, mState.mCaps);
   3102        transformFeedback->addRef();
   3103        mTransformFeedbackMap.assign(transformFeedbackHandle, transformFeedback);
   3104    }
   3105 
   3106    return transformFeedback;
   3107 }
   3108 
   3109 bool Context::isVertexArrayGenerated(VertexArrayID vertexArray) const
   3110 {
   3111    ASSERT(mVertexArrayMap.contains({0}));
   3112    return mVertexArrayMap.contains(vertexArray);
   3113 }
   3114 
   3115 bool Context::isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const
   3116 {
   3117    ASSERT(mTransformFeedbackMap.contains({0}));
   3118    return mTransformFeedbackMap.contains(transformFeedback);
   3119 }
   3120 
   3121 void Context::detachTexture(TextureID texture)
   3122 {
   3123    // The State cannot unbind image observers itself, they are owned by the Context
   3124    Texture *tex = mState.mTextureManager->getTexture(texture);
   3125    for (auto &imageBinding : mImageObserverBindings)
   3126    {
   3127        if (imageBinding.getSubject() == tex)
   3128        {
   3129            imageBinding.reset();
   3130        }
   3131    }
   3132 
   3133    // Simple pass-through to State's detachTexture method, as textures do not require
   3134    // allocation map management either here or in the resource manager at detach time.
   3135    // Zero textures are held by the Context, and we don't attempt to request them from
   3136    // the State.
   3137    mState.detachTexture(this, mZeroTextures, texture);
   3138 }
   3139 
   3140 void Context::detachBuffer(Buffer *buffer)
   3141 {
   3142    // Simple pass-through to State's detachBuffer method, since
   3143    // only buffer attachments to container objects that are bound to the current context
   3144    // should be detached. And all those are available in State.
   3145 
   3146    // [OpenGL ES 3.2] section 5.1.2 page 45:
   3147    // Attachments to unbound container objects, such as
   3148    // deletion of a buffer attached to a vertex array object which is not bound to the context,
   3149    // are not affected and continue to act as references on the deleted object
   3150    ANGLE_CONTEXT_TRY(mState.detachBuffer(this, buffer));
   3151 }
   3152 
   3153 void Context::detachFramebuffer(FramebufferID framebuffer)
   3154 {
   3155    // Framebuffer detachment is handled by Context, because 0 is a valid
   3156    // Framebuffer object, and a pointer to it must be passed from Context
   3157    // to State at binding time.
   3158 
   3159    // [OpenGL ES 2.0.24] section 4.4 page 107:
   3160    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as
   3161    // though BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of
   3162    // zero.
   3163 
   3164    if (mState.removeReadFramebufferBinding(framebuffer) && framebuffer.value != 0)
   3165    {
   3166        bindReadFramebuffer({0});
   3167    }
   3168 
   3169    if (mState.removeDrawFramebufferBinding(framebuffer) && framebuffer.value != 0)
   3170    {
   3171        bindDrawFramebuffer({0});
   3172    }
   3173 }
   3174 
   3175 void Context::detachRenderbuffer(RenderbufferID renderbuffer)
   3176 {
   3177    mState.detachRenderbuffer(this, renderbuffer);
   3178 }
   3179 
   3180 void Context::detachVertexArray(VertexArrayID vertexArray)
   3181 {
   3182    // Vertex array detachment is handled by Context, because 0 is a valid
   3183    // VAO, and a pointer to it must be passed from Context to State at
   3184    // binding time.
   3185 
   3186    // [OpenGL ES 3.0.2] section 2.10 page 43:
   3187    // If a vertex array object that is currently bound is deleted, the binding
   3188    // for that object reverts to zero and the default vertex array becomes current.
   3189    if (mState.removeVertexArrayBinding(this, vertexArray))
   3190    {
   3191        bindVertexArray({0});
   3192    }
   3193 }
   3194 
   3195 void Context::detachTransformFeedback(TransformFeedbackID transformFeedback)
   3196 {
   3197    // Transform feedback detachment is handled by Context, because 0 is a valid
   3198    // transform feedback, and a pointer to it must be passed from Context to State at
   3199    // binding time.
   3200 
   3201    // The OpenGL specification doesn't mention what should happen when the currently bound
   3202    // transform feedback object is deleted. Since it is a container object, we treat it like
   3203    // VAOs and FBOs and set the current bound transform feedback back to 0.
   3204    if (mState.removeTransformFeedbackBinding(this, transformFeedback))
   3205    {
   3206        bindTransformFeedback(GL_TRANSFORM_FEEDBACK, {0});
   3207        mStateCache.onActiveTransformFeedbackChange(this);
   3208    }
   3209 }
   3210 
   3211 void Context::detachSampler(SamplerID sampler)
   3212 {
   3213    mState.detachSampler(this, sampler);
   3214 }
   3215 
   3216 void Context::detachProgramPipeline(ProgramPipelineID pipeline)
   3217 {
   3218    mState.detachProgramPipeline(this, pipeline);
   3219 }
   3220 
   3221 void Context::vertexAttribDivisor(GLuint index, GLuint divisor)
   3222 {
   3223    mState.setVertexAttribDivisor(this, index, divisor);
   3224    mStateCache.onVertexArrayStateChange(this);
   3225 }
   3226 
   3227 void Context::samplerParameteri(SamplerID sampler, GLenum pname, GLint param)
   3228 {
   3229    Sampler *const samplerObject =
   3230        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3231    SetSamplerParameteri(this, samplerObject, pname, param);
   3232 }
   3233 
   3234 void Context::samplerParameteriv(SamplerID sampler, GLenum pname, const GLint *param)
   3235 {
   3236    Sampler *const samplerObject =
   3237        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3238    SetSamplerParameteriv(this, samplerObject, pname, param);
   3239 }
   3240 
   3241 void Context::samplerParameterIiv(SamplerID sampler, GLenum pname, const GLint *param)
   3242 {
   3243    Sampler *const samplerObject =
   3244        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3245    SetSamplerParameterIiv(this, samplerObject, pname, param);
   3246 }
   3247 
   3248 void Context::samplerParameterIuiv(SamplerID sampler, GLenum pname, const GLuint *param)
   3249 {
   3250    Sampler *const samplerObject =
   3251        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3252    SetSamplerParameterIuiv(this, samplerObject, pname, param);
   3253 }
   3254 
   3255 void Context::samplerParameterivRobust(SamplerID sampler,
   3256                                       GLenum pname,
   3257                                       GLsizei bufSize,
   3258                                       const GLint *param)
   3259 {
   3260    samplerParameteriv(sampler, pname, param);
   3261 }
   3262 
   3263 void Context::samplerParameterIivRobust(SamplerID sampler,
   3264                                        GLenum pname,
   3265                                        GLsizei bufSize,
   3266                                        const GLint *param)
   3267 {
   3268    UNIMPLEMENTED();
   3269 }
   3270 
   3271 void Context::samplerParameterIuivRobust(SamplerID sampler,
   3272                                         GLenum pname,
   3273                                         GLsizei bufSize,
   3274                                         const GLuint *param)
   3275 {
   3276    UNIMPLEMENTED();
   3277 }
   3278 
   3279 void Context::samplerParameterf(SamplerID sampler, GLenum pname, GLfloat param)
   3280 {
   3281    Sampler *const samplerObject =
   3282        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3283    SetSamplerParameterf(this, samplerObject, pname, param);
   3284 }
   3285 
   3286 void Context::samplerParameterfv(SamplerID sampler, GLenum pname, const GLfloat *param)
   3287 {
   3288    Sampler *const samplerObject =
   3289        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3290    SetSamplerParameterfv(this, samplerObject, pname, param);
   3291 }
   3292 
   3293 void Context::samplerParameterfvRobust(SamplerID sampler,
   3294                                       GLenum pname,
   3295                                       GLsizei bufSize,
   3296                                       const GLfloat *param)
   3297 {
   3298    samplerParameterfv(sampler, pname, param);
   3299 }
   3300 
   3301 void Context::getSamplerParameteriv(SamplerID sampler, GLenum pname, GLint *params)
   3302 {
   3303    const Sampler *const samplerObject =
   3304        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3305    QuerySamplerParameteriv(samplerObject, pname, params);
   3306 }
   3307 
   3308 void Context::getSamplerParameterIiv(SamplerID sampler, GLenum pname, GLint *params)
   3309 {
   3310    const Sampler *const samplerObject =
   3311        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3312    QuerySamplerParameterIiv(samplerObject, pname, params);
   3313 }
   3314 
   3315 void Context::getSamplerParameterIuiv(SamplerID sampler, GLenum pname, GLuint *params)
   3316 {
   3317    const Sampler *const samplerObject =
   3318        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3319    QuerySamplerParameterIuiv(samplerObject, pname, params);
   3320 }
   3321 
   3322 void Context::getSamplerParameterivRobust(SamplerID sampler,
   3323                                          GLenum pname,
   3324                                          GLsizei bufSize,
   3325                                          GLsizei *length,
   3326                                          GLint *params)
   3327 {
   3328    getSamplerParameteriv(sampler, pname, params);
   3329 }
   3330 
   3331 void Context::getSamplerParameterIivRobust(SamplerID sampler,
   3332                                           GLenum pname,
   3333                                           GLsizei bufSize,
   3334                                           GLsizei *length,
   3335                                           GLint *params)
   3336 {
   3337    UNIMPLEMENTED();
   3338 }
   3339 
   3340 void Context::getSamplerParameterIuivRobust(SamplerID sampler,
   3341                                            GLenum pname,
   3342                                            GLsizei bufSize,
   3343                                            GLsizei *length,
   3344                                            GLuint *params)
   3345 {
   3346    UNIMPLEMENTED();
   3347 }
   3348 
   3349 void Context::getSamplerParameterfv(SamplerID sampler, GLenum pname, GLfloat *params)
   3350 {
   3351    const Sampler *const samplerObject =
   3352        mState.mSamplerManager->checkSamplerAllocation(mImplementation.get(), sampler);
   3353    QuerySamplerParameterfv(samplerObject, pname, params);
   3354 }
   3355 
   3356 void Context::getSamplerParameterfvRobust(SamplerID sampler,
   3357                                          GLenum pname,
   3358                                          GLsizei bufSize,
   3359                                          GLsizei *length,
   3360                                          GLfloat *params)
   3361 {
   3362    getSamplerParameterfv(sampler, pname, params);
   3363 }
   3364 
   3365 void Context::programParameteri(ShaderProgramID program, GLenum pname, GLint value)
   3366 {
   3367    gl::Program *programObject = getProgramResolveLink(program);
   3368    SetProgramParameteri(programObject, pname, value);
   3369 }
   3370 
   3371 void Context::initRendererString()
   3372 {
   3373    std::ostringstream frontendRendererString;
   3374    std::string vendorString(mDisplay->getBackendVendorString());
   3375    std::string rendererString(mDisplay->getBackendRendererDescription());
   3376    std::string versionString(mDisplay->getBackendVersionString(!isWebGL()));
   3377    // Commas are used as a separator in ANGLE's renderer string, so remove commas from each
   3378    // element.
   3379    vendorString.erase(std::remove(vendorString.begin(), vendorString.end(), ','),
   3380                       vendorString.end());
   3381    rendererString.erase(std::remove(rendererString.begin(), rendererString.end(), ','),
   3382                         rendererString.end());
   3383    versionString.erase(std::remove(versionString.begin(), versionString.end(), ','),
   3384                        versionString.end());
   3385    frontendRendererString << "ANGLE (";
   3386    frontendRendererString << vendorString;
   3387    frontendRendererString << ", ";
   3388    frontendRendererString << rendererString;
   3389    frontendRendererString << ", ";
   3390    frontendRendererString << versionString;
   3391    frontendRendererString << ")";
   3392 
   3393    mRendererString = MakeStaticString(frontendRendererString.str());
   3394 }
   3395 
   3396 void Context::initVersionStrings()
   3397 {
   3398    const Version &clientVersion = getClientVersion();
   3399 
   3400    std::ostringstream versionString;
   3401    if (getClientType() == EGL_OPENGL_ES_API)
   3402    {
   3403        versionString << "OpenGL ES ";
   3404    }
   3405    versionString << clientVersion.major << "." << clientVersion.minor << ".0 (ANGLE "
   3406                  << angle::GetANGLEVersionString() << ")";
   3407    mVersionString = MakeStaticString(versionString.str());
   3408 
   3409    std::ostringstream shadingLanguageVersionString;
   3410    if (getClientType() == EGL_OPENGL_ES_API)
   3411    {
   3412        shadingLanguageVersionString << "OpenGL ES GLSL ES ";
   3413    }
   3414    else
   3415    {
   3416        ASSERT(getClientType() == EGL_OPENGL_API);
   3417        shadingLanguageVersionString << "OpenGL GLSL ";
   3418    }
   3419    shadingLanguageVersionString << (clientVersion.major == 2 ? 1 : clientVersion.major) << "."
   3420                                 << clientVersion.minor << "0 (ANGLE "
   3421                                 << angle::GetANGLEVersionString() << ")";
   3422    mShadingLanguageString = MakeStaticString(shadingLanguageVersionString.str());
   3423 }
   3424 
   3425 void Context::initExtensionStrings()
   3426 {
   3427    auto mergeExtensionStrings = [](const std::vector<const char *> &strings) {
   3428        std::ostringstream combinedStringStream;
   3429        std::copy(strings.begin(), strings.end(),
   3430                  std::ostream_iterator<const char *>(combinedStringStream, " "));
   3431        return MakeStaticString(combinedStringStream.str());
   3432    };
   3433 
   3434    mExtensionStrings.clear();
   3435    for (const auto &extensionString : mState.mExtensions.getStrings())
   3436    {
   3437        mExtensionStrings.push_back(MakeStaticString(extensionString));
   3438    }
   3439    mExtensionString = mergeExtensionStrings(mExtensionStrings);
   3440 
   3441    mRequestableExtensionStrings.clear();
   3442    for (const auto &extensionInfo : GetExtensionInfoMap())
   3443    {
   3444        if (extensionInfo.second.Requestable &&
   3445            !(mState.mExtensions.*(extensionInfo.second.ExtensionsMember)) &&
   3446            mSupportedExtensions.*(extensionInfo.second.ExtensionsMember))
   3447        {
   3448            mRequestableExtensionStrings.push_back(MakeStaticString(extensionInfo.first));
   3449        }
   3450    }
   3451    mRequestableExtensionString = mergeExtensionStrings(mRequestableExtensionStrings);
   3452 }
   3453 
   3454 const GLubyte *Context::getString(GLenum name)
   3455 {
   3456    return static_cast<const Context *>(this)->getString(name);
   3457 }
   3458 
   3459 const GLubyte *Context::getStringi(GLenum name, GLuint index)
   3460 {
   3461    return static_cast<const Context *>(this)->getStringi(name, index);
   3462 }
   3463 
   3464 const GLubyte *Context::getString(GLenum name) const
   3465 {
   3466    switch (name)
   3467    {
   3468        case GL_VENDOR:
   3469            return reinterpret_cast<const GLubyte *>(mDisplay->getVendorString().c_str());
   3470 
   3471        case GL_RENDERER:
   3472            return reinterpret_cast<const GLubyte *>(mRendererString);
   3473 
   3474        case GL_VERSION:
   3475            return reinterpret_cast<const GLubyte *>(mVersionString);
   3476 
   3477        case GL_SHADING_LANGUAGE_VERSION:
   3478            return reinterpret_cast<const GLubyte *>(mShadingLanguageString);
   3479 
   3480        case GL_EXTENSIONS:
   3481            return reinterpret_cast<const GLubyte *>(mExtensionString);
   3482 
   3483        case GL_REQUESTABLE_EXTENSIONS_ANGLE:
   3484            return reinterpret_cast<const GLubyte *>(mRequestableExtensionString);
   3485 
   3486        case GL_SERIALIZED_CONTEXT_STRING_ANGLE:
   3487            if (angle::SerializeContextToString(this, &mCachedSerializedStateString) ==
   3488                angle::Result::Continue)
   3489            {
   3490                return reinterpret_cast<const GLubyte *>(mCachedSerializedStateString.c_str());
   3491            }
   3492            else
   3493            {
   3494                return nullptr;
   3495            }
   3496 
   3497        default:
   3498            UNREACHABLE();
   3499            return nullptr;
   3500    }
   3501 }
   3502 
   3503 const GLubyte *Context::getStringi(GLenum name, GLuint index) const
   3504 {
   3505    switch (name)
   3506    {
   3507        case GL_EXTENSIONS:
   3508            return reinterpret_cast<const GLubyte *>(mExtensionStrings[index]);
   3509 
   3510        case GL_REQUESTABLE_EXTENSIONS_ANGLE:
   3511            return reinterpret_cast<const GLubyte *>(mRequestableExtensionStrings[index]);
   3512 
   3513        default:
   3514            UNREACHABLE();
   3515            return nullptr;
   3516    }
   3517 }
   3518 
   3519 size_t Context::getExtensionStringCount() const
   3520 {
   3521    return mExtensionStrings.size();
   3522 }
   3523 
   3524 bool Context::isExtensionRequestable(const char *name) const
   3525 {
   3526    const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
   3527    auto extension                         = extensionInfos.find(name);
   3528 
   3529    return extension != extensionInfos.end() && extension->second.Requestable &&
   3530           mSupportedExtensions.*(extension->second.ExtensionsMember);
   3531 }
   3532 
   3533 bool Context::isExtensionDisablable(const char *name) const
   3534 {
   3535    const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
   3536    auto extension                         = extensionInfos.find(name);
   3537 
   3538    return extension != extensionInfos.end() && extension->second.Disablable &&
   3539           mSupportedExtensions.*(extension->second.ExtensionsMember);
   3540 }
   3541 
   3542 void Context::requestExtension(const char *name)
   3543 {
   3544    setExtensionEnabled(name, true);
   3545 }
   3546 void Context::disableExtension(const char *name)
   3547 {
   3548    setExtensionEnabled(name, false);
   3549 }
   3550 
   3551 void Context::setExtensionEnabled(const char *name, bool enabled)
   3552 {
   3553    // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
   3554    if (strcmp(name, "GL_OVR_multiview2") == 0)
   3555    {
   3556        setExtensionEnabled("GL_OVR_multiview", enabled);
   3557    }
   3558    const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
   3559    ASSERT(extensionInfos.find(name) != extensionInfos.end());
   3560    const auto &extension = extensionInfos.at(name);
   3561    ASSERT(extension.Requestable);
   3562    ASSERT(isExtensionRequestable(name));
   3563 
   3564    if (mState.mExtensions.*(extension.ExtensionsMember) == enabled)
   3565    {
   3566        // No change
   3567        return;
   3568    }
   3569 
   3570    mState.mExtensions.*(extension.ExtensionsMember) = enabled;
   3571 
   3572    reinitializeAfterExtensionsChanged();
   3573 }
   3574 
   3575 void Context::reinitializeAfterExtensionsChanged()
   3576 {
   3577    updateCaps();
   3578    initExtensionStrings();
   3579 
   3580    // Release the shader compiler so it will be re-created with the requested extensions enabled.
   3581    releaseShaderCompiler();
   3582 
   3583    // Invalidate all textures and framebuffer. Some extensions make new formats renderable or
   3584    // sampleable.
   3585    mState.mTextureManager->signalAllTexturesDirty();
   3586    for (auto &zeroTexture : mZeroTextures)
   3587    {
   3588        if (zeroTexture.get() != nullptr)
   3589        {
   3590            zeroTexture->signalDirtyStorage(InitState::Initialized);
   3591        }
   3592    }
   3593 
   3594    mState.mFramebufferManager->invalidateFramebufferCompletenessCache();
   3595 }
   3596 
   3597 size_t Context::getRequestableExtensionStringCount() const
   3598 {
   3599    return mRequestableExtensionStrings.size();
   3600 }
   3601 
   3602 void Context::beginTransformFeedback(PrimitiveMode primitiveMode)
   3603 {
   3604    TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
   3605    ASSERT(transformFeedback != nullptr);
   3606    ASSERT(!transformFeedback->isPaused());
   3607 
   3608    // TODO: http://anglebug.com/7232: Handle PPOs
   3609    ANGLE_CONTEXT_TRY(transformFeedback->begin(this, primitiveMode, mState.getProgram()));
   3610    mStateCache.onActiveTransformFeedbackChange(this);
   3611 }
   3612 
   3613 bool Context::hasActiveTransformFeedback(ShaderProgramID program) const
   3614 {
   3615    for (auto pair : mTransformFeedbackMap)
   3616    {
   3617        if (pair.second != nullptr && pair.second->hasBoundProgram(program))
   3618        {
   3619            return true;
   3620        }
   3621    }
   3622    return false;
   3623 }
   3624 
   3625 Extensions Context::generateSupportedExtensions() const
   3626 {
   3627    Extensions supportedExtensions = mImplementation->getNativeExtensions();
   3628 
   3629    if (getClientVersion() < ES_2_0)
   3630    {
   3631        // Default extensions for GLES1
   3632        supportedExtensions.pointSizeArrayOES        = true;
   3633        supportedExtensions.textureCubeMapOES        = true;
   3634        supportedExtensions.pointSpriteOES           = true;
   3635        supportedExtensions.drawTextureOES           = true;
   3636        supportedExtensions.framebufferObjectOES     = true;
   3637        supportedExtensions.parallelShaderCompileKHR = false;
   3638        supportedExtensions.texture3DOES             = false;
   3639        supportedExtensions.clipDistanceAPPLE        = false;
   3640    }
   3641 
   3642    if (getClientVersion() < ES_3_0)
   3643    {
   3644        // Disable ES3+ extensions
   3645        supportedExtensions.colorBufferFloatEXT          = false;
   3646        supportedExtensions.EGLImageExternalEssl3OES     = false;
   3647        supportedExtensions.multiviewOVR                 = false;
   3648        supportedExtensions.multiview2OVR                = false;
   3649        supportedExtensions.multiviewMultisampleANGLE    = false;
   3650        supportedExtensions.copyTexture3dANGLE           = false;
   3651        supportedExtensions.textureMultisampleANGLE      = false;
   3652        supportedExtensions.drawBuffersIndexedEXT        = false;
   3653        supportedExtensions.drawBuffersIndexedOES        = false;
   3654        supportedExtensions.EGLImageArrayEXT             = false;
   3655        supportedExtensions.textureFormatSRGBOverrideEXT = false;
   3656 
   3657        // Support GL_EXT_texture_norm16 on non-WebGL ES2 contexts. This is needed for R16/RG16
   3658        // texturing for HDR video playback in Chromium which uses ES2 for compositor contexts.
   3659        // Remove this workaround after Chromium migrates to ES3 for compositor contexts.
   3660        if (mWebGLContext || getClientVersion() < ES_2_0)
   3661        {
   3662            supportedExtensions.textureNorm16EXT = false;
   3663        }
   3664 
   3665        // Requires immutable textures
   3666        supportedExtensions.yuvInternalFormatANGLE = false;
   3667 
   3668        // Require ESSL 3.0
   3669        supportedExtensions.shaderMultisampleInterpolationOES  = false;
   3670        supportedExtensions.shaderNoperspectiveInterpolationNV = false;
   3671        supportedExtensions.sampleVariablesOES                 = false;
   3672 
   3673        // Require ES 3.1 but could likely be exposed on 3.0
   3674        supportedExtensions.textureCubeMapArrayEXT = false;
   3675        supportedExtensions.textureCubeMapArrayOES = false;
   3676 
   3677        // Require RED and RG formats
   3678        supportedExtensions.textureSRGBR8EXT  = false;
   3679        supportedExtensions.textureSRGBRG8EXT = false;
   3680 
   3681        // Requires glCompressedTexImage3D
   3682        supportedExtensions.textureCompressionAstcOES = false;
   3683 
   3684        // Don't expose GL_EXT_texture_sRGB_decode without sRGB texture support
   3685        if (!supportedExtensions.sRGBEXT)
   3686        {
   3687            supportedExtensions.textureSRGBDecodeEXT = false;
   3688        }
   3689 
   3690        // Don't expose GL_OES_texture_float_linear without full legacy float texture support
   3691        // The renderer may report OES_texture_float_linear without OES_texture_float
   3692        // This is valid in a GLES 3.0 context, but not in a GLES 2.0 context
   3693        if (!(supportedExtensions.textureFloatOES && supportedExtensions.textureHalfFloatOES))
   3694        {
   3695            supportedExtensions.textureFloatLinearOES     = false;
   3696            supportedExtensions.textureHalfFloatLinearOES = false;
   3697        }
   3698 
   3699        // Because of the difference in the SNORM to FLOAT conversion formula
   3700        // between GLES 2.0 and 3.0, vertex type 10_10_10_2 is disabled
   3701        // when the context version is lower than 3.0
   3702        supportedExtensions.vertexType1010102OES = false;
   3703 
   3704        // GL_EXT_EGL_image_storage requires ESSL3
   3705        supportedExtensions.EGLImageStorageEXT = false;
   3706 
   3707        // GL_EXT_YUV_target requires ESSL3
   3708        supportedExtensions.YUVTargetEXT = false;
   3709 
   3710        // GL_EXT_clip_cull_distance requires ESSL3
   3711        supportedExtensions.clipCullDistanceEXT = false;
   3712 
   3713        // ANGLE_shader_pixel_local_storage requires ES3
   3714        supportedExtensions.shaderPixelLocalStorageANGLE         = false;
   3715        supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false;
   3716    }
   3717 
   3718    if (getClientVersion() < ES_3_1)
   3719    {
   3720        // Disable ES3.1+ extensions
   3721        supportedExtensions.geometryShaderEXT       = false;
   3722        supportedExtensions.geometryShaderOES       = false;
   3723        supportedExtensions.gpuShader5EXT           = false;
   3724        supportedExtensions.primitiveBoundingBoxEXT = false;
   3725        supportedExtensions.shaderImageAtomicOES    = false;
   3726        supportedExtensions.shaderIoBlocksEXT       = false;
   3727        supportedExtensions.shaderIoBlocksOES       = false;
   3728        supportedExtensions.tessellationShaderEXT   = false;
   3729        supportedExtensions.textureBufferEXT        = false;
   3730        supportedExtensions.textureBufferOES        = false;
   3731 
   3732        // TODO(http://anglebug.com/2775): Multisample arrays could be supported on ES 3.0 as well
   3733        // once 2D multisample texture extension is exposed there.
   3734        supportedExtensions.textureStorageMultisample2dArrayOES = false;
   3735    }
   3736 
   3737    if (getClientVersion() > ES_2_0)
   3738    {
   3739        // FIXME(geofflang): Don't support EXT_sRGB in non-ES2 contexts
   3740        // supportedExtensions.sRGB = false;
   3741 
   3742        // If colorBufferFloatEXT is disabled but colorBufferHalfFloatEXT is enabled, then we will
   3743        // expose some floating-point formats as color buffer targets but reject blits between
   3744        // fixed-point and floating-point formats (this behavior is only enabled in
   3745        // colorBufferFloatEXT, and must be rejected if only colorBufferHalfFloatEXT is enabled).
   3746        // dEQP does not check for this, and will assume that floating-point and fixed-point formats
   3747        // can be blit onto each other if the format is available.
   3748        // We require colorBufferFloatEXT to be present in order to enable colorBufferHalfFloatEXT,
   3749        // so that blitting is always allowed if the requested formats are exposed and have the
   3750        // correct feature capabilities. WebGL 2 wants to support colorBufferHalfFloatEXT without
   3751        // colorBufferFloatEXT.
   3752        if (!supportedExtensions.colorBufferFloatEXT && !mWebGLContext)
   3753        {
   3754            supportedExtensions.colorBufferHalfFloatEXT = false;
   3755        }
   3756 
   3757        // Disable support for CHROMIUM_color_buffer_float_rgb[a] in ES 3.0+, these extensions are
   3758        // non-conformant in ES 3.0 and superseded by EXT_color_buffer_float.
   3759        supportedExtensions.colorBufferFloatRgbCHROMIUM  = false;
   3760        supportedExtensions.colorBufferFloatRgbaCHROMIUM = false;
   3761    }
   3762 
   3763    if (getFrontendFeatures().disableDrawBuffersIndexed.enabled)
   3764    {
   3765        supportedExtensions.drawBuffersIndexedEXT = false;
   3766        supportedExtensions.drawBuffersIndexedOES = false;
   3767    }
   3768 
   3769    if (getFrontendFeatures().disableAnisotropicFiltering.enabled)
   3770    {
   3771        supportedExtensions.textureFilterAnisotropicEXT = false;
   3772    }
   3773 
   3774    if (!getFrontendFeatures().emulatePixelLocalStorage.enabled)
   3775    {
   3776        supportedExtensions.shaderPixelLocalStorageANGLE         = false;
   3777        supportedExtensions.shaderPixelLocalStorageCoherentANGLE = false;
   3778    }
   3779 
   3780    // Some extensions are always available because they are implemented in the GL layer.
   3781    supportedExtensions.bindUniformLocationCHROMIUM   = true;
   3782    supportedExtensions.vertexArrayObjectOES          = true;
   3783    supportedExtensions.bindGeneratesResourceCHROMIUM = true;
   3784    supportedExtensions.clientArraysANGLE             = true;
   3785    supportedExtensions.requestExtensionANGLE         = true;
   3786    supportedExtensions.multiDrawANGLE                = true;
   3787 
   3788    // Enable the no error extension if the context was created with the flag.
   3789    supportedExtensions.noErrorKHR = mSkipValidation;
   3790 
   3791    // Enable surfaceless to advertise we'll have the correct behavior when there is no default FBO
   3792    supportedExtensions.surfacelessContextOES = mSurfacelessSupported;
   3793 
   3794    // Explicitly enable GL_KHR_debug
   3795    supportedExtensions.debugKHR = true;
   3796 
   3797    // Explicitly enable GL_EXT_debug_label
   3798    supportedExtensions.debugLabelEXT = true;
   3799 
   3800    // Explicitly enable GL_ANGLE_robust_client_memory if the context supports validation.
   3801    supportedExtensions.robustClientMemoryANGLE = !mSkipValidation;
   3802 
   3803    // Determine robust resource init availability from EGL.
   3804    supportedExtensions.robustResourceInitializationANGLE = mState.isRobustResourceInitEnabled();
   3805 
   3806    // mState.mExtensions.robustBufferAccessBehaviorKHR is true only if robust access is true and
   3807    // the backend supports it.
   3808    supportedExtensions.robustBufferAccessBehaviorKHR =
   3809        mState.hasRobustAccess() && supportedExtensions.robustBufferAccessBehaviorKHR;
   3810 
   3811    // Enable the cache control query unconditionally.
   3812    supportedExtensions.programCacheControlANGLE = true;
   3813 
   3814    // If EGL_KHR_fence_sync is not enabled, don't expose GL_OES_EGL_sync.
   3815    ASSERT(mDisplay);
   3816    if (!mDisplay->getExtensions().fenceSync)
   3817    {
   3818        supportedExtensions.EGLSyncOES = false;
   3819    }
   3820 
   3821    if (mDisplay->getExtensions().robustnessVideoMemoryPurgeNV)
   3822    {
   3823        supportedExtensions.robustnessVideoMemoryPurgeNV = true;
   3824    }
   3825 
   3826    supportedExtensions.memorySizeANGLE = true;
   3827 
   3828    // GL_CHROMIUM_lose_context is implemented in the frontend
   3829    supportedExtensions.loseContextCHROMIUM = true;
   3830 
   3831    // The ASTC texture extensions have dependency requirements.
   3832    if (supportedExtensions.textureCompressionAstcHdrKHR ||
   3833        supportedExtensions.textureCompressionAstcSliced3dKHR)
   3834    {
   3835        // GL_KHR_texture_compression_astc_hdr cannot be exposed without also exposing
   3836        // GL_KHR_texture_compression_astc_ldr
   3837        ASSERT(supportedExtensions.textureCompressionAstcLdrKHR);
   3838    }
   3839 
   3840    if (supportedExtensions.textureCompressionAstcOES)
   3841    {
   3842        // GL_OES_texture_compression_astc cannot be exposed without also exposing
   3843        // GL_KHR_texture_compression_astc_ldr and GL_KHR_texture_compression_astc_hdr
   3844        ASSERT(supportedExtensions.textureCompressionAstcLdrKHR);
   3845        ASSERT(supportedExtensions.textureCompressionAstcHdrKHR);
   3846    }
   3847 
   3848    // GL_KHR_protected_textures
   3849    // If EGL_KHR_protected_content is not supported then GL_EXT_protected_texture
   3850    // can not be supported.
   3851    if (!mDisplay->getExtensions().protectedContentEXT)
   3852    {
   3853        supportedExtensions.protectedTexturesEXT = false;
   3854    }
   3855 
   3856    // GL_ANGLE_get_tex_level_parameter is implemented in the front-end
   3857    supportedExtensions.getTexLevelParameterANGLE = true;
   3858 
   3859    // Always enabled. Will return a default string if capture is not enabled.
   3860    supportedExtensions.getSerializedContextStringANGLE = true;
   3861 
   3862    // Performance counter queries are always supported. Different groups exist on each back-end.
   3863    supportedExtensions.performanceMonitorAMD = true;
   3864 
   3865    // GL_ANDROID_extension_pack_es31a
   3866    supportedExtensions.extensionPackEs31aANDROID =
   3867        CanSupportAEP(getClientVersion(), supportedExtensions);
   3868 
   3869    return supportedExtensions;
   3870 }
   3871 
   3872 void Context::initCaps()
   3873 {
   3874    mState.mCaps = mImplementation->getNativeCaps();
   3875 
   3876    // TODO (http://anglebug.com/6010): mSupportedExtensions should not be modified here
   3877    mSupportedExtensions = generateSupportedExtensions();
   3878 
   3879    if (!mDisplay->getFrontendFeatures().allowCompressedFormats.enabled)
   3880    {
   3881        INFO() << "Limiting compressed format support.\n";
   3882 
   3883        mSupportedExtensions.compressedEACR11SignedTextureOES                = false;
   3884        mSupportedExtensions.compressedEACR11UnsignedTextureOES              = false;
   3885        mSupportedExtensions.compressedEACRG11SignedTextureOES               = false;
   3886        mSupportedExtensions.compressedEACRG11UnsignedTextureOES             = false;
   3887        mSupportedExtensions.compressedETC1RGB8SubTextureEXT                 = false;
   3888        mSupportedExtensions.compressedETC1RGB8TextureOES                    = false;
   3889        mSupportedExtensions.compressedETC2PunchthroughARGBA8TextureOES      = false;
   3890        mSupportedExtensions.compressedETC2PunchthroughASRGB8AlphaTextureOES = false;
   3891        mSupportedExtensions.compressedETC2RGB8TextureOES                    = false;
   3892        mSupportedExtensions.compressedETC2RGBA8TextureOES                   = false;
   3893        mSupportedExtensions.compressedETC2SRGB8Alpha8TextureOES             = false;
   3894        mSupportedExtensions.compressedETC2SRGB8TextureOES                   = false;
   3895        mSupportedExtensions.compressedTextureEtcANGLE                       = false;
   3896        mSupportedExtensions.textureCompressionPvrtcIMG                      = false;
   3897        mSupportedExtensions.pvrtcSRGBEXT                                    = false;
   3898        mSupportedExtensions.copyCompressedTextureCHROMIUM                   = false;
   3899        mSupportedExtensions.textureCompressionAstcHdrKHR                    = false;
   3900        mSupportedExtensions.textureCompressionAstcLdrKHR                    = false;
   3901        mSupportedExtensions.textureCompressionAstcOES                       = false;
   3902        mSupportedExtensions.textureCompressionBptcEXT                       = false;
   3903        mSupportedExtensions.textureCompressionDxt1EXT                       = false;
   3904        mSupportedExtensions.textureCompressionDxt3ANGLE                     = false;
   3905        mSupportedExtensions.textureCompressionDxt5ANGLE                     = false;
   3906        mSupportedExtensions.textureCompressionRgtcEXT                       = false;
   3907        mSupportedExtensions.textureCompressionS3tcSrgbEXT                   = false;
   3908        mSupportedExtensions.textureCompressionAstcSliced3dKHR               = false;
   3909        mSupportedExtensions.textureFilteringHintCHROMIUM                    = false;
   3910 
   3911        mState.mCaps.compressedTextureFormats.clear();
   3912    }
   3913 
   3914    mState.mExtensions = mSupportedExtensions;
   3915 
   3916    mState.mLimitations = mImplementation->getNativeLimitations();
   3917 
   3918    // GLES1 emulation: Initialize caps (Table 6.20 / 6.22 in the ES 1.1 spec)
   3919    if (getClientType() == EGL_OPENGL_API || getClientVersion() < Version(2, 0))
   3920    {
   3921        mState.mCaps.maxMultitextureUnits          = 4;
   3922        mState.mCaps.maxClipPlanes                 = 6;
   3923        mState.mCaps.maxLights                     = 8;
   3924        mState.mCaps.maxModelviewMatrixStackDepth  = Caps::GlobalMatrixStackDepth;
   3925        mState.mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
   3926        mState.mCaps.maxTextureMatrixStackDepth    = Caps::GlobalMatrixStackDepth;
   3927        mState.mCaps.minSmoothPointSize            = 1.0f;
   3928        mState.mCaps.maxSmoothPointSize            = 1.0f;
   3929        mState.mCaps.minSmoothLineWidth            = 1.0f;
   3930        mState.mCaps.maxSmoothLineWidth            = 1.0f;
   3931    }
   3932 
   3933    mState.mCaps.maxDebugMessageLength   = 1024;
   3934    mState.mCaps.maxDebugLoggedMessages  = 1024;
   3935    mState.mCaps.maxDebugGroupStackDepth = 1024;
   3936    mState.mCaps.maxLabelLength          = 1024;
   3937 
   3938    if (getClientVersion() < Version(3, 0))
   3939    {
   3940        mState.mCaps.maxViews = 1u;
   3941    }
   3942 
   3943 #if 0
   3944 // This logging can generate a lot of spam in test suites that create many contexts
   3945 #    define ANGLE_LOG_LIMITED_CAP(cap, limit)                                               \
   3946        INFO() << "Limiting " << #cap << " to implementation limit " << (limit) << " (was " \
   3947               << (cap) << ")."
   3948 #else
   3949 #    define ANGLE_LOG_LIMITED_CAP(cap, limit)
   3950 #endif
   3951 
   3952 #define ANGLE_LIMIT_CAP(cap, limit)            \
   3953    do                                         \
   3954    {                                          \
   3955        if ((cap) > (limit))                   \
   3956        {                                      \
   3957            ANGLE_LOG_LIMITED_CAP(cap, limit); \
   3958            (cap) = (limit);                   \
   3959        }                                      \
   3960    } while (0)
   3961 
   3962    // Apply/Verify implementation limits
   3963    ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, IMPLEMENTATION_MAX_DRAW_BUFFERS);
   3964    ANGLE_LIMIT_CAP(mState.mCaps.maxColorAttachments, IMPLEMENTATION_MAX_DRAW_BUFFERS);
   3965    ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttributes, MAX_VERTEX_ATTRIBS);
   3966    ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribStride,
   3967                    static_cast<GLint>(limits::kMaxVertexAttribStride));
   3968 
   3969    ASSERT(mState.mCaps.minAliasedPointSize >= 1.0f);
   3970 
   3971    if (getClientVersion() < ES_3_1)
   3972    {
   3973        mState.mCaps.maxVertexAttribBindings = mState.mCaps.maxVertexAttributes;
   3974    }
   3975    else
   3976    {
   3977        ANGLE_LIMIT_CAP(mState.mCaps.maxVertexAttribBindings, MAX_VERTEX_ATTRIB_BINDINGS);
   3978    }
   3979 
   3980    if (mWebGLContext && getLimitations().limitWebglMaxTextureSizeTo4096)
   3981    {
   3982        constexpr GLint kMaxTextureSize = 4096;
   3983        ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, kMaxTextureSize);
   3984        ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, kMaxTextureSize);
   3985        ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, kMaxTextureSize);
   3986        ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, kMaxTextureSize);
   3987        ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, kMaxTextureSize);
   3988    }
   3989 
   3990    ANGLE_LIMIT_CAP(mState.mCaps.max2DTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
   3991    ANGLE_LIMIT_CAP(mState.mCaps.maxCubeMapTextureSize, IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
   3992    ANGLE_LIMIT_CAP(mState.mCaps.max3DTextureSize, IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
   3993    ANGLE_LIMIT_CAP(mState.mCaps.maxArrayTextureLayers, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS);
   3994    ANGLE_LIMIT_CAP(mState.mCaps.maxRectangleTextureSize, IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
   3995 
   3996    ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Vertex],
   3997                    IMPLEMENTATION_MAX_VERTEX_SHADER_UNIFORM_BUFFERS);
   3998    ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Geometry],
   3999                    IMPLEMENTATION_MAX_GEOMETRY_SHADER_UNIFORM_BUFFERS);
   4000    ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Fragment],
   4001                    IMPLEMENTATION_MAX_FRAGMENT_SHADER_UNIFORM_BUFFERS);
   4002    ANGLE_LIMIT_CAP(mState.mCaps.maxShaderUniformBlocks[ShaderType::Compute],
   4003                    IMPLEMENTATION_MAX_COMPUTE_SHADER_UNIFORM_BUFFERS);
   4004    ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedUniformBlocks,
   4005                    IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
   4006    ANGLE_LIMIT_CAP(mState.mCaps.maxUniformBufferBindings,
   4007                    IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS);
   4008 
   4009    ANGLE_LIMIT_CAP(mState.mCaps.maxVertexOutputComponents, IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
   4010    ANGLE_LIMIT_CAP(mState.mCaps.maxFragmentInputComponents,
   4011                    IMPLEMENTATION_MAX_VARYING_VECTORS * 4);
   4012 
   4013    ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackInterleavedComponents,
   4014                    IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
   4015    ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateAttributes,
   4016                    IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
   4017    ANGLE_LIMIT_CAP(mState.mCaps.maxTransformFeedbackSeparateComponents,
   4018                    IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
   4019 
   4020    if (getClientVersion() < ES_3_2 && !mState.mExtensions.tessellationShaderEXT)
   4021    {
   4022        ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits,
   4023                        IMPLEMENTATION_MAX_ES31_ACTIVE_TEXTURES);
   4024    }
   4025    else
   4026    {
   4027        ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedTextureImageUnits,
   4028                        IMPLEMENTATION_MAX_ACTIVE_TEXTURES);
   4029    }
   4030 
   4031    for (ShaderType shaderType : AllShaderTypes())
   4032    {
   4033        ANGLE_LIMIT_CAP(mState.mCaps.maxShaderTextureImageUnits[shaderType],
   4034                        IMPLEMENTATION_MAX_SHADER_TEXTURES);
   4035    }
   4036 
   4037    ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, IMPLEMENTATION_MAX_IMAGE_UNITS);
   4038    ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedImageUniforms, IMPLEMENTATION_MAX_IMAGE_UNITS);
   4039    for (ShaderType shaderType : AllShaderTypes())
   4040    {
   4041        ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType],
   4042                        IMPLEMENTATION_MAX_IMAGE_UNITS);
   4043    }
   4044 
   4045    for (ShaderType shaderType : AllShaderTypes())
   4046    {
   4047        ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
   4048                        IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
   4049    }
   4050    ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings,
   4051                    IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
   4052    ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedAtomicCounterBuffers,
   4053                    IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
   4054 
   4055    for (ShaderType shaderType : AllShaderTypes())
   4056    {
   4057        ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
   4058                        IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
   4059    }
   4060    ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
   4061                    IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
   4062    ANGLE_LIMIT_CAP(mState.mCaps.maxCombinedShaderStorageBlocks,
   4063                    IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
   4064 
   4065    ANGLE_LIMIT_CAP(mState.mCaps.maxClipDistances, IMPLEMENTATION_MAX_CLIP_DISTANCES);
   4066 
   4067    ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferLayers, IMPLEMENTATION_MAX_FRAMEBUFFER_LAYERS);
   4068 
   4069    ANGLE_LIMIT_CAP(mState.mCaps.maxSampleMaskWords, IMPLEMENTATION_MAX_SAMPLE_MASK_WORDS);
   4070    ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, IMPLEMENTATION_MAX_SAMPLES);
   4071    ANGLE_LIMIT_CAP(mState.mCaps.maxFramebufferSamples, IMPLEMENTATION_MAX_SAMPLES);
   4072    ANGLE_LIMIT_CAP(mState.mCaps.maxColorTextureSamples, IMPLEMENTATION_MAX_SAMPLES);
   4073    ANGLE_LIMIT_CAP(mState.mCaps.maxDepthTextureSamples, IMPLEMENTATION_MAX_SAMPLES);
   4074    ANGLE_LIMIT_CAP(mState.mCaps.maxIntegerSamples, IMPLEMENTATION_MAX_SAMPLES);
   4075 
   4076    ANGLE_LIMIT_CAP(mState.mCaps.maxViews, IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS);
   4077 
   4078    ANGLE_LIMIT_CAP(mState.mCaps.maxDualSourceDrawBuffers,
   4079                    IMPLEMENTATION_MAX_DUAL_SOURCE_DRAW_BUFFERS);
   4080 
   4081    // WebGL compatibility
   4082    mState.mExtensions.webglCompatibilityANGLE = mWebGLContext;
   4083    for (const auto &extensionInfo : GetExtensionInfoMap())
   4084    {
   4085        // If the user has requested that extensions start disabled and they are requestable,
   4086        // disable them.
   4087        if (!mExtensionsEnabled && extensionInfo.second.Requestable)
   4088        {
   4089            mState.mExtensions.*(extensionInfo.second.ExtensionsMember) = false;
   4090        }
   4091    }
   4092 
   4093    // Hide emulated ETC1 extension from WebGL contexts.
   4094    if (mWebGLContext && getLimitations().emulatedEtc1)
   4095    {
   4096        mSupportedExtensions.compressedETC1RGB8SubTextureEXT = false;
   4097        mSupportedExtensions.compressedETC1RGB8TextureOES    = false;
   4098    }
   4099 
   4100    if (getLimitations().emulatedAstc)
   4101    {
   4102        // Hide emulated ASTC extension from WebGL contexts.
   4103        if (mWebGLContext)
   4104        {
   4105            mSupportedExtensions.textureCompressionAstcLdrKHR = false;
   4106            mState.mExtensions.textureCompressionAstcLdrKHR   = false;
   4107        }
   4108 #if !defined(ANGLE_HAS_ASTCENC)
   4109        // Don't expose emulated ASTC when it's not built.
   4110        mSupportedExtensions.textureCompressionAstcLdrKHR = false;
   4111        mState.mExtensions.textureCompressionAstcLdrKHR   = false;
   4112 #endif
   4113    }
   4114 
   4115    // If we're capturing application calls for replay, apply some feature limits to increase
   4116    // portability of the trace.
   4117    if (getShareGroup()->getFrameCaptureShared()->enabled() ||
   4118        getFrontendFeatures().enableCaptureLimits.enabled)
   4119    {
   4120        INFO() << "Limit some features because "
   4121               << (getShareGroup()->getFrameCaptureShared()->enabled()
   4122                       ? "FrameCapture is enabled"
   4123                       : "FrameCapture limits were forced")
   4124               << std::endl;
   4125 
   4126        if (!getFrontendFeatures().enableProgramBinaryForCapture.enabled)
   4127        {
   4128            // Some apps insist on being able to use glProgramBinary. For those, we'll allow the
   4129            // extension to remain on. Otherwise, force the extension off.
   4130            INFO() << "Disabling GL_OES_get_program_binary for trace portability";
   4131            mDisplay->overrideFrontendFeatures({"disable_program_binary"}, true);
   4132        }
   4133 
   4134        // Set to the most common limit per gpuinfo.org. Required for several platforms we test.
   4135        constexpr GLint maxImageUnits = 8;
   4136        INFO() << "Limiting image unit count to " << maxImageUnits;
   4137        ANGLE_LIMIT_CAP(mState.mCaps.maxImageUnits, maxImageUnits);
   4138        for (ShaderType shaderType : AllShaderTypes())
   4139        {
   4140            ANGLE_LIMIT_CAP(mState.mCaps.maxShaderImageUniforms[shaderType], maxImageUnits);
   4141        }
   4142 
   4143        // Set a large uniform buffer offset alignment that works on multiple platforms.
   4144        // The offset used by the trace needs to be divisible by the device's actual value.
   4145        // Values seen during development: ARM (16), Intel (32), Qualcomm (128), Nvidia (256)
   4146        constexpr GLint uniformBufferOffsetAlignment = 256;
   4147        ASSERT(uniformBufferOffsetAlignment % mState.mCaps.uniformBufferOffsetAlignment == 0);
   4148        INFO() << "Setting uniform buffer offset alignment to " << uniformBufferOffsetAlignment;
   4149        mState.mCaps.uniformBufferOffsetAlignment = uniformBufferOffsetAlignment;
   4150 
   4151        // Also limit texture buffer offset alignment, if enabled
   4152        if (mState.mExtensions.textureBufferAny())
   4153        {
   4154            constexpr GLint textureBufferOffsetAlignment =
   4155                gl::limits::kMinTextureBufferOffsetAlignment;
   4156            ASSERT(textureBufferOffsetAlignment % mState.mCaps.textureBufferOffsetAlignment == 0);
   4157            INFO() << "Setting texture buffer offset alignment to " << textureBufferOffsetAlignment;
   4158            mState.mCaps.textureBufferOffsetAlignment = textureBufferOffsetAlignment;
   4159        }
   4160 
   4161        INFO() << "Disabling GL_EXT_map_buffer_range and GL_OES_mapbuffer during capture, which "
   4162                  "are not supported on some native drivers";
   4163        mState.mExtensions.mapBufferRangeEXT = false;
   4164        mState.mExtensions.mapbufferOES      = false;
   4165 
   4166        INFO() << "Disabling GL_CHROMIUM_bind_uniform_location during capture, which is not "
   4167                  "supported on native drivers";
   4168        mState.mExtensions.bindUniformLocationCHROMIUM = false;
   4169 
   4170        INFO() << "Disabling GL_NV_shader_noperspective_interpolation during capture, which is not "
   4171                  "supported on some native drivers";
   4172        mState.mExtensions.shaderNoperspectiveInterpolationNV = false;
   4173 
   4174        INFO() << "Disabling GL_NV_framebuffer_blit during capture, which is not "
   4175                  "supported on some native drivers";
   4176        mState.mExtensions.framebufferBlitNV = false;
   4177 
   4178        // NVIDIA's Vulkan driver only supports 4 draw buffers
   4179        constexpr GLint maxDrawBuffers = 4;
   4180        INFO() << "Limiting draw buffer count to " << maxDrawBuffers;
   4181        ANGLE_LIMIT_CAP(mState.mCaps.maxDrawBuffers, maxDrawBuffers);
   4182 
   4183        // Unity based applications are sending down GL streams with undefined behavior.
   4184        // Disabling EGL_KHR_create_context_no_error (which enables a new EGL attrib) prevents that,
   4185        // but we don't have the infrastructure for disabling EGL extensions yet.
   4186        // Instead, disable GL_KHR_no_error (which disables exposing the GL extension), which
   4187        // prevents writing invalid calls to the capture.
   4188        INFO() << "Enabling validation to prevent invalid calls from being captured. This "
   4189                  "effectively disables GL_KHR_no_error and enables GL_ANGLE_robust_client_memory.";
   4190        mSkipValidation                            = false;
   4191        mState.mExtensions.noErrorKHR              = mSkipValidation;
   4192        mState.mExtensions.robustClientMemoryANGLE = !mSkipValidation;
   4193 
   4194        INFO() << "Disabling GL_OES_depth32 during capture, which is not widely supported on "
   4195                  "mobile";
   4196        mState.mExtensions.depth32OES = false;
   4197 
   4198        // Pixel 4 (Qualcomm) only supports 6 atomic counter buffer bindings.
   4199        constexpr GLint maxAtomicCounterBufferBindings = 6;
   4200        INFO() << "Limiting max atomic counter buffer bindings to "
   4201               << maxAtomicCounterBufferBindings;
   4202        ANGLE_LIMIT_CAP(mState.mCaps.maxAtomicCounterBufferBindings,
   4203                        maxAtomicCounterBufferBindings);
   4204        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   4205        {
   4206            ANGLE_LIMIT_CAP(mState.mCaps.maxShaderAtomicCounterBuffers[shaderType],
   4207                            maxAtomicCounterBufferBindings);
   4208        }
   4209 
   4210        // SwiftShader only supports 12 shader storage buffer bindings.
   4211        constexpr GLint maxShaderStorageBufferBindings = 12;
   4212        INFO() << "Limiting max shader storage buffer bindings to "
   4213               << maxShaderStorageBufferBindings;
   4214        ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBufferBindings,
   4215                        maxShaderStorageBufferBindings);
   4216        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   4217        {
   4218            ANGLE_LIMIT_CAP(mState.mCaps.maxShaderStorageBlocks[shaderType],
   4219                            maxShaderStorageBufferBindings);
   4220        }
   4221 
   4222        // Pixel 4 only supports GL_MAX_SAMPLES of 4
   4223        constexpr GLint maxSamples = 4;
   4224        INFO() << "Limiting GL_MAX_SAMPLES to " << maxSamples;
   4225        ANGLE_LIMIT_CAP(mState.mCaps.maxSamples, maxSamples);
   4226    }
   4227 
   4228    // Disable support for OES_get_program_binary
   4229    if (mDisplay->getFrontendFeatures().disableProgramBinary.enabled)
   4230    {
   4231        mState.mExtensions.getProgramBinaryOES = false;
   4232        mState.mCaps.shaderBinaryFormats.clear();
   4233        mState.mCaps.programBinaryFormats.clear();
   4234        mMemoryProgramCache = nullptr;
   4235    }
   4236 
   4237    if (mSupportedExtensions.shaderPixelLocalStorageANGLE)
   4238    {
   4239        int maxDrawableAttachments =
   4240            std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments);
   4241        ShPixelLocalStorageType plsType = mImplementation->getNativePixelLocalStorageType();
   4242        if (ShPixelLocalStorageTypeUsesImages(plsType))
   4243        {
   4244            mState.mCaps.maxPixelLocalStoragePlanes =
   4245                mState.mCaps.maxShaderImageUniforms[ShaderType::Fragment];
   4246            ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes,
   4247                            IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
   4248            mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage =
   4249                mState.mCaps.maxColorAttachments;
   4250            mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = std::min<GLint>(
   4251                mState.mCaps.maxPixelLocalStoragePlanes +
   4252                    std::min(mState.mCaps.maxDrawBuffers, mState.mCaps.maxColorAttachments),
   4253                mState.mCaps.maxCombinedShaderOutputResources);
   4254        }
   4255        else
   4256        {
   4257            ASSERT(plsType == ShPixelLocalStorageType::FramebufferFetch);
   4258            mState.mCaps.maxPixelLocalStoragePlanes = maxDrawableAttachments;
   4259            ANGLE_LIMIT_CAP(mState.mCaps.maxPixelLocalStoragePlanes,
   4260                            IMPLEMENTATION_MAX_PIXEL_LOCAL_STORAGE_PLANES);
   4261            if (!mSupportedExtensions.drawBuffersIndexedAny())
   4262            {
   4263                // When pixel local storage is implemented as framebuffer attachments, we need to
   4264                // disable color masks and blending to its attachments. If the backend context
   4265                // doesn't have indexed blend and color mask support, then we will have have to
   4266                // disable them globally. This also means the application can't have its own draw
   4267                // buffers while PLS is active.
   4268                mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage = 0;
   4269            }
   4270            else
   4271            {
   4272                mState.mCaps.maxColorAttachmentsWithActivePixelLocalStorage =
   4273                    maxDrawableAttachments - 1;
   4274            }
   4275            mState.mCaps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes = maxDrawableAttachments;
   4276        }
   4277    }
   4278 
   4279 #undef ANGLE_LIMIT_CAP
   4280 #undef ANGLE_LOG_CAP_LIMIT
   4281 
   4282    // Generate texture caps
   4283    updateCaps();
   4284 }
   4285 
   4286 void Context::updateCaps()
   4287 {
   4288    mState.mCaps.compressedTextureFormats.clear();
   4289    mState.mTextureCaps.clear();
   4290 
   4291    for (GLenum sizedInternalFormat : GetAllSizedInternalFormats())
   4292    {
   4293        TextureCaps formatCaps = mImplementation->getNativeTextureCaps().get(sizedInternalFormat);
   4294        const InternalFormat &formatInfo = GetSizedInternalFormatInfo(sizedInternalFormat);
   4295 
   4296        // Update the format caps based on the client version and extensions.
   4297        // Caps are AND'd with the renderer caps because some core formats are still unsupported in
   4298        // ES3.
   4299        formatCaps.texturable = formatCaps.texturable &&
   4300                                formatInfo.textureSupport(getClientVersion(), mState.mExtensions);
   4301        formatCaps.filterable = formatCaps.filterable &&
   4302                                formatInfo.filterSupport(getClientVersion(), mState.mExtensions);
   4303        formatCaps.textureAttachment =
   4304            formatCaps.textureAttachment &&
   4305            formatInfo.textureAttachmentSupport(getClientVersion(), mState.mExtensions);
   4306        formatCaps.renderbuffer =
   4307            formatCaps.renderbuffer &&
   4308            formatInfo.renderbufferSupport(getClientVersion(), mState.mExtensions);
   4309        formatCaps.blendable =
   4310            formatCaps.blendable && formatInfo.blendSupport(getClientVersion(), mState.mExtensions);
   4311 
   4312        // OpenGL ES does not support multisampling with non-rendererable formats
   4313        // OpenGL ES 3.0 or prior does not support multisampling with integer formats
   4314        if (!formatCaps.renderbuffer ||
   4315            (getClientVersion() < ES_3_1 && !mState.mExtensions.textureMultisampleANGLE &&
   4316             formatInfo.isInt()))
   4317        {
   4318            formatCaps.sampleCounts.clear();
   4319        }
   4320        else
   4321        {
   4322            // We may have limited the max samples for some required renderbuffer formats due to
   4323            // non-conformant formats. In this case MAX_SAMPLES needs to be lowered accordingly.
   4324            GLuint formatMaxSamples = formatCaps.getMaxSamples();
   4325 
   4326            // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers
   4327            // in these required formats with up to the value of MAX_SAMPLES multisamples, with the
   4328            // exception of signed and unsigned integer formats."
   4329            if (!formatInfo.isInt() && formatInfo.isRequiredRenderbufferFormat(getClientVersion()))
   4330            {
   4331                ASSERT(getClientVersion() < ES_3_0 || formatMaxSamples >= 4);
   4332                mState.mCaps.maxSamples =
   4333                    std::min(static_cast<GLuint>(mState.mCaps.maxSamples), formatMaxSamples);
   4334            }
   4335 
   4336            // Handle GLES 3.1 MAX_*_SAMPLES values similarly to MAX_SAMPLES.
   4337            if (getClientVersion() >= ES_3_1 || mState.mExtensions.textureMultisampleANGLE)
   4338            {
   4339                // GLES 3.1 section 9.2.5: "Implementations must support creation of renderbuffers
   4340                // in these required formats with up to the value of MAX_SAMPLES multisamples, with
   4341                // the exception that the signed and unsigned integer formats are required only to
   4342                // support creation of renderbuffers with up to the value of MAX_INTEGER_SAMPLES
   4343                // multisamples, which must be at least one."
   4344                if (formatInfo.isInt())
   4345                {
   4346                    mState.mCaps.maxIntegerSamples = std::min(
   4347                        static_cast<GLuint>(mState.mCaps.maxIntegerSamples), formatMaxSamples);
   4348                }
   4349 
   4350                // GLES 3.1 section 19.3.1.
   4351                if (formatCaps.texturable)
   4352                {
   4353                    if (formatInfo.depthBits > 0)
   4354                    {
   4355                        mState.mCaps.maxDepthTextureSamples =
   4356                            std::min(static_cast<GLuint>(mState.mCaps.maxDepthTextureSamples),
   4357                                     formatMaxSamples);
   4358                    }
   4359                    else if (formatInfo.redBits > 0)
   4360                    {
   4361                        mState.mCaps.maxColorTextureSamples =
   4362                            std::min(static_cast<GLuint>(mState.mCaps.maxColorTextureSamples),
   4363                                     formatMaxSamples);
   4364                    }
   4365                }
   4366            }
   4367        }
   4368 
   4369        if (formatCaps.texturable && (formatInfo.compressed || formatInfo.paletted))
   4370        {
   4371            mState.mCaps.compressedTextureFormats.push_back(sizedInternalFormat);
   4372        }
   4373 
   4374        mState.mTextureCaps.insert(sizedInternalFormat, formatCaps);
   4375    }
   4376 
   4377    // If program binary is disabled, blank out the memory cache pointer.
   4378    if (!mSupportedExtensions.getProgramBinaryOES)
   4379    {
   4380        mMemoryProgramCache = nullptr;
   4381    }
   4382 
   4383    // Compute which buffer types are allowed
   4384    mValidBufferBindings.reset();
   4385    mValidBufferBindings.set(BufferBinding::ElementArray);
   4386    mValidBufferBindings.set(BufferBinding::Array);
   4387 
   4388    if (mState.mExtensions.pixelBufferObjectNV || getClientVersion() >= ES_3_0)
   4389    {
   4390        mValidBufferBindings.set(BufferBinding::PixelPack);
   4391        mValidBufferBindings.set(BufferBinding::PixelUnpack);
   4392    }
   4393 
   4394    if (getClientVersion() >= ES_3_0)
   4395    {
   4396        mValidBufferBindings.set(BufferBinding::CopyRead);
   4397        mValidBufferBindings.set(BufferBinding::CopyWrite);
   4398        mValidBufferBindings.set(BufferBinding::TransformFeedback);
   4399        mValidBufferBindings.set(BufferBinding::Uniform);
   4400    }
   4401 
   4402    if (getClientVersion() >= ES_3_1)
   4403    {
   4404        mValidBufferBindings.set(BufferBinding::AtomicCounter);
   4405        mValidBufferBindings.set(BufferBinding::ShaderStorage);
   4406        mValidBufferBindings.set(BufferBinding::DrawIndirect);
   4407        mValidBufferBindings.set(BufferBinding::DispatchIndirect);
   4408    }
   4409 
   4410    if (getClientVersion() >= ES_3_2 || mState.mExtensions.textureBufferAny())
   4411    {
   4412        mValidBufferBindings.set(BufferBinding::Texture);
   4413    }
   4414 
   4415    if (!mState.mExtensions.parallelShaderCompileKHR)
   4416    {
   4417        mSingleThreadPool = angle::WorkerThreadPool::Create(false);
   4418    }
   4419    mMultiThreadPool = angle::WorkerThreadPool::Create(
   4420        mState.mExtensions.parallelShaderCompileKHR ||
   4421        getFrontendFeatures().enableCompressingPipelineCacheInThreadPool.enabled);
   4422 
   4423    // Reinitialize some dirty bits that depend on extensions.
   4424    if (mState.isRobustResourceInitEnabled())
   4425    {
   4426        mDrawDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
   4427        mDrawDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
   4428        mDrawDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
   4429        mBlitDirtyObjects.set(State::DIRTY_OBJECT_DRAW_ATTACHMENTS);
   4430        mBlitDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
   4431        mComputeDirtyObjects.set(State::DIRTY_OBJECT_TEXTURES_INIT);
   4432        mComputeDirtyObjects.set(State::DIRTY_OBJECT_IMAGES_INIT);
   4433        mReadPixelsDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
   4434        mCopyImageDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
   4435        mCopyImageDirtyObjects.set(State::DIRTY_OBJECT_READ_ATTACHMENTS);
   4436    }
   4437 
   4438    // We need to validate buffer bounds if we are in a WebGL or robust access context and the
   4439    // back-end does not support robust buffer access behaviour.
   4440    mBufferAccessValidationEnabled = (!mSupportedExtensions.robustBufferAccessBehaviorKHR &&
   4441                                      (mState.isWebGL() || mState.hasRobustAccess()));
   4442 
   4443    // Cache this in the VertexArrays. They need to check it in state change notifications.
   4444    for (auto vaoIter : mVertexArrayMap)
   4445    {
   4446        VertexArray *vao = vaoIter.second;
   4447        vao->setBufferAccessValidationEnabled(mBufferAccessValidationEnabled);
   4448    }
   4449 
   4450    // Reinitialize state cache after extension changes.
   4451    mStateCache.initialize(this);
   4452 }
   4453 
   4454 bool Context::noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const
   4455 {
   4456    return (instanceCount == 0) || noopDraw(mode, count);
   4457 }
   4458 
   4459 angle::Result Context::prepareForClear(GLbitfield mask)
   4460 {
   4461    // Sync the draw framebuffer manually after the clear attachments.
   4462    ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearAttachmentsInitialized(this, mask));
   4463    return syncStateForClear();
   4464 }
   4465 
   4466 angle::Result Context::prepareForClearBuffer(GLenum buffer, GLint drawbuffer)
   4467 {
   4468    // Sync the draw framebuffer manually after the clear attachments.
   4469    ANGLE_TRY(mState.getDrawFramebuffer()->ensureClearBufferAttachmentsInitialized(this, buffer,
   4470                                                                                   drawbuffer));
   4471    return syncStateForClear();
   4472 }
   4473 
   4474 ANGLE_INLINE angle::Result Context::prepareForCopyImage()
   4475 {
   4476    ANGLE_TRY(syncDirtyObjects(mCopyImageDirtyObjects, Command::CopyImage));
   4477    return syncDirtyBits(mCopyImageDirtyBits, Command::CopyImage);
   4478 }
   4479 
   4480 ANGLE_INLINE angle::Result Context::prepareForDispatch()
   4481 {
   4482    // Converting a PPO from graphics to compute requires re-linking it.
   4483    // The compute shader must have successfully linked before being included in the PPO, so no link
   4484    // errors that would have been caught during validation should be possible when re-linking the
   4485    // PPO with the compute shader.
   4486    Program *program          = mState.getProgram();
   4487    ProgramPipeline *pipeline = mState.getProgramPipeline();
   4488    if (!program && pipeline)
   4489    {
   4490        // Linking the PPO can't fail due to a validation error within the compute program,
   4491        // since it successfully linked already in order to become part of the PPO in the first
   4492        // place.
   4493        pipeline->resolveLink(this);
   4494        ANGLE_CHECK(this, pipeline->isLinked(), "Program pipeline link failed",
   4495                    GL_INVALID_OPERATION);
   4496    }
   4497 
   4498    ANGLE_TRY(syncDirtyObjects(mComputeDirtyObjects, Command::Dispatch));
   4499    return syncDirtyBits(mComputeDirtyBits, Command::Dispatch);
   4500 }
   4501 
   4502 angle::Result Context::prepareForInvalidate(GLenum target)
   4503 {
   4504    // Only sync the FBO that's being invalidated.  Per the GLES3 spec, GL_FRAMEBUFFER is equivalent
   4505    // to GL_DRAW_FRAMEBUFFER for the purposes of invalidation.
   4506    GLenum effectiveTarget = target;
   4507    if (effectiveTarget == GL_FRAMEBUFFER)
   4508    {
   4509        effectiveTarget = GL_DRAW_FRAMEBUFFER;
   4510    }
   4511    ANGLE_TRY(mState.syncDirtyObject(this, effectiveTarget));
   4512    return syncDirtyBits(effectiveTarget == GL_READ_FRAMEBUFFER ? mReadInvalidateDirtyBits
   4513                                                                : mDrawInvalidateDirtyBits,
   4514                         Command::Invalidate);
   4515 }
   4516 
   4517 angle::Result Context::syncState(const State::DirtyBits &bitMask,
   4518                                 const State::DirtyObjects &objectMask,
   4519                                 Command command)
   4520 {
   4521    ANGLE_TRY(syncDirtyObjects(objectMask, command));
   4522    ANGLE_TRY(syncDirtyBits(bitMask, command));
   4523    return angle::Result::Continue;
   4524 }
   4525 
   4526 void Context::blitFramebuffer(GLint srcX0,
   4527                              GLint srcY0,
   4528                              GLint srcX1,
   4529                              GLint srcY1,
   4530                              GLint dstX0,
   4531                              GLint dstY0,
   4532                              GLint dstX1,
   4533                              GLint dstY1,
   4534                              GLbitfield mask,
   4535                              GLenum filter)
   4536 {
   4537    if (mask == 0)
   4538    {
   4539        // ES3.0 spec, section 4.3.2 specifies that a mask of zero is valid and no
   4540        // buffers are copied.
   4541        return;
   4542    }
   4543 
   4544    Framebuffer *drawFramebuffer = mState.getDrawFramebuffer();
   4545    ASSERT(drawFramebuffer);
   4546 
   4547    // Note that blitting is called against draw framebuffer.
   4548    // See the code in gl::Context::blitFramebuffer.
   4549    if ((mask & GL_COLOR_BUFFER_BIT) && !drawFramebuffer->hasEnabledDrawBuffer())
   4550    {
   4551        mask &= ~GL_COLOR_BUFFER_BIT;
   4552    }
   4553 
   4554    if ((mask & GL_STENCIL_BUFFER_BIT) &&
   4555        drawFramebuffer->getState().getStencilAttachment() == nullptr)
   4556    {
   4557        mask &= ~GL_STENCIL_BUFFER_BIT;
   4558    }
   4559 
   4560    if ((mask & GL_DEPTH_BUFFER_BIT) && drawFramebuffer->getState().getDepthAttachment() == nullptr)
   4561    {
   4562        mask &= ~GL_DEPTH_BUFFER_BIT;
   4563    }
   4564 
   4565    // Early out if none of the specified attachments exist or are enabled.
   4566    if (mask == 0)
   4567    {
   4568        ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW,
   4569                           "BlitFramebuffer called for non-existing buffers");
   4570        return;
   4571    }
   4572 
   4573    Rectangle srcArea(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
   4574    Rectangle dstArea(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
   4575 
   4576    if (dstArea.width == 0 || dstArea.height == 0)
   4577    {
   4578        return;
   4579    }
   4580 
   4581    ANGLE_CONTEXT_TRY(syncStateForBlit(mask));
   4582    ANGLE_CONTEXT_TRY(drawFramebuffer->blit(this, srcArea, dstArea, mask, filter));
   4583 }
   4584 
   4585 void Context::blitFramebufferNV(GLint srcX0,
   4586                                GLint srcY0,
   4587                                GLint srcX1,
   4588                                GLint srcY1,
   4589                                GLint dstX0,
   4590                                GLint dstY0,
   4591                                GLint dstX1,
   4592                                GLint dstY1,
   4593                                GLbitfield mask,
   4594                                GLenum filter)
   4595 {
   4596    blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
   4597 }
   4598 
   4599 void Context::clear(GLbitfield mask)
   4600 {
   4601    if (mState.isRasterizerDiscardEnabled())
   4602    {
   4603        return;
   4604    }
   4605 
   4606    // Noop empty scissors.
   4607    if (IsEmptyScissor(mState))
   4608    {
   4609        return;
   4610    }
   4611 
   4612    // Remove clear bits that are ineffective. An effective clear changes at least one fragment. If
   4613    // color/depth/stencil masks make the clear ineffective we skip it altogether.
   4614 
   4615    // If all color channels in all draw buffers are masked, don't attempt to clear color.
   4616    if (mState.allActiveDrawBufferChannelsMasked())
   4617    {
   4618        mask &= ~GL_COLOR_BUFFER_BIT;
   4619    }
   4620 
   4621    // If depth write is disabled, don't attempt to clear depth.
   4622    if (mState.getDrawFramebuffer()->getDepthAttachment() == nullptr ||
   4623        !mState.getDepthStencilState().depthMask)
   4624    {
   4625        mask &= ~GL_DEPTH_BUFFER_BIT;
   4626    }
   4627 
   4628    // If all stencil bits are masked, don't attempt to clear stencil.
   4629    if (mState.getDrawFramebuffer()->getStencilAttachment() == nullptr ||
   4630        (angle::BitMask<uint32_t>(
   4631             mState.getDrawFramebuffer()->getStencilAttachment()->getStencilSize()) &
   4632         mState.getDepthStencilState().stencilWritemask) == 0)
   4633    {
   4634        mask &= ~GL_STENCIL_BUFFER_BIT;
   4635    }
   4636 
   4637    if (mask == 0)
   4638    {
   4639        ANGLE_PERF_WARNING(mState.getDebug(), GL_DEBUG_SEVERITY_LOW,
   4640                           "Clear called for non-existing buffers");
   4641        return;
   4642    }
   4643 
   4644    ANGLE_CONTEXT_TRY(prepareForClear(mask));
   4645    ANGLE_CONTEXT_TRY(mState.getDrawFramebuffer()->clear(this, mask));
   4646 }
   4647 
   4648 bool Context::isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const
   4649 {
   4650    switch (buffer)
   4651    {
   4652        case GL_COLOR:
   4653            return IsColorMaskedOut(mState.getBlendStateExt(), drawbuffer);
   4654        case GL_DEPTH:
   4655            return mState.getDepthStencilState().isDepthMaskedOut();
   4656        case GL_STENCIL:
   4657            return mState.getDepthStencilState().isStencilMaskedOut();
   4658        case GL_DEPTH_STENCIL:
   4659            return mState.getDepthStencilState().isDepthMaskedOut() &&
   4660                   mState.getDepthStencilState().isStencilMaskedOut();
   4661        default:
   4662            UNREACHABLE();
   4663            return true;
   4664    }
   4665 }
   4666 
   4667 bool Context::noopClearBuffer(GLenum buffer, GLint drawbuffer) const
   4668 {
   4669    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
   4670 
   4671    return !IsClearBufferEnabled(framebufferObject->getState(), buffer, drawbuffer) ||
   4672           mState.isRasterizerDiscardEnabled() || isClearBufferMaskedOut(buffer, drawbuffer) ||
   4673           IsEmptyScissor(mState);
   4674 }
   4675 
   4676 void Context::clearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *values)
   4677 {
   4678    if (noopClearBuffer(buffer, drawbuffer))
   4679    {
   4680        return;
   4681    }
   4682 
   4683    Framebuffer *framebufferObject          = mState.getDrawFramebuffer();
   4684    const FramebufferAttachment *attachment = nullptr;
   4685    if (buffer == GL_DEPTH)
   4686    {
   4687        attachment = framebufferObject->getDepthAttachment();
   4688    }
   4689    else if (buffer == GL_COLOR &&
   4690             static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
   4691    {
   4692        attachment = framebufferObject->getColorAttachment(drawbuffer);
   4693    }
   4694    // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
   4695    // that the backend doesn't need to take this case into account.
   4696    if (!attachment)
   4697    {
   4698        return;
   4699    }
   4700    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
   4701    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfv(this, buffer, drawbuffer, values));
   4702 }
   4703 
   4704 void Context::clearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *values)
   4705 {
   4706    if (noopClearBuffer(buffer, drawbuffer))
   4707    {
   4708        return;
   4709    }
   4710 
   4711    Framebuffer *framebufferObject          = mState.getDrawFramebuffer();
   4712    const FramebufferAttachment *attachment = nullptr;
   4713    if (buffer == GL_COLOR &&
   4714        static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
   4715    {
   4716        attachment = framebufferObject->getColorAttachment(drawbuffer);
   4717    }
   4718    // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
   4719    // that the backend doesn't need to take this case into account.
   4720    if (!attachment)
   4721    {
   4722        return;
   4723    }
   4724    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
   4725    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferuiv(this, buffer, drawbuffer, values));
   4726 }
   4727 
   4728 void Context::clearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *values)
   4729 {
   4730    if (noopClearBuffer(buffer, drawbuffer))
   4731    {
   4732        return;
   4733    }
   4734 
   4735    Framebuffer *framebufferObject          = mState.getDrawFramebuffer();
   4736    const FramebufferAttachment *attachment = nullptr;
   4737    if (buffer == GL_STENCIL)
   4738    {
   4739        attachment = framebufferObject->getStencilAttachment();
   4740    }
   4741    else if (buffer == GL_COLOR &&
   4742             static_cast<size_t>(drawbuffer) < framebufferObject->getNumColorAttachments())
   4743    {
   4744        attachment = framebufferObject->getColorAttachment(drawbuffer);
   4745    }
   4746    // It's not an error to try to clear a non-existent buffer, but it's a no-op. We early out so
   4747    // that the backend doesn't need to take this case into account.
   4748    if (!attachment)
   4749    {
   4750        return;
   4751    }
   4752    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
   4753    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferiv(this, buffer, drawbuffer, values));
   4754 }
   4755 
   4756 void Context::clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
   4757 {
   4758    if (noopClearBuffer(buffer, drawbuffer))
   4759    {
   4760        return;
   4761    }
   4762 
   4763    Framebuffer *framebufferObject = mState.getDrawFramebuffer();
   4764    ASSERT(framebufferObject);
   4765 
   4766    // If a buffer is not present, the clear has no effect
   4767    if (framebufferObject->getDepthAttachment() == nullptr &&
   4768        framebufferObject->getStencilAttachment() == nullptr)
   4769    {
   4770        return;
   4771    }
   4772 
   4773    ANGLE_CONTEXT_TRY(prepareForClearBuffer(buffer, drawbuffer));
   4774    ANGLE_CONTEXT_TRY(framebufferObject->clearBufferfi(this, buffer, drawbuffer, depth, stencil));
   4775 }
   4776 
   4777 void Context::readPixels(GLint x,
   4778                         GLint y,
   4779                         GLsizei width,
   4780                         GLsizei height,
   4781                         GLenum format,
   4782                         GLenum type,
   4783                         void *pixels)
   4784 {
   4785    if (width == 0 || height == 0)
   4786    {
   4787        return;
   4788    }
   4789 
   4790    ANGLE_CONTEXT_TRY(syncStateForReadPixels());
   4791 
   4792    Framebuffer *readFBO = mState.getReadFramebuffer();
   4793    ASSERT(readFBO);
   4794 
   4795    Rectangle area(x, y, width, height);
   4796    PixelPackState packState = mState.getPackState();
   4797    Buffer *packBuffer       = mState.getTargetBuffer(gl::BufferBinding::PixelPack);
   4798    ANGLE_CONTEXT_TRY(readFBO->readPixels(this, area, format, type, packState, packBuffer, pixels));
   4799 }
   4800 
   4801 void Context::readPixelsRobust(GLint x,
   4802                               GLint y,
   4803                               GLsizei width,
   4804                               GLsizei height,
   4805                               GLenum format,
   4806                               GLenum type,
   4807                               GLsizei bufSize,
   4808                               GLsizei *length,
   4809                               GLsizei *columns,
   4810                               GLsizei *rows,
   4811                               void *pixels)
   4812 {
   4813    readPixels(x, y, width, height, format, type, pixels);
   4814 }
   4815 
   4816 void Context::readnPixelsRobust(GLint x,
   4817                                GLint y,
   4818                                GLsizei width,
   4819                                GLsizei height,
   4820                                GLenum format,
   4821                                GLenum type,
   4822                                GLsizei bufSize,
   4823                                GLsizei *length,
   4824                                GLsizei *columns,
   4825                                GLsizei *rows,
   4826                                void *data)
   4827 {
   4828    readPixels(x, y, width, height, format, type, data);
   4829 }
   4830 
   4831 void Context::copyTexImage2D(TextureTarget target,
   4832                             GLint level,
   4833                             GLenum internalformat,
   4834                             GLint x,
   4835                             GLint y,
   4836                             GLsizei width,
   4837                             GLsizei height,
   4838                             GLint border)
   4839 {
   4840    ANGLE_CONTEXT_TRY(prepareForCopyImage());
   4841 
   4842    Rectangle sourceArea(x, y, width, height);
   4843 
   4844    Framebuffer *framebuffer = mState.getReadFramebuffer();
   4845    Texture *texture         = getTextureByTarget(target);
   4846    ANGLE_CONTEXT_TRY(
   4847        texture->copyImage(this, target, level, sourceArea, internalformat, framebuffer));
   4848 }
   4849 
   4850 void Context::copyTexSubImage2D(TextureTarget target,
   4851                                GLint level,
   4852                                GLint xoffset,
   4853                                GLint yoffset,
   4854                                GLint x,
   4855                                GLint y,
   4856                                GLsizei width,
   4857                                GLsizei height)
   4858 {
   4859    if (width == 0 || height == 0)
   4860    {
   4861        return;
   4862    }
   4863 
   4864    ANGLE_CONTEXT_TRY(prepareForCopyImage());
   4865 
   4866    Offset destOffset(xoffset, yoffset, 0);
   4867    Rectangle sourceArea(x, y, width, height);
   4868 
   4869    ImageIndex index = ImageIndex::MakeFromTarget(target, level, 1);
   4870 
   4871    Framebuffer *framebuffer = mState.getReadFramebuffer();
   4872    Texture *texture         = getTextureByTarget(target);
   4873    ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
   4874 }
   4875 
   4876 void Context::copyTexSubImage3D(TextureTarget target,
   4877                                GLint level,
   4878                                GLint xoffset,
   4879                                GLint yoffset,
   4880                                GLint zoffset,
   4881                                GLint x,
   4882                                GLint y,
   4883                                GLsizei width,
   4884                                GLsizei height)
   4885 {
   4886    if (width == 0 || height == 0)
   4887    {
   4888        return;
   4889    }
   4890 
   4891    ANGLE_CONTEXT_TRY(prepareForCopyImage());
   4892 
   4893    Offset destOffset(xoffset, yoffset, zoffset);
   4894    Rectangle sourceArea(x, y, width, height);
   4895 
   4896    ImageIndex index = ImageIndex::MakeFromType(TextureTargetToType(target), level, zoffset);
   4897 
   4898    Framebuffer *framebuffer = mState.getReadFramebuffer();
   4899    Texture *texture         = getTextureByTarget(target);
   4900    ANGLE_CONTEXT_TRY(texture->copySubImage(this, index, destOffset, sourceArea, framebuffer));
   4901 }
   4902 
   4903 void Context::copyImageSubData(GLuint srcName,
   4904                               GLenum srcTarget,
   4905                               GLint srcLevel,
   4906                               GLint srcX,
   4907                               GLint srcY,
   4908                               GLint srcZ,
   4909                               GLuint dstName,
   4910                               GLenum dstTarget,
   4911                               GLint dstLevel,
   4912                               GLint dstX,
   4913                               GLint dstY,
   4914                               GLint dstZ,
   4915                               GLsizei srcWidth,
   4916                               GLsizei srcHeight,
   4917                               GLsizei srcDepth)
   4918 {
   4919    // if copy region is zero, the copy is a successful no-op
   4920    if ((srcWidth == 0) || (srcHeight == 0) || (srcDepth == 0))
   4921    {
   4922        return;
   4923    }
   4924 
   4925    if (srcTarget == GL_RENDERBUFFER)
   4926    {
   4927        // Source target is a Renderbuffer
   4928        Renderbuffer *readBuffer = getRenderbuffer(PackParam<RenderbufferID>(srcName));
   4929        if (dstTarget == GL_RENDERBUFFER)
   4930        {
   4931            // Destination target is a Renderbuffer
   4932            Renderbuffer *writeBuffer = getRenderbuffer(PackParam<RenderbufferID>(dstName));
   4933 
   4934            // Copy Renderbuffer to Renderbuffer
   4935            ANGLE_CONTEXT_TRY(writeBuffer->copyRenderbufferSubData(
   4936                this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
   4937                srcHeight, srcDepth));
   4938        }
   4939        else
   4940        {
   4941            // Destination target is a Texture
   4942            ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
   4943                   dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);
   4944 
   4945            Texture *writeTexture = getTexture(PackParam<TextureID>(dstName));
   4946            ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));
   4947 
   4948            // Copy Renderbuffer to Texture
   4949            ANGLE_CONTEXT_TRY(writeTexture->copyRenderbufferSubData(
   4950                this, readBuffer, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
   4951                srcHeight, srcDepth));
   4952        }
   4953    }
   4954    else
   4955    {
   4956        // Source target is a Texture
   4957        ASSERT(srcTarget == GL_TEXTURE_2D || srcTarget == GL_TEXTURE_2D_ARRAY ||
   4958               srcTarget == GL_TEXTURE_3D || srcTarget == GL_TEXTURE_CUBE_MAP);
   4959 
   4960        Texture *readTexture = getTexture(PackParam<TextureID>(srcName));
   4961        ANGLE_CONTEXT_TRY(syncTextureForCopy(readTexture));
   4962 
   4963        if (dstTarget == GL_RENDERBUFFER)
   4964        {
   4965            // Destination target is a Renderbuffer
   4966            Renderbuffer *writeBuffer = getRenderbuffer(PackParam<RenderbufferID>(dstName));
   4967 
   4968            // Copy Texture to Renderbuffer
   4969            ANGLE_CONTEXT_TRY(writeBuffer->copyTextureSubData(this, readTexture, srcLevel, srcX,
   4970                                                              srcY, srcZ, dstLevel, dstX, dstY,
   4971                                                              dstZ, srcWidth, srcHeight, srcDepth));
   4972        }
   4973        else
   4974        {
   4975            // Destination target is a Texture
   4976            ASSERT(dstTarget == GL_TEXTURE_2D || dstTarget == GL_TEXTURE_2D_ARRAY ||
   4977                   dstTarget == GL_TEXTURE_3D || dstTarget == GL_TEXTURE_CUBE_MAP);
   4978 
   4979            Texture *writeTexture = getTexture(PackParam<TextureID>(dstName));
   4980            ANGLE_CONTEXT_TRY(syncTextureForCopy(writeTexture));
   4981 
   4982            // Copy Texture to Texture
   4983            ANGLE_CONTEXT_TRY(writeTexture->copyTextureSubData(
   4984                this, readTexture, srcLevel, srcX, srcY, srcZ, dstLevel, dstX, dstY, dstZ, srcWidth,
   4985                srcHeight, srcDepth));
   4986        }
   4987    }
   4988 }
   4989 
   4990 void Context::framebufferTexture2D(GLenum target,
   4991                                   GLenum attachment,
   4992                                   TextureTarget textarget,
   4993                                   TextureID texture,
   4994                                   GLint level)
   4995 {
   4996    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   4997    ASSERT(framebuffer);
   4998 
   4999    if (texture.value != 0)
   5000    {
   5001        Texture *textureObj = getTexture(texture);
   5002        ImageIndex index    = ImageIndex::MakeFromTarget(textarget, level, 1);
   5003        framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
   5004    }
   5005    else
   5006    {
   5007        framebuffer->resetAttachment(this, attachment);
   5008    }
   5009 
   5010    mState.setObjectDirty(target);
   5011 }
   5012 
   5013 void Context::framebufferTexture3D(GLenum target,
   5014                                   GLenum attachment,
   5015                                   TextureTarget textargetPacked,
   5016                                   TextureID texture,
   5017                                   GLint level,
   5018                                   GLint zoffset)
   5019 {
   5020    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5021    ASSERT(framebuffer);
   5022 
   5023    if (texture.value != 0)
   5024    {
   5025        Texture *textureObj = getTexture(texture);
   5026        ImageIndex index    = ImageIndex::Make3D(level, zoffset);
   5027        framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
   5028    }
   5029    else
   5030    {
   5031        framebuffer->resetAttachment(this, attachment);
   5032    }
   5033 
   5034    mState.setObjectDirty(target);
   5035 }
   5036 
   5037 void Context::framebufferRenderbuffer(GLenum target,
   5038                                      GLenum attachment,
   5039                                      GLenum renderbuffertarget,
   5040                                      RenderbufferID renderbuffer)
   5041 {
   5042    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5043    ASSERT(framebuffer);
   5044 
   5045    if (renderbuffer.value != 0)
   5046    {
   5047        Renderbuffer *renderbufferObject = getRenderbuffer(renderbuffer);
   5048        GLsizei rbSamples                = renderbufferObject->getState().getSamples();
   5049 
   5050        framebuffer->setAttachmentMultisample(this, GL_RENDERBUFFER, attachment, gl::ImageIndex(),
   5051                                              renderbufferObject, rbSamples);
   5052    }
   5053    else
   5054    {
   5055        framebuffer->resetAttachment(this, attachment);
   5056    }
   5057 
   5058    mState.setObjectDirty(target);
   5059 }
   5060 
   5061 void Context::framebufferTextureLayer(GLenum target,
   5062                                      GLenum attachment,
   5063                                      TextureID texture,
   5064                                      GLint level,
   5065                                      GLint layer)
   5066 {
   5067    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5068    ASSERT(framebuffer);
   5069 
   5070    if (texture.value != 0)
   5071    {
   5072        Texture *textureObject = getTexture(texture);
   5073        ImageIndex index       = ImageIndex::MakeFromType(textureObject->getType(), level, layer);
   5074        framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObject);
   5075    }
   5076    else
   5077    {
   5078        framebuffer->resetAttachment(this, attachment);
   5079    }
   5080 
   5081    mState.setObjectDirty(target);
   5082 }
   5083 
   5084 void Context::framebufferTextureMultiview(GLenum target,
   5085                                          GLenum attachment,
   5086                                          TextureID texture,
   5087                                          GLint level,
   5088                                          GLint baseViewIndex,
   5089                                          GLsizei numViews)
   5090 {
   5091    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5092    ASSERT(framebuffer);
   5093 
   5094    if (texture.value != 0)
   5095    {
   5096        Texture *textureObj = getTexture(texture);
   5097 
   5098        ImageIndex index;
   5099        if (textureObj->getType() == TextureType::_2DArray)
   5100        {
   5101            index = ImageIndex::Make2DArrayRange(level, baseViewIndex, numViews);
   5102        }
   5103        else
   5104        {
   5105            ASSERT(textureObj->getType() == TextureType::_2DMultisampleArray);
   5106            ASSERT(level == 0);
   5107            index = ImageIndex::Make2DMultisampleArrayRange(baseViewIndex, numViews);
   5108        }
   5109        framebuffer->setAttachmentMultiview(this, GL_TEXTURE, attachment, index, textureObj,
   5110                                            numViews, baseViewIndex);
   5111    }
   5112    else
   5113    {
   5114        framebuffer->resetAttachment(this, attachment);
   5115    }
   5116 
   5117    mState.setObjectDirty(target);
   5118 }
   5119 
   5120 void Context::framebufferTexture(GLenum target, GLenum attachment, TextureID texture, GLint level)
   5121 {
   5122    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5123    ASSERT(framebuffer);
   5124 
   5125    if (texture.value != 0)
   5126    {
   5127        Texture *textureObj = getTexture(texture);
   5128 
   5129        ImageIndex index = ImageIndex::MakeFromType(
   5130            textureObj->getType(), level, ImageIndex::kEntireLevel, ImageIndex::kEntireLevel);
   5131        framebuffer->setAttachment(this, GL_TEXTURE, attachment, index, textureObj);
   5132    }
   5133    else
   5134    {
   5135        framebuffer->resetAttachment(this, attachment);
   5136    }
   5137 
   5138    mState.setObjectDirty(target);
   5139 }
   5140 
   5141 void Context::drawBuffers(GLsizei n, const GLenum *bufs)
   5142 {
   5143    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   5144    ASSERT(framebuffer);
   5145    framebuffer->setDrawBuffers(n, bufs);
   5146    mState.setDrawFramebufferDirty();
   5147    mStateCache.onDrawFramebufferChange(this);
   5148 }
   5149 
   5150 void Context::readBuffer(GLenum mode)
   5151 {
   5152    Framebuffer *readFBO = mState.getReadFramebuffer();
   5153    readFBO->setReadBuffer(mode);
   5154    mState.setObjectDirty(GL_READ_FRAMEBUFFER);
   5155 }
   5156 
   5157 void Context::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments)
   5158 {
   5159    // The specification isn't clear what should be done when the framebuffer isn't complete.
   5160    // We threat it the same way as GLES3 glInvalidateFramebuffer.
   5161    invalidateFramebuffer(target, numAttachments, attachments);
   5162 }
   5163 
   5164 void Context::invalidateFramebuffer(GLenum target,
   5165                                    GLsizei numAttachments,
   5166                                    const GLenum *attachments)
   5167 {
   5168    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5169    ASSERT(framebuffer);
   5170 
   5171    // No-op incomplete FBOs.
   5172    if (!framebuffer->isComplete(this))
   5173    {
   5174        return;
   5175    }
   5176 
   5177    ANGLE_CONTEXT_TRY(prepareForInvalidate(target));
   5178    ANGLE_CONTEXT_TRY(framebuffer->invalidate(this, numAttachments, attachments));
   5179 }
   5180 
   5181 void Context::invalidateSubFramebuffer(GLenum target,
   5182                                       GLsizei numAttachments,
   5183                                       const GLenum *attachments,
   5184                                       GLint x,
   5185                                       GLint y,
   5186                                       GLsizei width,
   5187                                       GLsizei height)
   5188 {
   5189    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   5190    ASSERT(framebuffer);
   5191 
   5192    if (!framebuffer->isComplete(this))
   5193    {
   5194        return;
   5195    }
   5196 
   5197    Rectangle area(x, y, width, height);
   5198    ANGLE_CONTEXT_TRY(prepareForInvalidate(target));
   5199    ANGLE_CONTEXT_TRY(framebuffer->invalidateSub(this, numAttachments, attachments, area));
   5200 }
   5201 
   5202 void Context::texImage2D(TextureTarget target,
   5203                         GLint level,
   5204                         GLint internalformat,
   5205                         GLsizei width,
   5206                         GLsizei height,
   5207                         GLint border,
   5208                         GLenum format,
   5209                         GLenum type,
   5210                         const void *pixels)
   5211 {
   5212    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5213 
   5214    gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
   5215 
   5216    Extents size(width, height, 1);
   5217    Texture *texture = getTextureByTarget(target);
   5218    ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
   5219                                        internalformat, size, format, type,
   5220                                        static_cast<const uint8_t *>(pixels)));
   5221 }
   5222 
   5223 void Context::texImage2DRobust(TextureTarget target,
   5224                               GLint level,
   5225                               GLint internalformat,
   5226                               GLsizei width,
   5227                               GLsizei height,
   5228                               GLint border,
   5229                               GLenum format,
   5230                               GLenum type,
   5231                               GLsizei bufSize,
   5232                               const void *pixels)
   5233 {
   5234    texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
   5235 }
   5236 
   5237 void Context::texImage3D(TextureTarget target,
   5238                         GLint level,
   5239                         GLint internalformat,
   5240                         GLsizei width,
   5241                         GLsizei height,
   5242                         GLsizei depth,
   5243                         GLint border,
   5244                         GLenum format,
   5245                         GLenum type,
   5246                         const void *pixels)
   5247 {
   5248    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5249 
   5250    gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
   5251 
   5252    Extents size(width, height, depth);
   5253    Texture *texture = getTextureByTarget(target);
   5254    ANGLE_CONTEXT_TRY(texture->setImage(this, mState.getUnpackState(), unpackBuffer, target, level,
   5255                                        internalformat, size, format, type,
   5256                                        static_cast<const uint8_t *>(pixels)));
   5257 }
   5258 
   5259 void Context::texImage3DRobust(TextureTarget target,
   5260                               GLint level,
   5261                               GLint internalformat,
   5262                               GLsizei width,
   5263                               GLsizei height,
   5264                               GLsizei depth,
   5265                               GLint border,
   5266                               GLenum format,
   5267                               GLenum type,
   5268                               GLsizei bufSize,
   5269                               const void *pixels)
   5270 {
   5271    texImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels);
   5272 }
   5273 
   5274 void Context::texSubImage2D(TextureTarget target,
   5275                            GLint level,
   5276                            GLint xoffset,
   5277                            GLint yoffset,
   5278                            GLsizei width,
   5279                            GLsizei height,
   5280                            GLenum format,
   5281                            GLenum type,
   5282                            const void *pixels)
   5283 {
   5284    // Zero sized uploads are valid but no-ops
   5285    if (width == 0 || height == 0)
   5286    {
   5287        return;
   5288    }
   5289 
   5290    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5291 
   5292    Box area(xoffset, yoffset, 0, width, height, 1);
   5293    Texture *texture = getTextureByTarget(target);
   5294 
   5295    gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
   5296 
   5297    ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
   5298                                           level, area, format, type,
   5299                                           static_cast<const uint8_t *>(pixels)));
   5300 }
   5301 
   5302 void Context::texSubImage2DRobust(TextureTarget target,
   5303                                  GLint level,
   5304                                  GLint xoffset,
   5305                                  GLint yoffset,
   5306                                  GLsizei width,
   5307                                  GLsizei height,
   5308                                  GLenum format,
   5309                                  GLenum type,
   5310                                  GLsizei bufSize,
   5311                                  const void *pixels)
   5312 {
   5313    texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
   5314 }
   5315 
   5316 void Context::texSubImage3D(TextureTarget target,
   5317                            GLint level,
   5318                            GLint xoffset,
   5319                            GLint yoffset,
   5320                            GLint zoffset,
   5321                            GLsizei width,
   5322                            GLsizei height,
   5323                            GLsizei depth,
   5324                            GLenum format,
   5325                            GLenum type,
   5326                            const void *pixels)
   5327 {
   5328    // Zero sized uploads are valid but no-ops
   5329    if (width == 0 || height == 0 || depth == 0)
   5330    {
   5331        return;
   5332    }
   5333 
   5334    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5335 
   5336    Box area(xoffset, yoffset, zoffset, width, height, depth);
   5337    Texture *texture = getTextureByTarget(target);
   5338 
   5339    gl::Buffer *unpackBuffer = mState.getTargetBuffer(gl::BufferBinding::PixelUnpack);
   5340 
   5341    ANGLE_CONTEXT_TRY(texture->setSubImage(this, mState.getUnpackState(), unpackBuffer, target,
   5342                                           level, area, format, type,
   5343                                           static_cast<const uint8_t *>(pixels)));
   5344 }
   5345 
   5346 void Context::texSubImage3DRobust(TextureTarget target,
   5347                                  GLint level,
   5348                                  GLint xoffset,
   5349                                  GLint yoffset,
   5350                                  GLint zoffset,
   5351                                  GLsizei width,
   5352                                  GLsizei height,
   5353                                  GLsizei depth,
   5354                                  GLenum format,
   5355                                  GLenum type,
   5356                                  GLsizei bufSize,
   5357                                  const void *pixels)
   5358 {
   5359    texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type,
   5360                  pixels);
   5361 }
   5362 
   5363 void Context::compressedTexImage2D(TextureTarget target,
   5364                                   GLint level,
   5365                                   GLenum internalformat,
   5366                                   GLsizei width,
   5367                                   GLsizei height,
   5368                                   GLint border,
   5369                                   GLsizei imageSize,
   5370                                   const void *data)
   5371 {
   5372    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5373 
   5374    Extents size(width, height, 1);
   5375    Texture *texture = getTextureByTarget(target);
   5376    // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
   5377    // image. So we use an empty PixelUnpackState.
   5378    ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level,
   5379                                                  internalformat, size, imageSize,
   5380                                                  static_cast<const uint8_t *>(data)));
   5381 }
   5382 
   5383 void Context::compressedTexImage2DRobust(TextureTarget target,
   5384                                         GLint level,
   5385                                         GLenum internalformat,
   5386                                         GLsizei width,
   5387                                         GLsizei height,
   5388                                         GLint border,
   5389                                         GLsizei imageSize,
   5390                                         GLsizei dataSize,
   5391                                         const GLvoid *data)
   5392 {
   5393    compressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
   5394 }
   5395 
   5396 void Context::compressedTexImage3D(TextureTarget target,
   5397                                   GLint level,
   5398                                   GLenum internalformat,
   5399                                   GLsizei width,
   5400                                   GLsizei height,
   5401                                   GLsizei depth,
   5402                                   GLint border,
   5403                                   GLsizei imageSize,
   5404                                   const void *data)
   5405 {
   5406    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5407 
   5408    Extents size(width, height, depth);
   5409    Texture *texture = getTextureByTarget(target);
   5410    // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
   5411    // image. So we use an empty PixelUnpackState.
   5412    ANGLE_CONTEXT_TRY(texture->setCompressedImage(this, PixelUnpackState(), target, level,
   5413                                                  internalformat, size, imageSize,
   5414                                                  static_cast<const uint8_t *>(data)));
   5415 }
   5416 
   5417 void Context::compressedTexImage3DRobust(TextureTarget target,
   5418                                         GLint level,
   5419                                         GLenum internalformat,
   5420                                         GLsizei width,
   5421                                         GLsizei height,
   5422                                         GLsizei depth,
   5423                                         GLint border,
   5424                                         GLsizei imageSize,
   5425                                         GLsizei dataSize,
   5426                                         const GLvoid *data)
   5427 {
   5428    compressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize,
   5429                         data);
   5430 }
   5431 
   5432 void Context::compressedTexSubImage2D(TextureTarget target,
   5433                                      GLint level,
   5434                                      GLint xoffset,
   5435                                      GLint yoffset,
   5436                                      GLsizei width,
   5437                                      GLsizei height,
   5438                                      GLenum format,
   5439                                      GLsizei imageSize,
   5440                                      const void *data)
   5441 {
   5442    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5443 
   5444    Box area(xoffset, yoffset, 0, width, height, 1);
   5445    Texture *texture = getTextureByTarget(target);
   5446    // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
   5447    // image. So we use an empty PixelUnpackState.
   5448    ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area,
   5449                                                     format, imageSize,
   5450                                                     static_cast<const uint8_t *>(data)));
   5451 }
   5452 
   5453 void Context::compressedTexSubImage2DRobust(TextureTarget target,
   5454                                            GLint level,
   5455                                            GLint xoffset,
   5456                                            GLint yoffset,
   5457                                            GLsizei width,
   5458                                            GLsizei height,
   5459                                            GLenum format,
   5460                                            GLsizei imageSize,
   5461                                            GLsizei dataSize,
   5462                                            const GLvoid *data)
   5463 {
   5464    compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize,
   5465                            data);
   5466 }
   5467 
   5468 void Context::compressedTexSubImage3D(TextureTarget target,
   5469                                      GLint level,
   5470                                      GLint xoffset,
   5471                                      GLint yoffset,
   5472                                      GLint zoffset,
   5473                                      GLsizei width,
   5474                                      GLsizei height,
   5475                                      GLsizei depth,
   5476                                      GLenum format,
   5477                                      GLsizei imageSize,
   5478                                      const void *data)
   5479 {
   5480    // Zero sized uploads are valid but no-ops
   5481    if (width == 0 || height == 0)
   5482    {
   5483        return;
   5484    }
   5485 
   5486    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5487 
   5488    Box area(xoffset, yoffset, zoffset, width, height, depth);
   5489    Texture *texture = getTextureByTarget(target);
   5490    // From OpenGL ES 3 spec: All pixel storage modes are ignored when decoding a compressed texture
   5491    // image. So we use an empty PixelUnpackState.
   5492    ANGLE_CONTEXT_TRY(texture->setCompressedSubImage(this, PixelUnpackState(), target, level, area,
   5493                                                     format, imageSize,
   5494                                                     static_cast<const uint8_t *>(data)));
   5495 }
   5496 
   5497 void Context::compressedTexSubImage3DRobust(TextureTarget target,
   5498                                            GLint level,
   5499                                            GLint xoffset,
   5500                                            GLint yoffset,
   5501                                            GLint zoffset,
   5502                                            GLsizei width,
   5503                                            GLsizei height,
   5504                                            GLsizei depth,
   5505                                            GLenum format,
   5506                                            GLsizei imageSize,
   5507                                            GLsizei dataSize,
   5508                                            const GLvoid *data)
   5509 {
   5510    compressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format,
   5511                            imageSize, data);
   5512 }
   5513 
   5514 void Context::generateMipmap(TextureType target)
   5515 {
   5516    Texture *texture = getTextureByType(target);
   5517    ANGLE_CONTEXT_TRY(texture->generateMipmap(this));
   5518 }
   5519 
   5520 void Context::copyTexture(TextureID sourceId,
   5521                          GLint sourceLevel,
   5522                          TextureTarget destTarget,
   5523                          TextureID destId,
   5524                          GLint destLevel,
   5525                          GLint internalFormat,
   5526                          GLenum destType,
   5527                          GLboolean unpackFlipY,
   5528                          GLboolean unpackPremultiplyAlpha,
   5529                          GLboolean unpackUnmultiplyAlpha)
   5530 {
   5531    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5532 
   5533    gl::Texture *sourceTexture = getTexture(sourceId);
   5534    gl::Texture *destTexture   = getTexture(destId);
   5535    ANGLE_CONTEXT_TRY(
   5536        destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
   5537                                 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
   5538                                 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
   5539 }
   5540 
   5541 void Context::copySubTexture(TextureID sourceId,
   5542                             GLint sourceLevel,
   5543                             TextureTarget destTarget,
   5544                             TextureID destId,
   5545                             GLint destLevel,
   5546                             GLint xoffset,
   5547                             GLint yoffset,
   5548                             GLint x,
   5549                             GLint y,
   5550                             GLsizei width,
   5551                             GLsizei height,
   5552                             GLboolean unpackFlipY,
   5553                             GLboolean unpackPremultiplyAlpha,
   5554                             GLboolean unpackUnmultiplyAlpha)
   5555 {
   5556    // Zero sized copies are valid but no-ops
   5557    if (width == 0 || height == 0)
   5558    {
   5559        return;
   5560    }
   5561 
   5562    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5563 
   5564    gl::Texture *sourceTexture = getTexture(sourceId);
   5565    gl::Texture *destTexture   = getTexture(destId);
   5566    Offset offset(xoffset, yoffset, 0);
   5567    Box box(x, y, 0, width, height, 1);
   5568    ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
   5569        this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
   5570        ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
   5571        sourceTexture));
   5572 }
   5573 
   5574 void Context::copyTexture3D(TextureID sourceId,
   5575                            GLint sourceLevel,
   5576                            TextureTarget destTarget,
   5577                            TextureID destId,
   5578                            GLint destLevel,
   5579                            GLint internalFormat,
   5580                            GLenum destType,
   5581                            GLboolean unpackFlipY,
   5582                            GLboolean unpackPremultiplyAlpha,
   5583                            GLboolean unpackUnmultiplyAlpha)
   5584 {
   5585    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5586 
   5587    Texture *sourceTexture = getTexture(sourceId);
   5588    Texture *destTexture   = getTexture(destId);
   5589    ANGLE_CONTEXT_TRY(
   5590        destTexture->copyTexture(this, destTarget, destLevel, internalFormat, destType, sourceLevel,
   5591                                 ConvertToBool(unpackFlipY), ConvertToBool(unpackPremultiplyAlpha),
   5592                                 ConvertToBool(unpackUnmultiplyAlpha), sourceTexture));
   5593 }
   5594 
   5595 void Context::copySubTexture3D(TextureID sourceId,
   5596                               GLint sourceLevel,
   5597                               TextureTarget destTarget,
   5598                               TextureID destId,
   5599                               GLint destLevel,
   5600                               GLint xoffset,
   5601                               GLint yoffset,
   5602                               GLint zoffset,
   5603                               GLint x,
   5604                               GLint y,
   5605                               GLint z,
   5606                               GLsizei width,
   5607                               GLsizei height,
   5608                               GLsizei depth,
   5609                               GLboolean unpackFlipY,
   5610                               GLboolean unpackPremultiplyAlpha,
   5611                               GLboolean unpackUnmultiplyAlpha)
   5612 {
   5613    // Zero sized copies are valid but no-ops
   5614    if (width == 0 || height == 0 || depth == 0)
   5615    {
   5616        return;
   5617    }
   5618 
   5619    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5620 
   5621    Texture *sourceTexture = getTexture(sourceId);
   5622    Texture *destTexture   = getTexture(destId);
   5623    Offset offset(xoffset, yoffset, zoffset);
   5624    Box box(x, y, z, width, height, depth);
   5625    ANGLE_CONTEXT_TRY(destTexture->copySubTexture(
   5626        this, destTarget, destLevel, offset, sourceLevel, box, ConvertToBool(unpackFlipY),
   5627        ConvertToBool(unpackPremultiplyAlpha), ConvertToBool(unpackUnmultiplyAlpha),
   5628        sourceTexture));
   5629 }
   5630 
   5631 void Context::compressedCopyTexture(TextureID sourceId, TextureID destId)
   5632 {
   5633    ANGLE_CONTEXT_TRY(syncStateForTexImage());
   5634 
   5635    gl::Texture *sourceTexture = getTexture(sourceId);
   5636    gl::Texture *destTexture   = getTexture(destId);
   5637    ANGLE_CONTEXT_TRY(destTexture->copyCompressedTexture(this, sourceTexture));
   5638 }
   5639 
   5640 void Context::getBufferPointerv(BufferBinding target, GLenum pname, void **params)
   5641 {
   5642    Buffer *buffer = mState.getTargetBuffer(target);
   5643    ASSERT(buffer);
   5644 
   5645    QueryBufferPointerv(buffer, pname, params);
   5646 }
   5647 
   5648 void Context::getBufferPointervRobust(BufferBinding target,
   5649                                      GLenum pname,
   5650                                      GLsizei bufSize,
   5651                                      GLsizei *length,
   5652                                      void **params)
   5653 {
   5654    getBufferPointerv(target, pname, params);
   5655 }
   5656 
   5657 void *Context::mapBuffer(BufferBinding target, GLenum access)
   5658 {
   5659    Buffer *buffer = mState.getTargetBuffer(target);
   5660    ASSERT(buffer);
   5661 
   5662    if (buffer->map(this, access) == angle::Result::Stop)
   5663    {
   5664        return nullptr;
   5665    }
   5666 
   5667    return buffer->getMapPointer();
   5668 }
   5669 
   5670 GLboolean Context::unmapBuffer(BufferBinding target)
   5671 {
   5672    Buffer *buffer = mState.getTargetBuffer(target);
   5673    ASSERT(buffer);
   5674 
   5675    GLboolean result;
   5676    if (buffer->unmap(this, &result) == angle::Result::Stop)
   5677    {
   5678        return GL_FALSE;
   5679    }
   5680 
   5681    return result;
   5682 }
   5683 
   5684 void *Context::mapBufferRange(BufferBinding target,
   5685                              GLintptr offset,
   5686                              GLsizeiptr length,
   5687                              GLbitfield access)
   5688 {
   5689    Buffer *buffer = mState.getTargetBuffer(target);
   5690    ASSERT(buffer);
   5691 
   5692    if (buffer->mapRange(this, offset, length, access) == angle::Result::Stop)
   5693    {
   5694        return nullptr;
   5695    }
   5696 
   5697    return buffer->getMapPointer();
   5698 }
   5699 
   5700 void Context::flushMappedBufferRange(BufferBinding /*target*/,
   5701                                     GLintptr /*offset*/,
   5702                                     GLsizeiptr /*length*/)
   5703 {
   5704    // We do not currently support a non-trivial implementation of FlushMappedBufferRange
   5705 }
   5706 
   5707 angle::Result Context::syncStateForReadPixels()
   5708 {
   5709    return syncState(mReadPixelsDirtyBits, mReadPixelsDirtyObjects, Command::ReadPixels);
   5710 }
   5711 
   5712 angle::Result Context::syncStateForTexImage()
   5713 {
   5714    return syncState(mTexImageDirtyBits, mTexImageDirtyObjects, Command::TexImage);
   5715 }
   5716 
   5717 angle::Result Context::syncStateForBlit(GLbitfield mask)
   5718 {
   5719    uint32_t commandMask = 0;
   5720    if ((mask & GL_COLOR_BUFFER_BIT) != 0)
   5721    {
   5722        commandMask |= CommandBlitBufferColor;
   5723    }
   5724    if ((mask & GL_DEPTH_BUFFER_BIT) != 0)
   5725    {
   5726        commandMask |= CommandBlitBufferDepth;
   5727    }
   5728    if ((mask & GL_STENCIL_BUFFER_BIT) != 0)
   5729    {
   5730        commandMask |= CommandBlitBufferStencil;
   5731    }
   5732 
   5733    Command command = static_cast<Command>(static_cast<uint32_t>(Command::Blit) + commandMask);
   5734 
   5735    return syncState(mBlitDirtyBits, mBlitDirtyObjects, command);
   5736 }
   5737 
   5738 angle::Result Context::syncStateForClear()
   5739 {
   5740    return syncState(mClearDirtyBits, mClearDirtyObjects, Command::Clear);
   5741 }
   5742 
   5743 angle::Result Context::syncTextureForCopy(Texture *texture)
   5744 {
   5745    ASSERT(texture);
   5746    // Sync texture not active but scheduled for a copy
   5747    if (texture->hasAnyDirtyBit())
   5748    {
   5749        return texture->syncState(this, Command::Other);
   5750    }
   5751 
   5752    return angle::Result::Continue;
   5753 }
   5754 
   5755 void Context::activeShaderProgram(ProgramPipelineID pipeline, ShaderProgramID program)
   5756 {
   5757    Program *shaderProgram = getProgramNoResolveLink(program);
   5758    ProgramPipeline *programPipeline =
   5759        mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
   5760                                                                       pipeline);
   5761    ASSERT(programPipeline);
   5762 
   5763    programPipeline->activeShaderProgram(shaderProgram);
   5764 }
   5765 
   5766 void Context::activeTexture(GLenum texture)
   5767 {
   5768    mState.setActiveSampler(texture - GL_TEXTURE0);
   5769 }
   5770 
   5771 void Context::blendBarrier()
   5772 {
   5773    mImplementation->blendBarrier();
   5774 }
   5775 
   5776 void Context::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
   5777 {
   5778    mState.setBlendColor(red, green, blue, alpha);
   5779 }
   5780 
   5781 void Context::blendEquation(GLenum mode)
   5782 {
   5783    mState.setBlendEquation(mode, mode);
   5784 
   5785    mStateCache.onBlendEquationChange(this);
   5786 }
   5787 
   5788 void Context::blendEquationi(GLuint buf, GLenum mode)
   5789 {
   5790    mState.setBlendEquationIndexed(mode, mode, buf);
   5791 
   5792    mStateCache.onBlendEquationChange(this);
   5793 }
   5794 
   5795 void Context::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
   5796 {
   5797    mState.setBlendEquation(modeRGB, modeAlpha);
   5798 }
   5799 
   5800 void Context::blendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeAlpha)
   5801 {
   5802    mState.setBlendEquationIndexed(modeRGB, modeAlpha, buf);
   5803 }
   5804 
   5805 void Context::blendFunc(GLenum sfactor, GLenum dfactor)
   5806 {
   5807    mState.setBlendFactors(sfactor, dfactor, sfactor, dfactor);
   5808 }
   5809 
   5810 void Context::blendFunci(GLuint buf, GLenum src, GLenum dst)
   5811 {
   5812    mState.setBlendFactorsIndexed(src, dst, src, dst, buf);
   5813 
   5814    if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
   5815    {
   5816        mStateCache.onBlendFuncIndexedChange(this);
   5817    }
   5818 }
   5819 
   5820 void Context::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
   5821 {
   5822    mState.setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
   5823 }
   5824 
   5825 void Context::blendFuncSeparatei(GLuint buf,
   5826                                 GLenum srcRGB,
   5827                                 GLenum dstRGB,
   5828                                 GLenum srcAlpha,
   5829                                 GLenum dstAlpha)
   5830 {
   5831    mState.setBlendFactorsIndexed(srcRGB, dstRGB, srcAlpha, dstAlpha, buf);
   5832 
   5833    if (mState.noSimultaneousConstantColorAndAlphaBlendFunc())
   5834    {
   5835        mStateCache.onBlendFuncIndexedChange(this);
   5836    }
   5837 }
   5838 
   5839 void Context::clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
   5840 {
   5841    mState.setColorClearValue(red, green, blue, alpha);
   5842 }
   5843 
   5844 void Context::clearDepthf(GLfloat depth)
   5845 {
   5846    mState.setDepthClearValue(clamp01(depth));
   5847 }
   5848 
   5849 void Context::clearStencil(GLint s)
   5850 {
   5851    mState.setStencilClearValue(s);
   5852 }
   5853 
   5854 void Context::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
   5855 {
   5856    mState.setColorMask(ConvertToBool(red), ConvertToBool(green), ConvertToBool(blue),
   5857                        ConvertToBool(alpha));
   5858    mStateCache.onColorMaskChange(this);
   5859 }
   5860 
   5861 void Context::colorMaski(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a)
   5862 {
   5863    mState.setColorMaskIndexed(ConvertToBool(r), ConvertToBool(g), ConvertToBool(b),
   5864                               ConvertToBool(a), index);
   5865    mStateCache.onColorMaskChange(this);
   5866 }
   5867 
   5868 void Context::cullFace(CullFaceMode mode)
   5869 {
   5870    mState.setCullMode(mode);
   5871 }
   5872 
   5873 void Context::depthFunc(GLenum func)
   5874 {
   5875    mState.setDepthFunc(func);
   5876 }
   5877 
   5878 void Context::depthMask(GLboolean flag)
   5879 {
   5880    mState.setDepthMask(ConvertToBool(flag));
   5881 }
   5882 
   5883 void Context::depthRangef(GLfloat zNear, GLfloat zFar)
   5884 {
   5885    mState.setDepthRange(clamp01(zNear), clamp01(zFar));
   5886 }
   5887 
   5888 void Context::clipControl(GLenum origin, GLenum depth)
   5889 {
   5890    mState.setClipControl(origin, depth);
   5891 }
   5892 
   5893 void Context::disable(GLenum cap)
   5894 {
   5895    mState.setEnableFeature(cap, false);
   5896    mStateCache.onContextCapChange(this);
   5897 }
   5898 
   5899 void Context::disablei(GLenum target, GLuint index)
   5900 {
   5901    mState.setEnableFeatureIndexed(target, false, index);
   5902    mStateCache.onContextCapChange(this);
   5903 }
   5904 
   5905 void Context::disableVertexAttribArray(GLuint index)
   5906 {
   5907    mState.setEnableVertexAttribArray(index, false);
   5908    mStateCache.onVertexArrayStateChange(this);
   5909 }
   5910 
   5911 void Context::enable(GLenum cap)
   5912 {
   5913    mState.setEnableFeature(cap, true);
   5914    mStateCache.onContextCapChange(this);
   5915 }
   5916 
   5917 void Context::enablei(GLenum target, GLuint index)
   5918 {
   5919    mState.setEnableFeatureIndexed(target, true, index);
   5920    mStateCache.onContextCapChange(this);
   5921 }
   5922 
   5923 void Context::enableVertexAttribArray(GLuint index)
   5924 {
   5925    mState.setEnableVertexAttribArray(index, true);
   5926    mStateCache.onVertexArrayStateChange(this);
   5927 }
   5928 
   5929 void Context::frontFace(GLenum mode)
   5930 {
   5931    mState.setFrontFace(mode);
   5932 }
   5933 
   5934 void Context::hint(GLenum target, GLenum mode)
   5935 {
   5936    switch (target)
   5937    {
   5938        case GL_GENERATE_MIPMAP_HINT:
   5939            mState.setGenerateMipmapHint(mode);
   5940            break;
   5941 
   5942        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   5943            mState.setFragmentShaderDerivativeHint(mode);
   5944            break;
   5945 
   5946        case GL_PERSPECTIVE_CORRECTION_HINT:
   5947        case GL_POINT_SMOOTH_HINT:
   5948        case GL_LINE_SMOOTH_HINT:
   5949        case GL_FOG_HINT:
   5950            mState.gles1().setHint(target, mode);
   5951            break;
   5952        case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
   5953            mState.setTextureFilteringHint(mode);
   5954            break;
   5955        default:
   5956            UNREACHABLE();
   5957            return;
   5958    }
   5959 }
   5960 
   5961 void Context::lineWidth(GLfloat width)
   5962 {
   5963    mState.setLineWidth(width);
   5964 }
   5965 
   5966 void Context::pixelStorei(GLenum pname, GLint param)
   5967 {
   5968    switch (pname)
   5969    {
   5970        case GL_UNPACK_ALIGNMENT:
   5971            mState.setUnpackAlignment(param);
   5972            break;
   5973 
   5974        case GL_PACK_ALIGNMENT:
   5975            mState.setPackAlignment(param);
   5976            break;
   5977 
   5978        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   5979            mState.setPackReverseRowOrder(param != 0);
   5980            break;
   5981 
   5982        case GL_UNPACK_ROW_LENGTH:
   5983            ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
   5984            mState.setUnpackRowLength(param);
   5985            break;
   5986 
   5987        case GL_UNPACK_IMAGE_HEIGHT:
   5988            ASSERT(getClientMajorVersion() >= 3);
   5989            mState.setUnpackImageHeight(param);
   5990            break;
   5991 
   5992        case GL_UNPACK_SKIP_IMAGES:
   5993            ASSERT(getClientMajorVersion() >= 3);
   5994            mState.setUnpackSkipImages(param);
   5995            break;
   5996 
   5997        case GL_UNPACK_SKIP_ROWS:
   5998            ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
   5999            mState.setUnpackSkipRows(param);
   6000            break;
   6001 
   6002        case GL_UNPACK_SKIP_PIXELS:
   6003            ASSERT((getClientMajorVersion() >= 3) || getExtensions().unpackSubimageEXT);
   6004            mState.setUnpackSkipPixels(param);
   6005            break;
   6006 
   6007        case GL_PACK_ROW_LENGTH:
   6008            ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
   6009            mState.setPackRowLength(param);
   6010            break;
   6011 
   6012        case GL_PACK_SKIP_ROWS:
   6013            ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
   6014            mState.setPackSkipRows(param);
   6015            break;
   6016 
   6017        case GL_PACK_SKIP_PIXELS:
   6018            ASSERT((getClientMajorVersion() >= 3) || getExtensions().packSubimageNV);
   6019            mState.setPackSkipPixels(param);
   6020            break;
   6021 
   6022        default:
   6023            UNREACHABLE();
   6024            return;
   6025    }
   6026 }
   6027 
   6028 void Context::polygonOffset(GLfloat factor, GLfloat units)
   6029 {
   6030    mState.setPolygonOffsetParams(factor, units);
   6031 }
   6032 
   6033 void Context::sampleCoverage(GLfloat value, GLboolean invert)
   6034 {
   6035    mState.setSampleCoverageParams(clamp01(value), ConvertToBool(invert));
   6036 }
   6037 
   6038 void Context::sampleMaski(GLuint maskNumber, GLbitfield mask)
   6039 {
   6040    mState.setSampleMaskParams(maskNumber, mask);
   6041 }
   6042 
   6043 void Context::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
   6044 {
   6045    mState.setScissorParams(x, y, width, height);
   6046 }
   6047 
   6048 void Context::shadingRateQCOM(GLenum rate)
   6049 {
   6050    mState.setShadingRate(rate);
   6051 }
   6052 
   6053 void Context::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
   6054 {
   6055    GLint clampedRef = gl::clamp(ref, 0, std::numeric_limits<uint8_t>::max());
   6056    if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   6057    {
   6058        mState.setStencilParams(func, clampedRef, mask);
   6059    }
   6060 
   6061    if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   6062    {
   6063        mState.setStencilBackParams(func, clampedRef, mask);
   6064    }
   6065 
   6066    mStateCache.onStencilStateChange(this);
   6067 }
   6068 
   6069 void Context::stencilMaskSeparate(GLenum face, GLuint mask)
   6070 {
   6071    if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   6072    {
   6073        mState.setStencilWritemask(mask);
   6074    }
   6075 
   6076    if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   6077    {
   6078        mState.setStencilBackWritemask(mask);
   6079    }
   6080 
   6081    mStateCache.onStencilStateChange(this);
   6082 }
   6083 
   6084 void Context::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
   6085 {
   6086    if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
   6087    {
   6088        mState.setStencilOperations(fail, zfail, zpass);
   6089    }
   6090 
   6091    if (face == GL_BACK || face == GL_FRONT_AND_BACK)
   6092    {
   6093        mState.setStencilBackOperations(fail, zfail, zpass);
   6094    }
   6095 }
   6096 
   6097 void Context::vertexAttrib1f(GLuint index, GLfloat x)
   6098 {
   6099    GLfloat vals[4] = {x, 0, 0, 1};
   6100    mState.setVertexAttribf(index, vals);
   6101    mStateCache.onDefaultVertexAttributeChange(this);
   6102 }
   6103 
   6104 void Context::vertexAttrib1fv(GLuint index, const GLfloat *values)
   6105 {
   6106    GLfloat vals[4] = {values[0], 0, 0, 1};
   6107    mState.setVertexAttribf(index, vals);
   6108    mStateCache.onDefaultVertexAttributeChange(this);
   6109 }
   6110 
   6111 void Context::vertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
   6112 {
   6113    GLfloat vals[4] = {x, y, 0, 1};
   6114    mState.setVertexAttribf(index, vals);
   6115    mStateCache.onDefaultVertexAttributeChange(this);
   6116 }
   6117 
   6118 void Context::vertexAttrib2fv(GLuint index, const GLfloat *values)
   6119 {
   6120    GLfloat vals[4] = {values[0], values[1], 0, 1};
   6121    mState.setVertexAttribf(index, vals);
   6122    mStateCache.onDefaultVertexAttributeChange(this);
   6123 }
   6124 
   6125 void Context::vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
   6126 {
   6127    GLfloat vals[4] = {x, y, z, 1};
   6128    mState.setVertexAttribf(index, vals);
   6129    mStateCache.onDefaultVertexAttributeChange(this);
   6130 }
   6131 
   6132 void Context::vertexAttrib3fv(GLuint index, const GLfloat *values)
   6133 {
   6134    GLfloat vals[4] = {values[0], values[1], values[2], 1};
   6135    mState.setVertexAttribf(index, vals);
   6136    mStateCache.onDefaultVertexAttributeChange(this);
   6137 }
   6138 
   6139 void Context::vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   6140 {
   6141    GLfloat vals[4] = {x, y, z, w};
   6142    mState.setVertexAttribf(index, vals);
   6143    mStateCache.onDefaultVertexAttributeChange(this);
   6144 }
   6145 
   6146 void Context::vertexAttrib4fv(GLuint index, const GLfloat *values)
   6147 {
   6148    mState.setVertexAttribf(index, values);
   6149    mStateCache.onDefaultVertexAttributeChange(this);
   6150 }
   6151 
   6152 void Context::vertexAttribPointer(GLuint index,
   6153                                  GLint size,
   6154                                  VertexAttribType type,
   6155                                  GLboolean normalized,
   6156                                  GLsizei stride,
   6157                                  const void *ptr)
   6158 {
   6159    mState.setVertexAttribPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
   6160                                  type, ConvertToBool(normalized), stride, ptr);
   6161    mStateCache.onVertexArrayStateChange(this);
   6162 }
   6163 
   6164 void Context::vertexAttribFormat(GLuint attribIndex,
   6165                                 GLint size,
   6166                                 VertexAttribType type,
   6167                                 GLboolean normalized,
   6168                                 GLuint relativeOffset)
   6169 {
   6170    mState.setVertexAttribFormat(attribIndex, size, type, ConvertToBool(normalized), false,
   6171                                 relativeOffset);
   6172    mStateCache.onVertexArrayFormatChange(this);
   6173 }
   6174 
   6175 void Context::vertexAttribIFormat(GLuint attribIndex,
   6176                                  GLint size,
   6177                                  VertexAttribType type,
   6178                                  GLuint relativeOffset)
   6179 {
   6180    mState.setVertexAttribFormat(attribIndex, size, type, false, true, relativeOffset);
   6181    mStateCache.onVertexArrayFormatChange(this);
   6182 }
   6183 
   6184 void Context::vertexAttribBinding(GLuint attribIndex, GLuint bindingIndex)
   6185 {
   6186    mState.setVertexAttribBinding(this, attribIndex, bindingIndex);
   6187    mStateCache.onVertexArrayStateChange(this);
   6188 }
   6189 
   6190 void Context::vertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
   6191 {
   6192    mState.setVertexBindingDivisor(this, bindingIndex, divisor);
   6193    mStateCache.onVertexArrayFormatChange(this);
   6194 }
   6195 
   6196 void Context::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
   6197 {
   6198    mState.setViewportParams(x, y, width, height);
   6199 }
   6200 
   6201 void Context::vertexAttribIPointer(GLuint index,
   6202                                   GLint size,
   6203                                   VertexAttribType type,
   6204                                   GLsizei stride,
   6205                                   const void *pointer)
   6206 {
   6207    mState.setVertexAttribIPointer(this, index, mState.getTargetBuffer(BufferBinding::Array), size,
   6208                                   type, stride, pointer);
   6209    mStateCache.onVertexArrayStateChange(this);
   6210 }
   6211 
   6212 void Context::vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w)
   6213 {
   6214    GLint vals[4] = {x, y, z, w};
   6215    mState.setVertexAttribi(index, vals);
   6216    mStateCache.onDefaultVertexAttributeChange(this);
   6217 }
   6218 
   6219 void Context::vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
   6220 {
   6221    GLuint vals[4] = {x, y, z, w};
   6222    mState.setVertexAttribu(index, vals);
   6223    mStateCache.onDefaultVertexAttributeChange(this);
   6224 }
   6225 
   6226 void Context::vertexAttribI4iv(GLuint index, const GLint *v)
   6227 {
   6228    mState.setVertexAttribi(index, v);
   6229    mStateCache.onDefaultVertexAttributeChange(this);
   6230 }
   6231 
   6232 void Context::vertexAttribI4uiv(GLuint index, const GLuint *v)
   6233 {
   6234    mState.setVertexAttribu(index, v);
   6235    mStateCache.onDefaultVertexAttributeChange(this);
   6236 }
   6237 
   6238 void Context::getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const
   6239 {
   6240    const VertexAttribCurrentValueData &currentValues =
   6241        getState().getVertexAttribCurrentValue(index);
   6242    const VertexArray *vao = getState().getVertexArray();
   6243    QueryVertexAttribiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
   6244                        currentValues, pname, params);
   6245 }
   6246 
   6247 void Context::getVertexAttribiv(GLuint index, GLenum pname, GLint *params)
   6248 {
   6249    return getVertexAttribivImpl(index, pname, params);
   6250 }
   6251 
   6252 void Context::getVertexAttribivRobust(GLuint index,
   6253                                      GLenum pname,
   6254                                      GLsizei bufSize,
   6255                                      GLsizei *length,
   6256                                      GLint *params)
   6257 {
   6258    getVertexAttribiv(index, pname, params);
   6259 }
   6260 
   6261 void Context::getVertexAttribfv(GLuint index, GLenum pname, GLfloat *params)
   6262 {
   6263    const VertexAttribCurrentValueData &currentValues =
   6264        getState().getVertexAttribCurrentValue(index);
   6265    const VertexArray *vao = getState().getVertexArray();
   6266    QueryVertexAttribfv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
   6267                        currentValues, pname, params);
   6268 }
   6269 
   6270 void Context::getVertexAttribfvRobust(GLuint index,
   6271                                      GLenum pname,
   6272                                      GLsizei bufSize,
   6273                                      GLsizei *length,
   6274                                      GLfloat *params)
   6275 {
   6276    getVertexAttribfv(index, pname, params);
   6277 }
   6278 
   6279 void Context::getVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
   6280 {
   6281    const VertexAttribCurrentValueData &currentValues =
   6282        getState().getVertexAttribCurrentValue(index);
   6283    const VertexArray *vao = getState().getVertexArray();
   6284    QueryVertexAttribIiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
   6285                         currentValues, pname, params);
   6286 }
   6287 
   6288 void Context::getVertexAttribIivRobust(GLuint index,
   6289                                       GLenum pname,
   6290                                       GLsizei bufSize,
   6291                                       GLsizei *length,
   6292                                       GLint *params)
   6293 {
   6294    getVertexAttribIiv(index, pname, params);
   6295 }
   6296 
   6297 void Context::getVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
   6298 {
   6299    const VertexAttribCurrentValueData &currentValues =
   6300        getState().getVertexAttribCurrentValue(index);
   6301    const VertexArray *vao = getState().getVertexArray();
   6302    QueryVertexAttribIuiv(vao->getVertexAttribute(index), vao->getBindingFromAttribIndex(index),
   6303                          currentValues, pname, params);
   6304 }
   6305 
   6306 void Context::getVertexAttribIuivRobust(GLuint index,
   6307                                        GLenum pname,
   6308                                        GLsizei bufSize,
   6309                                        GLsizei *length,
   6310                                        GLuint *params)
   6311 {
   6312    getVertexAttribIuiv(index, pname, params);
   6313 }
   6314 
   6315 void Context::getVertexAttribPointerv(GLuint index, GLenum pname, void **pointer)
   6316 {
   6317    const VertexAttribute &attrib = getState().getVertexArray()->getVertexAttribute(index);
   6318    QueryVertexAttribPointerv(attrib, pname, pointer);
   6319 }
   6320 
   6321 void Context::getVertexAttribPointervRobust(GLuint index,
   6322                                            GLenum pname,
   6323                                            GLsizei bufSize,
   6324                                            GLsizei *length,
   6325                                            void **pointer)
   6326 {
   6327    getVertexAttribPointerv(index, pname, pointer);
   6328 }
   6329 
   6330 void Context::debugMessageControl(GLenum source,
   6331                                  GLenum type,
   6332                                  GLenum severity,
   6333                                  GLsizei count,
   6334                                  const GLuint *ids,
   6335                                  GLboolean enabled)
   6336 {
   6337    std::vector<GLuint> idVector(ids, ids + count);
   6338    mState.getDebug().setMessageControl(source, type, severity, std::move(idVector),
   6339                                        ConvertToBool(enabled));
   6340 }
   6341 
   6342 void Context::debugMessageInsert(GLenum source,
   6343                                 GLenum type,
   6344                                 GLuint id,
   6345                                 GLenum severity,
   6346                                 GLsizei length,
   6347                                 const GLchar *buf)
   6348 {
   6349    std::string msg(buf, (length > 0) ? static_cast<size_t>(length) : strlen(buf));
   6350    mState.getDebug().insertMessage(source, type, id, severity, std::move(msg), gl::LOG_INFO,
   6351                                    angle::EntryPoint::GLDebugMessageInsert);
   6352 }
   6353 
   6354 void Context::debugMessageCallback(GLDEBUGPROCKHR callback, const void *userParam)
   6355 {
   6356    mState.getDebug().setCallback(callback, userParam);
   6357 }
   6358 
   6359 GLuint Context::getDebugMessageLog(GLuint count,
   6360                                   GLsizei bufSize,
   6361                                   GLenum *sources,
   6362                                   GLenum *types,
   6363                                   GLuint *ids,
   6364                                   GLenum *severities,
   6365                                   GLsizei *lengths,
   6366                                   GLchar *messageLog)
   6367 {
   6368    return static_cast<GLuint>(mState.getDebug().getMessages(count, bufSize, sources, types, ids,
   6369                                                             severities, lengths, messageLog));
   6370 }
   6371 
   6372 void Context::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const GLchar *message)
   6373 {
   6374    std::string msg(message, (length > 0) ? static_cast<size_t>(length) : strlen(message));
   6375    ANGLE_CONTEXT_TRY(mImplementation->pushDebugGroup(this, source, id, msg));
   6376    mState.getDebug().pushGroup(source, id, std::move(msg));
   6377 }
   6378 
   6379 angle::Result Context::handleNoopDrawEvent()
   6380 {
   6381    return (mImplementation->handleNoopDrawEvent());
   6382 }
   6383 
   6384 void Context::popDebugGroup()
   6385 {
   6386    mState.getDebug().popGroup();
   6387    ANGLE_CONTEXT_TRY(mImplementation->popDebugGroup(this));
   6388 }
   6389 
   6390 void Context::primitiveBoundingBox(GLfloat minX,
   6391                                   GLfloat minY,
   6392                                   GLfloat minZ,
   6393                                   GLfloat minW,
   6394                                   GLfloat maxX,
   6395                                   GLfloat maxY,
   6396                                   GLfloat maxZ,
   6397                                   GLfloat maxW)
   6398 {
   6399    mState.mBoundingBoxMinX = minX;
   6400    mState.mBoundingBoxMinY = minY;
   6401    mState.mBoundingBoxMinZ = minZ;
   6402    mState.mBoundingBoxMinW = minW;
   6403    mState.mBoundingBoxMaxX = maxX;
   6404    mState.mBoundingBoxMaxY = maxY;
   6405    mState.mBoundingBoxMaxZ = maxZ;
   6406    mState.mBoundingBoxMaxW = maxW;
   6407 }
   6408 
   6409 void Context::bufferStorage(BufferBinding target,
   6410                            GLsizeiptr size,
   6411                            const void *data,
   6412                            GLbitfield flags)
   6413 {
   6414    Buffer *buffer = mState.getTargetBuffer(target);
   6415    ASSERT(buffer);
   6416    ANGLE_CONTEXT_TRY(buffer->bufferStorage(this, target, size, data, flags));
   6417 }
   6418 
   6419 void Context::bufferStorageExternal(BufferBinding target,
   6420                                    GLintptr offset,
   6421                                    GLsizeiptr size,
   6422                                    GLeglClientBufferEXT clientBuffer,
   6423                                    GLbitfield flags)
   6424 {
   6425    Buffer *buffer = mState.getTargetBuffer(target);
   6426    ASSERT(buffer);
   6427 
   6428    ANGLE_CONTEXT_TRY(buffer->bufferStorageExternal(this, target, size, clientBuffer, flags));
   6429 }
   6430 
   6431 void Context::namedBufferStorageExternal(GLuint buffer,
   6432                                         GLintptr offset,
   6433                                         GLsizeiptr size,
   6434                                         GLeglClientBufferEXT clientBuffer,
   6435                                         GLbitfield flags)
   6436 {
   6437    UNIMPLEMENTED();
   6438 }
   6439 
   6440 void Context::bufferData(BufferBinding target, GLsizeiptr size, const void *data, BufferUsage usage)
   6441 {
   6442    Buffer *buffer = mState.getTargetBuffer(target);
   6443    ASSERT(buffer);
   6444    ANGLE_CONTEXT_TRY(buffer->bufferData(this, target, data, size, usage));
   6445 }
   6446 
   6447 void Context::bufferSubData(BufferBinding target,
   6448                            GLintptr offset,
   6449                            GLsizeiptr size,
   6450                            const void *data)
   6451 {
   6452    if (data == nullptr || size == 0)
   6453    {
   6454        return;
   6455    }
   6456 
   6457    Buffer *buffer = mState.getTargetBuffer(target);
   6458    ASSERT(buffer);
   6459    ANGLE_CONTEXT_TRY(buffer->bufferSubData(this, target, data, size, offset));
   6460 }
   6461 
   6462 void Context::attachShader(ShaderProgramID program, ShaderProgramID shader)
   6463 {
   6464    Program *programObject = mState.mShaderProgramManager->getProgram(program);
   6465    Shader *shaderObject   = mState.mShaderProgramManager->getShader(shader);
   6466    ASSERT(programObject && shaderObject);
   6467    programObject->attachShader(shaderObject);
   6468 }
   6469 
   6470 void Context::copyBufferSubData(BufferBinding readTarget,
   6471                                BufferBinding writeTarget,
   6472                                GLintptr readOffset,
   6473                                GLintptr writeOffset,
   6474                                GLsizeiptr size)
   6475 {
   6476    // if size is zero, the copy is a successful no-op
   6477    if (size == 0)
   6478    {
   6479        return;
   6480    }
   6481 
   6482    // TODO(jmadill): cache these.
   6483    Buffer *readBuffer  = mState.getTargetBuffer(readTarget);
   6484    Buffer *writeBuffer = mState.getTargetBuffer(writeTarget);
   6485 
   6486    ANGLE_CONTEXT_TRY(
   6487        writeBuffer->copyBufferSubData(this, readBuffer, readOffset, writeOffset, size));
   6488 }
   6489 
   6490 void Context::bindAttribLocation(ShaderProgramID program, GLuint index, const GLchar *name)
   6491 {
   6492    // Ideally we could share the program query with the validation layer if possible.
   6493    Program *programObject = getProgramResolveLink(program);
   6494    ASSERT(programObject);
   6495    programObject->bindAttributeLocation(index, name);
   6496 }
   6497 
   6498 void Context::bindBufferBase(BufferBinding target, GLuint index, BufferID buffer)
   6499 {
   6500    bindBufferRange(target, index, buffer, 0, 0);
   6501 }
   6502 
   6503 void Context::bindBufferRange(BufferBinding target,
   6504                              GLuint index,
   6505                              BufferID buffer,
   6506                              GLintptr offset,
   6507                              GLsizeiptr size)
   6508 {
   6509    Buffer *object = mState.mBufferManager->checkBufferAllocation(mImplementation.get(), buffer);
   6510    ANGLE_CONTEXT_TRY(mState.setIndexedBufferBinding(this, target, index, object, offset, size));
   6511    if (target == BufferBinding::Uniform)
   6512    {
   6513        mUniformBufferObserverBindings[index].bind(object);
   6514        mStateCache.onUniformBufferStateChange(this);
   6515    }
   6516    else if (target == BufferBinding::AtomicCounter)
   6517    {
   6518        mAtomicCounterBufferObserverBindings[index].bind(object);
   6519        mStateCache.onAtomicCounterBufferStateChange(this);
   6520    }
   6521    else if (target == BufferBinding::ShaderStorage)
   6522    {
   6523        mShaderStorageBufferObserverBindings[index].bind(object);
   6524        mStateCache.onShaderStorageBufferStateChange(this);
   6525    }
   6526    else
   6527    {
   6528        mStateCache.onBufferBindingChange(this);
   6529    }
   6530 }
   6531 
   6532 void Context::bindFramebuffer(GLenum target, FramebufferID framebuffer)
   6533 {
   6534    if (target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER)
   6535    {
   6536        bindReadFramebuffer(framebuffer);
   6537    }
   6538 
   6539    if (target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER)
   6540    {
   6541        bindDrawFramebuffer(framebuffer);
   6542    }
   6543 }
   6544 
   6545 void Context::bindRenderbuffer(GLenum target, RenderbufferID renderbuffer)
   6546 {
   6547    ASSERT(target == GL_RENDERBUFFER);
   6548    Renderbuffer *object = mState.mRenderbufferManager->checkRenderbufferAllocation(
   6549        mImplementation.get(), renderbuffer);
   6550    mState.setRenderbufferBinding(this, object);
   6551 }
   6552 
   6553 void Context::texStorage2DMultisample(TextureType target,
   6554                                      GLsizei samples,
   6555                                      GLenum internalformat,
   6556                                      GLsizei width,
   6557                                      GLsizei height,
   6558                                      GLboolean fixedsamplelocations)
   6559 {
   6560    Extents size(width, height, 1);
   6561    Texture *texture = getTextureByType(target);
   6562    ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
   6563                                                     ConvertToBool(fixedsamplelocations)));
   6564 }
   6565 
   6566 void Context::texStorage3DMultisample(TextureType target,
   6567                                      GLsizei samples,
   6568                                      GLenum internalformat,
   6569                                      GLsizei width,
   6570                                      GLsizei height,
   6571                                      GLsizei depth,
   6572                                      GLboolean fixedsamplelocations)
   6573 {
   6574    Extents size(width, height, depth);
   6575    Texture *texture = getTextureByType(target);
   6576    ANGLE_CONTEXT_TRY(texture->setStorageMultisample(this, target, samples, internalformat, size,
   6577                                                     ConvertToBool(fixedsamplelocations)));
   6578 }
   6579 
   6580 void Context::texImage2DExternal(TextureTarget target,
   6581                                 GLint level,
   6582                                 GLint internalformat,
   6583                                 GLsizei width,
   6584                                 GLsizei height,
   6585                                 GLint border,
   6586                                 GLenum format,
   6587                                 GLenum type)
   6588 {
   6589    Extents size(width, height, 1);
   6590    Texture *texture = getTextureByTarget(target);
   6591    ANGLE_CONTEXT_TRY(
   6592        texture->setImageExternal(this, target, level, internalformat, size, format, type));
   6593 }
   6594 
   6595 void Context::invalidateTexture(TextureType target)
   6596 {
   6597    mImplementation->invalidateTexture(target);
   6598    mState.invalidateTextureBindings(target);
   6599 }
   6600 
   6601 void Context::getMultisamplefv(GLenum pname, GLuint index, GLfloat *val)
   6602 {
   6603    // According to spec 3.1 Table 20.49: Framebuffer Dependent Values,
   6604    // the sample position should be queried by DRAW_FRAMEBUFFER.
   6605    ANGLE_CONTEXT_TRY(mState.syncDirtyObject(this, GL_DRAW_FRAMEBUFFER));
   6606    const Framebuffer *framebuffer = mState.getDrawFramebuffer();
   6607 
   6608    switch (pname)
   6609    {
   6610        case GL_SAMPLE_POSITION:
   6611            ANGLE_CONTEXT_TRY(framebuffer->getSamplePosition(this, index, val));
   6612            break;
   6613        default:
   6614            UNREACHABLE();
   6615    }
   6616 }
   6617 
   6618 void Context::getMultisamplefvRobust(GLenum pname,
   6619                                     GLuint index,
   6620                                     GLsizei bufSize,
   6621                                     GLsizei *length,
   6622                                     GLfloat *val)
   6623 {
   6624    UNIMPLEMENTED();
   6625 }
   6626 
   6627 void Context::renderbufferStorage(GLenum target,
   6628                                  GLenum internalformat,
   6629                                  GLsizei width,
   6630                                  GLsizei height)
   6631 {
   6632    // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
   6633    GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
   6634 
   6635    Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
   6636    ANGLE_CONTEXT_TRY(renderbuffer->setStorage(this, convertedInternalFormat, width, height));
   6637 }
   6638 
   6639 void Context::renderbufferStorageMultisample(GLenum target,
   6640                                             GLsizei samples,
   6641                                             GLenum internalformat,
   6642                                             GLsizei width,
   6643                                             GLsizei height)
   6644 {
   6645    renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height,
   6646                                       MultisamplingMode::Regular);
   6647 }
   6648 
   6649 void Context::renderbufferStorageMultisampleEXT(GLenum target,
   6650                                                GLsizei samples,
   6651                                                GLenum internalformat,
   6652                                                GLsizei width,
   6653                                                GLsizei height)
   6654 {
   6655    renderbufferStorageMultisampleImpl(target, samples, internalformat, width, height,
   6656                                       MultisamplingMode::MultisampledRenderToTexture);
   6657 }
   6658 
   6659 void Context::renderbufferStorageMultisampleImpl(GLenum target,
   6660                                                 GLsizei samples,
   6661                                                 GLenum internalformat,
   6662                                                 GLsizei width,
   6663                                                 GLsizei height,
   6664                                                 MultisamplingMode mode)
   6665 {
   6666    // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
   6667    GLenum convertedInternalFormat = getConvertedRenderbufferFormat(internalformat);
   6668 
   6669    Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
   6670    ANGLE_CONTEXT_TRY(renderbuffer->setStorageMultisample(this, samples, convertedInternalFormat,
   6671                                                          width, height, mode));
   6672 }
   6673 
   6674 void Context::framebufferTexture2DMultisample(GLenum target,
   6675                                              GLenum attachment,
   6676                                              TextureTarget textarget,
   6677                                              TextureID texture,
   6678                                              GLint level,
   6679                                              GLsizei samples)
   6680 {
   6681    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   6682    ASSERT(framebuffer);
   6683 
   6684    if (texture.value != 0)
   6685    {
   6686        Texture *textureObj = getTexture(texture);
   6687        ImageIndex index    = ImageIndex::MakeFromTarget(textarget, level, 1);
   6688        framebuffer->setAttachmentMultisample(this, GL_TEXTURE, attachment, index, textureObj,
   6689                                              samples);
   6690    }
   6691    else
   6692    {
   6693        framebuffer->resetAttachment(this, attachment);
   6694    }
   6695 
   6696    mState.setObjectDirty(target);
   6697 }
   6698 
   6699 void Context::getSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values)
   6700 {
   6701    const Sync *syncObject = nullptr;
   6702    if (!isContextLost())
   6703    {
   6704        syncObject = getSync(sync);
   6705    }
   6706    ANGLE_CONTEXT_TRY(QuerySynciv(this, syncObject, pname, bufSize, length, values));
   6707 }
   6708 
   6709 void Context::getFramebufferParameteriv(GLenum target, GLenum pname, GLint *params)
   6710 {
   6711    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   6712    QueryFramebufferParameteriv(framebuffer, pname, params);
   6713 }
   6714 
   6715 void Context::getFramebufferParameterivRobust(GLenum target,
   6716                                              GLenum pname,
   6717                                              GLsizei bufSize,
   6718                                              GLsizei *length,
   6719                                              GLint *params)
   6720 {
   6721    UNIMPLEMENTED();
   6722 }
   6723 
   6724 void Context::framebufferParameteri(GLenum target, GLenum pname, GLint param)
   6725 {
   6726    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   6727    SetFramebufferParameteri(this, framebuffer, pname, param);
   6728 }
   6729 
   6730 bool Context::getScratchBuffer(size_t requstedSizeBytes,
   6731                               angle::MemoryBuffer **scratchBufferOut) const
   6732 {
   6733    if (!mScratchBuffer.valid())
   6734    {
   6735        mScratchBuffer = mDisplay->requestScratchBuffer();
   6736    }
   6737 
   6738    ASSERT(mScratchBuffer.valid());
   6739    return mScratchBuffer.value().get(requstedSizeBytes, scratchBufferOut);
   6740 }
   6741 
   6742 angle::ScratchBuffer *Context::getScratchBuffer() const
   6743 {
   6744    if (!mScratchBuffer.valid())
   6745    {
   6746        mScratchBuffer = mDisplay->requestScratchBuffer();
   6747    }
   6748 
   6749    ASSERT(mScratchBuffer.valid());
   6750    return &mScratchBuffer.value();
   6751 }
   6752 
   6753 bool Context::getZeroFilledBuffer(size_t requstedSizeBytes,
   6754                                  angle::MemoryBuffer **zeroBufferOut) const
   6755 {
   6756    if (!mZeroFilledBuffer.valid())
   6757    {
   6758        mZeroFilledBuffer = mDisplay->requestZeroFilledBuffer();
   6759    }
   6760 
   6761    ASSERT(mZeroFilledBuffer.valid());
   6762    return mZeroFilledBuffer.value().getInitialized(requstedSizeBytes, zeroBufferOut, 0);
   6763 }
   6764 
   6765 void Context::dispatchCompute(GLuint numGroupsX, GLuint numGroupsY, GLuint numGroupsZ)
   6766 {
   6767    if (numGroupsX == 0u || numGroupsY == 0u || numGroupsZ == 0u)
   6768    {
   6769        return;
   6770    }
   6771 
   6772    ANGLE_CONTEXT_TRY(prepareForDispatch());
   6773 
   6774    angle::Result result =
   6775        mImplementation->dispatchCompute(this, numGroupsX, numGroupsY, numGroupsZ);
   6776 
   6777    // This must be called before convertPpoToComputeOrDraw() so it uses the PPO's compute values
   6778    // before convertPpoToComputeOrDraw() reverts the PPO back to graphics.
   6779    MarkShaderStorageUsage(this);
   6780 
   6781    if (ANGLE_UNLIKELY(IsError(result)))
   6782    {
   6783        return;
   6784    }
   6785 }
   6786 
   6787 void Context::dispatchComputeIndirect(GLintptr indirect)
   6788 {
   6789    ANGLE_CONTEXT_TRY(prepareForDispatch());
   6790    ANGLE_CONTEXT_TRY(mImplementation->dispatchComputeIndirect(this, indirect));
   6791 
   6792    MarkShaderStorageUsage(this);
   6793 }
   6794 
   6795 void Context::texStorage2D(TextureType target,
   6796                           GLsizei levels,
   6797                           GLenum internalFormat,
   6798                           GLsizei width,
   6799                           GLsizei height)
   6800 {
   6801    Extents size(width, height, 1);
   6802    Texture *texture = getTextureByType(target);
   6803    ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
   6804 }
   6805 
   6806 void Context::texStorage3D(TextureType target,
   6807                           GLsizei levels,
   6808                           GLenum internalFormat,
   6809                           GLsizei width,
   6810                           GLsizei height,
   6811                           GLsizei depth)
   6812 {
   6813    Extents size(width, height, depth);
   6814    Texture *texture = getTextureByType(target);
   6815    ANGLE_CONTEXT_TRY(texture->setStorage(this, target, levels, internalFormat, size));
   6816 }
   6817 
   6818 void Context::memoryBarrier(GLbitfield barriers)
   6819 {
   6820    ANGLE_CONTEXT_TRY(mImplementation->memoryBarrier(this, barriers));
   6821 }
   6822 
   6823 void Context::memoryBarrierByRegion(GLbitfield barriers)
   6824 {
   6825    ANGLE_CONTEXT_TRY(mImplementation->memoryBarrierByRegion(this, barriers));
   6826 }
   6827 
   6828 void Context::multiDrawArrays(PrimitiveMode mode,
   6829                              const GLint *firsts,
   6830                              const GLsizei *counts,
   6831                              GLsizei drawcount)
   6832 {
   6833    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6834    ANGLE_CONTEXT_TRY(mImplementation->multiDrawArrays(this, mode, firsts, counts, drawcount));
   6835 }
   6836 
   6837 void Context::multiDrawArraysInstanced(PrimitiveMode mode,
   6838                                       const GLint *firsts,
   6839                                       const GLsizei *counts,
   6840                                       const GLsizei *instanceCounts,
   6841                                       GLsizei drawcount)
   6842 {
   6843    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6844    ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstanced(this, mode, firsts, counts,
   6845                                                                instanceCounts, drawcount));
   6846 }
   6847 
   6848 void Context::multiDrawArraysIndirect(PrimitiveMode mode,
   6849                                      const void *indirect,
   6850                                      GLsizei drawcount,
   6851                                      GLsizei stride)
   6852 {
   6853    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6854    ANGLE_CONTEXT_TRY(
   6855        mImplementation->multiDrawArraysIndirect(this, mode, indirect, drawcount, stride));
   6856    MarkShaderStorageUsage(this);
   6857 }
   6858 
   6859 void Context::multiDrawElements(PrimitiveMode mode,
   6860                                const GLsizei *counts,
   6861                                DrawElementsType type,
   6862                                const GLvoid *const *indices,
   6863                                GLsizei drawcount)
   6864 {
   6865    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6866    ANGLE_CONTEXT_TRY(
   6867        mImplementation->multiDrawElements(this, mode, counts, type, indices, drawcount));
   6868 }
   6869 
   6870 void Context::multiDrawElementsInstanced(PrimitiveMode mode,
   6871                                         const GLsizei *counts,
   6872                                         DrawElementsType type,
   6873                                         const GLvoid *const *indices,
   6874                                         const GLsizei *instanceCounts,
   6875                                         GLsizei drawcount)
   6876 {
   6877    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6878    ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstanced(this, mode, counts, type, indices,
   6879                                                                  instanceCounts, drawcount));
   6880 }
   6881 
   6882 void Context::multiDrawElementsIndirect(PrimitiveMode mode,
   6883                                        DrawElementsType type,
   6884                                        const void *indirect,
   6885                                        GLsizei drawcount,
   6886                                        GLsizei stride)
   6887 {
   6888    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6889    ANGLE_CONTEXT_TRY(
   6890        mImplementation->multiDrawElementsIndirect(this, mode, type, indirect, drawcount, stride));
   6891    MarkShaderStorageUsage(this);
   6892 }
   6893 
   6894 void Context::drawArraysInstancedBaseInstance(PrimitiveMode mode,
   6895                                              GLint first,
   6896                                              GLsizei count,
   6897                                              GLsizei instanceCount,
   6898                                              GLuint baseInstance)
   6899 {
   6900    if (noopDrawInstanced(mode, count, instanceCount))
   6901    {
   6902        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   6903        return;
   6904    }
   6905 
   6906    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6907    Program *programObject = mState.getLinkedProgram(this);
   6908 
   6909    const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
   6910    if (hasBaseInstance)
   6911    {
   6912        programObject->setBaseInstanceUniform(baseInstance);
   6913    }
   6914 
   6915    rx::ResetBaseVertexBaseInstance resetUniforms(programObject, false, hasBaseInstance);
   6916 
   6917    // The input gl_InstanceID does not follow the baseinstance. gl_InstanceID always falls on
   6918    // the half-open range [0, instancecount). No need to set other stuff. Except for Vulkan.
   6919 
   6920    ANGLE_CONTEXT_TRY(mImplementation->drawArraysInstancedBaseInstance(
   6921        this, mode, first, count, instanceCount, baseInstance));
   6922    MarkTransformFeedbackBufferUsage(this, count, 1);
   6923 }
   6924 
   6925 void Context::drawArraysInstancedBaseInstanceANGLE(PrimitiveMode mode,
   6926                                                   GLint first,
   6927                                                   GLsizei count,
   6928                                                   GLsizei instanceCount,
   6929                                                   GLuint baseInstance)
   6930 {
   6931    drawArraysInstancedBaseInstance(mode, first, count, instanceCount, baseInstance);
   6932 }
   6933 
   6934 void Context::drawElementsInstancedBaseInstance(PrimitiveMode mode,
   6935                                                GLsizei count,
   6936                                                DrawElementsType type,
   6937                                                const void *indices,
   6938                                                GLsizei instanceCount,
   6939                                                GLuint baseInstance)
   6940 {
   6941    drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount, 0,
   6942                                                baseInstance);
   6943 }
   6944 
   6945 void Context::drawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
   6946                                                          GLsizei count,
   6947                                                          DrawElementsType type,
   6948                                                          const GLvoid *indices,
   6949                                                          GLsizei instanceCount,
   6950                                                          GLint baseVertex,
   6951                                                          GLuint baseInstance)
   6952 {
   6953    if (noopDrawInstanced(mode, count, instanceCount))
   6954    {
   6955        ANGLE_CONTEXT_TRY(mImplementation->handleNoopDrawEvent());
   6956        return;
   6957    }
   6958 
   6959    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   6960    Program *programObject = mState.getLinkedProgram(this);
   6961 
   6962    const bool hasBaseVertex = programObject && programObject->hasBaseVertexUniform();
   6963    if (hasBaseVertex)
   6964    {
   6965        programObject->setBaseVertexUniform(baseVertex);
   6966    }
   6967 
   6968    const bool hasBaseInstance = programObject && programObject->hasBaseInstanceUniform();
   6969    if (hasBaseInstance)
   6970    {
   6971        programObject->setBaseInstanceUniform(baseInstance);
   6972    }
   6973 
   6974    rx::ResetBaseVertexBaseInstance resetUniforms(programObject, hasBaseVertex, hasBaseInstance);
   6975 
   6976    ANGLE_CONTEXT_TRY(mImplementation->drawElementsInstancedBaseVertexBaseInstance(
   6977        this, mode, count, type, indices, instanceCount, baseVertex, baseInstance));
   6978 }
   6979 
   6980 void Context::drawElementsInstancedBaseVertexBaseInstanceANGLE(PrimitiveMode mode,
   6981                                                               GLsizei count,
   6982                                                               DrawElementsType type,
   6983                                                               const GLvoid *indices,
   6984                                                               GLsizei instanceCount,
   6985                                                               GLint baseVertex,
   6986                                                               GLuint baseInstance)
   6987 {
   6988    drawElementsInstancedBaseVertexBaseInstance(mode, count, type, indices, instanceCount,
   6989                                                baseVertex, baseInstance);
   6990 }
   6991 
   6992 void Context::multiDrawArraysInstancedBaseInstance(PrimitiveMode mode,
   6993                                                   const GLint *firsts,
   6994                                                   const GLsizei *counts,
   6995                                                   const GLsizei *instanceCounts,
   6996                                                   const GLuint *baseInstances,
   6997                                                   GLsizei drawcount)
   6998 {
   6999    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   7000    ANGLE_CONTEXT_TRY(mImplementation->multiDrawArraysInstancedBaseInstance(
   7001        this, mode, firsts, counts, instanceCounts, baseInstances, drawcount));
   7002 }
   7003 
   7004 void Context::multiDrawElementsInstancedBaseVertexBaseInstance(PrimitiveMode mode,
   7005                                                               const GLsizei *counts,
   7006                                                               DrawElementsType type,
   7007                                                               const GLvoid *const *indices,
   7008                                                               const GLsizei *instanceCounts,
   7009                                                               const GLint *baseVertices,
   7010                                                               const GLuint *baseInstances,
   7011                                                               GLsizei drawcount)
   7012 {
   7013    ANGLE_CONTEXT_TRY(prepareForDraw(mode));
   7014    ANGLE_CONTEXT_TRY(mImplementation->multiDrawElementsInstancedBaseVertexBaseInstance(
   7015        this, mode, counts, type, indices, instanceCounts, baseVertices, baseInstances, drawcount));
   7016 }
   7017 
   7018 void Context::provokingVertex(ProvokingVertexConvention provokeMode)
   7019 {
   7020    mState.setProvokingVertex(provokeMode);
   7021 }
   7022 
   7023 GLenum Context::checkFramebufferStatus(GLenum target)
   7024 {
   7025    Framebuffer *framebuffer = mState.getTargetFramebuffer(target);
   7026    ASSERT(framebuffer);
   7027    return framebuffer->checkStatus(this).status;
   7028 }
   7029 
   7030 void Context::compileShader(ShaderProgramID shader)
   7031 {
   7032    Shader *shaderObject = GetValidShader(this, angle::EntryPoint::GLCompileShader, shader);
   7033    if (!shaderObject)
   7034    {
   7035        return;
   7036    }
   7037    shaderObject->compile(this);
   7038 }
   7039 
   7040 void Context::deleteBuffers(GLsizei n, const BufferID *buffers)
   7041 {
   7042    for (int i = 0; i < n; i++)
   7043    {
   7044        deleteBuffer(buffers[i]);
   7045    }
   7046 }
   7047 
   7048 void Context::deleteFramebuffers(GLsizei n, const FramebufferID *framebuffers)
   7049 {
   7050    for (int i = 0; i < n; i++)
   7051    {
   7052        if (framebuffers[i].value != 0)
   7053        {
   7054            deleteFramebuffer(framebuffers[i]);
   7055        }
   7056    }
   7057 }
   7058 
   7059 void Context::deleteRenderbuffers(GLsizei n, const RenderbufferID *renderbuffers)
   7060 {
   7061    for (int i = 0; i < n; i++)
   7062    {
   7063        deleteRenderbuffer(renderbuffers[i]);
   7064    }
   7065 }
   7066 
   7067 void Context::deleteTextures(GLsizei n, const TextureID *textures)
   7068 {
   7069    for (int i = 0; i < n; i++)
   7070    {
   7071        if (textures[i].value != 0)
   7072        {
   7073            deleteTexture(textures[i]);
   7074        }
   7075    }
   7076 }
   7077 
   7078 void Context::detachShader(ShaderProgramID program, ShaderProgramID shader)
   7079 {
   7080    Program *programObject = getProgramNoResolveLink(program);
   7081    ASSERT(programObject);
   7082 
   7083    Shader *shaderObject = getShader(shader);
   7084    ASSERT(shaderObject);
   7085 
   7086    programObject->detachShader(this, shaderObject);
   7087 }
   7088 
   7089 void Context::genBuffers(GLsizei n, BufferID *buffers)
   7090 {
   7091    for (int i = 0; i < n; i++)
   7092    {
   7093        buffers[i] = createBuffer();
   7094    }
   7095 }
   7096 
   7097 void Context::genFramebuffers(GLsizei n, FramebufferID *framebuffers)
   7098 {
   7099    for (int i = 0; i < n; i++)
   7100    {
   7101        framebuffers[i] = createFramebuffer();
   7102    }
   7103 }
   7104 
   7105 void Context::genRenderbuffers(GLsizei n, RenderbufferID *renderbuffers)
   7106 {
   7107    for (int i = 0; i < n; i++)
   7108    {
   7109        renderbuffers[i] = createRenderbuffer();
   7110    }
   7111 }
   7112 
   7113 void Context::genTextures(GLsizei n, TextureID *textures)
   7114 {
   7115    for (int i = 0; i < n; i++)
   7116    {
   7117        textures[i] = createTexture();
   7118    }
   7119 }
   7120 
   7121 void Context::getActiveAttrib(ShaderProgramID program,
   7122                              GLuint index,
   7123                              GLsizei bufsize,
   7124                              GLsizei *length,
   7125                              GLint *size,
   7126                              GLenum *type,
   7127                              GLchar *name)
   7128 {
   7129    Program *programObject = getProgramResolveLink(program);
   7130    ASSERT(programObject);
   7131    programObject->getActiveAttribute(index, bufsize, length, size, type, name);
   7132 }
   7133 
   7134 void Context::getActiveUniform(ShaderProgramID program,
   7135                               GLuint index,
   7136                               GLsizei bufsize,
   7137                               GLsizei *length,
   7138                               GLint *size,
   7139                               GLenum *type,
   7140                               GLchar *name)
   7141 {
   7142    Program *programObject = getProgramResolveLink(program);
   7143    ASSERT(programObject);
   7144    programObject->getActiveUniform(index, bufsize, length, size, type, name);
   7145 }
   7146 
   7147 void Context::getAttachedShaders(ShaderProgramID program,
   7148                                 GLsizei maxcount,
   7149                                 GLsizei *count,
   7150                                 ShaderProgramID *shaders)
   7151 {
   7152    Program *programObject = getProgramNoResolveLink(program);
   7153    ASSERT(programObject);
   7154    programObject->getAttachedShaders(maxcount, count, shaders);
   7155 }
   7156 
   7157 GLint Context::getAttribLocation(ShaderProgramID program, const GLchar *name)
   7158 {
   7159    Program *programObject = getProgramResolveLink(program);
   7160    ASSERT(programObject);
   7161    return programObject->getAttributeLocation(name);
   7162 }
   7163 
   7164 void Context::getBooleanv(GLenum pname, GLboolean *params)
   7165 {
   7166    GLenum nativeType;
   7167    unsigned int numParams = 0;
   7168    getQueryParameterInfo(pname, &nativeType, &numParams);
   7169 
   7170    if (nativeType == GL_BOOL)
   7171    {
   7172        getBooleanvImpl(pname, params);
   7173    }
   7174    else
   7175    {
   7176        CastStateValues(this, nativeType, pname, numParams, params);
   7177    }
   7178 }
   7179 
   7180 void Context::getBooleanvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLboolean *params)
   7181 {
   7182    getBooleanv(pname, params);
   7183 }
   7184 
   7185 void Context::getFloatv(GLenum pname, GLfloat *params)
   7186 {
   7187    GLenum nativeType;
   7188    unsigned int numParams = 0;
   7189    getQueryParameterInfo(pname, &nativeType, &numParams);
   7190 
   7191    if (nativeType == GL_FLOAT)
   7192    {
   7193        getFloatvImpl(pname, params);
   7194    }
   7195    else
   7196    {
   7197        CastStateValues(this, nativeType, pname, numParams, params);
   7198    }
   7199 }
   7200 
   7201 void Context::getFloatvRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLfloat *params)
   7202 {
   7203    getFloatv(pname, params);
   7204 }
   7205 
   7206 void Context::getIntegerv(GLenum pname, GLint *params)
   7207 {
   7208    GLenum nativeType      = GL_NONE;
   7209    unsigned int numParams = 0;
   7210    getQueryParameterInfo(pname, &nativeType, &numParams);
   7211 
   7212    if (nativeType == GL_INT)
   7213    {
   7214        getIntegervImpl(pname, params);
   7215    }
   7216    else
   7217    {
   7218        CastStateValues(this, nativeType, pname, numParams, params);
   7219    }
   7220 }
   7221 
   7222 void Context::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint *data)
   7223 {
   7224    getIntegerv(pname, data);
   7225 }
   7226 
   7227 void Context::getProgramiv(ShaderProgramID program, GLenum pname, GLint *params)
   7228 {
   7229    // Don't resolve link if checking the link completion status.
   7230    Program *programObject = getProgramNoResolveLink(program);
   7231    if (!isContextLost() && pname != GL_COMPLETION_STATUS_KHR)
   7232    {
   7233        programObject = getProgramResolveLink(program);
   7234    }
   7235    ASSERT(programObject);
   7236    QueryProgramiv(this, programObject, pname, params);
   7237 }
   7238 
   7239 void Context::getProgramivRobust(ShaderProgramID program,
   7240                                 GLenum pname,
   7241                                 GLsizei bufSize,
   7242                                 GLsizei *length,
   7243                                 GLint *params)
   7244 {
   7245    getProgramiv(program, pname, params);
   7246 }
   7247 
   7248 void Context::getProgramPipelineiv(ProgramPipelineID pipeline, GLenum pname, GLint *params)
   7249 {
   7250    ProgramPipeline *programPipeline = nullptr;
   7251    if (!mContextLost)
   7252    {
   7253        programPipeline = getProgramPipeline(pipeline);
   7254    }
   7255    QueryProgramPipelineiv(this, programPipeline, pname, params);
   7256 }
   7257 
   7258 MemoryObject *Context::getMemoryObject(MemoryObjectID handle) const
   7259 {
   7260    return mState.mMemoryObjectManager->getMemoryObject(handle);
   7261 }
   7262 
   7263 Semaphore *Context::getSemaphore(SemaphoreID handle) const
   7264 {
   7265    return mState.mSemaphoreManager->getSemaphore(handle);
   7266 }
   7267 
   7268 void Context::getProgramInfoLog(ShaderProgramID program,
   7269                                GLsizei bufsize,
   7270                                GLsizei *length,
   7271                                GLchar *infolog)
   7272 {
   7273    Program *programObject = getProgramResolveLink(program);
   7274    ASSERT(programObject);
   7275    programObject->getExecutable().getInfoLog(bufsize, length, infolog);
   7276 }
   7277 
   7278 void Context::getProgramPipelineInfoLog(ProgramPipelineID pipeline,
   7279                                        GLsizei bufSize,
   7280                                        GLsizei *length,
   7281                                        GLchar *infoLog)
   7282 {
   7283    ProgramPipeline *programPipeline = getProgramPipeline(pipeline);
   7284    if (programPipeline)
   7285    {
   7286        programPipeline->getExecutable().getInfoLog(bufSize, length, infoLog);
   7287    }
   7288    else
   7289    {
   7290        *length  = 0;
   7291        *infoLog = '\0';
   7292    }
   7293 }
   7294 
   7295 void Context::getShaderiv(ShaderProgramID shader, GLenum pname, GLint *params)
   7296 {
   7297    Shader *shaderObject = nullptr;
   7298    if (!isContextLost())
   7299    {
   7300        shaderObject = getShader(shader);
   7301        ASSERT(shaderObject);
   7302    }
   7303    QueryShaderiv(this, shaderObject, pname, params);
   7304 }
   7305 
   7306 void Context::getShaderivRobust(ShaderProgramID shader,
   7307                                GLenum pname,
   7308                                GLsizei bufSize,
   7309                                GLsizei *length,
   7310                                GLint *params)
   7311 {
   7312    getShaderiv(shader, pname, params);
   7313 }
   7314 
   7315 void Context::getShaderInfoLog(ShaderProgramID shader,
   7316                               GLsizei bufsize,
   7317                               GLsizei *length,
   7318                               GLchar *infolog)
   7319 {
   7320    Shader *shaderObject = getShader(shader);
   7321    ASSERT(shaderObject);
   7322    shaderObject->getInfoLog(this, bufsize, length, infolog);
   7323 }
   7324 
   7325 void Context::getShaderPrecisionFormat(GLenum shadertype,
   7326                                       GLenum precisiontype,
   7327                                       GLint *range,
   7328                                       GLint *precision)
   7329 {
   7330    // TODO(jmadill): Compute shaders.
   7331 
   7332    switch (shadertype)
   7333    {
   7334        case GL_VERTEX_SHADER:
   7335            switch (precisiontype)
   7336            {
   7337                case GL_LOW_FLOAT:
   7338                    mState.mCaps.vertexLowpFloat.get(range, precision);
   7339                    break;
   7340                case GL_MEDIUM_FLOAT:
   7341                    mState.mCaps.vertexMediumpFloat.get(range, precision);
   7342                    break;
   7343                case GL_HIGH_FLOAT:
   7344                    mState.mCaps.vertexHighpFloat.get(range, precision);
   7345                    break;
   7346 
   7347                case GL_LOW_INT:
   7348                    mState.mCaps.vertexLowpInt.get(range, precision);
   7349                    break;
   7350                case GL_MEDIUM_INT:
   7351                    mState.mCaps.vertexMediumpInt.get(range, precision);
   7352                    break;
   7353                case GL_HIGH_INT:
   7354                    mState.mCaps.vertexHighpInt.get(range, precision);
   7355                    break;
   7356 
   7357                default:
   7358                    UNREACHABLE();
   7359                    return;
   7360            }
   7361            break;
   7362 
   7363        case GL_FRAGMENT_SHADER:
   7364            switch (precisiontype)
   7365            {
   7366                case GL_LOW_FLOAT:
   7367                    mState.mCaps.fragmentLowpFloat.get(range, precision);
   7368                    break;
   7369                case GL_MEDIUM_FLOAT:
   7370                    mState.mCaps.fragmentMediumpFloat.get(range, precision);
   7371                    break;
   7372                case GL_HIGH_FLOAT:
   7373                    mState.mCaps.fragmentHighpFloat.get(range, precision);
   7374                    break;
   7375 
   7376                case GL_LOW_INT:
   7377                    mState.mCaps.fragmentLowpInt.get(range, precision);
   7378                    break;
   7379                case GL_MEDIUM_INT:
   7380                    mState.mCaps.fragmentMediumpInt.get(range, precision);
   7381                    break;
   7382                case GL_HIGH_INT:
   7383                    mState.mCaps.fragmentHighpInt.get(range, precision);
   7384                    break;
   7385 
   7386                default:
   7387                    UNREACHABLE();
   7388                    return;
   7389            }
   7390            break;
   7391 
   7392        default:
   7393            UNREACHABLE();
   7394            return;
   7395    }
   7396 }
   7397 
   7398 void Context::getShaderSource(ShaderProgramID shader,
   7399                              GLsizei bufsize,
   7400                              GLsizei *length,
   7401                              GLchar *source)
   7402 {
   7403    Shader *shaderObject = getShader(shader);
   7404    ASSERT(shaderObject);
   7405    shaderObject->getSource(bufsize, length, source);
   7406 }
   7407 
   7408 void Context::getUniformfv(ShaderProgramID program, UniformLocation location, GLfloat *params)
   7409 {
   7410    Program *programObject = getProgramResolveLink(program);
   7411    ASSERT(programObject);
   7412    programObject->getUniformfv(this, location, params);
   7413 }
   7414 
   7415 void Context::getUniformfvRobust(ShaderProgramID program,
   7416                                 UniformLocation location,
   7417                                 GLsizei bufSize,
   7418                                 GLsizei *length,
   7419                                 GLfloat *params)
   7420 {
   7421    getUniformfv(program, location, params);
   7422 }
   7423 
   7424 void Context::getUniformiv(ShaderProgramID program, UniformLocation location, GLint *params)
   7425 {
   7426    Program *programObject = getProgramResolveLink(program);
   7427    ASSERT(programObject);
   7428    programObject->getUniformiv(this, location, params);
   7429 }
   7430 
   7431 void Context::getUniformivRobust(ShaderProgramID program,
   7432                                 UniformLocation location,
   7433                                 GLsizei bufSize,
   7434                                 GLsizei *length,
   7435                                 GLint *params)
   7436 {
   7437    getUniformiv(program, location, params);
   7438 }
   7439 
   7440 GLint Context::getUniformLocation(ShaderProgramID program, const GLchar *name)
   7441 {
   7442    Program *programObject = getProgramResolveLink(program);
   7443    ASSERT(programObject);
   7444    return programObject->getUniformLocation(name).value;
   7445 }
   7446 
   7447 GLboolean Context::isBuffer(BufferID buffer) const
   7448 {
   7449    if (buffer.value == 0)
   7450    {
   7451        return GL_FALSE;
   7452    }
   7453 
   7454    return ConvertToGLBoolean(getBuffer(buffer));
   7455 }
   7456 
   7457 GLboolean Context::isEnabled(GLenum cap) const
   7458 {
   7459    return mState.getEnableFeature(cap);
   7460 }
   7461 
   7462 GLboolean Context::isEnabledi(GLenum target, GLuint index) const
   7463 {
   7464    return mState.getEnableFeatureIndexed(target, index);
   7465 }
   7466 
   7467 GLboolean Context::isFramebuffer(FramebufferID framebuffer) const
   7468 {
   7469    if (framebuffer.value == 0)
   7470    {
   7471        return GL_FALSE;
   7472    }
   7473 
   7474    return ConvertToGLBoolean(getFramebuffer(framebuffer));
   7475 }
   7476 
   7477 GLboolean Context::isProgram(ShaderProgramID program) const
   7478 {
   7479    if (program.value == 0)
   7480    {
   7481        return GL_FALSE;
   7482    }
   7483 
   7484    return ConvertToGLBoolean(getProgramNoResolveLink(program));
   7485 }
   7486 
   7487 GLboolean Context::isRenderbuffer(RenderbufferID renderbuffer) const
   7488 {
   7489    if (renderbuffer.value == 0)
   7490    {
   7491        return GL_FALSE;
   7492    }
   7493 
   7494    return ConvertToGLBoolean(getRenderbuffer(renderbuffer));
   7495 }
   7496 
   7497 GLboolean Context::isShader(ShaderProgramID shader) const
   7498 {
   7499    if (shader.value == 0)
   7500    {
   7501        return GL_FALSE;
   7502    }
   7503 
   7504    return ConvertToGLBoolean(getShader(shader));
   7505 }
   7506 
   7507 GLboolean Context::isTexture(TextureID texture) const
   7508 {
   7509    if (texture.value == 0)
   7510    {
   7511        return GL_FALSE;
   7512    }
   7513 
   7514    return ConvertToGLBoolean(getTexture(texture));
   7515 }
   7516 
   7517 void Context::linkProgram(ShaderProgramID program)
   7518 {
   7519    Program *programObject = getProgramNoResolveLink(program);
   7520    ASSERT(programObject);
   7521    ANGLE_CONTEXT_TRY(programObject->link(this));
   7522    ANGLE_CONTEXT_TRY(onProgramLink(programObject));
   7523 }
   7524 
   7525 void Context::releaseShaderCompiler()
   7526 {
   7527    mCompiler.set(this, nullptr);
   7528 }
   7529 
   7530 void Context::shaderBinary(GLsizei n,
   7531                           const ShaderProgramID *shaders,
   7532                           GLenum binaryformat,
   7533                           const void *binary,
   7534                           GLsizei length)
   7535 {
   7536    // No binary shader formats are supported.
   7537    UNIMPLEMENTED();
   7538 }
   7539 
   7540 void Context::bindFragDataLocationIndexed(ShaderProgramID program,
   7541                                          GLuint colorNumber,
   7542                                          GLuint index,
   7543                                          const char *name)
   7544 {
   7545    Program *programObject = getProgramNoResolveLink(program);
   7546    programObject->bindFragmentOutputLocation(colorNumber, name);
   7547    programObject->bindFragmentOutputIndex(index, name);
   7548 }
   7549 
   7550 void Context::bindFragDataLocation(ShaderProgramID program, GLuint colorNumber, const char *name)
   7551 {
   7552    bindFragDataLocationIndexed(program, colorNumber, 0u, name);
   7553 }
   7554 
   7555 int Context::getFragDataIndex(ShaderProgramID program, const char *name)
   7556 {
   7557    Program *programObject = getProgramResolveLink(program);
   7558    return programObject->getFragDataIndex(name);
   7559 }
   7560 
   7561 int Context::getProgramResourceLocationIndex(ShaderProgramID program,
   7562                                             GLenum programInterface,
   7563                                             const char *name)
   7564 {
   7565    Program *programObject = getProgramResolveLink(program);
   7566    ASSERT(programInterface == GL_PROGRAM_OUTPUT);
   7567    return programObject->getFragDataIndex(name);
   7568 }
   7569 
   7570 void Context::shaderSource(ShaderProgramID shader,
   7571                           GLsizei count,
   7572                           const GLchar *const *string,
   7573                           const GLint *length)
   7574 {
   7575    Shader *shaderObject = getShader(shader);
   7576    ASSERT(shaderObject);
   7577    shaderObject->setSource(count, string, length);
   7578 }
   7579 
   7580 void Context::stencilFunc(GLenum func, GLint ref, GLuint mask)
   7581 {
   7582    stencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
   7583 }
   7584 
   7585 void Context::stencilMask(GLuint mask)
   7586 {
   7587    stencilMaskSeparate(GL_FRONT_AND_BACK, mask);
   7588 }
   7589 
   7590 void Context::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
   7591 {
   7592    stencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
   7593 }
   7594 
   7595 void Context::patchParameteri(GLenum pname, GLint value)
   7596 {
   7597    switch (pname)
   7598    {
   7599        case GL_PATCH_VERTICES:
   7600            mState.setPatchVertices(value);
   7601            break;
   7602        default:
   7603            break;
   7604    }
   7605 }
   7606 
   7607 Program *Context::getActiveLinkedProgram() const
   7608 {
   7609    Program *program = mState.getLinkedProgram(this);
   7610    if (!program)
   7611    {
   7612        ProgramPipeline *programPipelineObject = mState.getProgramPipeline();
   7613        if (programPipelineObject)
   7614        {
   7615            program = programPipelineObject->getLinkedActiveShaderProgram(this);
   7616        }
   7617    }
   7618 
   7619    return program;
   7620 }
   7621 
   7622 void Context::uniform1f(UniformLocation location, GLfloat x)
   7623 {
   7624    Program *program = getActiveLinkedProgram();
   7625    program->setUniform1fv(location, 1, &x);
   7626 }
   7627 
   7628 void Context::uniform1fv(UniformLocation location, GLsizei count, const GLfloat *v)
   7629 {
   7630    Program *program = getActiveLinkedProgram();
   7631    program->setUniform1fv(location, count, v);
   7632 }
   7633 
   7634 void Context::setUniform1iImpl(Program *program,
   7635                               UniformLocation location,
   7636                               GLsizei count,
   7637                               const GLint *v)
   7638 {
   7639    program->setUniform1iv(this, location, count, v);
   7640 }
   7641 
   7642 void Context::onSamplerUniformChange(size_t textureUnitIndex)
   7643 {
   7644    mState.onActiveTextureChange(this, textureUnitIndex);
   7645    mStateCache.onActiveTextureChange(this);
   7646 }
   7647 
   7648 void Context::uniform1i(UniformLocation location, GLint x)
   7649 {
   7650    Program *program = getActiveLinkedProgram();
   7651    setUniform1iImpl(program, location, 1, &x);
   7652 }
   7653 
   7654 void Context::uniform1iv(UniformLocation location, GLsizei count, const GLint *v)
   7655 {
   7656    Program *program = getActiveLinkedProgram();
   7657    setUniform1iImpl(program, location, count, v);
   7658 }
   7659 
   7660 void Context::uniform2f(UniformLocation location, GLfloat x, GLfloat y)
   7661 {
   7662    GLfloat xy[2]    = {x, y};
   7663    Program *program = getActiveLinkedProgram();
   7664    program->setUniform2fv(location, 1, xy);
   7665 }
   7666 
   7667 void Context::uniform2fv(UniformLocation location, GLsizei count, const GLfloat *v)
   7668 {
   7669    Program *program = getActiveLinkedProgram();
   7670    program->setUniform2fv(location, count, v);
   7671 }
   7672 
   7673 void Context::uniform2i(UniformLocation location, GLint x, GLint y)
   7674 {
   7675    GLint xy[2]      = {x, y};
   7676    Program *program = getActiveLinkedProgram();
   7677    program->setUniform2iv(location, 1, xy);
   7678 }
   7679 
   7680 void Context::uniform2iv(UniformLocation location, GLsizei count, const GLint *v)
   7681 {
   7682    Program *program = getActiveLinkedProgram();
   7683    program->setUniform2iv(location, count, v);
   7684 }
   7685 
   7686 void Context::uniform3f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z)
   7687 {
   7688    GLfloat xyz[3]   = {x, y, z};
   7689    Program *program = getActiveLinkedProgram();
   7690    program->setUniform3fv(location, 1, xyz);
   7691 }
   7692 
   7693 void Context::uniform3fv(UniformLocation location, GLsizei count, const GLfloat *v)
   7694 {
   7695    Program *program = getActiveLinkedProgram();
   7696    program->setUniform3fv(location, count, v);
   7697 }
   7698 
   7699 void Context::uniform3i(UniformLocation location, GLint x, GLint y, GLint z)
   7700 {
   7701    GLint xyz[3]     = {x, y, z};
   7702    Program *program = getActiveLinkedProgram();
   7703    program->setUniform3iv(location, 1, xyz);
   7704 }
   7705 
   7706 void Context::uniform3iv(UniformLocation location, GLsizei count, const GLint *v)
   7707 {
   7708    Program *program = getActiveLinkedProgram();
   7709    program->setUniform3iv(location, count, v);
   7710 }
   7711 
   7712 void Context::uniform4f(UniformLocation location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   7713 {
   7714    GLfloat xyzw[4]  = {x, y, z, w};
   7715    Program *program = getActiveLinkedProgram();
   7716    program->setUniform4fv(location, 1, xyzw);
   7717 }
   7718 
   7719 void Context::uniform4fv(UniformLocation location, GLsizei count, const GLfloat *v)
   7720 {
   7721    Program *program = getActiveLinkedProgram();
   7722    program->setUniform4fv(location, count, v);
   7723 }
   7724 
   7725 void Context::uniform4i(UniformLocation location, GLint x, GLint y, GLint z, GLint w)
   7726 {
   7727    GLint xyzw[4]    = {x, y, z, w};
   7728    Program *program = getActiveLinkedProgram();
   7729    program->setUniform4iv(location, 1, xyzw);
   7730 }
   7731 
   7732 void Context::uniform4iv(UniformLocation location, GLsizei count, const GLint *v)
   7733 {
   7734    Program *program = getActiveLinkedProgram();
   7735    program->setUniform4iv(location, count, v);
   7736 }
   7737 
   7738 void Context::uniformMatrix2fv(UniformLocation location,
   7739                               GLsizei count,
   7740                               GLboolean transpose,
   7741                               const GLfloat *value)
   7742 {
   7743    Program *program = getActiveLinkedProgram();
   7744    program->setUniformMatrix2fv(location, count, transpose, value);
   7745 }
   7746 
   7747 void Context::uniformMatrix3fv(UniformLocation location,
   7748                               GLsizei count,
   7749                               GLboolean transpose,
   7750                               const GLfloat *value)
   7751 {
   7752    Program *program = getActiveLinkedProgram();
   7753    program->setUniformMatrix3fv(location, count, transpose, value);
   7754 }
   7755 
   7756 void Context::uniformMatrix4fv(UniformLocation location,
   7757                               GLsizei count,
   7758                               GLboolean transpose,
   7759                               const GLfloat *value)
   7760 {
   7761    Program *program = getActiveLinkedProgram();
   7762    program->setUniformMatrix4fv(location, count, transpose, value);
   7763 }
   7764 
   7765 void Context::validateProgram(ShaderProgramID program)
   7766 {
   7767    Program *programObject = getProgramResolveLink(program);
   7768    ASSERT(programObject);
   7769    programObject->validate(mState.mCaps);
   7770 }
   7771 
   7772 void Context::validateProgramPipeline(ProgramPipelineID pipeline)
   7773 {
   7774    // GLES spec 3.2, Section 7.4 "Program Pipeline Objects"
   7775    // If pipeline is a name that has been generated (without subsequent deletion) by
   7776    // GenProgramPipelines, but refers to a program pipeline object that has not been
   7777    // previously bound, the GL first creates a new state vector in the same manner as
   7778    // when BindProgramPipeline creates a new program pipeline object.
   7779    //
   7780    // void BindProgramPipeline( uint pipeline );
   7781    // pipeline is the program pipeline object name. The resulting program pipeline
   7782    // object is a new state vector, comprising all the state and with the same initial values
   7783    // listed in table 21.20.
   7784    //
   7785    // If we do not have a pipeline object that's been created with glBindProgramPipeline, we leave
   7786    // VALIDATE_STATUS at it's default false value without generating a pipeline object.
   7787    if (!getProgramPipeline(pipeline))
   7788    {
   7789        return;
   7790    }
   7791 
   7792    ProgramPipeline *programPipeline =
   7793        mState.mProgramPipelineManager->checkProgramPipelineAllocation(mImplementation.get(),
   7794                                                                       pipeline);
   7795    ASSERT(programPipeline);
   7796 
   7797    programPipeline->validate(this);
   7798 }
   7799 
   7800 void Context::getProgramBinary(ShaderProgramID program,
   7801                               GLsizei bufSize,
   7802                               GLsizei *length,
   7803                               GLenum *binaryFormat,
   7804                               void *binary)
   7805 {
   7806    Program *programObject = getProgramResolveLink(program);
   7807    ASSERT(programObject != nullptr);
   7808 
   7809    ANGLE_CONTEXT_TRY(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
   7810 }
   7811 
   7812 void Context::programBinary(ShaderProgramID program,
   7813                            GLenum binaryFormat,
   7814                            const void *binary,
   7815                            GLsizei length)
   7816 {
   7817    Program *programObject = getProgramResolveLink(program);
   7818    ASSERT(programObject != nullptr);
   7819 
   7820    ANGLE_CONTEXT_TRY(programObject->loadBinary(this, binaryFormat, binary, length));
   7821    ANGLE_CONTEXT_TRY(onProgramLink(programObject));
   7822 }
   7823 
   7824 void Context::uniform1ui(UniformLocation location, GLuint v0)
   7825 {
   7826    Program *program = getActiveLinkedProgram();
   7827    program->setUniform1uiv(location, 1, &v0);
   7828 }
   7829 
   7830 void Context::uniform2ui(UniformLocation location, GLuint v0, GLuint v1)
   7831 {
   7832    Program *program  = getActiveLinkedProgram();
   7833    const GLuint xy[] = {v0, v1};
   7834    program->setUniform2uiv(location, 1, xy);
   7835 }
   7836 
   7837 void Context::uniform3ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2)
   7838 {
   7839    Program *program   = getActiveLinkedProgram();
   7840    const GLuint xyz[] = {v0, v1, v2};
   7841    program->setUniform3uiv(location, 1, xyz);
   7842 }
   7843 
   7844 void Context::uniform4ui(UniformLocation location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
   7845 {
   7846    Program *program    = getActiveLinkedProgram();
   7847    const GLuint xyzw[] = {v0, v1, v2, v3};
   7848    program->setUniform4uiv(location, 1, xyzw);
   7849 }
   7850 
   7851 void Context::uniform1uiv(UniformLocation location, GLsizei count, const GLuint *value)
   7852 {
   7853    Program *program = getActiveLinkedProgram();
   7854    program->setUniform1uiv(location, count, value);
   7855 }
   7856 void Context::uniform2uiv(UniformLocation location, GLsizei count, const GLuint *value)
   7857 {
   7858    Program *program = getActiveLinkedProgram();
   7859    program->setUniform2uiv(location, count, value);
   7860 }
   7861 
   7862 void Context::uniform3uiv(UniformLocation location, GLsizei count, const GLuint *value)
   7863 {
   7864    Program *program = getActiveLinkedProgram();
   7865    program->setUniform3uiv(location, count, value);
   7866 }
   7867 
   7868 void Context::uniform4uiv(UniformLocation location, GLsizei count, const GLuint *value)
   7869 {
   7870    Program *program = getActiveLinkedProgram();
   7871    program->setUniform4uiv(location, count, value);
   7872 }
   7873 
   7874 void Context::genQueries(GLsizei n, QueryID *ids)
   7875 {
   7876    for (GLsizei i = 0; i < n; i++)
   7877    {
   7878        QueryID handle = QueryID{mQueryHandleAllocator.allocate()};
   7879        mQueryMap.assign(handle, nullptr);
   7880        ids[i] = handle;
   7881    }
   7882 }
   7883 
   7884 void Context::deleteQueries(GLsizei n, const QueryID *ids)
   7885 {
   7886    for (int i = 0; i < n; i++)
   7887    {
   7888        QueryID query = ids[i];
   7889 
   7890        Query *queryObject = nullptr;
   7891        if (mQueryMap.erase(query, &queryObject))
   7892        {
   7893            mQueryHandleAllocator.release(query.value);
   7894            if (queryObject)
   7895            {
   7896                queryObject->release(this);
   7897            }
   7898        }
   7899    }
   7900 }
   7901 
   7902 bool Context::isQueryGenerated(QueryID query) const
   7903 {
   7904    return mQueryMap.contains(query);
   7905 }
   7906 
   7907 GLboolean Context::isQuery(QueryID id) const
   7908 {
   7909    return ConvertToGLBoolean(getQuery(id) != nullptr);
   7910 }
   7911 
   7912 void Context::uniformMatrix2x3fv(UniformLocation location,
   7913                                 GLsizei count,
   7914                                 GLboolean transpose,
   7915                                 const GLfloat *value)
   7916 {
   7917    Program *program = getActiveLinkedProgram();
   7918    program->setUniformMatrix2x3fv(location, count, transpose, value);
   7919 }
   7920 
   7921 void Context::uniformMatrix3x2fv(UniformLocation location,
   7922                                 GLsizei count,
   7923                                 GLboolean transpose,
   7924                                 const GLfloat *value)
   7925 {
   7926    Program *program = getActiveLinkedProgram();
   7927    program->setUniformMatrix3x2fv(location, count, transpose, value);
   7928 }
   7929 
   7930 void Context::uniformMatrix2x4fv(UniformLocation location,
   7931                                 GLsizei count,
   7932                                 GLboolean transpose,
   7933                                 const GLfloat *value)
   7934 {
   7935    Program *program = getActiveLinkedProgram();
   7936    program->setUniformMatrix2x4fv(location, count, transpose, value);
   7937 }
   7938 
   7939 void Context::uniformMatrix4x2fv(UniformLocation location,
   7940                                 GLsizei count,
   7941                                 GLboolean transpose,
   7942                                 const GLfloat *value)
   7943 {
   7944    Program *program = getActiveLinkedProgram();
   7945    program->setUniformMatrix4x2fv(location, count, transpose, value);
   7946 }
   7947 
   7948 void Context::uniformMatrix3x4fv(UniformLocation location,
   7949                                 GLsizei count,
   7950                                 GLboolean transpose,
   7951                                 const GLfloat *value)
   7952 {
   7953    Program *program = getActiveLinkedProgram();
   7954    program->setUniformMatrix3x4fv(location, count, transpose, value);
   7955 }
   7956 
   7957 void Context::uniformMatrix4x3fv(UniformLocation location,
   7958                                 GLsizei count,
   7959                                 GLboolean transpose,
   7960                                 const GLfloat *value)
   7961 {
   7962    Program *program = getActiveLinkedProgram();
   7963    program->setUniformMatrix4x3fv(location, count, transpose, value);
   7964 }
   7965 
   7966 void Context::deleteVertexArrays(GLsizei n, const VertexArrayID *arrays)
   7967 {
   7968    for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
   7969    {
   7970        VertexArrayID vertexArray = arrays[arrayIndex];
   7971 
   7972        if (arrays[arrayIndex].value != 0)
   7973        {
   7974            VertexArray *vertexArrayObject = nullptr;
   7975            if (mVertexArrayMap.erase(vertexArray, &vertexArrayObject))
   7976            {
   7977                if (vertexArrayObject != nullptr)
   7978                {
   7979                    detachVertexArray(vertexArray);
   7980                    vertexArrayObject->onDestroy(this);
   7981                }
   7982 
   7983                mVertexArrayHandleAllocator.release(vertexArray.value);
   7984            }
   7985        }
   7986    }
   7987 }
   7988 
   7989 void Context::genVertexArrays(GLsizei n, VertexArrayID *arrays)
   7990 {
   7991    for (int arrayIndex = 0; arrayIndex < n; arrayIndex++)
   7992    {
   7993        VertexArrayID vertexArray = {mVertexArrayHandleAllocator.allocate()};
   7994        mVertexArrayMap.assign(vertexArray, nullptr);
   7995        arrays[arrayIndex] = vertexArray;
   7996    }
   7997 }
   7998 
   7999 GLboolean Context::isVertexArray(VertexArrayID array) const
   8000 {
   8001    if (array.value == 0)
   8002    {
   8003        return GL_FALSE;
   8004    }
   8005 
   8006    VertexArray *vao = getVertexArray(array);
   8007    return ConvertToGLBoolean(vao != nullptr);
   8008 }
   8009 
   8010 void Context::endTransformFeedback()
   8011 {
   8012    TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
   8013    ANGLE_CONTEXT_TRY(transformFeedback->end(this));
   8014    mStateCache.onActiveTransformFeedbackChange(this);
   8015 }
   8016 
   8017 void Context::transformFeedbackVaryings(ShaderProgramID program,
   8018                                        GLsizei count,
   8019                                        const GLchar *const *varyings,
   8020                                        GLenum bufferMode)
   8021 {
   8022    Program *programObject = getProgramResolveLink(program);
   8023    ASSERT(programObject);
   8024    programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
   8025 }
   8026 
   8027 void Context::getTransformFeedbackVarying(ShaderProgramID program,
   8028                                          GLuint index,
   8029                                          GLsizei bufSize,
   8030                                          GLsizei *length,
   8031                                          GLsizei *size,
   8032                                          GLenum *type,
   8033                                          GLchar *name)
   8034 {
   8035    Program *programObject = getProgramResolveLink(program);
   8036    ASSERT(programObject);
   8037    programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
   8038 }
   8039 
   8040 void Context::deleteTransformFeedbacks(GLsizei n, const TransformFeedbackID *ids)
   8041 {
   8042    for (int i = 0; i < n; i++)
   8043    {
   8044        TransformFeedbackID transformFeedback = ids[i];
   8045        if (transformFeedback.value == 0)
   8046        {
   8047            continue;
   8048        }
   8049 
   8050        TransformFeedback *transformFeedbackObject = nullptr;
   8051        if (mTransformFeedbackMap.erase(transformFeedback, &transformFeedbackObject))
   8052        {
   8053            if (transformFeedbackObject != nullptr)
   8054            {
   8055                detachTransformFeedback(transformFeedback);
   8056                transformFeedbackObject->release(this);
   8057            }
   8058 
   8059            mTransformFeedbackHandleAllocator.release(transformFeedback.value);
   8060        }
   8061    }
   8062 }
   8063 
   8064 void Context::genTransformFeedbacks(GLsizei n, TransformFeedbackID *ids)
   8065 {
   8066    for (int i = 0; i < n; i++)
   8067    {
   8068        TransformFeedbackID transformFeedback = {mTransformFeedbackHandleAllocator.allocate()};
   8069        mTransformFeedbackMap.assign(transformFeedback, nullptr);
   8070        ids[i] = transformFeedback;
   8071    }
   8072 }
   8073 
   8074 GLboolean Context::isTransformFeedback(TransformFeedbackID id) const
   8075 {
   8076    if (id.value == 0)
   8077    {
   8078        // The 3.0.4 spec [section 6.1.11] states that if ID is zero, IsTransformFeedback
   8079        // returns FALSE
   8080        return GL_FALSE;
   8081    }
   8082 
   8083    const TransformFeedback *transformFeedback = getTransformFeedback(id);
   8084    return ConvertToGLBoolean(transformFeedback != nullptr);
   8085 }
   8086 
   8087 void Context::pauseTransformFeedback()
   8088 {
   8089    TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
   8090    ANGLE_CONTEXT_TRY(transformFeedback->pause(this));
   8091    mStateCache.onActiveTransformFeedbackChange(this);
   8092 }
   8093 
   8094 void Context::resumeTransformFeedback()
   8095 {
   8096    TransformFeedback *transformFeedback = mState.getCurrentTransformFeedback();
   8097    ANGLE_CONTEXT_TRY(transformFeedback->resume(this));
   8098    mStateCache.onActiveTransformFeedbackChange(this);
   8099 }
   8100 
   8101 void Context::getUniformuiv(ShaderProgramID program, UniformLocation location, GLuint *params)
   8102 {
   8103    const Program *programObject = getProgramResolveLink(program);
   8104    programObject->getUniformuiv(this, location, params);
   8105 }
   8106 
   8107 void Context::getUniformuivRobust(ShaderProgramID program,
   8108                                  UniformLocation location,
   8109                                  GLsizei bufSize,
   8110                                  GLsizei *length,
   8111                                  GLuint *params)
   8112 {
   8113    getUniformuiv(program, location, params);
   8114 }
   8115 
   8116 GLint Context::getFragDataLocation(ShaderProgramID program, const GLchar *name)
   8117 {
   8118    const Program *programObject = getProgramResolveLink(program);
   8119    return programObject->getFragDataLocation(name);
   8120 }
   8121 
   8122 void Context::getUniformIndices(ShaderProgramID program,
   8123                                GLsizei uniformCount,
   8124                                const GLchar *const *uniformNames,
   8125                                GLuint *uniformIndices)
   8126 {
   8127    const Program *programObject = getProgramResolveLink(program);
   8128    if (!programObject->isLinked())
   8129    {
   8130        for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8131        {
   8132            uniformIndices[uniformId] = GL_INVALID_INDEX;
   8133        }
   8134    }
   8135    else
   8136    {
   8137        for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8138        {
   8139            uniformIndices[uniformId] = programObject->getUniformIndex(uniformNames[uniformId]);
   8140        }
   8141    }
   8142 }
   8143 
   8144 void Context::getActiveUniformsiv(ShaderProgramID program,
   8145                                  GLsizei uniformCount,
   8146                                  const GLuint *uniformIndices,
   8147                                  GLenum pname,
   8148                                  GLint *params)
   8149 {
   8150    const Program *programObject = getProgramResolveLink(program);
   8151    for (int uniformId = 0; uniformId < uniformCount; uniformId++)
   8152    {
   8153        const GLuint index = uniformIndices[uniformId];
   8154        params[uniformId]  = GetUniformResourceProperty(programObject, index, pname);
   8155    }
   8156 }
   8157 
   8158 GLuint Context::getUniformBlockIndex(ShaderProgramID program, const GLchar *uniformBlockName)
   8159 {
   8160    const Program *programObject = getProgramResolveLink(program);
   8161    return programObject->getUniformBlockIndex(uniformBlockName);
   8162 }
   8163 
   8164 void Context::getActiveUniformBlockiv(ShaderProgramID program,
   8165                                      UniformBlockIndex uniformBlockIndex,
   8166                                      GLenum pname,
   8167                                      GLint *params)
   8168 {
   8169    const Program *programObject = getProgramResolveLink(program);
   8170    QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
   8171 }
   8172 
   8173 void Context::getActiveUniformBlockivRobust(ShaderProgramID program,
   8174                                            UniformBlockIndex uniformBlockIndex,
   8175                                            GLenum pname,
   8176                                            GLsizei bufSize,
   8177                                            GLsizei *length,
   8178                                            GLint *params)
   8179 {
   8180    getActiveUniformBlockiv(program, uniformBlockIndex, pname, params);
   8181 }
   8182 
   8183 void Context::getActiveUniformBlockName(ShaderProgramID program,
   8184                                        UniformBlockIndex uniformBlockIndex,
   8185                                        GLsizei bufSize,
   8186                                        GLsizei *length,
   8187                                        GLchar *uniformBlockName)
   8188 {
   8189    const Program *programObject = getProgramResolveLink(program);
   8190    programObject->getActiveUniformBlockName(this, uniformBlockIndex, bufSize, length,
   8191                                             uniformBlockName);
   8192 }
   8193 
   8194 void Context::uniformBlockBinding(ShaderProgramID program,
   8195                                  UniformBlockIndex uniformBlockIndex,
   8196                                  GLuint uniformBlockBinding)
   8197 {
   8198    Program *programObject = getProgramResolveLink(program);
   8199    programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
   8200 
   8201    // Note: If the Program is shared between Contexts we would be better using Observer/Subject.
   8202    if (programObject->isInUse())
   8203    {
   8204        mState.setObjectDirty(GL_PROGRAM);
   8205        mStateCache.onUniformBufferStateChange(this);
   8206    }
   8207 }
   8208 
   8209 GLsync Context::fenceSync(GLenum condition, GLbitfield flags)
   8210 {
   8211    GLuint handle     = mState.mSyncManager->createSync(mImplementation.get());
   8212    GLsync syncHandle = reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
   8213 
   8214    Sync *syncObject = getSync(syncHandle);
   8215    if (syncObject->set(this, condition, flags) == angle::Result::Stop)
   8216    {
   8217        deleteSync(syncHandle);
   8218        return nullptr;
   8219    }
   8220 
   8221    return syncHandle;
   8222 }
   8223 
   8224 GLboolean Context::isSync(GLsync sync) const
   8225 {
   8226    return (getSync(sync) != nullptr);
   8227 }
   8228 
   8229 GLenum Context::clientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
   8230 {
   8231    Sync *syncObject = getSync(sync);
   8232 
   8233    GLenum result = GL_WAIT_FAILED;
   8234    if (syncObject->clientWait(this, flags, timeout, &result) == angle::Result::Stop)
   8235    {
   8236        return GL_WAIT_FAILED;
   8237    }
   8238    return result;
   8239 }
   8240 
   8241 void Context::waitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
   8242 {
   8243    Sync *syncObject = getSync(sync);
   8244    ANGLE_CONTEXT_TRY(syncObject->serverWait(this, flags, timeout));
   8245 }
   8246 
   8247 void Context::getInteger64v(GLenum pname, GLint64 *params)
   8248 {
   8249    GLenum nativeType      = GL_NONE;
   8250    unsigned int numParams = 0;
   8251    getQueryParameterInfo(pname, &nativeType, &numParams);
   8252 
   8253    if (nativeType == GL_INT_64_ANGLEX)
   8254    {
   8255        getInteger64vImpl(pname, params);
   8256    }
   8257    else
   8258    {
   8259        CastStateValues(this, nativeType, pname, numParams, params);
   8260    }
   8261 }
   8262 
   8263 void Context::getInteger64vRobust(GLenum pname, GLsizei bufSize, GLsizei *length, GLint64 *data)
   8264 {
   8265    getInteger64v(pname, data);
   8266 }
   8267 
   8268 void Context::getBufferParameteri64v(BufferBinding target, GLenum pname, GLint64 *params)
   8269 {
   8270    Buffer *buffer = mState.getTargetBuffer(target);
   8271    QueryBufferParameteri64v(buffer, pname, params);
   8272 }
   8273 
   8274 void Context::getBufferParameteri64vRobust(BufferBinding target,
   8275                                           GLenum pname,
   8276                                           GLsizei bufSize,
   8277                                           GLsizei *length,
   8278                                           GLint64 *params)
   8279 {
   8280    getBufferParameteri64v(target, pname, params);
   8281 }
   8282 
   8283 void Context::genSamplers(GLsizei count, SamplerID *samplers)
   8284 {
   8285    for (int i = 0; i < count; i++)
   8286    {
   8287        samplers[i] = mState.mSamplerManager->createSampler();
   8288    }
   8289 }
   8290 
   8291 void Context::deleteSamplers(GLsizei count, const SamplerID *samplers)
   8292 {
   8293    for (int i = 0; i < count; i++)
   8294    {
   8295        SamplerID sampler = samplers[i];
   8296 
   8297        if (mState.mSamplerManager->getSampler(sampler))
   8298        {
   8299            detachSampler(sampler);
   8300        }
   8301 
   8302        mState.mSamplerManager->deleteObject(this, sampler);
   8303    }
   8304 }
   8305 
   8306 void Context::minSampleShading(GLfloat value)
   8307 {
   8308    mState.setMinSampleShading(value);
   8309 }
   8310 
   8311 void Context::getInternalformativ(GLenum target,
   8312                                  GLenum internalformat,
   8313                                  GLenum pname,
   8314                                  GLsizei bufSize,
   8315                                  GLint *params)
   8316 {
   8317    const TextureCaps &formatCaps = mState.mTextureCaps.get(internalformat);
   8318    QueryInternalFormativ(formatCaps, pname, bufSize, params);
   8319 }
   8320 
   8321 void Context::getInternalformativRobust(GLenum target,
   8322                                        GLenum internalformat,
   8323                                        GLenum pname,
   8324                                        GLsizei bufSize,
   8325                                        GLsizei *length,
   8326                                        GLint *params)
   8327 {
   8328    getInternalformativ(target, internalformat, pname, bufSize, params);
   8329 }
   8330 
   8331 void Context::programUniform1i(ShaderProgramID program, UniformLocation location, GLint v0)
   8332 {
   8333    programUniform1iv(program, location, 1, &v0);
   8334 }
   8335 
   8336 void Context::programUniform2i(ShaderProgramID program,
   8337                               UniformLocation location,
   8338                               GLint v0,
   8339                               GLint v1)
   8340 {
   8341    GLint xy[2] = {v0, v1};
   8342    programUniform2iv(program, location, 1, xy);
   8343 }
   8344 
   8345 void Context::programUniform3i(ShaderProgramID program,
   8346                               UniformLocation location,
   8347                               GLint v0,
   8348                               GLint v1,
   8349                               GLint v2)
   8350 {
   8351    GLint xyz[3] = {v0, v1, v2};
   8352    programUniform3iv(program, location, 1, xyz);
   8353 }
   8354 
   8355 void Context::programUniform4i(ShaderProgramID program,
   8356                               UniformLocation location,
   8357                               GLint v0,
   8358                               GLint v1,
   8359                               GLint v2,
   8360                               GLint v3)
   8361 {
   8362    GLint xyzw[4] = {v0, v1, v2, v3};
   8363    programUniform4iv(program, location, 1, xyzw);
   8364 }
   8365 
   8366 void Context::programUniform1ui(ShaderProgramID program, UniformLocation location, GLuint v0)
   8367 {
   8368    programUniform1uiv(program, location, 1, &v0);
   8369 }
   8370 
   8371 void Context::programUniform2ui(ShaderProgramID program,
   8372                                UniformLocation location,
   8373                                GLuint v0,
   8374                                GLuint v1)
   8375 {
   8376    GLuint xy[2] = {v0, v1};
   8377    programUniform2uiv(program, location, 1, xy);
   8378 }
   8379 
   8380 void Context::programUniform3ui(ShaderProgramID program,
   8381                                UniformLocation location,
   8382                                GLuint v0,
   8383                                GLuint v1,
   8384                                GLuint v2)
   8385 {
   8386    GLuint xyz[3] = {v0, v1, v2};
   8387    programUniform3uiv(program, location, 1, xyz);
   8388 }
   8389 
   8390 void Context::programUniform4ui(ShaderProgramID program,
   8391                                UniformLocation location,
   8392                                GLuint v0,
   8393                                GLuint v1,
   8394                                GLuint v2,
   8395                                GLuint v3)
   8396 {
   8397    GLuint xyzw[4] = {v0, v1, v2, v3};
   8398    programUniform4uiv(program, location, 1, xyzw);
   8399 }
   8400 
   8401 void Context::programUniform1f(ShaderProgramID program, UniformLocation location, GLfloat v0)
   8402 {
   8403    programUniform1fv(program, location, 1, &v0);
   8404 }
   8405 
   8406 void Context::programUniform2f(ShaderProgramID program,
   8407                               UniformLocation location,
   8408                               GLfloat v0,
   8409                               GLfloat v1)
   8410 {
   8411    GLfloat xy[2] = {v0, v1};
   8412    programUniform2fv(program, location, 1, xy);
   8413 }
   8414 
   8415 void Context::programUniform3f(ShaderProgramID program,
   8416                               UniformLocation location,
   8417                               GLfloat v0,
   8418                               GLfloat v1,
   8419                               GLfloat v2)
   8420 {
   8421    GLfloat xyz[3] = {v0, v1, v2};
   8422    programUniform3fv(program, location, 1, xyz);
   8423 }
   8424 
   8425 void Context::programUniform4f(ShaderProgramID program,
   8426                               UniformLocation location,
   8427                               GLfloat v0,
   8428                               GLfloat v1,
   8429                               GLfloat v2,
   8430                               GLfloat v3)
   8431 {
   8432    GLfloat xyzw[4] = {v0, v1, v2, v3};
   8433    programUniform4fv(program, location, 1, xyzw);
   8434 }
   8435 
   8436 void Context::programUniform1iv(ShaderProgramID program,
   8437                                UniformLocation location,
   8438                                GLsizei count,
   8439                                const GLint *value)
   8440 {
   8441    Program *programObject = getProgramResolveLink(program);
   8442    ASSERT(programObject);
   8443    setUniform1iImpl(programObject, location, count, value);
   8444 }
   8445 
   8446 void Context::programUniform2iv(ShaderProgramID program,
   8447                                UniformLocation location,
   8448                                GLsizei count,
   8449                                const GLint *value)
   8450 {
   8451    Program *programObject = getProgramResolveLink(program);
   8452    ASSERT(programObject);
   8453    programObject->setUniform2iv(location, count, value);
   8454 }
   8455 
   8456 void Context::programUniform3iv(ShaderProgramID program,
   8457                                UniformLocation location,
   8458                                GLsizei count,
   8459                                const GLint *value)
   8460 {
   8461    Program *programObject = getProgramResolveLink(program);
   8462    ASSERT(programObject);
   8463    programObject->setUniform3iv(location, count, value);
   8464 }
   8465 
   8466 void Context::programUniform4iv(ShaderProgramID program,
   8467                                UniformLocation location,
   8468                                GLsizei count,
   8469                                const GLint *value)
   8470 {
   8471    Program *programObject = getProgramResolveLink(program);
   8472    ASSERT(programObject);
   8473    programObject->setUniform4iv(location, count, value);
   8474 }
   8475 
   8476 void Context::programUniform1uiv(ShaderProgramID program,
   8477                                 UniformLocation location,
   8478                                 GLsizei count,
   8479                                 const GLuint *value)
   8480 {
   8481    Program *programObject = getProgramResolveLink(program);
   8482    ASSERT(programObject);
   8483    programObject->setUniform1uiv(location, count, value);
   8484 }
   8485 
   8486 void Context::programUniform2uiv(ShaderProgramID program,
   8487                                 UniformLocation location,
   8488                                 GLsizei count,
   8489                                 const GLuint *value)
   8490 {
   8491    Program *programObject = getProgramResolveLink(program);
   8492    ASSERT(programObject);
   8493    programObject->setUniform2uiv(location, count, value);
   8494 }
   8495 
   8496 void Context::programUniform3uiv(ShaderProgramID program,
   8497                                 UniformLocation location,
   8498                                 GLsizei count,
   8499                                 const GLuint *value)
   8500 {
   8501    Program *programObject = getProgramResolveLink(program);
   8502    ASSERT(programObject);
   8503    programObject->setUniform3uiv(location, count, value);
   8504 }
   8505 
   8506 void Context::programUniform4uiv(ShaderProgramID program,
   8507                                 UniformLocation location,
   8508                                 GLsizei count,
   8509                                 const GLuint *value)
   8510 {
   8511    Program *programObject = getProgramResolveLink(program);
   8512    ASSERT(programObject);
   8513    programObject->setUniform4uiv(location, count, value);
   8514 }
   8515 
   8516 void Context::programUniform1fv(ShaderProgramID program,
   8517                                UniformLocation location,
   8518                                GLsizei count,
   8519                                const GLfloat *value)
   8520 {
   8521    Program *programObject = getProgramResolveLink(program);
   8522    ASSERT(programObject);
   8523    programObject->setUniform1fv(location, count, value);
   8524 }
   8525 
   8526 void Context::programUniform2fv(ShaderProgramID program,
   8527                                UniformLocation location,
   8528                                GLsizei count,
   8529                                const GLfloat *value)
   8530 {
   8531    Program *programObject = getProgramResolveLink(program);
   8532    ASSERT(programObject);
   8533    programObject->setUniform2fv(location, count, value);
   8534 }
   8535 
   8536 void Context::programUniform3fv(ShaderProgramID program,
   8537                                UniformLocation location,
   8538                                GLsizei count,
   8539                                const GLfloat *value)
   8540 {
   8541    Program *programObject = getProgramResolveLink(program);
   8542    ASSERT(programObject);
   8543    programObject->setUniform3fv(location, count, value);
   8544 }
   8545 
   8546 void Context::programUniform4fv(ShaderProgramID program,
   8547                                UniformLocation location,
   8548                                GLsizei count,
   8549                                const GLfloat *value)
   8550 {
   8551    Program *programObject = getProgramResolveLink(program);
   8552    ASSERT(programObject);
   8553    programObject->setUniform4fv(location, count, value);
   8554 }
   8555 
   8556 void Context::programUniformMatrix2fv(ShaderProgramID program,
   8557                                      UniformLocation location,
   8558                                      GLsizei count,
   8559                                      GLboolean transpose,
   8560                                      const GLfloat *value)
   8561 {
   8562    Program *programObject = getProgramResolveLink(program);
   8563    ASSERT(programObject);
   8564    programObject->setUniformMatrix2fv(location, count, transpose, value);
   8565 }
   8566 
   8567 void Context::programUniformMatrix3fv(ShaderProgramID program,
   8568                                      UniformLocation location,
   8569                                      GLsizei count,
   8570                                      GLboolean transpose,
   8571                                      const GLfloat *value)
   8572 {
   8573    Program *programObject = getProgramResolveLink(program);
   8574    ASSERT(programObject);
   8575    programObject->setUniformMatrix3fv(location, count, transpose, value);
   8576 }
   8577 
   8578 void Context::programUniformMatrix4fv(ShaderProgramID program,
   8579                                      UniformLocation location,
   8580                                      GLsizei count,
   8581                                      GLboolean transpose,
   8582                                      const GLfloat *value)
   8583 {
   8584    Program *programObject = getProgramResolveLink(program);
   8585    ASSERT(programObject);
   8586    programObject->setUniformMatrix4fv(location, count, transpose, value);
   8587 }
   8588 
   8589 void Context::programUniformMatrix2x3fv(ShaderProgramID program,
   8590                                        UniformLocation location,
   8591                                        GLsizei count,
   8592                                        GLboolean transpose,
   8593                                        const GLfloat *value)
   8594 {
   8595    Program *programObject = getProgramResolveLink(program);
   8596    ASSERT(programObject);
   8597    programObject->setUniformMatrix2x3fv(location, count, transpose, value);
   8598 }
   8599 
   8600 void Context::programUniformMatrix3x2fv(ShaderProgramID program,
   8601                                        UniformLocation location,
   8602                                        GLsizei count,
   8603                                        GLboolean transpose,
   8604                                        const GLfloat *value)
   8605 {
   8606    Program *programObject = getProgramResolveLink(program);
   8607    ASSERT(programObject);
   8608    programObject->setUniformMatrix3x2fv(location, count, transpose, value);
   8609 }
   8610 
   8611 void Context::programUniformMatrix2x4fv(ShaderProgramID program,
   8612                                        UniformLocation location,
   8613                                        GLsizei count,
   8614                                        GLboolean transpose,
   8615                                        const GLfloat *value)
   8616 {
   8617    Program *programObject = getProgramResolveLink(program);
   8618    ASSERT(programObject);
   8619    programObject->setUniformMatrix2x4fv(location, count, transpose, value);
   8620 }
   8621 
   8622 void Context::programUniformMatrix4x2fv(ShaderProgramID program,
   8623                                        UniformLocation location,
   8624                                        GLsizei count,
   8625                                        GLboolean transpose,
   8626                                        const GLfloat *value)
   8627 {
   8628    Program *programObject = getProgramResolveLink(program);
   8629    ASSERT(programObject);
   8630    programObject->setUniformMatrix4x2fv(location, count, transpose, value);
   8631 }
   8632 
   8633 void Context::programUniformMatrix3x4fv(ShaderProgramID program,
   8634                                        UniformLocation location,
   8635                                        GLsizei count,
   8636                                        GLboolean transpose,
   8637                                        const GLfloat *value)
   8638 {
   8639    Program *programObject = getProgramResolveLink(program);
   8640    ASSERT(programObject);
   8641    programObject->setUniformMatrix3x4fv(location, count, transpose, value);
   8642 }
   8643 
   8644 void Context::programUniformMatrix4x3fv(ShaderProgramID program,
   8645                                        UniformLocation location,
   8646                                        GLsizei count,
   8647                                        GLboolean transpose,
   8648                                        const GLfloat *value)
   8649 {
   8650    Program *programObject = getProgramResolveLink(program);
   8651    ASSERT(programObject);
   8652    programObject->setUniformMatrix4x3fv(location, count, transpose, value);
   8653 }
   8654 
   8655 bool Context::isCurrentTransformFeedback(const TransformFeedback *tf) const
   8656 {
   8657    return mState.isCurrentTransformFeedback(tf);
   8658 }
   8659 
   8660 void Context::genProgramPipelines(GLsizei count, ProgramPipelineID *pipelines)
   8661 {
   8662    for (int i = 0; i < count; i++)
   8663    {
   8664        pipelines[i] = createProgramPipeline();
   8665    }
   8666 }
   8667 
   8668 void Context::deleteProgramPipelines(GLsizei count, const ProgramPipelineID *pipelines)
   8669 {
   8670    for (int i = 0; i < count; i++)
   8671    {
   8672        if (pipelines[i].value != 0)
   8673        {
   8674            deleteProgramPipeline(pipelines[i]);
   8675        }
   8676    }
   8677 }
   8678 
   8679 GLboolean Context::isProgramPipeline(ProgramPipelineID pipeline) const
   8680 {
   8681    if (pipeline.value == 0)
   8682    {
   8683        return GL_FALSE;
   8684    }
   8685 
   8686    if (getProgramPipeline(pipeline))
   8687    {
   8688        return GL_TRUE;
   8689    }
   8690 
   8691    return GL_FALSE;
   8692 }
   8693 
   8694 void Context::finishFenceNV(FenceNVID fence)
   8695 {
   8696    FenceNV *fenceObject = getFenceNV(fence);
   8697 
   8698    ASSERT(fenceObject && fenceObject->isSet());
   8699    ANGLE_CONTEXT_TRY(fenceObject->finish(this));
   8700 }
   8701 
   8702 void Context::getFenceivNV(FenceNVID fence, GLenum pname, GLint *params)
   8703 {
   8704    FenceNV *fenceObject = getFenceNV(fence);
   8705 
   8706    ASSERT(fenceObject && fenceObject->isSet());
   8707 
   8708    switch (pname)
   8709    {
   8710        case GL_FENCE_STATUS_NV:
   8711        {
   8712            // GL_NV_fence spec:
   8713            // Once the status of a fence has been finished (via FinishFenceNV) or tested and
   8714            // the returned status is TRUE (via either TestFenceNV or GetFenceivNV querying the
   8715            // FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence.
   8716            GLboolean status = GL_TRUE;
   8717            if (fenceObject->getStatus() != GL_TRUE)
   8718            {
   8719                ANGLE_CONTEXT_TRY(fenceObject->test(this, &status));
   8720            }
   8721            *params = status;
   8722            break;
   8723        }
   8724 
   8725        case GL_FENCE_CONDITION_NV:
   8726        {
   8727            *params = static_cast<GLint>(fenceObject->getCondition());
   8728            break;
   8729        }
   8730 
   8731        default:
   8732            UNREACHABLE();
   8733    }
   8734 }
   8735 
   8736 void Context::getTranslatedShaderSource(ShaderProgramID shader,
   8737                                        GLsizei bufsize,
   8738                                        GLsizei *length,
   8739                                        GLchar *source)
   8740 {
   8741    Shader *shaderObject = getShader(shader);
   8742    ASSERT(shaderObject);
   8743    shaderObject->getTranslatedSourceWithDebugInfo(this, bufsize, length, source);
   8744 }
   8745 
   8746 void Context::getnUniformfv(ShaderProgramID program,
   8747                            UniformLocation location,
   8748                            GLsizei bufSize,
   8749                            GLfloat *params)
   8750 {
   8751    Program *programObject = getProgramResolveLink(program);
   8752    ASSERT(programObject);
   8753 
   8754    programObject->getUniformfv(this, location, params);
   8755 }
   8756 
   8757 void Context::getnUniformfvRobust(ShaderProgramID program,
   8758                                  UniformLocation location,
   8759                                  GLsizei bufSize,
   8760                                  GLsizei *length,
   8761                                  GLfloat *params)
   8762 {
   8763    UNIMPLEMENTED();
   8764 }
   8765 
   8766 void Context::getnUniformiv(ShaderProgramID program,
   8767                            UniformLocation location,
   8768                            GLsizei bufSize,
   8769                            GLint *params)
   8770 {
   8771    Program *programObject = getProgramResolveLink(program);
   8772    ASSERT(programObject);
   8773 
   8774    programObject->getUniformiv(this, location, params);
   8775 }
   8776 
   8777 void Context::getnUniformuiv(ShaderProgramID program,
   8778                             UniformLocation location,
   8779                             GLsizei bufSize,
   8780                             GLuint *params)
   8781 {
   8782    Program *programObject = getProgramResolveLink(program);
   8783    ASSERT(programObject);
   8784 
   8785    programObject->getUniformuiv(this, location, params);
   8786 }
   8787 
   8788 void Context::getnUniformivRobust(ShaderProgramID program,
   8789                                  UniformLocation location,
   8790                                  GLsizei bufSize,
   8791                                  GLsizei *length,
   8792                                  GLint *params)
   8793 {
   8794    UNIMPLEMENTED();
   8795 }
   8796 
   8797 void Context::getnUniformuivRobust(ShaderProgramID program,
   8798                                   UniformLocation location,
   8799                                   GLsizei bufSize,
   8800                                   GLsizei *length,
   8801                                   GLuint *params)
   8802 {
   8803    UNIMPLEMENTED();
   8804 }
   8805 
   8806 GLboolean Context::isFenceNV(FenceNVID fence) const
   8807 {
   8808    FenceNV *fenceObject = getFenceNV(fence);
   8809 
   8810    if (fenceObject == nullptr)
   8811    {
   8812        return GL_FALSE;
   8813    }
   8814 
   8815    // GL_NV_fence spec:
   8816    // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an
   8817    // existing fence.
   8818    return fenceObject->isSet();
   8819 }
   8820 
   8821 void Context::readnPixels(GLint x,
   8822                          GLint y,
   8823                          GLsizei width,
   8824                          GLsizei height,
   8825                          GLenum format,
   8826                          GLenum type,
   8827                          GLsizei bufSize,
   8828                          void *data)
   8829 {
   8830    return readPixels(x, y, width, height, format, type, data);
   8831 }
   8832 
   8833 void Context::setFenceNV(FenceNVID fence, GLenum condition)
   8834 {
   8835    ASSERT(condition == GL_ALL_COMPLETED_NV);
   8836 
   8837    FenceNV *fenceObject = getFenceNV(fence);
   8838    ASSERT(fenceObject != nullptr);
   8839    ANGLE_CONTEXT_TRY(fenceObject->set(this, condition));
   8840 }
   8841 
   8842 GLboolean Context::testFenceNV(FenceNVID fence)
   8843 {
   8844    FenceNV *fenceObject = getFenceNV(fence);
   8845 
   8846    ASSERT(fenceObject != nullptr);
   8847    ASSERT(fenceObject->isSet() == GL_TRUE);
   8848 
   8849    GLboolean result = GL_TRUE;
   8850    if (fenceObject->test(this, &result) == angle::Result::Stop)
   8851    {
   8852        return GL_TRUE;
   8853    }
   8854 
   8855    return result;
   8856 }
   8857 
   8858 void Context::deleteMemoryObjects(GLsizei n, const MemoryObjectID *memoryObjects)
   8859 {
   8860    for (int i = 0; i < n; i++)
   8861    {
   8862        deleteMemoryObject(memoryObjects[i]);
   8863    }
   8864 }
   8865 
   8866 GLboolean Context::isMemoryObject(MemoryObjectID memoryObject) const
   8867 {
   8868    if (memoryObject.value == 0)
   8869    {
   8870        return GL_FALSE;
   8871    }
   8872 
   8873    return ConvertToGLBoolean(getMemoryObject(memoryObject));
   8874 }
   8875 
   8876 void Context::createMemoryObjects(GLsizei n, MemoryObjectID *memoryObjects)
   8877 {
   8878    for (int i = 0; i < n; i++)
   8879    {
   8880        memoryObjects[i] = createMemoryObject();
   8881    }
   8882 }
   8883 
   8884 void Context::memoryObjectParameteriv(MemoryObjectID memory, GLenum pname, const GLint *params)
   8885 {
   8886    MemoryObject *memoryObject = getMemoryObject(memory);
   8887    ASSERT(memoryObject);
   8888    ANGLE_CONTEXT_TRY(SetMemoryObjectParameteriv(this, memoryObject, pname, params));
   8889 }
   8890 
   8891 void Context::getMemoryObjectParameteriv(MemoryObjectID memory, GLenum pname, GLint *params)
   8892 {
   8893    const MemoryObject *memoryObject = getMemoryObject(memory);
   8894    ASSERT(memoryObject);
   8895    QueryMemoryObjectParameteriv(memoryObject, pname, params);
   8896 }
   8897 
   8898 void Context::texStorageMem2D(TextureType target,
   8899                              GLsizei levels,
   8900                              GLenum internalFormat,
   8901                              GLsizei width,
   8902                              GLsizei height,
   8903                              MemoryObjectID memory,
   8904                              GLuint64 offset)
   8905 {
   8906    texStorageMemFlags2D(target, levels, internalFormat, width, height, memory, offset, 0,
   8907                         std::numeric_limits<uint32_t>::max(), nullptr);
   8908 }
   8909 
   8910 void Context::texStorageMem2DMultisample(TextureType target,
   8911                                         GLsizei samples,
   8912                                         GLenum internalFormat,
   8913                                         GLsizei width,
   8914                                         GLsizei height,
   8915                                         GLboolean fixedSampleLocations,
   8916                                         MemoryObjectID memory,
   8917                                         GLuint64 offset)
   8918 {
   8919    UNIMPLEMENTED();
   8920 }
   8921 
   8922 void Context::texStorageMem3D(TextureType target,
   8923                              GLsizei levels,
   8924                              GLenum internalFormat,
   8925                              GLsizei width,
   8926                              GLsizei height,
   8927                              GLsizei depth,
   8928                              MemoryObjectID memory,
   8929                              GLuint64 offset)
   8930 {
   8931    UNIMPLEMENTED();
   8932 }
   8933 
   8934 void Context::texStorageMem3DMultisample(TextureType target,
   8935                                         GLsizei samples,
   8936                                         GLenum internalFormat,
   8937                                         GLsizei width,
   8938                                         GLsizei height,
   8939                                         GLsizei depth,
   8940                                         GLboolean fixedSampleLocations,
   8941                                         MemoryObjectID memory,
   8942                                         GLuint64 offset)
   8943 {
   8944    UNIMPLEMENTED();
   8945 }
   8946 
   8947 void Context::bufferStorageMem(TextureType target,
   8948                               GLsizeiptr size,
   8949                               MemoryObjectID memory,
   8950                               GLuint64 offset)
   8951 {
   8952    UNIMPLEMENTED();
   8953 }
   8954 
   8955 void Context::importMemoryFd(MemoryObjectID memory, GLuint64 size, HandleType handleType, GLint fd)
   8956 {
   8957    MemoryObject *memoryObject = getMemoryObject(memory);
   8958    ASSERT(memoryObject != nullptr);
   8959    ANGLE_CONTEXT_TRY(memoryObject->importFd(this, size, handleType, fd));
   8960 }
   8961 
   8962 void Context::texStorageMemFlags2D(TextureType target,
   8963                                   GLsizei levels,
   8964                                   GLenum internalFormat,
   8965                                   GLsizei width,
   8966                                   GLsizei height,
   8967                                   MemoryObjectID memory,
   8968                                   GLuint64 offset,
   8969                                   GLbitfield createFlags,
   8970                                   GLbitfield usageFlags,
   8971                                   const void *imageCreateInfoPNext)
   8972 {
   8973    MemoryObject *memoryObject = getMemoryObject(memory);
   8974    ASSERT(memoryObject);
   8975    Extents size(width, height, 1);
   8976    Texture *texture = getTextureByType(target);
   8977    ANGLE_CONTEXT_TRY(texture->setStorageExternalMemory(this, target, levels, internalFormat, size,
   8978                                                        memoryObject, offset, createFlags,
   8979                                                        usageFlags, imageCreateInfoPNext));
   8980 }
   8981 
   8982 void Context::texStorageMemFlags2DMultisample(TextureType target,
   8983                                              GLsizei samples,
   8984                                              GLenum internalFormat,
   8985                                              GLsizei width,
   8986                                              GLsizei height,
   8987                                              GLboolean fixedSampleLocations,
   8988                                              MemoryObjectID memory,
   8989                                              GLuint64 offset,
   8990                                              GLbitfield createFlags,
   8991                                              GLbitfield usageFlags,
   8992                                              const void *imageCreateInfoPNext)
   8993 {
   8994    UNIMPLEMENTED();
   8995 }
   8996 
   8997 void Context::texStorageMemFlags3D(TextureType target,
   8998                                   GLsizei levels,
   8999                                   GLenum internalFormat,
   9000                                   GLsizei width,
   9001                                   GLsizei height,
   9002                                   GLsizei depth,
   9003                                   MemoryObjectID memory,
   9004                                   GLuint64 offset,
   9005                                   GLbitfield createFlags,
   9006                                   GLbitfield usageFlags,
   9007                                   const void *imageCreateInfoPNext)
   9008 {
   9009    UNIMPLEMENTED();
   9010 }
   9011 
   9012 void Context::texStorageMemFlags3DMultisample(TextureType target,
   9013                                              GLsizei samples,
   9014                                              GLenum internalFormat,
   9015                                              GLsizei width,
   9016                                              GLsizei height,
   9017                                              GLsizei depth,
   9018                                              GLboolean fixedSampleLocations,
   9019                                              MemoryObjectID memory,
   9020                                              GLuint64 offset,
   9021                                              GLbitfield createFlags,
   9022                                              GLbitfield usageFlags,
   9023                                              const void *imageCreateInfoPNext)
   9024 {
   9025    UNIMPLEMENTED();
   9026 }
   9027 
   9028 void Context::importMemoryZirconHandle(MemoryObjectID memory,
   9029                                       GLuint64 size,
   9030                                       HandleType handleType,
   9031                                       GLuint handle)
   9032 {
   9033    MemoryObject *memoryObject = getMemoryObject(memory);
   9034    ASSERT(memoryObject != nullptr);
   9035    ANGLE_CONTEXT_TRY(memoryObject->importZirconHandle(this, size, handleType, handle));
   9036 }
   9037 
   9038 void Context::genSemaphores(GLsizei n, SemaphoreID *semaphores)
   9039 {
   9040    for (int i = 0; i < n; i++)
   9041    {
   9042        semaphores[i] = createSemaphore();
   9043    }
   9044 }
   9045 
   9046 void Context::deleteSemaphores(GLsizei n, const SemaphoreID *semaphores)
   9047 {
   9048    for (int i = 0; i < n; i++)
   9049    {
   9050        deleteSemaphore(semaphores[i]);
   9051    }
   9052 }
   9053 
   9054 GLboolean Context::isSemaphore(SemaphoreID semaphore) const
   9055 {
   9056    if (semaphore.value == 0)
   9057    {
   9058        return GL_FALSE;
   9059    }
   9060 
   9061    return ConvertToGLBoolean(getSemaphore(semaphore));
   9062 }
   9063 
   9064 void Context::semaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, const GLuint64 *params)
   9065 {
   9066    UNIMPLEMENTED();
   9067 }
   9068 
   9069 void Context::getSemaphoreParameterui64v(SemaphoreID semaphore, GLenum pname, GLuint64 *params)
   9070 {
   9071    UNIMPLEMENTED();
   9072 }
   9073 
   9074 void Context::acquireTextures(GLuint numTextures,
   9075                              const TextureID *textureIds,
   9076                              const GLenum *layouts)
   9077 {
   9078    TextureBarrierVector textureBarriers(numTextures);
   9079    for (size_t i = 0; i < numTextures; i++)
   9080    {
   9081        textureBarriers[i].texture = getTexture(textureIds[i]);
   9082        textureBarriers[i].layout  = layouts[i];
   9083    }
   9084    ANGLE_CONTEXT_TRY(mImplementation->acquireTextures(this, textureBarriers));
   9085 }
   9086 
   9087 void Context::releaseTextures(GLuint numTextures, const TextureID *textureIds, GLenum *layouts)
   9088 {
   9089    TextureBarrierVector textureBarriers(numTextures);
   9090    for (size_t i = 0; i < numTextures; i++)
   9091    {
   9092        textureBarriers[i].texture = getTexture(textureIds[i]);
   9093    }
   9094    ANGLE_CONTEXT_TRY(mImplementation->releaseTextures(this, &textureBarriers));
   9095    for (size_t i = 0; i < numTextures; i++)
   9096    {
   9097        layouts[i] = textureBarriers[i].layout;
   9098    }
   9099 }
   9100 
   9101 void Context::waitSemaphore(SemaphoreID semaphoreHandle,
   9102                            GLuint numBufferBarriers,
   9103                            const BufferID *buffers,
   9104                            GLuint numTextureBarriers,
   9105                            const TextureID *textures,
   9106                            const GLenum *srcLayouts)
   9107 {
   9108    Semaphore *semaphore = getSemaphore(semaphoreHandle);
   9109    ASSERT(semaphore);
   9110 
   9111    BufferBarrierVector bufferBarriers(numBufferBarriers);
   9112    for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
   9113    {
   9114        bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
   9115    }
   9116 
   9117    TextureBarrierVector textureBarriers(numTextureBarriers);
   9118    for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
   9119    {
   9120        textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
   9121        textureBarriers[textureBarrierIdx].layout  = srcLayouts[textureBarrierIdx];
   9122    }
   9123 
   9124    ANGLE_CONTEXT_TRY(semaphore->wait(this, bufferBarriers, textureBarriers));
   9125 }
   9126 
   9127 void Context::signalSemaphore(SemaphoreID semaphoreHandle,
   9128                              GLuint numBufferBarriers,
   9129                              const BufferID *buffers,
   9130                              GLuint numTextureBarriers,
   9131                              const TextureID *textures,
   9132                              const GLenum *dstLayouts)
   9133 {
   9134    Semaphore *semaphore = getSemaphore(semaphoreHandle);
   9135    ASSERT(semaphore);
   9136 
   9137    BufferBarrierVector bufferBarriers(numBufferBarriers);
   9138    for (GLuint bufferBarrierIdx = 0; bufferBarrierIdx < numBufferBarriers; bufferBarrierIdx++)
   9139    {
   9140        bufferBarriers[bufferBarrierIdx] = getBuffer(buffers[bufferBarrierIdx]);
   9141    }
   9142 
   9143    TextureBarrierVector textureBarriers(numTextureBarriers);
   9144    for (GLuint textureBarrierIdx = 0; textureBarrierIdx < numTextureBarriers; textureBarrierIdx++)
   9145    {
   9146        textureBarriers[textureBarrierIdx].texture = getTexture(textures[textureBarrierIdx]);
   9147        textureBarriers[textureBarrierIdx].layout  = dstLayouts[textureBarrierIdx];
   9148    }
   9149 
   9150    ANGLE_CONTEXT_TRY(semaphore->signal(this, bufferBarriers, textureBarriers));
   9151 }
   9152 
   9153 void Context::importSemaphoreFd(SemaphoreID semaphore, HandleType handleType, GLint fd)
   9154 {
   9155    Semaphore *semaphoreObject = getSemaphore(semaphore);
   9156    ASSERT(semaphoreObject != nullptr);
   9157    ANGLE_CONTEXT_TRY(semaphoreObject->importFd(this, handleType, fd));
   9158 }
   9159 
   9160 void Context::importSemaphoreZirconHandle(SemaphoreID semaphore,
   9161                                          HandleType handleType,
   9162                                          GLuint handle)
   9163 {
   9164    Semaphore *semaphoreObject = getSemaphore(semaphore);
   9165    ASSERT(semaphoreObject != nullptr);
   9166    ANGLE_CONTEXT_TRY(semaphoreObject->importZirconHandle(this, handleType, handle));
   9167 }
   9168 
   9169 void Context::framebufferMemorylessPixelLocalStorage(GLint plane, GLenum internalformat)
   9170 {
   9171    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   9172    ASSERT(framebuffer);
   9173    PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
   9174 
   9175    if (internalformat == GL_NONE)
   9176    {
   9177        pls.deinitialize(this, plane);
   9178    }
   9179    else
   9180    {
   9181        pls.setMemoryless(this, plane, internalformat);
   9182    }
   9183 }
   9184 
   9185 void Context::framebufferTexturePixelLocalStorage(GLint plane,
   9186                                                  TextureID backingtexture,
   9187                                                  GLint level,
   9188                                                  GLint layer)
   9189 {
   9190    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   9191    ASSERT(framebuffer);
   9192    PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
   9193 
   9194    if (backingtexture.value == 0)
   9195    {
   9196        pls.deinitialize(this, plane);
   9197    }
   9198    else
   9199    {
   9200        Texture *tex = getTexture(backingtexture);
   9201        ASSERT(tex);  // Validation guarantees this.
   9202        pls.setTextureBacked(this, plane, tex, level, layer);
   9203    }
   9204 }
   9205 
   9206 void Context::beginPixelLocalStorage(GLsizei planes, const GLenum loadops[], const void *cleardata)
   9207 {
   9208    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   9209    ASSERT(framebuffer);
   9210    PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
   9211 
   9212    pls.begin(this, planes, loadops, cleardata);
   9213    mState.setPixelLocalStorageActive(true);
   9214 }
   9215 
   9216 void Context::endPixelLocalStorage()
   9217 {
   9218    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   9219    ASSERT(framebuffer);
   9220    PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
   9221 
   9222    pls.end(this);
   9223    mState.setPixelLocalStorageActive(false);
   9224 }
   9225 
   9226 void Context::pixelLocalStorageBarrier()
   9227 {
   9228    if (getExtensions().shaderPixelLocalStorageCoherentANGLE)
   9229    {
   9230        return;
   9231    }
   9232 
   9233    Framebuffer *framebuffer = mState.getDrawFramebuffer();
   9234    ASSERT(framebuffer);
   9235    PixelLocalStorage &pls = framebuffer->getPixelLocalStorage(this);
   9236 
   9237    pls.barrier(this);
   9238 }
   9239 
   9240 void Context::eGLImageTargetTexStorage(GLenum target, GLeglImageOES image, const GLint *attrib_list)
   9241 {
   9242    Texture *texture        = getTextureByType(FromGLenum<TextureType>(target));
   9243    egl::Image *imageObject = static_cast<egl::Image *>(image);
   9244    ANGLE_CONTEXT_TRY(texture->setStorageEGLImageTarget(this, FromGLenum<TextureType>(target),
   9245                                                        imageObject, attrib_list));
   9246 }
   9247 
   9248 void Context::eGLImageTargetTextureStorage(GLuint texture,
   9249                                           GLeglImageOES image,
   9250                                           const GLint *attrib_list)
   9251 {
   9252    return;
   9253 }
   9254 
   9255 void Context::eGLImageTargetTexture2D(TextureType target, GLeglImageOES image)
   9256 {
   9257    Texture *texture        = getTextureByType(target);
   9258    egl::Image *imageObject = static_cast<egl::Image *>(image);
   9259    ANGLE_CONTEXT_TRY(texture->setEGLImageTarget(this, target, imageObject));
   9260 }
   9261 
   9262 void Context::eGLImageTargetRenderbufferStorage(GLenum target, GLeglImageOES image)
   9263 {
   9264    Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
   9265    egl::Image *imageObject    = static_cast<egl::Image *>(image);
   9266    ANGLE_CONTEXT_TRY(renderbuffer->setStorageEGLImageTarget(this, imageObject));
   9267 }
   9268 
   9269 void Context::framebufferFetchBarrier()
   9270 {
   9271    mImplementation->framebufferFetchBarrier();
   9272 }
   9273 
   9274 void Context::texStorage1D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width)
   9275 {
   9276    UNIMPLEMENTED();
   9277 }
   9278 
   9279 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
   9280 {
   9281    return GetQueryParameterInfo(mState, pname, type, numParams);
   9282 }
   9283 
   9284 bool Context::getIndexedQueryParameterInfo(GLenum target,
   9285                                           GLenum *type,
   9286                                           unsigned int *numParams) const
   9287 {
   9288    if (getClientVersion() < Version(3, 0))
   9289    {
   9290        return false;
   9291    }
   9292 
   9293    switch (target)
   9294    {
   9295        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   9296        case GL_UNIFORM_BUFFER_BINDING:
   9297        {
   9298            *type      = GL_INT;
   9299            *numParams = 1;
   9300            return true;
   9301        }
   9302        case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   9303        case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   9304        case GL_UNIFORM_BUFFER_START:
   9305        case GL_UNIFORM_BUFFER_SIZE:
   9306        {
   9307            *type      = GL_INT_64_ANGLEX;
   9308            *numParams = 1;
   9309            return true;
   9310        }
   9311    }
   9312 
   9313    if (mSupportedExtensions.drawBuffersIndexedAny())
   9314    {
   9315        switch (target)
   9316        {
   9317            case GL_BLEND_SRC_RGB:
   9318            case GL_BLEND_SRC_ALPHA:
   9319            case GL_BLEND_DST_RGB:
   9320            case GL_BLEND_DST_ALPHA:
   9321            case GL_BLEND_EQUATION_RGB:
   9322            case GL_BLEND_EQUATION_ALPHA:
   9323            {
   9324                *type      = GL_INT;
   9325                *numParams = 1;
   9326                return true;
   9327            }
   9328            case GL_COLOR_WRITEMASK:
   9329            {
   9330                *type      = GL_BOOL;
   9331                *numParams = 4;
   9332                return true;
   9333            }
   9334        }
   9335    }
   9336 
   9337    if (mSupportedExtensions.shaderPixelLocalStorageANGLE)
   9338    {
   9339        switch (target)
   9340        {
   9341            case GL_PIXEL_LOCAL_FORMAT_ANGLE:
   9342            case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
   9343            case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
   9344            case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
   9345                *type      = GL_INT;
   9346                *numParams = 1;
   9347                return true;
   9348        }
   9349    }
   9350 
   9351    if (getClientVersion() < Version(3, 1))
   9352    {
   9353        return false;
   9354    }
   9355 
   9356    switch (target)
   9357    {
   9358        case GL_IMAGE_BINDING_LAYERED:
   9359        {
   9360            *type      = GL_BOOL;
   9361            *numParams = 1;
   9362            return true;
   9363        }
   9364        case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
   9365        case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
   9366        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
   9367        case GL_SHADER_STORAGE_BUFFER_BINDING:
   9368        case GL_VERTEX_BINDING_BUFFER:
   9369        case GL_VERTEX_BINDING_DIVISOR:
   9370        case GL_VERTEX_BINDING_OFFSET:
   9371        case GL_VERTEX_BINDING_STRIDE:
   9372        case GL_SAMPLE_MASK_VALUE:
   9373        case GL_IMAGE_BINDING_NAME:
   9374        case GL_IMAGE_BINDING_LEVEL:
   9375        case GL_IMAGE_BINDING_LAYER:
   9376        case GL_IMAGE_BINDING_ACCESS:
   9377        case GL_IMAGE_BINDING_FORMAT:
   9378        {
   9379            *type      = GL_INT;
   9380            *numParams = 1;
   9381            return true;
   9382        }
   9383        case GL_ATOMIC_COUNTER_BUFFER_START:
   9384        case GL_ATOMIC_COUNTER_BUFFER_SIZE:
   9385        case GL_SHADER_STORAGE_BUFFER_START:
   9386        case GL_SHADER_STORAGE_BUFFER_SIZE:
   9387        {
   9388            *type      = GL_INT_64_ANGLEX;
   9389            *numParams = 1;
   9390            return true;
   9391        }
   9392    }
   9393 
   9394    return false;
   9395 }
   9396 
   9397 Program *Context::getProgramNoResolveLink(ShaderProgramID handle) const
   9398 {
   9399    return mState.mShaderProgramManager->getProgram(handle);
   9400 }
   9401 
   9402 Shader *Context::getShader(ShaderProgramID handle) const
   9403 {
   9404    return mState.mShaderProgramManager->getShader(handle);
   9405 }
   9406 
   9407 const angle::FrontendFeatures &Context::getFrontendFeatures() const
   9408 {
   9409    return mDisplay->getFrontendFeatures();
   9410 }
   9411 
   9412 bool Context::isRenderbufferGenerated(RenderbufferID renderbuffer) const
   9413 {
   9414    return mState.mRenderbufferManager->isHandleGenerated(renderbuffer);
   9415 }
   9416 
   9417 bool Context::isFramebufferGenerated(FramebufferID framebuffer) const
   9418 {
   9419    return mState.mFramebufferManager->isHandleGenerated(framebuffer);
   9420 }
   9421 
   9422 bool Context::isProgramPipelineGenerated(ProgramPipelineID pipeline) const
   9423 {
   9424    return mState.mProgramPipelineManager->isHandleGenerated(pipeline);
   9425 }
   9426 
   9427 bool Context::usingDisplayTextureShareGroup() const
   9428 {
   9429    return mDisplayTextureShareGroup;
   9430 }
   9431 
   9432 bool Context::usingDisplaySemaphoreShareGroup() const
   9433 {
   9434    return mDisplaySemaphoreShareGroup;
   9435 }
   9436 
   9437 GLenum Context::getConvertedRenderbufferFormat(GLenum internalformat) const
   9438 {
   9439    if (isWebGL() && mState.mClientVersion.major == 2 && internalformat == GL_DEPTH_STENCIL)
   9440    {
   9441        return GL_DEPTH24_STENCIL8;
   9442    }
   9443    if (getClientType() == EGL_OPENGL_API && internalformat == GL_DEPTH_COMPONENT)
   9444    {
   9445        return GL_DEPTH_COMPONENT24;
   9446    }
   9447    return internalformat;
   9448 }
   9449 
   9450 void Context::maxShaderCompilerThreads(GLuint count)
   9451 {
   9452    GLuint oldCount = mState.getMaxShaderCompilerThreads();
   9453    mState.setMaxShaderCompilerThreads(count);
   9454    // A count of zero specifies a request for no parallel compiling or linking.
   9455    if ((oldCount == 0 || count == 0) && (oldCount != 0 || count != 0))
   9456    {
   9457        mMultiThreadPool = angle::WorkerThreadPool::Create(count > 0);
   9458    }
   9459    mMultiThreadPool->setMaxThreads(count);
   9460    mImplementation->setMaxShaderCompilerThreads(count);
   9461 }
   9462 
   9463 void Context::framebufferParameteriMESA(GLenum target, GLenum pname, GLint param)
   9464 {
   9465    framebufferParameteri(target, pname, param);
   9466 }
   9467 
   9468 void Context::getFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params)
   9469 {
   9470    getFramebufferParameteriv(target, pname, params);
   9471 }
   9472 
   9473 bool Context::isGLES1() const
   9474 {
   9475    return mState.isGLES1();
   9476 }
   9477 
   9478 void Context::onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message)
   9479 {
   9480    switch (index)
   9481    {
   9482        case kVertexArraySubjectIndex:
   9483            switch (message)
   9484            {
   9485                case angle::SubjectMessage::ContentsChanged:
   9486                    mState.setObjectDirty(GL_VERTEX_ARRAY);
   9487                    mStateCache.onVertexArrayBufferContentsChange(this);
   9488                    break;
   9489                case angle::SubjectMessage::SubjectMapped:
   9490                case angle::SubjectMessage::SubjectUnmapped:
   9491                case angle::SubjectMessage::BindingChanged:
   9492                    mStateCache.onVertexArrayBufferStateChange(this);
   9493                    break;
   9494                default:
   9495                    break;
   9496            }
   9497            break;
   9498 
   9499        case kReadFramebufferSubjectIndex:
   9500            switch (message)
   9501            {
   9502                case angle::SubjectMessage::DirtyBitsFlagged:
   9503                    mState.setReadFramebufferDirty();
   9504                    break;
   9505                case angle::SubjectMessage::SurfaceChanged:
   9506                    mState.setReadFramebufferBindingDirty();
   9507                    break;
   9508                default:
   9509                    UNREACHABLE();
   9510                    break;
   9511            }
   9512            break;
   9513 
   9514        case kDrawFramebufferSubjectIndex:
   9515            switch (message)
   9516            {
   9517                case angle::SubjectMessage::DirtyBitsFlagged:
   9518                    mState.setDrawFramebufferDirty();
   9519                    mStateCache.onDrawFramebufferChange(this);
   9520                    break;
   9521                case angle::SubjectMessage::SurfaceChanged:
   9522                    mState.setDrawFramebufferBindingDirty();
   9523                    break;
   9524                default:
   9525                    UNREACHABLE();
   9526                    break;
   9527            }
   9528            break;
   9529 
   9530        case kProgramPipelineSubjectIndex:
   9531            switch (message)
   9532            {
   9533                case angle::SubjectMessage::SubjectChanged:
   9534                    ANGLE_CONTEXT_TRY(mState.onProgramPipelineExecutableChange(this));
   9535                    mStateCache.onProgramExecutableChange(this);
   9536                    break;
   9537                case angle::SubjectMessage::ProgramRelinked:
   9538                    ANGLE_CONTEXT_TRY(mState.mProgramPipeline->link(this));
   9539                    break;
   9540                default:
   9541                    UNREACHABLE();
   9542                    break;
   9543            }
   9544            break;
   9545 
   9546        default:
   9547            if (index < kTextureMaxSubjectIndex)
   9548            {
   9549                if (message != angle::SubjectMessage::ContentsChanged &&
   9550                    message != angle::SubjectMessage::BindingChanged)
   9551                {
   9552                    mState.onActiveTextureStateChange(this, index);
   9553                    mStateCache.onActiveTextureChange(this);
   9554                }
   9555            }
   9556            else if (index < kImageMaxSubjectIndex)
   9557            {
   9558                mState.onImageStateChange(this, index - kImage0SubjectIndex);
   9559                if (message == angle::SubjectMessage::ContentsChanged)
   9560                {
   9561                    mState.mDirtyBits.set(State::DirtyBitType::DIRTY_BIT_IMAGE_BINDINGS);
   9562                }
   9563            }
   9564            else if (index < kUniformBufferMaxSubjectIndex)
   9565            {
   9566                mState.onUniformBufferStateChange(index - kUniformBuffer0SubjectIndex);
   9567                mStateCache.onUniformBufferStateChange(this);
   9568            }
   9569            else if (index < kAtomicCounterBufferMaxSubjectIndex)
   9570            {
   9571                mState.onAtomicCounterBufferStateChange(index - kAtomicCounterBuffer0SubjectIndex);
   9572                mStateCache.onAtomicCounterBufferStateChange(this);
   9573            }
   9574            else if (index < kShaderStorageBufferMaxSubjectIndex)
   9575            {
   9576                mState.onShaderStorageBufferStateChange(index - kShaderStorageBuffer0SubjectIndex);
   9577                mStateCache.onShaderStorageBufferStateChange(this);
   9578            }
   9579            else
   9580            {
   9581                ASSERT(index < kSamplerMaxSubjectIndex);
   9582                mState.setSamplerDirty(index - kSampler0SubjectIndex);
   9583                mState.onActiveTextureStateChange(this, index - kSampler0SubjectIndex);
   9584            }
   9585            break;
   9586    }
   9587 }
   9588 
   9589 angle::Result Context::onProgramLink(Program *programObject)
   9590 {
   9591    // Don't parallel link a program which is active in any GL contexts. With this assumption, we
   9592    // don't need to worry that:
   9593    //   1. Draw calls after link use the new executable code or the old one depending on the link
   9594    //      result.
   9595    //   2. When a backend program, e.g., ProgramD3D is linking, other backend classes like
   9596    //      StateManager11, Renderer11, etc., may have a chance to make unexpected calls to
   9597    //      ProgramD3D.
   9598    if (programObject->isInUse())
   9599    {
   9600        programObject->resolveLink(this);
   9601        if (programObject->isLinked())
   9602        {
   9603            ANGLE_TRY(mState.onProgramExecutableChange(this, programObject));
   9604            programObject->onStateChange(angle::SubjectMessage::ProgramRelinked);
   9605        }
   9606        mStateCache.onProgramExecutableChange(this);
   9607    }
   9608 
   9609    return angle::Result::Continue;
   9610 }
   9611 
   9612 egl::Error Context::setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface)
   9613 {
   9614    ASSERT(mCurrentDrawSurface == nullptr);
   9615    ASSERT(mCurrentReadSurface == nullptr);
   9616 
   9617    mCurrentDrawSurface = drawSurface;
   9618    mCurrentReadSurface = readSurface;
   9619 
   9620    if (drawSurface != nullptr)
   9621    {
   9622        ANGLE_TRY(drawSurface->makeCurrent(this));
   9623    }
   9624 
   9625    ANGLE_TRY(mDefaultFramebuffer->setSurfaces(this, drawSurface, readSurface));
   9626 
   9627    if (readSurface && (drawSurface != readSurface))
   9628    {
   9629        ANGLE_TRY(readSurface->makeCurrent(this));
   9630    }
   9631 
   9632    // Update default framebuffer, the binding of the previous default
   9633    // framebuffer (or lack of) will have a nullptr.
   9634    mState.mFramebufferManager->setDefaultFramebuffer(mDefaultFramebuffer.get());
   9635    if (mState.getDrawFramebuffer() == nullptr)
   9636    {
   9637        bindDrawFramebuffer(mDefaultFramebuffer->id());
   9638    }
   9639    if (mState.getReadFramebuffer() == nullptr)
   9640    {
   9641        bindReadFramebuffer(mDefaultFramebuffer->id());
   9642    }
   9643 
   9644    return egl::NoError();
   9645 }
   9646 
   9647 egl::Error Context::unsetDefaultFramebuffer()
   9648 {
   9649    Framebuffer *defaultFramebuffer =
   9650        mState.mFramebufferManager->getFramebuffer(Framebuffer::kDefaultDrawFramebufferHandle);
   9651 
   9652    if (defaultFramebuffer)
   9653    {
   9654        // Remove the default framebuffer
   9655        if (defaultFramebuffer == mState.getReadFramebuffer())
   9656        {
   9657            mState.setReadFramebufferBinding(nullptr);
   9658            mReadFramebufferObserverBinding.bind(nullptr);
   9659        }
   9660 
   9661        if (defaultFramebuffer == mState.getDrawFramebuffer())
   9662        {
   9663            mState.setDrawFramebufferBinding(nullptr);
   9664            mDrawFramebufferObserverBinding.bind(nullptr);
   9665        }
   9666 
   9667        ANGLE_TRY(defaultFramebuffer->unsetSurfaces(this));
   9668        mState.mFramebufferManager->setDefaultFramebuffer(nullptr);
   9669    }
   9670 
   9671    // Always unset the current surface, even if setIsCurrent fails.
   9672    egl::Surface *drawSurface = mCurrentDrawSurface;
   9673    egl::Surface *readSurface = mCurrentReadSurface;
   9674    mCurrentDrawSurface       = nullptr;
   9675    mCurrentReadSurface       = nullptr;
   9676    if (drawSurface)
   9677    {
   9678        ANGLE_TRY(drawSurface->unMakeCurrent(this));
   9679    }
   9680    if (drawSurface != readSurface)
   9681    {
   9682        ANGLE_TRY(readSurface->unMakeCurrent(this));
   9683    }
   9684 
   9685    return egl::NoError();
   9686 }
   9687 
   9688 void Context::onPreSwap() const
   9689 {
   9690    // Dump frame capture if enabled.
   9691    getShareGroup()->getFrameCaptureShared()->onEndFrame(this);
   9692 }
   9693 
   9694 void Context::getTexImage(TextureTarget target,
   9695                          GLint level,
   9696                          GLenum format,
   9697                          GLenum type,
   9698                          void *pixels)
   9699 {
   9700    Texture *texture   = getTextureByTarget(target);
   9701    Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
   9702    ANGLE_CONTEXT_TRY(texture->getTexImage(this, mState.getPackState(), packBuffer, target, level,
   9703                                           format, type, pixels));
   9704 }
   9705 
   9706 void Context::getCompressedTexImage(TextureTarget target, GLint level, void *pixels)
   9707 {
   9708    Texture *texture   = getTextureByTarget(target);
   9709    Buffer *packBuffer = mState.getTargetBuffer(BufferBinding::PixelPack);
   9710    ANGLE_CONTEXT_TRY(texture->getCompressedTexImage(this, mState.getPackState(), packBuffer,
   9711                                                     target, level, pixels));
   9712 }
   9713 
   9714 void Context::getRenderbufferImage(GLenum target, GLenum format, GLenum type, void *pixels)
   9715 {
   9716    Renderbuffer *renderbuffer = mState.getCurrentRenderbuffer();
   9717    Buffer *packBuffer         = mState.getTargetBuffer(BufferBinding::PixelPack);
   9718    ANGLE_CONTEXT_TRY(renderbuffer->getRenderbufferImage(this, mState.getPackState(), packBuffer,
   9719                                                         format, type, pixels));
   9720 }
   9721 
   9722 void Context::logicOpANGLE(LogicalOperation opcodePacked)
   9723 {
   9724    mState.setLogicOp(opcodePacked);
   9725 }
   9726 
   9727 egl::Error Context::releaseHighPowerGPU()
   9728 {
   9729    return mImplementation->releaseHighPowerGPU(this);
   9730 }
   9731 
   9732 egl::Error Context::reacquireHighPowerGPU()
   9733 {
   9734    return mImplementation->reacquireHighPowerGPU(this);
   9735 }
   9736 
   9737 void Context::onGPUSwitch()
   9738 {
   9739    // Re-initialize the renderer string, which just changed, and
   9740    // which must be visible to applications.
   9741    initRendererString();
   9742 }
   9743 
   9744 std::mutex &Context::getProgramCacheMutex() const
   9745 {
   9746    return mDisplay->getProgramCacheMutex();
   9747 }
   9748 
   9749 bool Context::supportsGeometryOrTesselation() const
   9750 {
   9751    return mState.getClientVersion() == ES_3_2 || mState.getExtensions().geometryShaderAny() ||
   9752           mState.getExtensions().tessellationShaderEXT;
   9753 }
   9754 
   9755 void Context::dirtyAllState()
   9756 {
   9757    mState.setAllDirtyBits();
   9758    mState.setAllDirtyObjects();
   9759    mState.gles1().setAllDirty();
   9760 }
   9761 
   9762 void Context::finishImmutable() const
   9763 {
   9764    ANGLE_CONTEXT_TRY(mImplementation->finish(this));
   9765 }
   9766 
   9767 void Context::beginPerfMonitor(GLuint monitor) {}
   9768 
   9769 void Context::deletePerfMonitors(GLsizei n, GLuint *monitors) {}
   9770 
   9771 void Context::endPerfMonitor(GLuint monitor) {}
   9772 
   9773 void Context::genPerfMonitors(GLsizei n, GLuint *monitors)
   9774 {
   9775    for (GLsizei monitorIndex = 0; monitorIndex < n; ++monitorIndex)
   9776    {
   9777        monitors[n] = static_cast<GLuint>(monitorIndex);
   9778    }
   9779 }
   9780 
   9781 void Context::getPerfMonitorCounterData(GLuint monitor,
   9782                                        GLenum pname,
   9783                                        GLsizei dataSize,
   9784                                        GLuint *data,
   9785                                        GLint *bytesWritten)
   9786 {
   9787    using namespace angle;
   9788    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9789    GLint byteCount                                   = 0;
   9790    switch (pname)
   9791    {
   9792        case GL_PERFMON_RESULT_AVAILABLE_AMD:
   9793        {
   9794            *data = GL_TRUE;
   9795            byteCount += sizeof(GLuint);
   9796            break;
   9797        }
   9798        case GL_PERFMON_RESULT_SIZE_AMD:
   9799        {
   9800            GLuint resultSize = 0;
   9801            for (const PerfMonitorCounterGroup &group : perfMonitorGroups)
   9802            {
   9803                resultSize += sizeof(PerfMonitorTriplet) * group.counters.size();
   9804            }
   9805            *data = resultSize;
   9806            byteCount += sizeof(GLuint);
   9807            break;
   9808        }
   9809        case GL_PERFMON_RESULT_AMD:
   9810        {
   9811            PerfMonitorTriplet *resultsOut = reinterpret_cast<PerfMonitorTriplet *>(data);
   9812            GLsizei maxResults             = dataSize / (3 * sizeof(GLuint));
   9813            GLsizei resultCount            = 0;
   9814            for (size_t groupIndex = 0;
   9815                 groupIndex < perfMonitorGroups.size() && resultCount < maxResults; ++groupIndex)
   9816            {
   9817                const PerfMonitorCounterGroup &group = perfMonitorGroups[groupIndex];
   9818                for (size_t counterIndex = 0;
   9819                     counterIndex < group.counters.size() && resultCount < maxResults;
   9820                     ++counterIndex)
   9821                {
   9822                    const PerfMonitorCounter &counter = group.counters[counterIndex];
   9823                    PerfMonitorTriplet &triplet       = resultsOut[resultCount++];
   9824                    triplet.counter                   = static_cast<GLuint>(counterIndex);
   9825                    triplet.group                     = static_cast<GLuint>(groupIndex);
   9826                    triplet.value                     = counter.value;
   9827                }
   9828            }
   9829            byteCount += sizeof(PerfMonitorTriplet) * resultCount;
   9830            break;
   9831        }
   9832        default:
   9833            UNREACHABLE();
   9834    }
   9835 
   9836    if (bytesWritten)
   9837    {
   9838        *bytesWritten = byteCount;
   9839    }
   9840 }
   9841 
   9842 void Context::getPerfMonitorCounterInfo(GLuint group, GLuint counter, GLenum pname, void *data)
   9843 {
   9844    using namespace angle;
   9845    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9846    ASSERT(group < perfMonitorGroups.size());
   9847    const PerfMonitorCounters &counters = perfMonitorGroups[group].counters;
   9848    ASSERT(counter < counters.size());
   9849 
   9850    switch (pname)
   9851    {
   9852        case GL_COUNTER_TYPE_AMD:
   9853        {
   9854            GLenum *dataOut = reinterpret_cast<GLenum *>(data);
   9855            *dataOut        = GL_UNSIGNED_INT;
   9856            break;
   9857        }
   9858        case GL_COUNTER_RANGE_AMD:
   9859        {
   9860            GLuint *dataOut = reinterpret_cast<GLuint *>(data);
   9861            dataOut[0]      = 0;
   9862            dataOut[1]      = std::numeric_limits<GLuint>::max();
   9863            break;
   9864        }
   9865        default:
   9866            UNREACHABLE();
   9867    }
   9868 }
   9869 
   9870 void Context::getPerfMonitorCounterString(GLuint group,
   9871                                          GLuint counter,
   9872                                          GLsizei bufSize,
   9873                                          GLsizei *length,
   9874                                          GLchar *counterString)
   9875 {
   9876    using namespace angle;
   9877    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9878    ASSERT(group < perfMonitorGroups.size());
   9879    const PerfMonitorCounters &counters = perfMonitorGroups[group].counters;
   9880    ASSERT(counter < counters.size());
   9881    GetPerfMonitorString(counters[counter].name, bufSize, length, counterString);
   9882 }
   9883 
   9884 void Context::getPerfMonitorCounters(GLuint group,
   9885                                     GLint *numCounters,
   9886                                     GLint *maxActiveCounters,
   9887                                     GLsizei counterSize,
   9888                                     GLuint *counters)
   9889 {
   9890    using namespace angle;
   9891    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9892    ASSERT(group < perfMonitorGroups.size());
   9893    const PerfMonitorCounters &groupCounters = perfMonitorGroups[group].counters;
   9894 
   9895    if (numCounters)
   9896    {
   9897        *numCounters = static_cast<GLint>(groupCounters.size());
   9898    }
   9899 
   9900    if (maxActiveCounters)
   9901    {
   9902        *maxActiveCounters = static_cast<GLint>(groupCounters.size());
   9903    }
   9904 
   9905    if (counters)
   9906    {
   9907        GLsizei maxCounterIndex = std::min(counterSize, static_cast<GLsizei>(groupCounters.size()));
   9908        for (GLsizei counterIndex = 0; counterIndex < maxCounterIndex; ++counterIndex)
   9909        {
   9910            counters[counterIndex] = static_cast<GLuint>(counterIndex);
   9911        }
   9912    }
   9913 }
   9914 
   9915 void Context::getPerfMonitorGroupString(GLuint group,
   9916                                        GLsizei bufSize,
   9917                                        GLsizei *length,
   9918                                        GLchar *groupString)
   9919 {
   9920    using namespace angle;
   9921    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9922    ASSERT(group < perfMonitorGroups.size());
   9923    GetPerfMonitorString(perfMonitorGroups[group].name, bufSize, length, groupString);
   9924 }
   9925 
   9926 void Context::getPerfMonitorGroups(GLint *numGroups, GLsizei groupsSize, GLuint *groups)
   9927 {
   9928    using namespace angle;
   9929    const PerfMonitorCounterGroups &perfMonitorGroups = mImplementation->getPerfMonitorCounters();
   9930 
   9931    if (numGroups)
   9932    {
   9933        *numGroups = static_cast<GLint>(perfMonitorGroups.size());
   9934    }
   9935 
   9936    GLuint maxGroupIndex =
   9937        std::min<GLuint>(groupsSize, static_cast<GLuint>(perfMonitorGroups.size()));
   9938    for (GLuint groupIndex = 0; groupIndex < maxGroupIndex; ++groupIndex)
   9939    {
   9940        groups[groupIndex] = groupIndex;
   9941    }
   9942 }
   9943 
   9944 void Context::selectPerfMonitorCounters(GLuint monitor,
   9945                                        GLboolean enable,
   9946                                        GLuint group,
   9947                                        GLint numCounters,
   9948                                        GLuint *counterList)
   9949 {}
   9950 
   9951 const angle::PerfMonitorCounterGroups &Context::getPerfMonitorCounterGroups() const
   9952 {
   9953    return mImplementation->getPerfMonitorCounters();
   9954 }
   9955 
   9956 // ErrorSet implementation.
   9957 ErrorSet::ErrorSet(Context *context) : mContext(context) {}
   9958 
   9959 ErrorSet::~ErrorSet() = default;
   9960 
   9961 void ErrorSet::handleError(GLenum errorCode,
   9962                           const char *message,
   9963                           const char *file,
   9964                           const char *function,
   9965                           unsigned int line)
   9966 {
   9967    if (errorCode == GL_OUT_OF_MEMORY &&
   9968        mContext->getGraphicsResetStrategy() == GL_LOSE_CONTEXT_ON_RESET_EXT &&
   9969        mContext->getDisplay()->getFrontendFeatures().loseContextOnOutOfMemory.enabled)
   9970    {
   9971        mContext->markContextLost(GraphicsResetStatus::UnknownContextReset);
   9972    }
   9973 
   9974    std::stringstream errorStream;
   9975    errorStream << "Error: " << gl::FmtHex(errorCode) << ", in " << file << ", " << function << ":"
   9976                << line << ". " << message;
   9977 
   9978    std::string formattedMessage = errorStream.str();
   9979 
   9980    // Process the error, but log it with WARN severity so it shows up in logs.
   9981    ASSERT(errorCode != GL_NO_ERROR);
   9982    mErrors.insert(errorCode);
   9983 
   9984    mContext->getState().getDebug().insertMessage(
   9985        GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR, errorCode, GL_DEBUG_SEVERITY_HIGH,
   9986        std::move(formattedMessage), gl::LOG_WARN, angle::EntryPoint::GLInvalid);
   9987 }
   9988 
   9989 void ErrorSet::validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message)
   9990 {
   9991    ASSERT(errorCode != GL_NO_ERROR);
   9992    mErrors.insert(errorCode);
   9993 
   9994    mContext->getState().getDebug().insertMessage(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_ERROR,
   9995                                                  errorCode, GL_DEBUG_SEVERITY_HIGH, message,
   9996                                                  gl::LOG_INFO, entryPoint);
   9997 }
   9998 
   9999 bool ErrorSet::empty() const
  10000 {
  10001    return mErrors.empty();
  10002 }
  10003 
  10004 GLenum ErrorSet::popError()
  10005 {
  10006    ASSERT(!empty());
  10007    GLenum error = *mErrors.begin();
  10008    mErrors.erase(mErrors.begin());
  10009    return error;
  10010 }
  10011 
  10012 // StateCache implementation.
  10013 StateCache::StateCache()
  10014    : mCachedHasAnyEnabledClientAttrib(false),
  10015      mCachedNonInstancedVertexElementLimit(0),
  10016      mCachedInstancedVertexElementLimit(0),
  10017      mCachedBasicDrawStatesError(kInvalidPointer),
  10018      mCachedBasicDrawElementsError(kInvalidPointer),
  10019      mCachedProgramPipelineError(kInvalidPointer),
  10020      mCachedTransformFeedbackActiveUnpaused(false),
  10021      mCachedCanDraw(false)
  10022 {
  10023    mCachedValidDrawModes.fill(false);
  10024 }
  10025 
  10026 StateCache::~StateCache() = default;
  10027 
  10028 ANGLE_INLINE void StateCache::updateVertexElementLimits(Context *context)
  10029 {
  10030    if (context->isBufferAccessValidationEnabled())
  10031    {
  10032        updateVertexElementLimitsImpl(context);
  10033    }
  10034 }
  10035 
  10036 void StateCache::initialize(Context *context)
  10037 {
  10038    updateValidDrawModes(context);
  10039    updateValidBindTextureTypes(context);
  10040    updateValidDrawElementsTypes(context);
  10041    updateBasicDrawStatesError();
  10042    updateBasicDrawElementsError();
  10043    updateVertexAttribTypesValidation(context);
  10044    updateCanDraw(context);
  10045 }
  10046 
  10047 void StateCache::updateActiveAttribsMask(Context *context)
  10048 {
  10049    bool isGLES1         = context->isGLES1();
  10050    const State &glState = context->getState();
  10051 
  10052    if (!isGLES1 && !glState.getProgramExecutable())
  10053    {
  10054        mCachedActiveBufferedAttribsMask = AttributesMask();
  10055        mCachedActiveClientAttribsMask   = AttributesMask();
  10056        mCachedActiveDefaultAttribsMask  = AttributesMask();
  10057        return;
  10058    }
  10059 
  10060    AttributesMask activeAttribs =
  10061        isGLES1 ? glState.gles1().getActiveAttributesMask()
  10062                : glState.getProgramExecutable()->getActiveAttribLocationsMask();
  10063 
  10064    const VertexArray *vao = glState.getVertexArray();
  10065    ASSERT(vao);
  10066 
  10067    const AttributesMask &clientAttribs  = vao->getClientAttribsMask();
  10068    const AttributesMask &enabledAttribs = vao->getEnabledAttributesMask();
  10069    const AttributesMask &activeEnabled  = activeAttribs & enabledAttribs;
  10070 
  10071    mCachedActiveClientAttribsMask   = activeEnabled & clientAttribs;
  10072    mCachedActiveBufferedAttribsMask = activeEnabled & ~clientAttribs;
  10073    mCachedActiveDefaultAttribsMask  = activeAttribs & ~enabledAttribs;
  10074    mCachedHasAnyEnabledClientAttrib = (clientAttribs & enabledAttribs).any();
  10075 }
  10076 
  10077 void StateCache::updateVertexElementLimitsImpl(Context *context)
  10078 {
  10079    ASSERT(context->isBufferAccessValidationEnabled());
  10080 
  10081    const VertexArray *vao = context->getState().getVertexArray();
  10082 
  10083    mCachedNonInstancedVertexElementLimit = std::numeric_limits<GLint64>::max();
  10084    mCachedInstancedVertexElementLimit    = std::numeric_limits<GLint64>::max();
  10085 
  10086    // VAO can be null on Context startup. If we make this computation lazier we could ASSERT.
  10087    // If there are no buffered attributes then we should not limit the draw call count.
  10088    if (!vao || !mCachedActiveBufferedAttribsMask.any())
  10089    {
  10090        return;
  10091    }
  10092 
  10093    const auto &vertexAttribs  = vao->getVertexAttributes();
  10094    const auto &vertexBindings = vao->getVertexBindings();
  10095 
  10096    for (size_t attributeIndex : mCachedActiveBufferedAttribsMask)
  10097    {
  10098        const VertexAttribute &attrib = vertexAttribs[attributeIndex];
  10099 
  10100        const VertexBinding &binding = vertexBindings[attrib.bindingIndex];
  10101        ASSERT(context->isGLES1() ||
  10102               context->getState().getProgramExecutable()->isAttribLocationActive(attributeIndex));
  10103 
  10104        GLint64 limit = attrib.getCachedElementLimit();
  10105        if (binding.getDivisor() > 0)
  10106        {
  10107            mCachedInstancedVertexElementLimit =
  10108                std::min(mCachedInstancedVertexElementLimit, limit);
  10109        }
  10110        else
  10111        {
  10112            mCachedNonInstancedVertexElementLimit =
  10113                std::min(mCachedNonInstancedVertexElementLimit, limit);
  10114        }
  10115    }
  10116 }
  10117 
  10118 void StateCache::updateBasicDrawStatesError()
  10119 {
  10120    mCachedBasicDrawStatesError = kInvalidPointer;
  10121 }
  10122 
  10123 void StateCache::updateProgramPipelineError()
  10124 {
  10125    mCachedProgramPipelineError = kInvalidPointer;
  10126 }
  10127 
  10128 void StateCache::updateBasicDrawElementsError()
  10129 {
  10130    mCachedBasicDrawElementsError = kInvalidPointer;
  10131 }
  10132 
  10133 intptr_t StateCache::getBasicDrawStatesErrorImpl(const Context *context) const
  10134 {
  10135    ASSERT(mCachedBasicDrawStatesError == kInvalidPointer);
  10136    mCachedBasicDrawStatesError = reinterpret_cast<intptr_t>(ValidateDrawStates(context));
  10137    return mCachedBasicDrawStatesError;
  10138 }
  10139 
  10140 intptr_t StateCache::getProgramPipelineErrorImpl(const Context *context) const
  10141 {
  10142    ASSERT(mCachedProgramPipelineError == kInvalidPointer);
  10143    mCachedProgramPipelineError = reinterpret_cast<intptr_t>(ValidateProgramPipeline(context));
  10144    return mCachedProgramPipelineError;
  10145 }
  10146 
  10147 intptr_t StateCache::getBasicDrawElementsErrorImpl(const Context *context) const
  10148 {
  10149    ASSERT(mCachedBasicDrawElementsError == kInvalidPointer);
  10150    mCachedBasicDrawElementsError = reinterpret_cast<intptr_t>(ValidateDrawElementsStates(context));
  10151    return mCachedBasicDrawElementsError;
  10152 }
  10153 
  10154 void StateCache::onVertexArrayBindingChange(Context *context)
  10155 {
  10156    updateActiveAttribsMask(context);
  10157    updateVertexElementLimits(context);
  10158    updateBasicDrawStatesError();
  10159    updateBasicDrawElementsError();
  10160 }
  10161 
  10162 void StateCache::onProgramExecutableChange(Context *context)
  10163 {
  10164    updateActiveAttribsMask(context);
  10165    updateVertexElementLimits(context);
  10166    updateBasicDrawStatesError();
  10167    updateProgramPipelineError();
  10168    updateValidDrawModes(context);
  10169    updateActiveShaderStorageBufferIndices(context);
  10170    updateActiveImageUnitIndices(context);
  10171    updateCanDraw(context);
  10172 }
  10173 
  10174 void StateCache::onVertexArrayFormatChange(Context *context)
  10175 {
  10176    updateVertexElementLimits(context);
  10177 }
  10178 
  10179 void StateCache::onVertexArrayBufferContentsChange(Context *context)
  10180 {
  10181    updateVertexElementLimits(context);
  10182    updateBasicDrawStatesError();
  10183 }
  10184 
  10185 void StateCache::onVertexArrayStateChange(Context *context)
  10186 {
  10187    updateActiveAttribsMask(context);
  10188    updateVertexElementLimits(context);
  10189    updateBasicDrawStatesError();
  10190    updateBasicDrawElementsError();
  10191 }
  10192 
  10193 void StateCache::onVertexArrayBufferStateChange(Context *context)
  10194 {
  10195    updateBasicDrawStatesError();
  10196    updateBasicDrawElementsError();
  10197 }
  10198 
  10199 void StateCache::onGLES1ClientStateChange(Context *context)
  10200 {
  10201    updateActiveAttribsMask(context);
  10202 }
  10203 
  10204 void StateCache::onDrawFramebufferChange(Context *context)
  10205 {
  10206    updateBasicDrawStatesError();
  10207 }
  10208 
  10209 void StateCache::onContextCapChange(Context *context)
  10210 {
  10211    updateBasicDrawStatesError();
  10212 }
  10213 
  10214 void StateCache::onStencilStateChange(Context *context)
  10215 {
  10216    updateBasicDrawStatesError();
  10217 }
  10218 
  10219 void StateCache::onDefaultVertexAttributeChange(Context *context)
  10220 {
  10221    updateBasicDrawStatesError();
  10222 }
  10223 
  10224 void StateCache::onActiveTextureChange(Context *context)
  10225 {
  10226    updateBasicDrawStatesError();
  10227 }
  10228 
  10229 void StateCache::onQueryChange(Context *context)
  10230 {
  10231    updateBasicDrawStatesError();
  10232 }
  10233 
  10234 void StateCache::onActiveTransformFeedbackChange(Context *context)
  10235 {
  10236    updateTransformFeedbackActiveUnpaused(context);
  10237    updateBasicDrawStatesError();
  10238    updateBasicDrawElementsError();
  10239    updateValidDrawModes(context);
  10240 }
  10241 
  10242 void StateCache::onUniformBufferStateChange(Context *context)
  10243 {
  10244    updateBasicDrawStatesError();
  10245 }
  10246 
  10247 void StateCache::onAtomicCounterBufferStateChange(Context *context)
  10248 {
  10249    updateBasicDrawStatesError();
  10250 }
  10251 
  10252 void StateCache::onShaderStorageBufferStateChange(Context *context)
  10253 {
  10254    updateBasicDrawStatesError();
  10255 }
  10256 
  10257 void StateCache::onColorMaskChange(Context *context)
  10258 {
  10259    updateBasicDrawStatesError();
  10260 }
  10261 
  10262 void StateCache::onBlendFuncIndexedChange(Context *context)
  10263 {
  10264    updateBasicDrawStatesError();
  10265 }
  10266 
  10267 void StateCache::onBlendEquationChange(Context *context)
  10268 {
  10269    updateBasicDrawStatesError();
  10270 }
  10271 
  10272 void StateCache::setValidDrawModes(bool pointsOK,
  10273                                   bool linesOK,
  10274                                   bool trisOK,
  10275                                   bool lineAdjOK,
  10276                                   bool triAdjOK,
  10277                                   bool patchOK)
  10278 {
  10279    mCachedValidDrawModes[PrimitiveMode::Points]                 = pointsOK;
  10280    mCachedValidDrawModes[PrimitiveMode::Lines]                  = linesOK;
  10281    mCachedValidDrawModes[PrimitiveMode::LineLoop]               = linesOK;
  10282    mCachedValidDrawModes[PrimitiveMode::LineStrip]              = linesOK;
  10283    mCachedValidDrawModes[PrimitiveMode::Triangles]              = trisOK;
  10284    mCachedValidDrawModes[PrimitiveMode::TriangleStrip]          = trisOK;
  10285    mCachedValidDrawModes[PrimitiveMode::TriangleFan]            = trisOK;
  10286    mCachedValidDrawModes[PrimitiveMode::LinesAdjacency]         = lineAdjOK;
  10287    mCachedValidDrawModes[PrimitiveMode::LineStripAdjacency]     = lineAdjOK;
  10288    mCachedValidDrawModes[PrimitiveMode::TrianglesAdjacency]     = triAdjOK;
  10289    mCachedValidDrawModes[PrimitiveMode::TriangleStripAdjacency] = triAdjOK;
  10290    mCachedValidDrawModes[PrimitiveMode::Patches]                = patchOK;
  10291 }
  10292 
  10293 void StateCache::updateValidDrawModes(Context *context)
  10294 {
  10295    const State &state = context->getState();
  10296 
  10297    const ProgramExecutable *programExecutable = context->getState().getProgramExecutable();
  10298 
  10299    // If tessellation is active primitive mode must be GL_PATCHES.
  10300    if (programExecutable && programExecutable->hasLinkedTessellationShader())
  10301    {
  10302        setValidDrawModes(false, false, false, false, false, true);
  10303        return;
  10304    }
  10305 
  10306    if (mCachedTransformFeedbackActiveUnpaused)
  10307    {
  10308        TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
  10309 
  10310        // ES Spec 3.0 validation text:
  10311        // When transform feedback is active and not paused, all geometric primitives generated must
  10312        // match the value of primitiveMode passed to BeginTransformFeedback. The error
  10313        // INVALID_OPERATION is generated by DrawArrays and DrawArraysInstanced if mode is not
  10314        // identical to primitiveMode. The error INVALID_OPERATION is also generated by
  10315        // DrawElements, DrawElementsInstanced, and DrawRangeElements while transform feedback is
  10316        // active and not paused, regardless of mode. Any primitive type may be used while transform
  10317        // feedback is paused.
  10318        if (!context->getExtensions().geometryShaderAny() &&
  10319            !context->getExtensions().tessellationShaderEXT && context->getClientVersion() < ES_3_2)
  10320        {
  10321            mCachedValidDrawModes.fill(false);
  10322            mCachedValidDrawModes[curTransformFeedback->getPrimitiveMode()] = true;
  10323            return;
  10324        }
  10325    }
  10326 
  10327    if (!programExecutable || !programExecutable->hasLinkedShaderStage(ShaderType::Geometry))
  10328    {
  10329        // All draw modes are valid, since drawing without a program does not generate an error and
  10330        // and operations requiring a GS will trigger other validation errors.
  10331        // `patchOK = false` due to checking above already enabling it if a TS is present.
  10332        setValidDrawModes(true, true, true, true, true, false);
  10333        return;
  10334    }
  10335 
  10336    PrimitiveMode gsMode = programExecutable->getGeometryShaderInputPrimitiveType();
  10337    bool pointsOK        = gsMode == PrimitiveMode::Points;
  10338    bool linesOK         = gsMode == PrimitiveMode::Lines;
  10339    bool trisOK          = gsMode == PrimitiveMode::Triangles;
  10340    bool lineAdjOK       = gsMode == PrimitiveMode::LinesAdjacency;
  10341    bool triAdjOK        = gsMode == PrimitiveMode::TrianglesAdjacency;
  10342 
  10343    setValidDrawModes(pointsOK, linesOK, trisOK, lineAdjOK, triAdjOK, false);
  10344 }
  10345 
  10346 void StateCache::updateValidBindTextureTypes(Context *context)
  10347 {
  10348    const Extensions &exts = context->getExtensions();
  10349    bool isGLES3           = context->getClientMajorVersion() >= 3;
  10350    bool isGLES31          = context->getClientVersion() >= Version(3, 1);
  10351 
  10352    mCachedValidBindTextureTypes = {{
  10353        {TextureType::_2D, true},
  10354        {TextureType::_2DArray, isGLES3},
  10355        {TextureType::_2DMultisample, isGLES31 || exts.textureMultisampleANGLE},
  10356        {TextureType::_2DMultisampleArray, exts.textureStorageMultisample2dArrayOES},
  10357        {TextureType::_3D, isGLES3 || exts.texture3DOES},
  10358        {TextureType::External, exts.EGLImageExternalOES || exts.EGLStreamConsumerExternalNV},
  10359        {TextureType::Rectangle, exts.textureRectangleANGLE},
  10360        {TextureType::CubeMap, true},
  10361        {TextureType::CubeMapArray, exts.textureCubeMapArrayAny()},
  10362        {TextureType::VideoImage, exts.videoTextureWEBGL},
  10363        {TextureType::Buffer, exts.textureBufferAny()},
  10364    }};
  10365 }
  10366 
  10367 void StateCache::updateValidDrawElementsTypes(Context *context)
  10368 {
  10369    bool supportsUint =
  10370        (context->getClientMajorVersion() >= 3 || context->getExtensions().elementIndexUintOES);
  10371 
  10372    mCachedValidDrawElementsTypes = {{
  10373        {DrawElementsType::UnsignedByte, true},
  10374        {DrawElementsType::UnsignedShort, true},
  10375        {DrawElementsType::UnsignedInt, supportsUint},
  10376    }};
  10377 }
  10378 
  10379 void StateCache::updateTransformFeedbackActiveUnpaused(Context *context)
  10380 {
  10381    TransformFeedback *xfb                 = context->getState().getCurrentTransformFeedback();
  10382    mCachedTransformFeedbackActiveUnpaused = xfb && xfb->isActive() && !xfb->isPaused();
  10383 }
  10384 
  10385 void StateCache::updateVertexAttribTypesValidation(Context *context)
  10386 {
  10387    VertexAttribTypeCase halfFloatValidity = (context->getExtensions().vertexHalfFloatOES)
  10388                                                 ? VertexAttribTypeCase::Valid
  10389                                                 : VertexAttribTypeCase::Invalid;
  10390 
  10391    VertexAttribTypeCase vertexType1010102Validity = (context->getExtensions().vertexType1010102OES)
  10392                                                         ? VertexAttribTypeCase::ValidSize3or4
  10393                                                         : VertexAttribTypeCase::Invalid;
  10394 
  10395    if (context->getClientMajorVersion() <= 2)
  10396    {
  10397        mCachedVertexAttribTypesValidation = {{
  10398            {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
  10399            {VertexAttribType::Short, VertexAttribTypeCase::Valid},
  10400            {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
  10401            {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
  10402            {VertexAttribType::Float, VertexAttribTypeCase::Valid},
  10403            {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
  10404            {VertexAttribType::HalfFloatOES, halfFloatValidity},
  10405        }};
  10406    }
  10407    else
  10408    {
  10409        mCachedVertexAttribTypesValidation = {{
  10410            {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
  10411            {VertexAttribType::Short, VertexAttribTypeCase::Valid},
  10412            {VertexAttribType::Int, VertexAttribTypeCase::Valid},
  10413            {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
  10414            {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
  10415            {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
  10416            {VertexAttribType::Float, VertexAttribTypeCase::Valid},
  10417            {VertexAttribType::HalfFloat, VertexAttribTypeCase::Valid},
  10418            {VertexAttribType::Fixed, VertexAttribTypeCase::Valid},
  10419            {VertexAttribType::Int2101010, VertexAttribTypeCase::ValidSize4Only},
  10420            {VertexAttribType::HalfFloatOES, halfFloatValidity},
  10421            {VertexAttribType::UnsignedInt2101010, VertexAttribTypeCase::ValidSize4Only},
  10422            {VertexAttribType::Int1010102, vertexType1010102Validity},
  10423            {VertexAttribType::UnsignedInt1010102, vertexType1010102Validity},
  10424        }};
  10425 
  10426        mCachedIntegerVertexAttribTypesValidation = {{
  10427            {VertexAttribType::Byte, VertexAttribTypeCase::Valid},
  10428            {VertexAttribType::Short, VertexAttribTypeCase::Valid},
  10429            {VertexAttribType::Int, VertexAttribTypeCase::Valid},
  10430            {VertexAttribType::UnsignedByte, VertexAttribTypeCase::Valid},
  10431            {VertexAttribType::UnsignedShort, VertexAttribTypeCase::Valid},
  10432            {VertexAttribType::UnsignedInt, VertexAttribTypeCase::Valid},
  10433        }};
  10434    }
  10435 }
  10436 
  10437 void StateCache::updateActiveShaderStorageBufferIndices(Context *context)
  10438 {
  10439    mCachedActiveShaderStorageBufferIndices.reset();
  10440    const ProgramExecutable *executable = context->getState().getProgramExecutable();
  10441    if (executable)
  10442    {
  10443        for (const InterfaceBlock &block : executable->getShaderStorageBlocks())
  10444        {
  10445            mCachedActiveShaderStorageBufferIndices.set(block.binding);
  10446        }
  10447    }
  10448 }
  10449 
  10450 void StateCache::updateActiveImageUnitIndices(Context *context)
  10451 {
  10452    mCachedActiveImageUnitIndices.reset();
  10453    const ProgramExecutable *executable = context->getState().getProgramExecutable();
  10454    if (executable)
  10455    {
  10456        for (const ImageBinding &imageBinding : executable->getImageBindings())
  10457        {
  10458            for (GLuint binding : imageBinding.boundImageUnits)
  10459            {
  10460                mCachedActiveImageUnitIndices.set(binding);
  10461            }
  10462        }
  10463    }
  10464 }
  10465 
  10466 void StateCache::updateCanDraw(Context *context)
  10467 {
  10468    mCachedCanDraw =
  10469        (context->isGLES1() || (context->getState().getProgramExecutable() &&
  10470                                context->getState().getProgramExecutable()->hasVertexShader()));
  10471 }
  10472 }  // namespace gl