1 //
2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // State.h: Defines the State class, encapsulating raw GL state
8
9 #ifndef LIBANGLE_STATE_H_
10 #define LIBANGLE_STATE_H_
11
12 #include <bitset>
13 #include <memory>
14
15 #include "common/Color.h"
16 #include "common/angleutils.h"
17 #include "common/bitset_utils.h"
18 #include "libANGLE/Debug.h"
19 #include "libANGLE/GLES1State.h"
20 #include "libANGLE/Overlay.h"
21 #include "libANGLE/Program.h"
22 #include "libANGLE/ProgramExecutable.h"
23 #include "libANGLE/ProgramPipeline.h"
24 #include "libANGLE/RefCountObject.h"
25 #include "libANGLE/Renderbuffer.h"
26 #include "libANGLE/Sampler.h"
27 #include "libANGLE/Texture.h"
28 #include "libANGLE/TransformFeedback.h"
29 #include "libANGLE/Version.h"
30 #include "libANGLE/VertexArray.h"
31 #include "libANGLE/angletypes.h"
32
33 namespace egl
34 {
35 class ShareGroup;
36 } // namespace egl
37
38 namespace gl
39 {
40 class BufferManager;
41 struct Caps;
42 class Context;
43 class FramebufferManager;
44 class MemoryObjectManager;
45 class ProgramPipelineManager;
46 class Query;
47 class RenderbufferManager;
48 class SamplerManager;
49 class SemaphoreManager;
50 class ShaderProgramManager;
51 class SyncManager;
52 class TextureManager;
53 class VertexArray;
54
55 static constexpr Version ES_1_0 = Version(1, 0);
56 static constexpr Version ES_1_1 = Version(1, 1);
57 static constexpr Version ES_2_0 = Version(2, 0);
58 static constexpr Version ES_3_0 = Version(3, 0);
59 static constexpr Version ES_3_1 = Version(3, 1);
60 static constexpr Version ES_3_2 = Version(3, 2);
61
62 template <typename T>
63 using BufferBindingMap = angle::PackedEnumMap<BufferBinding, T>;
64 using BoundBufferMap = BufferBindingMap<BindingPointer<Buffer>>;
65 using SamplerBindingVector = std::vector<BindingPointer<Sampler>>;
66 using TextureBindingVector = std::vector<BindingPointer<Texture>>;
67 using TextureBindingMap = angle::PackedEnumMap<TextureType, TextureBindingVector>;
68 using ActiveQueryMap = angle::PackedEnumMap<QueryType, BindingPointer<Query>>;
69 using BufferVector = std::vector<OffsetBindingPointer<Buffer>>;
70
71 class ActiveTexturesCache final : angle::NonCopyable
72 {
73 public:
74 ActiveTexturesCache();
75 ~ActiveTexturesCache();
76
77 Texture *operator[](size_t textureIndex) const { return mTextures[textureIndex]; }
78
79 void clear();
80 void set(size_t textureIndex, Texture *texture);
81 void reset(size_t textureIndex);
82 bool empty() const;
83
84 private:
85 ActiveTextureArray<Texture *> mTextures;
86 };
87
88 class State : angle::NonCopyable
89 {
90 public:
91 State(const State *shareContextState,
92 egl::ShareGroup *shareGroup,
93 TextureManager *shareTextures,
94 SemaphoreManager *shareSemaphores,
95 const OverlayType *overlay,
96 const EGLenum clientType,
97 const Version &clientVersion,
98 bool debug,
99 bool bindGeneratesResource,
100 bool clientArraysEnabled,
101 bool robustResourceInit,
102 bool programBinaryCacheEnabled,
103 EGLenum contextPriority,
104 bool hasProtectedContent);
105 ~State();
106
107 void initialize(Context *context);
108 void reset(const Context *context);
109
110 // Getters
getContextID()111 ContextID getContextID() const { return mID; }
getClientType()112 EGLenum getClientType() const { return mClientType; }
getContextPriority()113 EGLenum getContextPriority() const { return mContextPriority; }
hasProtectedContent()114 bool hasProtectedContent() const { return mHasProtectedContent; }
getClientMajorVersion()115 GLint getClientMajorVersion() const { return mClientVersion.major; }
getClientMinorVersion()116 GLint getClientMinorVersion() const { return mClientVersion.minor; }
getClientVersion()117 const Version &getClientVersion() const { return mClientVersion; }
getCaps()118 const Caps &getCaps() const { return mCaps; }
getTextureCaps()119 const TextureCapsMap &getTextureCaps() const { return mTextureCaps; }
getExtensions()120 const Extensions &getExtensions() const { return mExtensions; }
getLimitations()121 const Limitations &getLimitations() const { return mLimitations; }
getShareGroup()122 egl::ShareGroup *getShareGroup() const { return mShareGroup; }
123
isWebGL()124 bool isWebGL() const { return mExtensions.webglCompatibility; }
125
isWebGL1()126 bool isWebGL1() const { return (isWebGL() && mClientVersion.major == 2); }
127
getTextureCap(GLenum internalFormat)128 const TextureCaps &getTextureCap(GLenum internalFormat) const
129 {
130 return mTextureCaps.get(internalFormat);
131 }
132
133 // State chunk getters
134 bool allActiveDrawBufferChannelsMasked() const;
135 bool anyActiveDrawBufferChannelMasked() const;
136 const RasterizerState &getRasterizerState() const;
getBlendState()137 const BlendState &getBlendState() const { return mBlendState; }
getBlendStateExt()138 const BlendStateExt &getBlendStateExt() const { return mBlendStateExt; }
139 const DepthStencilState &getDepthStencilState() const;
140
141 // Clear behavior setters & state parameter block generation function
142 void setColorClearValue(float red, float green, float blue, float alpha);
143 void setDepthClearValue(float depth);
144 void setStencilClearValue(int stencil);
145
getColorClearValue()146 const ColorF &getColorClearValue() const { return mColorClearValue; }
getDepthClearValue()147 float getDepthClearValue() const { return mDepthClearValue; }
getStencilClearValue()148 int getStencilClearValue() const { return mStencilClearValue; }
149
150 // Write mask manipulation
151 void setColorMask(bool red, bool green, bool blue, bool alpha);
152 void setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index);
153 void setDepthMask(bool mask);
154
155 // Discard toggle & query
isRasterizerDiscardEnabled()156 bool isRasterizerDiscardEnabled() const { return mRasterizer.rasterizerDiscard; }
157 void setRasterizerDiscard(bool enabled);
158
159 // Primitive restart
isPrimitiveRestartEnabled()160 bool isPrimitiveRestartEnabled() const { return mPrimitiveRestart; }
161 void setPrimitiveRestart(bool enabled);
162
163 // Face culling state manipulation
isCullFaceEnabled()164 bool isCullFaceEnabled() const { return mRasterizer.cullFace; }
165 void setCullFace(bool enabled);
166 void setCullMode(CullFaceMode mode);
167 void setFrontFace(GLenum front);
168
169 // Depth test state manipulation
isDepthTestEnabled()170 bool isDepthTestEnabled() const { return mDepthStencil.depthTest; }
isDepthWriteEnabled()171 bool isDepthWriteEnabled() const { return mDepthStencil.depthTest && mDepthStencil.depthMask; }
172 void setDepthTest(bool enabled);
173 void setDepthFunc(GLenum depthFunc);
174 void setDepthRange(float zNear, float zFar);
getNearPlane()175 float getNearPlane() const { return mNearZ; }
getFarPlane()176 float getFarPlane() const { return mFarZ; }
177
178 // Clip control extension
179 void setClipControl(GLenum origin, GLenum depth);
isClipControlDepthZeroToOne()180 bool isClipControlDepthZeroToOne() const { return mClipControlDepth == GL_ZERO_TO_ONE_EXT; }
getClipSpaceOrigin()181 gl::ClipSpaceOrigin getClipSpaceOrigin() const
182 {
183 return mClipControlOrigin == GL_UPPER_LEFT_EXT ? ClipSpaceOrigin::UpperLeft
184 : ClipSpaceOrigin::LowerLeft;
185 }
186
187 // Blend state manipulation
isBlendEnabled()188 bool isBlendEnabled() const { return mBlendStateExt.mEnabledMask.test(0); }
isBlendEnabledIndexed(GLuint index)189 bool isBlendEnabledIndexed(GLuint index) const
190 {
191 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
192 return mBlendStateExt.mEnabledMask.test(index);
193 }
getBlendEnabledDrawBufferMask()194 DrawBufferMask getBlendEnabledDrawBufferMask() const { return mBlendStateExt.mEnabledMask; }
195 void setBlend(bool enabled);
196 void setBlendIndexed(bool enabled, GLuint index);
197 void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha);
198 void setBlendFactorsIndexed(GLenum sourceRGB,
199 GLenum destRGB,
200 GLenum sourceAlpha,
201 GLenum destAlpha,
202 GLuint index);
203 void setBlendColor(float red, float green, float blue, float alpha);
204 void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation);
205 void setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index);
getBlendColor()206 const ColorF &getBlendColor() const { return mBlendColor; }
207
208 // Stencil state maniupulation
isStencilTestEnabled()209 bool isStencilTestEnabled() const { return mDepthStencil.stencilTest; }
210 void setStencilTest(bool enabled);
211 void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask);
212 void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask);
213 void setStencilWritemask(GLuint stencilWritemask);
214 void setStencilBackWritemask(GLuint stencilBackWritemask);
215 void setStencilOperations(GLenum stencilFail,
216 GLenum stencilPassDepthFail,
217 GLenum stencilPassDepthPass);
218 void setStencilBackOperations(GLenum stencilBackFail,
219 GLenum stencilBackPassDepthFail,
220 GLenum stencilBackPassDepthPass);
getStencilRef()221 GLint getStencilRef() const { return mStencilRef; }
getStencilBackRef()222 GLint getStencilBackRef() const { return mStencilBackRef; }
223
224 // Depth bias/polygon offset state manipulation
isPolygonOffsetFillEnabled()225 bool isPolygonOffsetFillEnabled() const { return mRasterizer.polygonOffsetFill; }
226 void setPolygonOffsetFill(bool enabled);
227 void setPolygonOffsetParams(GLfloat factor, GLfloat units);
228
229 // Multisample coverage state manipulation
isSampleAlphaToCoverageEnabled()230 bool isSampleAlphaToCoverageEnabled() const { return mSampleAlphaToCoverage; }
231 void setSampleAlphaToCoverage(bool enabled);
isSampleCoverageEnabled()232 bool isSampleCoverageEnabled() const { return mSampleCoverage; }
233 void setSampleCoverage(bool enabled);
234 void setSampleCoverageParams(GLclampf value, bool invert);
getSampleCoverageValue()235 GLclampf getSampleCoverageValue() const { return mSampleCoverageValue; }
getSampleCoverageInvert()236 bool getSampleCoverageInvert() const { return mSampleCoverageInvert; }
237
238 // Multisample mask state manipulation.
isSampleMaskEnabled()239 bool isSampleMaskEnabled() const { return mSampleMask; }
240 void setSampleMaskEnabled(bool enabled);
241 void setSampleMaskParams(GLuint maskNumber, GLbitfield mask);
getSampleMaskWord(GLuint maskNumber)242 GLbitfield getSampleMaskWord(GLuint maskNumber) const
243 {
244 ASSERT(maskNumber < mMaxSampleMaskWords);
245 return mSampleMaskValues[maskNumber];
246 }
getSampleMaskValues()247 std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> getSampleMaskValues() const
248 {
249 return mSampleMaskValues;
250 }
getMaxSampleMaskWords()251 GLuint getMaxSampleMaskWords() const { return mMaxSampleMaskWords; }
252
253 // Multisampling/alpha to one manipulation.
254 void setSampleAlphaToOne(bool enabled);
isSampleAlphaToOneEnabled()255 bool isSampleAlphaToOneEnabled() const { return mSampleAlphaToOne; }
256 void setMultisampling(bool enabled);
isMultisamplingEnabled()257 bool isMultisamplingEnabled() const { return mMultiSampling; }
258
259 void setSampleShading(bool enabled);
isSampleShadingEnabled()260 bool isSampleShadingEnabled() const { return mIsSampleShadingEnabled; }
261 void setMinSampleShading(float value);
getMinSampleShading()262 float getMinSampleShading() const { return mMinSampleShading; }
263
264 // Scissor test state toggle & query
isScissorTestEnabled()265 bool isScissorTestEnabled() const { return mScissorTest; }
266 void setScissorTest(bool enabled);
267 void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height);
getScissor()268 const Rectangle &getScissor() const { return mScissor; }
269
270 // Dither state toggle & query
isDitherEnabled()271 bool isDitherEnabled() const { return mRasterizer.dither; }
272 void setDither(bool enabled);
273
274 // Generic state toggle & query
275 void setEnableFeature(GLenum feature, bool enabled);
276 void setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index);
277 bool getEnableFeature(GLenum feature) const;
278 bool getEnableFeatureIndexed(GLenum feature, GLuint index) const;
279
280 // Line width state setter
281 void setLineWidth(GLfloat width);
getLineWidth()282 float getLineWidth() const { return mLineWidth; }
283
284 // Hint setters
285 void setGenerateMipmapHint(GLenum hint);
286 GLenum getGenerateMipmapHint() const;
287 void setTextureFilteringHint(GLenum hint);
288 GLenum getTextureFilteringHint() const;
getFragmentShaderDerivativeHint()289 GLenum getFragmentShaderDerivativeHint() const { return mFragmentShaderDerivativeHint; }
290 void setFragmentShaderDerivativeHint(GLenum hint);
291
292 // GL_CHROMIUM_bind_generates_resource
isBindGeneratesResourceEnabled()293 bool isBindGeneratesResourceEnabled() const { return mBindGeneratesResource; }
294
295 // GL_ANGLE_client_arrays
areClientArraysEnabled()296 bool areClientArraysEnabled() const { return mClientArraysEnabled; }
297
298 // Viewport state setter/getter
299 void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height);
getViewport()300 const Rectangle &getViewport() const { return mViewport; }
301
302 // Texture binding & active texture unit manipulation
303 void setActiveSampler(unsigned int active);
getActiveSampler()304 unsigned int getActiveSampler() const { return static_cast<unsigned int>(mActiveSampler); }
305
306 void setSamplerTexture(const Context *context, TextureType type, Texture *texture);
307 Texture *getTargetTexture(TextureType type) const;
308
getSamplerTexture(unsigned int sampler,TextureType type)309 Texture *getSamplerTexture(unsigned int sampler, TextureType type) const
310 {
311 ASSERT(sampler < mSamplerTextures[type].size());
312 return mSamplerTextures[type][sampler].get();
313 }
314
315 TextureID getSamplerTextureId(unsigned int sampler, TextureType type) const;
316 void detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture);
317 void initializeZeroTextures(const Context *context, const TextureMap &zeroTextures);
318
319 void invalidateTextureBindings(TextureType type);
320
321 // Sampler object binding manipulation
322 void setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler);
getSamplerId(GLuint textureUnit)323 SamplerID getSamplerId(GLuint textureUnit) const
324 {
325 ASSERT(textureUnit < mSamplers.size());
326 return mSamplers[textureUnit].id();
327 }
328
getSampler(GLuint textureUnit)329 Sampler *getSampler(GLuint textureUnit) const { return mSamplers[textureUnit].get(); }
330
getSamplers()331 const SamplerBindingVector &getSamplers() const { return mSamplers; }
332
333 void detachSampler(const Context *context, SamplerID sampler);
334
335 // Renderbuffer binding manipulation
336 void setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer);
getRenderbufferId()337 RenderbufferID getRenderbufferId() const { return mRenderbuffer.id(); }
getCurrentRenderbuffer()338 Renderbuffer *getCurrentRenderbuffer() const { return mRenderbuffer.get(); }
339 void detachRenderbuffer(const Context *context, RenderbufferID renderbuffer);
340
341 // Framebuffer binding manipulation
342 void setReadFramebufferBinding(Framebuffer *framebuffer);
343 void setDrawFramebufferBinding(Framebuffer *framebuffer);
344 Framebuffer *getTargetFramebuffer(GLenum target) const;
getReadFramebuffer()345 Framebuffer *getReadFramebuffer() const { return mReadFramebuffer; }
getDrawFramebuffer()346 Framebuffer *getDrawFramebuffer() const { return mDrawFramebuffer; }
347 Framebuffer *getDefaultFramebuffer() const;
348
349 bool removeReadFramebufferBinding(FramebufferID framebuffer);
350 bool removeDrawFramebufferBinding(FramebufferID framebuffer);
351
352 // Vertex array object binding manipulation
353 void setVertexArrayBinding(const Context *context, VertexArray *vertexArray);
354 bool removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray);
355 VertexArrayID getVertexArrayId() const;
356
getVertexArray()357 VertexArray *getVertexArray() const
358 {
359 ASSERT(mVertexArray != nullptr);
360 return mVertexArray;
361 }
362
363 // If both a Program and a ProgramPipeline are bound, the Program will
364 // always override the ProgramPipeline.
getProgramExecutable()365 const ProgramExecutable *getProgramExecutable() const { return mExecutable; }
366
367 // Program binding manipulation
368 angle::Result setProgram(const Context *context, Program *newProgram);
369
getProgram()370 Program *getProgram() const
371 {
372 ASSERT(!mProgram || !mProgram->isLinking());
373 return mProgram;
374 }
375
getLinkedProgram(const Context * context)376 Program *getLinkedProgram(const Context *context) const
377 {
378 if (mProgram)
379 {
380 mProgram->resolveLink(context);
381 }
382 return mProgram;
383 }
384
getProgramPipeline()385 ProgramPipeline *getProgramPipeline() const { return mProgramPipeline.get(); }
386
387 // Transform feedback object (not buffer) binding manipulation
388 void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);
getCurrentTransformFeedback()389 TransformFeedback *getCurrentTransformFeedback() const { return mTransformFeedback.get(); }
390
isTransformFeedbackActive()391 ANGLE_INLINE bool isTransformFeedbackActive() const
392 {
393 TransformFeedback *curTransformFeedback = mTransformFeedback.get();
394 return curTransformFeedback && curTransformFeedback->isActive();
395 }
isTransformFeedbackActiveUnpaused()396 ANGLE_INLINE bool isTransformFeedbackActiveUnpaused() const
397 {
398 TransformFeedback *curTransformFeedback = mTransformFeedback.get();
399 return curTransformFeedback && curTransformFeedback->isActive() &&
400 !curTransformFeedback->isPaused();
401 }
402
403 bool removeTransformFeedbackBinding(const Context *context,
404 TransformFeedbackID transformFeedback);
405
406 // Query binding manipulation
407 bool isQueryActive(QueryType type) const;
408 bool isQueryActive(Query *query) const;
409 void setActiveQuery(const Context *context, QueryType type, Query *query);
410 QueryID getActiveQueryId(QueryType type) const;
411 Query *getActiveQuery(QueryType type) const;
412
413 // Program Pipeline binding manipulation
414 angle::Result useProgramStages(const Context *context,
415 ProgramPipeline *programPipeline,
416 GLbitfield stages,
417 Program *shaderProgram);
418 angle::Result setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
419 void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
420
421 //// Typed buffer binding point manipulation ////
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)422 ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
423 {
424 (this->*(kBufferSetters[target]))(context, buffer);
425 }
426
getTargetBuffer(BufferBinding target)427 ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
428 {
429 switch (target)
430 {
431 case BufferBinding::ElementArray:
432 return getVertexArray()->getElementArrayBuffer();
433 default:
434 return mBoundBuffers[target].get();
435 }
436 }
437
getArrayBuffer()438 ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
439
440 angle::Result setIndexedBufferBinding(const Context *context,
441 BufferBinding target,
442 GLuint index,
443 Buffer *buffer,
444 GLintptr offset,
445 GLsizeiptr size);
446
getAtomicCounterBufferCount()447 size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
448
hasValidAtomicCounterBuffer()449 ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
450 {
451 return mBoundAtomicCounterBuffersMask.any();
452 }
453
454 const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
455 const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
456 const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
457
getUniformBuffersMask()458 const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
459 const
460 {
461 return mBoundUniformBuffersMask;
462 }
463 const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
getAtomicCounterBuffersMask()464 &getAtomicCounterBuffersMask() const
465 {
466 return mBoundAtomicCounterBuffersMask;
467 }
468 const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
getShaderStorageBuffersMask()469 &getShaderStorageBuffersMask() const
470 {
471 return mBoundShaderStorageBuffersMask;
472 }
473
474 // Detach a buffer from all bindings
475 angle::Result detachBuffer(Context *context, const Buffer *buffer);
476
477 // Vertex attrib manipulation
478 void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
479 void setVertexAttribf(GLuint index, const GLfloat values[4]);
480 void setVertexAttribu(GLuint index, const GLuint values[4]);
481 void setVertexAttribi(GLuint index, const GLint values[4]);
482
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,bool normalized,GLsizei stride,const void * pointer)483 ANGLE_INLINE void setVertexAttribPointer(const Context *context,
484 unsigned int attribNum,
485 Buffer *boundBuffer,
486 GLint size,
487 VertexAttribType type,
488 bool normalized,
489 GLsizei stride,
490 const void *pointer)
491 {
492 mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
493 normalized, stride, pointer);
494 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
495 }
496
setVertexAttribIPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)497 ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
498 unsigned int attribNum,
499 Buffer *boundBuffer,
500 GLint size,
501 VertexAttribType type,
502 GLsizei stride,
503 const void *pointer)
504 {
505 mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
506 pointer);
507 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
508 }
509
510 void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
getVertexAttribCurrentValue(size_t attribNum)511 const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
512 {
513 ASSERT(attribNum < mVertexAttribCurrentValues.size());
514 return mVertexAttribCurrentValues[attribNum];
515 }
516
getVertexAttribCurrentValues()517 const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
518 {
519 return mVertexAttribCurrentValues;
520 }
521
522 const void *getVertexAttribPointer(unsigned int attribNum) const;
523
524 void bindVertexBuffer(const Context *context,
525 GLuint bindingIndex,
526 Buffer *boundBuffer,
527 GLintptr offset,
528 GLsizei stride);
529 void setVertexAttribFormat(GLuint attribIndex,
530 GLint size,
531 VertexAttribType type,
532 bool normalized,
533 bool pureInteger,
534 GLuint relativeOffset);
535
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)536 void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
537 {
538 mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
539 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
540 }
541
542 void setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor);
543
544 // Pixel pack state manipulation
545 void setPackAlignment(GLint alignment);
getPackAlignment()546 GLint getPackAlignment() const { return mPack.alignment; }
547 void setPackReverseRowOrder(bool reverseRowOrder);
getPackReverseRowOrder()548 bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
549 void setPackRowLength(GLint rowLength);
getPackRowLength()550 GLint getPackRowLength() const { return mPack.rowLength; }
551 void setPackSkipRows(GLint skipRows);
getPackSkipRows()552 GLint getPackSkipRows() const { return mPack.skipRows; }
553 void setPackSkipPixels(GLint skipPixels);
getPackSkipPixels()554 GLint getPackSkipPixels() const { return mPack.skipPixels; }
getPackState()555 const PixelPackState &getPackState() const { return mPack; }
getPackState()556 PixelPackState &getPackState() { return mPack; }
557
558 // Pixel unpack state manipulation
559 void setUnpackAlignment(GLint alignment);
getUnpackAlignment()560 GLint getUnpackAlignment() const { return mUnpack.alignment; }
561 void setUnpackRowLength(GLint rowLength);
getUnpackRowLength()562 GLint getUnpackRowLength() const { return mUnpack.rowLength; }
563 void setUnpackImageHeight(GLint imageHeight);
getUnpackImageHeight()564 GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
565 void setUnpackSkipImages(GLint skipImages);
getUnpackSkipImages()566 GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
567 void setUnpackSkipRows(GLint skipRows);
getUnpackSkipRows()568 GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
569 void setUnpackSkipPixels(GLint skipPixels);
getUnpackSkipPixels()570 GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
getUnpackState()571 const PixelUnpackState &getUnpackState() const { return mUnpack; }
getUnpackState()572 PixelUnpackState &getUnpackState() { return mUnpack; }
573
574 // Debug state
getDebug()575 const Debug &getDebug() const { return mDebug; }
getDebug()576 Debug &getDebug() { return mDebug; }
577
578 // CHROMIUM_framebuffer_mixed_samples coverage modulation
579 void setCoverageModulation(GLenum components);
getCoverageModulation()580 GLenum getCoverageModulation() const { return mCoverageModulation; }
581
582 // GL_EXT_sRGB_write_control
583 void setFramebufferSRGB(bool sRGB);
getFramebufferSRGB()584 bool getFramebufferSRGB() const { return mFramebufferSRGB; }
585
586 // GL_KHR_parallel_shader_compile
587 void setMaxShaderCompilerThreads(GLuint count);
getMaxShaderCompilerThreads()588 GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
589
590 // GL_EXT_tessellation_shader
591 void setPatchVertices(GLuint value);
getPatchVertices()592 GLuint getPatchVertices() const { return mPatchVertices; }
593
594 // State query functions
595 void getBooleanv(GLenum pname, GLboolean *params) const;
596 void getFloatv(GLenum pname, GLfloat *params) const;
597 angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
598 void getPointerv(const Context *context, GLenum pname, void **params) const;
599 void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
600 void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
601 void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
602
isRobustResourceInitEnabled()603 bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
604
605 // Sets the dirty bit for the program executable.
606 angle::Result onProgramExecutableChange(const Context *context, Program *program);
607 // Sets the dirty bit for the program pipeline executable.
608 angle::Result onProgramPipelineExecutableChange(const Context *context,
609 ProgramPipeline *program);
610
611 enum DirtyBitType
612 {
613 // Note: process draw framebuffer binding first, so that other dirty bits whose effect
614 // depend on the current draw framebuffer are not processed while the old framebuffer is
615 // still bound.
616 DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
617 DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
618 DIRTY_BIT_SCISSOR_TEST_ENABLED,
619 DIRTY_BIT_SCISSOR,
620 DIRTY_BIT_VIEWPORT,
621 DIRTY_BIT_DEPTH_RANGE,
622 DIRTY_BIT_BLEND_ENABLED,
623 DIRTY_BIT_BLEND_COLOR,
624 DIRTY_BIT_BLEND_FUNCS,
625 DIRTY_BIT_BLEND_EQUATIONS,
626 DIRTY_BIT_COLOR_MASK,
627 DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
628 DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
629 DIRTY_BIT_SAMPLE_COVERAGE,
630 DIRTY_BIT_SAMPLE_MASK_ENABLED,
631 DIRTY_BIT_SAMPLE_MASK,
632 DIRTY_BIT_DEPTH_TEST_ENABLED,
633 DIRTY_BIT_DEPTH_FUNC,
634 DIRTY_BIT_DEPTH_MASK,
635 DIRTY_BIT_STENCIL_TEST_ENABLED,
636 DIRTY_BIT_STENCIL_FUNCS_FRONT,
637 DIRTY_BIT_STENCIL_FUNCS_BACK,
638 DIRTY_BIT_STENCIL_OPS_FRONT,
639 DIRTY_BIT_STENCIL_OPS_BACK,
640 DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
641 DIRTY_BIT_STENCIL_WRITEMASK_BACK,
642 DIRTY_BIT_CULL_FACE_ENABLED,
643 DIRTY_BIT_CULL_FACE,
644 DIRTY_BIT_FRONT_FACE,
645 DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
646 DIRTY_BIT_POLYGON_OFFSET,
647 DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
648 DIRTY_BIT_LINE_WIDTH,
649 DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
650 DIRTY_BIT_CLEAR_COLOR,
651 DIRTY_BIT_CLEAR_DEPTH,
652 DIRTY_BIT_CLEAR_STENCIL,
653 DIRTY_BIT_UNPACK_STATE,
654 DIRTY_BIT_UNPACK_BUFFER_BINDING,
655 DIRTY_BIT_PACK_STATE,
656 DIRTY_BIT_PACK_BUFFER_BINDING,
657 DIRTY_BIT_DITHER_ENABLED,
658 DIRTY_BIT_RENDERBUFFER_BINDING,
659 DIRTY_BIT_VERTEX_ARRAY_BINDING,
660 DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
661 DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
662 // TODO(jmadill): Fine-grained dirty bits for each index.
663 DIRTY_BIT_PROGRAM_BINDING, // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
664 DIRTY_BIT_PROGRAM_EXECUTABLE,
665 // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
666 DIRTY_BIT_SAMPLER_BINDINGS,
667 DIRTY_BIT_TEXTURE_BINDINGS,
668 DIRTY_BIT_IMAGE_BINDINGS,
669 DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
670 DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
671 DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
672 DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
673 DIRTY_BIT_MULTISAMPLING,
674 DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
675 DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples
676 DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE, // GL_EXT_sRGB_write_control
677 DIRTY_BIT_CURRENT_VALUES,
678 DIRTY_BIT_PROVOKING_VERTEX,
679 DIRTY_BIT_SAMPLE_SHADING,
680 DIRTY_BIT_PATCH_VERTICES,
681 DIRTY_BIT_EXTENDED, // clip distances, mipmap generation hint, derivative hint,
682 // EXT_clip_control
683 DIRTY_BIT_INVALID,
684 DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
685 };
686
687 static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
688
689 enum ExtendedDirtyBitType
690 {
691 EXTENDED_DIRTY_BIT_CLIP_CONTROL, // EXT_clip_control
692 EXTENDED_DIRTY_BIT_CLIP_DISTANCES, // clip distances
693 EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT, // mipmap generation hint
694 EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT, // shader derivative hint
695 EXTENDED_DIRTY_BIT_INVALID,
696 EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
697 };
698
699 static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
700
701 // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
702 enum DirtyObjectType
703 {
704 DIRTY_OBJECT_ACTIVE_TEXTURES, // Top-level dirty bit. Also see mDirtyActiveTextures.
705 DIRTY_OBJECT_TEXTURES_INIT,
706 DIRTY_OBJECT_IMAGES_INIT,
707 DIRTY_OBJECT_READ_ATTACHMENTS,
708 DIRTY_OBJECT_DRAW_ATTACHMENTS,
709 DIRTY_OBJECT_VERTEX_ARRAY,
710 DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures.
711 DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages.
712 DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers.
713 DIRTY_OBJECT_READ_FRAMEBUFFER,
714 DIRTY_OBJECT_DRAW_FRAMEBUFFER,
715 DIRTY_OBJECT_PROGRAM,
716 DIRTY_OBJECT_UNKNOWN,
717 DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
718 };
719
720 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
getDirtyBits()721 const DirtyBits &getDirtyBits() const { return mDirtyBits; }
clearDirtyBits()722 void clearDirtyBits() { mDirtyBits.reset(); }
clearDirtyBits(const DirtyBits & bitset)723 void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
setAllDirtyBits()724 void setAllDirtyBits()
725 {
726 mDirtyBits.set();
727 mDirtyCurrentValues.set();
728 }
729
730 using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
getExtendedDirtyBits()731 const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
732 // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
733 ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
clearExtendedDirtyBits()734 void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
735
736 using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
clearDirtyObjects()737 void clearDirtyObjects() { mDirtyObjects.reset(); }
setAllDirtyObjects()738 void setAllDirtyObjects() { mDirtyObjects.set(); }
739 angle::Result syncDirtyObjects(const Context *context,
740 const DirtyObjects &bitset,
741 Command command);
742 angle::Result syncDirtyObject(const Context *context, GLenum target);
743 void setObjectDirty(GLenum target);
744 void setTextureDirty(size_t textureUnitIndex);
745 void setSamplerDirty(size_t samplerIndex);
746
setReadFramebufferDirty()747 ANGLE_INLINE void setReadFramebufferDirty()
748 {
749 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
750 mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
751 }
752
setDrawFramebufferDirty()753 ANGLE_INLINE void setDrawFramebufferDirty()
754 {
755 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
756 mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
757 }
758
759 // This actually clears the current value dirty bits.
760 // TODO(jmadill): Pass mutable dirty bits into Impl.
761 AttributesMask getAndResetDirtyCurrentValues() const;
762
763 void setImageUnit(const Context *context,
764 size_t unit,
765 Texture *texture,
766 GLint level,
767 GLboolean layered,
768 GLint layer,
769 GLenum access,
770 GLenum format);
771
getImageUnit(size_t unit)772 const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
getActiveTexturesCache()773 const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
getCurrentValuesTypeMask()774 ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
775
776 // "onActiveTextureChange" is called when a texture binding changes.
777 void onActiveTextureChange(const Context *context, size_t textureUnit);
778
779 // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
780 void onActiveTextureStateChange(const Context *context, size_t textureUnit);
781
782 void onImageStateChange(const Context *context, size_t unit);
783
784 void onUniformBufferStateChange(size_t uniformBufferIndex);
785
isCurrentTransformFeedback(const TransformFeedback * tf)786 bool isCurrentTransformFeedback(const TransformFeedback *tf) const
787 {
788 return tf == mTransformFeedback.get();
789 }
isCurrentVertexArray(const VertexArray * va)790 bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
791
gles1()792 GLES1State &gles1() { return mGLES1State; }
gles1()793 const GLES1State &gles1() const { return mGLES1State; }
794
795 // Helpers for setting bound buffers. They should all have the same signature.
796 // Not meant to be called externally. Used for local helpers in State.cpp.
797 template <BufferBinding Target>
798 void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
799
800 template <BufferBinding Target>
801 void setGenericBufferBinding(const Context *context, Buffer *buffer);
802
803 using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
804
validateSamplerFormats()805 ANGLE_INLINE bool validateSamplerFormats() const
806 {
807 return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
808 mExecutable->getActiveSamplersMask())));
809 }
810
getProvokingVertex()811 ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)812 void setProvokingVertex(ProvokingVertexConvention val)
813 {
814 mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
815 mProvokingVertex = val;
816 }
817
setReadFramebufferBindingDirty()818 ANGLE_INLINE void setReadFramebufferBindingDirty()
819 {
820 mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
821 }
822
setDrawFramebufferBindingDirty()823 ANGLE_INLINE void setDrawFramebufferBindingDirty()
824 {
825 mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
826 }
827
828 using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
getEnabledClipDistances()829 const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
830 void setClipDistanceEnable(int idx, bool enable);
831
getOverlay()832 const OverlayType *getOverlay() const { return mOverlay; }
833
834 // Not for general use.
getBufferManagerForCapture()835 const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()836 const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()837 const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()838 const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()839 const RenderbufferManager &getRenderbufferManagerForCapture() const
840 {
841 return *mRenderbufferManager;
842 }
getFramebufferManagerForCapture()843 const FramebufferManager &getFramebufferManagerForCapture() const
844 {
845 return *mFramebufferManager;
846 }
getShaderProgramManagerForCapture()847 const ShaderProgramManager &getShaderProgramManagerForCapture() const
848 {
849 return *mShaderProgramManager;
850 }
getSyncManagerForCapture()851 const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()852 const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getSamplerBindingsForCapture()853 const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
854
getActiveQueriesForCapture()855 const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
856
hasConstantAlphaBlendFunc()857 bool hasConstantAlphaBlendFunc() const
858 {
859 return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.mEnabledMask).any();
860 }
861
hasSimultaneousConstantColorAndAlphaBlendFunc()862 bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
863 {
864 return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.mEnabledMask).any() &&
865 hasConstantAlphaBlendFunc();
866 }
867
noSimultaneousConstantColorAndAlphaBlendFunc()868 bool noSimultaneousConstantColorAndAlphaBlendFunc() const
869 {
870 return mNoSimultaneousConstantColorAndAlphaBlendFunc;
871 }
872
canEnableEarlyFragmentTestsOptimization()873 bool canEnableEarlyFragmentTestsOptimization() const
874 {
875 return !isSampleAlphaToCoverageEnabled();
876 }
877
getOffsetBindingPointerUniformBuffers()878 const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
879
getOffsetBindingPointerAtomicCounterBuffers()880 const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
881 {
882 return mAtomicCounterBuffers;
883 }
884
getOffsetBindingPointerShaderStorageBuffers()885 const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
886 {
887 return mShaderStorageBuffers;
888 }
889
getTexturesIncompatibleWithSamplers()890 ActiveTextureMask getTexturesIncompatibleWithSamplers() const
891 {
892 return mTexturesIncompatibleWithSamplers;
893 }
894
isProgramBinaryCacheEnabled()895 bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
896
isTextureRectangleEnabled()897 bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
898
getBlendFuncConstantAlphaDrawBuffers()899 DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
900 {
901 return mBlendFuncConstantAlphaDrawBuffers;
902 }
903
getBlendFuncConstantColorDrawBuffers()904 DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
905 {
906 return mBlendFuncConstantColorDrawBuffers;
907 }
908
getImageUnits()909 const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
910
getProgramPipelineManagerForCapture()911 const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
912 {
913 return mProgramPipelineManager;
914 }
915
916 private:
917 friend class Context;
918
919 void unsetActiveTextures(const ActiveTextureMask &textureMask);
920 void setActiveTextureDirty(size_t textureIndex, Texture *texture);
921 void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
922 void updateActiveTextureStateOnSync(const Context *context,
923 size_t textureIndex,
924 const Sampler *sampler,
925 Texture *texture);
926 Texture *getTextureForActiveSampler(TextureType type, size_t index);
927
928 bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
929 bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
930
931 // Functions to synchronize dirty states
932 angle::Result syncActiveTextures(const Context *context, Command command);
933 angle::Result syncTexturesInit(const Context *context, Command command);
934 angle::Result syncImagesInit(const Context *context, Command command);
935 angle::Result syncReadAttachments(const Context *context, Command command);
936 angle::Result syncDrawAttachments(const Context *context, Command command);
937 angle::Result syncReadFramebuffer(const Context *context, Command command);
938 angle::Result syncDrawFramebuffer(const Context *context, Command command);
939 angle::Result syncVertexArray(const Context *context, Command command);
940 angle::Result syncTextures(const Context *context, Command command);
941 angle::Result syncImages(const Context *context, Command command);
942 angle::Result syncSamplers(const Context *context, Command command);
943 angle::Result syncProgram(const Context *context, Command command);
944
945 using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
946 static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
947 &State::syncActiveTextures, &State::syncTexturesInit, &State::syncImagesInit,
948 &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncVertexArray,
949 &State::syncTextures, &State::syncImages, &State::syncSamplers,
950 &State::syncReadFramebuffer, &State::syncDrawFramebuffer, &State::syncProgram};
951
952 // Robust init must happen before Framebuffer init for the Vulkan back-end.
953 static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
954 static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
955 static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
956 static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
957 static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
958
959 static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
960 static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
961 static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
962 static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
963 static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
964 static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 5, "check DIRTY_OBJECT_VERTEX_ARRAY index");
965 static_assert(DIRTY_OBJECT_TEXTURES == 6, "check DIRTY_OBJECT_TEXTURES index");
966 static_assert(DIRTY_OBJECT_IMAGES == 7, "check DIRTY_OBJECT_IMAGES index");
967 static_assert(DIRTY_OBJECT_SAMPLERS == 8, "check DIRTY_OBJECT_SAMPLERS index");
968 static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 9, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
969 static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 10, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
970 static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
971
972 // Container (FBO) object must handled after the texture so that if texture code adds dirty bit
973 // to container object, they will be picked up in the same draw call.
974 static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_READ_FRAMEBUFFER,
975 "State::syncDirtyObjects order");
976 static_assert(DIRTY_OBJECT_TEXTURES < DIRTY_OBJECT_DRAW_FRAMEBUFFER,
977 "State::syncDirtyObjects order");
978
979 // Dispatch table for buffer update functions.
980 static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
981
982 ContextID mID;
983
984 EGLenum mClientType;
985 EGLenum mContextPriority;
986 bool mHasProtectedContent;
987 Version mClientVersion;
988
989 // Caps to use for validation
990 Caps mCaps;
991 TextureCapsMap mTextureCaps;
992 Extensions mExtensions;
993 Limitations mLimitations;
994
995 egl::ShareGroup *mShareGroup;
996
997 // Resource managers.
998 BufferManager *mBufferManager;
999 ShaderProgramManager *mShaderProgramManager;
1000 TextureManager *mTextureManager;
1001 RenderbufferManager *mRenderbufferManager;
1002 SamplerManager *mSamplerManager;
1003 SyncManager *mSyncManager;
1004 FramebufferManager *mFramebufferManager;
1005 ProgramPipelineManager *mProgramPipelineManager;
1006 MemoryObjectManager *mMemoryObjectManager;
1007 SemaphoreManager *mSemaphoreManager;
1008
1009 // Cached values from Context's caps
1010 GLuint mMaxDrawBuffers;
1011 GLuint mMaxCombinedTextureImageUnits;
1012
1013 ColorF mColorClearValue;
1014 GLfloat mDepthClearValue;
1015 int mStencilClearValue;
1016
1017 RasterizerState mRasterizer;
1018 bool mScissorTest;
1019 Rectangle mScissor;
1020
1021 BlendState mBlendState; // Buffer zero blend state legacy struct
1022 BlendStateExt mBlendStateExt;
1023 ColorF mBlendColor;
1024 bool mSampleAlphaToCoverage;
1025 bool mSampleCoverage;
1026 GLfloat mSampleCoverageValue;
1027 bool mSampleCoverageInvert;
1028 bool mSampleMask;
1029 GLuint mMaxSampleMaskWords;
1030 std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
1031 bool mIsSampleShadingEnabled;
1032 float mMinSampleShading;
1033
1034 DepthStencilState mDepthStencil;
1035 GLint mStencilRef;
1036 GLint mStencilBackRef;
1037
1038 GLfloat mLineWidth;
1039
1040 GLenum mGenerateMipmapHint;
1041 GLenum mTextureFilteringHint;
1042 GLenum mFragmentShaderDerivativeHint;
1043
1044 const bool mBindGeneratesResource;
1045 const bool mClientArraysEnabled;
1046
1047 Rectangle mViewport;
1048 float mNearZ;
1049 float mFarZ;
1050
1051 GLenum mClipControlOrigin;
1052 GLenum mClipControlDepth;
1053
1054 Framebuffer *mReadFramebuffer;
1055 Framebuffer *mDrawFramebuffer;
1056 BindingPointer<Renderbuffer> mRenderbuffer;
1057 Program *mProgram;
1058 BindingPointer<ProgramPipeline> mProgramPipeline;
1059 ProgramExecutable *mExecutable;
1060
1061 // GL_ANGLE_provoking_vertex
1062 ProvokingVertexConvention mProvokingVertex;
1063
1064 using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
1065 VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
1066 VertexArray *mVertexArray;
1067 ComponentTypeMask mCurrentValuesTypeMask;
1068
1069 // Texture and sampler bindings
1070 size_t mActiveSampler; // Active texture unit selector - GL_TEXTURE0
1071
1072 TextureBindingMap mSamplerTextures;
1073
1074 // Active Textures Cache
1075 // ---------------------
1076 // The active textures cache gives ANGLE components access to a complete array of textures
1077 // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1078 // changes via the onSubjectStateChange method above. We update the cache before draws.
1079 // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1080 //
1081 // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1082 // and flag dirty bits. nullptr indicates unbound or incomplete.
1083 ActiveTexturesCache mActiveTexturesCache;
1084 std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1085
1086 ActiveTextureMask mTexturesIncompatibleWithSamplers;
1087
1088 SamplerBindingVector mSamplers;
1089
1090 // It would be nice to merge the image and observer binding. Same for textures.
1091 std::vector<ImageUnit> mImageUnits;
1092
1093 ActiveQueryMap mActiveQueries;
1094
1095 // Stores the currently bound buffer for each binding point. It has an entry for the element
1096 // array buffer but it should not be used. Instead this bind point is owned by the current
1097 // vertex array object.
1098 BoundBufferMap mBoundBuffers;
1099
1100 BufferVector mUniformBuffers;
1101 BufferVector mAtomicCounterBuffers;
1102 BufferVector mShaderStorageBuffers;
1103
1104 angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1105 angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1106 mBoundAtomicCounterBuffersMask;
1107 angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1108 mBoundShaderStorageBuffersMask;
1109
1110 BindingPointer<TransformFeedback> mTransformFeedback;
1111
1112 PixelUnpackState mUnpack;
1113 PixelPackState mPack;
1114
1115 bool mPrimitiveRestart;
1116
1117 Debug mDebug;
1118
1119 bool mMultiSampling;
1120 bool mSampleAlphaToOne;
1121
1122 GLenum mCoverageModulation;
1123
1124 // GL_EXT_sRGB_write_control
1125 bool mFramebufferSRGB;
1126
1127 // GL_ANGLE_robust_resource_initialization
1128 const bool mRobustResourceInit;
1129
1130 // GL_ANGLE_program_cache_control
1131 const bool mProgramBinaryCacheEnabled;
1132
1133 // GL_ANGLE_webgl_compatibility
1134 bool mTextureRectangleEnabled;
1135
1136 // GL_KHR_parallel_shader_compile
1137 GLuint mMaxShaderCompilerThreads;
1138
1139 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1140 ClipDistanceEnableBits mClipDistancesEnabled;
1141
1142 // GL_EXT_tessellation_shader
1143 GLuint mPatchVertices;
1144
1145 // GLES1 emulation: state specific to GLES1
1146 GLES1State mGLES1State;
1147
1148 DirtyBits mDirtyBits;
1149 mutable ExtendedDirtyBits mExtendedDirtyBits;
1150 DirtyObjects mDirtyObjects;
1151 mutable AttributesMask mDirtyCurrentValues;
1152 ActiveTextureMask mDirtyActiveTextures;
1153 ActiveTextureMask mDirtyTextures;
1154 ActiveTextureMask mDirtySamplers;
1155 ImageUnitMask mDirtyImages;
1156
1157 // The Overlay object, used by the backend to render the overlay.
1158 const OverlayType *mOverlay;
1159
1160 // OES_draw_buffers_indexed
1161 DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
1162 DrawBufferMask mBlendFuncConstantColorDrawBuffers;
1163 bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
1164 };
1165
syncDirtyObjects(const Context * context,const DirtyObjects & bitset,Command command)1166 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1167 const DirtyObjects &bitset,
1168 Command command)
1169 {
1170 const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1171
1172 for (size_t dirtyObject : dirtyObjects)
1173 {
1174 ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
1175 }
1176
1177 mDirtyObjects &= ~dirtyObjects;
1178 return angle::Result::Continue;
1179 }
1180
1181 } // namespace gl
1182
1183 #endif // LIBANGLE_STATE_H_
1184