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