xref: /aosp_15_r20/external/angle/src/libANGLE/Context.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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