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