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