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