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