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