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