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 bindGeneratesResourceCHROMIUM,
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.webglCompatibilityANGLE; }
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 setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline);
415 void detachProgramPipeline(const Context *context, ProgramPipelineID pipeline);
416
417 //// Typed buffer binding point manipulation ////
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)418 ANGLE_INLINE void setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
419 {
420 (this->*(kBufferSetters[target]))(context, buffer);
421 }
422
getTargetBuffer(BufferBinding target)423 ANGLE_INLINE Buffer *getTargetBuffer(BufferBinding target) const
424 {
425 switch (target)
426 {
427 case BufferBinding::ElementArray:
428 return getVertexArray()->getElementArrayBuffer();
429 default:
430 return mBoundBuffers[target].get();
431 }
432 }
433
getArrayBuffer()434 ANGLE_INLINE Buffer *getArrayBuffer() const { return getTargetBuffer(BufferBinding::Array); }
435
436 angle::Result setIndexedBufferBinding(const Context *context,
437 BufferBinding target,
438 GLuint index,
439 Buffer *buffer,
440 GLintptr offset,
441 GLsizeiptr size);
442
getAtomicCounterBufferCount()443 size_t getAtomicCounterBufferCount() const { return mAtomicCounterBuffers.size(); }
444
hasValidAtomicCounterBuffer()445 ANGLE_INLINE bool hasValidAtomicCounterBuffer() const
446 {
447 return mBoundAtomicCounterBuffersMask.any();
448 }
449
450 const OffsetBindingPointer<Buffer> &getIndexedUniformBuffer(size_t index) const;
451 const OffsetBindingPointer<Buffer> &getIndexedAtomicCounterBuffer(size_t index) const;
452 const OffsetBindingPointer<Buffer> &getIndexedShaderStorageBuffer(size_t index) const;
453
getUniformBuffersMask()454 const angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> &getUniformBuffersMask()
455 const
456 {
457 return mBoundUniformBuffersMask;
458 }
459 const angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
getAtomicCounterBuffersMask()460 &getAtomicCounterBuffersMask() const
461 {
462 return mBoundAtomicCounterBuffersMask;
463 }
464 const angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
getShaderStorageBuffersMask()465 &getShaderStorageBuffersMask() const
466 {
467 return mBoundShaderStorageBuffersMask;
468 }
469
470 // Detach a buffer from all bindings
471 angle::Result detachBuffer(Context *context, const Buffer *buffer);
472
473 // Vertex attrib manipulation
474 void setEnableVertexAttribArray(unsigned int attribNum, bool enabled);
475 void setVertexAttribf(GLuint index, const GLfloat values[4]);
476 void setVertexAttribu(GLuint index, const GLuint values[4]);
477 void setVertexAttribi(GLuint index, const GLint values[4]);
478
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,bool normalized,GLsizei stride,const void * pointer)479 ANGLE_INLINE void setVertexAttribPointer(const Context *context,
480 unsigned int attribNum,
481 Buffer *boundBuffer,
482 GLint size,
483 VertexAttribType type,
484 bool normalized,
485 GLsizei stride,
486 const void *pointer)
487 {
488 mVertexArray->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
489 normalized, stride, pointer);
490 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
491 }
492
setVertexAttribIPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)493 ANGLE_INLINE void setVertexAttribIPointer(const Context *context,
494 unsigned int attribNum,
495 Buffer *boundBuffer,
496 GLint size,
497 VertexAttribType type,
498 GLsizei stride,
499 const void *pointer)
500 {
501 mVertexArray->setVertexAttribIPointer(context, attribNum, boundBuffer, size, type, stride,
502 pointer);
503 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
504 }
505
506 void setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor);
getVertexAttribCurrentValue(size_t attribNum)507 const VertexAttribCurrentValueData &getVertexAttribCurrentValue(size_t attribNum) const
508 {
509 ASSERT(attribNum < mVertexAttribCurrentValues.size());
510 return mVertexAttribCurrentValues[attribNum];
511 }
512
getVertexAttribCurrentValues()513 const std::vector<VertexAttribCurrentValueData> &getVertexAttribCurrentValues() const
514 {
515 return mVertexAttribCurrentValues;
516 }
517
518 const void *getVertexAttribPointer(unsigned int attribNum) const;
519
520 void bindVertexBuffer(const Context *context,
521 GLuint bindingIndex,
522 Buffer *boundBuffer,
523 GLintptr offset,
524 GLsizei stride);
525 void setVertexAttribFormat(GLuint attribIndex,
526 GLint size,
527 VertexAttribType type,
528 bool normalized,
529 bool pureInteger,
530 GLuint relativeOffset);
531
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)532 void setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
533 {
534 mVertexArray->setVertexAttribBinding(context, attribIndex, bindingIndex);
535 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
536 }
537
538 void setVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor);
539
540 // Pixel pack state manipulation
541 void setPackAlignment(GLint alignment);
getPackAlignment()542 GLint getPackAlignment() const { return mPack.alignment; }
543 void setPackReverseRowOrder(bool reverseRowOrder);
getPackReverseRowOrder()544 bool getPackReverseRowOrder() const { return mPack.reverseRowOrder; }
545 void setPackRowLength(GLint rowLength);
getPackRowLength()546 GLint getPackRowLength() const { return mPack.rowLength; }
547 void setPackSkipRows(GLint skipRows);
getPackSkipRows()548 GLint getPackSkipRows() const { return mPack.skipRows; }
549 void setPackSkipPixels(GLint skipPixels);
getPackSkipPixels()550 GLint getPackSkipPixels() const { return mPack.skipPixels; }
getPackState()551 const PixelPackState &getPackState() const { return mPack; }
getPackState()552 PixelPackState &getPackState() { return mPack; }
553
554 // Pixel unpack state manipulation
555 void setUnpackAlignment(GLint alignment);
getUnpackAlignment()556 GLint getUnpackAlignment() const { return mUnpack.alignment; }
557 void setUnpackRowLength(GLint rowLength);
getUnpackRowLength()558 GLint getUnpackRowLength() const { return mUnpack.rowLength; }
559 void setUnpackImageHeight(GLint imageHeight);
getUnpackImageHeight()560 GLint getUnpackImageHeight() const { return mUnpack.imageHeight; }
561 void setUnpackSkipImages(GLint skipImages);
getUnpackSkipImages()562 GLint getUnpackSkipImages() const { return mUnpack.skipImages; }
563 void setUnpackSkipRows(GLint skipRows);
getUnpackSkipRows()564 GLint getUnpackSkipRows() const { return mUnpack.skipRows; }
565 void setUnpackSkipPixels(GLint skipPixels);
getUnpackSkipPixels()566 GLint getUnpackSkipPixels() const { return mUnpack.skipPixels; }
getUnpackState()567 const PixelUnpackState &getUnpackState() const { return mUnpack; }
getUnpackState()568 PixelUnpackState &getUnpackState() { return mUnpack; }
569
570 // Debug state
getDebug()571 const Debug &getDebug() const { return mDebug; }
getDebug()572 Debug &getDebug() { return mDebug; }
573
574 // CHROMIUM_framebuffer_mixed_samples coverage modulation
575 void setCoverageModulation(GLenum components);
getCoverageModulation()576 GLenum getCoverageModulation() const { return mCoverageModulation; }
577
578 // GL_EXT_sRGB_write_control
579 void setFramebufferSRGB(bool sRGB);
getFramebufferSRGB()580 bool getFramebufferSRGB() const { return mFramebufferSRGB; }
581
582 // GL_KHR_parallel_shader_compile
583 void setMaxShaderCompilerThreads(GLuint count);
getMaxShaderCompilerThreads()584 GLuint getMaxShaderCompilerThreads() const { return mMaxShaderCompilerThreads; }
585
586 // GL_EXT_tessellation_shader
587 void setPatchVertices(GLuint value);
getPatchVertices()588 GLuint getPatchVertices() const { return mPatchVertices; }
589
590 // State query functions
591 void getBooleanv(GLenum pname, GLboolean *params) const;
592 void getFloatv(GLenum pname, GLfloat *params) const;
593 angle::Result getIntegerv(const Context *context, GLenum pname, GLint *params) const;
594 void getPointerv(const Context *context, GLenum pname, void **params) const;
595 void getIntegeri_v(GLenum target, GLuint index, GLint *data) const;
596 void getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const;
597 void getBooleani_v(GLenum target, GLuint index, GLboolean *data) const;
598
isRobustResourceInitEnabled()599 bool isRobustResourceInitEnabled() const { return mRobustResourceInit; }
600
601 // Sets the dirty bit for the program executable.
602 angle::Result onProgramExecutableChange(const Context *context, Program *program);
603 // Sets the dirty bit for the program pipeline executable.
604 angle::Result onProgramPipelineExecutableChange(const Context *context);
605
606 enum DirtyBitType
607 {
608 // Note: process draw framebuffer binding first, so that other dirty bits whose effect
609 // depend on the current draw framebuffer are not processed while the old framebuffer is
610 // still bound.
611 DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
612 DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
613 DIRTY_BIT_SCISSOR_TEST_ENABLED,
614 DIRTY_BIT_SCISSOR,
615 DIRTY_BIT_VIEWPORT,
616 DIRTY_BIT_DEPTH_RANGE,
617 DIRTY_BIT_BLEND_ENABLED,
618 DIRTY_BIT_BLEND_COLOR,
619 DIRTY_BIT_BLEND_FUNCS,
620 DIRTY_BIT_BLEND_EQUATIONS,
621 DIRTY_BIT_COLOR_MASK,
622 DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
623 DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
624 DIRTY_BIT_SAMPLE_COVERAGE,
625 DIRTY_BIT_SAMPLE_MASK_ENABLED,
626 DIRTY_BIT_SAMPLE_MASK,
627 DIRTY_BIT_DEPTH_TEST_ENABLED,
628 DIRTY_BIT_DEPTH_FUNC,
629 DIRTY_BIT_DEPTH_MASK,
630 DIRTY_BIT_STENCIL_TEST_ENABLED,
631 DIRTY_BIT_STENCIL_FUNCS_FRONT,
632 DIRTY_BIT_STENCIL_FUNCS_BACK,
633 DIRTY_BIT_STENCIL_OPS_FRONT,
634 DIRTY_BIT_STENCIL_OPS_BACK,
635 DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
636 DIRTY_BIT_STENCIL_WRITEMASK_BACK,
637 DIRTY_BIT_CULL_FACE_ENABLED,
638 DIRTY_BIT_CULL_FACE,
639 DIRTY_BIT_FRONT_FACE,
640 DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
641 DIRTY_BIT_POLYGON_OFFSET,
642 DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
643 DIRTY_BIT_LINE_WIDTH,
644 DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
645 DIRTY_BIT_CLEAR_COLOR,
646 DIRTY_BIT_CLEAR_DEPTH,
647 DIRTY_BIT_CLEAR_STENCIL,
648 DIRTY_BIT_UNPACK_STATE,
649 DIRTY_BIT_UNPACK_BUFFER_BINDING,
650 DIRTY_BIT_PACK_STATE,
651 DIRTY_BIT_PACK_BUFFER_BINDING,
652 DIRTY_BIT_DITHER_ENABLED,
653 DIRTY_BIT_RENDERBUFFER_BINDING,
654 DIRTY_BIT_VERTEX_ARRAY_BINDING,
655 DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING,
656 DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING,
657 // TODO(jmadill): Fine-grained dirty bits for each index.
658 DIRTY_BIT_PROGRAM_BINDING, // Must be before DIRTY_BIT_PROGRAM_EXECUTABLE
659 DIRTY_BIT_PROGRAM_EXECUTABLE,
660 // TODO(jmadill): Fine-grained dirty bits for each texture/sampler.
661 DIRTY_BIT_SAMPLER_BINDINGS,
662 DIRTY_BIT_TEXTURE_BINDINGS,
663 DIRTY_BIT_IMAGE_BINDINGS,
664 DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING,
665 DIRTY_BIT_UNIFORM_BUFFER_BINDINGS,
666 DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING,
667 DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING,
668 DIRTY_BIT_MULTISAMPLING,
669 DIRTY_BIT_SAMPLE_ALPHA_TO_ONE,
670 DIRTY_BIT_COVERAGE_MODULATION, // CHROMIUM_framebuffer_mixed_samples
671 DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE, // GL_EXT_sRGB_write_control
672 DIRTY_BIT_CURRENT_VALUES,
673 DIRTY_BIT_PROVOKING_VERTEX,
674 DIRTY_BIT_SAMPLE_SHADING,
675 DIRTY_BIT_PATCH_VERTICES,
676 DIRTY_BIT_EXTENDED, // clip distances, mipmap generation hint, derivative hint,
677 // EXT_clip_control
678 DIRTY_BIT_INVALID,
679 DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
680 };
681
682 static_assert(DIRTY_BIT_MAX <= 64, "State dirty bits must be capped at 64");
683
684 enum ExtendedDirtyBitType
685 {
686 EXTENDED_DIRTY_BIT_CLIP_CONTROL, // EXT_clip_control
687 EXTENDED_DIRTY_BIT_CLIP_DISTANCES, // clip distances
688 EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT, // mipmap generation hint
689 EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT, // shader derivative hint
690 EXTENDED_DIRTY_BIT_INVALID,
691 EXTENDED_DIRTY_BIT_MAX = EXTENDED_DIRTY_BIT_INVALID,
692 };
693
694 static_assert(EXTENDED_DIRTY_BIT_MAX <= 32, "State extended dirty bits must be capped at 32");
695
696 // TODO(jmadill): Consider storing dirty objects in a list instead of by binding.
697 enum DirtyObjectType
698 {
699 DIRTY_OBJECT_ACTIVE_TEXTURES, // Top-level dirty bit. Also see mDirtyActiveTextures.
700 DIRTY_OBJECT_TEXTURES_INIT,
701 DIRTY_OBJECT_IMAGES_INIT,
702 DIRTY_OBJECT_READ_ATTACHMENTS,
703 DIRTY_OBJECT_DRAW_ATTACHMENTS,
704 DIRTY_OBJECT_READ_FRAMEBUFFER,
705 DIRTY_OBJECT_DRAW_FRAMEBUFFER,
706 DIRTY_OBJECT_VERTEX_ARRAY,
707 DIRTY_OBJECT_TEXTURES, // Top-level dirty bit. Also see mDirtyTextures.
708 DIRTY_OBJECT_IMAGES, // Top-level dirty bit. Also see mDirtyImages.
709 DIRTY_OBJECT_SAMPLERS, // Top-level dirty bit. Also see mDirtySamplers.
710 DIRTY_OBJECT_PROGRAM,
711 DIRTY_OBJECT_UNKNOWN,
712 DIRTY_OBJECT_MAX = DIRTY_OBJECT_UNKNOWN,
713 };
714
715 using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
getDirtyBits()716 const DirtyBits &getDirtyBits() const { return mDirtyBits; }
clearDirtyBits()717 void clearDirtyBits() { mDirtyBits.reset(); }
clearDirtyBits(const DirtyBits & bitset)718 void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
setAllDirtyBits()719 void setAllDirtyBits()
720 {
721 mDirtyBits.set();
722 mDirtyCurrentValues.set();
723 }
724
725 using ExtendedDirtyBits = angle::BitSet32<EXTENDED_DIRTY_BIT_MAX>;
getExtendedDirtyBits()726 const ExtendedDirtyBits &getExtendedDirtyBits() const { return mExtendedDirtyBits; }
727 // TODO(https://anglebug.com/5631): Handle extended dirty bits on non-vulkan backends
728 ExtendedDirtyBits getAndResetExtendedDirtyBits() const;
clearExtendedDirtyBits()729 void clearExtendedDirtyBits() { mExtendedDirtyBits.reset(); }
730
731 using DirtyObjects = angle::BitSet<DIRTY_OBJECT_MAX>;
clearDirtyObjects()732 void clearDirtyObjects() { mDirtyObjects.reset(); }
setAllDirtyObjects()733 void setAllDirtyObjects() { mDirtyObjects.set(); }
734 angle::Result syncDirtyObjects(const Context *context,
735 const DirtyObjects &bitset,
736 Command command);
737 angle::Result syncDirtyObject(const Context *context, GLenum target);
738 void setObjectDirty(GLenum target);
739 void setTextureDirty(size_t textureUnitIndex);
740 void setSamplerDirty(size_t samplerIndex);
741
setReadFramebufferDirty()742 ANGLE_INLINE void setReadFramebufferDirty()
743 {
744 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
745 mDirtyObjects.set(DIRTY_OBJECT_READ_ATTACHMENTS);
746 }
747
setDrawFramebufferDirty()748 ANGLE_INLINE void setDrawFramebufferDirty()
749 {
750 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
751 mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
752 }
753
754 // This actually clears the current value dirty bits.
755 // TODO(jmadill): Pass mutable dirty bits into Impl.
756 AttributesMask getAndResetDirtyCurrentValues() const;
757
758 void setImageUnit(const Context *context,
759 size_t unit,
760 Texture *texture,
761 GLint level,
762 GLboolean layered,
763 GLint layer,
764 GLenum access,
765 GLenum format);
766
getImageUnit(size_t unit)767 const ImageUnit &getImageUnit(size_t unit) const { return mImageUnits[unit]; }
getActiveTexturesCache()768 const ActiveTexturesCache &getActiveTexturesCache() const { return mActiveTexturesCache; }
getCurrentValuesTypeMask()769 ComponentTypeMask getCurrentValuesTypeMask() const { return mCurrentValuesTypeMask; }
770
771 // "onActiveTextureChange" is called when a texture binding changes.
772 void onActiveTextureChange(const Context *context, size_t textureUnit);
773
774 // "onActiveTextureStateChange" is called when the Texture changed but the binding did not.
775 void onActiveTextureStateChange(const Context *context, size_t textureUnit);
776
777 void onImageStateChange(const Context *context, size_t unit);
778
779 void onUniformBufferStateChange(size_t uniformBufferIndex);
780 void onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex);
781 void onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex);
782
isCurrentTransformFeedback(const TransformFeedback * tf)783 bool isCurrentTransformFeedback(const TransformFeedback *tf) const
784 {
785 return tf == mTransformFeedback.get();
786 }
isCurrentVertexArray(const VertexArray * va)787 bool isCurrentVertexArray(const VertexArray *va) const { return va == mVertexArray; }
788
gles1()789 GLES1State &gles1() { return mGLES1State; }
gles1()790 const GLES1State &gles1() const { return mGLES1State; }
791
792 // Helpers for setting bound buffers. They should all have the same signature.
793 // Not meant to be called externally. Used for local helpers in State.cpp.
794 template <BufferBinding Target>
795 void setGenericBufferBindingWithBit(const Context *context, Buffer *buffer);
796
797 template <BufferBinding Target>
798 void setGenericBufferBinding(const Context *context, Buffer *buffer);
799
800 using BufferBindingSetter = void (State::*)(const Context *, Buffer *);
801
validateSamplerFormats()802 ANGLE_INLINE bool validateSamplerFormats() const
803 {
804 return (!mExecutable || !(mTexturesIncompatibleWithSamplers.intersects(
805 mExecutable->getActiveSamplersMask())));
806 }
807
getProvokingVertex()808 ProvokingVertexConvention getProvokingVertex() const { return mProvokingVertex; }
setProvokingVertex(ProvokingVertexConvention val)809 void setProvokingVertex(ProvokingVertexConvention val)
810 {
811 mDirtyBits.set(State::DIRTY_BIT_PROVOKING_VERTEX);
812 mProvokingVertex = val;
813 }
814
setReadFramebufferBindingDirty()815 ANGLE_INLINE void setReadFramebufferBindingDirty()
816 {
817 mDirtyBits.set(State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
818 }
819
setDrawFramebufferBindingDirty()820 ANGLE_INLINE void setDrawFramebufferBindingDirty()
821 {
822 mDirtyBits.set(State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
823 }
824
825 using ClipDistanceEnableBits = angle::BitSet32<IMPLEMENTATION_MAX_CLIP_DISTANCES>;
getEnabledClipDistances()826 const ClipDistanceEnableBits &getEnabledClipDistances() const { return mClipDistancesEnabled; }
827 void setClipDistanceEnable(int idx, bool enable);
828
getOverlay()829 const OverlayType *getOverlay() const { return mOverlay; }
830
831 // Not for general use.
getBufferManagerForCapture()832 const BufferManager &getBufferManagerForCapture() const { return *mBufferManager; }
getBoundBuffersForCapture()833 const BoundBufferMap &getBoundBuffersForCapture() const { return mBoundBuffers; }
getTextureManagerForCapture()834 const TextureManager &getTextureManagerForCapture() const { return *mTextureManager; }
getBoundTexturesForCapture()835 const TextureBindingMap &getBoundTexturesForCapture() const { return mSamplerTextures; }
getRenderbufferManagerForCapture()836 const RenderbufferManager &getRenderbufferManagerForCapture() const
837 {
838 return *mRenderbufferManager;
839 }
getFramebufferManagerForCapture()840 const FramebufferManager &getFramebufferManagerForCapture() const
841 {
842 return *mFramebufferManager;
843 }
getShaderProgramManagerForCapture()844 const ShaderProgramManager &getShaderProgramManagerForCapture() const
845 {
846 return *mShaderProgramManager;
847 }
getSyncManagerForCapture()848 const SyncManager &getSyncManagerForCapture() const { return *mSyncManager; }
getSamplerManagerForCapture()849 const SamplerManager &getSamplerManagerForCapture() const { return *mSamplerManager; }
getProgramPipelineManagerForCapture()850 const ProgramPipelineManager *getProgramPipelineManagerForCapture() const
851 {
852 return mProgramPipelineManager;
853 }
getSamplerBindingsForCapture()854 const SamplerBindingVector &getSamplerBindingsForCapture() const { return mSamplers; }
getActiveQueriesForCapture()855 const ActiveQueryMap &getActiveQueriesForCapture() const { return mActiveQueries; }
856 void initializeForCapture(const Context *context);
857
hasConstantAlphaBlendFunc()858 bool hasConstantAlphaBlendFunc() const
859 {
860 return (mBlendFuncConstantAlphaDrawBuffers & mBlendStateExt.mEnabledMask).any();
861 }
862
hasSimultaneousConstantColorAndAlphaBlendFunc()863 bool hasSimultaneousConstantColorAndAlphaBlendFunc() const
864 {
865 return (mBlendFuncConstantColorDrawBuffers & mBlendStateExt.mEnabledMask).any() &&
866 hasConstantAlphaBlendFunc();
867 }
868
noSimultaneousConstantColorAndAlphaBlendFunc()869 bool noSimultaneousConstantColorAndAlphaBlendFunc() const
870 {
871 return mNoSimultaneousConstantColorAndAlphaBlendFunc;
872 }
873
canEnableEarlyFragmentTestsOptimization()874 bool canEnableEarlyFragmentTestsOptimization() const
875 {
876 return !isSampleAlphaToCoverageEnabled();
877 }
878
getOffsetBindingPointerUniformBuffers()879 const BufferVector &getOffsetBindingPointerUniformBuffers() const { return mUniformBuffers; }
880
getOffsetBindingPointerAtomicCounterBuffers()881 const BufferVector &getOffsetBindingPointerAtomicCounterBuffers() const
882 {
883 return mAtomicCounterBuffers;
884 }
885
getOffsetBindingPointerShaderStorageBuffers()886 const BufferVector &getOffsetBindingPointerShaderStorageBuffers() const
887 {
888 return mShaderStorageBuffers;
889 }
890
getTexturesIncompatibleWithSamplers()891 ActiveTextureMask getTexturesIncompatibleWithSamplers() const
892 {
893 return mTexturesIncompatibleWithSamplers;
894 }
895
isProgramBinaryCacheEnabled()896 bool isProgramBinaryCacheEnabled() const { return mProgramBinaryCacheEnabled; }
897
isTextureRectangleEnabled()898 bool isTextureRectangleEnabled() const { return mTextureRectangleEnabled; }
899
getBlendFuncConstantAlphaDrawBuffers()900 DrawBufferMask getBlendFuncConstantAlphaDrawBuffers() const
901 {
902 return mBlendFuncConstantAlphaDrawBuffers;
903 }
904
getBlendFuncConstantColorDrawBuffers()905 DrawBufferMask getBlendFuncConstantColorDrawBuffers() const
906 {
907 return mBlendFuncConstantColorDrawBuffers;
908 }
909
getImageUnits()910 const std::vector<ImageUnit> &getImageUnits() const { return mImageUnits; }
911
912 private:
913 friend class Context;
914
915 void unsetActiveTextures(const ActiveTextureMask &textureMask);
916 void setActiveTextureDirty(size_t textureIndex, Texture *texture);
917 void updateTextureBinding(const Context *context, size_t textureIndex, Texture *texture);
918 void updateActiveTextureStateOnSync(const Context *context,
919 size_t textureIndex,
920 const Sampler *sampler,
921 Texture *texture);
922 Texture *getTextureForActiveSampler(TextureType type, size_t index);
923
924 bool hasConstantColor(GLenum sourceRGB, GLenum destRGB) const;
925 bool hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const;
926
927 // Functions to synchronize dirty states
928 angle::Result syncActiveTextures(const Context *context, Command command);
929 angle::Result syncTexturesInit(const Context *context, Command command);
930 angle::Result syncImagesInit(const Context *context, Command command);
931 angle::Result syncReadAttachments(const Context *context, Command command);
932 angle::Result syncDrawAttachments(const Context *context, Command command);
933 angle::Result syncReadFramebuffer(const Context *context, Command command);
934 angle::Result syncDrawFramebuffer(const Context *context, Command command);
935 angle::Result syncVertexArray(const Context *context, Command command);
936 angle::Result syncTextures(const Context *context, Command command);
937 angle::Result syncImages(const Context *context, Command command);
938 angle::Result syncSamplers(const Context *context, Command command);
939 angle::Result syncProgram(const Context *context, Command command);
940
941 using DirtyObjectHandler = angle::Result (State::*)(const Context *context, Command command);
942
943 static constexpr DirtyObjectHandler kDirtyObjectHandlers[DIRTY_OBJECT_MAX] = {
944 &State::syncActiveTextures, &State::syncTexturesInit, &State::syncImagesInit,
945 &State::syncReadAttachments, &State::syncDrawAttachments, &State::syncReadFramebuffer,
946 &State::syncDrawFramebuffer, &State::syncVertexArray, &State::syncTextures,
947 &State::syncImages, &State::syncSamplers, &State::syncProgram};
948
949 // Robust init must happen before Framebuffer init for the Vulkan back-end.
950 static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES < DIRTY_OBJECT_TEXTURES_INIT, "init order");
951 static_assert(DIRTY_OBJECT_TEXTURES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
952 static_assert(DIRTY_OBJECT_IMAGES_INIT < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
953 static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS < DIRTY_OBJECT_DRAW_FRAMEBUFFER, "init order");
954 static_assert(DIRTY_OBJECT_READ_ATTACHMENTS < DIRTY_OBJECT_READ_FRAMEBUFFER, "init order");
955
956 static_assert(DIRTY_OBJECT_ACTIVE_TEXTURES == 0, "check DIRTY_OBJECT_ACTIVE_TEXTURES index");
957 static_assert(DIRTY_OBJECT_TEXTURES_INIT == 1, "check DIRTY_OBJECT_TEXTURES_INIT index");
958 static_assert(DIRTY_OBJECT_IMAGES_INIT == 2, "check DIRTY_OBJECT_IMAGES_INIT index");
959 static_assert(DIRTY_OBJECT_READ_ATTACHMENTS == 3, "check DIRTY_OBJECT_READ_ATTACHMENTS index");
960 static_assert(DIRTY_OBJECT_DRAW_ATTACHMENTS == 4, "check DIRTY_OBJECT_DRAW_ATTACHMENTS index");
961 static_assert(DIRTY_OBJECT_READ_FRAMEBUFFER == 5, "check DIRTY_OBJECT_READ_FRAMEBUFFER index");
962 static_assert(DIRTY_OBJECT_DRAW_FRAMEBUFFER == 6, "check DIRTY_OBJECT_DRAW_FRAMEBUFFER index");
963 static_assert(DIRTY_OBJECT_VERTEX_ARRAY == 7, "check DIRTY_OBJECT_VERTEX_ARRAY index");
964 static_assert(DIRTY_OBJECT_TEXTURES == 8, "check DIRTY_OBJECT_TEXTURES index");
965 static_assert(DIRTY_OBJECT_IMAGES == 9, "check DIRTY_OBJECT_IMAGES index");
966 static_assert(DIRTY_OBJECT_SAMPLERS == 10, "check DIRTY_OBJECT_SAMPLERS index");
967 static_assert(DIRTY_OBJECT_PROGRAM == 11, "check DIRTY_OBJECT_PROGRAM index");
968
969 // Dispatch table for buffer update functions.
970 static const angle::PackedEnumMap<BufferBinding, BufferBindingSetter> kBufferSetters;
971
972 ContextID mID;
973
974 EGLenum mClientType;
975 EGLenum mContextPriority;
976 bool mHasProtectedContent;
977 Version mClientVersion;
978
979 // Caps to use for validation
980 Caps mCaps;
981 TextureCapsMap mTextureCaps;
982 Extensions mExtensions;
983 Limitations mLimitations;
984
985 egl::ShareGroup *mShareGroup;
986
987 // Resource managers.
988 BufferManager *mBufferManager;
989 ShaderProgramManager *mShaderProgramManager;
990 TextureManager *mTextureManager;
991 RenderbufferManager *mRenderbufferManager;
992 SamplerManager *mSamplerManager;
993 SyncManager *mSyncManager;
994 FramebufferManager *mFramebufferManager;
995 ProgramPipelineManager *mProgramPipelineManager;
996 MemoryObjectManager *mMemoryObjectManager;
997 SemaphoreManager *mSemaphoreManager;
998
999 ColorF mColorClearValue;
1000 GLfloat mDepthClearValue;
1001 int mStencilClearValue;
1002
1003 RasterizerState mRasterizer;
1004 bool mScissorTest;
1005 Rectangle mScissor;
1006
1007 BlendState mBlendState; // Buffer zero blend state legacy struct
1008 BlendStateExt mBlendStateExt;
1009 ColorF mBlendColor;
1010 bool mSampleAlphaToCoverage;
1011 bool mSampleCoverage;
1012 GLfloat mSampleCoverageValue;
1013 bool mSampleCoverageInvert;
1014 bool mSampleMask;
1015 GLuint mMaxSampleMaskWords;
1016 std::array<GLbitfield, MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
1017 bool mIsSampleShadingEnabled;
1018 float mMinSampleShading;
1019
1020 DepthStencilState mDepthStencil;
1021 GLint mStencilRef;
1022 GLint mStencilBackRef;
1023
1024 GLfloat mLineWidth;
1025
1026 GLenum mGenerateMipmapHint;
1027 GLenum mTextureFilteringHint;
1028 GLenum mFragmentShaderDerivativeHint;
1029
1030 const bool mBindGeneratesResource;
1031 const bool mClientArraysEnabled;
1032
1033 Rectangle mViewport;
1034 float mNearZ;
1035 float mFarZ;
1036
1037 GLenum mClipControlOrigin;
1038 GLenum mClipControlDepth;
1039
1040 Framebuffer *mReadFramebuffer;
1041 Framebuffer *mDrawFramebuffer;
1042 BindingPointer<Renderbuffer> mRenderbuffer;
1043 Program *mProgram;
1044 BindingPointer<ProgramPipeline> mProgramPipeline;
1045 ProgramExecutable *mExecutable;
1046
1047 // GL_ANGLE_provoking_vertex
1048 ProvokingVertexConvention mProvokingVertex;
1049
1050 using VertexAttribVector = std::vector<VertexAttribCurrentValueData>;
1051 VertexAttribVector mVertexAttribCurrentValues; // From glVertexAttrib
1052 VertexArray *mVertexArray;
1053 ComponentTypeMask mCurrentValuesTypeMask;
1054
1055 // Texture and sampler bindings
1056 GLint mActiveSampler; // Active texture unit selector - GL_TEXTURE0
1057
1058 TextureBindingMap mSamplerTextures;
1059
1060 // Active Textures Cache
1061 // ---------------------
1062 // The active textures cache gives ANGLE components access to a complete array of textures
1063 // on a draw call. gl::State implements angle::Observer and watches gl::Texture for state
1064 // changes via the onSubjectStateChange method above. We update the cache before draws.
1065 // See Observer.h and the design doc linked there for more info on Subject/Observer events.
1066 //
1067 // On state change events (re-binding textures, samplers, programs etc) we clear the cache
1068 // and flag dirty bits. nullptr indicates unbound or incomplete.
1069 ActiveTexturesCache mActiveTexturesCache;
1070 std::vector<angle::ObserverBinding> mCompleteTextureBindings;
1071
1072 ActiveTextureMask mTexturesIncompatibleWithSamplers;
1073
1074 SamplerBindingVector mSamplers;
1075
1076 // It would be nice to merge the image and observer binding. Same for textures.
1077 std::vector<ImageUnit> mImageUnits;
1078
1079 ActiveQueryMap mActiveQueries;
1080
1081 // Stores the currently bound buffer for each binding point. It has an entry for the element
1082 // array buffer but it should not be used. Instead this bind point is owned by the current
1083 // vertex array object.
1084 BoundBufferMap mBoundBuffers;
1085
1086 BufferVector mUniformBuffers;
1087 BufferVector mAtomicCounterBuffers;
1088 BufferVector mShaderStorageBuffers;
1089
1090 angle::BitSet<gl::IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS> mBoundUniformBuffersMask;
1091 angle::BitSet<gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>
1092 mBoundAtomicCounterBuffersMask;
1093 angle::BitSet<gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
1094 mBoundShaderStorageBuffersMask;
1095
1096 BindingPointer<TransformFeedback> mTransformFeedback;
1097
1098 PixelUnpackState mUnpack;
1099 PixelPackState mPack;
1100
1101 bool mPrimitiveRestart;
1102
1103 Debug mDebug;
1104
1105 bool mMultiSampling;
1106 bool mSampleAlphaToOne;
1107
1108 GLenum mCoverageModulation;
1109
1110 // GL_EXT_sRGB_write_control
1111 bool mFramebufferSRGB;
1112
1113 // GL_ANGLE_robust_resource_initialization
1114 const bool mRobustResourceInit;
1115
1116 // GL_ANGLE_program_cache_control
1117 const bool mProgramBinaryCacheEnabled;
1118
1119 // GL_ANGLE_webgl_compatibility
1120 bool mTextureRectangleEnabled;
1121
1122 // GL_KHR_parallel_shader_compile
1123 GLuint mMaxShaderCompilerThreads;
1124
1125 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1126 ClipDistanceEnableBits mClipDistancesEnabled;
1127
1128 // GL_EXT_tessellation_shader
1129 GLuint mPatchVertices;
1130
1131 // GLES1 emulation: state specific to GLES1
1132 GLES1State mGLES1State;
1133
1134 DirtyBits mDirtyBits;
1135 mutable ExtendedDirtyBits mExtendedDirtyBits;
1136 DirtyObjects mDirtyObjects;
1137 mutable AttributesMask mDirtyCurrentValues;
1138 ActiveTextureMask mDirtyActiveTextures;
1139 ActiveTextureMask mDirtyTextures;
1140 ActiveTextureMask mDirtySamplers;
1141 ImageUnitMask mDirtyImages;
1142
1143 // The Overlay object, used by the backend to render the overlay.
1144 const OverlayType *mOverlay;
1145
1146 // OES_draw_buffers_indexed
1147 DrawBufferMask mBlendFuncConstantAlphaDrawBuffers;
1148 DrawBufferMask mBlendFuncConstantColorDrawBuffers;
1149 bool mNoSimultaneousConstantColorAndAlphaBlendFunc;
1150 // Whether the indexed variants of setBlend* have been called. If so, the call to the
1151 // non-indexed variants are not no-oped.
1152 bool mSetBlendIndexedInvoked;
1153 bool mSetBlendFactorsIndexedInvoked;
1154 bool mSetBlendEquationsIndexedInvoked;
1155
1156 // GL_EXT_primitive_bounding_box
1157 GLfloat mBoundingBoxMinX;
1158 GLfloat mBoundingBoxMinY;
1159 GLfloat mBoundingBoxMinZ;
1160 GLfloat mBoundingBoxMinW;
1161 GLfloat mBoundingBoxMaxX;
1162 GLfloat mBoundingBoxMaxY;
1163 GLfloat mBoundingBoxMaxZ;
1164 GLfloat mBoundingBoxMaxW;
1165 };
1166
syncDirtyObjects(const Context * context,const DirtyObjects & bitset,Command command)1167 ANGLE_INLINE angle::Result State::syncDirtyObjects(const Context *context,
1168 const DirtyObjects &bitset,
1169 Command command)
1170 {
1171 const DirtyObjects &dirtyObjects = mDirtyObjects & bitset;
1172
1173 for (size_t dirtyObject : dirtyObjects)
1174 {
1175 ANGLE_TRY((this->*kDirtyObjectHandlers[dirtyObject])(context, command));
1176 }
1177
1178 mDirtyObjects &= ~dirtyObjects;
1179 return angle::Result::Continue;
1180 }
1181
1182 } // namespace gl
1183
1184 #endif // LIBANGLE_STATE_H_
1185