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