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