tor-browser

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

State.cpp (127283B)


      1 //
      2 // Copyright 2014 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 // State.cpp: Implements the State class, encapsulating raw GL state.
      8 
      9 #include "libANGLE/State.h"
     10 
     11 #include <string.h>
     12 #include <limits>
     13 
     14 #include "common/bitset_utils.h"
     15 #include "common/mathutil.h"
     16 #include "common/matrix_utils.h"
     17 #include "libANGLE/Buffer.h"
     18 #include "libANGLE/Caps.h"
     19 #include "libANGLE/Context.h"
     20 #include "libANGLE/Debug.h"
     21 #include "libANGLE/Framebuffer.h"
     22 #include "libANGLE/FramebufferAttachment.h"
     23 #include "libANGLE/PixelLocalStorage.h"
     24 #include "libANGLE/Query.h"
     25 #include "libANGLE/VertexArray.h"
     26 #include "libANGLE/formatutils.h"
     27 #include "libANGLE/queryconversions.h"
     28 #include "libANGLE/queryutils.h"
     29 #include "libANGLE/renderer/ContextImpl.h"
     30 #include "libANGLE/renderer/TextureImpl.h"
     31 
     32 namespace gl
     33 {
     34 
     35 namespace
     36 {
     37 bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
     38 {
     39    switch (type)
     40    {
     41        case QueryType::AnySamples:
     42            *alternativeType = QueryType::AnySamplesConservative;
     43            return true;
     44        case QueryType::AnySamplesConservative:
     45            *alternativeType = QueryType::AnySamples;
     46            return true;
     47        default:
     48            return false;
     49    }
     50 }
     51 
     52 // Mapping from a buffer binding type to a dirty bit type.
     53 constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{
     54    {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING},
     55    {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING},
     56    {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING},
     57    {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING},
     58    {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING},
     59    {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING},
     60    {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS},
     61 }};
     62 
     63 // Returns a buffer binding function depending on if a dirty bit is set.
     64 template <BufferBinding Target>
     65 constexpr std::pair<BufferBinding, State::BufferBindingSetter> GetBufferBindingSetter()
     66 {
     67    return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0
     68                                      ? &State::setGenericBufferBindingWithBit<Target>
     69                                      : &State::setGenericBufferBinding<Target>);
     70 }
     71 
     72 template <typename T>
     73 using ContextStateMember = T *(State::*);
     74 
     75 template <typename T>
     76 T *AllocateOrGetSharedResourceManager(const State *shareContextState,
     77                                      ContextStateMember<T> member,
     78                                      T *shareResources = nullptr)
     79 {
     80    if (shareContextState)
     81    {
     82        T *resourceManager = (*shareContextState).*member;
     83        ASSERT(!resourceManager || resourceManager == shareResources || !shareResources);
     84        resourceManager->addRef();
     85        return resourceManager;
     86    }
     87    else if (shareResources)
     88    {
     89        shareResources->addRef();
     90        return shareResources;
     91    }
     92    else
     93    {
     94        return new T();
     95    }
     96 }
     97 
     98 // TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
     99 // refactory done.
    100 bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler)
    101 {
    102    if (sampler == texture)
    103    {
    104        return true;
    105    }
    106 
    107    if (sampler == TextureType::VideoImage)
    108    {
    109        if (texture == TextureType::VideoImage || texture == TextureType::_2D)
    110        {
    111            return true;
    112        }
    113    }
    114 
    115    return false;
    116 }
    117 
    118 uint32_t gIDCounter = 1;
    119 }  // namespace
    120 
    121 template <typename BindingT, typename... ArgsT>
    122 ANGLE_INLINE void UpdateNonTFBufferBindingWebGL(const Context *context,
    123                                                BindingT *binding,
    124                                                Buffer *buffer,
    125                                                ArgsT... args)
    126 {
    127    Buffer *oldBuffer = binding->get();
    128    if (oldBuffer)
    129    {
    130        oldBuffer->onNonTFBindingChanged(-1);
    131        oldBuffer->release(context);
    132    }
    133    binding->assign(buffer, args...);
    134    if (buffer)
    135    {
    136        buffer->addRef();
    137        buffer->onNonTFBindingChanged(1);
    138    }
    139 }
    140 
    141 template <typename BindingT, typename... ArgsT>
    142 void UpdateTFBufferBindingWebGL(const Context *context,
    143                                BindingT *binding,
    144                                bool indexed,
    145                                ArgsT... args)
    146 {
    147    if (binding->get())
    148        (*binding)->onTFBindingChanged(context, false, indexed);
    149    binding->set(context, args...);
    150    if (binding->get())
    151        (*binding)->onTFBindingChanged(context, true, indexed);
    152 }
    153 
    154 void UpdateBufferBinding(const Context *context,
    155                         BindingPointer<Buffer> *binding,
    156                         Buffer *buffer,
    157                         BufferBinding target)
    158 {
    159    if (context->isWebGL())
    160    {
    161        if (target == BufferBinding::TransformFeedback)
    162        {
    163            UpdateTFBufferBindingWebGL(context, binding, false, buffer);
    164        }
    165        else
    166        {
    167            UpdateNonTFBufferBindingWebGL(context, binding, buffer);
    168        }
    169    }
    170    else
    171    {
    172        binding->set(context, buffer);
    173    }
    174 }
    175 
    176 void UpdateIndexedBufferBinding(const Context *context,
    177                                OffsetBindingPointer<Buffer> *binding,
    178                                Buffer *buffer,
    179                                BufferBinding target,
    180                                GLintptr offset,
    181                                GLsizeiptr size)
    182 {
    183    if (context->isWebGL())
    184    {
    185        if (target == BufferBinding::TransformFeedback)
    186        {
    187            UpdateTFBufferBindingWebGL(context, binding, true, buffer, offset, size);
    188        }
    189        else
    190        {
    191            UpdateNonTFBufferBindingWebGL(context, binding, buffer, offset, size);
    192        }
    193    }
    194    else
    195    {
    196        binding->set(context, buffer, offset, size);
    197    }
    198 }
    199 
    200 // These template functions must be defined before they are instantiated in kBufferSetters.
    201 template <BufferBinding Target>
    202 void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer)
    203 {
    204    if (context->isWebGL())
    205    {
    206        UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
    207    }
    208    else
    209    {
    210        mBoundBuffers[Target].set(context, buffer);
    211    }
    212    mDirtyBits.set(kBufferBindingDirtyBits[Target]);
    213 }
    214 
    215 template <BufferBinding Target>
    216 void State::setGenericBufferBinding(const Context *context, Buffer *buffer)
    217 {
    218    if (context->isWebGL())
    219    {
    220        UpdateNonTFBufferBindingWebGL(context, &mBoundBuffers[Target], buffer);
    221    }
    222    else
    223    {
    224        mBoundBuffers[Target].set(context, buffer);
    225    }
    226 }
    227 
    228 template <>
    229 void State::setGenericBufferBinding<BufferBinding::TransformFeedback>(const Context *context,
    230                                                                      Buffer *buffer)
    231 {
    232    if (context->isWebGL())
    233    {
    234        UpdateTFBufferBindingWebGL(context, &mBoundBuffers[BufferBinding::TransformFeedback], false,
    235                                   buffer);
    236    }
    237    else
    238    {
    239        mBoundBuffers[BufferBinding::TransformFeedback].set(context, buffer);
    240    }
    241 }
    242 
    243 template <>
    244 void State::setGenericBufferBinding<BufferBinding::ElementArray>(const Context *context,
    245                                                                 Buffer *buffer)
    246 {
    247    Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get();
    248    if (oldBuffer)
    249    {
    250        oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer);
    251        oldBuffer->removeContentsObserver(mVertexArray, kElementArrayBufferIndex);
    252        if (context->isWebGL())
    253        {
    254            oldBuffer->onNonTFBindingChanged(-1);
    255        }
    256        oldBuffer->release(context);
    257    }
    258    mVertexArray->mState.mElementArrayBuffer.assign(buffer);
    259    if (buffer)
    260    {
    261        buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer);
    262        buffer->addContentsObserver(mVertexArray, kElementArrayBufferIndex);
    263        if (context->isWebGL())
    264        {
    265            buffer->onNonTFBindingChanged(1);
    266        }
    267        buffer->addRef();
    268    }
    269    mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
    270    mVertexArray->mIndexRangeCache.invalidate();
    271    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
    272 }
    273 
    274 const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBufferSetters = {{
    275    GetBufferBindingSetter<BufferBinding::Array>(),
    276    GetBufferBindingSetter<BufferBinding::AtomicCounter>(),
    277    GetBufferBindingSetter<BufferBinding::CopyRead>(),
    278    GetBufferBindingSetter<BufferBinding::CopyWrite>(),
    279    GetBufferBindingSetter<BufferBinding::DispatchIndirect>(),
    280    GetBufferBindingSetter<BufferBinding::DrawIndirect>(),
    281    GetBufferBindingSetter<BufferBinding::ElementArray>(),
    282    GetBufferBindingSetter<BufferBinding::PixelPack>(),
    283    GetBufferBindingSetter<BufferBinding::PixelUnpack>(),
    284    GetBufferBindingSetter<BufferBinding::ShaderStorage>(),
    285    GetBufferBindingSetter<BufferBinding::Texture>(),
    286    GetBufferBindingSetter<BufferBinding::TransformFeedback>(),
    287    GetBufferBindingSetter<BufferBinding::Uniform>(),
    288 }};
    289 
    290 ActiveTexturesCache::ActiveTexturesCache() : mTextures{} {}
    291 
    292 ActiveTexturesCache::~ActiveTexturesCache()
    293 {
    294    ASSERT(empty());
    295 }
    296 
    297 void ActiveTexturesCache::clear()
    298 {
    299    for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex)
    300    {
    301        reset(textureIndex);
    302    }
    303 }
    304 
    305 bool ActiveTexturesCache::empty() const
    306 {
    307    for (Texture *texture : mTextures)
    308    {
    309        if (texture)
    310        {
    311            return false;
    312        }
    313    }
    314 
    315    return true;
    316 }
    317 
    318 ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex)
    319 {
    320    if (mTextures[textureIndex])
    321    {
    322        mTextures[textureIndex] = nullptr;
    323    }
    324 }
    325 
    326 ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture)
    327 {
    328    ASSERT(texture);
    329    mTextures[textureIndex] = texture;
    330 }
    331 
    332 State::State(const State *shareContextState,
    333             egl::ShareGroup *shareGroup,
    334             TextureManager *shareTextures,
    335             SemaphoreManager *shareSemaphores,
    336             const OverlayType *overlay,
    337             const EGLenum clientType,
    338             const Version &clientVersion,
    339             EGLint profileMask,
    340             bool debug,
    341             bool bindGeneratesResourceCHROMIUM,
    342             bool clientArraysEnabled,
    343             bool robustResourceInit,
    344             bool programBinaryCacheEnabled,
    345             EGLenum contextPriority,
    346             bool hasRobustAccess,
    347             bool hasProtectedContent)
    348    : mID({gIDCounter++}),
    349      mClientType(clientType),
    350      mProfileMask(profileMask),
    351      mContextPriority(contextPriority),
    352      mHasRobustAccess(hasRobustAccess),
    353      mHasProtectedContent(hasProtectedContent),
    354      mIsDebugContext(debug),
    355      mClientVersion(clientVersion),
    356      mShareGroup(shareGroup),
    357      mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
    358      mShaderProgramManager(
    359          AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
    360      mTextureManager(AllocateOrGetSharedResourceManager(shareContextState,
    361                                                         &State::mTextureManager,
    362                                                         shareTextures)),
    363      mRenderbufferManager(
    364          AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
    365      mSamplerManager(
    366          AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)),
    367      mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)),
    368      mFramebufferManager(new FramebufferManager()),
    369      mProgramPipelineManager(new ProgramPipelineManager()),
    370      mMemoryObjectManager(
    371          AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
    372      mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState,
    373                                                           &State::mSemaphoreManager,
    374                                                           shareSemaphores)),
    375      mDepthClearValue(0),
    376      mStencilClearValue(0),
    377      mScissorTest(false),
    378      mSampleAlphaToCoverage(false),
    379      mSampleCoverage(false),
    380      mSampleCoverageValue(0),
    381      mSampleCoverageInvert(false),
    382      mSampleMask(false),
    383      mMaxSampleMaskWords(0),
    384      mIsSampleShadingEnabled(false),
    385      mMinSampleShading(0.0f),
    386      mStencilRef(0),
    387      mStencilBackRef(0),
    388      mLineWidth(0),
    389      mGenerateMipmapHint(GL_NONE),
    390      mTextureFilteringHint(GL_NONE),
    391      mFragmentShaderDerivativeHint(GL_NONE),
    392      mBindGeneratesResource(bindGeneratesResourceCHROMIUM),
    393      mClientArraysEnabled(clientArraysEnabled),
    394      mNearZ(0),
    395      mFarZ(0),
    396      mReadFramebuffer(nullptr),
    397      mDrawFramebuffer(nullptr),
    398      mProgram(nullptr),
    399      mExecutable(nullptr),
    400      mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention),
    401      mVertexArray(nullptr),
    402      mActiveSampler(0),
    403      mPrimitiveRestart(false),
    404      mDebug(debug),
    405      mMultiSampling(false),
    406      mSampleAlphaToOne(false),
    407      mFramebufferSRGB(true),
    408      mRobustResourceInit(robustResourceInit),
    409      mProgramBinaryCacheEnabled(programBinaryCacheEnabled),
    410      mTextureRectangleEnabled(true),
    411      mLogicOpEnabled(false),
    412      mLogicOp(LogicalOperation::Copy),
    413      mMaxShaderCompilerThreads(std::numeric_limits<GLuint>::max()),
    414      mPatchVertices(3),
    415      mPixelLocalStorageActive(false),
    416      mOverlay(overlay),
    417      mNoSimultaneousConstantColorAndAlphaBlendFunc(false),
    418      mSetBlendIndexedInvoked(false),
    419      mSetBlendFactorsIndexedInvoked(false),
    420      mSetBlendEquationsIndexedInvoked(false),
    421      mDisplayTextureShareGroup(shareTextures != nullptr),
    422      mBoundingBoxMinX(-1.0f),
    423      mBoundingBoxMinY(-1.0f),
    424      mBoundingBoxMinZ(-1.0f),
    425      mBoundingBoxMinW(1.0f),
    426      mBoundingBoxMaxX(1.0f),
    427      mBoundingBoxMaxY(1.0f),
    428      mBoundingBoxMaxZ(1.0f),
    429      mBoundingBoxMaxW(1.0f),
    430      mShadingRatePreserveAspectRatio(false),
    431      mShadingRate(ShadingRate::Undefined)
    432 {}
    433 
    434 State::~State() {}
    435 
    436 void State::initialize(Context *context)
    437 {
    438    const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
    439    const Version &clientVersion       = context->getClientVersion();
    440 
    441    mBlendStateExt = BlendStateExt(mCaps.maxDrawBuffers);
    442 
    443    setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
    444 
    445    mDepthClearValue   = 1.0f;
    446    mStencilClearValue = 0;
    447 
    448    mScissorTest    = false;
    449    mScissor.x      = 0;
    450    mScissor.y      = 0;
    451    mScissor.width  = 0;
    452    mScissor.height = 0;
    453 
    454    mBlendColor.red   = 0;
    455    mBlendColor.green = 0;
    456    mBlendColor.blue  = 0;
    457    mBlendColor.alpha = 0;
    458 
    459    mStencilRef     = 0;
    460    mStencilBackRef = 0;
    461 
    462    mSampleCoverage       = false;
    463    mSampleCoverageValue  = 1.0f;
    464    mSampleCoverageInvert = false;
    465 
    466    mMaxSampleMaskWords = static_cast<GLuint>(mCaps.maxSampleMaskWords);
    467    mSampleMask         = false;
    468    mSampleMaskValues.fill(~GLbitfield(0));
    469 
    470    mGenerateMipmapHint           = GL_DONT_CARE;
    471    mTextureFilteringHint         = GL_DONT_CARE;
    472    mFragmentShaderDerivativeHint = GL_DONT_CARE;
    473 
    474    mLineWidth = 1.0f;
    475 
    476    mViewport.x      = 0;
    477    mViewport.y      = 0;
    478    mViewport.width  = 0;
    479    mViewport.height = 0;
    480    mNearZ           = 0.0f;
    481    mFarZ            = 1.0f;
    482 
    483    mClipControlOrigin = GL_LOWER_LEFT_EXT;
    484    mClipControlDepth  = GL_NEGATIVE_ONE_TO_ONE_EXT;
    485 
    486    mActiveSampler = 0;
    487 
    488    mVertexAttribCurrentValues.resize(mCaps.maxVertexAttributes);
    489 
    490    // Set all indexes in state attributes type mask to float (default)
    491    for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
    492    {
    493        SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
    494    }
    495 
    496    mUniformBuffers.resize(mCaps.maxUniformBufferBindings);
    497 
    498    mSamplerTextures[TextureType::_2D].resize(mCaps.maxCombinedTextureImageUnits);
    499    mSamplerTextures[TextureType::CubeMap].resize(mCaps.maxCombinedTextureImageUnits);
    500    if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES)
    501    {
    502        mSamplerTextures[TextureType::_3D].resize(mCaps.maxCombinedTextureImageUnits);
    503    }
    504    if (clientVersion >= Version(3, 0))
    505    {
    506        mSamplerTextures[TextureType::_2DArray].resize(mCaps.maxCombinedTextureImageUnits);
    507    }
    508    if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisampleANGLE)
    509    {
    510        mSamplerTextures[TextureType::_2DMultisample].resize(mCaps.maxCombinedTextureImageUnits);
    511    }
    512    if (clientVersion >= Version(3, 1))
    513    {
    514        mSamplerTextures[TextureType::_2DMultisampleArray].resize(
    515            mCaps.maxCombinedTextureImageUnits);
    516 
    517        mAtomicCounterBuffers.resize(mCaps.maxAtomicCounterBufferBindings);
    518        mShaderStorageBuffers.resize(mCaps.maxShaderStorageBufferBindings);
    519    }
    520    if (clientVersion >= Version(3, 1) ||
    521        (mExtensions.shaderPixelLocalStorageANGLE &&
    522         ShPixelLocalStorageTypeUsesImages(
    523             context->getImplementation()->getNativePixelLocalStorageType())))
    524    {
    525        mImageUnits.resize(mCaps.maxImageUnits);
    526    }
    527    if (clientVersion >= Version(3, 2) || mExtensions.textureCubeMapArrayAny())
    528    {
    529        mSamplerTextures[TextureType::CubeMapArray].resize(mCaps.maxCombinedTextureImageUnits);
    530    }
    531    if (clientVersion >= Version(3, 2) || mExtensions.textureBufferAny())
    532    {
    533        mSamplerTextures[TextureType::Buffer].resize(mCaps.maxCombinedTextureImageUnits);
    534    }
    535    if (nativeExtensions.textureRectangleANGLE)
    536    {
    537        mSamplerTextures[TextureType::Rectangle].resize(mCaps.maxCombinedTextureImageUnits);
    538    }
    539    if (nativeExtensions.EGLImageExternalOES || nativeExtensions.EGLStreamConsumerExternalNV)
    540    {
    541        mSamplerTextures[TextureType::External].resize(mCaps.maxCombinedTextureImageUnits);
    542    }
    543    if (nativeExtensions.videoTextureWEBGL)
    544    {
    545        mSamplerTextures[TextureType::VideoImage].resize(mCaps.maxCombinedTextureImageUnits);
    546    }
    547    mCompleteTextureBindings.reserve(mCaps.maxCombinedTextureImageUnits);
    548    for (int32_t textureIndex = 0; textureIndex < mCaps.maxCombinedTextureImageUnits;
    549         ++textureIndex)
    550    {
    551        mCompleteTextureBindings.emplace_back(context, textureIndex);
    552    }
    553 
    554    mSamplers.resize(mCaps.maxCombinedTextureImageUnits);
    555 
    556    for (QueryType type : angle::AllEnums<QueryType>())
    557    {
    558        mActiveQueries[type].set(context, nullptr);
    559    }
    560 
    561    mProgram    = nullptr;
    562    mExecutable = nullptr;
    563 
    564    mReadFramebuffer = nullptr;
    565    mDrawFramebuffer = nullptr;
    566 
    567    mPrimitiveRestart = false;
    568 
    569    mDebug.setMaxLoggedMessages(mCaps.maxDebugLoggedMessages);
    570 
    571    mMultiSampling    = true;
    572    mSampleAlphaToOne = false;
    573 
    574    mCoverageModulation = GL_NONE;
    575 
    576    mNoSimultaneousConstantColorAndAlphaBlendFunc =
    577        context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
    578        context->getExtensions().webglCompatibilityANGLE;
    579 
    580    mNoUnclampedBlendColor = context->getLimitations().noUnclampedBlendColor;
    581 
    582    // GLES1 emulation: Initialize state for GLES1 if version applies
    583    // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile
    584    if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API)
    585    {
    586        mGLES1State.initialize(context, this);
    587    }
    588 }
    589 
    590 void State::reset(const Context *context)
    591 {
    592    // Force a sync so clear doesn't end up dereferencing stale pointers.
    593    (void)syncActiveTextures(context, Command::Other);
    594    mActiveTexturesCache.clear();
    595 
    596    for (TextureBindingVector &bindingVec : mSamplerTextures)
    597    {
    598        for (BindingPointer<Texture> &texBinding : bindingVec)
    599        {
    600            texBinding.set(context, nullptr);
    601        }
    602    }
    603    for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
    604    {
    605        mSamplers[samplerIdx].set(context, nullptr);
    606    }
    607 
    608    for (ImageUnit &imageUnit : mImageUnits)
    609    {
    610        imageUnit.texture.set(context, nullptr);
    611        imageUnit.level   = 0;
    612        imageUnit.layered = false;
    613        imageUnit.layer   = 0;
    614        imageUnit.access  = GL_READ_ONLY;
    615        imageUnit.format  = GL_R32UI;
    616    }
    617 
    618    mRenderbuffer.set(context, nullptr);
    619 
    620    for (BufferBinding type : angle::AllEnums<BufferBinding>())
    621    {
    622        UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
    623    }
    624 
    625    if (mProgram)
    626    {
    627        mProgram->release(context);
    628    }
    629    mProgram = nullptr;
    630    mProgramPipeline.set(context, nullptr);
    631    mExecutable = nullptr;
    632 
    633    if (mTransformFeedback.get())
    634    {
    635        mTransformFeedback->onBindingChanged(context, false);
    636    }
    637    mTransformFeedback.set(context, nullptr);
    638 
    639    for (QueryType type : angle::AllEnums<QueryType>())
    640    {
    641        mActiveQueries[type].set(context, nullptr);
    642    }
    643 
    644    for (OffsetBindingPointer<Buffer> &buf : mUniformBuffers)
    645    {
    646        UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
    647    }
    648    mBoundUniformBuffersMask.reset();
    649 
    650    for (OffsetBindingPointer<Buffer> &buf : mAtomicCounterBuffers)
    651    {
    652        UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
    653    }
    654    mBoundAtomicCounterBuffersMask.reset();
    655 
    656    for (OffsetBindingPointer<Buffer> &buf : mShaderStorageBuffers)
    657    {
    658        UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
    659    }
    660    mBoundShaderStorageBuffersMask.reset();
    661 
    662    mClipDistancesEnabled.reset();
    663 
    664    setAllDirtyBits();
    665 }
    666 
    667 ANGLE_INLINE void State::unsetActiveTextures(const ActiveTextureMask &textureMask)
    668 {
    669    // Unset any relevant bound textures.
    670    for (size_t textureIndex : textureMask)
    671    {
    672        mActiveTexturesCache.reset(textureIndex);
    673        mCompleteTextureBindings[textureIndex].reset();
    674    }
    675 }
    676 
    677 ANGLE_INLINE void State::updateActiveTextureStateOnSync(const Context *context,
    678                                                        size_t textureIndex,
    679                                                        const Sampler *sampler,
    680                                                        Texture *texture)
    681 {
    682    if (!texture || !texture->isSamplerComplete(context, sampler))
    683    {
    684        mActiveTexturesCache.reset(textureIndex);
    685    }
    686    else
    687    {
    688        mActiveTexturesCache.set(textureIndex, texture);
    689    }
    690 
    691    mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
    692 }
    693 
    694 ANGLE_INLINE void State::setActiveTextureDirty(size_t textureIndex, Texture *texture)
    695 {
    696    mDirtyObjects.set(DIRTY_OBJECT_ACTIVE_TEXTURES);
    697    mDirtyActiveTextures.set(textureIndex);
    698 
    699    if (!texture)
    700    {
    701        return;
    702    }
    703 
    704    if (texture->hasAnyDirtyBit())
    705    {
    706        setTextureDirty(textureIndex);
    707    }
    708 
    709    if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit)
    710    {
    711        mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT);
    712    }
    713 
    714    // This cache is updated immediately because we use the cache in the validation layer.
    715    // If we defer the update until syncState it's too late and we've already passed validation.
    716    if (texture && mExecutable)
    717    {
    718        // It is invalid to try to sample a non-yuv texture with a yuv sampler.
    719        mTexturesIncompatibleWithSamplers[textureIndex] =
    720            mExecutable->getActiveYUVSamplers().test(textureIndex) && !texture->isYUV();
    721 
    722        if (isWebGL())
    723        {
    724            const Sampler *sampler = mSamplers[textureIndex].get();
    725            const SamplerState &samplerState =
    726                sampler ? sampler->getSamplerState() : texture->getSamplerState();
    727            if (!texture->getTextureState().compatibleWithSamplerFormatForWebGL(
    728                    mExecutable->getSamplerFormatForTextureUnitIndex(textureIndex), samplerState))
    729            {
    730                mTexturesIncompatibleWithSamplers[textureIndex] = true;
    731            }
    732        }
    733    }
    734    else
    735    {
    736        mTexturesIncompatibleWithSamplers[textureIndex] = false;
    737    }
    738 }
    739 
    740 ANGLE_INLINE void State::updateTextureBinding(const Context *context,
    741                                              size_t textureIndex,
    742                                              Texture *texture)
    743 {
    744    mCompleteTextureBindings[textureIndex].bind(texture);
    745    mActiveTexturesCache.reset(textureIndex);
    746    setActiveTextureDirty(textureIndex, texture);
    747 }
    748 
    749 ANGLE_INLINE bool State::hasConstantColor(GLenum sourceRGB, GLenum destRGB) const
    750 {
    751    return sourceRGB == GL_CONSTANT_COLOR || sourceRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
    752           destRGB == GL_CONSTANT_COLOR || destRGB == GL_ONE_MINUS_CONSTANT_COLOR;
    753 }
    754 
    755 ANGLE_INLINE bool State::hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const
    756 {
    757    return sourceRGB == GL_CONSTANT_ALPHA || sourceRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
    758           destRGB == GL_CONSTANT_ALPHA || destRGB == GL_ONE_MINUS_CONSTANT_ALPHA;
    759 }
    760 
    761 const RasterizerState &State::getRasterizerState() const
    762 {
    763    return mRasterizer;
    764 }
    765 
    766 const DepthStencilState &State::getDepthStencilState() const
    767 {
    768    return mDepthStencil;
    769 }
    770 
    771 void State::setColorClearValue(float red, float green, float blue, float alpha)
    772 {
    773    mColorClearValue.red   = red;
    774    mColorClearValue.green = green;
    775    mColorClearValue.blue  = blue;
    776    mColorClearValue.alpha = alpha;
    777    mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
    778 }
    779 
    780 void State::setDepthClearValue(float depth)
    781 {
    782    mDepthClearValue = depth;
    783    mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
    784 }
    785 
    786 void State::setStencilClearValue(int stencil)
    787 {
    788    mStencilClearValue = stencil;
    789    mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
    790 }
    791 
    792 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
    793 {
    794    mBlendState.colorMaskRed   = red;
    795    mBlendState.colorMaskGreen = green;
    796    mBlendState.colorMaskBlue  = blue;
    797    mBlendState.colorMaskAlpha = alpha;
    798 
    799    mBlendStateExt.setColorMask(red, green, blue, alpha);
    800    mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
    801 }
    802 
    803 void State::setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index)
    804 {
    805    mBlendStateExt.setColorMaskIndexed(index, red, green, blue, alpha);
    806    mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
    807 }
    808 
    809 bool State::allActiveDrawBufferChannelsMasked() const
    810 {
    811    // Compare current color mask with all-disabled color mask, while ignoring disabled draw
    812    // buffers.
    813    return (mBlendStateExt.compareColorMask(0) & mDrawFramebuffer->getDrawBufferMask()).none();
    814 }
    815 
    816 bool State::anyActiveDrawBufferChannelMasked() const
    817 {
    818    // Compare current color mask with all-enabled color mask, while ignoring disabled draw
    819    // buffers.
    820    return (mBlendStateExt.compareColorMask(mBlendStateExt.getAllColorMaskBits()) &
    821            mDrawFramebuffer->getDrawBufferMask())
    822        .any();
    823 }
    824 
    825 void State::setDepthMask(bool mask)
    826 {
    827    if (mDepthStencil.depthMask != mask)
    828    {
    829        mDepthStencil.depthMask = mask;
    830        mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
    831    }
    832 }
    833 
    834 void State::setRasterizerDiscard(bool enabled)
    835 {
    836    if (mRasterizer.rasterizerDiscard != enabled)
    837    {
    838        mRasterizer.rasterizerDiscard = enabled;
    839        mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
    840    }
    841 }
    842 
    843 void State::setCullFace(bool enabled)
    844 {
    845    if (mRasterizer.cullFace != enabled)
    846    {
    847        mRasterizer.cullFace = enabled;
    848        mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
    849    }
    850 }
    851 
    852 void State::setCullMode(CullFaceMode mode)
    853 {
    854    if (mRasterizer.cullMode != mode)
    855    {
    856        mRasterizer.cullMode = mode;
    857        mDirtyBits.set(DIRTY_BIT_CULL_FACE);
    858    }
    859 }
    860 
    861 void State::setFrontFace(GLenum front)
    862 {
    863    if (mRasterizer.frontFace != front)
    864    {
    865        mRasterizer.frontFace = front;
    866        mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
    867    }
    868 }
    869 
    870 void State::setDepthTest(bool enabled)
    871 {
    872    if (mDepthStencil.depthTest != enabled)
    873    {
    874        mDepthStencil.depthTest = enabled;
    875        mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
    876    }
    877 }
    878 
    879 void State::setDepthFunc(GLenum depthFunc)
    880 {
    881    if (mDepthStencil.depthFunc != depthFunc)
    882    {
    883        mDepthStencil.depthFunc = depthFunc;
    884        mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
    885    }
    886 }
    887 
    888 void State::setDepthRange(float zNear, float zFar)
    889 {
    890    if (mNearZ != zNear || mFarZ != zFar)
    891    {
    892        mNearZ = zNear;
    893        mFarZ  = zFar;
    894        mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
    895    }
    896 }
    897 
    898 void State::setClipControl(GLenum origin, GLenum depth)
    899 {
    900    bool updated = false;
    901    if (mClipControlOrigin != origin)
    902    {
    903        mClipControlOrigin = origin;
    904        updated            = true;
    905    }
    906 
    907    if (mClipControlDepth != depth)
    908    {
    909        mClipControlDepth = depth;
    910        updated           = true;
    911    }
    912 
    913    if (updated)
    914    {
    915        mDirtyBits.set(DIRTY_BIT_EXTENDED);
    916        mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_CONTROL);
    917    }
    918 }
    919 
    920 void State::setBlend(bool enabled)
    921 {
    922    if (mSetBlendIndexedInvoked || mBlendState.blend != enabled)
    923    {
    924        mBlendState.blend = enabled;
    925 
    926        mSetBlendIndexedInvoked = false;
    927        mBlendStateExt.setEnabled(enabled);
    928        mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
    929    }
    930 }
    931 
    932 void State::setBlendIndexed(bool enabled, GLuint index)
    933 {
    934    mSetBlendIndexedInvoked = true;
    935    mBlendStateExt.setEnabledIndexed(index, enabled);
    936    mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
    937 }
    938 
    939 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    940 {
    941    if (!mSetBlendFactorsIndexedInvoked && mBlendState.sourceBlendRGB == sourceRGB &&
    942        mBlendState.destBlendRGB == destRGB && mBlendState.sourceBlendAlpha == sourceAlpha &&
    943        mBlendState.destBlendAlpha == destAlpha)
    944    {
    945        return;
    946    }
    947 
    948    mBlendState.sourceBlendRGB   = sourceRGB;
    949    mBlendState.destBlendRGB     = destRGB;
    950    mBlendState.sourceBlendAlpha = sourceAlpha;
    951    mBlendState.destBlendAlpha   = destAlpha;
    952 
    953    if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
    954    {
    955        if (hasConstantColor(sourceRGB, destRGB))
    956        {
    957            mBlendFuncConstantColorDrawBuffers.set();
    958        }
    959        else
    960        {
    961            mBlendFuncConstantColorDrawBuffers.reset();
    962        }
    963 
    964        if (hasConstantAlpha(sourceRGB, destRGB))
    965        {
    966            mBlendFuncConstantAlphaDrawBuffers.set();
    967        }
    968        else
    969        {
    970            mBlendFuncConstantAlphaDrawBuffers.reset();
    971        }
    972    }
    973 
    974    mSetBlendFactorsIndexedInvoked = false;
    975    mBlendStateExt.setFactors(sourceRGB, destRGB, sourceAlpha, destAlpha);
    976    mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
    977 }
    978 
    979 void State::setBlendFactorsIndexed(GLenum sourceRGB,
    980                                   GLenum destRGB,
    981                                   GLenum sourceAlpha,
    982                                   GLenum destAlpha,
    983                                   GLuint index)
    984 {
    985    if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
    986    {
    987        mBlendFuncConstantColorDrawBuffers.set(index, hasConstantColor(sourceRGB, destRGB));
    988        mBlendFuncConstantAlphaDrawBuffers.set(index, hasConstantAlpha(sourceRGB, destRGB));
    989    }
    990 
    991    mSetBlendFactorsIndexedInvoked = true;
    992    mBlendStateExt.setFactorsIndexed(index, sourceRGB, destRGB, sourceAlpha, destAlpha);
    993    mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
    994 }
    995 
    996 void State::setBlendColor(float red, float green, float blue, float alpha)
    997 {
    998    // In ES2 without render-to-float extensions, BlendColor clamps to [0,1] on store.
    999    // On ES3+, or with render-to-float exts enabled, it does not clamp on store.
   1000    const bool isES2 = mClientVersion.major == 2;
   1001    const bool hasFloatBlending =
   1002        mExtensions.colorBufferFloatEXT || mExtensions.colorBufferHalfFloatEXT ||
   1003        mExtensions.colorBufferFloatRgbCHROMIUM || mExtensions.colorBufferFloatRgbaCHROMIUM;
   1004    if ((isES2 && !hasFloatBlending) || mNoUnclampedBlendColor)
   1005    {
   1006        red   = clamp01(red);
   1007        green = clamp01(green);
   1008        blue  = clamp01(blue);
   1009        alpha = clamp01(alpha);
   1010    }
   1011 
   1012    if (mBlendColor.red != red || mBlendColor.green != green || mBlendColor.blue != blue ||
   1013        mBlendColor.alpha != alpha)
   1014    {
   1015        mBlendColor.red   = red;
   1016        mBlendColor.green = green;
   1017        mBlendColor.blue  = blue;
   1018        mBlendColor.alpha = alpha;
   1019        mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
   1020    }
   1021 }
   1022 
   1023 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
   1024 {
   1025    if (mSetBlendEquationsIndexedInvoked || mBlendState.blendEquationRGB != rgbEquation ||
   1026        mBlendState.blendEquationAlpha != alphaEquation)
   1027    {
   1028        mBlendState.blendEquationRGB   = rgbEquation;
   1029        mBlendState.blendEquationAlpha = alphaEquation;
   1030 
   1031        mSetBlendEquationsIndexedInvoked = false;
   1032        mBlendStateExt.setEquations(rgbEquation, alphaEquation);
   1033        mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
   1034    }
   1035 }
   1036 
   1037 void State::setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index)
   1038 {
   1039    mSetBlendEquationsIndexedInvoked = true;
   1040    mBlendStateExt.setEquationsIndexed(index, rgbEquation, alphaEquation);
   1041    mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
   1042 }
   1043 
   1044 void State::setStencilTest(bool enabled)
   1045 {
   1046    if (mDepthStencil.stencilTest != enabled)
   1047    {
   1048        mDepthStencil.stencilTest = enabled;
   1049        mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
   1050    }
   1051 }
   1052 
   1053 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
   1054 {
   1055    if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef ||
   1056        mDepthStencil.stencilMask != stencilMask)
   1057    {
   1058        mDepthStencil.stencilFunc = stencilFunc;
   1059        mStencilRef               = stencilRef;
   1060        mDepthStencil.stencilMask = stencilMask;
   1061        mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
   1062    }
   1063 }
   1064 
   1065 void State::setStencilBackParams(GLenum stencilBackFunc,
   1066                                 GLint stencilBackRef,
   1067                                 GLuint stencilBackMask)
   1068 {
   1069    if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef ||
   1070        mDepthStencil.stencilBackMask != stencilBackMask)
   1071    {
   1072        mDepthStencil.stencilBackFunc = stencilBackFunc;
   1073        mStencilBackRef               = stencilBackRef;
   1074        mDepthStencil.stencilBackMask = stencilBackMask;
   1075        mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
   1076    }
   1077 }
   1078 
   1079 void State::setStencilWritemask(GLuint stencilWritemask)
   1080 {
   1081    if (mDepthStencil.stencilWritemask != stencilWritemask)
   1082    {
   1083        mDepthStencil.stencilWritemask = stencilWritemask;
   1084        mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
   1085    }
   1086 }
   1087 
   1088 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
   1089 {
   1090    if (mDepthStencil.stencilBackWritemask != stencilBackWritemask)
   1091    {
   1092        mDepthStencil.stencilBackWritemask = stencilBackWritemask;
   1093        mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
   1094    }
   1095 }
   1096 
   1097 void State::setStencilOperations(GLenum stencilFail,
   1098                                 GLenum stencilPassDepthFail,
   1099                                 GLenum stencilPassDepthPass)
   1100 {
   1101    if (mDepthStencil.stencilFail != stencilFail ||
   1102        mDepthStencil.stencilPassDepthFail != stencilPassDepthFail ||
   1103        mDepthStencil.stencilPassDepthPass != stencilPassDepthPass)
   1104    {
   1105        mDepthStencil.stencilFail          = stencilFail;
   1106        mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
   1107        mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
   1108        mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
   1109    }
   1110 }
   1111 
   1112 void State::setStencilBackOperations(GLenum stencilBackFail,
   1113                                     GLenum stencilBackPassDepthFail,
   1114                                     GLenum stencilBackPassDepthPass)
   1115 {
   1116    if (mDepthStencil.stencilBackFail != stencilBackFail ||
   1117        mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail ||
   1118        mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass)
   1119    {
   1120        mDepthStencil.stencilBackFail          = stencilBackFail;
   1121        mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
   1122        mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
   1123        mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
   1124    }
   1125 }
   1126 
   1127 void State::setPolygonOffsetFill(bool enabled)
   1128 {
   1129    if (mRasterizer.polygonOffsetFill != enabled)
   1130    {
   1131        mRasterizer.polygonOffsetFill = enabled;
   1132        mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
   1133    }
   1134 }
   1135 
   1136 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
   1137 {
   1138    // An application can pass NaN values here, so handle this gracefully
   1139    mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
   1140    mRasterizer.polygonOffsetUnits  = units != units ? 0.0f : units;
   1141    mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
   1142 }
   1143 
   1144 void State::setSampleAlphaToCoverage(bool enabled)
   1145 {
   1146    if (mSampleAlphaToCoverage != enabled)
   1147    {
   1148        mSampleAlphaToCoverage = enabled;
   1149        mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
   1150    }
   1151 }
   1152 
   1153 void State::setSampleCoverage(bool enabled)
   1154 {
   1155    if (mSampleCoverage != enabled)
   1156    {
   1157        mSampleCoverage = enabled;
   1158        mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
   1159    }
   1160 }
   1161 
   1162 void State::setSampleCoverageParams(GLclampf value, bool invert)
   1163 {
   1164    mSampleCoverageValue  = value;
   1165    mSampleCoverageInvert = invert;
   1166    mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
   1167 }
   1168 
   1169 void State::setSampleMaskEnabled(bool enabled)
   1170 {
   1171    if (mSampleMask != enabled)
   1172    {
   1173        mSampleMask = enabled;
   1174        mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
   1175    }
   1176 }
   1177 
   1178 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
   1179 {
   1180    ASSERT(maskNumber < mMaxSampleMaskWords);
   1181    mSampleMaskValues[maskNumber] = mask;
   1182    // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
   1183    mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
   1184 }
   1185 
   1186 void State::setSampleAlphaToOne(bool enabled)
   1187 {
   1188    if (mSampleAlphaToOne != enabled)
   1189    {
   1190        mSampleAlphaToOne = enabled;
   1191        mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
   1192    }
   1193 }
   1194 
   1195 void State::setMultisampling(bool enabled)
   1196 {
   1197    if (mMultiSampling != enabled)
   1198    {
   1199        mMultiSampling = enabled;
   1200        mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
   1201    }
   1202 }
   1203 
   1204 void State::setSampleShading(bool enabled)
   1205 {
   1206    if (mIsSampleShadingEnabled != enabled)
   1207    {
   1208        mIsSampleShadingEnabled = enabled;
   1209        mMinSampleShading       = (enabled) ? 1.0f : mMinSampleShading;
   1210        mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
   1211    }
   1212 }
   1213 
   1214 void State::setMinSampleShading(float value)
   1215 {
   1216    value = gl::clamp01(value);
   1217 
   1218    if (mMinSampleShading != value)
   1219    {
   1220        mMinSampleShading = value;
   1221        mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
   1222    }
   1223 }
   1224 
   1225 void State::setScissorTest(bool enabled)
   1226 {
   1227    if (mScissorTest != enabled)
   1228    {
   1229        mScissorTest = enabled;
   1230        mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
   1231    }
   1232 }
   1233 
   1234 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
   1235 {
   1236    // Skip if same scissor info
   1237    if (mScissor.x != x || mScissor.y != y || mScissor.width != width || mScissor.height != height)
   1238    {
   1239        mScissor.x      = x;
   1240        mScissor.y      = y;
   1241        mScissor.width  = width;
   1242        mScissor.height = height;
   1243        mDirtyBits.set(DIRTY_BIT_SCISSOR);
   1244    }
   1245 }
   1246 
   1247 void State::setDither(bool enabled)
   1248 {
   1249    if (mRasterizer.dither != enabled)
   1250    {
   1251        mRasterizer.dither = enabled;
   1252        mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
   1253    }
   1254 }
   1255 
   1256 void State::setPrimitiveRestart(bool enabled)
   1257 {
   1258    if (mPrimitiveRestart != enabled)
   1259    {
   1260        mPrimitiveRestart = enabled;
   1261        mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
   1262    }
   1263 }
   1264 
   1265 void State::setClipDistanceEnable(int idx, bool enable)
   1266 {
   1267    if (enable)
   1268    {
   1269        mClipDistancesEnabled.set(idx);
   1270    }
   1271    else
   1272    {
   1273        mClipDistancesEnabled.reset(idx);
   1274    }
   1275 
   1276    mDirtyBits.set(DIRTY_BIT_EXTENDED);
   1277    mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
   1278 }
   1279 
   1280 void State::setEnableFeature(GLenum feature, bool enabled)
   1281 {
   1282    switch (feature)
   1283    {
   1284        case GL_MULTISAMPLE_EXT:
   1285            setMultisampling(enabled);
   1286            return;
   1287        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   1288            setSampleAlphaToOne(enabled);
   1289            return;
   1290        case GL_CULL_FACE:
   1291            setCullFace(enabled);
   1292            return;
   1293        case GL_POLYGON_OFFSET_FILL:
   1294            setPolygonOffsetFill(enabled);
   1295            return;
   1296        case GL_SAMPLE_ALPHA_TO_COVERAGE:
   1297            setSampleAlphaToCoverage(enabled);
   1298            return;
   1299        case GL_SAMPLE_COVERAGE:
   1300            setSampleCoverage(enabled);
   1301            return;
   1302        case GL_SCISSOR_TEST:
   1303            setScissorTest(enabled);
   1304            return;
   1305        case GL_STENCIL_TEST:
   1306            setStencilTest(enabled);
   1307            return;
   1308        case GL_DEPTH_TEST:
   1309            setDepthTest(enabled);
   1310            return;
   1311        case GL_BLEND:
   1312            setBlend(enabled);
   1313            return;
   1314        case GL_DITHER:
   1315            setDither(enabled);
   1316            return;
   1317        case GL_COLOR_LOGIC_OP:
   1318            if (mClientVersion.major == 1)
   1319            {
   1320                // Handle logicOp in GLES1 through the GLES1 state management and emulation.
   1321                // Otherwise this state could be set as part of ANGLE_logic_op.
   1322                break;
   1323            }
   1324            setLogicOpEnabled(enabled);
   1325            return;
   1326        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   1327            setPrimitiveRestart(enabled);
   1328            return;
   1329        case GL_RASTERIZER_DISCARD:
   1330            setRasterizerDiscard(enabled);
   1331            return;
   1332        case GL_SAMPLE_MASK:
   1333            setSampleMaskEnabled(enabled);
   1334            return;
   1335        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
   1336            mDebug.setOutputSynchronous(enabled);
   1337            return;
   1338        case GL_DEBUG_OUTPUT:
   1339            mDebug.setOutputEnabled(enabled);
   1340            return;
   1341        case GL_FRAMEBUFFER_SRGB_EXT:
   1342            setFramebufferSRGB(enabled);
   1343            return;
   1344        case GL_TEXTURE_RECTANGLE_ANGLE:
   1345            mTextureRectangleEnabled = enabled;
   1346            return;
   1347        case GL_SAMPLE_SHADING:
   1348            setSampleShading(enabled);
   1349            return;
   1350        // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
   1351        case GL_CLIP_DISTANCE0_EXT:
   1352        case GL_CLIP_DISTANCE1_EXT:
   1353        case GL_CLIP_DISTANCE2_EXT:
   1354        case GL_CLIP_DISTANCE3_EXT:
   1355        case GL_CLIP_DISTANCE4_EXT:
   1356        case GL_CLIP_DISTANCE5_EXT:
   1357        case GL_CLIP_DISTANCE6_EXT:
   1358        case GL_CLIP_DISTANCE7_EXT:
   1359            // NOTE(hqle): These enums are conflicted with GLES1's enums, need
   1360            // to do additional check here:
   1361            if (mClientVersion.major >= 2)
   1362            {
   1363                setClipDistanceEnable(feature - GL_CLIP_DISTANCE0_EXT, enabled);
   1364                return;
   1365            }
   1366            break;
   1367        case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
   1368            mShadingRatePreserveAspectRatio = enabled;
   1369            return;
   1370    }
   1371 
   1372    ASSERT(mClientVersion.major == 1);
   1373 
   1374    // GLES1 emulation. Need to separate from main switch due to conflict enum between
   1375    // GL_CLIP_DISTANCE0_EXT & GL_CLIP_PLANE0
   1376    switch (feature)
   1377    {
   1378        case GL_ALPHA_TEST:
   1379            mGLES1State.mAlphaTestEnabled = enabled;
   1380            break;
   1381        case GL_TEXTURE_2D:
   1382            mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled);
   1383            break;
   1384        case GL_TEXTURE_CUBE_MAP:
   1385            mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled);
   1386            break;
   1387        case GL_LIGHTING:
   1388            mGLES1State.mLightingEnabled = enabled;
   1389            break;
   1390        case GL_LIGHT0:
   1391        case GL_LIGHT1:
   1392        case GL_LIGHT2:
   1393        case GL_LIGHT3:
   1394        case GL_LIGHT4:
   1395        case GL_LIGHT5:
   1396        case GL_LIGHT6:
   1397        case GL_LIGHT7:
   1398            mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled;
   1399            break;
   1400        case GL_NORMALIZE:
   1401            mGLES1State.mNormalizeEnabled = enabled;
   1402            break;
   1403        case GL_RESCALE_NORMAL:
   1404            mGLES1State.mRescaleNormalEnabled = enabled;
   1405            break;
   1406        case GL_COLOR_MATERIAL:
   1407            mGLES1State.mColorMaterialEnabled = enabled;
   1408            break;
   1409        case GL_CLIP_PLANE0:
   1410        case GL_CLIP_PLANE1:
   1411        case GL_CLIP_PLANE2:
   1412        case GL_CLIP_PLANE3:
   1413        case GL_CLIP_PLANE4:
   1414        case GL_CLIP_PLANE5:
   1415            mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
   1416            break;
   1417        case GL_FOG:
   1418            mGLES1State.mFogEnabled = enabled;
   1419            break;
   1420        case GL_POINT_SMOOTH:
   1421            mGLES1State.mPointSmoothEnabled = enabled;
   1422            break;
   1423        case GL_LINE_SMOOTH:
   1424            mGLES1State.mLineSmoothEnabled = enabled;
   1425            break;
   1426        case GL_POINT_SPRITE_OES:
   1427            mGLES1State.mPointSpriteEnabled = enabled;
   1428            break;
   1429        case GL_COLOR_LOGIC_OP:
   1430            mGLES1State.setLogicOpEnabled(enabled);
   1431            break;
   1432        default:
   1433            UNREACHABLE();
   1434    }
   1435 }
   1436 
   1437 void State::setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index)
   1438 {
   1439    switch (feature)
   1440    {
   1441        case GL_BLEND:
   1442            setBlendIndexed(enabled, index);
   1443            break;
   1444        default:
   1445            UNREACHABLE();
   1446    }
   1447 }
   1448 
   1449 bool State::getEnableFeature(GLenum feature) const
   1450 {
   1451    switch (feature)
   1452    {
   1453        case GL_MULTISAMPLE_EXT:
   1454            return isMultisamplingEnabled();
   1455        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   1456            return isSampleAlphaToOneEnabled();
   1457        case GL_CULL_FACE:
   1458            return isCullFaceEnabled();
   1459        case GL_POLYGON_OFFSET_FILL:
   1460            return isPolygonOffsetFillEnabled();
   1461        case GL_SAMPLE_ALPHA_TO_COVERAGE:
   1462            return isSampleAlphaToCoverageEnabled();
   1463        case GL_SAMPLE_COVERAGE:
   1464            return isSampleCoverageEnabled();
   1465        case GL_SCISSOR_TEST:
   1466            return isScissorTestEnabled();
   1467        case GL_STENCIL_TEST:
   1468            return isStencilTestEnabled();
   1469        case GL_DEPTH_TEST:
   1470            return isDepthTestEnabled();
   1471        case GL_BLEND:
   1472            return isBlendEnabled();
   1473        case GL_DITHER:
   1474            return isDitherEnabled();
   1475        case GL_COLOR_LOGIC_OP:
   1476            if (mClientVersion.major == 1)
   1477            {
   1478                // Handle logicOp in GLES1 through the GLES1 state management and emulation.
   1479                break;
   1480            }
   1481            return isLogicOpEnabled();
   1482        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   1483            return isPrimitiveRestartEnabled();
   1484        case GL_RASTERIZER_DISCARD:
   1485            return isRasterizerDiscardEnabled();
   1486        case GL_SAMPLE_MASK:
   1487            return isSampleMaskEnabled();
   1488        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
   1489            return mDebug.isOutputSynchronous();
   1490        case GL_DEBUG_OUTPUT:
   1491            return mDebug.isOutputEnabled();
   1492        case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
   1493            return isBindGeneratesResourceEnabled();
   1494        case GL_CLIENT_ARRAYS_ANGLE:
   1495            return areClientArraysEnabled();
   1496        case GL_FRAMEBUFFER_SRGB_EXT:
   1497            return getFramebufferSRGB();
   1498        case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
   1499            return mRobustResourceInit;
   1500        case GL_PROGRAM_CACHE_ENABLED_ANGLE:
   1501            return mProgramBinaryCacheEnabled;
   1502        case GL_TEXTURE_RECTANGLE_ANGLE:
   1503            return mTextureRectangleEnabled;
   1504        case GL_SAMPLE_SHADING:
   1505            return isSampleShadingEnabled();
   1506        // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
   1507        case GL_CLIP_DISTANCE0_EXT:
   1508        case GL_CLIP_DISTANCE1_EXT:
   1509        case GL_CLIP_DISTANCE2_EXT:
   1510        case GL_CLIP_DISTANCE3_EXT:
   1511        case GL_CLIP_DISTANCE4_EXT:
   1512        case GL_CLIP_DISTANCE5_EXT:
   1513        case GL_CLIP_DISTANCE6_EXT:
   1514        case GL_CLIP_DISTANCE7_EXT:
   1515            if (mClientVersion.major >= 2)
   1516            {
   1517                // If GLES version is 1, the GL_CLIP_DISTANCE0_EXT enum will be used as
   1518                // GL_CLIP_PLANE0 instead.
   1519                return mClipDistancesEnabled.test(feature - GL_CLIP_DISTANCE0_EXT);
   1520            }
   1521            break;
   1522        case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
   1523            return mShadingRatePreserveAspectRatio;
   1524    }
   1525 
   1526    ASSERT(mClientVersion.major == 1);
   1527 
   1528    switch (feature)
   1529    {
   1530        // GLES1 emulation
   1531        case GL_ALPHA_TEST:
   1532            return mGLES1State.mAlphaTestEnabled;
   1533        case GL_VERTEX_ARRAY:
   1534            return mGLES1State.mVertexArrayEnabled;
   1535        case GL_NORMAL_ARRAY:
   1536            return mGLES1State.mNormalArrayEnabled;
   1537        case GL_COLOR_ARRAY:
   1538            return mGLES1State.mColorArrayEnabled;
   1539        case GL_POINT_SIZE_ARRAY_OES:
   1540            return mGLES1State.mPointSizeArrayEnabled;
   1541        case GL_TEXTURE_COORD_ARRAY:
   1542            return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture];
   1543        case GL_TEXTURE_2D:
   1544            return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::_2D);
   1545        case GL_TEXTURE_CUBE_MAP:
   1546            return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::CubeMap);
   1547        case GL_LIGHTING:
   1548            return mGLES1State.mLightingEnabled;
   1549        case GL_LIGHT0:
   1550        case GL_LIGHT1:
   1551        case GL_LIGHT2:
   1552        case GL_LIGHT3:
   1553        case GL_LIGHT4:
   1554        case GL_LIGHT5:
   1555        case GL_LIGHT6:
   1556        case GL_LIGHT7:
   1557            return mGLES1State.mLights[feature - GL_LIGHT0].enabled;
   1558        case GL_NORMALIZE:
   1559            return mGLES1State.mNormalizeEnabled;
   1560        case GL_RESCALE_NORMAL:
   1561            return mGLES1State.mRescaleNormalEnabled;
   1562        case GL_COLOR_MATERIAL:
   1563            return mGLES1State.mColorMaterialEnabled;
   1564        case GL_CLIP_PLANE0:
   1565        case GL_CLIP_PLANE1:
   1566        case GL_CLIP_PLANE2:
   1567        case GL_CLIP_PLANE3:
   1568        case GL_CLIP_PLANE4:
   1569        case GL_CLIP_PLANE5:
   1570            return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
   1571        case GL_FOG:
   1572            return mGLES1State.mFogEnabled;
   1573        case GL_POINT_SMOOTH:
   1574            return mGLES1State.mPointSmoothEnabled;
   1575        case GL_LINE_SMOOTH:
   1576            return mGLES1State.mLineSmoothEnabled;
   1577        case GL_POINT_SPRITE_OES:
   1578            return mGLES1State.mPointSpriteEnabled;
   1579        case GL_COLOR_LOGIC_OP:
   1580            return mGLES1State.mLogicOpEnabled;
   1581        default:
   1582            UNREACHABLE();
   1583            return false;
   1584    }
   1585 }
   1586 
   1587 bool State::getEnableFeatureIndexed(GLenum feature, GLuint index) const
   1588 {
   1589    switch (feature)
   1590    {
   1591        case GL_BLEND:
   1592            return isBlendEnabledIndexed(index);
   1593        default:
   1594            UNREACHABLE();
   1595            return false;
   1596    }
   1597 }
   1598 
   1599 void State::setLineWidth(GLfloat width)
   1600 {
   1601    mLineWidth = width;
   1602    mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
   1603 }
   1604 
   1605 void State::setGenerateMipmapHint(GLenum hint)
   1606 {
   1607    mGenerateMipmapHint = hint;
   1608    mDirtyBits.set(DIRTY_BIT_EXTENDED);
   1609    mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT);
   1610 }
   1611 
   1612 GLenum State::getGenerateMipmapHint() const
   1613 {
   1614    return mGenerateMipmapHint;
   1615 }
   1616 
   1617 void State::setTextureFilteringHint(GLenum hint)
   1618 {
   1619    mTextureFilteringHint = hint;
   1620    // Note: we don't add a dirty bit for this flag as it's not expected to be toggled at
   1621    // runtime.
   1622 }
   1623 
   1624 GLenum State::getTextureFilteringHint() const
   1625 {
   1626    return mTextureFilteringHint;
   1627 }
   1628 
   1629 void State::setFragmentShaderDerivativeHint(GLenum hint)
   1630 {
   1631    mFragmentShaderDerivativeHint = hint;
   1632    mDirtyBits.set(DIRTY_BIT_EXTENDED);
   1633    mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT);
   1634    // TODO: Propagate the hint to shader translator so we can write
   1635    // ddx, ddx_coarse, or ddx_fine depending on the hint.
   1636    // Ignore for now. It is valid for implementations to ignore hint.
   1637 }
   1638 
   1639 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
   1640 {
   1641    // [OpenGL ES 2.0.25] section 2.12.1 page 45:
   1642    // Viewport width and height are clamped to implementation-dependent maximums when specified.
   1643    width  = std::min(width, mCaps.maxViewportWidth);
   1644    height = std::min(height, mCaps.maxViewportHeight);
   1645 
   1646    // Skip if same viewport info
   1647    if (mViewport.x != x || mViewport.y != y || mViewport.width != width ||
   1648        mViewport.height != height)
   1649    {
   1650        mViewport.x      = x;
   1651        mViewport.y      = y;
   1652        mViewport.width  = width;
   1653        mViewport.height = height;
   1654        mDirtyBits.set(DIRTY_BIT_VIEWPORT);
   1655    }
   1656 }
   1657 
   1658 void State::setActiveSampler(unsigned int active)
   1659 {
   1660    mActiveSampler = active;
   1661 }
   1662 
   1663 void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
   1664 {
   1665    if (mExecutable && mExecutable->getActiveSamplersMask()[mActiveSampler] &&
   1666        IsTextureCompatibleWithSampler(type, mExecutable->getActiveSamplerTypes()[mActiveSampler]))
   1667    {
   1668        updateTextureBinding(context, mActiveSampler, texture);
   1669    }
   1670 
   1671    mSamplerTextures[type][mActiveSampler].set(context, texture);
   1672 
   1673    mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
   1674 }
   1675 
   1676 Texture *State::getTargetTexture(TextureType type) const
   1677 {
   1678    return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
   1679 }
   1680 
   1681 TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) const
   1682 {
   1683    ASSERT(sampler < mSamplerTextures[type].size());
   1684    return mSamplerTextures[type][sampler].id();
   1685 }
   1686 
   1687 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
   1688 {
   1689    // Textures have a detach method on State rather than a simple
   1690    // removeBinding, because the zero/null texture objects are managed
   1691    // separately, and don't have to go through the Context's maps or
   1692    // the ResourceManager.
   1693 
   1694    // [OpenGL ES 2.0.24] section 3.8 page 84:
   1695    // If a texture object is deleted, it is as if all texture units which are bound to that texture
   1696    // object are rebound to texture object zero
   1697 
   1698    for (TextureType type : angle::AllEnums<TextureType>())
   1699    {
   1700        TextureBindingVector &textureVector = mSamplerTextures[type];
   1701 
   1702        for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
   1703        {
   1704            BindingPointer<Texture> &binding = textureVector[bindingIndex];
   1705            if (binding.id() == texture)
   1706            {
   1707                // Zero textures are the "default" textures instead of NULL
   1708                Texture *zeroTexture = zeroTextures[type].get();
   1709                ASSERT(zeroTexture != nullptr);
   1710                if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get())
   1711                {
   1712                    updateTextureBinding(context, bindingIndex, zeroTexture);
   1713                }
   1714                binding.set(context, zeroTexture);
   1715            }
   1716        }
   1717    }
   1718 
   1719    for (auto &bindingImageUnit : mImageUnits)
   1720    {
   1721        if (bindingImageUnit.texture.id() == texture)
   1722        {
   1723            bindingImageUnit.texture.set(context, nullptr);
   1724            bindingImageUnit.level   = 0;
   1725            bindingImageUnit.layered = false;
   1726            bindingImageUnit.layer   = 0;
   1727            bindingImageUnit.access  = GL_READ_ONLY;
   1728            bindingImageUnit.format  = GL_R32UI;
   1729        }
   1730    }
   1731 
   1732    // [OpenGL ES 2.0.24] section 4.4 page 112:
   1733    // If a texture object is deleted while its image is attached to the currently bound
   1734    // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
   1735    // each attachment point to which this image was attached in the currently bound framebuffer.
   1736 
   1737    if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
   1738    {
   1739        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   1740    }
   1741 
   1742    if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
   1743    {
   1744        setDrawFramebufferDirty();
   1745    }
   1746 }
   1747 
   1748 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
   1749 {
   1750    for (TextureType type : angle::AllEnums<TextureType>())
   1751    {
   1752        for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
   1753        {
   1754            mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
   1755        }
   1756    }
   1757 }
   1758 
   1759 void State::invalidateTextureBindings(TextureType type)
   1760 {
   1761    mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
   1762 }
   1763 
   1764 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
   1765 {
   1766    if (mSamplers[textureUnit].get() == sampler)
   1767    {
   1768        return;
   1769    }
   1770 
   1771    mSamplers[textureUnit].set(context, sampler);
   1772    mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
   1773    // This is overly conservative as it assumes the sampler has never been bound.
   1774    setSamplerDirty(textureUnit);
   1775    onActiveTextureChange(context, textureUnit);
   1776 }
   1777 
   1778 void State::detachSampler(const Context *context, SamplerID sampler)
   1779 {
   1780    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
   1781    // If a sampler object that is currently bound to one or more texture units is
   1782    // deleted, it is as though BindSampler is called once for each texture unit to
   1783    // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
   1784    for (size_t i = 0; i < mSamplers.size(); i++)
   1785    {
   1786        if (mSamplers[i].id() == sampler)
   1787        {
   1788            setSamplerBinding(context, static_cast<GLuint>(i), nullptr);
   1789        }
   1790    }
   1791 }
   1792 
   1793 void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
   1794 {
   1795    mRenderbuffer.set(context, renderbuffer);
   1796    mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
   1797 }
   1798 
   1799 void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
   1800 {
   1801    // [OpenGL ES 2.0.24] section 4.4 page 109:
   1802    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
   1803    // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
   1804 
   1805    if (mRenderbuffer.id() == renderbuffer)
   1806    {
   1807        setRenderbufferBinding(context, nullptr);
   1808    }
   1809 
   1810    // [OpenGL ES 2.0.24] section 4.4 page 111:
   1811    // If a renderbuffer object is deleted while its image is attached to the currently bound
   1812    // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
   1813    // 0, for each attachment point to which this image was attached in the currently bound
   1814    // framebuffer.
   1815 
   1816    Framebuffer *readFramebuffer = mReadFramebuffer;
   1817    Framebuffer *drawFramebuffer = mDrawFramebuffer;
   1818 
   1819    if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
   1820    {
   1821        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   1822    }
   1823 
   1824    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
   1825    {
   1826        if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
   1827        {
   1828            setDrawFramebufferDirty();
   1829        }
   1830    }
   1831 }
   1832 
   1833 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
   1834 {
   1835    if (mReadFramebuffer == framebuffer)
   1836        return;
   1837 
   1838    mReadFramebuffer = framebuffer;
   1839    mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
   1840 
   1841    if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
   1842    {
   1843        mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   1844    }
   1845 }
   1846 
   1847 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
   1848 {
   1849    if (mDrawFramebuffer == framebuffer)
   1850        return;
   1851 
   1852    mDrawFramebuffer = framebuffer;
   1853    mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
   1854 
   1855    if (mDrawFramebuffer)
   1856    {
   1857        mDrawFramebuffer->setWriteControlMode(getFramebufferSRGB() ? SrgbWriteControlMode::Default
   1858                                                                   : SrgbWriteControlMode::Linear);
   1859 
   1860        if (mDrawFramebuffer->hasAnyDirtyBit())
   1861        {
   1862            mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
   1863        }
   1864 
   1865        if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit())
   1866        {
   1867            mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
   1868        }
   1869    }
   1870 }
   1871 
   1872 Framebuffer *State::getTargetFramebuffer(GLenum target) const
   1873 {
   1874    switch (target)
   1875    {
   1876        case GL_READ_FRAMEBUFFER_ANGLE:
   1877            return mReadFramebuffer;
   1878        case GL_DRAW_FRAMEBUFFER_ANGLE:
   1879        case GL_FRAMEBUFFER:
   1880            return mDrawFramebuffer;
   1881        default:
   1882            UNREACHABLE();
   1883            return nullptr;
   1884    }
   1885 }
   1886 
   1887 Framebuffer *State::getDefaultFramebuffer() const
   1888 {
   1889    return mFramebufferManager->getDefaultFramebuffer();
   1890 }
   1891 
   1892 bool State::removeReadFramebufferBinding(FramebufferID framebuffer)
   1893 {
   1894    if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
   1895    {
   1896        setReadFramebufferBinding(nullptr);
   1897        return true;
   1898    }
   1899 
   1900    return false;
   1901 }
   1902 
   1903 bool State::removeDrawFramebufferBinding(FramebufferID framebuffer)
   1904 {
   1905    if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
   1906    {
   1907        setDrawFramebufferBinding(nullptr);
   1908        return true;
   1909    }
   1910 
   1911    return false;
   1912 }
   1913 
   1914 void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray)
   1915 {
   1916    if (mVertexArray == vertexArray)
   1917    {
   1918        return;
   1919    }
   1920 
   1921    if (mVertexArray)
   1922    {
   1923        mVertexArray->onBindingChanged(context, -1);
   1924    }
   1925    if (vertexArray)
   1926    {
   1927        vertexArray->onBindingChanged(context, 1);
   1928    }
   1929 
   1930    mVertexArray = vertexArray;
   1931    mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
   1932 
   1933    if (mVertexArray && mVertexArray->hasAnyDirtyBit())
   1934    {
   1935        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   1936    }
   1937 }
   1938 
   1939 bool State::removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray)
   1940 {
   1941    if (mVertexArray && mVertexArray->id().value == vertexArray.value)
   1942    {
   1943        mVertexArray->onBindingChanged(context, -1);
   1944        mVertexArray = nullptr;
   1945        mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
   1946        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   1947        return true;
   1948    }
   1949 
   1950    return false;
   1951 }
   1952 
   1953 VertexArrayID State::getVertexArrayId() const
   1954 {
   1955    ASSERT(mVertexArray != nullptr);
   1956    return mVertexArray->id();
   1957 }
   1958 
   1959 void State::bindVertexBuffer(const Context *context,
   1960                             GLuint bindingIndex,
   1961                             Buffer *boundBuffer,
   1962                             GLintptr offset,
   1963                             GLsizei stride)
   1964 {
   1965    getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
   1966    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   1967 }
   1968 
   1969 void State::setVertexAttribFormat(GLuint attribIndex,
   1970                                  GLint size,
   1971                                  VertexAttribType type,
   1972                                  bool normalized,
   1973                                  bool pureInteger,
   1974                                  GLuint relativeOffset)
   1975 {
   1976    getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
   1977                                            relativeOffset);
   1978    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   1979 }
   1980 
   1981 void State::setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
   1982 {
   1983    getVertexArray()->setVertexBindingDivisor(context, bindingIndex, divisor);
   1984    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   1985 }
   1986 
   1987 angle::Result State::setProgram(const Context *context, Program *newProgram)
   1988 {
   1989    if (newProgram && !newProgram->isLinked())
   1990    {
   1991        // Protect against applications that disable validation and try to use a program that was
   1992        // not successfully linked.
   1993        WARN() << "Attempted to use a program that was not successfully linked";
   1994        return angle::Result::Continue;
   1995    }
   1996 
   1997    if (mProgram != newProgram)
   1998    {
   1999        if (mProgram)
   2000        {
   2001            unsetActiveTextures(mExecutable->getActiveSamplersMask());
   2002            mProgram->release(context);
   2003        }
   2004 
   2005        mProgram    = newProgram;
   2006        mExecutable = nullptr;
   2007 
   2008        if (mProgram)
   2009        {
   2010            mExecutable = &mProgram->getExecutable();
   2011            newProgram->addRef();
   2012            ANGLE_TRY(onProgramExecutableChange(context, newProgram));
   2013        }
   2014        else if (mProgramPipeline.get())
   2015        {
   2016            mExecutable = &mProgramPipeline->getExecutable();
   2017            ANGLE_TRY(onProgramPipelineExecutableChange(context));
   2018        }
   2019 
   2020        // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate
   2021        // an error if the app tries to draw in this case.
   2022 
   2023        mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
   2024    }
   2025 
   2026    return angle::Result::Continue;
   2027 }
   2028 
   2029 void State::setTransformFeedbackBinding(const Context *context,
   2030                                        TransformFeedback *transformFeedback)
   2031 {
   2032    if (transformFeedback == mTransformFeedback.get())
   2033        return;
   2034    if (mTransformFeedback.get())
   2035        mTransformFeedback->onBindingChanged(context, false);
   2036    mTransformFeedback.set(context, transformFeedback);
   2037    if (mTransformFeedback.get())
   2038        mTransformFeedback->onBindingChanged(context, true);
   2039    mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
   2040 }
   2041 
   2042 bool State::removeTransformFeedbackBinding(const Context *context,
   2043                                           TransformFeedbackID transformFeedback)
   2044 {
   2045    if (mTransformFeedback.id() == transformFeedback)
   2046    {
   2047        if (mTransformFeedback.get())
   2048            mTransformFeedback->onBindingChanged(context, false);
   2049        mTransformFeedback.set(context, nullptr);
   2050        return true;
   2051    }
   2052 
   2053    return false;
   2054 }
   2055 
   2056 angle::Result State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
   2057 {
   2058    if (mProgramPipeline.get() == pipeline)
   2059    {
   2060        return angle::Result::Continue;
   2061    }
   2062 
   2063    if (mProgramPipeline.get())
   2064    {
   2065        unsetActiveTextures(mProgramPipeline->getExecutable().getActiveSamplersMask());
   2066    }
   2067 
   2068    mProgramPipeline.set(context, pipeline);
   2069    mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
   2070 
   2071    // A bound Program always overrides the ProgramPipeline, so only update the
   2072    // current ProgramExecutable if there isn't currently a Program bound.
   2073    if (!mProgram)
   2074    {
   2075        if (mProgramPipeline.get())
   2076        {
   2077            mExecutable = &mProgramPipeline->getExecutable();
   2078            ANGLE_TRY(onProgramPipelineExecutableChange(context));
   2079        }
   2080        else
   2081        {
   2082            mExecutable = nullptr;
   2083        }
   2084    }
   2085 
   2086    return angle::Result::Continue;
   2087 }
   2088 
   2089 void State::detachProgramPipeline(const Context *context, ProgramPipelineID pipeline)
   2090 {
   2091    mProgramPipeline.set(context, nullptr);
   2092 
   2093    // A bound Program always overrides the ProgramPipeline, so only update the
   2094    // current ProgramExecutable if there isn't currently a Program bound.
   2095    if (!mProgram)
   2096    {
   2097        mExecutable = nullptr;
   2098    }
   2099 }
   2100 
   2101 bool State::isQueryActive(QueryType type) const
   2102 {
   2103    const Query *query = mActiveQueries[type].get();
   2104    if (query != nullptr)
   2105    {
   2106        return true;
   2107    }
   2108 
   2109    QueryType alternativeType;
   2110    if (GetAlternativeQueryType(type, &alternativeType))
   2111    {
   2112        query = mActiveQueries[alternativeType].get();
   2113        return query != nullptr;
   2114    }
   2115 
   2116    return false;
   2117 }
   2118 
   2119 bool State::isQueryActive(Query *query) const
   2120 {
   2121    for (auto &queryPointer : mActiveQueries)
   2122    {
   2123        if (queryPointer.get() == query)
   2124        {
   2125            return true;
   2126        }
   2127    }
   2128 
   2129    return false;
   2130 }
   2131 
   2132 void State::setActiveQuery(const Context *context, QueryType type, Query *query)
   2133 {
   2134    mActiveQueries[type].set(context, query);
   2135 }
   2136 
   2137 QueryID State::getActiveQueryId(QueryType type) const
   2138 {
   2139    const Query *query = getActiveQuery(type);
   2140    if (query)
   2141    {
   2142        return query->id();
   2143    }
   2144    return {0};
   2145 }
   2146 
   2147 Query *State::getActiveQuery(QueryType type) const
   2148 {
   2149    return mActiveQueries[type].get();
   2150 }
   2151 
   2152 angle::Result State::setIndexedBufferBinding(const Context *context,
   2153                                             BufferBinding target,
   2154                                             GLuint index,
   2155                                             Buffer *buffer,
   2156                                             GLintptr offset,
   2157                                             GLsizeiptr size)
   2158 {
   2159    setBufferBinding(context, target, buffer);
   2160 
   2161    switch (target)
   2162    {
   2163        case BufferBinding::TransformFeedback:
   2164            ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size));
   2165            setBufferBinding(context, target, buffer);
   2166            break;
   2167        case BufferBinding::Uniform:
   2168            mBoundUniformBuffersMask.set(index, buffer != nullptr);
   2169            UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
   2170                                       size);
   2171            break;
   2172        case BufferBinding::AtomicCounter:
   2173            mBoundAtomicCounterBuffersMask.set(index, buffer != nullptr);
   2174            UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
   2175                                       offset, size);
   2176            break;
   2177        case BufferBinding::ShaderStorage:
   2178            mBoundShaderStorageBuffersMask.set(index, buffer != nullptr);
   2179            UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
   2180                                       offset, size);
   2181            break;
   2182        default:
   2183            UNREACHABLE();
   2184            break;
   2185    }
   2186 
   2187    return angle::Result::Continue;
   2188 }
   2189 
   2190 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
   2191 {
   2192    ASSERT(index < mUniformBuffers.size());
   2193    return mUniformBuffers[index];
   2194 }
   2195 
   2196 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
   2197 {
   2198    ASSERT(index < mAtomicCounterBuffers.size());
   2199    return mAtomicCounterBuffers[index];
   2200 }
   2201 
   2202 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
   2203 {
   2204    ASSERT(index < mShaderStorageBuffers.size());
   2205    return mShaderStorageBuffers[index];
   2206 }
   2207 
   2208 angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
   2209 {
   2210    BufferID bufferID = buffer->id();
   2211    for (gl::BufferBinding target : angle::AllEnums<BufferBinding>())
   2212    {
   2213        if (mBoundBuffers[target].id() == bufferID)
   2214        {
   2215            UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
   2216        }
   2217    }
   2218 
   2219    TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
   2220    if (curTransformFeedback)
   2221    {
   2222        ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
   2223        context->getStateCache().onActiveTransformFeedbackChange(context);
   2224    }
   2225 
   2226    if (getVertexArray()->detachBuffer(context, bufferID))
   2227    {
   2228        mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   2229        context->getStateCache().onVertexArrayStateChange(context);
   2230    }
   2231 
   2232    for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
   2233    {
   2234        OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
   2235 
   2236        if (binding.id() == bufferID)
   2237        {
   2238            UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
   2239            mBoundUniformBuffersMask.reset(uniformBufferIndex);
   2240        }
   2241    }
   2242 
   2243    for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
   2244    {
   2245        OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
   2246 
   2247        if (binding.id() == bufferID)
   2248        {
   2249            UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
   2250                                       0);
   2251            mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
   2252        }
   2253    }
   2254 
   2255    for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
   2256    {
   2257        OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
   2258 
   2259        if (binding.id() == bufferID)
   2260        {
   2261            UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
   2262                                       0);
   2263            mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
   2264        }
   2265    }
   2266 
   2267    return angle::Result::Continue;
   2268 }
   2269 
   2270 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
   2271 {
   2272    getVertexArray()->enableAttribute(attribNum, enabled);
   2273    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   2274 }
   2275 
   2276 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
   2277 {
   2278    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
   2279    mVertexAttribCurrentValues[index].setFloatValues(values);
   2280    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
   2281    mDirtyCurrentValues.set(index);
   2282    SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
   2283 }
   2284 
   2285 void State::setVertexAttribu(GLuint index, const GLuint values[4])
   2286 {
   2287    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
   2288    mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
   2289    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
   2290    mDirtyCurrentValues.set(index);
   2291    SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
   2292 }
   2293 
   2294 void State::setVertexAttribi(GLuint index, const GLint values[4])
   2295 {
   2296    ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
   2297    mVertexAttribCurrentValues[index].setIntValues(values);
   2298    mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
   2299    mDirtyCurrentValues.set(index);
   2300    SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
   2301 }
   2302 
   2303 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
   2304 {
   2305    getVertexArray()->setVertexAttribDivisor(context, index, divisor);
   2306    mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   2307 }
   2308 
   2309 const void *State::getVertexAttribPointer(unsigned int attribNum) const
   2310 {
   2311    return getVertexArray()->getVertexAttribute(attribNum).pointer;
   2312 }
   2313 
   2314 void State::setPackAlignment(GLint alignment)
   2315 {
   2316    mPack.alignment = alignment;
   2317    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
   2318 }
   2319 
   2320 void State::setPackReverseRowOrder(bool reverseRowOrder)
   2321 {
   2322    mPack.reverseRowOrder = reverseRowOrder;
   2323    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
   2324 }
   2325 
   2326 void State::setPackRowLength(GLint rowLength)
   2327 {
   2328    mPack.rowLength = rowLength;
   2329    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
   2330 }
   2331 
   2332 void State::setPackSkipRows(GLint skipRows)
   2333 {
   2334    mPack.skipRows = skipRows;
   2335    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
   2336 }
   2337 
   2338 void State::setPackSkipPixels(GLint skipPixels)
   2339 {
   2340    mPack.skipPixels = skipPixels;
   2341    mDirtyBits.set(DIRTY_BIT_PACK_STATE);
   2342 }
   2343 
   2344 void State::setUnpackAlignment(GLint alignment)
   2345 {
   2346    mUnpack.alignment = alignment;
   2347    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2348 }
   2349 
   2350 void State::setUnpackRowLength(GLint rowLength)
   2351 {
   2352    mUnpack.rowLength = rowLength;
   2353    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2354 }
   2355 
   2356 void State::setUnpackImageHeight(GLint imageHeight)
   2357 {
   2358    mUnpack.imageHeight = imageHeight;
   2359    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2360 }
   2361 
   2362 void State::setUnpackSkipImages(GLint skipImages)
   2363 {
   2364    mUnpack.skipImages = skipImages;
   2365    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2366 }
   2367 
   2368 void State::setUnpackSkipRows(GLint skipRows)
   2369 {
   2370    mUnpack.skipRows = skipRows;
   2371    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2372 }
   2373 
   2374 void State::setUnpackSkipPixels(GLint skipPixels)
   2375 {
   2376    mUnpack.skipPixels = skipPixels;
   2377    mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
   2378 }
   2379 
   2380 void State::setCoverageModulation(GLenum components)
   2381 {
   2382    if (mCoverageModulation != components)
   2383    {
   2384        mCoverageModulation = components;
   2385        mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
   2386    }
   2387 }
   2388 
   2389 void State::setFramebufferSRGB(bool sRGB)
   2390 {
   2391    if (mFramebufferSRGB != sRGB)
   2392    {
   2393        mFramebufferSRGB = sRGB;
   2394        mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
   2395        setDrawFramebufferDirty();
   2396    }
   2397 }
   2398 
   2399 void State::setMaxShaderCompilerThreads(GLuint count)
   2400 {
   2401    mMaxShaderCompilerThreads = count;
   2402 }
   2403 
   2404 void State::setPatchVertices(GLuint value)
   2405 {
   2406    if (mPatchVertices != value)
   2407    {
   2408        mPatchVertices = value;
   2409        mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
   2410    }
   2411 }
   2412 
   2413 void State::setPixelLocalStorageActive(bool active)
   2414 {
   2415    mPixelLocalStorageActive = active;
   2416 }
   2417 
   2418 void State::setShadingRate(GLenum rate)
   2419 {
   2420    mShadingRate = FromGLenum<ShadingRate>(rate);
   2421    mDirtyBits.set(DIRTY_BIT_EXTENDED);
   2422    mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADING_RATE);
   2423 }
   2424 
   2425 void State::getBooleanv(GLenum pname, GLboolean *params) const
   2426 {
   2427    switch (pname)
   2428    {
   2429        case GL_SAMPLE_COVERAGE_INVERT:
   2430            *params = mSampleCoverageInvert;
   2431            break;
   2432        case GL_DEPTH_WRITEMASK:
   2433            *params = mDepthStencil.depthMask;
   2434            break;
   2435        case GL_COLOR_WRITEMASK:
   2436        {
   2437            // non-indexed get returns the state of draw buffer zero
   2438            bool r, g, b, a;
   2439            mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
   2440            params[0] = r;
   2441            params[1] = g;
   2442            params[2] = b;
   2443            params[3] = a;
   2444            break;
   2445        }
   2446        case GL_CULL_FACE:
   2447            *params = mRasterizer.cullFace;
   2448            break;
   2449        case GL_POLYGON_OFFSET_FILL:
   2450            *params = mRasterizer.polygonOffsetFill;
   2451            break;
   2452        case GL_SAMPLE_ALPHA_TO_COVERAGE:
   2453            *params = mSampleAlphaToCoverage;
   2454            break;
   2455        case GL_SAMPLE_COVERAGE:
   2456            *params = mSampleCoverage;
   2457            break;
   2458        case GL_SAMPLE_MASK:
   2459            *params = mSampleMask;
   2460            break;
   2461        case GL_SCISSOR_TEST:
   2462            *params = mScissorTest;
   2463            break;
   2464        case GL_STENCIL_TEST:
   2465            *params = mDepthStencil.stencilTest;
   2466            break;
   2467        case GL_DEPTH_TEST:
   2468            *params = mDepthStencil.depthTest;
   2469            break;
   2470        case GL_BLEND:
   2471            // non-indexed get returns the state of draw buffer zero
   2472            *params = mBlendStateExt.getEnabledMask().test(0);
   2473            break;
   2474        case GL_DITHER:
   2475            *params = mRasterizer.dither;
   2476            break;
   2477        case GL_COLOR_LOGIC_OP:
   2478            ASSERT(mClientVersion.major > 1);
   2479            *params = mLogicOpEnabled;
   2480            break;
   2481        case GL_TRANSFORM_FEEDBACK_ACTIVE:
   2482            *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
   2483            break;
   2484        case GL_TRANSFORM_FEEDBACK_PAUSED:
   2485            *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
   2486            break;
   2487        case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   2488            *params = mPrimitiveRestart;
   2489            break;
   2490        case GL_RASTERIZER_DISCARD:
   2491            *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
   2492            break;
   2493        case GL_DEBUG_OUTPUT_SYNCHRONOUS:
   2494            *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
   2495            break;
   2496        case GL_DEBUG_OUTPUT:
   2497            *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
   2498            break;
   2499        case GL_MULTISAMPLE_EXT:
   2500            *params = mMultiSampling;
   2501            break;
   2502        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   2503            *params = mSampleAlphaToOne;
   2504            break;
   2505        case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
   2506            *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
   2507            break;
   2508        case GL_CLIENT_ARRAYS_ANGLE:
   2509            *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
   2510            break;
   2511        case GL_FRAMEBUFFER_SRGB_EXT:
   2512            *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
   2513            break;
   2514        case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
   2515            *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
   2516            break;
   2517        case GL_PROGRAM_CACHE_ENABLED_ANGLE:
   2518            *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
   2519            break;
   2520        case GL_TEXTURE_RECTANGLE_ANGLE:
   2521            *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
   2522            break;
   2523        case GL_LIGHT_MODEL_TWO_SIDE:
   2524            *params = IsLightModelTwoSided(&mGLES1State);
   2525            break;
   2526        case GL_SAMPLE_SHADING:
   2527            *params = mIsSampleShadingEnabled;
   2528            break;
   2529        case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
   2530            *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
   2531            break;
   2532        // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
   2533        // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
   2534        // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
   2535        // GL_EXT_clip_control
   2536        case GL_CLIP_ORIGIN_EXT:
   2537            *params = GL_TRUE;
   2538            break;
   2539        case GL_CLIP_DEPTH_MODE_EXT:
   2540            *params = GL_TRUE;
   2541            break;
   2542        case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE:
   2543            *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE;
   2544            break;
   2545        // GL_ANGLE_shader_pixel_local_storage
   2546        case GL_PIXEL_LOCAL_STORAGE_ACTIVE_ANGLE:
   2547            *params = mPixelLocalStorageActive ? GL_TRUE : GL_FALSE;
   2548            break;
   2549        default:
   2550            UNREACHABLE();
   2551            break;
   2552    }
   2553 }
   2554 
   2555 void State::getFloatv(GLenum pname, GLfloat *params) const
   2556 {
   2557    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   2558    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   2559    // GetIntegerv as its native query function. As it would require conversion in any
   2560    // case, this should make no difference to the calling application.
   2561    switch (pname)
   2562    {
   2563        case GL_LINE_WIDTH:
   2564            *params = mLineWidth;
   2565            break;
   2566        case GL_SAMPLE_COVERAGE_VALUE:
   2567            *params = mSampleCoverageValue;
   2568            break;
   2569        case GL_DEPTH_CLEAR_VALUE:
   2570            *params = mDepthClearValue;
   2571            break;
   2572        case GL_POLYGON_OFFSET_FACTOR:
   2573            *params = mRasterizer.polygonOffsetFactor;
   2574            break;
   2575        case GL_POLYGON_OFFSET_UNITS:
   2576            *params = mRasterizer.polygonOffsetUnits;
   2577            break;
   2578        case GL_DEPTH_RANGE:
   2579            params[0] = mNearZ;
   2580            params[1] = mFarZ;
   2581            break;
   2582        case GL_COLOR_CLEAR_VALUE:
   2583            params[0] = mColorClearValue.red;
   2584            params[1] = mColorClearValue.green;
   2585            params[2] = mColorClearValue.blue;
   2586            params[3] = mColorClearValue.alpha;
   2587            break;
   2588        case GL_BLEND_COLOR:
   2589            params[0] = mBlendColor.red;
   2590            params[1] = mBlendColor.green;
   2591            params[2] = mBlendColor.blue;
   2592            params[3] = mBlendColor.alpha;
   2593            break;
   2594        case GL_MULTISAMPLE_EXT:
   2595            *params = static_cast<GLfloat>(mMultiSampling);
   2596            break;
   2597        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   2598            *params = static_cast<GLfloat>(mSampleAlphaToOne);
   2599            break;
   2600        case GL_COVERAGE_MODULATION_CHROMIUM:
   2601            params[0] = static_cast<GLfloat>(mCoverageModulation);
   2602            break;
   2603        case GL_ALPHA_TEST_REF:
   2604            *params = mGLES1State.mAlphaTestRef;
   2605            break;
   2606        case GL_CURRENT_COLOR:
   2607        {
   2608            const auto &color = mGLES1State.mCurrentColor;
   2609            params[0]         = color.red;
   2610            params[1]         = color.green;
   2611            params[2]         = color.blue;
   2612            params[3]         = color.alpha;
   2613            break;
   2614        }
   2615        case GL_CURRENT_NORMAL:
   2616        {
   2617            const auto &normal = mGLES1State.mCurrentNormal;
   2618            params[0]          = normal[0];
   2619            params[1]          = normal[1];
   2620            params[2]          = normal[2];
   2621            break;
   2622        }
   2623        case GL_CURRENT_TEXTURE_COORDS:
   2624        {
   2625            const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
   2626            params[0]            = texcoord.s;
   2627            params[1]            = texcoord.t;
   2628            params[2]            = texcoord.r;
   2629            params[3]            = texcoord.q;
   2630            break;
   2631        }
   2632        case GL_MODELVIEW_MATRIX:
   2633            memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
   2634            break;
   2635        case GL_PROJECTION_MATRIX:
   2636            memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
   2637                   16 * sizeof(GLfloat));
   2638            break;
   2639        case GL_TEXTURE_MATRIX:
   2640            memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
   2641                   16 * sizeof(GLfloat));
   2642            break;
   2643        case GL_LIGHT_MODEL_AMBIENT:
   2644            GetLightModelParameters(&mGLES1State, pname, params);
   2645            break;
   2646        case GL_FOG_MODE:
   2647        case GL_FOG_DENSITY:
   2648        case GL_FOG_START:
   2649        case GL_FOG_END:
   2650        case GL_FOG_COLOR:
   2651            GetFogParameters(&mGLES1State, pname, params);
   2652            break;
   2653        case GL_POINT_SIZE:
   2654            GetPointSize(&mGLES1State, params);
   2655            break;
   2656        case GL_POINT_SIZE_MIN:
   2657        case GL_POINT_SIZE_MAX:
   2658        case GL_POINT_FADE_THRESHOLD_SIZE:
   2659        case GL_POINT_DISTANCE_ATTENUATION:
   2660            GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
   2661            break;
   2662        case GL_MIN_SAMPLE_SHADING_VALUE:
   2663            *params = mMinSampleShading;
   2664            break;
   2665        // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
   2666        // If a command returning floating-point data is called, such as GetFloatv, ... An integer
   2667        // value is coerced to floating-point.
   2668        case GL_CLIP_ORIGIN_EXT:
   2669            *params = static_cast<float>(mClipControlOrigin);
   2670            break;
   2671        case GL_CLIP_DEPTH_MODE_EXT:
   2672            *params = static_cast<float>(mClipControlDepth);
   2673            break;
   2674        default:
   2675            UNREACHABLE();
   2676            break;
   2677    }
   2678 }
   2679 
   2680 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
   2681 {
   2682    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
   2683    {
   2684        size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
   2685        ASSERT(drawBuffer < static_cast<size_t>(mCaps.maxDrawBuffers));
   2686        Framebuffer *framebuffer = mDrawFramebuffer;
   2687        // The default framebuffer may have fewer draw buffer states than a user-created one. The
   2688        // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
   2689        // the draw buffer is out of range for this framebuffer.
   2690        *params = drawBuffer < framebuffer->getDrawbufferStateCount()
   2691                      ? framebuffer->getDrawBufferState(drawBuffer)
   2692                      : GL_NONE;
   2693        return angle::Result::Continue;
   2694    }
   2695 
   2696    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   2697    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   2698    // GetIntegerv as its native query function. As it would require conversion in any
   2699    // case, this should make no difference to the calling application. You may find it in
   2700    // State::getFloatv.
   2701    switch (pname)
   2702    {
   2703        case GL_ARRAY_BUFFER_BINDING:
   2704            *params = mBoundBuffers[BufferBinding::Array].id().value;
   2705            break;
   2706        case GL_DRAW_INDIRECT_BUFFER_BINDING:
   2707            *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
   2708            break;
   2709        case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   2710        {
   2711            Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
   2712            *params                    = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
   2713            break;
   2714        }
   2715        case GL_DRAW_FRAMEBUFFER_BINDING:
   2716            static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
   2717                          "Enum mismatch");
   2718            *params = mDrawFramebuffer->id().value;
   2719            break;
   2720        case GL_READ_FRAMEBUFFER_BINDING:
   2721            static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
   2722                          "Enum mismatch");
   2723            *params = mReadFramebuffer->id().value;
   2724            break;
   2725        case GL_RENDERBUFFER_BINDING:
   2726            *params = mRenderbuffer.id().value;
   2727            break;
   2728        case GL_VERTEX_ARRAY_BINDING:
   2729            *params = mVertexArray->id().value;
   2730            break;
   2731        case GL_CURRENT_PROGRAM:
   2732            *params = mProgram ? mProgram->id().value : 0;
   2733            break;
   2734        case GL_PACK_ALIGNMENT:
   2735            *params = mPack.alignment;
   2736            break;
   2737        case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
   2738            *params = mPack.reverseRowOrder;
   2739            break;
   2740        case GL_PACK_ROW_LENGTH:
   2741            *params = mPack.rowLength;
   2742            break;
   2743        case GL_PACK_SKIP_ROWS:
   2744            *params = mPack.skipRows;
   2745            break;
   2746        case GL_PACK_SKIP_PIXELS:
   2747            *params = mPack.skipPixels;
   2748            break;
   2749        case GL_UNPACK_ALIGNMENT:
   2750            *params = mUnpack.alignment;
   2751            break;
   2752        case GL_UNPACK_ROW_LENGTH:
   2753            *params = mUnpack.rowLength;
   2754            break;
   2755        case GL_UNPACK_IMAGE_HEIGHT:
   2756            *params = mUnpack.imageHeight;
   2757            break;
   2758        case GL_UNPACK_SKIP_IMAGES:
   2759            *params = mUnpack.skipImages;
   2760            break;
   2761        case GL_UNPACK_SKIP_ROWS:
   2762            *params = mUnpack.skipRows;
   2763            break;
   2764        case GL_UNPACK_SKIP_PIXELS:
   2765            *params = mUnpack.skipPixels;
   2766            break;
   2767        case GL_GENERATE_MIPMAP_HINT:
   2768            *params = mGenerateMipmapHint;
   2769            break;
   2770        case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
   2771            *params = mTextureFilteringHint;
   2772            break;
   2773        case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   2774            *params = mFragmentShaderDerivativeHint;
   2775            break;
   2776        case GL_ACTIVE_TEXTURE:
   2777            *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
   2778            break;
   2779        case GL_STENCIL_FUNC:
   2780            *params = mDepthStencil.stencilFunc;
   2781            break;
   2782        case GL_STENCIL_REF:
   2783            *params = mStencilRef;
   2784            break;
   2785        case GL_STENCIL_VALUE_MASK:
   2786            *params = CastMaskValue(mDepthStencil.stencilMask);
   2787            break;
   2788        case GL_STENCIL_BACK_FUNC:
   2789            *params = mDepthStencil.stencilBackFunc;
   2790            break;
   2791        case GL_STENCIL_BACK_REF:
   2792            *params = mStencilBackRef;
   2793            break;
   2794        case GL_STENCIL_BACK_VALUE_MASK:
   2795            *params = CastMaskValue(mDepthStencil.stencilBackMask);
   2796            break;
   2797        case GL_STENCIL_FAIL:
   2798            *params = mDepthStencil.stencilFail;
   2799            break;
   2800        case GL_STENCIL_PASS_DEPTH_FAIL:
   2801            *params = mDepthStencil.stencilPassDepthFail;
   2802            break;
   2803        case GL_STENCIL_PASS_DEPTH_PASS:
   2804            *params = mDepthStencil.stencilPassDepthPass;
   2805            break;
   2806        case GL_STENCIL_BACK_FAIL:
   2807            *params = mDepthStencil.stencilBackFail;
   2808            break;
   2809        case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   2810            *params = mDepthStencil.stencilBackPassDepthFail;
   2811            break;
   2812        case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   2813            *params = mDepthStencil.stencilBackPassDepthPass;
   2814            break;
   2815        case GL_DEPTH_FUNC:
   2816            *params = mDepthStencil.depthFunc;
   2817            break;
   2818        case GL_BLEND_SRC_RGB:
   2819            // non-indexed get returns the state of draw buffer zero
   2820            *params = mBlendStateExt.getSrcColorIndexed(0);
   2821            break;
   2822        case GL_BLEND_SRC_ALPHA:
   2823            *params = mBlendStateExt.getSrcAlphaIndexed(0);
   2824            break;
   2825        case GL_BLEND_DST_RGB:
   2826            *params = mBlendStateExt.getDstColorIndexed(0);
   2827            break;
   2828        case GL_BLEND_DST_ALPHA:
   2829            *params = mBlendStateExt.getDstAlphaIndexed(0);
   2830            break;
   2831        case GL_BLEND_EQUATION_RGB:
   2832            *params = mBlendStateExt.getEquationColorIndexed(0);
   2833            break;
   2834        case GL_BLEND_EQUATION_ALPHA:
   2835            *params = mBlendStateExt.getEquationAlphaIndexed(0);
   2836            break;
   2837        case GL_STENCIL_WRITEMASK:
   2838            *params = CastMaskValue(mDepthStencil.stencilWritemask);
   2839            break;
   2840        case GL_STENCIL_BACK_WRITEMASK:
   2841            *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
   2842            break;
   2843        case GL_STENCIL_CLEAR_VALUE:
   2844            *params = mStencilClearValue;
   2845            break;
   2846        case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   2847            *params = mReadFramebuffer->getImplementationColorReadType(context);
   2848            break;
   2849        case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   2850            *params = mReadFramebuffer->getImplementationColorReadFormat(context);
   2851            break;
   2852        case GL_SAMPLE_BUFFERS:
   2853        case GL_SAMPLES:
   2854        {
   2855            Framebuffer *framebuffer = mDrawFramebuffer;
   2856            if (framebuffer->isComplete(context))
   2857            {
   2858                GLint samples = framebuffer->getSamples(context);
   2859                switch (pname)
   2860                {
   2861                    case GL_SAMPLE_BUFFERS:
   2862                        if (samples != 0)
   2863                        {
   2864                            *params = 1;
   2865                        }
   2866                        else
   2867                        {
   2868                            *params = 0;
   2869                        }
   2870                        break;
   2871                    case GL_SAMPLES:
   2872                        *params = samples;
   2873                        break;
   2874                }
   2875            }
   2876            else
   2877            {
   2878                *params = 0;
   2879            }
   2880        }
   2881        break;
   2882        case GL_VIEWPORT:
   2883            params[0] = mViewport.x;
   2884            params[1] = mViewport.y;
   2885            params[2] = mViewport.width;
   2886            params[3] = mViewport.height;
   2887            break;
   2888        case GL_SCISSOR_BOX:
   2889            params[0] = mScissor.x;
   2890            params[1] = mScissor.y;
   2891            params[2] = mScissor.width;
   2892            params[3] = mScissor.height;
   2893            break;
   2894        case GL_CULL_FACE_MODE:
   2895            *params = ToGLenum(mRasterizer.cullMode);
   2896            break;
   2897        case GL_FRONT_FACE:
   2898            *params = mRasterizer.frontFace;
   2899            break;
   2900        case GL_RED_BITS:
   2901        case GL_GREEN_BITS:
   2902        case GL_BLUE_BITS:
   2903        case GL_ALPHA_BITS:
   2904        {
   2905            Framebuffer *framebuffer                 = getDrawFramebuffer();
   2906            const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
   2907 
   2908            if (colorbuffer)
   2909            {
   2910                switch (pname)
   2911                {
   2912                    case GL_RED_BITS:
   2913                        *params = colorbuffer->getRedSize();
   2914                        break;
   2915                    case GL_GREEN_BITS:
   2916                        *params = colorbuffer->getGreenSize();
   2917                        break;
   2918                    case GL_BLUE_BITS:
   2919                        *params = colorbuffer->getBlueSize();
   2920                        break;
   2921                    case GL_ALPHA_BITS:
   2922                        *params = colorbuffer->getAlphaSize();
   2923                        break;
   2924                }
   2925            }
   2926            else
   2927            {
   2928                *params = 0;
   2929            }
   2930        }
   2931        break;
   2932        case GL_DEPTH_BITS:
   2933        {
   2934            const Framebuffer *framebuffer           = getDrawFramebuffer();
   2935            const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
   2936 
   2937            if (depthbuffer)
   2938            {
   2939                *params = depthbuffer->getDepthSize();
   2940            }
   2941            else
   2942            {
   2943                *params = 0;
   2944            }
   2945        }
   2946        break;
   2947        case GL_STENCIL_BITS:
   2948        {
   2949            const Framebuffer *framebuffer             = getDrawFramebuffer();
   2950            const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
   2951 
   2952            if (stencilbuffer)
   2953            {
   2954                *params = stencilbuffer->getStencilSize();
   2955            }
   2956            else
   2957            {
   2958                *params = 0;
   2959            }
   2960        }
   2961        break;
   2962        case GL_TEXTURE_BINDING_2D:
   2963            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2964            *params =
   2965                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
   2966                    .value;
   2967            break;
   2968        case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
   2969            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2970            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   2971                                          TextureType::Rectangle)
   2972                          .value;
   2973            break;
   2974        case GL_TEXTURE_BINDING_CUBE_MAP:
   2975            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2976            *params =
   2977                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
   2978                    .value;
   2979            break;
   2980        case GL_TEXTURE_BINDING_3D:
   2981            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2982            *params =
   2983                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
   2984                    .value;
   2985            break;
   2986        case GL_TEXTURE_BINDING_2D_ARRAY:
   2987            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2988            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   2989                                          TextureType::_2DArray)
   2990                          .value;
   2991            break;
   2992        case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
   2993            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   2994            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   2995                                          TextureType::_2DMultisample)
   2996                          .value;
   2997            break;
   2998        case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
   2999            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   3000            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   3001                                          TextureType::_2DMultisampleArray)
   3002                          .value;
   3003            break;
   3004        case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
   3005            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   3006            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   3007                                          TextureType::CubeMapArray)
   3008                          .value;
   3009            break;
   3010        case GL_TEXTURE_BINDING_EXTERNAL_OES:
   3011            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   3012            *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
   3013                                          TextureType::External)
   3014                          .value;
   3015            break;
   3016 
   3017        // GL_OES_texture_buffer
   3018        case GL_TEXTURE_BINDING_BUFFER:
   3019            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   3020            *params =
   3021                getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
   3022                    .value;
   3023            break;
   3024        case GL_TEXTURE_BUFFER_BINDING:
   3025            *params = mBoundBuffers[BufferBinding::Texture].id().value;
   3026            break;
   3027 
   3028        case GL_UNIFORM_BUFFER_BINDING:
   3029            *params = mBoundBuffers[BufferBinding::Uniform].id().value;
   3030            break;
   3031        case GL_TRANSFORM_FEEDBACK_BINDING:
   3032            *params = mTransformFeedback.id().value;
   3033            break;
   3034        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   3035            *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
   3036            break;
   3037        case GL_COPY_READ_BUFFER_BINDING:
   3038            *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
   3039            break;
   3040        case GL_COPY_WRITE_BUFFER_BINDING:
   3041            *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
   3042            break;
   3043        case GL_PIXEL_PACK_BUFFER_BINDING:
   3044            *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
   3045            break;
   3046        case GL_PIXEL_UNPACK_BUFFER_BINDING:
   3047            *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
   3048            break;
   3049 
   3050        case GL_READ_BUFFER:
   3051            *params = mReadFramebuffer->getReadBufferState();
   3052            break;
   3053        case GL_SAMPLER_BINDING:
   3054            ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
   3055            *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
   3056            break;
   3057        case GL_DEBUG_LOGGED_MESSAGES:
   3058            *params = static_cast<GLint>(mDebug.getMessageCount());
   3059            break;
   3060        case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
   3061            *params = static_cast<GLint>(mDebug.getNextMessageLength());
   3062            break;
   3063        case GL_DEBUG_GROUP_STACK_DEPTH:
   3064            *params = static_cast<GLint>(mDebug.getGroupStackDepth());
   3065            break;
   3066        case GL_MULTISAMPLE_EXT:
   3067            *params = static_cast<GLint>(mMultiSampling);
   3068            break;
   3069        case GL_SAMPLE_ALPHA_TO_ONE_EXT:
   3070            *params = static_cast<GLint>(mSampleAlphaToOne);
   3071            break;
   3072        case GL_COVERAGE_MODULATION_CHROMIUM:
   3073            *params = static_cast<GLint>(mCoverageModulation);
   3074            break;
   3075        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
   3076            *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
   3077            break;
   3078        case GL_SHADER_STORAGE_BUFFER_BINDING:
   3079            *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
   3080            break;
   3081        case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
   3082            *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
   3083            break;
   3084        case GL_ALPHA_TEST_FUNC:
   3085            *params = ToGLenum(mGLES1State.mAlphaTestFunc);
   3086            break;
   3087        case GL_CLIENT_ACTIVE_TEXTURE:
   3088            *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
   3089            break;
   3090        case GL_MATRIX_MODE:
   3091            *params = ToGLenum(mGLES1State.mMatrixMode);
   3092            break;
   3093        case GL_SHADE_MODEL:
   3094            *params = ToGLenum(mGLES1State.mShadeModel);
   3095            break;
   3096        case GL_MODELVIEW_STACK_DEPTH:
   3097        case GL_PROJECTION_STACK_DEPTH:
   3098        case GL_TEXTURE_STACK_DEPTH:
   3099            *params = mGLES1State.getCurrentMatrixStackDepth(pname);
   3100            break;
   3101        case GL_LOGIC_OP_MODE:
   3102            *params = ToGLenum(mGLES1State.mLogicOp);
   3103            break;
   3104        case GL_BLEND_SRC:
   3105            // non-indexed get returns the state of draw buffer zero
   3106            *params = mBlendStateExt.getSrcColorIndexed(0);
   3107            break;
   3108        case GL_BLEND_DST:
   3109            *params = mBlendStateExt.getDstColorIndexed(0);
   3110            break;
   3111        case GL_PERSPECTIVE_CORRECTION_HINT:
   3112        case GL_POINT_SMOOTH_HINT:
   3113        case GL_LINE_SMOOTH_HINT:
   3114        case GL_FOG_HINT:
   3115            *params = mGLES1State.getHint(pname);
   3116            break;
   3117 
   3118        // GL_ANGLE_provoking_vertex
   3119        case GL_PROVOKING_VERTEX:
   3120            *params = ToGLenum(mProvokingVertex);
   3121            break;
   3122 
   3123        case GL_PROGRAM_PIPELINE_BINDING:
   3124        {
   3125            ProgramPipeline *pipeline = getProgramPipeline();
   3126            if (pipeline)
   3127            {
   3128                *params = pipeline->id().value;
   3129            }
   3130            else
   3131            {
   3132                *params = 0;
   3133            }
   3134            break;
   3135        }
   3136        case GL_PATCH_VERTICES:
   3137            *params = mPatchVertices;
   3138            break;
   3139 
   3140        // GL_EXT_clip_control
   3141        case GL_CLIP_ORIGIN_EXT:
   3142            *params = mClipControlOrigin;
   3143            break;
   3144        case GL_CLIP_DEPTH_MODE_EXT:
   3145            *params = mClipControlDepth;
   3146            break;
   3147 
   3148        // GL_QCOM_shading_rate
   3149        case GL_SHADING_RATE_QCOM:
   3150            *params = ToGLenum(mShadingRate);
   3151            break;
   3152 
   3153        default:
   3154            UNREACHABLE();
   3155            break;
   3156    }
   3157 
   3158    return angle::Result::Continue;
   3159 }
   3160 
   3161 void State::getPointerv(const Context *context, GLenum pname, void **params) const
   3162 {
   3163    switch (pname)
   3164    {
   3165        case GL_DEBUG_CALLBACK_FUNCTION:
   3166            *params = reinterpret_cast<void *>(mDebug.getCallback());
   3167            break;
   3168        case GL_DEBUG_CALLBACK_USER_PARAM:
   3169            *params = const_cast<void *>(mDebug.getUserParam());
   3170            break;
   3171        case GL_VERTEX_ARRAY_POINTER:
   3172        case GL_NORMAL_ARRAY_POINTER:
   3173        case GL_COLOR_ARRAY_POINTER:
   3174        case GL_TEXTURE_COORD_ARRAY_POINTER:
   3175        case GL_POINT_SIZE_ARRAY_POINTER_OES:
   3176            QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
   3177                                          context->vertexArrayIndex(ParamToVertexArrayType(pname))),
   3178                                      GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
   3179            return;
   3180        default:
   3181            UNREACHABLE();
   3182            break;
   3183    }
   3184 }
   3185 
   3186 void State::getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const
   3187 {
   3188    switch (target)
   3189    {
   3190        case GL_BLEND_SRC_RGB:
   3191            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3192            *data = mBlendStateExt.getSrcColorIndexed(index);
   3193            break;
   3194        case GL_BLEND_SRC_ALPHA:
   3195            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3196            *data = mBlendStateExt.getSrcAlphaIndexed(index);
   3197            break;
   3198        case GL_BLEND_DST_RGB:
   3199            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3200            *data = mBlendStateExt.getDstColorIndexed(index);
   3201            break;
   3202        case GL_BLEND_DST_ALPHA:
   3203            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3204            *data = mBlendStateExt.getDstAlphaIndexed(index);
   3205            break;
   3206        case GL_BLEND_EQUATION_RGB:
   3207            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3208            *data = mBlendStateExt.getEquationColorIndexed(index);
   3209            break;
   3210        case GL_BLEND_EQUATION_ALPHA:
   3211            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3212            *data = mBlendStateExt.getEquationAlphaIndexed(index);
   3213            break;
   3214        case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   3215            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
   3216            *data = mTransformFeedback->getIndexedBuffer(index).id().value;
   3217            break;
   3218        case GL_UNIFORM_BUFFER_BINDING:
   3219            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
   3220            *data = mUniformBuffers[index].id().value;
   3221            break;
   3222        case GL_ATOMIC_COUNTER_BUFFER_BINDING:
   3223            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
   3224            *data = mAtomicCounterBuffers[index].id().value;
   3225            break;
   3226        case GL_SHADER_STORAGE_BUFFER_BINDING:
   3227            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
   3228            *data = mShaderStorageBuffers[index].id().value;
   3229            break;
   3230        case GL_VERTEX_BINDING_BUFFER:
   3231            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
   3232            *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
   3233            break;
   3234        case GL_VERTEX_BINDING_DIVISOR:
   3235            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
   3236            *data = mVertexArray->getVertexBinding(index).getDivisor();
   3237            break;
   3238        case GL_VERTEX_BINDING_OFFSET:
   3239            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
   3240            *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
   3241            break;
   3242        case GL_VERTEX_BINDING_STRIDE:
   3243            ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
   3244            *data = mVertexArray->getVertexBinding(index).getStride();
   3245            break;
   3246        case GL_SAMPLE_MASK_VALUE:
   3247            ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
   3248            *data = mSampleMaskValues[index];
   3249            break;
   3250        case GL_IMAGE_BINDING_NAME:
   3251            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3252            *data = mImageUnits[index].texture.id().value;
   3253            break;
   3254        case GL_IMAGE_BINDING_LEVEL:
   3255            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3256            *data = mImageUnits[index].level;
   3257            break;
   3258        case GL_IMAGE_BINDING_LAYER:
   3259            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3260            *data = mImageUnits[index].layer;
   3261            break;
   3262        case GL_IMAGE_BINDING_ACCESS:
   3263            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3264            *data = mImageUnits[index].access;
   3265            break;
   3266        case GL_IMAGE_BINDING_FORMAT:
   3267            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3268            *data = mImageUnits[index].format;
   3269            break;
   3270        // GL_ANGLE_shader_pixel_local_storage.
   3271        case GL_PIXEL_LOCAL_FORMAT_ANGLE:
   3272        case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
   3273        case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
   3274        case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
   3275        {
   3276            ASSERT(mDrawFramebuffer);
   3277            *data = mDrawFramebuffer->getPixelLocalStorage(context).getPlane(index).getIntegeri(
   3278                context, target, index);
   3279            break;
   3280        }
   3281        default:
   3282            UNREACHABLE();
   3283            break;
   3284    }
   3285 }
   3286 
   3287 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
   3288 {
   3289    switch (target)
   3290    {
   3291        case GL_TRANSFORM_FEEDBACK_BUFFER_START:
   3292            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
   3293            *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
   3294            break;
   3295        case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
   3296            ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
   3297            *data = mTransformFeedback->getIndexedBuffer(index).getSize();
   3298            break;
   3299        case GL_UNIFORM_BUFFER_START:
   3300            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
   3301            *data = mUniformBuffers[index].getOffset();
   3302            break;
   3303        case GL_UNIFORM_BUFFER_SIZE:
   3304            ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
   3305            *data = mUniformBuffers[index].getSize();
   3306            break;
   3307        case GL_ATOMIC_COUNTER_BUFFER_START:
   3308            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
   3309            *data = mAtomicCounterBuffers[index].getOffset();
   3310            break;
   3311        case GL_ATOMIC_COUNTER_BUFFER_SIZE:
   3312            ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
   3313            *data = mAtomicCounterBuffers[index].getSize();
   3314            break;
   3315        case GL_SHADER_STORAGE_BUFFER_START:
   3316            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
   3317            *data = mShaderStorageBuffers[index].getOffset();
   3318            break;
   3319        case GL_SHADER_STORAGE_BUFFER_SIZE:
   3320            ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
   3321            *data = mShaderStorageBuffers[index].getSize();
   3322            break;
   3323        default:
   3324            UNREACHABLE();
   3325            break;
   3326    }
   3327 }
   3328 
   3329 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
   3330 {
   3331    switch (target)
   3332    {
   3333        case GL_COLOR_WRITEMASK:
   3334        {
   3335            ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
   3336            bool r, g, b, a;
   3337            mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
   3338            data[0] = r;
   3339            data[1] = g;
   3340            data[2] = b;
   3341            data[3] = a;
   3342            break;
   3343        }
   3344        case GL_IMAGE_BINDING_LAYERED:
   3345            ASSERT(static_cast<size_t>(index) < mImageUnits.size());
   3346            *data = mImageUnits[index].layered;
   3347            break;
   3348        default:
   3349            UNREACHABLE();
   3350            break;
   3351    }
   3352 }
   3353 
   3354 // TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part
   3355 // refactor done.
   3356 Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
   3357 {
   3358    if (type != TextureType::VideoImage)
   3359    {
   3360        return mSamplerTextures[type][index].get();
   3361    }
   3362 
   3363    ASSERT(type == TextureType::VideoImage);
   3364 
   3365    Texture *candidateTexture = mSamplerTextures[type][index].get();
   3366    if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
   3367        candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
   3368        candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
   3369    {
   3370        return mSamplerTextures[TextureType::_2D][index].get();
   3371    }
   3372 
   3373    return mSamplerTextures[type][index].get();
   3374 }
   3375 
   3376 angle::Result State::syncActiveTextures(const Context *context, Command command)
   3377 {
   3378    if (mDirtyActiveTextures.none())
   3379    {
   3380        return angle::Result::Continue;
   3381    }
   3382 
   3383    for (size_t textureUnit : mDirtyActiveTextures)
   3384    {
   3385        if (mExecutable)
   3386        {
   3387            TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
   3388            Texture *activeTexture = (type != TextureType::InvalidEnum)
   3389                                         ? getTextureForActiveSampler(type, textureUnit)
   3390                                         : nullptr;
   3391            const Sampler *sampler = mSamplers[textureUnit].get();
   3392 
   3393            updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
   3394        }
   3395    }
   3396 
   3397    mDirtyActiveTextures.reset();
   3398    return angle::Result::Continue;
   3399 }
   3400 
   3401 angle::Result State::syncTexturesInit(const Context *context, Command command)
   3402 {
   3403    ASSERT(mRobustResourceInit);
   3404 
   3405    if (!mProgram)
   3406        return angle::Result::Continue;
   3407 
   3408    for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
   3409    {
   3410        Texture *texture = mActiveTexturesCache[textureUnitIndex];
   3411        if (texture)
   3412        {
   3413            ANGLE_TRY(texture->ensureInitialized(context));
   3414        }
   3415    }
   3416    return angle::Result::Continue;
   3417 }
   3418 
   3419 angle::Result State::syncImagesInit(const Context *context, Command command)
   3420 {
   3421    ASSERT(mRobustResourceInit);
   3422    ASSERT(mExecutable);
   3423    for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
   3424    {
   3425        Texture *texture = mImageUnits[imageUnitIndex].texture.get();
   3426        if (texture)
   3427        {
   3428            ANGLE_TRY(texture->ensureInitialized(context));
   3429        }
   3430    }
   3431    return angle::Result::Continue;
   3432 }
   3433 
   3434 angle::Result State::syncReadAttachments(const Context *context, Command command)
   3435 {
   3436    ASSERT(mReadFramebuffer);
   3437    ASSERT(mRobustResourceInit);
   3438    return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
   3439 }
   3440 
   3441 angle::Result State::syncDrawAttachments(const Context *context, Command command)
   3442 {
   3443    ASSERT(mDrawFramebuffer);
   3444    ASSERT(mRobustResourceInit);
   3445    return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
   3446 }
   3447 
   3448 angle::Result State::syncReadFramebuffer(const Context *context, Command command)
   3449 {
   3450    ASSERT(mReadFramebuffer);
   3451    return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
   3452 }
   3453 
   3454 angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
   3455 {
   3456    ASSERT(mDrawFramebuffer);
   3457    mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
   3458                                              ? SrgbWriteControlMode::Default
   3459                                              : SrgbWriteControlMode::Linear);
   3460    return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
   3461 }
   3462 
   3463 angle::Result State::syncTextures(const Context *context, Command command)
   3464 {
   3465    if (mDirtyTextures.none())
   3466        return angle::Result::Continue;
   3467 
   3468    for (size_t textureIndex : mDirtyTextures)
   3469    {
   3470        Texture *texture = mActiveTexturesCache[textureIndex];
   3471        if (texture && texture->hasAnyDirtyBit())
   3472        {
   3473            ANGLE_TRY(texture->syncState(context, Command::Other));
   3474        }
   3475    }
   3476 
   3477    mDirtyTextures.reset();
   3478    return angle::Result::Continue;
   3479 }
   3480 
   3481 angle::Result State::syncImages(const Context *context, Command command)
   3482 {
   3483    if (mDirtyImages.none())
   3484        return angle::Result::Continue;
   3485 
   3486    for (size_t imageUnitIndex : mDirtyImages)
   3487    {
   3488        Texture *texture = mImageUnits[imageUnitIndex].texture.get();
   3489        if (texture && texture->hasAnyDirtyBit())
   3490        {
   3491            ANGLE_TRY(texture->syncState(context, Command::Other));
   3492        }
   3493    }
   3494 
   3495    mDirtyImages.reset();
   3496    return angle::Result::Continue;
   3497 }
   3498 
   3499 angle::Result State::syncSamplers(const Context *context, Command command)
   3500 {
   3501    if (mDirtySamplers.none())
   3502        return angle::Result::Continue;
   3503 
   3504    for (size_t samplerIndex : mDirtySamplers)
   3505    {
   3506        BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
   3507        if (sampler.get() && sampler->isDirty())
   3508        {
   3509            ANGLE_TRY(sampler->syncState(context));
   3510        }
   3511    }
   3512 
   3513    mDirtySamplers.reset();
   3514 
   3515    return angle::Result::Continue;
   3516 }
   3517 
   3518 angle::Result State::syncVertexArray(const Context *context, Command command)
   3519 {
   3520    ASSERT(mVertexArray);
   3521    return mVertexArray->syncState(context);
   3522 }
   3523 
   3524 angle::Result State::syncProgram(const Context *context, Command command)
   3525 {
   3526    // There may not be a program if the calling application only uses program pipelines.
   3527    if (mProgram)
   3528    {
   3529        return mProgram->syncState(context);
   3530    }
   3531    return angle::Result::Continue;
   3532 }
   3533 
   3534 angle::Result State::syncProgramPipelineObject(const Context *context, Command command)
   3535 {
   3536    // If a ProgramPipeline is bound, ensure it is linked.
   3537    if (mProgramPipeline.get())
   3538    {
   3539        mProgramPipeline->resolveLink(context);
   3540    }
   3541    return angle::Result::Continue;
   3542 }
   3543 
   3544 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
   3545 {
   3546    DirtyObjects localSet;
   3547 
   3548    switch (target)
   3549    {
   3550        case GL_READ_FRAMEBUFFER:
   3551            localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   3552            break;
   3553        case GL_DRAW_FRAMEBUFFER:
   3554            localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
   3555            break;
   3556        case GL_FRAMEBUFFER:
   3557            localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   3558            localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
   3559            break;
   3560        case GL_VERTEX_ARRAY:
   3561            localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
   3562            break;
   3563        case GL_TEXTURE:
   3564            localSet.set(DIRTY_OBJECT_TEXTURES);
   3565            break;
   3566        case GL_SAMPLER:
   3567            localSet.set(DIRTY_OBJECT_SAMPLERS);
   3568            break;
   3569        case GL_PROGRAM:
   3570            localSet.set(DIRTY_OBJECT_PROGRAM);
   3571            break;
   3572    }
   3573 
   3574    return syncDirtyObjects(context, localSet, Command::Other);
   3575 }
   3576 
   3577 void State::setObjectDirty(GLenum target)
   3578 {
   3579    switch (target)
   3580    {
   3581        case GL_READ_FRAMEBUFFER:
   3582            mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   3583            break;
   3584        case GL_DRAW_FRAMEBUFFER:
   3585            setDrawFramebufferDirty();
   3586            break;
   3587        case GL_FRAMEBUFFER:
   3588            mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
   3589            setDrawFramebufferDirty();
   3590            break;
   3591        case GL_VERTEX_ARRAY:
   3592            mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
   3593            break;
   3594        case GL_PROGRAM:
   3595            mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
   3596            break;
   3597        default:
   3598            break;
   3599    }
   3600 }
   3601 
   3602 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
   3603 {
   3604    // OpenGL Spec:
   3605    // "If LinkProgram or ProgramBinary successfully re-links a program object
   3606    //  that was already in use as a result of a previous call to UseProgram, then the
   3607    //  generated executable code will be installed as part of the current rendering state."
   3608    ASSERT(program->isLinked());
   3609 
   3610    // If this Program is currently active, we need to update the State's pointer to the current
   3611    // ProgramExecutable if we just changed it.
   3612    if (mProgram == program)
   3613    {
   3614        mExecutable = &program->getExecutable();
   3615    }
   3616 
   3617    mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
   3618 
   3619    if (program->hasAnyDirtyBit())
   3620    {
   3621        mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
   3622    }
   3623 
   3624    // Set any bound textures.
   3625    const ProgramExecutable &executable        = program->getExecutable();
   3626    const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
   3627    for (size_t textureIndex : executable.getActiveSamplersMask())
   3628    {
   3629        TextureType type = textureTypes[textureIndex];
   3630 
   3631        // This can happen if there is a conflicting texture type.
   3632        if (type == TextureType::InvalidEnum)
   3633            continue;
   3634 
   3635        Texture *texture = getTextureForActiveSampler(type, textureIndex);
   3636        updateTextureBinding(context, textureIndex, texture);
   3637    }
   3638 
   3639    for (size_t imageUnitIndex : executable.getActiveImagesMask())
   3640    {
   3641        Texture *image = mImageUnits[imageUnitIndex].texture.get();
   3642        if (!image)
   3643            continue;
   3644 
   3645        if (image->hasAnyDirtyBit())
   3646        {
   3647            ANGLE_TRY(image->syncState(context, Command::Other));
   3648        }
   3649 
   3650        if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
   3651        {
   3652            mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
   3653        }
   3654    }
   3655 
   3656    return angle::Result::Continue;
   3657 }
   3658 
   3659 angle::Result State::onProgramPipelineExecutableChange(const Context *context)
   3660 {
   3661    mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
   3662 
   3663    if (!mProgramPipeline->isLinked())
   3664    {
   3665        mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT);
   3666    }
   3667 
   3668    // Set any bound textures.
   3669    const ProgramExecutable &executable        = mProgramPipeline->getExecutable();
   3670    const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
   3671 
   3672    for (size_t textureIndex : executable.getActiveSamplersMask())
   3673    {
   3674        TextureType type = textureTypes[textureIndex];
   3675 
   3676        // This can happen if there is a conflicting texture type.
   3677        if (type == TextureType::InvalidEnum)
   3678            continue;
   3679 
   3680        Texture *texture = getTextureForActiveSampler(type, textureIndex);
   3681        updateTextureBinding(context, textureIndex, texture);
   3682    }
   3683 
   3684    for (size_t imageUnitIndex : executable.getActiveImagesMask())
   3685    {
   3686        Texture *image = mImageUnits[imageUnitIndex].texture.get();
   3687        if (!image)
   3688            continue;
   3689 
   3690        if (image->hasAnyDirtyBit())
   3691        {
   3692            ANGLE_TRY(image->syncState(context, Command::Other));
   3693        }
   3694 
   3695        if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
   3696        {
   3697            mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
   3698        }
   3699    }
   3700 
   3701    return angle::Result::Continue;
   3702 }
   3703 
   3704 void State::setTextureDirty(size_t textureUnitIndex)
   3705 {
   3706    mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
   3707    mDirtyTextures.set(textureUnitIndex);
   3708 }
   3709 
   3710 void State::setSamplerDirty(size_t samplerIndex)
   3711 {
   3712    mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
   3713    mDirtySamplers.set(samplerIndex);
   3714 }
   3715 
   3716 void State::setImageUnit(const Context *context,
   3717                         size_t unit,
   3718                         Texture *texture,
   3719                         GLint level,
   3720                         GLboolean layered,
   3721                         GLint layer,
   3722                         GLenum access,
   3723                         GLenum format)
   3724 {
   3725    ASSERT(!mImageUnits.empty());
   3726 
   3727    ImageUnit &imageUnit = mImageUnits[unit];
   3728 
   3729    if (texture)
   3730    {
   3731        texture->onBindAsImageTexture();
   3732 
   3733        // Using individual layers of a 3d image as 2d may require that the image be respecified in
   3734        // a compatible layout
   3735        if (!layered && texture->getType() == TextureType::_3D)
   3736        {
   3737            texture->onBind3DTextureAs2DImage();
   3738        }
   3739    }
   3740    imageUnit.texture.set(context, texture);
   3741    imageUnit.level   = level;
   3742    imageUnit.layered = layered;
   3743    imageUnit.layer   = layer;
   3744    imageUnit.access  = access;
   3745    imageUnit.format  = format;
   3746    mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
   3747 
   3748    onImageStateChange(context, unit);
   3749 }
   3750 
   3751 // Handle a dirty texture event.
   3752 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
   3753 {
   3754    if (mExecutable)
   3755    {
   3756        TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
   3757        Texture *activeTexture = (type != TextureType::InvalidEnum)
   3758                                     ? getTextureForActiveSampler(type, textureUnit)
   3759                                     : nullptr;
   3760        updateTextureBinding(context, textureUnit, activeTexture);
   3761 
   3762        mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
   3763    }
   3764 }
   3765 
   3766 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
   3767 {
   3768    if (mExecutable)
   3769    {
   3770        TextureType type       = mExecutable->getActiveSamplerTypes()[textureUnit];
   3771        Texture *activeTexture = (type != TextureType::InvalidEnum)
   3772                                     ? getTextureForActiveSampler(type, textureUnit)
   3773                                     : nullptr;
   3774        setActiveTextureDirty(textureUnit, activeTexture);
   3775    }
   3776 }
   3777 
   3778 void State::onImageStateChange(const Context *context, size_t unit)
   3779 {
   3780    if (mExecutable)
   3781    {
   3782        const ImageUnit &image = mImageUnits[unit];
   3783 
   3784        // Have nothing to do here if no texture bound
   3785        if (!image.texture.get())
   3786            return;
   3787 
   3788        if (image.texture->hasAnyDirtyBit())
   3789        {
   3790            mDirtyImages.set(unit);
   3791            mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
   3792        }
   3793 
   3794        if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
   3795        {
   3796            mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
   3797        }
   3798 
   3799        mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
   3800    }
   3801 }
   3802 
   3803 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
   3804 {
   3805    // This could be represented by a different dirty bit. Using the same one keeps it simple.
   3806    mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
   3807 }
   3808 
   3809 void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)
   3810 {
   3811    mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
   3812 }
   3813 
   3814 void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)
   3815 {
   3816    mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
   3817 }
   3818 
   3819 AttributesMask State::getAndResetDirtyCurrentValues() const
   3820 {
   3821    AttributesMask retVal = mDirtyCurrentValues;
   3822    mDirtyCurrentValues.reset();
   3823    return retVal;
   3824 }
   3825 
   3826 State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
   3827 {
   3828    ExtendedDirtyBits retVal = mExtendedDirtyBits;
   3829    mExtendedDirtyBits.reset();
   3830    return retVal;
   3831 }
   3832 
   3833 void State::initializeForCapture(const Context *context)
   3834 {
   3835    mCaps       = context->getCaps();
   3836    mExtensions = context->getExtensions();
   3837 
   3838    // This little kludge gets around the frame capture "constness". It should be safe because
   3839    // nothing in the context is modified in a non-compatible way during capture.
   3840    Context *mutableContext = const_cast<Context *>(context);
   3841    initialize(mutableContext);
   3842 }
   3843 
   3844 void State::setLogicOpEnabled(bool enabled)
   3845 {
   3846    if (mLogicOpEnabled != enabled)
   3847    {
   3848        mLogicOpEnabled = enabled;
   3849        mDirtyBits.set(DIRTY_BIT_EXTENDED);
   3850        mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED);
   3851    }
   3852 }
   3853 
   3854 void State::setLogicOp(LogicalOperation opcode)
   3855 {
   3856    if (mLogicOp != opcode)
   3857    {
   3858        mLogicOp = opcode;
   3859        mDirtyBits.set(DIRTY_BIT_EXTENDED);
   3860        mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_LOGIC_OP);
   3861    }
   3862 }
   3863 
   3864 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
   3865 
   3866 }  // namespace gl