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