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