1 // 2 // 3 // Copyright 2002 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // Context.h: Defines the gl::Context class, managing all GL state and performing 9 // rendering operations. It is the GLES2 specific implementation of EGLContext. 10 11 #ifndef LIBANGLE_CONTEXT_H_ 12 #define LIBANGLE_CONTEXT_H_ 13 14 #include <mutex> 15 #include <set> 16 #include <string> 17 18 #include "angle_gl.h" 19 #include "common/MemoryBuffer.h" 20 #include "common/PackedEnums.h" 21 #include "common/SimpleMutex.h" 22 #include "common/angleutils.h" 23 #include "libANGLE/Caps.h" 24 #include "libANGLE/Constants.h" 25 #include "libANGLE/Context_gles_1_0_autogen.h" 26 #include "libANGLE/Context_gles_2_0_autogen.h" 27 #include "libANGLE/Context_gles_3_0_autogen.h" 28 #include "libANGLE/Context_gles_3_1_autogen.h" 29 #include "libANGLE/Context_gles_3_2_autogen.h" 30 #include "libANGLE/Context_gles_ext_autogen.h" 31 #include "libANGLE/Error.h" 32 #include "libANGLE/Framebuffer.h" 33 #include "libANGLE/HandleAllocator.h" 34 #include "libANGLE/RefCountObject.h" 35 #include "libANGLE/ResourceManager.h" 36 #include "libANGLE/ResourceMap.h" 37 #include "libANGLE/State.h" 38 #include "libANGLE/VertexAttribute.h" 39 #include "libANGLE/angletypes.h" 40 41 namespace angle 42 { 43 class Closure; 44 class FrameCapture; 45 class FrameCaptureShared; 46 struct FrontendFeatures; 47 class WaitableEvent; 48 } // namespace angle 49 50 namespace rx 51 { 52 class ContextImpl; 53 class EGLImplFactory; 54 } // namespace rx 55 56 namespace egl 57 { 58 class AttributeMap; 59 class Surface; 60 struct Config; 61 class Thread; 62 } // namespace egl 63 64 namespace gl 65 { 66 class Buffer; 67 class Compiler; 68 class FenceNV; 69 class GLES1Renderer; 70 class MemoryProgramCache; 71 class MemoryShaderCache; 72 class MemoryObject; 73 class PixelLocalStoragePlane; 74 class Program; 75 class ProgramPipeline; 76 class Query; 77 class Renderbuffer; 78 class Sampler; 79 class Semaphore; 80 class Shader; 81 class Sync; 82 class Texture; 83 class TransformFeedback; 84 class VertexArray; 85 struct VertexAttribute; 86 87 class ErrorSet : angle::NonCopyable 88 { 89 public: 90 explicit ErrorSet(Debug *debug, 91 const angle::FrontendFeatures &frontendFeatures, 92 const egl::AttributeMap &attribs); 93 ~ErrorSet(); 94 empty()95 bool empty() const { return mHasAnyErrors.load(std::memory_order_relaxed) == 0; } 96 GLenum popError(); 97 98 void handleError(GLenum errorCode, 99 const char *message, 100 const char *file, 101 const char *function, 102 unsigned int line); 103 104 void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message); 105 ANGLE_FORMAT_PRINTF(4, 5) 106 void validationErrorF(angle::EntryPoint entryPoint, GLenum errorCode, const char *format, ...); 107 skipValidation()108 bool skipValidation() const 109 { 110 // Ensure we don't skip validation when context becomes lost, since implementations 111 // generally assume a non-lost context, non-null objects, etc. 112 ASSERT(!isContextLost() || !mSkipValidation); 113 return mSkipValidation.load(std::memory_order_relaxed) != 0; 114 } forceValidation()115 void forceValidation() { mSkipValidation = 0; } 116 117 void markContextLost(GraphicsResetStatus status); isContextLost()118 bool isContextLost() const { return mContextLost.load(std::memory_order_relaxed) != 0; } 119 GLenum getGraphicsResetStatus(rx::ContextImpl *contextImpl); getResetStrategy()120 GLenum getResetStrategy() const { return mResetStrategy; } 121 GLenum getErrorForCapture() const; 122 123 private: 124 void setContextLost(); 125 void pushError(GLenum errorCode); 126 std::unique_lock<std::mutex> getLockIfNotAlready(); 127 128 // Non-atomic members of this class are protected by a mutex. This is to allow errors to be 129 // safely set by entry points that don't hold a lock. Note that other contexts may end up 130 // triggering an error on this context (through making failable calls on other contexts in the 131 // share group). 132 // 133 // Note also that the functionality used through the Debug class is thread-safe. 134 std::mutex mMutex; 135 136 // Error handling and reporting 137 Debug *mDebug; 138 std::set<GLenum> mErrors; 139 140 const GLenum mResetStrategy; 141 const bool mLoseContextOnOutOfMemory; 142 143 // Context-loss handling 144 bool mContextLostForced; 145 GraphicsResetStatus mResetStatus; 146 147 // The following are atomic and lockless as they are very frequently accessed. 148 std::atomic_int mSkipValidation; 149 std::atomic_int mContextLost; 150 std::atomic_int mHasAnyErrors; 151 }; 152 153 enum class VertexAttribTypeCase 154 { 155 Invalid = 0, 156 Valid = 1, 157 ValidSize4Only = 2, 158 ValidSize3or4 = 3, 159 }; 160 161 // Part of StateCache (see below) that is private to the context and is inaccessible to other 162 // contexts. 163 class PrivateStateCache final : angle::NonCopyable 164 { 165 public: 166 PrivateStateCache(); 167 ~PrivateStateCache(); 168 onCapChange()169 void onCapChange() { mIsCachedBasicDrawStatesErrorValid = false; } onColorMaskChange()170 void onColorMaskChange() { mIsCachedBasicDrawStatesErrorValid = false; } onDefaultVertexAttributeChange()171 void onDefaultVertexAttributeChange() { mIsCachedBasicDrawStatesErrorValid = false; } 172 173 // Blending updates invalidate draw 174 // state in the following cases: 175 // 176 // * Blend equations have been changed and the context 177 // supports KHR_blend_equation_advanced. The number 178 // of enabled draw buffers may need to be checked 179 // to not be greater than 1. 180 // 181 // * Blend funcs have been changed with indexed 182 // commands. The D3D11 backend cannot support 183 // constant color and alpha blend funcs together 184 // so a check is needed across all draw buffers. 185 // 186 // * Blend funcs have been changed and the context 187 // supports EXT_blend_func_extended. The number 188 // of enabled draw buffers may need to be checked 189 // against MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT limit. onBlendEquationOrFuncChange()190 void onBlendEquationOrFuncChange() { mIsCachedBasicDrawStatesErrorValid = false; } 191 onStencilStateChange()192 void onStencilStateChange() { mIsCachedBasicDrawStatesErrorValid = false; } 193 isCachedBasicDrawStatesErrorValid()194 bool isCachedBasicDrawStatesErrorValid() const { return mIsCachedBasicDrawStatesErrorValid; } setCachedBasicDrawStatesErrorValid()195 void setCachedBasicDrawStatesErrorValid() const { mIsCachedBasicDrawStatesErrorValid = true; } 196 197 private: 198 // StateCache::mCachedBasicDrawStatesError* may be invalidated through numerous calls (see the 199 // comment on getBasicDrawStatesErrorString), some of which may originate from other contexts 200 // (through the observer interface). However, ContextPrivate* helpers may also need to 201 // invalidate the draw states, but they are called without holding the share group lock. The 202 // following tracks whether StateCache::mCachedBasicDrawStatesError* values are valid and is 203 // accessed only by the context itself. 204 mutable bool mIsCachedBasicDrawStatesErrorValid; 205 }; 206 207 // Helper class for managing cache variables and state changes. 208 class StateCache final : angle::NonCopyable 209 { 210 public: 211 StateCache(); 212 ~StateCache(); 213 214 void initialize(Context *context); 215 216 // Places that can trigger updateActiveAttribsMask: 217 // 1. onVertexArrayBindingChange. 218 // 2. onProgramExecutableChange. 219 // 3. onVertexArrayStateChange. 220 // 4. onGLES1ClientStateChange. 221 // 5. onGLES1TextureStateChange. getActiveBufferedAttribsMask()222 AttributesMask getActiveBufferedAttribsMask() const { return mCachedActiveBufferedAttribsMask; } getActiveClientAttribsMask()223 AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; } getActiveDefaultAttribsMask()224 AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; } hasAnyEnabledClientAttrib()225 bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; } hasAnyActiveClientAttrib()226 bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); } 227 228 // Places that can trigger updateVertexElementLimits: 229 // 1. onVertexArrayBindingChange. 230 // 2. onProgramExecutableChange. 231 // 3. onVertexArrayFormatChange. 232 // 4. onVertexArrayBufferChange. 233 // 5. onVertexArrayStateChange. getNonInstancedVertexElementLimit()234 GLint64 getNonInstancedVertexElementLimit() const 235 { 236 return mCachedNonInstancedVertexElementLimit; 237 } getInstancedVertexElementLimit()238 GLint64 getInstancedVertexElementLimit() const { return mCachedInstancedVertexElementLimit; } 239 240 // Places that can trigger updateBasicDrawStatesError: 241 // 1. onVertexArrayBindingChange. 242 // 2. onProgramExecutableChange. 243 // 3. onVertexArrayBufferContentsChange. 244 // 4. onVertexArrayStateChange. 245 // 5. onVertexArrayBufferStateChange. 246 // 6. onDrawFramebufferChange. 247 // 7. onActiveTextureChange. 248 // 8. onQueryChange. 249 // 9. onActiveTransformFeedbackChange. 250 // 10. onUniformBufferStateChange. 251 // 11. onBufferBindingChange. 252 // 253 // Additionally, the following in PrivateStateCache can lead to updateBasicDrawStatesError: 254 // 1. onCapChange. 255 // 2. onStencilStateChange. 256 // 3. onDefaultVertexAttributeChange. 257 // 4. onColorMaskChange. 258 // 5. onBlendEquationOrFuncChange. getBasicDrawStatesErrorString(const Context * context,const PrivateStateCache * privateStateCache)259 intptr_t getBasicDrawStatesErrorString(const Context *context, 260 const PrivateStateCache *privateStateCache) const 261 { 262 // This is only ever called with the context that owns this state cache 263 ASSERT(isCurrentContext(context, privateStateCache)); 264 if (privateStateCache->isCachedBasicDrawStatesErrorValid() && 265 mCachedBasicDrawStatesErrorString != kInvalidPointer) 266 { 267 return mCachedBasicDrawStatesErrorString; 268 } 269 270 return getBasicDrawStatesErrorImpl(context, privateStateCache); 271 } 272 273 // The GL error enum to use when generating errors due to failed draw states. Only valid if 274 // getBasicDrawStatesErrorString returns non-zero. getBasicDrawElementsErrorCode()275 GLenum getBasicDrawElementsErrorCode() const 276 { 277 ASSERT(mCachedBasicDrawStatesErrorString != kInvalidPointer); 278 ASSERT(mCachedBasicDrawStatesErrorCode != GL_NO_ERROR); 279 return mCachedBasicDrawStatesErrorCode; 280 } 281 282 // Places that can trigger updateProgramPipelineError: 283 // 1. onProgramExecutableChange. getProgramPipelineError(const Context * context)284 intptr_t getProgramPipelineError(const Context *context) const 285 { 286 if (mCachedProgramPipelineError != kInvalidPointer) 287 { 288 return mCachedProgramPipelineError; 289 } 290 291 return getProgramPipelineErrorImpl(context); 292 } 293 294 // Places that can trigger updateBasicDrawElementsError: 295 // 1. onActiveTransformFeedbackChange. 296 // 2. onVertexArrayBufferStateChange. 297 // 3. onBufferBindingChange. 298 // 4. onVertexArrayStateChange. 299 // 5. onVertexArrayBindingStateChange. getBasicDrawElementsError(const Context * context)300 intptr_t getBasicDrawElementsError(const Context *context) const 301 { 302 if (mCachedBasicDrawElementsError != kInvalidPointer) 303 { 304 return mCachedBasicDrawElementsError; 305 } 306 307 return getBasicDrawElementsErrorImpl(context); 308 } 309 310 // Places that can trigger updateValidDrawModes: 311 // 1. onProgramExecutableChange. 312 // 2. onActiveTransformFeedbackChange. isValidDrawMode(PrimitiveMode primitiveMode)313 bool isValidDrawMode(PrimitiveMode primitiveMode) const 314 { 315 return mCachedValidDrawModes[primitiveMode]; 316 } 317 318 // Cannot change except on Context/Extension init. isValidBindTextureType(TextureType type)319 bool isValidBindTextureType(TextureType type) const 320 { 321 return mCachedValidBindTextureTypes[type]; 322 } 323 324 // Cannot change except on Context/Extension init. isValidDrawElementsType(DrawElementsType type)325 bool isValidDrawElementsType(DrawElementsType type) const 326 { 327 return mCachedValidDrawElementsTypes[type]; 328 } 329 330 // Places that can trigger updateTransformFeedbackActiveUnpaused: 331 // 1. onActiveTransformFeedbackChange. isTransformFeedbackActiveUnpaused()332 bool isTransformFeedbackActiveUnpaused() const 333 { 334 return mCachedTransformFeedbackActiveUnpaused; 335 } 336 337 // Cannot change except on Context/Extension init. getVertexAttribTypeValidation(VertexAttribType type)338 VertexAttribTypeCase getVertexAttribTypeValidation(VertexAttribType type) const 339 { 340 return mCachedVertexAttribTypesValidation[type]; 341 } 342 getIntegerVertexAttribTypeValidation(VertexAttribType type)343 VertexAttribTypeCase getIntegerVertexAttribTypeValidation(VertexAttribType type) const 344 { 345 return mCachedIntegerVertexAttribTypesValidation[type]; 346 } 347 348 // Places that can trigger updateActiveShaderStorageBufferIndices: 349 // 1. onProgramExecutableChange. getActiveShaderStorageBufferIndices()350 StorageBuffersMask getActiveShaderStorageBufferIndices() const 351 { 352 return mCachedActiveShaderStorageBufferIndices; 353 } 354 355 // Places that can trigger updateActiveImageUnitIndices: 356 // 1. onProgramExecutableChange. getActiveImageUnitIndices()357 const ImageUnitMask &getActiveImageUnitIndices() const { return mCachedActiveImageUnitIndices; } 358 359 // Places that can trigger updateCanDraw: 360 // 1. onProgramExecutableChange. getCanDraw()361 bool getCanDraw() const { return mCachedCanDraw; } 362 363 // State change notifications. 364 void onVertexArrayBindingChange(Context *context); 365 void onProgramExecutableChange(Context *context); 366 void onVertexArrayFormatChange(Context *context); 367 void onVertexArrayBufferContentsChange(Context *context); 368 void onVertexArrayStateChange(Context *context); 369 void onVertexArrayBufferStateChange(Context *context); 370 void onGLES1TextureStateChange(Context *context); 371 void onGLES1ClientStateChange(Context *context); 372 void onDrawFramebufferChange(Context *context); 373 void onActiveTextureChange(Context *context); 374 void onQueryChange(Context *context); 375 void onActiveTransformFeedbackChange(Context *context); 376 void onUniformBufferStateChange(Context *context); 377 void onAtomicCounterBufferStateChange(Context *context); 378 void onShaderStorageBufferStateChange(Context *context); 379 void onBufferBindingChange(Context *context); 380 381 private: 382 bool isCurrentContext(const Context *context, const PrivateStateCache *privateStateCache) const; 383 384 // Cache update functions. 385 void updateActiveAttribsMask(Context *context); 386 void updateVertexElementLimits(Context *context); 387 void updateVertexElementLimitsImpl(Context *context); 388 void updateValidDrawModes(Context *context); 389 void updateValidBindTextureTypes(Context *context); 390 void updateValidDrawElementsTypes(Context *context); updateBasicDrawStatesError()391 void updateBasicDrawStatesError() 392 { 393 mCachedBasicDrawStatesErrorString = kInvalidPointer; 394 mCachedBasicDrawStatesErrorCode = GL_NO_ERROR; 395 } updateProgramPipelineError()396 void updateProgramPipelineError() { mCachedProgramPipelineError = kInvalidPointer; } updateBasicDrawElementsError()397 void updateBasicDrawElementsError() { mCachedBasicDrawElementsError = kInvalidPointer; } 398 void updateTransformFeedbackActiveUnpaused(Context *context); 399 void updateVertexAttribTypesValidation(Context *context); 400 void updateActiveShaderStorageBufferIndices(Context *context); 401 void updateActiveImageUnitIndices(Context *context); 402 void updateCanDraw(Context *context); 403 404 void setValidDrawModes(bool pointsOK, 405 bool linesOK, 406 bool trisOK, 407 bool lineAdjOK, 408 bool triAdjOK, 409 bool patchOK); 410 411 intptr_t getBasicDrawStatesErrorImpl(const Context *context, 412 const PrivateStateCache *privateStateCache) const; 413 intptr_t getProgramPipelineErrorImpl(const Context *context) const; 414 intptr_t getBasicDrawElementsErrorImpl(const Context *context) const; 415 416 static constexpr intptr_t kInvalidPointer = 1; 417 418 AttributesMask mCachedActiveBufferedAttribsMask; 419 AttributesMask mCachedActiveClientAttribsMask; 420 AttributesMask mCachedActiveDefaultAttribsMask; 421 422 // Given a vertex attribute's stride, the corresponding vertex buffer can fit a number of such 423 // attributes. A draw call that attempts to use more vertex attributes thus needs to fail (when 424 // robust access is enabled). The following variables help implement this limit given the 425 // following situations: 426 // 427 // Assume: 428 // 429 // Ni = Number of vertex attributes that can fit in buffer bound to attribute i. 430 // Di = Vertex attribute divisor set for attribute i. 431 // F = Draw calls "first" vertex index 432 // C = Draw calls vertex "count" 433 // B = Instanced draw calls "baseinstance" 434 // P = Instanced draw calls "primcount" 435 // 436 // Then, for each attribute i: 437 // 438 // If Di == 0 (i.e. non-instanced) 439 // Vertices [F, F+C) are accessed 440 // Draw call should fail if F+C > Ni 441 // 442 // If Di != 0 (i.e. instanced), in a non-instanced draw call: 443 // Only vertex 0 is accessed - note that a non-zero divisor in a non-instanced draw call 444 // implies that F is ignored and the vertex index is not incremented. 445 // Draw call should fail if Ni < 1 446 // 447 // If Di != 0, in an instanced draw call: 448 // Vertices [B, B+ceil(P/Di)) are accessed 449 // Draw call should fail if B+ceil(P/Di) > Ni 450 // 451 // To avoid needing to iterate over all attributes in the hot paths, the following is 452 // calculated: 453 // 454 // Non-instanced limit: min(Ni) for all non-instanced attributes. At draw time F+C <= min(Ni) 455 // is validated. 456 // Instanced limit: min(Ni*Di) for all instanced attributes. At draw time, B+P <= min(Ni*Di) is 457 // validated (the math works out, try with an example!) 458 // 459 // For instanced attributes in a non-instanced draw call, need to check that min(Ni) > 0. 460 // Evaluating min(Ni*DI) > 0 produces the same result though, so the instanced limit is used 461 // there too. 462 // 463 // If there are no instanced attributes, the non-instanced limit is set to infinity. If there 464 // are no instanced attributes, the instanced limits are set to infinity. 465 GLint64 mCachedNonInstancedVertexElementLimit; 466 GLint64 mCachedInstancedVertexElementLimit; 467 468 mutable intptr_t mCachedBasicDrawStatesErrorString; 469 mutable GLenum mCachedBasicDrawStatesErrorCode; 470 mutable intptr_t mCachedBasicDrawElementsError; 471 // mCachedProgramPipelineError checks only the 472 // current-program-exists subset of mCachedBasicDrawStatesError. 473 // Therefore, mCachedProgramPipelineError follows 474 // mCachedBasicDrawStatesError in that if mCachedBasicDrawStatesError is 475 // no-error, so is mCachedProgramPipelineError. Otherwise, if 476 // mCachedBasicDrawStatesError is in error, the state of 477 // mCachedProgramPipelineError can be no-error or also in error, or 478 // unknown due to early exiting. 479 mutable intptr_t mCachedProgramPipelineError; 480 bool mCachedHasAnyEnabledClientAttrib; 481 bool mCachedTransformFeedbackActiveUnpaused; 482 StorageBuffersMask mCachedActiveShaderStorageBufferIndices; 483 ImageUnitMask mCachedActiveImageUnitIndices; 484 485 // Reserve an extra slot at the end of these maps for invalid enum. 486 angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1> 487 mCachedValidDrawModes; 488 angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1> 489 mCachedValidBindTextureTypes; 490 angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1> 491 mCachedValidDrawElementsTypes; 492 angle::PackedEnumMap<VertexAttribType, 493 VertexAttribTypeCase, 494 angle::EnumSize<VertexAttribType>() + 1> 495 mCachedVertexAttribTypesValidation; 496 angle::PackedEnumMap<VertexAttribType, 497 VertexAttribTypeCase, 498 angle::EnumSize<VertexAttribType>() + 1> 499 mCachedIntegerVertexAttribTypesValidation; 500 501 bool mCachedCanDraw; 502 }; 503 504 using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>; 505 using QueryMap = ResourceMap<Query, QueryID>; 506 using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>; 507 508 class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface 509 { 510 public: 511 Context(egl::Display *display, 512 const egl::Config *config, 513 const Context *shareContext, 514 TextureManager *shareTextures, 515 SemaphoreManager *shareSemaphores, 516 egl::ContextMutex *sharedContextMutex, 517 MemoryProgramCache *memoryProgramCache, 518 MemoryShaderCache *memoryShaderCache, 519 const egl::AttributeMap &attribs, 520 const egl::DisplayExtensions &displayExtensions, 521 const egl::ClientExtensions &clientExtensions); 522 523 // Use for debugging. id()524 ContextID id() const { return mState.getContextID(); } 525 526 egl::Error initialize(); 527 528 egl::Error onDestroy(const egl::Display *display); 529 ~Context() override; 530 531 void setLabel(EGLLabelKHR label) override; 532 EGLLabelKHR getLabel() const override; 533 534 egl::Error makeCurrent(egl::Display *display, 535 egl::Surface *drawSurface, 536 egl::Surface *readSurface); 537 egl::Error unMakeCurrent(const egl::Display *display); 538 539 // These create and destroy methods pass through to ResourceManager, which owns these objects. 540 BufferID createBuffer(); 541 TextureID createTexture(); 542 RenderbufferID createRenderbuffer(); 543 ProgramPipelineID createProgramPipeline(); 544 MemoryObjectID createMemoryObject(); 545 SemaphoreID createSemaphore(); 546 547 void deleteBuffer(BufferID buffer); 548 void deleteTexture(TextureID texture); 549 void deleteRenderbuffer(RenderbufferID renderbuffer); 550 void deleteProgramPipeline(ProgramPipelineID pipeline); 551 void deleteMemoryObject(MemoryObjectID memoryObject); 552 void deleteSemaphore(SemaphoreID semaphore); 553 554 void bindReadFramebuffer(FramebufferID framebufferHandle); 555 void bindDrawFramebuffer(FramebufferID framebufferHandle); 556 557 Buffer *getBuffer(BufferID handle) const; 558 FenceNV *getFenceNV(FenceNVID handle) const; 559 Sync *getSync(SyncID syncPacked) const; getTexture(TextureID handle)560 ANGLE_INLINE Texture *getTexture(TextureID handle) const 561 { 562 return mState.mTextureManager->getTexture(handle); 563 } 564 565 Framebuffer *getFramebuffer(FramebufferID handle) const; 566 Renderbuffer *getRenderbuffer(RenderbufferID handle) const; 567 VertexArray *getVertexArray(VertexArrayID handle) const; 568 Sampler *getSampler(SamplerID handle) const; 569 Query *getOrCreateQuery(QueryID handle, QueryType type); 570 Query *getQuery(QueryID handle) const; 571 TransformFeedback *getTransformFeedback(TransformFeedbackID handle) const; 572 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 573 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 574 Semaphore *getSemaphore(SemaphoreID handle) const; 575 576 Texture *getTextureByType(TextureType type) const; 577 Texture *getTextureByTarget(TextureTarget target) const; 578 Texture *getSamplerTexture(unsigned int sampler, TextureType type) const; 579 580 Compiler *getCompiler() const; 581 582 bool isVertexArrayGenerated(VertexArrayID vertexArray) const; 583 bool isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const; 584 isExternal()585 bool isExternal() const { return mState.isExternal(); } 586 587 void getBooleanvImpl(GLenum pname, GLboolean *params) const; 588 void getFloatvImpl(GLenum pname, GLfloat *params) const; 589 void getIntegervImpl(GLenum pname, GLint *params) const; 590 void getInteger64vImpl(GLenum pname, GLint64 *params) const; 591 void getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const; 592 void getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const; 593 594 // Framebuffers are owned by the Context, so these methods do not pass through 595 FramebufferID createFramebuffer(); 596 void deleteFramebuffer(FramebufferID framebuffer); 597 598 bool hasActiveTransformFeedback(ShaderProgramID program) const; 599 600 // GLES entry point interface 601 ANGLE_GLES_1_0_CONTEXT_API 602 ANGLE_GLES_2_0_CONTEXT_API 603 ANGLE_GLES_3_0_CONTEXT_API 604 ANGLE_GLES_3_1_CONTEXT_API 605 ANGLE_GLES_3_2_CONTEXT_API 606 ANGLE_GLES_EXT_CONTEXT_API 607 608 angle::Result handleNoopDrawEvent(); 609 610 // Consumes an error. 611 void handleError(GLenum errorCode, 612 const char *message, 613 const char *file, 614 const char *function, 615 unsigned int line); 616 617 bool isResetNotificationEnabled() const; 618 isRobustnessEnabled()619 bool isRobustnessEnabled() const { return mState.hasRobustAccess(); } 620 getConfig()621 const egl::Config *getConfig() const { return mConfig; } 622 EGLenum getRenderBuffer() const; 623 EGLenum getContextPriority() const; 624 625 const GLubyte *getString(GLenum name) const; 626 const GLubyte *getStringi(GLenum name, GLuint index) const; 627 628 size_t getExtensionStringCount() const; 629 630 bool isExtensionRequestable(const char *name) const; 631 bool isExtensionDisablable(const char *name) const; 632 size_t getRequestableExtensionStringCount() const; 633 void setExtensionEnabled(const char *name, bool enabled); 634 void reinitializeAfterExtensionsChanged(); 635 getImplementation()636 rx::ContextImpl *getImplementation() const { return mImplementation.get(); } 637 638 [[nodiscard]] bool getScratchBuffer(size_t requestedSizeBytes, 639 angle::MemoryBuffer **scratchBufferOut) const; 640 [[nodiscard]] bool getZeroFilledBuffer(size_t requstedSizeBytes, 641 angle::MemoryBuffer **zeroBufferOut) const; 642 angle::ScratchBuffer *getScratchBuffer() const; 643 644 angle::Result prepareForCopyImage(); 645 angle::Result prepareForDispatch(); 646 angle::Result prepareForInvalidate(GLenum target); 647 getMemoryProgramCache()648 MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; } getMemoryShaderCache()649 MemoryShaderCache *getMemoryShaderCache() const { return mMemoryShaderCache; } 650 651 angle::SimpleMutex &getProgramCacheMutex() const; 652 hasBeenCurrent()653 bool hasBeenCurrent() const { return mHasBeenCurrent; } getDisplay()654 egl::Display *getDisplay() const { return mDisplay; } getCurrentDrawSurface()655 egl::Surface *getCurrentDrawSurface() const { return mCurrentDrawSurface; } getCurrentReadSurface()656 egl::Surface *getCurrentReadSurface() const { return mCurrentReadSurface; } 657 isRobustResourceInitEnabled()658 bool isRobustResourceInitEnabled() const { return mState.isRobustResourceInitEnabled(); } 659 660 bool isCurrentTransformFeedback(const TransformFeedback *tf) const; 661 isCurrentVertexArray(const VertexArray * va)662 bool isCurrentVertexArray(const VertexArray *va) const 663 { 664 return mState.isCurrentVertexArray(va); 665 } 666 isShared()667 ANGLE_INLINE bool isShared() const { return mShared; } 668 // Once a context is setShared() it cannot be undone setShared()669 void setShared() { mShared = true; } 670 getState()671 const State &getState() const { return mState; } getPrivateState()672 const PrivateState &getPrivateState() const { return mState.privateState(); } getClientMajorVersion()673 GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); } getClientMinorVersion()674 GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); } getClientVersion()675 const Version &getClientVersion() const { return mState.getClientVersion(); } getCaps()676 const Caps &getCaps() const { return mState.getCaps(); } getTextureCaps()677 const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } getExtensions()678 const Extensions &getExtensions() const { return mState.getExtensions(); } getLimitations()679 const Limitations &getLimitations() const { return mState.getLimitations(); } 680 bool isGLES1() const; 681 682 // To be used **only** directly by the entry points. getMutablePrivateState()683 PrivateState *getMutablePrivateState() { return mState.getMutablePrivateState(); } getMutableGLES1State()684 GLES1State *getMutableGLES1State() { return mState.getMutableGLES1State(); } 685 skipValidation()686 bool skipValidation() const { return mErrors.skipValidation(); } markContextLost(GraphicsResetStatus status)687 void markContextLost(GraphicsResetStatus status) { mErrors.markContextLost(status); } isContextLost()688 bool isContextLost() const { return mErrors.isContextLost(); } 689 getMutableErrorSetForValidation()690 ErrorSet *getMutableErrorSetForValidation() const { return &mErrors; } 691 692 // Specific methods needed for validation. 693 bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const; 694 bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const; 695 getProgramResolveLink(ShaderProgramID handle)696 ANGLE_INLINE Program *getProgramResolveLink(ShaderProgramID handle) const 697 { 698 Program *program = mState.mShaderProgramManager->getProgram(handle); 699 if (ANGLE_LIKELY(program)) 700 { 701 program->resolveLink(this); 702 } 703 return program; 704 } 705 706 Program *getProgramNoResolveLink(ShaderProgramID handle) const; 707 Shader *getShaderResolveCompile(ShaderProgramID handle) const; 708 Shader *getShaderNoResolveCompile(ShaderProgramID handle) const; 709 isTextureGenerated(TextureID texture)710 ANGLE_INLINE bool isTextureGenerated(TextureID texture) const 711 { 712 return mState.mTextureManager->isHandleGenerated(texture); 713 } 714 isBufferGenerated(BufferID buffer)715 ANGLE_INLINE bool isBufferGenerated(BufferID buffer) const 716 { 717 return mState.mBufferManager->isHandleGenerated(buffer); 718 } 719 720 bool isRenderbufferGenerated(RenderbufferID renderbuffer) const; 721 bool isFramebufferGenerated(FramebufferID framebuffer) const; 722 bool isProgramPipelineGenerated(ProgramPipelineID pipeline) const; 723 bool isQueryGenerated(QueryID query) const; 724 725 bool usingDisplayTextureShareGroup() const; 726 bool usingDisplaySemaphoreShareGroup() const; 727 728 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. 729 GLenum getConvertedRenderbufferFormat(GLenum internalformat) const; 730 isWebGL()731 bool isWebGL() const { return mState.isWebGL(); } isWebGL1()732 bool isWebGL1() const { return mState.isWebGL1(); } getRendererString()733 const char *getRendererString() const { return mRendererString; } 734 isValidBufferBinding(BufferBinding binding)735 bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; } 736 737 // GLES1 emulation: Renderer level (for validation) 738 int vertexArrayIndex(ClientVertexArrayType type) const; 739 static int TexCoordArrayIndex(unsigned int unit); 740 741 // GL_KHR_parallel_shader_compile 742 std::shared_ptr<angle::WorkerThreadPool> getShaderCompileThreadPool() const; 743 std::shared_ptr<angle::WorkerThreadPool> getLinkSubTaskThreadPool() const; 744 std::shared_ptr<angle::WaitableEvent> postCompileLinkTask( 745 const std::shared_ptr<angle::Closure> &task, 746 angle::JobThreadSafety safety, 747 angle::JobResultExpectancy resultExpectancy) const; 748 749 // Single-threaded pool; runs everything instantly 750 std::shared_ptr<angle::WorkerThreadPool> getSingleThreadPool() const; 751 752 // Generic multithread pool. 753 std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const; 754 getStateCache()755 const StateCache &getStateCache() const { return mStateCache; } getStateCache()756 StateCache &getStateCache() { return mStateCache; } 757 getPrivateStateCache()758 const PrivateStateCache &getPrivateStateCache() const { return mPrivateStateCache; } getMutablePrivateStateCache()759 PrivateStateCache *getMutablePrivateStateCache() { return &mPrivateStateCache; } 760 761 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 762 763 void onSamplerUniformChange(size_t textureUnitIndex); 764 isBufferAccessValidationEnabled()765 bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; } 766 767 const angle::FrontendFeatures &getFrontendFeatures() const; 768 getFrameCapture()769 angle::FrameCapture *getFrameCapture() const { return mFrameCapture.get(); } 770 getVertexArraysForCapture()771 const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; } getQueriesForCapture()772 const QueryMap &getQueriesForCapture() const { return mQueryMap; } getTransformFeedbacksForCapture()773 const TransformFeedbackMap &getTransformFeedbacksForCapture() const 774 { 775 return mTransformFeedbackMap; 776 } getErrorForCapture()777 GLenum getErrorForCapture() const { return mErrors.getErrorForCapture(); } 778 779 void onPreSwap(); 780 getActiveLinkedProgram()781 ANGLE_INLINE Program *getActiveLinkedProgram() const 782 { 783 Program *program = mState.getLinkedProgram(this); 784 if (ANGLE_LIKELY(program)) 785 { 786 return program; 787 } 788 return getActiveLinkedProgramPPO(); 789 } 790 791 ANGLE_NOINLINE Program *getActiveLinkedProgramPPO() const; 792 793 // EGL_ANGLE_power_preference implementation. 794 egl::Error releaseHighPowerGPU(); 795 egl::Error reacquireHighPowerGPU(); 796 void onGPUSwitch(); 797 798 // EGL_ANGLE_external_context_and_surface implementation. 799 egl::Error acquireExternalContext(egl::Surface *drawAndReadSurface); 800 egl::Error releaseExternalContext(); 801 802 bool noopDraw(PrimitiveMode mode, GLsizei count) const; 803 bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const; 804 bool noopMultiDraw(GLsizei drawcount) const; 805 806 bool isClearBufferMaskedOut(GLenum buffer, 807 GLint drawbuffer, 808 GLuint framebufferStencilSize) const; 809 bool noopClearBuffer(GLenum buffer, GLint drawbuffer) const; 810 addRef()811 void addRef() const { mRefCount++; } release()812 void release() const { mRefCount--; } isReferenced()813 bool isReferenced() const { return mRefCount > 0; } 814 getShareGroup()815 egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); } 816 817 // Warning! When need to store pointer to the mutex in other object use `getRoot()` pointer, do 818 // NOT get pointer of the `getContextMutex()` reference. getContextMutex()819 egl::ContextMutex &getContextMutex() const { return mState.mContextMutex; } 820 821 bool supportsGeometryOrTesselation() const; 822 void dirtyAllState(); 823 isDestroyed()824 bool isDestroyed() const { return mIsDestroyed; } setIsDestroyed()825 void setIsDestroyed() { mIsDestroyed = true; } 826 827 // This function acts as glEnable(GL_COLOR_LOGIC_OP), but it's called from the GLES1 emulation 828 // code to implement logicOp using the non-GLES1 functionality (i.e. GL_ANGLE_logic_op). The 829 // ContextPrivateEnable() entry point implementation cannot be used (as ContextPrivate* 830 // functions are typically used by other frontend-emulated features) because it forwards this 831 // back to GLES1. 832 void setLogicOpEnabledForGLES1(bool enabled); 833 834 // Needed by capture serialization logic that works with a "const" Context pointer. 835 void finishImmutable() const; 836 837 const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const; 838 839 // Ends the currently active pixel local storage session with GL_STORE_OP_STORE on all planes. 840 void endPixelLocalStorageImplicit(); 841 842 bool areBlobCacheFuncsSet() const; 843 844 size_t getMemoryUsage() const; 845 846 // Only used by vulkan backend. onSwapChainImageChanged()847 void onSwapChainImageChanged() const { mDefaultFramebuffer->onSwapChainImageChanged(); } 848 849 private: 850 void initializeDefaultResources(); 851 void releaseSharedObjects(); 852 853 angle::Result prepareForDraw(PrimitiveMode mode); 854 angle::Result prepareForClear(GLbitfield mask); 855 angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer); 856 angle::Result syncState(const state::DirtyBits bitMask, 857 const state::ExtendedDirtyBits extendedBitMask, 858 const state::DirtyObjects &objectMask, 859 Command command); 860 angle::Result syncAllDirtyBits(Command command); 861 angle::Result syncDirtyBits(const state::DirtyBits bitMask, 862 const state::ExtendedDirtyBits extendedBitMask, 863 Command command); 864 angle::Result syncDirtyObjects(const state::DirtyObjects &objectMask, Command command); 865 angle::Result syncStateForReadPixels(); 866 angle::Result syncStateForTexImage(); 867 angle::Result syncStateForBlit(GLbitfield mask); 868 angle::Result syncStateForClear(); 869 angle::Result syncTextureForCopy(Texture *texture); 870 871 VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle); 872 TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback); 873 874 void detachBuffer(Buffer *buffer); 875 void detachTexture(TextureID texture); 876 void detachFramebuffer(FramebufferID framebuffer); 877 void detachRenderbuffer(RenderbufferID renderbuffer); 878 void detachVertexArray(VertexArrayID vertexArray); 879 void detachTransformFeedback(TransformFeedbackID transformFeedback); 880 void detachSampler(SamplerID sampler); 881 void detachProgramPipeline(ProgramPipelineID pipeline); 882 883 egl::Error setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface); 884 egl::Error unsetDefaultFramebuffer(); 885 886 void initRendererString(); 887 void initVendorString(); 888 void initVersionStrings(); 889 void initExtensionStrings(); 890 891 Extensions generateSupportedExtensions() const; 892 void initCaps(); 893 void updateCaps(); 894 895 gl::LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; 896 gl::LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; 897 898 void setUniform1iImpl(Program *program, 899 UniformLocation location, 900 GLsizei count, 901 const GLint *v); 902 void renderbufferStorageMultisampleImpl(GLenum target, 903 GLsizei samples, 904 GLenum internalformat, 905 GLsizei width, 906 GLsizei height, 907 MultisamplingMode mode); 908 909 void onUniformBlockBindingUpdated(GLuint uniformBlockIndex); 910 911 void endTilingImplicit(); 912 913 State mState; 914 bool mShared; 915 bool mDisplayTextureShareGroup; 916 bool mDisplaySemaphoreShareGroup; 917 918 // Recorded errors 919 mutable ErrorSet mErrors; 920 921 // Stores for each buffer binding type whether is it allowed to be used in this context. 922 angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings; 923 924 std::unique_ptr<rx::ContextImpl> mImplementation; 925 926 EGLLabelKHR mLabel; 927 928 // Extensions supported by the implementation plus extensions that are implemented entirely 929 // within the frontend. 930 Extensions mSupportedExtensions; 931 932 // Shader compiler. Lazily initialized hence the mutable value. 933 mutable BindingPointer<Compiler> mCompiler; 934 935 const egl::Config *mConfig; 936 937 TextureMap mZeroTextures; 938 939 ResourceMap<FenceNV, FenceNVID> mFenceNVMap; 940 HandleAllocator mFenceNVHandleAllocator; 941 942 QueryMap mQueryMap; 943 HandleAllocator mQueryHandleAllocator; 944 945 VertexArrayMap mVertexArrayMap; 946 HandleAllocator mVertexArrayHandleAllocator; 947 948 TransformFeedbackMap mTransformFeedbackMap; 949 HandleAllocator mTransformFeedbackHandleAllocator; 950 951 const char *mVendorString; 952 const char *mVersionString; 953 const char *mShadingLanguageString; 954 const char *mRendererString; 955 const char *mExtensionString; 956 std::vector<const char *> mExtensionStrings; 957 const char *mRequestableExtensionString; 958 std::vector<const char *> mRequestableExtensionStrings; 959 960 // GLES1 renderer state 961 std::unique_ptr<GLES1Renderer> mGLES1Renderer; 962 963 // Current/lost context flags 964 bool mHasBeenCurrent; 965 const bool mSurfacelessSupported; 966 egl::Surface *mCurrentDrawSurface; 967 egl::Surface *mCurrentReadSurface; 968 egl::Display *mDisplay; 969 const bool mWebGLContext; 970 bool mBufferAccessValidationEnabled; 971 const bool mExtensionsEnabled; 972 MemoryProgramCache *mMemoryProgramCache; 973 MemoryShaderCache *mMemoryShaderCache; 974 975 state::DirtyObjects mDrawDirtyObjects; 976 977 StateCache mStateCache; 978 PrivateStateCache mPrivateStateCache; 979 980 state::DirtyObjects mTexImageDirtyObjects; 981 state::DirtyObjects mReadPixelsDirtyObjects; 982 state::DirtyObjects mClearDirtyObjects; 983 state::DirtyObjects mBlitDirtyObjects; 984 state::DirtyObjects mComputeDirtyObjects; 985 state::DirtyBits mCopyImageDirtyBits; 986 state::DirtyObjects mCopyImageDirtyObjects; 987 988 // Binding to container objects that use dependent state updates. 989 angle::ObserverBinding mVertexArrayObserverBinding; 990 angle::ObserverBinding mDrawFramebufferObserverBinding; 991 angle::ObserverBinding mReadFramebufferObserverBinding; 992 angle::ObserverBinding mProgramObserverBinding; 993 angle::ObserverBinding mProgramPipelineObserverBinding; 994 std::vector<angle::ObserverBinding> mUniformBufferObserverBindings; 995 std::vector<angle::ObserverBinding> mAtomicCounterBufferObserverBindings; 996 std::vector<angle::ObserverBinding> mShaderStorageBufferObserverBindings; 997 std::vector<angle::ObserverBinding> mSamplerObserverBindings; 998 std::vector<angle::ObserverBinding> mImageObserverBindings; 999 1000 // Not really a property of context state. The size and contexts change per-api-call. 1001 mutable Optional<angle::ScratchBuffer> mScratchBuffer; 1002 mutable Optional<angle::ScratchBuffer> mZeroFilledBuffer; 1003 1004 // Note: we use a raw pointer here so we can exclude frame capture sources from the build. 1005 std::unique_ptr<angle::FrameCapture> mFrameCapture; 1006 1007 // Cache representation of the serialized context string. 1008 mutable std::string mCachedSerializedStateString; 1009 1010 mutable size_t mRefCount; 1011 1012 OverlayType mOverlay; 1013 1014 bool mIsDestroyed; 1015 1016 std::unique_ptr<Framebuffer> mDefaultFramebuffer; 1017 }; 1018 1019 class [[nodiscard]] ScopedContextRef 1020 { 1021 public: ScopedContextRef(Context * context)1022 ScopedContextRef(Context *context) : mContext(context) 1023 { 1024 if (mContext) 1025 { 1026 mContext->addRef(); 1027 } 1028 } ~ScopedContextRef()1029 ~ScopedContextRef() 1030 { 1031 if (mContext) 1032 { 1033 mContext->release(); 1034 } 1035 } 1036 1037 private: 1038 Context *const mContext; 1039 }; 1040 1041 // Thread-local current valid context bound to the thread. 1042 #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES) 1043 extern Context *GetCurrentValidContextTLS(); 1044 extern void SetCurrentValidContextTLS(Context *context); 1045 #else 1046 extern thread_local Context *gCurrentValidContext; 1047 #endif 1048 1049 extern void SetCurrentValidContext(Context *context); 1050 1051 } // namespace gl 1052 1053 #endif // LIBANGLE_CONTEXT_H_ 1054