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