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