xref: /aosp_15_r20/external/angle/src/libANGLE/State.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2014 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 // State.h: Defines the State class, encapsulating raw GL state
8 
9 #ifndef LIBANGLE_STATE_H_
10 #define LIBANGLE_STATE_H_
11 
12 #include <bitset>
13 #include <memory>
14 
15 #include "common/Color.h"
16 #include "common/angleutils.h"
17 #include "common/bitset_utils.h"
18 #include "libANGLE/ContextMutex.h"
19 #include "libANGLE/Debug.h"
20 #include "libANGLE/GLES1State.h"
21 #include "libANGLE/Overlay.h"
22 #include "libANGLE/Program.h"
23 #include "libANGLE/ProgramExecutable.h"
24 #include "libANGLE/ProgramPipeline.h"
25 #include "libANGLE/RefCountObject.h"
26 #include "libANGLE/Renderbuffer.h"
27 #include "libANGLE/Sampler.h"
28 #include "libANGLE/Texture.h"
29 #include "libANGLE/TransformFeedback.h"
30 #include "libANGLE/Version.h"
31 #include "libANGLE/VertexArray.h"
32 #include "libANGLE/angletypes.h"
33 
34 namespace egl
35 {
36 class ShareGroup;
37 }  // namespace egl
38 
39 namespace gl
40 {
41 class BufferManager;
42 struct Caps;
43 class Context;
44 class FramebufferManager;
45 class MemoryObjectManager;
46 class ProgramPipelineManager;
47 class Query;
48 class RenderbufferManager;
49 class SamplerManager;
50 class SemaphoreManager;
51 class ShaderProgramManager;
52 class SyncManager;
53 class TextureManager;
54 class VertexArray;
55 
56 static constexpr Version ES_1_0 = Version(1, 0);
57 static constexpr Version ES_1_1 = Version(1, 1);
58 static constexpr Version ES_2_0 = Version(2, 0);
59 static constexpr Version ES_3_0 = Version(3, 0);
60 static constexpr Version ES_3_1 = Version(3, 1);
61 static constexpr Version ES_3_2 = Version(3, 2);
62 
63 template <typename T>
64 using BufferBindingMap     = angle::PackedEnumMap<BufferBinding, T>;
65 using BoundBufferMap       = BufferBindingMap<BindingPointer<Buffer>>;
66 using TextureBindingVector = std::vector<BindingPointer<Texture>>;
67 using TextureBindingMap    = angle::PackedEnumMap<TextureType, TextureBindingVector>;
68 using ActiveQueryMap       = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
69 
70 class ActiveTexturesCache final : angle::NonCopyable
71 {
72   public:
73     ActiveTexturesCache();
74     ~ActiveTexturesCache();
75 
76     Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
77 
78     void clear();
79     void set(size_t textureIndex, Texture *texture);
80     void reset(size_t textureIndex);
81     bool empty() const;
size()82     size_t size() const { return mTextures.size(); }
83 
84   private:
85     ActiveTextureArray<Texture *> mTextures;
86 };
87 
88 namespace state
89 {
90 enum DirtyBitType
91 {
92     // Note: process draw framebuffer binding first, so that other dirty bits whose effect
93     // depend on the current draw framebuffer are not processed while the old framebuffer is
94     // still bound.
95     DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
96     DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
97     DIRTY_BIT_SCISSOR_TEST_ENABLED,
98     DIRTY_BIT_SCISSOR,
99     DIRTY_BIT_VIEWPORT,
100     DIRTY_BIT_DEPTH_RANGE,
101     DIRTY_BIT_BLEND_ENABLED,
102     DIRTY_BIT_BLEND_COLOR,
103     DIRTY_BIT_BLEND_FUNCS,
104     DIRTY_BIT_BLEND_EQUATIONS,
105     DIRTY_BIT_COLOR_MASK,
106     DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
107     DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
108     DIRTY_BIT_SAMPLE_COVERAGE,
109     DIRTY_BIT_SAMPLE_MASK_ENABLED,
110     DIRTY_BIT_SAMPLE_MASK,
111     DIRTY_BIT_DEPTH_TEST_ENABLED,
112     DIRTY_BIT_DEPTH_FUNC,
113     DIRTY_BIT_DEPTH_MASK,
114     DIRTY_BIT_STENCIL_TEST_ENABLED,
115     DIRTY_BIT_STENCIL_FUNCS_FRONT,
116     DIRTY_BIT_STENCIL_FUNCS_BACK,
117     DIRTY_BIT_STENCIL_OPS_FRONT,
118     DIRTY_BIT_STENCIL_OPS_BACK,
119     DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
120     DIRTY_BIT_STENCIL_WRITEMASK_BACK,
121     DIRTY_BIT_CULL_FACE_ENABLED,
122     DIRTY_BIT_CULL_FACE,
123     DIRTY_BIT_FRONT_FACE,
124     DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
125     DIRTY_BIT_POLYGON_OFFSET,
126     DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
127     DIRTY_BIT_LINE_WIDTH,
128     DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
129     DIRTY_BIT_CLEAR_COLOR,
130     DIRTY_BIT_CLEAR_DEPTH,
131     DIRTY_BIT_CLEAR_STENCIL,
132     DIRTY_BIT_UNPACK_STATE,
133     DIRTY_BIT_UNPACK_BUFFER_BINDING,
134     DIRTY_BIT_PACK_STATE,
135     DIRTY_BIT_PACK_BUFFER_BINDING,
136     DIRTY_BIT_DITHER_ENABLED,
137     DIRTY_BIT_RENDERBUFFER_BINDING,
138     DIRTY_BIT_VERTEX_ARRAY_BINDING,
139     DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
140     DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
141     // Note: Fine-grained dirty bits for each index could be an optimization.
142     DIRTY_BIT_PROGRAM_BINDING,  // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
143     DIRTY_BIT_PROGRAM_EXECUTABLE,
144     // Note: Fine-grained dirty bits for each texture/sampler could be an optimization.
145     DIRTY_BIT_SAMPLER_BINDINGS,
146     DIRTY_BIT_TEXTURE_BINDINGS,
147     DIRTY_BIT_IMAGE_BINDINGS,
148     DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
149     DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
150     DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
151     DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
152     DIRTY_BIT_MULTISAMPLING,
153     DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
154     DIRTY_BIT_COVERAGE_MODULATION,                  // CHROMIUM_framebuffer_mixed_samples
155     DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE,  // GL_EXT_sRGB_write_control
156     DIRTY_BIT_CURRENT_VALUES,
157     DIRTY_BIT_PROVOKING_VERTEX,
158     DIRTY_BIT_SAMPLE_SHADING,
159     DIRTY_BIT_PATCH_VERTICES,
160     DIRTY_BIT_EXTENDED,  // clip distances, mipmap generation hint, derivative hint,
161                          // EXT_clip_control, EXT_depth_clamp
162 
163     DIRTY_BIT_INVALID,
164     DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
165 };
166 static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
167 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
168 
169 enum ExtendedDirtyBitType
170 {
171     EXTENDED_DIRTY_BIT_CLIP_CONTROL,                  // EXT_clip_control
172     EXTENDED_DIRTY_BIT_CLIP_DISTANCES,                // clip distances
173     EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED,           // EXT_depth_clamp
174     EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT,        // mipmap generation hint
175     EXTENDED_DIRTY_BIT_POLYGON_MODE,                  // NV_polygon_mode
176     EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED,  // NV_polygon_mode
177     EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED,   // NV_polygon_mode
178     EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT,        // shader derivative hint
179     EXTENDED_DIRTY_BIT_SHADING_RATE,                  // QCOM_shading_rate
180     EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED,              // ANGLE_logic_op
181     EXTENDED_DIRTY_BIT_LOGIC_OP,                      // ANGLE_logic_op
182     EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT,       // KHR_blend_operation_advanced_coherent
183 
184     EXTENDED_DIRTY_BIT_INVALID,
185     EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
186 };
187 static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
188 using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
189 
190 // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
191 enum DirtyObjectType
192 {
193     DIRTY_OBJECT_ACTIVE_TEXTURES,  // Top-level dirty bit. Also see mDirtyActiveTextures.
194     DIRTY_OBJECT_TEXTURES_INIT,
195     DIRTY_OBJECT_IMAGES_INIT,
196     DIRTY_OBJECT_READ_ATTACHMENTS,
197     DIRTY_OBJECT_DRAW_ATTACHMENTS,
198     DIRTY_OBJECT_READ_FRAMEBUFFER,
199     DIRTY_OBJECT_DRAW_FRAMEBUFFER,
200     DIRTY_OBJECT_VERTEX_ARRAY,
201     DIRTY_OBJECT_TEXTURES,  // Top-level dirty bit. Also see mDirtyTextures.
202     DIRTY_OBJECT_IMAGES,    // Top-level dirty bit. Also see mDirtyImages.
203     DIRTY_OBJECT_SAMPLERS,  // Top-level dirty bit. Also see mDirtySamplers.
204     DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT,
205 
206     DIRTY_OBJECT_INVALID,
207     DIRTY_OBJECT_MAX = DIRTY_OBJECT_INVALID,
208 };
209 using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
210 
211 }  // namespace state
212 
213 // This class represents the portion of the GL context's state that is purely private to the
214 // context. Manipulating this state does not affect the other contexts in any way, nor do operations
215 // in other contexts affect this.
216 //
217 // Note that "currently bound X" states do not belong here because unbinding most objects could lead
218 // to object destruction which in turn may trigger a notification to an observer that may affect
219 // another context.
220 class PrivateState : angle::NonCopyable
221 {
222   public:
223     PrivateState(const Version &clientVersion,
224                  bool debug,
225                  bool bindGeneratesResourceCHROMIUM,
226                  bool clientArraysEnabled,
227                  bool robustResourceInit,
228                  bool programBinaryCacheEnabled,
229                  bool isExternal);
230     ~PrivateState();
231 
232     void initialize(Context *context);
233     void initializeForCapture(const Context *context);
234 
235     void reset();
236 
getClientVersion()237     const Version &getClientVersion() const { return mClientVersion; }
getClientMajorVersion()238     GLint getClientMajorVersion() const { return mClientVersion.major; }
getClientMinorVersion()239     GLint getClientMinorVersion() const { return mClientVersion.minor; }
240 
isWebGL()241     bool isWebGL() const { return getExtensions().webglCompatibilityANGLE; }
isWebGL1()242     bool isWebGL1() const { return isWebGL() && getClientVersion().major == 2; }
isGLES1()243     bool isGLES1() const { return getClientVersion() < ES_2_0; }
244 
getCaps()245     const Caps &getCaps() const { return mCaps; }
getTextureCaps()246     const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
getExtensions()247     const Extensions &getExtensions() const { return mExtensions; }
getLimitations()248     const Limitations &getLimitations() const { return mLimitations; }
249 
isExternal()250     bool isExternal() const { return mIsExternal; }
251 
getMutableCaps()252     Caps *getMutableCaps() { return &mCaps; }
getMutableTextureCaps()253     TextureCapsMap *getMutableTextureCaps() { return &mTextureCaps; }
getMutableExtensions()254     Extensions *getMutableExtensions() { return &mExtensions; }
getMutableLimitations()255     Limitations *getMutableLimitations() { return &mLimitations; }
256 
257     // State chunk getters
getRasterizerState()258     const RasterizerState &getRasterizerState() const { return mRasterizer; }
getBlendState()259     const BlendState &getBlendState() const { return mBlendState; }
getBlendStateExt()260     const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
getDepthStencilState()261     const DepthStencilState &getDepthStencilState() const { return mDepthStencil; }
262 
263     // Clear values
264     void setColorClearValue(float red, float green, float blue, float alpha);
265     void setDepthClearValue(float depth);
266     void setStencilClearValue(int stencil);
267 
getColorClearValue()268     const ColorF &getColorClearValue() const { return mColorClearValue; }
getDepthClearValue()269     float getDepthClearValue() const { return mDepthClearValue; }
getStencilClearValue()270     int getStencilClearValue() const { return mStencilClearValue; }
271 
272     // Write mask manipulation
273     void setColorMask(bool red, bool green, bool blue, bool alpha);
274     void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
275     void setDepthMask(bool mask);
276 
277     // Discard toggle & query
isRasterizerDiscardEnabled()278     bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
279     void setRasterizerDiscard(bool enabled);
280 
281     // Primitive restart
isPrimitiveRestartEnabled()282     bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
283     void setPrimitiveRestart(bool enabled);
284 
285     // Face culling state manipulation
isCullFaceEnabled()286     bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
287     void setCullFace(bool enabled);
288     void setCullMode(CullFaceMode mode);
289     void setFrontFace(GLenum front);
290 
291     // EXT_depth_clamp
isDepthClampEnabled()292     bool isDepthClampEnabled() const { return mRasterizer.depthClamp; }
293     void setDepthClamp(bool enabled);
294 
295     // Depth test state manipulation
isDepthTestEnabled()296     bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
isDepthWriteEnabled()297     bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
298     void setDepthTest(bool enabled);
299     void setDepthFunc(GLenum depthFunc);
300     void setDepthRange(float zNear, float zFar);
getNearPlane()301     float getNearPlane() const { return mNearZ; }
getFarPlane()302     float getFarPlane() const { return mFarZ; }
303 
304     // EXT_clip_control
305     void setClipControl(ClipOrigin origin, ClipDepthMode depth);
getClipOrigin()306     ClipOrigin getClipOrigin() const { return mClipOrigin; }
getClipDepthMode()307     ClipDepthMode getClipDepthMode() const { return mClipDepthMode; }
isClipDepthModeZeroToOne()308     bool isClipDepthModeZeroToOne() const { return mClipDepthMode == ClipDepthMode::ZeroToOne; }
309 
310     // Blend state manipulation
isBlendEnabled()311     bool isBlendEnabled() const { return mBlendStateExt.getEnabledMask().test(0); }
isBlendEnabledIndexed(GLuint index)312     bool isBlendEnabledIndexed(GLuint index) const
313     {
314         ASSERT(static_cast<size_t>(index) < mBlendStateExt.getDrawBufferCount());
315         return mBlendStateExt.getEnabledMask().test(index);
316     }
getBlendEnabledDrawBufferMask()317     DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.getEnabledMask(); }
318     void setBlend(bool enabled);
319     void setBlendIndexed(bool enabled, GLuint index);
320     void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
321     void setBlendFactorsIndexed(GLenum sourceRGB,
322                                 GLenum destRGB,
323                                 GLenum sourceAlpha,
324                                 GLenum destAlpha,
325                                 GLuint index);
326     void setBlendColor(float red, float green, float blue, float alpha);
327     void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
328     void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
getBlendColor()329     const ColorF &getBlendColor() const { return mBlendColor; }
330 
331     // Stencil state maniupulation
isStencilTestEnabled()332     bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
isStencilWriteEnabled(GLuint framebufferStencilSize)333     bool isStencilWriteEnabled(GLuint framebufferStencilSize) const
334     {
335         return mDepthStencil.stencilTest &&
336                !(mDepthStencil.isStencilNoOp(framebufferStencilSize) &&
337                  mDepthStencil.isStencilBackNoOp(framebufferStencilSize));
338     }
339     void setStencilTest(bool enabled);
340     void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
341     void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
342     void setStencilWritemask(GLuint stencilWritemask);
343     void setStencilBackWritemask(GLuint stencilBackWritemask);
344     void setStencilOperations(GLenum stencilFail,
345                               GLenum stencilPassDepthFail,
346                               GLenum stencilPassDepthPass);
347     void setStencilBackOperations(GLenum stencilBackFail,
348                                   GLenum stencilBackPassDepthFail,
349                                   GLenum stencilBackPassDepthPass);
getStencilRef()350     GLint getStencilRef() const { return mStencilRef; }
getStencilBackRef()351     GLint getStencilBackRef() const { return mStencilBackRef; }
352 
getPolygonMode()353     PolygonMode getPolygonMode() const { return mRasterizer.polygonMode; }
354     void setPolygonMode(PolygonMode mode);
355 
356     // Depth bias/polygon offset state manipulation
isPolygonOffsetPointEnabled()357     bool isPolygonOffsetPointEnabled() const { return mRasterizer.polygonOffsetPoint; }
isPolygonOffsetLineEnabled()358     bool isPolygonOffsetLineEnabled() const { return mRasterizer.polygonOffsetLine; }
isPolygonOffsetFillEnabled()359     bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
isPolygonOffsetEnabled()360     bool isPolygonOffsetEnabled() const { return mRasterizer.isPolygonOffsetEnabled(); }
361     void setPolygonOffsetPoint(bool enabled);
362     void setPolygonOffsetLine(bool enabled);
363     void setPolygonOffsetFill(bool enabled);
364     void setPolygonOffsetParams(GLfloat factor, GLfloat units, GLfloat clamp);
365 
366     // Multisample coverage state manipulation
isSampleAlphaToCoverageEnabled()367     bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
368     void setSampleAlphaToCoverage(bool enabled);
isSampleCoverageEnabled()369     bool isSampleCoverageEnabled() const { return mSampleCoverage; }
370     void setSampleCoverage(bool enabled);
371     void setSampleCoverageParams(GLclampf value, bool invert);
getSampleCoverageValue()372     GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
getSampleCoverageInvert()373     bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }
374 
375     // Multisample mask state manipulation.
isSampleMaskEnabled()376     bool isSampleMaskEnabled() const { return mSampleMask; }
377     void setSampleMaskEnabled(bool enabled);
378     void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
getSampleMaskWord(GLuint maskNumber)379     GLbitfield getSampleMaskWord(GLuint maskNumber) const
380     {
381         ASSERT(maskNumber < mMaxSampleMaskWords);
382         return mSampleMaskValues[maskNumber];
383     }
getSampleMaskValues()384     SampleMaskArray<GLbitfield> getSampleMaskValues() const { return mSampleMaskValues; }
getMaxSampleMaskWords()385     GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }
386 
387     // Multisampling/alpha to one manipulation.
388     void setSampleAlphaToOne(bool enabled);
isSampleAlphaToOneEnabled()389     bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
390     void setMultisampling(bool enabled);
isMultisamplingEnabled()391     bool isMultisamplingEnabled() const { return mMultiSampling; }
392 
393     void setSampleShading(bool enabled);
isSampleShadingEnabled()394     bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
395     void setMinSampleShading(float value);
getMinSampleShading()396     float getMinSampleShading() const { return mMinSampleShading; }
397 
398     // Scissor test state toggle & query
isScissorTestEnabled()399     bool isScissorTestEnabled() const { return mScissorTest; }
400     void setScissorTest(bool enabled);
401     void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
getScissor()402     const Rectangle &getScissor() const { return mScissor; }
403 
404     // Dither state toggle & query
isDitherEnabled()405     bool isDitherEnabled() const { return mRasterizer.dither; }
406     void setDither(bool enabled);
407 
408     // GL_KHR_blend_equation_advanced_coherent
409     void setBlendAdvancedCoherent(bool enabled);
isBlendAdvancedCoherentEnabled()410     bool isBlendAdvancedCoherentEnabled() const { return mBlendAdvancedCoherent; }
411 
412     // GL_CHROMIUM_bind_generates_resource
isBindGeneratesResourceEnabled()413     bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
414 
415     // GL_ANGLE_client_arrays
areClientArraysEnabled()416     bool areClientArraysEnabled() const { return mClientArraysEnabled; }
417 
418     // GL_ANGLE_robust_resource_initialization
isRobustResourceInitEnabled()419     bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
420 
421     // GL_ANGLE_program_cache_control
isProgramBinaryCacheEnabled()422     bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
423 
424     // Viewport state setter/getter
425     void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
getViewport()426     const Rectangle &getViewport() const { return mViewport; }
427 
428     // QCOM_shading_rate helpers
429     void setShadingRate(GLenum rate);
getShadingRate()430     ShadingRate getShadingRate() const { return mShadingRate; }
431 
432     // Pixel pack state manipulation
433     void setPackAlignment(GLint alignment);
getPackAlignment()434     GLint getPackAlignment() const { return mPack.alignment; }
435     void setPackReverseRowOrder(bool reverseRowOrder);
getPackReverseRowOrder()436     bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
437     void setPackRowLength(GLint rowLength);
getPackRowLength()438     GLint getPackRowLength() const { return mPack.rowLength; }
439     void setPackSkipRows(GLint skipRows);
getPackSkipRows()440     GLint getPackSkipRows() const { return mPack.skipRows; }
441     void setPackSkipPixels(GLint skipPixels);
getPackSkipPixels()442     GLint getPackSkipPixels() const { return mPack.skipPixels; }
getPackState()443     const PixelPackState &getPackState() const { return mPack; }
getPackState()444     PixelPackState &getPackState() { return mPack; }
445 
446     // Pixel unpack state manipulation
447     void setUnpackAlignment(GLint alignment);
getUnpackAlignment()448     GLint getUnpackAlignment() const { return mUnpack.alignment; }
449     void setUnpackRowLength(GLint rowLength);
getUnpackRowLength()450     GLint getUnpackRowLength() const { return mUnpack.rowLength; }
451     void setUnpackImageHeight(GLint imageHeight);
getUnpackImageHeight()452     GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
453     void setUnpackSkipImages(GLint skipImages);
getUnpackSkipImages()454     GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
455     void setUnpackSkipRows(GLint skipRows);
getUnpackSkipRows()456     GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
457     void setUnpackSkipPixels(GLint skipPixels);
getUnpackSkipPixels()458     GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
getUnpackState()459     const PixelUnpackState &getUnpackState() const { return mUnpack; }
getUnpackState()460     PixelUnpackState &getUnpackState() { return mUnpack; }
461 
462     // CHROMIUM_framebuffer_mixed_samples coverage modulation
463     void setCoverageModulation(GLenum components);
getCoverageModulation()464     GLenum getCoverageModulation() const { return mCoverageModulation; }
465 
466     // GL_EXT_sRGB_write_control
467     void setFramebufferSRGB(bool sRGB);
getFramebufferSRGB()468     bool getFramebufferSRGB() const { return mFramebufferSRGB; }
469 
470     // GL_EXT_tessellation_shader
471     void setPatchVertices(GLuint value);
getPatchVertices()472     GLuint getPatchVertices() const { return mPatchVertices; }
473 
474     // GL_ANGLE_shader_pixel_local_storage
475     void setPixelLocalStorageActivePlanes(GLsizei n);
getPixelLocalStorageActivePlanes()476     GLsizei getPixelLocalStorageActivePlanes() const { return mPixelLocalStorageActivePlanes; }
477     // While pixel local storage is active, some draw buffers may be reserved for internal use by
478     // PLS and blocked from the client. All draw buffers at or beyond 'firstActivePLSDrawBuffer' are
479     // overridden.
480     bool hasActivelyOverriddenPLSDrawBuffers(GLint *firstActivePLSDrawBuffer) const;
481     bool isActivelyOverriddenPLSDrawBuffer(GLint drawbuffer) const;
482 
483     // Line width state setter
484     void setLineWidth(GLfloat width);
getLineWidth()485     float getLineWidth() const { return mLineWidth; }
486 
487     void setActiveSampler(unsigned int active);
getActiveSampler()488     unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
489 
490     // Hint setters
491     void setGenerateMipmapHint(GLenum hint);
getGenerateMipmapHint()492     GLenum getGenerateMipmapHint() const { return mGenerateMipmapHint; }
getFragmentShaderDerivativeHint()493     GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
494     void setFragmentShaderDerivativeHint(GLenum hint);
495 
getProvokingVertex()496     ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)497     void setProvokingVertex(ProvokingVertexConvention val)
498     {
499         mDirtyBits.set(state::DIRTY_BIT_PROVOKING_VERTEX);
500         mProvokingVertex = val;
501     }
502 
getVertexAttribCurrentValue(size_t attribNum)503     const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
504     {
505         ASSERT(attribNum < mVertexAttribCurrentValues.size());
506         return mVertexAttribCurrentValues[attribNum];
507     }
getVertexAttribCurrentValues()508     const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
509     {
510         return mVertexAttribCurrentValues;
511     }
512     // This actually clears the current value dirty bits.
513     // TODO(jmadill): Pass mutable dirty bits into Impl.
514     AttributesMask getAndResetDirtyCurrentValues() const;
getCurrentValuesTypeMask()515     ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
516 
getEnabledClipDistances()517     const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
518     void setClipDistanceEnable(int idx, bool enable);
519 
noSimultaneousConstantColorAndAlphaBlendFunc()520     bool noSimultaneousConstantColorAndAlphaBlendFunc() const
521     {
522         return mNoSimultaneousConstantColorAndAlphaBlendFunc;
523     }
524 
getBoundingBoxMinX()525     GLfloat getBoundingBoxMinX() const { return mBoundingBoxMinX; }
getBoundingBoxMinY()526     GLfloat getBoundingBoxMinY() const { return mBoundingBoxMinY; }
getBoundingBoxMinZ()527     GLfloat getBoundingBoxMinZ() const { return mBoundingBoxMinZ; }
getBoundingBoxMinW()528     GLfloat getBoundingBoxMinW() const { return mBoundingBoxMinW; }
getBoundingBoxMaxX()529     GLfloat getBoundingBoxMaxX() const { return mBoundingBoxMaxX; }
getBoundingBoxMaxY()530     GLfloat getBoundingBoxMaxY() const { return mBoundingBoxMaxY; }
getBoundingBoxMaxZ()531     GLfloat getBoundingBoxMaxZ() const { return mBoundingBoxMaxZ; }
getBoundingBoxMaxW()532     GLfloat getBoundingBoxMaxW() const { return mBoundingBoxMaxW; }
533     void setBoundingBox(GLfloat minX,
534                         GLfloat minY,
535                         GLfloat minZ,
536                         GLfloat minW,
537                         GLfloat maxX,
538                         GLfloat maxY,
539                         GLfloat maxZ,
540                         GLfloat maxW);
541 
isTextureRectangleEnabled()542     bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
543 
getBlendFuncConstantAlphaDrawBuffers()544     DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
545     {
546         return mBlendFuncConstantAlphaDrawBuffers;
547     }
548 
getBlendFuncConstantColorDrawBuffers()549     DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
550     {
551         return mBlendFuncConstantColorDrawBuffers;
552     }
553 
554     void setLogicOpEnabled(bool enabled);
isLogicOpEnabled()555     bool isLogicOpEnabled() const { return mLogicOpEnabled; }
556 
557     void setLogicOp(LogicalOperation opcode);
getLogicOp()558     LogicalOperation getLogicOp() const { return mLogicOp; }
559 
560     // Vertex attrib manipulation
561     void setVertexAttribf(GLuint index, const GLfloat values[4]);
562     void setVertexAttribu(GLuint index, const GLuint values[4]);
563     void setVertexAttribi(GLuint index, const GLint values[4]);
564 
565     // QCOM_tiled_rendering
setTiledRendering(bool tiledRendering)566     void setTiledRendering(bool tiledRendering) { mTiledRendering = tiledRendering; }
isTiledRendering()567     bool isTiledRendering() const { return mTiledRendering; }
568 
569     // Debug state
getDebug()570     const Debug &getDebug() const { return mDebug; }
getDebug()571     Debug &getDebug() { return mDebug; }
572 
573     // GL_ANGLE_blob_cache
getBlobCacheCallbacks()574     const BlobCacheCallbacks &getBlobCacheCallbacks() const { return mBlobCacheCallbacks; }
getBlobCacheCallbacks()575     BlobCacheCallbacks &getBlobCacheCallbacks() { return mBlobCacheCallbacks; }
576 
577     // Generic state toggle & query
578     void setEnableFeature(GLenum feature, bool enabled);
579     void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
580     bool getEnableFeature(GLenum feature) const;
581     bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;
582 
583     // State query functions
584     void getBooleanv(GLenum pname, GLboolean *params) const;
585     void getFloatv(GLenum pname, GLfloat *params) const;
586     void getIntegerv(GLenum pname, GLint *params) const;
587     void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
588     void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
589 
getMutableGLES1State()590     GLES1State *getMutableGLES1State() { return &mGLES1State; }
gles1()591     const GLES1State &gles1() const { return mGLES1State; }
592 
getDirtyBits()593     const state::DirtyBits &getDirtyBits() const { return mDirtyBits; }
clearDirtyBits()594     void clearDirtyBits() { mDirtyBits.reset(); }
clearDirtyBits(const state::DirtyBits & bitset)595     void clearDirtyBits(const state::DirtyBits &bitset) { mDirtyBits &= ~bitset; }
setAllDirtyBits()596     void setAllDirtyBits()
597     {
598         mDirtyBits.set();
599         mExtendedDirtyBits.set();
600         mDirtyCurrentValues = mAllAttribsMask;
601     }
602 
getExtendedDirtyBits()603     const state::ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
clearExtendedDirtyBits()604     void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
clearExtendedDirtyBits(const state::ExtendedDirtyBits & bitset)605     void clearExtendedDirtyBits(const state::ExtendedDirtyBits &bitset)
606     {
607         mExtendedDirtyBits &= ~bitset;
608     }
609 
getDirtyObjects()610     const state::DirtyObjects &getDirtyObjects() const { return mDirtyObjects; }
clearDirtyObjects()611     void clearDirtyObjects() { mDirtyObjects.reset(); }
612 
setPerfMonitorActive(bool active)613     void setPerfMonitorActive(bool active) { mIsPerfMonitorActive = active; }
isPerfMonitorActive()614     bool isPerfMonitorActive() const { return mIsPerfMonitorActive; }
615 
616   private:
617     bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
618     bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
619 
620     const Version mClientVersion;
621 
622     // Caps to use for validation
623     Caps mCaps;
624     TextureCapsMap mTextureCaps;
625     Extensions mExtensions;
626     Limitations mLimitations;
627     const bool mIsExternal;
628 
629     ColorF mColorClearValue;
630     GLfloat mDepthClearValue;
631     int mStencilClearValue;
632 
633     RasterizerState mRasterizer;
634     bool mScissorTest;
635     Rectangle mScissor;
636 
637     bool mNoUnclampedBlendColor;
638 
639     BlendState mBlendState;  // Buffer zero blend state legacy struct
640     BlendStateExt mBlendStateExt;
641     ColorF mBlendColor;
642     bool mSampleAlphaToCoverage;
643     bool mSampleCoverage;
644     GLfloat mSampleCoverageValue;
645     bool mSampleCoverageInvert;
646     bool mSampleMask;
647     GLuint mMaxSampleMaskWords;
648     SampleMaskArray<GLbitfield> mSampleMaskValues;
649     bool mIsSampleShadingEnabled;
650     float mMinSampleShading;
651 
652     DepthStencilState mDepthStencil;
653     GLint mStencilRef;
654     GLint mStencilBackRef;
655 
656     GLfloat mLineWidth;
657 
658     GLenum mGenerateMipmapHint;
659     GLenum mFragmentShaderDerivativeHint;
660 
661     Rectangle mViewport;
662     float mNearZ;
663     float mFarZ;
664 
665     ClipOrigin mClipOrigin;
666     ClipDepthMode mClipDepthMode;
667 
668     // GL_ANGLE_provoking_vertex
669     ProvokingVertexConvention mProvokingVertex;
670 
671     using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
672     VertexAttribVector mVertexAttribCurrentValues;  // From glVertexAttrib
673     ComponentTypeMask mCurrentValuesTypeMask;
674 
675     // Mask of all attributes that are available to this context: [0, maxVertexAttributes)
676     AttributesMask mAllAttribsMask;
677 
678     // Texture and sampler bindings
679     GLint mActiveSampler;  // Active texture unit selector - GL_TEXTURE0
680 
681     PixelUnpackState mUnpack;
682     PixelPackState mPack;
683 
684     bool mPrimitiveRestart;
685 
686     bool mMultiSampling;
687     bool mSampleAlphaToOne;
688 
689     // GL_KHR_blend_equation_advanced_coherent
690     bool mBlendAdvancedCoherent;
691 
692     GLenum mCoverageModulation;
693 
694     // GL_EXT_sRGB_write_control
695     bool mFramebufferSRGB;
696 
697     // GL_ANGLE_webgl_compatibility
698     bool mTextureRectangleEnabled;
699 
700     // GL_ANGLE_logic_op
701     bool mLogicOpEnabled;
702     LogicalOperation mLogicOp;
703 
704     // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance
705     ClipDistanceEnableBits mClipDistancesEnabled;
706 
707     // GL_EXT_tessellation_shader
708     GLuint mPatchVertices;
709 
710     // GL_ANGLE_shader_pixel_local_storage
711     GLsizei mPixelLocalStorageActivePlanes;
712 
713     // GLES1 emulation: state specific to GLES1
714     GLES1State mGLES1State;
715 
716     // OES_draw_buffers_indexed
717     DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
718     DrawBufferMask mBlendFuncConstantColorDrawBuffers;
719     bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
720     // Whether the indexed variants of setBlend* have been called.  If so, the call to the
721     // non-indexed variants are not no-oped.
722     bool mSetBlendIndexedInvoked;
723     bool mSetBlendFactorsIndexedInvoked;
724     bool mSetBlendEquationsIndexedInvoked;
725 
726     // GL_EXT_primitive_bounding_box
727     GLfloat mBoundingBoxMinX;
728     GLfloat mBoundingBoxMinY;
729     GLfloat mBoundingBoxMinZ;
730     GLfloat mBoundingBoxMinW;
731     GLfloat mBoundingBoxMaxX;
732     GLfloat mBoundingBoxMaxY;
733     GLfloat mBoundingBoxMaxZ;
734     GLfloat mBoundingBoxMaxW;
735 
736     // QCOM_shading_rate
737     bool mShadingRatePreserveAspectRatio;
738     ShadingRate mShadingRate;
739 
740     // GL_ARM_shader_framebuffer_fetch
741     bool mFetchPerSample;
742 
743     // Whether perf monitoring is enabled through GL_AMD_performance_monitor.
744     bool mIsPerfMonitorActive;
745 
746     // QCOM_tiled_rendering
747     bool mTiledRendering;
748 
749     const bool mBindGeneratesResource;
750     const bool mClientArraysEnabled;
751     const bool mRobustResourceInit;
752     const bool mProgramBinaryCacheEnabled;
753 
754     Debug mDebug;
755 
756     // ANGLE_blob_cache
757     BlobCacheCallbacks mBlobCacheCallbacks;
758 
759     state::DirtyBits mDirtyBits;
760     state::ExtendedDirtyBits mExtendedDirtyBits;
761     state::DirtyObjects mDirtyObjects;
762     mutable AttributesMask mDirtyCurrentValues;
763 };
764 
765 // This class represents all of the GL context's state.
766 class State : angle::NonCopyable
767 {
768   public:
769     State(const State *shareContextState,
770           egl::ShareGroup *shareGroup,
771           TextureManager *shareTextures,
772           SemaphoreManager *shareSemaphores,
773           egl::ContextMutex *contextMutex,
774           const OverlayType *overlay,
775           const Version &clientVersion,
776           bool debug,
777           bool bindGeneratesResourceCHROMIUM,
778           bool clientArraysEnabled,
779           bool robustResourceInit,
780           bool programBinaryCacheEnabled,
781           EGLenum contextPriority,
782           bool hasRobustAccess,
783           bool hasProtectedContent,
784           bool isExternal);
785     ~State();
786 
787     void initialize(Context *context);
788     void reset(const Context *context);
789 
790     // Getters
getContextID()791     ContextID getContextID() const { return mID; }
getContextPriority()792     EGLenum getContextPriority() const { return mContextPriority; }
hasRobustAccess()793     bool hasRobustAccess() const { return mHasRobustAccess; }
hasProtectedContent()794     bool hasProtectedContent() const { return mHasProtectedContent; }
isDebugContext()795     bool isDebugContext() const { return mIsDebugContext; }
getClientMajorVersion()796     GLint getClientMajorVersion() const { return mPrivateState.getClientMajorVersion(); }
getClientMinorVersion()797     GLint getClientMinorVersion() const { return mPrivateState.getClientMinorVersion(); }
getClientVersion()798     const Version &getClientVersion() const { return mPrivateState.getClientVersion(); }
getShareGroup()799     egl::ShareGroup *getShareGroup() const { return mShareGroup; }
800 
isWebGL()801     bool isWebGL() const { return mPrivateState.isWebGL(); }
isWebGL1()802     bool isWebGL1() const { return mPrivateState.isWebGL1(); }
isGLES1()803     bool isGLES1() const { return mPrivateState.isGLES1(); }
804 
getCaps()805     const Caps &getCaps() const { return mPrivateState.getCaps(); }
getTextureCaps()806     const TextureCapsMap &getTextureCaps() const { return mPrivateState.getTextureCaps(); }
getExtensions()807     const Extensions &getExtensions() const { return mPrivateState.getExtensions(); }
getLimitations()808     const Limitations &getLimitations() const { return mPrivateState.getLimitations(); }
809 
isExternal()810     bool isExternal() const { return mPrivateState.isExternal(); }
811 
getMutableCaps()812     Caps *getMutableCaps() { return mPrivateState.getMutableCaps(); }
getMutableTextureCaps()813     TextureCapsMap *getMutableTextureCaps() { return mPrivateState.getMutableTextureCaps(); }
getMutableExtensions()814     Extensions *getMutableExtensions() { return mPrivateState.getMutableExtensions(); }
getMutableLimitations()815     Limitations *getMutableLimitations() { return mPrivateState.getMutableLimitations(); }
816 
getTextureCap(GLenum internalFormat)817     const TextureCaps &getTextureCap(GLenum internalFormat) const
818     {
819         return getTextureCaps().get(internalFormat);
820     }
821 
822     bool allActiveDrawBufferChannelsMasked() const;
823     bool anyActiveDrawBufferChannelMasked() const;
824 
825     // Texture binding & active texture unit manipulation
826     void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
827     Texture *getTargetTexture(TextureType type) const;
828 
getSamplerTexture(unsigned int sampler,TextureType type)829     Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
830     {
831         ASSERT(sampler < mSamplerTextures[type].size());
832         return mSamplerTextures[type][sampler].get();
833     }
834 
835     TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
836     void detachTexture(Context *context, const TextureMap &zeroTextures, TextureID texture);
837     void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
838 
839     void invalidateTextureBindings(TextureType type);
840 
841     // Sampler object binding manipulation
842     void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
getSamplerId(GLuint textureUnit)843     SamplerID getSamplerId(GLuint textureUnit) const
844     {
845         ASSERT(textureUnit < mSamplers.size());
846         return mSamplers[textureUnit].id();
847     }
848 
getSampler(GLuint textureUnit)849     Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }
850 
getSamplers()851     const SamplerBindingVector &getSamplers() const { return mSamplers; }
852 
853     void detachSampler(const Context *context, SamplerID sampler);
854 
855     // Renderbuffer binding manipulation
856     void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
getRenderbufferId()857     RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
getCurrentRenderbuffer()858     Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
859     void detachRenderbuffer(Context *context, RenderbufferID renderbuffer);
860 
861     // Framebuffer binding manipulation
862     void setReadFramebufferBinding(Framebuffer *framebuffer);
863     void setDrawFramebufferBinding(Framebuffer *framebuffer);
864     Framebuffer *getTargetFramebuffer(GLenum target) const;
getReadFramebuffer()865     Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
getDrawFramebuffer()866     Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
867     Framebuffer *getDefaultFramebuffer() const;
868 
869     bool removeReadFramebufferBinding(FramebufferID framebuffer);
870     bool removeDrawFramebufferBinding(FramebufferID framebuffer);
871 
872     // Vertex array object binding manipulation
873     void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
874     bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
875     VertexArrayID getVertexArrayId() const;
876 
getVertexArray()877     VertexArray *getVertexArray() const
878     {
879         ASSERT(mVertexArray != nullptr);
880         return mVertexArray;
881     }
882 
883     // If both a Program and a ProgramPipeline are bound, the Program will
884     // always override the ProgramPipeline.
getProgramExecutable()885     ProgramExecutable *getProgramExecutable() const { return mExecutable.get(); }
ensureNoPendingLink(const Context * context)886     void ensureNoPendingLink(const Context *context) const
887     {
888         if (mProgram)
889         {
890             mProgram->resolveLink(context);
891         }
892         else if (mProgramPipeline.get())
893         {
894             mProgramPipeline->resolveLink(context);
895         }
896     }
getLinkedProgramExecutable(const Context * context)897     ProgramExecutable *getLinkedProgramExecutable(const Context *context) const
898     {
899         ensureNoPendingLink(context);
900         return mExecutable.get();
901     }
902 
903     // Program binding manipulation
904     angle::Result setProgram(const Context *context, Program *newProgram);
905 
getProgram()906     Program *getProgram() const
907     {
908         ASSERT(!mProgram || !mProgram->isLinking());
909         return mProgram;
910     }
911 
getLinkedProgram(const Context * context)912     Program *getLinkedProgram(const Context *context) const
913     {
914         if (mProgram)
915         {
916             mProgram->resolveLink(context);
917         }
918         return mProgram;
919     }
920 
getProgramPipeline()921     ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }
922 
getLinkedProgramPipeline(const Context * context)923     ProgramPipeline *getLinkedProgramPipeline(const Context *context) const
924     {
925         if (mProgramPipeline.get())
926         {
927             mProgramPipeline->resolveLink(context);
928         }
929         return mProgramPipeline.get();
930     }
931 
932     // Transform feedback object (not buffer) binding manipulation
933     void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
getCurrentTransformFeedback()934     TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }
935 
isTransformFeedbackActive()936     ANGLE_INLINE bool isTransformFeedbackActive() const
937     {
938         TransformFeedback *curTransformFeedback = mTransformFeedback.get();
939         return curTransformFeedback && curTransformFeedback->isActive();
940     }
isTransformFeedbackActiveUnpaused()941     ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
942     {
943         TransformFeedback *curTransformFeedback = mTransformFeedback.get();
944         return curTransformFeedback && curTransformFeedback->isActive() &&
945                !curTransformFeedback->isPaused();
946     }
947 
948     bool removeTransformFeedbackBinding(const Context *context,
949                                         TransformFeedbackID transformFeedback);
950 
951     // Query binding manipulation
952     bool isQueryActive(QueryType type) const;
953     bool isQueryActive(Query *query) const;
954     void setActiveQuery(const Context *context, QueryType type, Query *query);
955     QueryID getActiveQueryId(QueryType type) const;
956     Query *getActiveQuery(QueryType type) const;
957 
958     // Program Pipeline binding manipulation
959     angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
960     void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
961 
962     //// Typed buffer binding point manipulation ////
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)963     ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
964     {
965         (this->*(kBufferSetters[target]))(context, buffer);
966     }
967 
getTargetBuffer(BufferBinding target)968     ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
969     {
970         switch (target)
971         {
972             case BufferBinding::ElementArray:
973                 return getVertexArray()->getElementArrayBuffer();
974             default:
975                 return mBoundBuffers[target].get();
976         }
977     }
978 
getArrayBuffer()979     ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
980 
981     angle::Result setIndexedBufferBinding(const Context *context,
982                                           BufferBinding target,
983                                           GLuint index,
984                                           Buffer *buffer,
985                                           GLintptr offset,
986                                           GLsizeiptr size);
987 
getAtomicCounterBufferCount()988     size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
989 
hasValidAtomicCounterBuffer()990     ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
991     {
992         return mBoundAtomicCounterBuffersMask.any();
993     }
994 
995     const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
996     const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
997     const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
998 
getUniformBuffersMask()999     const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
1000         const
1001     {
1002         return mBoundUniformBuffersMask;
1003     }
1004     const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS> &
getAtomicCounterBuffersMask()1005     getAtomicCounterBuffersMask() const
1006     {
1007         return mBoundAtomicCounterBuffersMask;
1008     }
1009     const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS> &
getShaderStorageBuffersMask()1010     getShaderStorageBuffersMask() const
1011     {
1012         return mBoundShaderStorageBuffersMask;
1013     }
1014 
1015     // Detach a buffer from all bindings
1016     angle::Result detachBuffer(Context *context, const Buffer *buffer);
1017 
1018     // Vertex attrib manipulation
1019     void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
1020 
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,bool normalized,GLsizei stride,const void * pointer)1021     ANGLE_INLINE void setVertexAttribPointer(const Context *context,
1022                                              unsigned int attribNum,
1023                                              Buffer *boundBuffer,
1024                                              GLint size,
1025                                              VertexAttribType type,
1026                                              bool normalized,
1027                                              GLsizei stride,
1028                                              const void *pointer)
1029     {
1030         mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
1031                                              normalized, stride, pointer);
1032         mDirtyObjects.set(state::DIRTY_OBJECT_VERTEX_ARRAY);
1033     }
1034 
setVertexAttribIPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)1035     ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
1036                                               unsigned int attribNum,
1037                                               Buffer *boundBuffer,
1038                                               GLint size,
1039                                               VertexAttribType type,
1040                                               GLsizei stride,
1041                                               const void *pointer)
1042     {
1043         mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
1044                                               pointer);
1045         mDirtyObjects.set(state::DIRTY_OBJECT_VERTEX_ARRAY);
1046     }
1047 
1048     void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
1049     const void *getVertexAttribPointer(unsigned int attribNum) const;
1050 
1051     void bindVertexBuffer(const Context *context,
1052                           GLuint bindingIndex,
1053                           Buffer *boundBuffer,
1054                           GLintptr offset,
1055                           GLsizei stride);
1056     void setVertexAttribFormat(GLuint attribIndex,
1057                                GLint size,
1058                                VertexAttribType type,
1059                                bool normalized,
1060                                bool pureInteger,
1061                                GLuint relativeOffset);
1062 
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1063     void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1064     {
1065         mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
1066         mDirtyObjects.set(state::DIRTY_OBJECT_VERTEX_ARRAY);
1067     }
1068 
1069     void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor);
1070 
1071     // State query functions
1072     void getBooleanv(GLenum pname, GLboolean *params) const;
getFloatv(GLenum pname,GLfloat * params)1073     void getFloatv(GLenum pname, GLfloat *params) const { mPrivateState.getFloatv(pname, params); }
1074     angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
1075     void getPointerv(const Context *context, GLenum pname, void **params) const;
1076     void getIntegeri_v(const Context *context, GLenum target, GLuint index, GLint *data) const;
1077     void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
1078     void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
1079 
isDrawFramebufferBindingDirty()1080     bool isDrawFramebufferBindingDirty() const
1081     {
1082         return mDirtyBits.test(state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1083     }
1084 
1085     // Sets the dirty bit for the program executable.
1086     angle::Result installProgramExecutable(const Context *context);
1087     // Sets the dirty bit for the program pipeline executable.
1088     angle::Result installProgramPipelineExecutable(const Context *context);
1089 
getDirtyBits()1090     const state::DirtyBits getDirtyBits() const
1091     {
1092         return mDirtyBits | mPrivateState.getDirtyBits();
1093     }
clearDirtyBits()1094     void clearDirtyBits()
1095     {
1096         mDirtyBits.reset();
1097         mPrivateState.clearDirtyBits();
1098     }
clearDirtyBits(const state::DirtyBits & bitset)1099     void clearDirtyBits(const state::DirtyBits &bitset)
1100     {
1101         mDirtyBits &= ~bitset;
1102         mPrivateState.clearDirtyBits(bitset);
1103     }
setAllDirtyBits()1104     void setAllDirtyBits()
1105     {
1106         mDirtyBits.set();
1107         mExtendedDirtyBits.set();
1108         mPrivateState.setAllDirtyBits();
1109     }
1110 
getExtendedDirtyBits()1111     const state::ExtendedDirtyBits getExtendedDirtyBits() const
1112     {
1113         return mExtendedDirtyBits | mPrivateState.getExtendedDirtyBits();
1114     }
clearExtendedDirtyBits()1115     void clearExtendedDirtyBits()
1116     {
1117         mExtendedDirtyBits.reset();
1118         mPrivateState.clearExtendedDirtyBits();
1119     }
clearExtendedDirtyBits(const state::ExtendedDirtyBits & bitset)1120     void clearExtendedDirtyBits(const state::ExtendedDirtyBits &bitset)
1121     {
1122         mExtendedDirtyBits &= ~bitset;
1123         mPrivateState.clearExtendedDirtyBits(bitset);
1124     }
1125 
clearDirtyObjects()1126     void clearDirtyObjects()
1127     {
1128         mDirtyObjects.reset();
1129         mPrivateState.clearDirtyObjects();
1130     }
setAllDirtyObjects()1131     void setAllDirtyObjects() { mDirtyObjects.set(); }
1132     angle::Result syncDirtyObjects(const Context *context,
1133                                    const state::DirtyObjects &bitset,
1134                                    Command command);
1135     angle::Result syncDirtyObject(const Context *context, GLenum target);
1136     void setObjectDirty(GLenum target);
1137     void setTextureDirty(size_t textureUnitIndex);
1138     void setSamplerDirty(size_t samplerIndex);
1139 
setReadFramebufferDirty()1140     ANGLE_INLINE void setReadFramebufferDirty()
1141     {
1142         mDirtyObjects.set(state::DIRTY_OBJECT_READ_FRAMEBUFFER);
1143         mDirtyObjects.set(state::DIRTY_OBJECT_READ_ATTACHMENTS);
1144     }
1145 
setDrawFramebufferDirty()1146     ANGLE_INLINE void setDrawFramebufferDirty()
1147     {
1148         mDirtyObjects.set(state::DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1149         mDirtyObjects.set(state::DIRTY_OBJECT_DRAW_ATTACHMENTS);
1150     }
1151 
1152     void setImageUnit(const Context *context,
1153                       size_t unit,
1154                       Texture *texture,
1155                       GLint level,
1156                       GLboolean layered,
1157                       GLint layer,
1158                       GLenum access,
1159                       GLenum format);
1160 
getImageUnit(size_t unit)1161     const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
getActiveTexturesCache()1162     const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
1163 
1164     // "onActiveTextureChange" is called when a texture binding changes.
1165     void onActiveTextureChange(const Context *context, size_t textureUnit);
1166 
1167     // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
1168     void onActiveTextureStateChange(const Context *context, size_t textureUnit);
1169 
1170     void onImageStateChange(const Context *context, size_t unit);
1171 
1172     void onUniformBufferStateChange(size_t uniformBufferIndex);
1173     void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
1174     void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
1175 
isCurrentTransformFeedback(const TransformFeedback * tf)1176     bool isCurrentTransformFeedback(const TransformFeedback *tf) const
1177     {
1178         return tf == mTransformFeedback.get();
1179     }
isCurrentVertexArray(const VertexArray * va)1180     bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
1181 
1182     // Helpers for setting bound buffers. They should all have the same signature.
1183     // Not meant to be called externally. Used for local helpers in State.cpp.
1184     template <BufferBinding Target>
1185     void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
1186 
1187     template <BufferBinding Target>
1188     void setGenericBufferBinding(const Context *context, Buffer *buffer);
1189 
1190     using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
1191 
validateSamplerFormats()1192     ANGLE_INLINE bool validateSamplerFormats() const
1193     {
1194         return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
1195                                     mExecutable->getActiveSamplersMask())));
1196     }
1197 
setReadFramebufferBindingDirty()1198     ANGLE_INLINE void setReadFramebufferBindingDirty()
1199     {
1200         mDirtyBits.set(state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
1201     }
1202 
setDrawFramebufferBindingDirty()1203     ANGLE_INLINE void setDrawFramebufferBindingDirty()
1204     {
1205         mDirtyBits.set(state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1206     }
1207 
getOverlay()1208     const OverlayType *getOverlay() const { return mOverlay; }
1209 
1210     // Not for general use.
getBufferManagerForCapture()1211     const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()1212     const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()1213     const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()1214     const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()1215     const RenderbufferManager &getRenderbufferManagerForCapture() const
1216     {
1217         return *mRenderbufferManager;
1218     }
getFramebufferManagerForCapture()1219     const FramebufferManager &getFramebufferManagerForCapture() const
1220     {
1221         return *mFramebufferManager;
1222     }
getShaderProgramManagerForCapture()1223     const ShaderProgramManager &getShaderProgramManagerForCapture() const
1224     {
1225         return *mShaderProgramManager;
1226     }
getSyncManagerForCapture()1227     const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()1228     const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getProgramPipelineManagerForCapture()1229     const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
1230     {
1231         return mProgramPipelineManager;
1232     }
getSamplerBindingsForCapture()1233     const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
getActiveQueriesForCapture()1234     const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
1235     void initializeForCapture(const Context *context);
1236 
hasConstantAlphaBlendFunc()1237     bool hasConstantAlphaBlendFunc() const
1238     {
1239         return (getBlendFuncConstantAlphaDrawBuffers() & getBlendStateExt().getEnabledMask()).any();
1240     }
1241 
hasSimultaneousConstantColorAndAlphaBlendFunc()1242     bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
1243     {
1244         return (getBlendFuncConstantColorDrawBuffers() & getBlendStateExt().getEnabledMask())
1245                    .any() &&
1246                hasConstantAlphaBlendFunc();
1247     }
1248 
getOffsetBindingPointerUniformBuffers()1249     const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
1250 
getOffsetBindingPointerAtomicCounterBuffers()1251     const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
1252     {
1253         return mAtomicCounterBuffers;
1254     }
1255 
getOffsetBindingPointerShaderStorageBuffers()1256     const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
1257     {
1258         return mShaderStorageBuffers;
1259     }
1260 
getTexturesIncompatibleWithSamplers()1261     ActiveTextureMask getTexturesIncompatibleWithSamplers() const
1262     {
1263         return mTexturesIncompatibleWithSamplers;
1264     }
1265 
getImageUnits()1266     const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
1267 
hasDisplayTextureShareGroup()1268     bool hasDisplayTextureShareGroup() const { return mDisplayTextureShareGroup; }
1269 
1270     // GL_KHR_parallel_shader_compile
1271     void setMaxShaderCompilerThreads(GLuint count);
getMaxShaderCompilerThreads()1272     GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
1273 
1274     // Convenience functions that forward to context-private state.
getRasterizerState()1275     const RasterizerState &getRasterizerState() const { return mPrivateState.getRasterizerState(); }
getBlendState()1276     const BlendState &getBlendState() const { return mPrivateState.getBlendState(); }
getBlendStateExt()1277     const BlendStateExt &getBlendStateExt() const { return mPrivateState.getBlendStateExt(); }
getDepthStencilState()1278     const DepthStencilState &getDepthStencilState() const
1279     {
1280         return mPrivateState.getDepthStencilState();
1281     }
getColorClearValue()1282     const ColorF &getColorClearValue() const { return mPrivateState.getColorClearValue(); }
getDepthClearValue()1283     float getDepthClearValue() const { return mPrivateState.getDepthClearValue(); }
getStencilClearValue()1284     int getStencilClearValue() const { return mPrivateState.getStencilClearValue(); }
isRasterizerDiscardEnabled()1285     bool isRasterizerDiscardEnabled() const { return mPrivateState.isRasterizerDiscardEnabled(); }
isPrimitiveRestartEnabled()1286     bool isPrimitiveRestartEnabled() const { return mPrivateState.isPrimitiveRestartEnabled(); }
isCullFaceEnabled()1287     bool isCullFaceEnabled() const { return mPrivateState.isCullFaceEnabled(); }
isDepthClampEnabled()1288     bool isDepthClampEnabled() const { return mPrivateState.isDepthClampEnabled(); }
isDepthTestEnabled()1289     bool isDepthTestEnabled() const { return mPrivateState.isDepthTestEnabled(); }
isDepthWriteEnabled()1290     bool isDepthWriteEnabled() const { return mPrivateState.isDepthWriteEnabled(); }
getNearPlane()1291     float getNearPlane() const { return mPrivateState.getNearPlane(); }
getFarPlane()1292     float getFarPlane() const { return mPrivateState.getFarPlane(); }
getClipOrigin()1293     ClipOrigin getClipOrigin() const { return mPrivateState.getClipOrigin(); }
getClipDepthMode()1294     ClipDepthMode getClipDepthMode() const { return mPrivateState.getClipDepthMode(); }
isClipDepthModeZeroToOne()1295     bool isClipDepthModeZeroToOne() const { return mPrivateState.isClipDepthModeZeroToOne(); }
isBlendEnabled()1296     bool isBlendEnabled() const { return mPrivateState.isBlendEnabled(); }
isBlendEnabledIndexed(GLuint index)1297     bool isBlendEnabledIndexed(GLuint index) const
1298     {
1299         return mPrivateState.isBlendEnabledIndexed(index);
1300     }
getBlendEnabledDrawBufferMask()1301     DrawBufferMask getBlendEnabledDrawBufferMask() const
1302     {
1303         return mPrivateState.getBlendEnabledDrawBufferMask();
1304     }
getBlendColor()1305     const ColorF &getBlendColor() const { return mPrivateState.getBlendColor(); }
isStencilTestEnabled()1306     bool isStencilTestEnabled() const { return mPrivateState.isStencilTestEnabled(); }
isBlendAdvancedCoherentEnabled()1307     bool isBlendAdvancedCoherentEnabled() const
1308     {
1309         return mPrivateState.isBlendAdvancedCoherentEnabled();
1310     }
isStencilWriteEnabled(GLuint framebufferStencilSize)1311     bool isStencilWriteEnabled(GLuint framebufferStencilSize) const
1312     {
1313         return mPrivateState.isStencilWriteEnabled(framebufferStencilSize);
1314     }
getStencilRef()1315     GLint getStencilRef() const { return mPrivateState.getStencilRef(); }
getStencilBackRef()1316     GLint getStencilBackRef() const { return mPrivateState.getStencilBackRef(); }
getPolygonMode()1317     PolygonMode getPolygonMode() const { return mPrivateState.getPolygonMode(); }
isPolygonOffsetPointEnabled()1318     bool isPolygonOffsetPointEnabled() const { return mPrivateState.isPolygonOffsetPointEnabled(); }
isPolygonOffsetLineEnabled()1319     bool isPolygonOffsetLineEnabled() const { return mPrivateState.isPolygonOffsetLineEnabled(); }
isPolygonOffsetFillEnabled()1320     bool isPolygonOffsetFillEnabled() const { return mPrivateState.isPolygonOffsetFillEnabled(); }
isPolygonOffsetEnabled()1321     bool isPolygonOffsetEnabled() const { return mPrivateState.isPolygonOffsetEnabled(); }
isSampleAlphaToCoverageEnabled()1322     bool isSampleAlphaToCoverageEnabled() const
1323     {
1324         return mPrivateState.isSampleAlphaToCoverageEnabled();
1325     }
isSampleCoverageEnabled()1326     bool isSampleCoverageEnabled() const { return mPrivateState.isSampleCoverageEnabled(); }
getSampleCoverageValue()1327     GLclampf getSampleCoverageValue() const { return mPrivateState.getSampleCoverageValue(); }
getSampleCoverageInvert()1328     bool getSampleCoverageInvert() const { return mPrivateState.getSampleCoverageInvert(); }
isSampleMaskEnabled()1329     bool isSampleMaskEnabled() const { return mPrivateState.isSampleMaskEnabled(); }
getSampleMaskWord(GLuint maskNumber)1330     GLbitfield getSampleMaskWord(GLuint maskNumber) const
1331     {
1332         return mPrivateState.getSampleMaskWord(maskNumber);
1333     }
getSampleMaskValues()1334     SampleMaskArray<GLbitfield> getSampleMaskValues() const
1335     {
1336         return mPrivateState.getSampleMaskValues();
1337     }
getMaxSampleMaskWords()1338     GLuint getMaxSampleMaskWords() const { return mPrivateState.getMaxSampleMaskWords(); }
isSampleAlphaToOneEnabled()1339     bool isSampleAlphaToOneEnabled() const { return mPrivateState.isSampleAlphaToOneEnabled(); }
isMultisamplingEnabled()1340     bool isMultisamplingEnabled() const { return mPrivateState.isMultisamplingEnabled(); }
isSampleShadingEnabled()1341     bool isSampleShadingEnabled() const { return mPrivateState.isSampleShadingEnabled(); }
getMinSampleShading()1342     float getMinSampleShading() const { return mPrivateState.getMinSampleShading(); }
isScissorTestEnabled()1343     bool isScissorTestEnabled() const { return mPrivateState.isScissorTestEnabled(); }
getScissor()1344     const Rectangle &getScissor() const { return mPrivateState.getScissor(); }
isDitherEnabled()1345     bool isDitherEnabled() const { return mPrivateState.isDitherEnabled(); }
isBindGeneratesResourceEnabled()1346     bool isBindGeneratesResourceEnabled() const
1347     {
1348         return mPrivateState.isBindGeneratesResourceEnabled();
1349     }
areClientArraysEnabled()1350     bool areClientArraysEnabled() const { return mPrivateState.areClientArraysEnabled(); }
isRobustResourceInitEnabled()1351     bool isRobustResourceInitEnabled() const { return mPrivateState.isRobustResourceInitEnabled(); }
isProgramBinaryCacheEnabled()1352     bool isProgramBinaryCacheEnabled() const { return mPrivateState.isProgramBinaryCacheEnabled(); }
getViewport()1353     const Rectangle &getViewport() const { return mPrivateState.getViewport(); }
getShadingRate()1354     ShadingRate getShadingRate() const { return mPrivateState.getShadingRate(); }
getPackAlignment()1355     GLint getPackAlignment() const { return mPrivateState.getPackAlignment(); }
getPackReverseRowOrder()1356     bool getPackReverseRowOrder() const { return mPrivateState.getPackReverseRowOrder(); }
getPackRowLength()1357     GLint getPackRowLength() const { return mPrivateState.getPackRowLength(); }
getPackSkipRows()1358     GLint getPackSkipRows() const { return mPrivateState.getPackSkipRows(); }
getPackSkipPixels()1359     GLint getPackSkipPixels() const { return mPrivateState.getPackSkipPixels(); }
getPackState()1360     const PixelPackState &getPackState() const { return mPrivateState.getPackState(); }
getPackState()1361     PixelPackState &getPackState() { return mPrivateState.getPackState(); }
getUnpackAlignment()1362     GLint getUnpackAlignment() const { return mPrivateState.getUnpackAlignment(); }
getUnpackRowLength()1363     GLint getUnpackRowLength() const { return mPrivateState.getUnpackRowLength(); }
getUnpackImageHeight()1364     GLint getUnpackImageHeight() const { return mPrivateState.getUnpackImageHeight(); }
getUnpackSkipImages()1365     GLint getUnpackSkipImages() const { return mPrivateState.getUnpackSkipImages(); }
getUnpackSkipRows()1366     GLint getUnpackSkipRows() const { return mPrivateState.getUnpackSkipRows(); }
getUnpackSkipPixels()1367     GLint getUnpackSkipPixels() const { return mPrivateState.getUnpackSkipPixels(); }
getUnpackState()1368     const PixelUnpackState &getUnpackState() const { return mPrivateState.getUnpackState(); }
getUnpackState()1369     PixelUnpackState &getUnpackState() { return mPrivateState.getUnpackState(); }
getCoverageModulation()1370     GLenum getCoverageModulation() const { return mPrivateState.getCoverageModulation(); }
getFramebufferSRGB()1371     bool getFramebufferSRGB() const { return mPrivateState.getFramebufferSRGB(); }
getPatchVertices()1372     GLuint getPatchVertices() const { return mPrivateState.getPatchVertices(); }
setPixelLocalStorageActivePlanes(GLsizei n)1373     void setPixelLocalStorageActivePlanes(GLsizei n)
1374     {
1375         mPrivateState.setPixelLocalStorageActivePlanes(n);
1376     }
getPixelLocalStorageActivePlanes()1377     GLsizei getPixelLocalStorageActivePlanes() const
1378     {
1379         return mPrivateState.getPixelLocalStorageActivePlanes();
1380     }
getLineWidth()1381     float getLineWidth() const { return mPrivateState.getLineWidth(); }
getActiveSampler()1382     unsigned int getActiveSampler() const { return mPrivateState.getActiveSampler(); }
getGenerateMipmapHint()1383     GLenum getGenerateMipmapHint() const { return mPrivateState.getGenerateMipmapHint(); }
getFragmentShaderDerivativeHint()1384     GLenum getFragmentShaderDerivativeHint() const
1385     {
1386         return mPrivateState.getFragmentShaderDerivativeHint();
1387     }
getProvokingVertex()1388     ProvokingVertexConvention getProvokingVertex() const
1389     {
1390         return mPrivateState.getProvokingVertex();
1391     }
getVertexAttribCurrentValue(size_t attribNum)1392     const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
1393     {
1394         return mPrivateState.getVertexAttribCurrentValue(attribNum);
1395     }
getVertexAttribCurrentValues()1396     const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
1397     {
1398         return mPrivateState.getVertexAttribCurrentValues();
1399     }
getAndResetDirtyCurrentValues()1400     AttributesMask getAndResetDirtyCurrentValues() const
1401     {
1402         return mPrivateState.getAndResetDirtyCurrentValues();
1403     }
getCurrentValuesTypeMask()1404     ComponentTypeMask getCurrentValuesTypeMask() const
1405     {
1406         return mPrivateState.getCurrentValuesTypeMask();
1407     }
getEnabledClipDistances()1408     const ClipDistanceEnableBits &getEnabledClipDistances() const
1409     {
1410         return mPrivateState.getEnabledClipDistances();
1411     }
noSimultaneousConstantColorAndAlphaBlendFunc()1412     bool noSimultaneousConstantColorAndAlphaBlendFunc() const
1413     {
1414         return mPrivateState.noSimultaneousConstantColorAndAlphaBlendFunc();
1415     }
getBoundingBoxMinX()1416     GLfloat getBoundingBoxMinX() const { return mPrivateState.getBoundingBoxMinX(); }
getBoundingBoxMinY()1417     GLfloat getBoundingBoxMinY() const { return mPrivateState.getBoundingBoxMinY(); }
getBoundingBoxMinZ()1418     GLfloat getBoundingBoxMinZ() const { return mPrivateState.getBoundingBoxMinZ(); }
getBoundingBoxMinW()1419     GLfloat getBoundingBoxMinW() const { return mPrivateState.getBoundingBoxMinW(); }
getBoundingBoxMaxX()1420     GLfloat getBoundingBoxMaxX() const { return mPrivateState.getBoundingBoxMaxX(); }
getBoundingBoxMaxY()1421     GLfloat getBoundingBoxMaxY() const { return mPrivateState.getBoundingBoxMaxY(); }
getBoundingBoxMaxZ()1422     GLfloat getBoundingBoxMaxZ() const { return mPrivateState.getBoundingBoxMaxZ(); }
getBoundingBoxMaxW()1423     GLfloat getBoundingBoxMaxW() const { return mPrivateState.getBoundingBoxMaxW(); }
isTextureRectangleEnabled()1424     bool isTextureRectangleEnabled() const { return mPrivateState.isTextureRectangleEnabled(); }
getBlendFuncConstantAlphaDrawBuffers()1425     DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
1426     {
1427         return mPrivateState.getBlendFuncConstantAlphaDrawBuffers();
1428     }
getBlendFuncConstantColorDrawBuffers()1429     DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
1430     {
1431         return mPrivateState.getBlendFuncConstantColorDrawBuffers();
1432     }
isLogicOpEnabled()1433     bool isLogicOpEnabled() const { return mPrivateState.isLogicOpEnabled(); }
getLogicOp()1434     LogicalOperation getLogicOp() const { return mPrivateState.getLogicOp(); }
isPerfMonitorActive()1435     bool isPerfMonitorActive() const { return mPrivateState.isPerfMonitorActive(); }
getDebug()1436     const Debug &getDebug() const { return mPrivateState.getDebug(); }
getDebug()1437     Debug &getDebug() { return mPrivateState.getDebug(); }
getBlobCacheCallbacks()1438     const BlobCacheCallbacks &getBlobCacheCallbacks() const
1439     {
1440         return mPrivateState.getBlobCacheCallbacks();
1441     }
getBlobCacheCallbacks()1442     BlobCacheCallbacks &getBlobCacheCallbacks() { return mPrivateState.getBlobCacheCallbacks(); }
getEnableFeature(GLenum feature)1443     bool getEnableFeature(GLenum feature) const { return mPrivateState.getEnableFeature(feature); }
getEnableFeatureIndexed(GLenum feature,GLuint index)1444     bool getEnableFeatureIndexed(GLenum feature, GLuint index) const
1445     {
1446         return mPrivateState.getEnableFeatureIndexed(feature, index);
1447     }
getAndResetDirtyUniformBlocks()1448     ProgramUniformBlockMask getAndResetDirtyUniformBlocks() const
1449     {
1450         ProgramUniformBlockMask dirtyBits = mDirtyUniformBlocks;
1451         mDirtyUniformBlocks.reset();
1452         return dirtyBits;
1453     }
privateState()1454     const PrivateState &privateState() const { return mPrivateState; }
gles1()1455     const GLES1State &gles1() const { return mPrivateState.gles1(); }
1456 
1457     // Used by the capture/replay tool to create state.
getMutablePrivateStateForCapture()1458     PrivateState *getMutablePrivateStateForCapture() { return &mPrivateState; }
1459 
1460   private:
1461     friend class Context;
1462 
1463     // Used only by the entry points to set private state without holding the share group lock.
getMutablePrivateState()1464     PrivateState *getMutablePrivateState() { return &mPrivateState; }
getMutableGLES1State()1465     GLES1State *getMutableGLES1State() { return mPrivateState.getMutableGLES1State(); }
1466 
1467     angle::Result installProgramPipelineExecutableIfNotAlready(const Context *context);
1468     angle::Result onExecutableChange(const Context *context);
1469 
1470     void unsetActiveTextures(const ActiveTextureMask &textureMask);
1471     void setActiveTextureDirty(size_t textureIndex, Texture *texture);
1472     void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
1473     void updateActiveTextureStateOnSync(const Context *context,
1474                                         size_t textureIndex,
1475                                         const Sampler *sampler,
1476                                         Texture *texture);
1477     Texture *getTextureForActiveSampler(TextureType type, size_t index);
1478 
1479     // Functions to synchronize dirty states
1480     angle::Result syncActiveTextures(const Context *context, Command command);
1481     angle::Result syncTexturesInit(const Context *context, Command command);
1482     angle::Result syncImagesInit(const Context *context, Command command);
1483     angle::Result syncReadAttachments(const Context *context, Command command);
1484     angle::Result syncDrawAttachments(const Context *context, Command command);
1485     angle::Result syncReadFramebuffer(const Context *context, Command command);
1486     angle::Result syncDrawFramebuffer(const Context *context, Command command);
1487     angle::Result syncVertexArray(const Context *context, Command command);
1488     angle::Result syncTextures(const Context *context, Command command);
1489     angle::Result syncImages(const Context *context, Command command);
1490     angle::Result syncSamplers(const Context *context, Command command);
1491     angle::Result syncProgramPipelineObject(const Context *context, Command command);
1492 
1493     using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
1494     using DirtyObjectHandlerArray = std::array<DirtyObjectHandler, state::DIRTY_OBJECT_MAX>;
1495 
MakeDirtyObjectHandlers()1496     static constexpr DirtyObjectHandlerArray MakeDirtyObjectHandlers()
1497     {
1498         // Work around C++'s lack of array element support in designated initializers
1499         // This function cannot be a lambda due to MSVC C++17 limitations b/330910097#comment5
1500         DirtyObjectHandlerArray handlers{};
1501 
1502         handlers[state::DIRTY_OBJECT_ACTIVE_TEXTURES]         = &State::syncActiveTextures;
1503         handlers[state::DIRTY_OBJECT_TEXTURES_INIT]           = &State::syncTexturesInit;
1504         handlers[state::DIRTY_OBJECT_IMAGES_INIT]             = &State::syncImagesInit;
1505         handlers[state::DIRTY_OBJECT_READ_ATTACHMENTS]        = &State::syncReadAttachments;
1506         handlers[state::DIRTY_OBJECT_DRAW_ATTACHMENTS]        = &State::syncDrawAttachments;
1507         handlers[state::DIRTY_OBJECT_READ_FRAMEBUFFER]        = &State::syncReadFramebuffer;
1508         handlers[state::DIRTY_OBJECT_DRAW_FRAMEBUFFER]        = &State::syncDrawFramebuffer;
1509         handlers[state::DIRTY_OBJECT_VERTEX_ARRAY]            = &State::syncVertexArray;
1510         handlers[state::DIRTY_OBJECT_TEXTURES]                = &State::syncTextures;
1511         handlers[state::DIRTY_OBJECT_IMAGES]                  = &State::syncImages;
1512         handlers[state::DIRTY_OBJECT_SAMPLERS]                = &State::syncSamplers;
1513         handlers[state::DIRTY_OBJECT_PROGRAM_PIPELINE_OBJECT] = &State::syncProgramPipelineObject;
1514 
1515         // If a handler is missing, reset everything for ease of static_assert
1516         for (auto handler : handlers)
1517         {
1518             if (handler == nullptr)
1519             {
1520                 return DirtyObjectHandlerArray();
1521             }
1522         }
1523 
1524         return handlers;
1525     }
1526 
dirtyObjectHandler(size_t dirtyObject,const Context * context,Command command)1527     angle::Result dirtyObjectHandler(size_t dirtyObject, const Context *context, Command command)
1528     {
1529         static constexpr DirtyObjectHandlerArray handlers = MakeDirtyObjectHandlers();
1530         static_assert(handlers[0] != nullptr, "MakeDirtyObjectHandlers missing a handler");
1531 
1532         return (this->*handlers[dirtyObject])(context, command);
1533     }
1534 
1535     // Robust init must happen before Framebuffer init for the Vulkan back-end.
1536     static_assert(state::DIRTY_OBJECT_ACTIVE_TEXTURES < state::DIRTY_OBJECT_TEXTURES_INIT,
1537                   "init order");
1538     static_assert(state::DIRTY_OBJECT_TEXTURES_INIT < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
1539                   "init order");
1540     static_assert(state::DIRTY_OBJECT_IMAGES_INIT < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
1541                   "init order");
1542     static_assert(state::DIRTY_OBJECT_DRAW_ATTACHMENTS < state::DIRTY_OBJECT_DRAW_FRAMEBUFFER,
1543                   "init order");
1544     static_assert(state::DIRTY_OBJECT_READ_ATTACHMENTS < state::DIRTY_OBJECT_READ_FRAMEBUFFER,
1545                   "init order");
1546 
1547     // Dispatch table for buffer update functions.
1548     static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
1549 
1550     ContextID mID;
1551 
1552     EGLenum mContextPriority;
1553     bool mHasRobustAccess;
1554     bool mHasProtectedContent;
1555     bool mIsDebugContext;
1556 
1557     egl::ShareGroup *mShareGroup;
1558     mutable egl::ContextMutex mContextMutex;
1559 
1560     // Resource managers.
1561     BufferManager *mBufferManager;
1562     ShaderProgramManager *mShaderProgramManager;
1563     TextureManager *mTextureManager;
1564     RenderbufferManager *mRenderbufferManager;
1565     SamplerManager *mSamplerManager;
1566     SyncManager *mSyncManager;
1567     FramebufferManager *mFramebufferManager;
1568     ProgramPipelineManager *mProgramPipelineManager;
1569     MemoryObjectManager *mMemoryObjectManager;
1570     SemaphoreManager *mSemaphoreManager;
1571 
1572     Framebuffer *mReadFramebuffer;
1573     Framebuffer *mDrawFramebuffer;
1574     BindingPointer<Renderbuffer> mRenderbuffer;
1575     Program *mProgram;
1576     BindingPointer<ProgramPipeline> mProgramPipeline;
1577     // The _installed_ executable.  Note that this may be different from the program's (or the
1578     // program pipeline's) executable, as they may have been unsuccessfully relinked.
1579     SharedProgramExecutable mExecutable;
1580 
1581     VertexArray *mVertexArray;
1582 
1583     TextureBindingMap mSamplerTextures;
1584 
1585     // Active Textures Cache
1586     // ---------------------
1587     // The active textures cache gives ANGLE components access to a complete array of textures
1588     // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1589     // changes via the onSubjectStateChange method above. We update the cache before draws.
1590     // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1591     //
1592     // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1593     // and flag dirty bits. nullptr indicates unbound or incomplete.
1594     ActiveTexturesCache mActiveTexturesCache;
1595     std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1596 
1597     ActiveTextureMask mTexturesIncompatibleWithSamplers;
1598 
1599     SamplerBindingVector mSamplers;
1600 
1601     // It would be nice to merge the image and observer binding. Same for textures.
1602     std::vector<ImageUnit> mImageUnits;
1603 
1604     ActiveQueryMap mActiveQueries;
1605 
1606     // Stores the currently bound buffer for each binding point. It has an entry for the element
1607     // array buffer but it should not be used. Instead this bind point is owned by the current
1608     // vertex array object.
1609     BoundBufferMap mBoundBuffers;
1610 
1611     BufferVector mUniformBuffers;
1612     BufferVector mAtomicCounterBuffers;
1613     BufferVector mShaderStorageBuffers;
1614 
1615     angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1616     angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1617         mBoundAtomicCounterBuffersMask;
1618     angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1619         mBoundShaderStorageBuffersMask;
1620 
1621     BindingPointer<TransformFeedback> mTransformFeedback;
1622 
1623     bool mDisplayTextureShareGroup;
1624 
1625     // GL_KHR_parallel_shader_compile
1626     GLuint mMaxShaderCompilerThreads;
1627 
1628     // The Overlay object, used by the backend to render the overlay.
1629     const OverlayType *mOverlay;
1630 
1631     state::DirtyBits mDirtyBits;
1632     state::ExtendedDirtyBits mExtendedDirtyBits;
1633     state::DirtyObjects mDirtyObjects;
1634     ActiveTextureMask mDirtyActiveTextures;
1635     ActiveTextureMask mDirtyTextures;
1636     ActiveTextureMask mDirtySamplers;
1637     ImageUnitMask mDirtyImages;
1638     // Tracks uniform blocks that need reprocessing, for example because their mapped bindings have
1639     // changed, or buffers in their mapped bindings have changed.  This is in State because every
1640     // context needs to react to such changes.
1641     mutable ProgramUniformBlockMask mDirtyUniformBlocks;
1642 
1643     PrivateState mPrivateState;
1644 };
1645 
syncDirtyObjects(const Context * context,const state::DirtyObjects & bitset,Command command)1646 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1647                                                    const state::DirtyObjects &bitset,
1648                                                    Command command)
1649 {
1650     // Accumulate any dirty objects that might have been set due to context-private state changes.
1651     mDirtyObjects |= mPrivateState.getDirtyObjects();
1652     mPrivateState.clearDirtyObjects();
1653 
1654     const state::DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1655 
1656     for (size_t dirtyObject : dirtyObjects)
1657     {
1658         ANGLE_TRY(dirtyObjectHandler(dirtyObject, context, command));
1659     }
1660 
1661     mDirtyObjects &= ~dirtyObjects;
1662     return angle::Result::Continue;
1663 }
1664 
1665 }  // namespace gl
1666 
1667 #endif  // LIBANGLE_STATE_H_
1668