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