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