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