summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libANGLE/Context.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/libANGLE/Context.h')
-rw-r--r--gfx/angle/checkout/src/libANGLE/Context.h901
1 files changed, 901 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libANGLE/Context.h b/gfx/angle/checkout/src/libANGLE/Context.h
new file mode 100644
index 0000000000..fec6a6653c
--- /dev/null
+++ b/gfx/angle/checkout/src/libANGLE/Context.h
@@ -0,0 +1,901 @@
+//
+// Copyright 2002 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// Context.h: Defines the gl::Context class, managing all GL state and performing
+// rendering operations. It is the GLES2 specific implementation of EGLContext.
+
+#ifndef LIBANGLE_CONTEXT_H_
+#define LIBANGLE_CONTEXT_H_
+
+#include <mutex>
+#include <set>
+#include <string>
+
+#include "angle_gl.h"
+#include "common/MemoryBuffer.h"
+#include "common/PackedEnums.h"
+#include "common/angleutils.h"
+#include "libANGLE/Caps.h"
+#include "libANGLE/Constants.h"
+#include "libANGLE/Context_gl_1_autogen.h"
+#include "libANGLE/Context_gl_2_autogen.h"
+#include "libANGLE/Context_gl_3_autogen.h"
+#include "libANGLE/Context_gl_4_autogen.h"
+#include "libANGLE/Context_gles_1_0_autogen.h"
+#include "libANGLE/Context_gles_2_0_autogen.h"
+#include "libANGLE/Context_gles_3_0_autogen.h"
+#include "libANGLE/Context_gles_3_1_autogen.h"
+#include "libANGLE/Context_gles_3_2_autogen.h"
+#include "libANGLE/Context_gles_ext_autogen.h"
+#include "libANGLE/Error.h"
+#include "libANGLE/Framebuffer.h"
+#include "libANGLE/HandleAllocator.h"
+#include "libANGLE/RefCountObject.h"
+#include "libANGLE/ResourceManager.h"
+#include "libANGLE/ResourceMap.h"
+#include "libANGLE/State.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/WorkerThread.h"
+#include "libANGLE/angletypes.h"
+
+namespace angle
+{
+class FrameCapture;
+class FrameCaptureShared;
+struct FrontendFeatures;
+} // namespace angle
+
+namespace rx
+{
+class ContextImpl;
+class EGLImplFactory;
+} // namespace rx
+
+namespace egl
+{
+class AttributeMap;
+class Surface;
+struct Config;
+class Thread;
+} // namespace egl
+
+namespace gl
+{
+class Buffer;
+class Compiler;
+class FenceNV;
+class GLES1Renderer;
+class MemoryProgramCache;
+class MemoryShaderCache;
+class MemoryObject;
+class Program;
+class ProgramPipeline;
+class Query;
+class Renderbuffer;
+class Sampler;
+class Semaphore;
+class Shader;
+class Sync;
+class Texture;
+class TransformFeedback;
+class VertexArray;
+struct VertexAttribute;
+
+class ErrorSet : angle::NonCopyable
+{
+ public:
+ explicit ErrorSet(Context *context);
+ ~ErrorSet();
+
+ bool empty() const;
+ GLenum popError();
+
+ void handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line);
+
+ void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message);
+
+ private:
+ Context *mContext;
+ std::set<GLenum> mErrors;
+};
+
+enum class VertexAttribTypeCase
+{
+ Invalid = 0,
+ Valid = 1,
+ ValidSize4Only = 2,
+ ValidSize3or4 = 3,
+};
+
+// Helper class for managing cache variables and state changes.
+class StateCache final : angle::NonCopyable
+{
+ public:
+ StateCache();
+ ~StateCache();
+
+ void initialize(Context *context);
+
+ // Places that can trigger updateActiveAttribsMask:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayStateChange.
+ // 4. onGLES1ClientStateChange.
+ AttributesMask getActiveBufferedAttribsMask() const { return mCachedActiveBufferedAttribsMask; }
+ AttributesMask getActiveClientAttribsMask() const { return mCachedActiveClientAttribsMask; }
+ AttributesMask getActiveDefaultAttribsMask() const { return mCachedActiveDefaultAttribsMask; }
+ bool hasAnyEnabledClientAttrib() const { return mCachedHasAnyEnabledClientAttrib; }
+ bool hasAnyActiveClientAttrib() const { return mCachedActiveClientAttribsMask.any(); }
+
+ // Places that can trigger updateVertexElementLimits:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayFormatChange.
+ // 4. onVertexArrayBufferChange.
+ // 5. onVertexArrayStateChange.
+ GLint64 getNonInstancedVertexElementLimit() const
+ {
+ return mCachedNonInstancedVertexElementLimit;
+ }
+ GLint64 getInstancedVertexElementLimit() const { return mCachedInstancedVertexElementLimit; }
+
+ // Places that can trigger updateBasicDrawStatesError:
+ // 1. onVertexArrayBindingChange.
+ // 2. onProgramExecutableChange.
+ // 3. onVertexArrayBufferContentsChange.
+ // 4. onVertexArrayStateChange.
+ // 5. onVertexArrayBufferStateChange.
+ // 6. onDrawFramebufferChange.
+ // 7. onContextCapChange.
+ // 8. onStencilStateChange.
+ // 9. onDefaultVertexAttributeChange.
+ // 10. onActiveTextureChange.
+ // 11. onQueryChange.
+ // 12. onActiveTransformFeedbackChange.
+ // 13. onUniformBufferStateChange.
+ // 14. onColorMaskChange.
+ // 15. onBufferBindingChange.
+ // 16. onBlendFuncIndexedChange.
+ bool hasBasicDrawStatesError(Context *context) const
+ {
+ if (mCachedBasicDrawStatesError == 0)
+ {
+ return false;
+ }
+ if (mCachedBasicDrawStatesError != kInvalidPointer)
+ {
+ return true;
+ }
+ return getBasicDrawStatesErrorImpl(context) != 0;
+ }
+
+ intptr_t getBasicDrawStatesError(const Context *context) const
+ {
+ if (mCachedBasicDrawStatesError != kInvalidPointer)
+ {
+ return mCachedBasicDrawStatesError;
+ }
+
+ return getBasicDrawStatesErrorImpl(context);
+ }
+
+ // Places that can trigger updateProgramPipelineError:
+ // 1. onProgramExecutableChange.
+ intptr_t getProgramPipelineError(const Context *context) const
+ {
+ if (mCachedProgramPipelineError != kInvalidPointer)
+ {
+ return mCachedProgramPipelineError;
+ }
+
+ return getProgramPipelineErrorImpl(context);
+ }
+
+ // Places that can trigger updateBasicDrawElementsError:
+ // 1. onActiveTransformFeedbackChange.
+ // 2. onVertexArrayBufferStateChange.
+ // 3. onBufferBindingChange.
+ // 4. onVertexArrayStateChange.
+ // 5. onVertexArrayBindingStateChange.
+ intptr_t getBasicDrawElementsError(const Context *context) const
+ {
+ if (mCachedBasicDrawElementsError != kInvalidPointer)
+ {
+ return mCachedBasicDrawElementsError;
+ }
+
+ return getBasicDrawElementsErrorImpl(context);
+ }
+
+ // Places that can trigger updateValidDrawModes:
+ // 1. onProgramExecutableChange.
+ // 2. onActiveTransformFeedbackChange.
+ bool isValidDrawMode(PrimitiveMode primitiveMode) const
+ {
+ return mCachedValidDrawModes[primitiveMode];
+ }
+
+ // Cannot change except on Context/Extension init.
+ bool isValidBindTextureType(TextureType type) const
+ {
+ return mCachedValidBindTextureTypes[type];
+ }
+
+ // Cannot change except on Context/Extension init.
+ bool isValidDrawElementsType(DrawElementsType type) const
+ {
+ return mCachedValidDrawElementsTypes[type];
+ }
+
+ // Places that can trigger updateTransformFeedbackActiveUnpaused:
+ // 1. onActiveTransformFeedbackChange.
+ bool isTransformFeedbackActiveUnpaused() const
+ {
+ return mCachedTransformFeedbackActiveUnpaused;
+ }
+
+ // Cannot change except on Context/Extension init.
+ VertexAttribTypeCase getVertexAttribTypeValidation(VertexAttribType type) const
+ {
+ return mCachedVertexAttribTypesValidation[type];
+ }
+
+ VertexAttribTypeCase getIntegerVertexAttribTypeValidation(VertexAttribType type) const
+ {
+ return mCachedIntegerVertexAttribTypesValidation[type];
+ }
+
+ // Places that can trigger updateActiveShaderStorageBufferIndices:
+ // 1. onProgramExecutableChange.
+ StorageBuffersMask getActiveShaderStorageBufferIndices() const
+ {
+ return mCachedActiveShaderStorageBufferIndices;
+ }
+
+ // Places that can trigger updateActiveImageUnitIndices:
+ // 1. onProgramExecutableChange.
+ const ImageUnitMask &getActiveImageUnitIndices() const { return mCachedActiveImageUnitIndices; }
+
+ // Places that can trigger updateCanDraw:
+ // 1. onProgramExecutableChange.
+ bool getCanDraw() const { return mCachedCanDraw; }
+
+ // State change notifications.
+ void onVertexArrayBindingChange(Context *context);
+ void onProgramExecutableChange(Context *context);
+ void onVertexArrayFormatChange(Context *context);
+ void onVertexArrayBufferContentsChange(Context *context);
+ void onVertexArrayStateChange(Context *context);
+ void onVertexArrayBufferStateChange(Context *context);
+ void onGLES1ClientStateChange(Context *context);
+ void onDrawFramebufferChange(Context *context);
+ void onContextCapChange(Context *context);
+ void onStencilStateChange(Context *context);
+ void onDefaultVertexAttributeChange(Context *context);
+ void onActiveTextureChange(Context *context);
+ void onQueryChange(Context *context);
+ void onActiveTransformFeedbackChange(Context *context);
+ void onUniformBufferStateChange(Context *context);
+ void onAtomicCounterBufferStateChange(Context *context);
+ void onShaderStorageBufferStateChange(Context *context);
+ void onColorMaskChange(Context *context);
+ void onBufferBindingChange(Context *context);
+ void onBlendFuncIndexedChange(Context *context);
+ void onBlendEquationChange(Context *context);
+
+ private:
+ // Cache update functions.
+ void updateActiveAttribsMask(Context *context);
+ void updateVertexElementLimits(Context *context);
+ void updateVertexElementLimitsImpl(Context *context);
+ void updateValidDrawModes(Context *context);
+ void updateValidBindTextureTypes(Context *context);
+ void updateValidDrawElementsTypes(Context *context);
+ void updateBasicDrawStatesError();
+ void updateProgramPipelineError();
+ void updateBasicDrawElementsError();
+ void updateTransformFeedbackActiveUnpaused(Context *context);
+ void updateVertexAttribTypesValidation(Context *context);
+ void updateActiveShaderStorageBufferIndices(Context *context);
+ void updateActiveImageUnitIndices(Context *context);
+ void updateCanDraw(Context *context);
+
+ void setValidDrawModes(bool pointsOK,
+ bool linesOK,
+ bool trisOK,
+ bool lineAdjOK,
+ bool triAdjOK,
+ bool patchOK);
+
+ intptr_t getBasicDrawStatesErrorImpl(const Context *context) const;
+ intptr_t getProgramPipelineErrorImpl(const Context *context) const;
+ intptr_t getBasicDrawElementsErrorImpl(const Context *context) const;
+
+ static constexpr intptr_t kInvalidPointer = 1;
+
+ AttributesMask mCachedActiveBufferedAttribsMask;
+ AttributesMask mCachedActiveClientAttribsMask;
+ AttributesMask mCachedActiveDefaultAttribsMask;
+ bool mCachedHasAnyEnabledClientAttrib;
+ GLint64 mCachedNonInstancedVertexElementLimit;
+ GLint64 mCachedInstancedVertexElementLimit;
+ mutable intptr_t mCachedBasicDrawStatesError;
+ mutable intptr_t mCachedBasicDrawElementsError;
+ // mCachedProgramPipelineError checks only the
+ // current-program-exists subset of mCachedBasicDrawStatesError.
+ // Therefore, mCachedProgramPipelineError follows
+ // mCachedBasicDrawStatesError in that if mCachedBasicDrawStatesError is
+ // no-error, so is mCachedProgramPipelineError. Otherwise, if
+ // mCachedBasicDrawStatesError is in error, the state of
+ // mCachedProgramPipelineError can be no-error or also in error, or
+ // unknown due to early exiting.
+ mutable intptr_t mCachedProgramPipelineError;
+ bool mCachedTransformFeedbackActiveUnpaused;
+ StorageBuffersMask mCachedActiveShaderStorageBufferIndices;
+ ImageUnitMask mCachedActiveImageUnitIndices;
+
+ // Reserve an extra slot at the end of these maps for invalid enum.
+ angle::PackedEnumMap<PrimitiveMode, bool, angle::EnumSize<PrimitiveMode>() + 1>
+ mCachedValidDrawModes;
+ angle::PackedEnumMap<TextureType, bool, angle::EnumSize<TextureType>() + 1>
+ mCachedValidBindTextureTypes;
+ angle::PackedEnumMap<DrawElementsType, bool, angle::EnumSize<DrawElementsType>() + 1>
+ mCachedValidDrawElementsTypes;
+ angle::PackedEnumMap<VertexAttribType,
+ VertexAttribTypeCase,
+ angle::EnumSize<VertexAttribType>() + 1>
+ mCachedVertexAttribTypesValidation;
+ angle::PackedEnumMap<VertexAttribType,
+ VertexAttribTypeCase,
+ angle::EnumSize<VertexAttribType>() + 1>
+ mCachedIntegerVertexAttribTypesValidation;
+
+ bool mCachedCanDraw;
+};
+
+using VertexArrayMap = ResourceMap<VertexArray, VertexArrayID>;
+using QueryMap = ResourceMap<Query, QueryID>;
+using TransformFeedbackMap = ResourceMap<TransformFeedback, TransformFeedbackID>;
+
+class Context final : public egl::LabeledObject, angle::NonCopyable, public angle::ObserverInterface
+{
+ public:
+ Context(egl::Display *display,
+ const egl::Config *config,
+ const Context *shareContext,
+ TextureManager *shareTextures,
+ SemaphoreManager *shareSemaphores,
+ MemoryProgramCache *memoryProgramCache,
+ MemoryShaderCache *memoryShaderCache,
+ const EGLenum clientType,
+ const egl::AttributeMap &attribs,
+ const egl::DisplayExtensions &displayExtensions,
+ const egl::ClientExtensions &clientExtensions);
+
+ // Use for debugging.
+ ContextID id() const { return mState.getContextID(); }
+
+ egl::Error initialize();
+
+ egl::Error onDestroy(const egl::Display *display);
+ ~Context() override;
+
+ void setLabel(EGLLabelKHR label) override;
+ EGLLabelKHR getLabel() const override;
+
+ egl::Error makeCurrent(egl::Display *display,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface);
+ egl::Error unMakeCurrent(const egl::Display *display);
+
+ // These create and destroy methods pass through to ResourceManager, which owns these objects.
+ BufferID createBuffer();
+ TextureID createTexture();
+ RenderbufferID createRenderbuffer();
+ ProgramPipelineID createProgramPipeline();
+ MemoryObjectID createMemoryObject();
+ SemaphoreID createSemaphore();
+
+ void deleteBuffer(BufferID buffer);
+ void deleteTexture(TextureID texture);
+ void deleteRenderbuffer(RenderbufferID renderbuffer);
+ void deleteProgramPipeline(ProgramPipelineID pipeline);
+ void deleteMemoryObject(MemoryObjectID memoryObject);
+ void deleteSemaphore(SemaphoreID semaphore);
+
+ void bindReadFramebuffer(FramebufferID framebufferHandle);
+ void bindDrawFramebuffer(FramebufferID framebufferHandle);
+
+ Buffer *getBuffer(BufferID handle) const;
+ FenceNV *getFenceNV(FenceNVID handle) const;
+ Sync *getSync(GLsync handle) const;
+ ANGLE_INLINE Texture *getTexture(TextureID handle) const
+ {
+ return mState.mTextureManager->getTexture(handle);
+ }
+
+ Framebuffer *getFramebuffer(FramebufferID handle) const;
+ Renderbuffer *getRenderbuffer(RenderbufferID handle) const;
+ VertexArray *getVertexArray(VertexArrayID handle) const;
+ Sampler *getSampler(SamplerID handle) const;
+ Query *getOrCreateQuery(QueryID handle, QueryType type);
+ Query *getQuery(QueryID handle) const;
+ TransformFeedback *getTransformFeedback(TransformFeedbackID handle) const;
+ ProgramPipeline *getProgramPipeline(ProgramPipelineID handle) const;
+ MemoryObject *getMemoryObject(MemoryObjectID handle) const;
+ Semaphore *getSemaphore(SemaphoreID handle) const;
+
+ Texture *getTextureByType(TextureType type) const;
+ Texture *getTextureByTarget(TextureTarget target) const;
+ Texture *getSamplerTexture(unsigned int sampler, TextureType type) const;
+
+ Compiler *getCompiler() const;
+
+ bool isVertexArrayGenerated(VertexArrayID vertexArray) const;
+ bool isTransformFeedbackGenerated(TransformFeedbackID transformFeedback) const;
+
+ bool isExternal() const { return mIsExternal; }
+ bool saveAndRestoreState() const { return mSaveAndRestoreState; }
+
+ void getBooleanvImpl(GLenum pname, GLboolean *params) const;
+ void getFloatvImpl(GLenum pname, GLfloat *params) const;
+ void getIntegervImpl(GLenum pname, GLint *params) const;
+ void getInteger64vImpl(GLenum pname, GLint64 *params) const;
+ void getIntegerVertexAttribImpl(GLenum pname, GLenum attribpname, GLint *params) const;
+ void getVertexAttribivImpl(GLuint index, GLenum pname, GLint *params) const;
+
+ // Framebuffers are owned by the Context, so these methods do not pass through
+ FramebufferID createFramebuffer();
+ void deleteFramebuffer(FramebufferID framebuffer);
+
+ bool hasActiveTransformFeedback(ShaderProgramID program) const;
+
+ // Desktop GL entry point interface
+ ANGLE_GL_1_CONTEXT_API
+ ANGLE_GL_2_CONTEXT_API
+ ANGLE_GL_3_CONTEXT_API
+ ANGLE_GL_4_CONTEXT_API
+
+ // GLES entry point interface
+ ANGLE_GLES_1_0_CONTEXT_API
+ ANGLE_GLES_2_0_CONTEXT_API
+ ANGLE_GLES_3_0_CONTEXT_API
+ ANGLE_GLES_3_1_CONTEXT_API
+ ANGLE_GLES_3_2_CONTEXT_API
+ ANGLE_GLES_EXT_CONTEXT_API
+
+ angle::Result handleNoopDrawEvent();
+
+ // Consumes an error.
+ void handleError(GLenum errorCode,
+ const char *message,
+ const char *file,
+ const char *function,
+ unsigned int line);
+
+ void validationError(angle::EntryPoint entryPoint, GLenum errorCode, const char *message) const;
+ ANGLE_FORMAT_PRINTF(4, 5)
+ void validationErrorF(angle::EntryPoint entryPoint,
+ GLenum errorCode,
+ const char *format,
+ ...) const;
+
+ void markContextLost(GraphicsResetStatus status);
+
+ bool isContextLost() const { return mContextLost; }
+ void setContextLost();
+
+ GLenum getGraphicsResetStrategy() const { return mResetStrategy; }
+ bool isResetNotificationEnabled() const;
+
+ bool isRobustnessEnabled() const;
+
+ const egl::Config *getConfig() const;
+ EGLenum getClientType() const;
+ EGLenum getRenderBuffer() const;
+ EGLenum getContextPriority() const;
+
+ const GLubyte *getString(GLenum name) const;
+ const GLubyte *getStringi(GLenum name, GLuint index) const;
+
+ size_t getExtensionStringCount() const;
+
+ bool isExtensionRequestable(const char *name) const;
+ bool isExtensionDisablable(const char *name) const;
+ size_t getRequestableExtensionStringCount() const;
+ void setExtensionEnabled(const char *name, bool enabled);
+ void reinitializeAfterExtensionsChanged();
+
+ rx::ContextImpl *getImplementation() const { return mImplementation.get(); }
+
+ [[nodiscard]] bool getScratchBuffer(size_t requestedSizeBytes,
+ angle::MemoryBuffer **scratchBufferOut) const;
+ [[nodiscard]] bool getZeroFilledBuffer(size_t requstedSizeBytes,
+ angle::MemoryBuffer **zeroBufferOut) const;
+ angle::ScratchBuffer *getScratchBuffer() const;
+
+ angle::Result prepareForCopyImage();
+ angle::Result prepareForDispatch();
+ angle::Result prepareForInvalidate(GLenum target);
+
+ MemoryProgramCache *getMemoryProgramCache() const { return mMemoryProgramCache; }
+ MemoryShaderCache *getMemoryShaderCache() const { return mMemoryShaderCache; }
+
+ std::mutex &getProgramCacheMutex() const;
+
+ bool hasBeenCurrent() const { return mHasBeenCurrent; }
+ egl::Display *getDisplay() const { return mDisplay; }
+ egl::Surface *getCurrentDrawSurface() const { return mCurrentDrawSurface; }
+ egl::Surface *getCurrentReadSurface() const { return mCurrentReadSurface; }
+
+ bool isRobustResourceInitEnabled() const { return mState.isRobustResourceInitEnabled(); }
+
+ bool isCurrentTransformFeedback(const TransformFeedback *tf) const;
+
+ bool isCurrentVertexArray(const VertexArray *va) const
+ {
+ return mState.isCurrentVertexArray(va);
+ }
+
+ ANGLE_INLINE bool isShared() const { return mShared; }
+ // Once a context is setShared() it cannot be undone
+ void setShared() { mShared = true; }
+
+ const State &getState() const { return mState; }
+ GLint getClientMajorVersion() const { return mState.getClientMajorVersion(); }
+ GLint getClientMinorVersion() const { return mState.getClientMinorVersion(); }
+ const Version &getClientVersion() const { return mState.getClientVersion(); }
+ const Caps &getCaps() const { return mState.getCaps(); }
+ const TextureCapsMap &getTextureCaps() const { return mState.getTextureCaps(); }
+ const Extensions &getExtensions() const { return mState.getExtensions(); }
+ const Limitations &getLimitations() const { return mState.getLimitations(); }
+ bool isGLES1() const;
+
+ bool skipValidation() const
+ {
+ // Ensure we don't skip validation when context becomes lost, since implementations
+ // generally assume a non-lost context, non-null objects, etc.
+ ASSERT(!isContextLost() || !mSkipValidation);
+ return mSkipValidation;
+ }
+
+ // Specific methods needed for validation.
+ bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const;
+ bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams) const;
+
+ ANGLE_INLINE Program *getProgramResolveLink(ShaderProgramID handle) const
+ {
+ Program *program = mState.mShaderProgramManager->getProgram(handle);
+ if (program)
+ {
+ program->resolveLink(this);
+ }
+ return program;
+ }
+
+ Program *getProgramNoResolveLink(ShaderProgramID handle) const;
+ Shader *getShader(ShaderProgramID handle) const;
+
+ ANGLE_INLINE bool isTextureGenerated(TextureID texture) const
+ {
+ return mState.mTextureManager->isHandleGenerated(texture);
+ }
+
+ ANGLE_INLINE bool isBufferGenerated(BufferID buffer) const
+ {
+ return mState.mBufferManager->isHandleGenerated(buffer);
+ }
+
+ bool isRenderbufferGenerated(RenderbufferID renderbuffer) const;
+ bool isFramebufferGenerated(FramebufferID framebuffer) const;
+ bool isProgramPipelineGenerated(ProgramPipelineID pipeline) const;
+ bool isQueryGenerated(QueryID query) const;
+
+ bool usingDisplayTextureShareGroup() const;
+ bool usingDisplaySemaphoreShareGroup() const;
+
+ // Hack for the special WebGL 1 "DEPTH_STENCIL" internal format.
+ GLenum getConvertedRenderbufferFormat(GLenum internalformat) const;
+
+ bool isWebGL() const { return mState.isWebGL(); }
+ bool isWebGL1() const { return mState.isWebGL1(); }
+
+ bool isValidBufferBinding(BufferBinding binding) const { return mValidBufferBindings[binding]; }
+
+ // GLES1 emulation: Renderer level (for validation)
+ int vertexArrayIndex(ClientVertexArrayType type) const;
+ static int TexCoordArrayIndex(unsigned int unit);
+
+ // GL_KHR_parallel_shader_compile
+ std::shared_ptr<angle::WorkerThreadPool> getShaderCompileThreadPool() const
+ {
+ if (mState.mExtensions.parallelShaderCompileKHR)
+ {
+ return mMultiThreadPool;
+ }
+ return mSingleThreadPool;
+ }
+
+ // Generic multithread pool.
+ std::shared_ptr<angle::WorkerThreadPool> getWorkerThreadPool() const
+ {
+ return mMultiThreadPool;
+ }
+
+ const StateCache &getStateCache() const { return mStateCache; }
+ StateCache &getStateCache() { return mStateCache; }
+
+ void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
+
+ void onSamplerUniformChange(size_t textureUnitIndex);
+
+ bool isBufferAccessValidationEnabled() const { return mBufferAccessValidationEnabled; }
+
+ const angle::FrontendFeatures &getFrontendFeatures() const;
+
+ angle::FrameCapture *getFrameCapture() const { return mFrameCapture.get(); }
+
+ const VertexArrayMap &getVertexArraysForCapture() const { return mVertexArrayMap; }
+ const QueryMap &getQueriesForCapture() const { return mQueryMap; }
+ const TransformFeedbackMap &getTransformFeedbacksForCapture() const
+ {
+ return mTransformFeedbackMap;
+ }
+
+ void onPreSwap() const;
+
+ Program *getActiveLinkedProgram() const;
+
+ // EGL_ANGLE_power_preference implementation.
+ egl::Error releaseHighPowerGPU();
+ egl::Error reacquireHighPowerGPU();
+ void onGPUSwitch();
+
+ bool noopDraw(PrimitiveMode mode, GLsizei count) const;
+ bool noopDrawInstanced(PrimitiveMode mode, GLsizei count, GLsizei instanceCount) const;
+
+ bool isClearBufferMaskedOut(GLenum buffer, GLint drawbuffer) const;
+ bool noopClearBuffer(GLenum buffer, GLint drawbuffer) const;
+
+ void addRef() const { mRefCount++; }
+ void release() const { mRefCount--; }
+ size_t getRefCount() const { return mRefCount; }
+
+ egl::ShareGroup *getShareGroup() const { return mState.getShareGroup(); }
+
+ bool supportsGeometryOrTesselation() const;
+ void dirtyAllState();
+
+ bool isDestroyed() const { return mIsDestroyed; }
+ void setIsDestroyed() { mIsDestroyed = true; }
+
+ void setLogicOpEnabled(bool enabled) { mState.setLogicOpEnabled(enabled); }
+ void setLogicOp(LogicalOperation opcode) { mState.setLogicOp(opcode); }
+
+ // Needed by capture serialization logic that works with a "const" Context pointer.
+ void finishImmutable() const;
+
+ const angle::PerfMonitorCounterGroups &getPerfMonitorCounterGroups() const;
+
+ private:
+ void initializeDefaultResources();
+
+ angle::Result prepareForDraw(PrimitiveMode mode);
+ angle::Result prepareForClear(GLbitfield mask);
+ angle::Result prepareForClearBuffer(GLenum buffer, GLint drawbuffer);
+ angle::Result syncState(const State::DirtyBits &bitMask,
+ const State::DirtyObjects &objectMask,
+ Command command);
+ angle::Result syncDirtyBits(Command command);
+ angle::Result syncDirtyBits(const State::DirtyBits &bitMask, Command command);
+ angle::Result syncDirtyObjects(const State::DirtyObjects &objectMask, Command command);
+ angle::Result syncStateForReadPixels();
+ angle::Result syncStateForTexImage();
+ angle::Result syncStateForBlit(GLbitfield mask);
+ angle::Result syncStateForClear();
+ angle::Result syncTextureForCopy(Texture *texture);
+
+ VertexArray *checkVertexArrayAllocation(VertexArrayID vertexArrayHandle);
+ TransformFeedback *checkTransformFeedbackAllocation(TransformFeedbackID transformFeedback);
+
+ angle::Result onProgramLink(Program *programObject);
+
+ void detachBuffer(Buffer *buffer);
+ void detachTexture(TextureID texture);
+ void detachFramebuffer(FramebufferID framebuffer);
+ void detachRenderbuffer(RenderbufferID renderbuffer);
+ void detachVertexArray(VertexArrayID vertexArray);
+ void detachTransformFeedback(TransformFeedbackID transformFeedback);
+ void detachSampler(SamplerID sampler);
+ void detachProgramPipeline(ProgramPipelineID pipeline);
+
+ egl::Error setDefaultFramebuffer(egl::Surface *drawSurface, egl::Surface *readSurface);
+ egl::Error unsetDefaultFramebuffer();
+
+ void initRendererString();
+ void initVersionStrings();
+ void initExtensionStrings();
+
+ Extensions generateSupportedExtensions() const;
+ void initCaps();
+ void updateCaps();
+
+ gl::LabeledObject *getLabeledObject(GLenum identifier, GLuint name) const;
+ gl::LabeledObject *getLabeledObjectFromPtr(const void *ptr) const;
+
+ void setUniform1iImpl(Program *program,
+ UniformLocation location,
+ GLsizei count,
+ const GLint *v);
+ void renderbufferStorageMultisampleImpl(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height,
+ MultisamplingMode mode);
+
+ State mState;
+ bool mShared;
+ bool mSkipValidation;
+ bool mDisplayTextureShareGroup;
+ bool mDisplaySemaphoreShareGroup;
+
+ // Recorded errors
+ ErrorSet mErrors;
+
+ // Stores for each buffer binding type whether is it allowed to be used in this context.
+ angle::PackedEnumBitSet<BufferBinding> mValidBufferBindings;
+
+ std::unique_ptr<rx::ContextImpl> mImplementation;
+
+ EGLLabelKHR mLabel;
+
+ // Extensions supported by the implementation plus extensions that are implemented entirely
+ // within the frontend.
+ Extensions mSupportedExtensions;
+
+ // Shader compiler. Lazily initialized hence the mutable value.
+ mutable BindingPointer<Compiler> mCompiler;
+
+ const egl::Config *mConfig;
+
+ TextureMap mZeroTextures;
+
+ ResourceMap<FenceNV, FenceNVID> mFenceNVMap;
+ HandleAllocator mFenceNVHandleAllocator;
+
+ QueryMap mQueryMap;
+ HandleAllocator mQueryHandleAllocator;
+
+ VertexArrayMap mVertexArrayMap;
+ HandleAllocator mVertexArrayHandleAllocator;
+
+ TransformFeedbackMap mTransformFeedbackMap;
+ HandleAllocator mTransformFeedbackHandleAllocator;
+
+ const char *mVersionString;
+ const char *mShadingLanguageString;
+ const char *mRendererString;
+ const char *mExtensionString;
+ std::vector<const char *> mExtensionStrings;
+ const char *mRequestableExtensionString;
+ std::vector<const char *> mRequestableExtensionStrings;
+
+ // GLES1 renderer state
+ std::unique_ptr<GLES1Renderer> mGLES1Renderer;
+
+ // Current/lost context flags
+ bool mHasBeenCurrent;
+ bool mContextLost; // Set with setContextLost so that we also set mSkipValidation=false.
+ GraphicsResetStatus mResetStatus;
+ bool mContextLostForced;
+ GLenum mResetStrategy;
+ const bool mSurfacelessSupported;
+ egl::Surface *mCurrentDrawSurface;
+ egl::Surface *mCurrentReadSurface;
+ egl::Display *mDisplay;
+ const bool mWebGLContext;
+ bool mBufferAccessValidationEnabled;
+ const bool mExtensionsEnabled;
+ MemoryProgramCache *mMemoryProgramCache;
+ MemoryShaderCache *mMemoryShaderCache;
+
+ State::DirtyObjects mDrawDirtyObjects;
+
+ StateCache mStateCache;
+
+ State::DirtyBits mAllDirtyBits;
+ State::DirtyBits mTexImageDirtyBits;
+ State::DirtyObjects mTexImageDirtyObjects;
+ State::DirtyBits mReadPixelsDirtyBits;
+ State::DirtyObjects mReadPixelsDirtyObjects;
+ State::DirtyBits mClearDirtyBits;
+ State::DirtyObjects mClearDirtyObjects;
+ State::DirtyBits mBlitDirtyBits;
+ State::DirtyObjects mBlitDirtyObjects;
+ State::DirtyBits mComputeDirtyBits;
+ State::DirtyObjects mComputeDirtyObjects;
+ State::DirtyBits mCopyImageDirtyBits;
+ State::DirtyObjects mCopyImageDirtyObjects;
+ State::DirtyBits mReadInvalidateDirtyBits;
+ State::DirtyBits mDrawInvalidateDirtyBits;
+
+ // Binding to container objects that use dependent state updates.
+ angle::ObserverBinding mVertexArrayObserverBinding;
+ angle::ObserverBinding mDrawFramebufferObserverBinding;
+ angle::ObserverBinding mReadFramebufferObserverBinding;
+ angle::ObserverBinding mProgramPipelineObserverBinding;
+ std::vector<angle::ObserverBinding> mUniformBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mAtomicCounterBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mShaderStorageBufferObserverBindings;
+ std::vector<angle::ObserverBinding> mSamplerObserverBindings;
+ std::vector<angle::ObserverBinding> mImageObserverBindings;
+
+ // Not really a property of context state. The size and contexts change per-api-call.
+ mutable Optional<angle::ScratchBuffer> mScratchBuffer;
+ mutable Optional<angle::ScratchBuffer> mZeroFilledBuffer;
+
+ // Single-threaded pool may not always be initialized. It currently depends on the extension
+ // GL_KHR_parallel_shader_compile being disabled.
+ std::shared_ptr<angle::WorkerThreadPool> mSingleThreadPool;
+ // Multithreaded pool will always be initialized so it can be used for more generic work.
+ std::shared_ptr<angle::WorkerThreadPool> mMultiThreadPool;
+
+ // Note: we use a raw pointer here so we can exclude frame capture sources from the build.
+ std::unique_ptr<angle::FrameCapture> mFrameCapture;
+
+ // Cache representation of the serialized context string.
+ mutable std::string mCachedSerializedStateString;
+
+ mutable size_t mRefCount;
+
+ OverlayType mOverlay;
+
+ const bool mIsExternal;
+ const bool mSaveAndRestoreState;
+
+ bool mIsDestroyed;
+
+ std::unique_ptr<Framebuffer> mDefaultFramebuffer;
+};
+
+class [[nodiscard]] ScopedContextRef
+{
+ public:
+ ScopedContextRef(Context *context) : mContext(context)
+ {
+ if (mContext)
+ {
+ mContext->addRef();
+ }
+ }
+ ~ScopedContextRef()
+ {
+ if (mContext)
+ {
+ mContext->release();
+ }
+ }
+
+ private:
+ Context *const mContext;
+};
+
+// Thread-local current valid context bound to the thread.
+#if defined(ANGLE_PLATFORM_APPLE)
+extern Context *GetCurrentValidContextTLS();
+extern void SetCurrentValidContextTLS(Context *context);
+#else
+extern thread_local Context *gCurrentValidContext;
+#endif
+
+} // namespace gl
+
+#endif // LIBANGLE_CONTEXT_H_