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