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); 391 void updateBasicDrawStatesError(); 392 void updateProgramPipelineError(); 393 void updateBasicDrawElementsError(); 394 void updateTransformFeedbackActiveUnpaused(Context *context); 395 void updateVertexAttribTypesValidation(Context *context); 396 void updateActiveShaderStorageBufferIndices(Context *context); 397 void updateActiveImageUnitIndices(Context *context); 398 void updateCanDraw(Context *context); 399 400 void setValidDrawModes(bool pointsOK, 401 bool linesOK, 402 bool trisOK, 403 bool lineAdjOK, 404 bool triAdjOK, 405 bool patchOK); 406 407 intptr_t getBasicDrawStatesErrorImpl(const Context *context, 408 const PrivateStateCache *privateStateCache) const; 409 intptr_t getProgramPipelineErrorImpl(const Context *context) const; 410 intptr_t getBasicDrawElementsErrorImpl(const Context *context) const; 411 412 static constexpr intptr_t kInvalidPointer = 1; 413 414 AttributesMask mCachedActiveBufferedAttribsMask; 415 AttributesMask mCachedActiveClientAttribsMask; 416 AttributesMask mCachedActiveDefaultAttribsMask; 417 418 // Given a vertex attribute's stride, the corresponding vertex buffer can fit a number of such 419 // attributes. A draw call that attempts to use more vertex attributes thus needs to fail (when 420 // robust access is enabled). The following variables help implement this limit given the 421 // following situations: 422 // 423 // Assume: 424 // 425 // Ni = Number of vertex attributes that can fit in buffer bound to attribute i. 426 // Di = Vertex attribute divisor set for attribute i. 427 // F = Draw calls "first" vertex index 428 // C = Draw calls vertex "count" 429 // B = Instanced draw calls "baseinstance" 430 // P = Instanced draw calls "primcount" 431 // 432 // Then, for each attribute i: 433 // 434 // If Di == 0 (i.e. non-instanced) 435 // Vertices [F, F+C) are accessed 436 // Draw call should fail if F+C > Ni 437 // 438 // If Di != 0 (i.e. instanced), in a non-instanced draw call: 439 // Only vertex 0 is accessed - note that a non-zero divisor in a non-instanced draw call 440 // implies that F is ignored and the vertex index is not incremented. 441 // Draw call should fail if Ni < 1 442 // 443 // If Di != 0, in an instanced draw call: 444 // Vertices [B, B+ceil(P/Di)) are accessed 445 // Draw call should fail if B+ceil(P/Di) > Ni 446 // 447 // To avoid needing to iterate over all attributes in the hot paths, the following is 448 // calculated: 449 // 450 // Non-instanced limit: min(Ni) for all non-instanced attributes. At draw time F+C <= min(Ni) 451 // is validated. 452 // Instanced limit: min(Ni*Di) for all instanced attributes. At draw time, B+P <= min(Ni*Di) is 453 // validated (the math works out, try with an example!) 454 // 455 // For instanced attributes in a non-instanced draw call, need to check that min(Ni) > 0. 456 // Evaluating min(Ni*DI) > 0 produces the same result though, so the instanced limit is used 457 // there too. 458 // 459 // If there are no instanced attributes, the non-instanced limit is set to infinity. If there 460 // are no instanced attributes, the instanced limits are set to infinity. 461 GLint64 mCachedNonInstancedVertexElementLimit; 462 GLint64 mCachedInstancedVertexElementLimit; 463 464 mutable intptr_t mCachedBasicDrawStatesErrorString; 465 mutable GLenum mCachedBasicDrawStatesErrorCode; 466 mutable intptr_t mCachedBasicDrawElementsError; 467 // mCachedProgramPipelineError checks only the 468 // current-program-exists subset of mCachedBasicDrawStatesError. 469 // Therefore, mCachedProgramPipelineError follows 470 // mCachedBasicDrawStatesError in that if mCachedBasicDrawStatesError is 471 // no-error, so is mCachedProgramPipelineError. Otherwise, if 472 // mCachedBasicDrawStatesError is in error, the state of 473 // mCachedProgramPipelineError can be no-error or also in error, or 474 // unknown due to early exiting. 475 mutable intptr_t mCachedProgramPipelineError; 476 bool mCachedHasAnyEnabledClientAttrib; 477 bool mCachedTransformFeedbackActiveUnpaused; 478 StorageBuffersMask mCachedActiveShaderStorageBufferIndices; 479 ImageUnitMask mCachedActiveImageUnitIndices; 480 481 // Reserve an extra slot at the end of these maps for invalid enum. 482 angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1> 483 mCachedValidDrawModes; 484 angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1> 485 mCachedValidBindTextureTypes; 486 angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1> 487 mCachedValidDrawElementsTypes; 488 angle::PackedEnumMap<VertexAttribType, 489 VertexAttribTypeCase, 490 angle::EnumSize<VertexAttribType>() + 1> 491 mCachedVertexAttribTypesValidation; 492 angle::PackedEnumMap<VertexAttribType, 493 VertexAttribTypeCase, 494 angle::EnumSize<VertexAttribType>() + 1> 495 mCachedIntegerVertexAttribTypesValidation; 496 497 bool mCachedCanDraw; 498 }; 499 500 using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>; 501 using QueryMap = ResourceMap<Query, QueryID>; 502 using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>; 503 504 class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface 505 { 506 public: 507 Context(egl::Display *display, 508 const egl::Config *config, 509 const Context *shareContext, 510 TextureManager *shareTextures, 511 SemaphoreManager *shareSemaphores, 512 egl::ContextMutex *sharedContextMutex, 513 MemoryProgramCache *memoryProgramCache, 514 MemoryShaderCache *memoryShaderCache, 515 const egl::AttributeMap &attribs, 516 const egl::DisplayExtensions &displayExtensions, 517 const egl::ClientExtensions &clientExtensions); 518 519 // Use for debugging. id()520 ContextID id() const { return mState.getContextID(); } 521 522 egl::Error initialize(); 523 524 egl::Error onDestroy(const egl::Display *display); 525 ~Context() override; 526 527 void setLabel(EGLLabelKHR label) override; 528 EGLLabelKHR getLabel() const override; 529 530 egl::Error makeCurrent(egl::Display *display, 531 egl::Surface *drawSurface, 532 egl::Surface *readSurface); 533 egl::Error unMakeCurrent(const egl::Display *display); 534 535 // These create and destroy methods pass through to ResourceManager, which owns these objects. 536 BufferID createBuffer(); 537 TextureID createTexture(); 538 RenderbufferID createRenderbuffer(); 539 ProgramPipelineID createProgramPipeline(); 540 MemoryObjectID createMemoryObject(); 541 SemaphoreID createSemaphore(); 542 543 void deleteBuffer(BufferID buffer); 544 void deleteTexture(TextureID texture); 545 void deleteRenderbuffer(RenderbufferID renderbuffer); 546 void deleteProgramPipeline(ProgramPipelineID pipeline); 547 void deleteMemoryObject(MemoryObjectID memoryObject); 548 void deleteSemaphore(SemaphoreID semaphore); 549 550 void bindReadFramebuffer(FramebufferID framebufferHandle); 551 void bindDrawFramebuffer(FramebufferID framebufferHandle); 552 553 Buffer *getBuffer(BufferID handle) const; 554 FenceNV *getFenceNV(FenceNVID handle) const; 555 Sync *getSync(SyncID syncPacked) const; getTexture(TextureID handle)556 ANGLE_INLINE Texture *getTexture(TextureID handle) const 557 { 558 return mState.mTextureManager->getTexture(handle); 559 } 560 561 Framebuffer *getFramebuffer(FramebufferID handle) const; 562 Renderbuffer *getRenderbuffer(RenderbufferID handle) const; 563 VertexArray *getVertexArray(VertexArrayID handle) const; 564 Sampler *getSampler(SamplerID handle) const; 565 Query *getOrCreateQuery(QueryID handle, QueryType type); 566 Query *getQuery(QueryID handle) const; 567 TransformFeedback *getTransformFeedback(TransformFeedbackID handle) const; 568 ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const; 569 MemoryObject *getMemoryObject(MemoryObjectID handle) const; 570 Semaphore *getSemaphore(SemaphoreID handle) const; 571 572 Texture *getTextureByType(TextureType type) const; 573 Texture *getTextureByTarget(TextureTarget target) const; 574 Texture *getSamplerTexture(unsigned int sampler, TextureType type) const; 575 576 Compiler *getCompiler() const; 577 578 bool isVertexArrayGenerated(VertexArrayID vertexArray) const; 579 bool isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const; 580 isExternal()581 bool isExternal() const { return mState.isExternal(); } 582 583 void getBooleanvImpl(GLenum pname, GLboolean *params) const; 584 void getFloatvImpl(GLenum pname, GLfloat *params) const; 585 void getIntegervImpl(GLenum pname, GLint *params) const; 586 void getInteger64vImpl(GLenum pname, GLint64 *params) const; 587 void getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const; 588 void getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const; 589 590 // Framebuffers are owned by the Context, so these methods do not pass through 591 FramebufferID createFramebuffer(); 592 void deleteFramebuffer(FramebufferID framebuffer); 593 594 bool hasActiveTransformFeedback(ShaderProgramID program) const; 595 596 // GLES entry point interface 597 ANGLE_GLES_1_0_CONTEXT_API 598 ANGLE_GLES_2_0_CONTEXT_API 599 ANGLE_GLES_3_0_CONTEXT_API 600 ANGLE_GLES_3_1_CONTEXT_API 601 ANGLE_GLES_3_2_CONTEXT_API 602 ANGLE_GLES_EXT_CONTEXT_API 603 604 angle::Result handleNoopDrawEvent(); 605 606 // Consumes an error. 607 void handleError(GLenum errorCode, 608 const char *message, 609 const char *file, 610 const char *function, 611 unsigned int line); 612 613 bool isResetNotificationEnabled() const; 614 isRobustnessEnabled()615 bool isRobustnessEnabled() const { return mState.hasRobustAccess(); } 616 getConfig()617 const egl::Config *getConfig() const { return mConfig; } 618 EGLenum getRenderBuffer() const; 619 EGLenum getContextPriority() const; 620 621 const GLubyte *getString(GLenum name) const; 622 const GLubyte *getStringi(GLenum name, GLuint index) const; 623 624 size_t getExtensionStringCount() const; 625 626 bool isExtensionRequestable(const char *name) const; 627 bool isExtensionDisablable(const char *name) const; 628 size_t getRequestableExtensionStringCount() const; 629 void setExtensionEnabled(const char *name, bool enabled); 630 void reinitializeAfterExtensionsChanged(); 631 getImplementation()632 rx::ContextImpl *getImplementation() const { return mImplementation.get(); } 633 634 [[nodiscard]] bool getScratchBuffer(size_t requestedSizeBytes, 635 angle::MemoryBuffer **scratchBufferOut) const; 636 [[nodiscard]] bool getZeroFilledBuffer(size_t requstedSizeBytes, 637 angle::MemoryBuffer **zeroBufferOut) const; 638 angle::ScratchBuffer *getScratchBuffer() const; 639 640 angle::Result prepareForCopyImage(); 641 angle::Result prepareForDispatch(); 642 angle::Result prepareForInvalidate(GLenum target); 643 getMemoryProgramCache()644 MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; } getMemoryShaderCache()645 MemoryShaderCache *getMemoryShaderCache() const { return mMemoryShaderCache; } 646 647 angle::SimpleMutex &getProgramCacheMutex() const; 648 hasBeenCurrent()649 bool hasBeenCurrent() const { return mHasBeenCurrent; } getDisplay()650 egl::Display *getDisplay() const { return mDisplay; } getCurrentDrawSurface()651 egl::Surface *getCurrentDrawSurface() const { return mCurrentDrawSurface; } getCurrentReadSurface()652 egl::Surface *getCurrentReadSurface() const { return mCurrentReadSurface; } 653 isRobustResourceInitEnabled()654 bool isRobustResourceInitEnabled() const { return mState.isRobustResourceInitEnabled(); } 655 656 bool isCurrentTransformFeedback(const TransformFeedback *tf) const; 657 isCurrentVertexArray(const VertexArray * va)658 bool isCurrentVertexArray(const VertexArray *va) const 659 { 660 return mState.isCurrentVertexArray(va); 661 } 662 isShared()663 ANGLE_INLINE bool isShared() const { return mShared; } 664 // Once a context is setShared() it cannot be undone setShared()665 void setShared() { mShared = true; } 666 getState()667 const State &getState() const { return mState; } getPrivateState()668 const PrivateState &getPrivateState() const { return mState.privateState(); } getClientMajorVersion()669 GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); } getClientMinorVersion()670 GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); } getClientVersion()671 const Version &getClientVersion() const { return mState.getClientVersion(); } getCaps()672 const Caps &getCaps() const { return mState.getCaps(); } getTextureCaps()673 const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); } getExtensions()674 const Extensions &getExtensions() const { return mState.getExtensions(); } getLimitations()675 const Limitations &getLimitations() const { return mState.getLimitations(); } 676 bool isGLES1() const; 677 678 // To be used **only** directly by the entry points. getMutablePrivateState()679 PrivateState *getMutablePrivateState() { return mState.getMutablePrivateState(); } getMutableGLES1State()680 GLES1State *getMutableGLES1State() { return mState.getMutableGLES1State(); } 681 skipValidation()682 bool skipValidation() const { return mErrors.skipValidation(); } markContextLost(GraphicsResetStatus status)683 void markContextLost(GraphicsResetStatus status) { mErrors.markContextLost(status); } isContextLost()684 bool isContextLost() const { return mErrors.isContextLost(); } 685 getMutableErrorSetForValidation()686 ErrorSet *getMutableErrorSetForValidation() const { return &mErrors; } 687 688 // Specific methods needed for validation. 689 bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const; 690 bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const; 691 getProgramResolveLink(ShaderProgramID handle)692 ANGLE_INLINE Program *getProgramResolveLink(ShaderProgramID handle) const 693 { 694 Program *program = mState.mShaderProgramManager->getProgram(handle); 695 if (program) 696 { 697 program->resolveLink(this); 698 } 699 return program; 700 } 701 702 Program *getProgramNoResolveLink(ShaderProgramID handle) const; 703 Shader *getShaderResolveCompile(ShaderProgramID handle) const; 704 Shader *getShaderNoResolveCompile(ShaderProgramID handle) const; 705 isTextureGenerated(TextureID texture)706 ANGLE_INLINE bool isTextureGenerated(TextureID texture) const 707 { 708 return mState.mTextureManager->isHandleGenerated(texture); 709 } 710 isBufferGenerated(BufferID buffer)711 ANGLE_INLINE bool isBufferGenerated(BufferID buffer) const 712 { 713 return mState.mBufferManager->isHandleGenerated(buffer); 714 } 715 716 bool isRenderbufferGenerated(RenderbufferID renderbuffer) const; 717 bool isFramebufferGenerated(FramebufferID framebuffer) const; 718 bool isProgramPipelineGenerated(ProgramPipelineID pipeline) const; 719 bool isQueryGenerated(QueryID query) const; 720 721 bool usingDisplayTextureShareGroup() const; 722 bool usingDisplaySemaphoreShareGroup() const; 723 724 // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format. 725 GLenum getConvertedRenderbufferFormat(GLenum internalformat) const; 726 isWebGL()727 bool isWebGL() const { return mState.isWebGL(); } isWebGL1()728 bool isWebGL1() const { return mState.isWebGL1(); } getRendererString()729 const char *getRendererString() const { return mRendererString; } 730 isValidBufferBinding(BufferBinding binding)731 bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; } 732 733 // GLES1 emulation: Renderer level (for validation) 734 int vertexArrayIndex(ClientVertexArrayType type) const; 735 static int TexCoordArrayIndex(unsigned int unit); 736 737 // GL_KHR_parallel_shader_compile 738 std::shared_ptr<angle::WorkerThreadPool> getShaderCompileThreadPool() const; 739 std::shared_ptr<angle::WorkerThreadPool> getLinkSubTaskThreadPool() const; 740 std::shared_ptr<angle::WaitableEvent> postCompileLinkTask( 741 const std::shared_ptr<angle::Closure> &task, 742 angle::JobThreadSafety safety, 743 angle::JobResultExpectancy resultExpectancy) const; 744 745 // Single-threaded pool; runs everything instantly 746 std::shared_ptr<angle::WorkerThreadPool> getSingleThreadPool() const; 747 748 // Generic multithread pool. 749 std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const; 750 getStateCache()751 const StateCache &getStateCache() const { return mStateCache; } getStateCache()752 StateCache &getStateCache() { return mStateCache; } 753 getPrivateStateCache()754 const PrivateStateCache &getPrivateStateCache() const { return mPrivateStateCache; } getMutablePrivateStateCache()755 PrivateStateCache *getMutablePrivateStateCache() { return &mPrivateStateCache; } 756 757 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 758 759 void onSamplerUniformChange(size_t textureUnitIndex); 760 isBufferAccessValidationEnabled()761 bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; } 762 763 const angle::FrontendFeatures &getFrontendFeatures() const; 764 getFrameCapture()765 angle::FrameCapture *getFrameCapture() const { return mFrameCapture.get(); } 766 getVertexArraysForCapture()767 const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; } getQueriesForCapture()768 const QueryMap &getQueriesForCapture() const { return mQueryMap; } getTransformFeedbacksForCapture()769 const TransformFeedbackMap &getTransformFeedbacksForCapture() const 770 { 771 return mTransformFeedbackMap; 772 } getErrorForCapture()773 GLenum getErrorForCapture() const { return mErrors.getErrorForCapture(); } 774 775 void onPreSwap(); 776 777 Program *getActiveLinkedProgram() const; 778 779 // EGL_ANGLE_power_preference implementation. 780 egl::Error releaseHighPowerGPU(); 781 egl::Error reacquireHighPowerGPU(); 782 void onGPUSwitch(); 783 784 // EGL_ANGLE_external_context_and_surface implementation. 785 egl::Error acquireExternalContext(egl::Surface *drawAndReadSurface); 786 egl::Error releaseExternalContext(); 787 788 bool noopDraw(PrimitiveMode mode, GLsizei count) const; 789 bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const; 790 bool noopMultiDraw(GLsizei drawcount) const; 791 792 bool isClearBufferMaskedOut(GLenum buffer, 793 GLint drawbuffer, 794 GLuint framebufferStencilSize) const; 795 bool noopClearBuffer(GLenum buffer, GLint drawbuffer) const; 796 addRef()797 void addRef() const { mRefCount++; } release()798 void release() const { mRefCount--; } isReferenced()799 bool isReferenced() const { return mRefCount > 0; } 800 getShareGroup()801 egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); } 802 803 // Warning! When need to store pointer to the mutex in other object use `getRoot()` pointer, do 804 // NOT get pointer of the `getContextMutex()` reference. getContextMutex()805 egl::ContextMutex &getContextMutex() const { return mState.mContextMutex; } 806 807 bool supportsGeometryOrTesselation() const; 808 void dirtyAllState(); 809 isDestroyed()810 bool isDestroyed() const { return mIsDestroyed; } setIsDestroyed()811 void setIsDestroyed() { mIsDestroyed = true; } 812 813 // This function acts as glEnable(GL_COLOR_LOGIC_OP), but it's called from the GLES1 emulation 814 // code to implement logicOp using the non-GLES1 functionality (i.e. GL_ANGLE_logic_op). The 815 // ContextPrivateEnable() entry point implementation cannot be used (as ContextPrivate* 816 // functions are typically used by other frontend-emulated features) because it forwards this 817 // back to GLES1. 818 void setLogicOpEnabledForGLES1(bool enabled); 819 820 // Needed by capture serialization logic that works with a "const" Context pointer. 821 void finishImmutable() const; 822 823 const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const; 824 825 // Ends the currently active pixel local storage session with GL_STORE_OP_STORE on all planes. 826 void endPixelLocalStorageImplicit(); 827 828 bool areBlobCacheFuncsSet() const; 829 830 private: 831 void initializeDefaultResources(); 832 void releaseSharedObjects(); 833 834 angle::Result prepareForDraw(PrimitiveMode mode); 835 angle::Result prepareForClear(GLbitfield mask); 836 angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer); 837 angle::Result syncState(const state::DirtyBits bitMask, 838 const state::ExtendedDirtyBits extendedBitMask, 839 const state::DirtyObjects &objectMask, 840 Command command); 841 angle::Result syncAllDirtyBits(Command command); 842 angle::Result syncDirtyBits(const state::DirtyBits bitMask, 843 const state::ExtendedDirtyBits extendedBitMask, 844 Command command); 845 angle::Result syncDirtyObjects(const state::DirtyObjects &objectMask, Command command); 846 angle::Result syncStateForReadPixels(); 847 angle::Result syncStateForTexImage(); 848 angle::Result syncStateForBlit(GLbitfield mask); 849 angle::Result syncStateForClear(); 850 angle::Result syncTextureForCopy(Texture *texture); 851 852 VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle); 853 TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback); 854 855 void detachBuffer(Buffer *buffer); 856 void detachTexture(TextureID texture); 857 void detachFramebuffer(FramebufferID framebuffer); 858 void detachRenderbuffer(RenderbufferID renderbuffer); 859 void detachVertexArray(VertexArrayID vertexArray); 860 void detachTransformFeedback(TransformFeedbackID transformFeedback); 861 void detachSampler(SamplerID sampler); 862 void detachProgramPipeline(ProgramPipelineID pipeline); 863 864 egl::Error setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface); 865 egl::Error unsetDefaultFramebuffer(); 866 867 void initRendererString(); 868 void initVendorString(); 869 void initVersionStrings(); 870 void initExtensionStrings(); 871 872 Extensions generateSupportedExtensions() const; 873 void initCaps(); 874 void updateCaps(); 875 876 gl::LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const; 877 gl::LabeledObject *getLabeledObjectFromPtr(const void *ptr) const; 878 879 void setUniform1iImpl(Program *program, 880 UniformLocation location, 881 GLsizei count, 882 const GLint *v); 883 void renderbufferStorageMultisampleImpl(GLenum target, 884 GLsizei samples, 885 GLenum internalformat, 886 GLsizei width, 887 GLsizei height, 888 MultisamplingMode mode); 889 890 void onUniformBlockBindingUpdated(GLuint uniformBlockIndex); 891 892 void endTilingImplicit(); 893 894 State mState; 895 bool mShared; 896 bool mDisplayTextureShareGroup; 897 bool mDisplaySemaphoreShareGroup; 898 899 // Recorded errors 900 mutable ErrorSet mErrors; 901 902 // Stores for each buffer binding type whether is it allowed to be used in this context. 903 angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings; 904 905 std::unique_ptr<rx::ContextImpl> mImplementation; 906 907 EGLLabelKHR mLabel; 908 909 // Extensions supported by the implementation plus extensions that are implemented entirely 910 // within the frontend. 911 Extensions mSupportedExtensions; 912 913 // Shader compiler. Lazily initialized hence the mutable value. 914 mutable BindingPointer<Compiler> mCompiler; 915 916 const egl::Config *mConfig; 917 918 TextureMap mZeroTextures; 919 920 ResourceMap<FenceNV, FenceNVID> mFenceNVMap; 921 HandleAllocator mFenceNVHandleAllocator; 922 923 QueryMap mQueryMap; 924 HandleAllocator mQueryHandleAllocator; 925 926 VertexArrayMap mVertexArrayMap; 927 HandleAllocator mVertexArrayHandleAllocator; 928 929 TransformFeedbackMap mTransformFeedbackMap; 930 HandleAllocator mTransformFeedbackHandleAllocator; 931 932 const char *mVendorString; 933 const char *mVersionString; 934 const char *mShadingLanguageString; 935 const char *mRendererString; 936 const char *mExtensionString; 937 std::vector<const char *> mExtensionStrings; 938 const char *mRequestableExtensionString; 939 std::vector<const char *> mRequestableExtensionStrings; 940 941 // GLES1 renderer state 942 std::unique_ptr<GLES1Renderer> mGLES1Renderer; 943 944 // Current/lost context flags 945 bool mHasBeenCurrent; 946 const bool mSurfacelessSupported; 947 egl::Surface *mCurrentDrawSurface; 948 egl::Surface *mCurrentReadSurface; 949 egl::Display *mDisplay; 950 const bool mWebGLContext; 951 bool mBufferAccessValidationEnabled; 952 const bool mExtensionsEnabled; 953 MemoryProgramCache *mMemoryProgramCache; 954 MemoryShaderCache *mMemoryShaderCache; 955 956 state::DirtyObjects mDrawDirtyObjects; 957 958 StateCache mStateCache; 959 PrivateStateCache mPrivateStateCache; 960 961 state::DirtyObjects mTexImageDirtyObjects; 962 state::DirtyObjects mReadPixelsDirtyObjects; 963 state::DirtyObjects mClearDirtyObjects; 964 state::DirtyObjects mBlitDirtyObjects; 965 state::DirtyObjects mComputeDirtyObjects; 966 state::DirtyBits mCopyImageDirtyBits; 967 state::DirtyObjects mCopyImageDirtyObjects; 968 969 // Binding to container objects that use dependent state updates. 970 angle::ObserverBinding mVertexArrayObserverBinding; 971 angle::ObserverBinding mDrawFramebufferObserverBinding; 972 angle::ObserverBinding mReadFramebufferObserverBinding; 973 angle::ObserverBinding mProgramObserverBinding; 974 angle::ObserverBinding mProgramPipelineObserverBinding; 975 std::vector<angle::ObserverBinding> mUniformBufferObserverBindings; 976 std::vector<angle::ObserverBinding> mAtomicCounterBufferObserverBindings; 977 std::vector<angle::ObserverBinding> mShaderStorageBufferObserverBindings; 978 std::vector<angle::ObserverBinding> mSamplerObserverBindings; 979 std::vector<angle::ObserverBinding> mImageObserverBindings; 980 981 // Not really a property of context state. The size and contexts change per-api-call. 982 mutable Optional<angle::ScratchBuffer> mScratchBuffer; 983 mutable Optional<angle::ScratchBuffer> mZeroFilledBuffer; 984 985 // Note: we use a raw pointer here so we can exclude frame capture sources from the build. 986 std::unique_ptr<angle::FrameCapture> mFrameCapture; 987 988 // Cache representation of the serialized context string. 989 mutable std::string mCachedSerializedStateString; 990 991 mutable size_t mRefCount; 992 993 OverlayType mOverlay; 994 995 bool mIsDestroyed; 996 997 std::unique_ptr<Framebuffer> mDefaultFramebuffer; 998 }; 999 1000 class [[nodiscard]] ScopedContextRef 1001 { 1002 public: ScopedContextRef(Context * context)1003 ScopedContextRef(Context *context) : mContext(context) 1004 { 1005 if (mContext) 1006 { 1007 mContext->addRef(); 1008 } 1009 } ~ScopedContextRef()1010 ~ScopedContextRef() 1011 { 1012 if (mContext) 1013 { 1014 mContext->release(); 1015 } 1016 } 1017 1018 private: 1019 Context *const mContext; 1020 }; 1021 1022 // Thread-local current valid context bound to the thread. 1023 #if defined(ANGLE_PLATFORM_APPLE) || defined(ANGLE_USE_STATIC_THREAD_LOCAL_VARIABLES) 1024 extern Context *GetCurrentValidContextTLS(); 1025 extern void SetCurrentValidContextTLS(Context *context); 1026 #else 1027 extern thread_local Context *gCurrentValidContext; 1028 #endif 1029 1030 extern void SetCurrentValidContext(Context *context); 1031 1032 } // namespace gl 1033 1034 #endif // LIBANGLE_CONTEXT_H_ 1035