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