• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 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 // StateManagerGL.h: Defines a class for caching applied OpenGL state
8 
9 #include "libANGLE/renderer/gl/StateManagerGL.h"
10 
11 #include <string.h>
12 #include <algorithm>
13 #include <limits>
14 
15 #include "anglebase/numerics/safe_conversions.h"
16 #include "common/bitset_utils.h"
17 #include "common/mathutil.h"
18 #include "common/matrix_utils.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/Framebuffer.h"
21 #include "libANGLE/Query.h"
22 #include "libANGLE/TransformFeedback.h"
23 #include "libANGLE/VertexArray.h"
24 #include "libANGLE/renderer/gl/BufferGL.h"
25 #include "libANGLE/renderer/gl/FramebufferGL.h"
26 #include "libANGLE/renderer/gl/FunctionsGL.h"
27 #include "libANGLE/renderer/gl/ProgramGL.h"
28 #include "libANGLE/renderer/gl/QueryGL.h"
29 #include "libANGLE/renderer/gl/SamplerGL.h"
30 #include "libANGLE/renderer/gl/TextureGL.h"
31 #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
32 #include "libANGLE/renderer/gl/VertexArrayGL.h"
33 
34 namespace rx
35 {
36 
37 namespace
38 {
39 
ValidateStateHelper(const FunctionsGL * functions,const GLuint localValue,const GLenum pname,const char * localName,const char * driverName)40 static void ValidateStateHelper(const FunctionsGL *functions,
41                                 const GLuint localValue,
42                                 const GLenum pname,
43                                 const char *localName,
44                                 const char *driverName)
45 {
46     GLint queryValue;
47     functions->getIntegerv(pname, &queryValue);
48     if (localValue != static_cast<GLuint>(queryValue))
49     {
50         WARN() << localName << " (" << localValue << ") != " << driverName << " (" << queryValue
51                << ")";
52         // Re-add ASSERT: http://anglebug.com/3900
53         // ASSERT(false);
54     }
55 }
56 
57 }  // anonymous namespace
58 
VertexArrayStateGL(size_t maxAttribs,size_t maxBindings)59 VertexArrayStateGL::VertexArrayStateGL(size_t maxAttribs, size_t maxBindings)
60     : attributes(std::min<size_t>(maxAttribs, gl::MAX_VERTEX_ATTRIBS)),
61       bindings(std::min<size_t>(maxBindings, gl::MAX_VERTEX_ATTRIBS))
62 {
63     // Set the cached vertex attribute array and vertex attribute binding array size
64     for (GLuint i = 0; i < attributes.size(); i++)
65     {
66         attributes[i].bindingIndex = i;
67     }
68 }
69 
IndexedBufferBinding()70 StateManagerGL::IndexedBufferBinding::IndexedBufferBinding() : offset(0), size(0), buffer(0) {}
71 
StateManagerGL(const FunctionsGL * functions,const gl::Caps & rendererCaps,const gl::Extensions & extensions,const angle::FeaturesGL & features)72 StateManagerGL::StateManagerGL(const FunctionsGL *functions,
73                                const gl::Caps &rendererCaps,
74                                const gl::Extensions &extensions,
75                                const angle::FeaturesGL &features)
76     : mFunctions(functions),
77       mFeatures(features),
78       mProgram(0),
79       mVAO(0),
80       mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes),
81       mDefaultVAOState(rendererCaps.maxVertexAttributes, rendererCaps.maxVertexAttribBindings),
82       mVAOState(&mDefaultVAOState),
83       mBuffers(),
84       mIndexedBuffers(),
85       mTextureUnitIndex(0),
86       mTextures{},
87       mSamplers{},
88       mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
89       mTransformFeedback(0),
90       mCurrentTransformFeedback(nullptr),
91       mQueries(),
92       mPrevDrawContext({0}),
93       mUnpackAlignment(4),
94       mUnpackRowLength(0),
95       mUnpackSkipRows(0),
96       mUnpackSkipPixels(0),
97       mUnpackImageHeight(0),
98       mUnpackSkipImages(0),
99       mPackAlignment(4),
100       mPackRowLength(0),
101       mPackSkipRows(0),
102       mPackSkipPixels(0),
103       mFramebuffers(angle::FramebufferBindingSingletonMax, 0),
104       mRenderbuffer(0),
105       mScissorTestEnabled(false),
106       mScissor(0, 0, 0, 0),
107       mViewport(0, 0, 0, 0),
108       mNear(0.0f),
109       mFar(1.0f),
110       mBlendColor(0, 0, 0, 0),
111       mBlendStateExt(rendererCaps.maxDrawBuffers),
112       mIndependentBlendStates(extensions.drawBuffersIndexedAny()),
113       mSampleAlphaToCoverageEnabled(false),
114       mSampleCoverageEnabled(false),
115       mSampleCoverageValue(1.0f),
116       mSampleCoverageInvert(false),
117       mSampleMaskEnabled(false),
118       mDepthTestEnabled(false),
119       mDepthFunc(GL_LESS),
120       mDepthMask(true),
121       mStencilTestEnabled(false),
122       mStencilFrontFunc(GL_ALWAYS),
123       mStencilFrontRef(0),
124       mStencilFrontValueMask(static_cast<GLuint>(-1)),
125       mStencilFrontStencilFailOp(GL_KEEP),
126       mStencilFrontStencilPassDepthFailOp(GL_KEEP),
127       mStencilFrontStencilPassDepthPassOp(GL_KEEP),
128       mStencilFrontWritemask(static_cast<GLuint>(-1)),
129       mStencilBackFunc(GL_ALWAYS),
130       mStencilBackRef(0),
131       mStencilBackValueMask(static_cast<GLuint>(-1)),
132       mStencilBackStencilFailOp(GL_KEEP),
133       mStencilBackStencilPassDepthFailOp(GL_KEEP),
134       mStencilBackStencilPassDepthPassOp(GL_KEEP),
135       mStencilBackWritemask(static_cast<GLuint>(-1)),
136       mCullFaceEnabled(false),
137       mCullFace(gl::CullFaceMode::Back),
138       mFrontFace(GL_CCW),
139       mPolygonOffsetFillEnabled(false),
140       mPolygonOffsetFactor(0.0f),
141       mPolygonOffsetUnits(0.0f),
142       mRasterizerDiscardEnabled(false),
143       mLineWidth(1.0f),
144       mPrimitiveRestartEnabled(false),
145       mPrimitiveRestartIndex(0),
146       mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
147       mClearDepth(1.0f),
148       mClearStencil(0),
149       mFramebufferSRGBAvailable(extensions.sRGBWriteControlEXT),
150       mFramebufferSRGBEnabled(false),
151       mHasSeparateFramebufferBindings(mFunctions->isAtLeastGL(gl::Version(3, 0)) ||
152                                       mFunctions->isAtLeastGLES(gl::Version(3, 0))),
153       mDitherEnabled(true),
154       mTextureCubemapSeamlessEnabled(false),
155       mMultisamplingEnabled(true),
156       mSampleAlphaToOneEnabled(false),
157       mCoverageModulation(GL_NONE),
158       mIsMultiviewEnabled(extensions.multiviewOVR || extensions.multiview2OVR),
159       mProvokingVertex(GL_LAST_VERTEX_CONVENTION),
160       mMaxClipDistances(rendererCaps.maxClipDistances),
161       mLocalDirtyBits()
162 {
163     ASSERT(mFunctions);
164     ASSERT(rendererCaps.maxViews >= 1u);
165 
166     mIndexedBuffers[gl::BufferBinding::Uniform].resize(rendererCaps.maxUniformBufferBindings);
167     mIndexedBuffers[gl::BufferBinding::AtomicCounter].resize(
168         rendererCaps.maxAtomicCounterBufferBindings);
169     mIndexedBuffers[gl::BufferBinding::ShaderStorage].resize(
170         rendererCaps.maxShaderStorageBufferBindings);
171 
172     mSampleMaskValues.fill(~GLbitfield(0));
173 
174     mQueries.fill(nullptr);
175     mTemporaryPausedQueries.fill(nullptr);
176 
177     // Initialize point sprite state for desktop GL
178     if (mFunctions->standard == STANDARD_GL_DESKTOP)
179     {
180         mFunctions->enable(GL_PROGRAM_POINT_SIZE);
181 
182         // GL_POINT_SPRITE was deprecated in the core profile. Point rasterization is always
183         // performed
184         // as though POINT_SPRITE were enabled.
185         if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0)
186         {
187             mFunctions->enable(GL_POINT_SPRITE);
188         }
189     }
190 
191     if (features.emulatePrimitiveRestartFixedIndex.enabled)
192     {
193         // There is no consistent default value for primitive restart index. Set it to UINT -1.
194         constexpr GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndexFromType<GLuint>();
195         mFunctions->primitiveRestartIndex(primitiveRestartIndex);
196         mPrimitiveRestartIndex = primitiveRestartIndex;
197     }
198 
199     // It's possible we've enabled the emulated VAO feature for testing but we're on a core profile.
200     // Use a generated VAO as the default VAO so we can still test.
201     if (features.syncVertexArraysToDefault.enabled &&
202         !nativegl::CanUseDefaultVertexArrayObject(mFunctions))
203     {
204         ASSERT(nativegl::SupportsVertexArrayObjects(mFunctions));
205         mFunctions->genVertexArrays(1, &mDefaultVAO);
206         mFunctions->bindVertexArray(mDefaultVAO);
207         mVAO = mDefaultVAO;
208     }
209 }
210 
~StateManagerGL()211 StateManagerGL::~StateManagerGL()
212 {
213     if (mDefaultVAO != 0)
214     {
215         mFunctions->deleteVertexArrays(1, &mDefaultVAO);
216     }
217 }
218 
deleteProgram(GLuint program)219 void StateManagerGL::deleteProgram(GLuint program)
220 {
221     if (program != 0)
222     {
223         if (mProgram == program)
224         {
225             useProgram(0);
226         }
227 
228         mFunctions->deleteProgram(program);
229     }
230 }
231 
deleteVertexArray(GLuint vao)232 void StateManagerGL::deleteVertexArray(GLuint vao)
233 {
234     if (vao != 0)
235     {
236         if (mVAO == vao)
237         {
238             bindVertexArray(0, &mDefaultVAOState);
239         }
240         mFunctions->deleteVertexArrays(1, &vao);
241     }
242 }
243 
deleteTexture(GLuint texture)244 void StateManagerGL::deleteTexture(GLuint texture)
245 {
246     if (texture != 0)
247     {
248         for (gl::TextureType type : angle::AllEnums<gl::TextureType>())
249         {
250             const auto &textureVector = mTextures[type];
251             for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size();
252                  textureUnitIndex++)
253             {
254                 if (textureVector[textureUnitIndex] == texture)
255                 {
256                     activeTexture(textureUnitIndex);
257                     bindTexture(type, 0);
258                 }
259             }
260         }
261 
262         for (size_t imageUnitIndex = 0; imageUnitIndex < mImages.size(); imageUnitIndex++)
263         {
264             if (mImages[imageUnitIndex].texture == texture)
265             {
266                 bindImageTexture(imageUnitIndex, 0, 0, false, 0, GL_READ_ONLY, GL_R32UI);
267             }
268         }
269 
270         mFunctions->deleteTextures(1, &texture);
271     }
272 }
273 
deleteSampler(GLuint sampler)274 void StateManagerGL::deleteSampler(GLuint sampler)
275 {
276     if (sampler != 0)
277     {
278         for (size_t unit = 0; unit < mSamplers.size(); unit++)
279         {
280             if (mSamplers[unit] == sampler)
281             {
282                 bindSampler(unit, 0);
283             }
284         }
285 
286         mFunctions->deleteSamplers(1, &sampler);
287     }
288 }
289 
deleteBuffer(GLuint buffer)290 void StateManagerGL::deleteBuffer(GLuint buffer)
291 {
292     if (buffer == 0)
293     {
294         return;
295     }
296 
297     for (auto target : angle::AllEnums<gl::BufferBinding>())
298     {
299         if (mBuffers[target] == buffer)
300         {
301             bindBuffer(target, 0);
302         }
303 
304         auto &indexedTarget = mIndexedBuffers[target];
305         for (size_t bindIndex = 0; bindIndex < indexedTarget.size(); ++bindIndex)
306         {
307             if (indexedTarget[bindIndex].buffer == buffer)
308             {
309                 bindBufferBase(target, bindIndex, 0);
310             }
311         }
312     }
313 
314     if (mVAOState)
315     {
316         if (mVAOState->elementArrayBuffer == buffer)
317         {
318             mVAOState->elementArrayBuffer = 0;
319         }
320 
321         for (VertexBindingGL &binding : mVAOState->bindings)
322         {
323             if (binding.buffer == buffer)
324             {
325                 binding.buffer = 0;
326             }
327         }
328     }
329 
330     mFunctions->deleteBuffers(1, &buffer);
331 }
332 
deleteFramebuffer(GLuint fbo)333 void StateManagerGL::deleteFramebuffer(GLuint fbo)
334 {
335     if (fbo != 0)
336     {
337         if (mHasSeparateFramebufferBindings)
338         {
339             for (size_t binding = 0; binding < mFramebuffers.size(); ++binding)
340             {
341                 if (mFramebuffers[binding] == fbo)
342                 {
343                     GLenum enumValue = angle::FramebufferBindingToEnum(
344                         static_cast<angle::FramebufferBinding>(binding));
345                     bindFramebuffer(enumValue, 0);
346                 }
347             }
348         }
349         else
350         {
351             ASSERT(mFramebuffers[angle::FramebufferBindingRead] ==
352                    mFramebuffers[angle::FramebufferBindingDraw]);
353             if (mFramebuffers[angle::FramebufferBindingRead] == fbo)
354             {
355                 bindFramebuffer(GL_FRAMEBUFFER, 0);
356             }
357         }
358         mFunctions->deleteFramebuffers(1, &fbo);
359     }
360 }
361 
deleteRenderbuffer(GLuint rbo)362 void StateManagerGL::deleteRenderbuffer(GLuint rbo)
363 {
364     if (rbo != 0)
365     {
366         if (mRenderbuffer == rbo)
367         {
368             bindRenderbuffer(GL_RENDERBUFFER, 0);
369         }
370 
371         mFunctions->deleteRenderbuffers(1, &rbo);
372     }
373 }
374 
deleteTransformFeedback(GLuint transformFeedback)375 void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
376 {
377     if (transformFeedback != 0)
378     {
379         if (mTransformFeedback == transformFeedback)
380         {
381             bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
382         }
383 
384         if (mCurrentTransformFeedback != nullptr &&
385             mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
386         {
387             mCurrentTransformFeedback = nullptr;
388         }
389 
390         mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
391     }
392 }
393 
useProgram(GLuint program)394 void StateManagerGL::useProgram(GLuint program)
395 {
396     if (mProgram != program)
397     {
398         forceUseProgram(program);
399     }
400 }
401 
forceUseProgram(GLuint program)402 void StateManagerGL::forceUseProgram(GLuint program)
403 {
404     mProgram = program;
405     mFunctions->useProgram(mProgram);
406     mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
407 }
408 
bindVertexArray(GLuint vao,VertexArrayStateGL * vaoState)409 void StateManagerGL::bindVertexArray(GLuint vao, VertexArrayStateGL *vaoState)
410 {
411     ASSERT(vaoState);
412     if (mVAO != vao)
413     {
414         ASSERT(!mFeatures.syncVertexArraysToDefault.enabled);
415 
416         mVAO                                      = vao;
417         mVAOState                                 = vaoState;
418         mBuffers[gl::BufferBinding::ElementArray] = vaoState ? vaoState->elementArrayBuffer : 0;
419 
420         mFunctions->bindVertexArray(vao);
421 
422         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
423     }
424 }
425 
bindBuffer(gl::BufferBinding target,GLuint buffer)426 void StateManagerGL::bindBuffer(gl::BufferBinding target, GLuint buffer)
427 {
428     // GL drivers differ in whether the transform feedback bind point is modified when
429     // glBindTransformFeedback is called. To avoid these behavior differences we shouldn't try to
430     // use it.
431     ASSERT(target != gl::BufferBinding::TransformFeedback);
432     if (mBuffers[target] != buffer)
433     {
434         mBuffers[target] = buffer;
435         mFunctions->bindBuffer(gl::ToGLenum(target), buffer);
436     }
437 }
438 
bindBufferBase(gl::BufferBinding target,size_t index,GLuint buffer)439 void StateManagerGL::bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer)
440 {
441     // Transform feedback buffer bindings are tracked in TransformFeedbackGL
442     ASSERT(target != gl::BufferBinding::TransformFeedback);
443 
444     ASSERT(index < mIndexedBuffers[target].size());
445     auto &binding = mIndexedBuffers[target][index];
446     if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
447         binding.size != static_cast<size_t>(-1))
448     {
449         binding.buffer   = buffer;
450         binding.offset   = static_cast<size_t>(-1);
451         binding.size     = static_cast<size_t>(-1);
452         mBuffers[target] = buffer;
453         mFunctions->bindBufferBase(gl::ToGLenum(target), static_cast<GLuint>(index), buffer);
454     }
455 }
456 
bindBufferRange(gl::BufferBinding target,size_t index,GLuint buffer,size_t offset,size_t size)457 void StateManagerGL::bindBufferRange(gl::BufferBinding target,
458                                      size_t index,
459                                      GLuint buffer,
460                                      size_t offset,
461                                      size_t size)
462 {
463     // Transform feedback buffer bindings are tracked in TransformFeedbackGL
464     ASSERT(target != gl::BufferBinding::TransformFeedback);
465 
466     auto &binding = mIndexedBuffers[target][index];
467     if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
468     {
469         binding.buffer   = buffer;
470         binding.offset   = offset;
471         binding.size     = size;
472         mBuffers[target] = buffer;
473         mFunctions->bindBufferRange(gl::ToGLenum(target), static_cast<GLuint>(index), buffer,
474                                     offset, size);
475     }
476 }
477 
activeTexture(size_t unit)478 void StateManagerGL::activeTexture(size_t unit)
479 {
480     if (mTextureUnitIndex != unit)
481     {
482         mTextureUnitIndex = unit;
483         mFunctions->activeTexture(GL_TEXTURE0 + static_cast<GLenum>(mTextureUnitIndex));
484     }
485 }
486 
bindTexture(gl::TextureType type,GLuint texture)487 void StateManagerGL::bindTexture(gl::TextureType type, GLuint texture)
488 {
489     gl::TextureType nativeType = nativegl::GetNativeTextureType(type);
490     if (mTextures[nativeType][mTextureUnitIndex] != texture)
491     {
492         mTextures[nativeType][mTextureUnitIndex] = texture;
493         mFunctions->bindTexture(nativegl::GetTextureBindingTarget(type), texture);
494         mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
495     }
496 }
497 
invalidateTexture(gl::TextureType type)498 void StateManagerGL::invalidateTexture(gl::TextureType type)
499 {
500     // Assume the tracked texture binding is incorrect, query the real bound texture from GL.
501     GLint boundTexture = 0;
502     mFunctions->getIntegerv(nativegl::GetTextureBindingQuery(type), &boundTexture);
503     mTextures[type][mTextureUnitIndex] = static_cast<GLuint>(boundTexture);
504     mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
505 }
506 
bindSampler(size_t unit,GLuint sampler)507 void StateManagerGL::bindSampler(size_t unit, GLuint sampler)
508 {
509     if (mSamplers[unit] != sampler)
510     {
511         mSamplers[unit] = sampler;
512         mFunctions->bindSampler(static_cast<GLuint>(unit), sampler);
513         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLER_BINDINGS);
514     }
515 }
516 
bindImageTexture(size_t unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)517 void StateManagerGL::bindImageTexture(size_t unit,
518                                       GLuint texture,
519                                       GLint level,
520                                       GLboolean layered,
521                                       GLint layer,
522                                       GLenum access,
523                                       GLenum format)
524 {
525     auto &binding = mImages[unit];
526     if (binding.texture != texture || binding.level != level || binding.layered != layered ||
527         binding.layer != layer || binding.access != access || binding.format != format)
528     {
529         binding.texture = texture;
530         binding.level   = level;
531         binding.layered = layered;
532         binding.layer   = layer;
533         binding.access  = access;
534         binding.format  = format;
535         mFunctions->bindImageTexture(angle::base::checked_cast<GLuint>(unit), texture, level,
536                                      layered, layer, access, format);
537     }
538 }
539 
setPixelUnpackState(const gl::Context * context,const gl::PixelUnpackState & unpack)540 angle::Result StateManagerGL::setPixelUnpackState(const gl::Context *context,
541                                                   const gl::PixelUnpackState &unpack)
542 {
543     if (mUnpackAlignment != unpack.alignment)
544     {
545         mUnpackAlignment = unpack.alignment;
546         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment));
547 
548         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
549     }
550 
551     if (mUnpackRowLength != unpack.rowLength)
552     {
553         mUnpackRowLength = unpack.rowLength;
554         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength));
555 
556         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
557     }
558 
559     if (mUnpackSkipRows != unpack.skipRows)
560     {
561         mUnpackSkipRows = unpack.skipRows;
562         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows));
563 
564         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
565     }
566 
567     if (mUnpackSkipPixels != unpack.skipPixels)
568     {
569         mUnpackSkipPixels = unpack.skipPixels;
570         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels));
571 
572         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
573     }
574 
575     if (mUnpackImageHeight != unpack.imageHeight)
576     {
577         mUnpackImageHeight = unpack.imageHeight;
578         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight));
579 
580         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
581     }
582 
583     if (mUnpackSkipImages != unpack.skipImages)
584     {
585         mUnpackSkipImages = unpack.skipImages;
586         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages));
587 
588         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
589     }
590 
591     return angle::Result::Continue;
592 }
593 
setPixelUnpackBuffer(const gl::Context * context,const gl::Buffer * pixelBuffer)594 angle::Result StateManagerGL::setPixelUnpackBuffer(const gl::Context *context,
595                                                    const gl::Buffer *pixelBuffer)
596 {
597     GLuint bufferID = 0;
598     if (pixelBuffer != nullptr)
599     {
600         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
601     }
602     bindBuffer(gl::BufferBinding::PixelUnpack, bufferID);
603 
604     return angle::Result::Continue;
605 }
606 
setPixelPackState(const gl::Context * context,const gl::PixelPackState & pack)607 angle::Result StateManagerGL::setPixelPackState(const gl::Context *context,
608                                                 const gl::PixelPackState &pack)
609 {
610     if (mPackAlignment != pack.alignment)
611     {
612         mPackAlignment = pack.alignment;
613         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment));
614 
615         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
616     }
617 
618     if (mPackRowLength != pack.rowLength)
619     {
620         mPackRowLength = pack.rowLength;
621         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength));
622 
623         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
624     }
625 
626     if (mPackSkipRows != pack.skipRows)
627     {
628         mPackSkipRows = pack.skipRows;
629         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows));
630 
631         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
632     }
633 
634     if (mPackSkipPixels != pack.skipPixels)
635     {
636         mPackSkipPixels = pack.skipPixels;
637         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels));
638 
639         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
640     }
641 
642     return angle::Result::Continue;
643 }
644 
setPixelPackBuffer(const gl::Context * context,const gl::Buffer * pixelBuffer)645 angle::Result StateManagerGL::setPixelPackBuffer(const gl::Context *context,
646                                                  const gl::Buffer *pixelBuffer)
647 {
648     GLuint bufferID = 0;
649     if (pixelBuffer != nullptr)
650     {
651         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
652     }
653     bindBuffer(gl::BufferBinding::PixelPack, bufferID);
654 
655     return angle::Result::Continue;
656 }
657 
bindFramebuffer(GLenum type,GLuint framebuffer)658 void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
659 {
660     bool framebufferChanged = false;
661     switch (type)
662     {
663         case GL_FRAMEBUFFER:
664             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer ||
665                 mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
666             {
667                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
668                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
669                 mFunctions->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
670 
671                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
672                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
673 
674                 framebufferChanged = true;
675             }
676             break;
677 
678         case GL_READ_FRAMEBUFFER:
679             ASSERT(mHasSeparateFramebufferBindings);
680             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer)
681             {
682                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
683                 mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
684 
685                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
686 
687                 framebufferChanged = true;
688             }
689             break;
690 
691         case GL_DRAW_FRAMEBUFFER:
692             ASSERT(mHasSeparateFramebufferBindings);
693             if (mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
694             {
695                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
696                 mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
697 
698                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
699 
700                 framebufferChanged = true;
701             }
702             break;
703 
704         default:
705             UNREACHABLE();
706             break;
707     }
708 
709     if (framebufferChanged && mFeatures.flushOnFramebufferChange.enabled)
710     {
711         mFunctions->flush();
712     }
713 }
714 
bindRenderbuffer(GLenum type,GLuint renderbuffer)715 void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
716 {
717     ASSERT(type == GL_RENDERBUFFER);
718     if (mRenderbuffer != renderbuffer)
719     {
720         mRenderbuffer = renderbuffer;
721         mFunctions->bindRenderbuffer(type, mRenderbuffer);
722     }
723 }
724 
bindTransformFeedback(GLenum type,GLuint transformFeedback)725 void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback)
726 {
727     ASSERT(type == GL_TRANSFORM_FEEDBACK);
728     if (mTransformFeedback != transformFeedback)
729     {
730         // Pause the current transform feedback if one is active.
731         // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
732         // feedback at any time, even if there is one active.
733         if (mCurrentTransformFeedback != nullptr &&
734             mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
735         {
736             mCurrentTransformFeedback->syncPausedState(true);
737             mCurrentTransformFeedback = nullptr;
738         }
739 
740         mTransformFeedback = transformFeedback;
741         mFunctions->bindTransformFeedback(type, mTransformFeedback);
742         onTransformFeedbackStateChange();
743     }
744 }
745 
onTransformFeedbackStateChange()746 void StateManagerGL::onTransformFeedbackStateChange()
747 {
748     mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
749 }
750 
beginQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)751 void StateManagerGL::beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
752 {
753     // Make sure this is a valid query type and there is no current active query of this type
754     ASSERT(mQueries[type] == nullptr);
755     ASSERT(queryId != 0);
756 
757     mQueries[type] = queryObject;
758     mFunctions->beginQuery(ToGLenum(type), queryId);
759 }
760 
endQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)761 void StateManagerGL::endQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
762 {
763     ASSERT(queryObject != nullptr);
764     ASSERT(mQueries[type] == queryObject);
765     mQueries[type] = nullptr;
766     mFunctions->endQuery(ToGLenum(type));
767 }
768 
updateDrawIndirectBufferBinding(const gl::Context * context)769 void StateManagerGL::updateDrawIndirectBufferBinding(const gl::Context *context)
770 {
771     gl::Buffer *drawIndirectBuffer =
772         context->getState().getTargetBuffer(gl::BufferBinding::DrawIndirect);
773     if (drawIndirectBuffer != nullptr)
774     {
775         const BufferGL *bufferGL = GetImplAs<BufferGL>(drawIndirectBuffer);
776         bindBuffer(gl::BufferBinding::DrawIndirect, bufferGL->getBufferID());
777     }
778 }
779 
updateDispatchIndirectBufferBinding(const gl::Context * context)780 void StateManagerGL::updateDispatchIndirectBufferBinding(const gl::Context *context)
781 {
782     gl::Buffer *dispatchIndirectBuffer =
783         context->getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
784     if (dispatchIndirectBuffer != nullptr)
785     {
786         const BufferGL *bufferGL = GetImplAs<BufferGL>(dispatchIndirectBuffer);
787         bindBuffer(gl::BufferBinding::DispatchIndirect, bufferGL->getBufferID());
788     }
789 }
790 
pauseTransformFeedback()791 void StateManagerGL::pauseTransformFeedback()
792 {
793     if (mCurrentTransformFeedback != nullptr)
794     {
795         mCurrentTransformFeedback->syncPausedState(true);
796         onTransformFeedbackStateChange();
797     }
798 }
799 
pauseAllQueries(const gl::Context * context)800 angle::Result StateManagerGL::pauseAllQueries(const gl::Context *context)
801 {
802     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
803     {
804         QueryGL *previousQuery = mQueries[type];
805 
806         if (previousQuery != nullptr)
807         {
808             ANGLE_TRY(previousQuery->pause(context));
809             mTemporaryPausedQueries[type] = previousQuery;
810             mQueries[type]                = nullptr;
811         }
812     }
813 
814     return angle::Result::Continue;
815 }
816 
pauseQuery(const gl::Context * context,gl::QueryType type)817 angle::Result StateManagerGL::pauseQuery(const gl::Context *context, gl::QueryType type)
818 {
819     QueryGL *previousQuery = mQueries[type];
820 
821     if (previousQuery)
822     {
823         ANGLE_TRY(previousQuery->pause(context));
824         mTemporaryPausedQueries[type] = previousQuery;
825         mQueries[type]                = nullptr;
826     }
827 
828     return angle::Result::Continue;
829 }
830 
resumeAllQueries(const gl::Context * context)831 angle::Result StateManagerGL::resumeAllQueries(const gl::Context *context)
832 {
833     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
834     {
835         QueryGL *pausedQuery = mTemporaryPausedQueries[type];
836 
837         if (pausedQuery != nullptr)
838         {
839             ASSERT(mQueries[type] == nullptr);
840             ANGLE_TRY(pausedQuery->resume(context));
841             mTemporaryPausedQueries[type] = nullptr;
842         }
843     }
844 
845     return angle::Result::Continue;
846 }
847 
resumeQuery(const gl::Context * context,gl::QueryType type)848 angle::Result StateManagerGL::resumeQuery(const gl::Context *context, gl::QueryType type)
849 {
850     QueryGL *pausedQuery = mTemporaryPausedQueries[type];
851 
852     if (pausedQuery != nullptr)
853     {
854         ANGLE_TRY(pausedQuery->resume(context));
855         mTemporaryPausedQueries[type] = nullptr;
856     }
857 
858     return angle::Result::Continue;
859 }
860 
onMakeCurrent(const gl::Context * context)861 angle::Result StateManagerGL::onMakeCurrent(const gl::Context *context)
862 {
863     const gl::State &glState = context->getState();
864 
865 #if defined(ANGLE_ENABLE_ASSERTS)
866     // Temporarily pausing queries during context switch is not supported
867     for (QueryGL *pausedQuery : mTemporaryPausedQueries)
868     {
869         ASSERT(pausedQuery == nullptr);
870     }
871 #endif
872 
873     // If the context has changed, pause the previous context's queries
874     auto contextID = context->getState().getContextID();
875     if (contextID != mPrevDrawContext)
876     {
877         for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
878         {
879             QueryGL *currentQuery = mQueries[type];
880             // Pause any old query object
881             if (currentQuery != nullptr)
882             {
883                 ANGLE_TRY(currentQuery->pause(context));
884                 mQueries[type] = nullptr;
885             }
886 
887             // Check if this new context needs to resume a query
888             gl::Query *newQuery = glState.getActiveQuery(type);
889             if (newQuery != nullptr)
890             {
891                 QueryGL *queryGL = GetImplAs<QueryGL>(newQuery);
892                 ANGLE_TRY(queryGL->resume(context));
893             }
894         }
895     }
896     onTransformFeedbackStateChange();
897     mPrevDrawContext = contextID;
898 
899     // Seamless cubemaps are required for ES3 and higher contexts. It should be the cheapest to set
900     // this state here since MakeCurrent is expected to be called less frequently than draw calls.
901     setTextureCubemapSeamlessEnabled(context->getClientMajorVersion() >= 3);
902 
903     return angle::Result::Continue;
904 }
905 
updateProgramTextureBindings(const gl::Context * context)906 void StateManagerGL::updateProgramTextureBindings(const gl::Context *context)
907 {
908     const gl::State &glState                = context->getState();
909     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
910 
911     // It is possible there is no active program during a path operation.
912     if (!executable)
913         return;
914 
915     const gl::ActiveTexturesCache &textures        = glState.getActiveTexturesCache();
916     const gl::ActiveTextureMask &activeTextures    = executable->getActiveSamplersMask();
917     const gl::ActiveTextureTypeArray &textureTypes = executable->getActiveSamplerTypes();
918 
919     for (size_t textureUnitIndex : activeTextures)
920     {
921         gl::TextureType textureType = textureTypes[textureUnitIndex];
922         gl::Texture *texture        = textures[textureUnitIndex];
923 
924         // A nullptr texture indicates incomplete.
925         if (texture != nullptr)
926         {
927             const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
928             // The DIRTY_BIT_BOUND_AS_ATTACHMENT may get inserted when texture is attached to
929             // FBO and if texture is already bound, Texture::syncState will not get called and dirty
930             // bit not gets cleared. But this bit is not used by GL backend at all, so it is
931             // harmless even though we expect texture is clean when reaching here. The bit will
932             // still get cleared next time syncState been called.
933             ASSERT(!texture->hasAnyDirtyBitExcludingBoundAsAttachmentBit());
934             ASSERT(!textureGL->hasAnyDirtyBit());
935 
936             activeTexture(textureUnitIndex);
937             bindTexture(textureType, textureGL->getTextureID());
938         }
939         else
940         {
941             activeTexture(textureUnitIndex);
942             bindTexture(textureType, 0);
943         }
944     }
945 }
946 
updateProgramStorageBufferBindings(const gl::Context * context)947 void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
948 {
949     const gl::State &glState   = context->getState();
950     const gl::Program *program = glState.getProgram();
951 
952     for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
953          blockIndex++)
954     {
955         GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
956         const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
957 
958         if (shaderStorageBuffer.get() != nullptr)
959         {
960             BufferGL *bufferGL = GetImplAs<BufferGL>(shaderStorageBuffer.get());
961 
962             if (shaderStorageBuffer.getSize() == 0)
963             {
964                 bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
965             }
966             else
967             {
968                 bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
969                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
970             }
971         }
972     }
973 }
974 
updateProgramUniformBufferBindings(const gl::Context * context)975 void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *context)
976 {
977     // Sync the current program state
978     const gl::State &glState   = context->getState();
979     const gl::Program *program = glState.getProgram();
980 
981     for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
982          uniformBlockIndex++)
983     {
984         GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
985         const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
986 
987         if (uniformBuffer.get() != nullptr)
988         {
989             BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
990 
991             if (uniformBuffer.getSize() == 0)
992             {
993                 bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
994             }
995             else
996             {
997                 bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
998                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
999             }
1000         }
1001     }
1002 }
1003 
updateProgramAtomicCounterBufferBindings(const gl::Context * context)1004 void StateManagerGL::updateProgramAtomicCounterBufferBindings(const gl::Context *context)
1005 {
1006     const gl::State &glState   = context->getState();
1007     const gl::Program *program = glState.getProgram();
1008 
1009     for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
1010     {
1011         GLuint binding     = atomicCounterBuffer.binding;
1012         const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
1013 
1014         if (buffer.get() != nullptr)
1015         {
1016             BufferGL *bufferGL = GetImplAs<BufferGL>(buffer.get());
1017 
1018             if (buffer.getSize() == 0)
1019             {
1020                 bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
1021             }
1022             else
1023             {
1024                 bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
1025                                 buffer.getOffset(), buffer.getSize());
1026             }
1027         }
1028     }
1029 }
1030 
updateProgramImageBindings(const gl::Context * context)1031 void StateManagerGL::updateProgramImageBindings(const gl::Context *context)
1032 {
1033     const gl::State &glState                = context->getState();
1034     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1035     const gl::Program *program              = glState.getProgram();
1036 
1037     // It is possible there is no active program during a path operation.
1038     if (!executable || !program)
1039         return;
1040 
1041     ASSERT(context->getClientVersion() >= gl::ES_3_1 || program->getImageBindings().empty());
1042     for (size_t imageUnitIndex : executable->getActiveImagesMask())
1043     {
1044         const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
1045         const TextureGL *textureGL     = SafeGetImplAs<TextureGL>(imageUnit.texture.get());
1046         if (textureGL)
1047         {
1048             bindImageTexture(imageUnitIndex, textureGL->getTextureID(), imageUnit.level,
1049                              imageUnit.layered, imageUnit.layer, imageUnit.access,
1050                              imageUnit.format);
1051         }
1052         else
1053         {
1054             bindImageTexture(imageUnitIndex, 0, imageUnit.level, imageUnit.layered, imageUnit.layer,
1055                              imageUnit.access, imageUnit.format);
1056         }
1057     }
1058 }
1059 
setAttributeCurrentData(size_t index,const gl::VertexAttribCurrentValueData & data)1060 void StateManagerGL::setAttributeCurrentData(size_t index,
1061                                              const gl::VertexAttribCurrentValueData &data)
1062 {
1063     if (mVertexAttribCurrentValues[index] != data)
1064     {
1065         mVertexAttribCurrentValues[index] = data;
1066         switch (mVertexAttribCurrentValues[index].Type)
1067         {
1068             case gl::VertexAttribType::Float:
1069                 mFunctions->vertexAttrib4fv(static_cast<GLuint>(index),
1070                                             mVertexAttribCurrentValues[index].Values.FloatValues);
1071                 break;
1072             case gl::VertexAttribType::Int:
1073                 mFunctions->vertexAttribI4iv(static_cast<GLuint>(index),
1074                                              mVertexAttribCurrentValues[index].Values.IntValues);
1075                 break;
1076             case gl::VertexAttribType::UnsignedInt:
1077                 mFunctions->vertexAttribI4uiv(
1078                     static_cast<GLuint>(index),
1079                     mVertexAttribCurrentValues[index].Values.UnsignedIntValues);
1080                 break;
1081             default:
1082                 UNREACHABLE();
1083         }
1084 
1085         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUES);
1086         mLocalDirtyCurrentValues.set(index);
1087     }
1088 }
1089 
setScissorTestEnabled(bool enabled)1090 void StateManagerGL::setScissorTestEnabled(bool enabled)
1091 {
1092     if (mScissorTestEnabled != enabled)
1093     {
1094         mScissorTestEnabled = enabled;
1095         if (mScissorTestEnabled)
1096         {
1097             mFunctions->enable(GL_SCISSOR_TEST);
1098         }
1099         else
1100         {
1101             mFunctions->disable(GL_SCISSOR_TEST);
1102         }
1103 
1104         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
1105     }
1106 }
1107 
setScissor(const gl::Rectangle & scissor)1108 void StateManagerGL::setScissor(const gl::Rectangle &scissor)
1109 {
1110     if (scissor != mScissor)
1111     {
1112         mScissor = scissor;
1113         mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height);
1114 
1115         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
1116     }
1117 }
1118 
setViewport(const gl::Rectangle & viewport)1119 void StateManagerGL::setViewport(const gl::Rectangle &viewport)
1120 {
1121     if (viewport != mViewport)
1122     {
1123         mViewport = viewport;
1124         mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height);
1125 
1126         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
1127     }
1128 }
1129 
setDepthRange(float near,float far)1130 void StateManagerGL::setDepthRange(float near, float far)
1131 {
1132     mNear = near;
1133     mFar  = far;
1134 
1135     // The glDepthRangef function isn't available until OpenGL 4.1.  Prefer it when it is
1136     // available because OpenGL ES only works in floats.
1137     if (mFunctions->depthRangef)
1138     {
1139         mFunctions->depthRangef(mNear, mFar);
1140     }
1141     else
1142     {
1143         ASSERT(mFunctions->depthRange);
1144         mFunctions->depthRange(mNear, mFar);
1145     }
1146 
1147     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
1148 }
1149 
setBlendEnabled(bool enabled)1150 void StateManagerGL::setBlendEnabled(bool enabled)
1151 {
1152     const gl::DrawBufferMask mask =
1153         enabled ? mBlendStateExt.mMaxEnabledMask : gl::DrawBufferMask::Zero();
1154     if (mBlendStateExt.mEnabledMask == mask)
1155     {
1156         return;
1157     }
1158 
1159     if (enabled)
1160     {
1161         mFunctions->enable(GL_BLEND);
1162     }
1163     else
1164     {
1165         mFunctions->disable(GL_BLEND);
1166     }
1167 
1168     mBlendStateExt.setEnabled(enabled);
1169     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
1170 }
1171 
setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)1172 void StateManagerGL::setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)
1173 {
1174     if (mBlendStateExt.mEnabledMask == enabledMask)
1175     {
1176         return;
1177     }
1178 
1179     // Get DrawBufferMask of buffers with different blend enable state
1180     gl::DrawBufferMask diffMask = mBlendStateExt.mEnabledMask ^ enabledMask;
1181     const size_t diffCount      = diffMask.count();
1182 
1183     // Check if enabling or disabling blending for all buffers reduces the number of subsequent
1184     // indexed commands. Implicitly handles the case when the new blend enable state is the same for
1185     // all buffers.
1186     if (diffCount > 1)
1187     {
1188         // The number of indexed blend enable commands in case a mass disable is used.
1189         const size_t enabledCount = enabledMask.count();
1190 
1191         // The mask and the number of indexed blend disable commands in case a mass enable is used.
1192         const gl::DrawBufferMask disabledMask = enabledMask ^ mBlendStateExt.mMaxEnabledMask;
1193         const size_t disabledCount            = disabledMask.count();
1194 
1195         if (enabledCount < diffCount && enabledCount <= disabledCount)
1196         {
1197             diffMask = enabledMask;
1198             mFunctions->disable(GL_BLEND);
1199         }
1200         else if (disabledCount < diffCount && disabledCount <= enabledCount)
1201         {
1202             diffMask = disabledMask;
1203             mFunctions->enable(GL_BLEND);
1204         }
1205     }
1206 
1207     for (size_t drawBufferIndex : diffMask)
1208     {
1209         if (enabledMask.test(drawBufferIndex))
1210         {
1211             mFunctions->enablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1212         }
1213         else
1214         {
1215             mFunctions->disablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1216         }
1217     }
1218 
1219     mBlendStateExt.mEnabledMask = enabledMask;
1220     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
1221 }
1222 
setBlendColor(const gl::ColorF & blendColor)1223 void StateManagerGL::setBlendColor(const gl::ColorF &blendColor)
1224 {
1225     if (mBlendColor != blendColor)
1226     {
1227         mBlendColor = blendColor;
1228         mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue,
1229                                mBlendColor.alpha);
1230 
1231         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
1232     }
1233 }
1234 
setBlendFuncs(const gl::BlendStateExt & blendStateExt)1235 void StateManagerGL::setBlendFuncs(const gl::BlendStateExt &blendStateExt)
1236 {
1237     if (mBlendStateExt.mSrcColor == blendStateExt.mSrcColor &&
1238         mBlendStateExt.mDstColor == blendStateExt.mDstColor &&
1239         mBlendStateExt.mSrcAlpha == blendStateExt.mSrcAlpha &&
1240         mBlendStateExt.mDstAlpha == blendStateExt.mDstAlpha)
1241     {
1242         return;
1243     }
1244 
1245     if (!mIndependentBlendStates)
1246     {
1247         mFunctions->blendFuncSeparate(
1248             blendStateExt.getSrcColorIndexed(0), blendStateExt.getDstColorIndexed(0),
1249             blendStateExt.getSrcAlphaIndexed(0), blendStateExt.getDstAlphaIndexed(0));
1250     }
1251     else
1252     {
1253         // Get DrawBufferMask of buffers with different blend factors
1254         gl::DrawBufferMask diffMask =
1255             mBlendStateExt.compareFactors(blendStateExt.mSrcColor, blendStateExt.mDstColor,
1256                                           blendStateExt.mSrcAlpha, blendStateExt.mDstAlpha);
1257         size_t diffCount = diffMask.count();
1258 
1259         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1260         // commands. Implicitly handles the case when the new blend function state is the same for
1261         // all buffers.
1262         if (diffCount > 1)
1263         {
1264             bool found                                            = false;
1265             gl::BlendStateExt::FactorStorage::Type commonSrcColor = 0;
1266             gl::BlendStateExt::FactorStorage::Type commonDstColor = 0;
1267             gl::BlendStateExt::FactorStorage::Type commonSrcAlpha = 0;
1268             gl::BlendStateExt::FactorStorage::Type commonDstAlpha = 0;
1269             for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
1270             {
1271                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcColor =
1272                     blendStateExt.expandSrcColorIndexed(i);
1273                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstColor =
1274                     blendStateExt.expandDstColorIndexed(i);
1275                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcAlpha =
1276                     blendStateExt.expandSrcAlphaIndexed(i);
1277                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstAlpha =
1278                     blendStateExt.expandDstAlphaIndexed(i);
1279 
1280                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareFactors(
1281                     tempCommonSrcColor, tempCommonDstColor, tempCommonSrcAlpha, tempCommonDstAlpha);
1282 
1283                 const size_t tempDiffCount = tempDiffMask.count();
1284                 if (tempDiffCount < diffCount)
1285                 {
1286                     found          = true;
1287                     diffMask       = tempDiffMask;
1288                     diffCount      = tempDiffCount;
1289                     commonSrcColor = tempCommonSrcColor;
1290                     commonDstColor = tempCommonDstColor;
1291                     commonSrcAlpha = tempCommonSrcAlpha;
1292                     commonDstAlpha = tempCommonDstAlpha;
1293                     if (tempDiffCount == 0)
1294                     {
1295                         break;  // the blend factors are the same for all buffers
1296                     }
1297                 }
1298             }
1299             if (found)
1300             {
1301                 mFunctions->blendFuncSeparate(
1302                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcColor)),
1303                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstColor)),
1304                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcAlpha)),
1305                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstAlpha)));
1306             }
1307         }
1308 
1309         for (size_t drawBufferIndex : diffMask)
1310         {
1311             mFunctions->blendFuncSeparatei(static_cast<GLuint>(drawBufferIndex),
1312                                            blendStateExt.getSrcColorIndexed(drawBufferIndex),
1313                                            blendStateExt.getDstColorIndexed(drawBufferIndex),
1314                                            blendStateExt.getSrcAlphaIndexed(drawBufferIndex),
1315                                            blendStateExt.getDstAlphaIndexed(drawBufferIndex));
1316         }
1317     }
1318     mBlendStateExt.mSrcColor = blendStateExt.mSrcColor;
1319     mBlendStateExt.mDstColor = blendStateExt.mDstColor;
1320     mBlendStateExt.mSrcAlpha = blendStateExt.mSrcAlpha;
1321     mBlendStateExt.mDstAlpha = blendStateExt.mDstAlpha;
1322     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
1323 }
1324 
setBlendEquations(const gl::BlendStateExt & blendStateExt)1325 void StateManagerGL::setBlendEquations(const gl::BlendStateExt &blendStateExt)
1326 {
1327     if (mBlendStateExt.mEquationColor == blendStateExt.mEquationColor &&
1328         mBlendStateExt.mEquationAlpha == blendStateExt.mEquationAlpha)
1329     {
1330         return;
1331     }
1332 
1333     if (!mIndependentBlendStates)
1334     {
1335         mFunctions->blendEquationSeparate(blendStateExt.getEquationColorIndexed(0),
1336                                           blendStateExt.getEquationAlphaIndexed(0));
1337     }
1338     else
1339     {
1340         // Get DrawBufferMask of buffers with different blend equations
1341         gl::DrawBufferMask diffMask = mBlendStateExt.compareEquations(blendStateExt.mEquationColor,
1342                                                                       blendStateExt.mEquationAlpha);
1343         size_t diffCount            = diffMask.count();
1344 
1345         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1346         // commands. Implicitly handles the case when the new blend equation state is the same for
1347         // all buffers.
1348         if (diffCount > 1)
1349         {
1350             bool found                                                   = false;
1351             gl::BlendStateExt::EquationStorage::Type commonEquationColor = 0;
1352             gl::BlendStateExt::EquationStorage::Type commonEquationAlpha = 0;
1353             for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
1354             {
1355                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationColor =
1356                     blendStateExt.expandEquationColorIndexed(i);
1357                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationAlpha =
1358                     blendStateExt.expandEquationAlphaIndexed(i);
1359 
1360                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareEquations(
1361                     tempCommonEquationColor, tempCommonEquationAlpha);
1362 
1363                 const size_t tempDiffCount = tempDiffMask.count();
1364                 if (tempDiffCount < diffCount)
1365                 {
1366                     found               = true;
1367                     diffMask            = tempDiffMask;
1368                     diffCount           = tempDiffCount;
1369                     commonEquationColor = tempCommonEquationColor;
1370                     commonEquationAlpha = tempCommonEquationAlpha;
1371                     if (tempDiffCount == 0)
1372                     {
1373                         break;  // the new blend equations are the same for all buffers
1374                     }
1375                 }
1376             }
1377             if (found)
1378             {
1379                 mFunctions->blendEquationSeparate(
1380                     ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1381                         0, commonEquationColor)),
1382                     ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1383                         0, commonEquationAlpha)));
1384             }
1385         }
1386 
1387         for (size_t drawBufferIndex : diffMask)
1388         {
1389             mFunctions->blendEquationSeparatei(
1390                 static_cast<GLuint>(drawBufferIndex),
1391                 blendStateExt.getEquationColorIndexed(drawBufferIndex),
1392                 blendStateExt.getEquationAlphaIndexed(drawBufferIndex));
1393         }
1394     }
1395     mBlendStateExt.mEquationColor = blendStateExt.mEquationColor;
1396     mBlendStateExt.mEquationAlpha = blendStateExt.mEquationAlpha;
1397     mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
1398 }
1399 
setColorMask(bool red,bool green,bool blue,bool alpha)1400 void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha)
1401 {
1402     const gl::BlendStateExt::ColorMaskStorage::Type mask =
1403         mBlendStateExt.expandColorMaskValue(red, green, blue, alpha);
1404     if (mBlendStateExt.mColorMask != mask)
1405     {
1406         mFunctions->colorMask(red, green, blue, alpha);
1407         mBlendStateExt.mColorMask = mask;
1408         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
1409     }
1410 }
1411 
setSampleAlphaToCoverageEnabled(bool enabled)1412 void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled)
1413 {
1414     if (mSampleAlphaToCoverageEnabled != enabled)
1415     {
1416         mSampleAlphaToCoverageEnabled = enabled;
1417         if (mSampleAlphaToCoverageEnabled)
1418         {
1419             mFunctions->enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1420         }
1421         else
1422         {
1423             mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1424         }
1425 
1426         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1427     }
1428 }
1429 
setSampleCoverageEnabled(bool enabled)1430 void StateManagerGL::setSampleCoverageEnabled(bool enabled)
1431 {
1432     if (mSampleCoverageEnabled != enabled)
1433     {
1434         mSampleCoverageEnabled = enabled;
1435         if (mSampleCoverageEnabled)
1436         {
1437             mFunctions->enable(GL_SAMPLE_COVERAGE);
1438         }
1439         else
1440         {
1441             mFunctions->disable(GL_SAMPLE_COVERAGE);
1442         }
1443 
1444         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1445     }
1446 }
1447 
setSampleCoverage(float value,bool invert)1448 void StateManagerGL::setSampleCoverage(float value, bool invert)
1449 {
1450     if (mSampleCoverageValue != value || mSampleCoverageInvert != invert)
1451     {
1452         mSampleCoverageValue  = value;
1453         mSampleCoverageInvert = invert;
1454         mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert);
1455 
1456         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
1457     }
1458 }
1459 
setSampleMaskEnabled(bool enabled)1460 void StateManagerGL::setSampleMaskEnabled(bool enabled)
1461 {
1462     if (mSampleMaskEnabled != enabled)
1463     {
1464         mSampleMaskEnabled = enabled;
1465         if (mSampleMaskEnabled)
1466         {
1467             mFunctions->enable(GL_SAMPLE_MASK);
1468         }
1469         else
1470         {
1471             mFunctions->disable(GL_SAMPLE_MASK);
1472         }
1473 
1474         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED);
1475     }
1476 }
1477 
setSampleMaski(GLuint maskNumber,GLbitfield mask)1478 void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
1479 {
1480     ASSERT(maskNumber < mSampleMaskValues.size());
1481     if (mSampleMaskValues[maskNumber] != mask)
1482     {
1483         mSampleMaskValues[maskNumber] = mask;
1484         mFunctions->sampleMaski(maskNumber, mask);
1485 
1486         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK);
1487     }
1488 }
1489 
1490 // Depth and stencil redundant state changes are guarded in the
1491 // frontend so for related cases here just set the dirty bit
1492 // and update backend states.
setDepthTestEnabled(bool enabled)1493 void StateManagerGL::setDepthTestEnabled(bool enabled)
1494 {
1495     mDepthTestEnabled = enabled;
1496     if (mDepthTestEnabled)
1497     {
1498         mFunctions->enable(GL_DEPTH_TEST);
1499     }
1500     else
1501     {
1502         mFunctions->disable(GL_DEPTH_TEST);
1503     }
1504 
1505     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
1506 }
1507 
setDepthFunc(GLenum depthFunc)1508 void StateManagerGL::setDepthFunc(GLenum depthFunc)
1509 {
1510     mDepthFunc = depthFunc;
1511     mFunctions->depthFunc(mDepthFunc);
1512 
1513     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
1514 }
1515 
setDepthMask(bool mask)1516 void StateManagerGL::setDepthMask(bool mask)
1517 {
1518     mDepthMask = mask;
1519     mFunctions->depthMask(mDepthMask);
1520 
1521     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
1522 }
1523 
setStencilTestEnabled(bool enabled)1524 void StateManagerGL::setStencilTestEnabled(bool enabled)
1525 {
1526     mStencilTestEnabled = enabled;
1527     if (mStencilTestEnabled)
1528     {
1529         mFunctions->enable(GL_STENCIL_TEST);
1530     }
1531     else
1532     {
1533         mFunctions->disable(GL_STENCIL_TEST);
1534     }
1535 
1536     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
1537 }
1538 
setStencilFrontWritemask(GLuint mask)1539 void StateManagerGL::setStencilFrontWritemask(GLuint mask)
1540 {
1541     mStencilFrontWritemask = mask;
1542     mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask);
1543 
1544     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
1545 }
1546 
setStencilBackWritemask(GLuint mask)1547 void StateManagerGL::setStencilBackWritemask(GLuint mask)
1548 {
1549     mStencilBackWritemask = mask;
1550     mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask);
1551 
1552     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
1553 }
1554 
setStencilFrontFuncs(GLenum func,GLint ref,GLuint mask)1555 void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask)
1556 {
1557     mStencilFrontFunc      = func;
1558     mStencilFrontRef       = ref;
1559     mStencilFrontValueMask = mask;
1560     mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef,
1561                                     mStencilFrontValueMask);
1562 
1563     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
1564 }
1565 
setStencilBackFuncs(GLenum func,GLint ref,GLuint mask)1566 void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask)
1567 {
1568     mStencilBackFunc      = func;
1569     mStencilBackRef       = ref;
1570     mStencilBackValueMask = mask;
1571     mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef,
1572                                     mStencilBackValueMask);
1573 
1574     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
1575 }
1576 
setStencilFrontOps(GLenum sfail,GLenum dpfail,GLenum dppass)1577 void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1578 {
1579     mStencilFrontStencilFailOp          = sfail;
1580     mStencilFrontStencilPassDepthFailOp = dpfail;
1581     mStencilFrontStencilPassDepthPassOp = dppass;
1582     mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp,
1583                                   mStencilFrontStencilPassDepthFailOp,
1584                                   mStencilFrontStencilPassDepthPassOp);
1585 
1586     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
1587 }
1588 
setStencilBackOps(GLenum sfail,GLenum dpfail,GLenum dppass)1589 void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1590 {
1591     mStencilBackStencilFailOp          = sfail;
1592     mStencilBackStencilPassDepthFailOp = dpfail;
1593     mStencilBackStencilPassDepthPassOp = dppass;
1594     mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp,
1595                                   mStencilBackStencilPassDepthFailOp,
1596                                   mStencilBackStencilPassDepthPassOp);
1597 
1598     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
1599 }
1600 
setCullFaceEnabled(bool enabled)1601 void StateManagerGL::setCullFaceEnabled(bool enabled)
1602 {
1603     if (mCullFaceEnabled != enabled)
1604     {
1605         mCullFaceEnabled = enabled;
1606         if (mCullFaceEnabled)
1607         {
1608             mFunctions->enable(GL_CULL_FACE);
1609         }
1610         else
1611         {
1612             mFunctions->disable(GL_CULL_FACE);
1613         }
1614 
1615         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
1616     }
1617 }
1618 
setCullFace(gl::CullFaceMode cullFace)1619 void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
1620 {
1621     if (mCullFace != cullFace)
1622     {
1623         mCullFace = cullFace;
1624         mFunctions->cullFace(ToGLenum(mCullFace));
1625 
1626         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
1627     }
1628 }
1629 
setFrontFace(GLenum frontFace)1630 void StateManagerGL::setFrontFace(GLenum frontFace)
1631 {
1632     if (mFrontFace != frontFace)
1633     {
1634         mFrontFace = frontFace;
1635         mFunctions->frontFace(mFrontFace);
1636 
1637         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
1638     }
1639 }
1640 
setPolygonOffsetFillEnabled(bool enabled)1641 void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled)
1642 {
1643     if (mPolygonOffsetFillEnabled != enabled)
1644     {
1645         mPolygonOffsetFillEnabled = enabled;
1646         if (mPolygonOffsetFillEnabled)
1647         {
1648             mFunctions->enable(GL_POLYGON_OFFSET_FILL);
1649         }
1650         else
1651         {
1652             mFunctions->disable(GL_POLYGON_OFFSET_FILL);
1653         }
1654 
1655         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1656     }
1657 }
1658 
setPolygonOffset(float factor,float units)1659 void StateManagerGL::setPolygonOffset(float factor, float units)
1660 {
1661     if (mPolygonOffsetFactor != factor || mPolygonOffsetUnits != units)
1662     {
1663         mPolygonOffsetFactor = factor;
1664         mPolygonOffsetUnits  = units;
1665         mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits);
1666 
1667         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
1668     }
1669 }
1670 
setRasterizerDiscardEnabled(bool enabled)1671 void StateManagerGL::setRasterizerDiscardEnabled(bool enabled)
1672 {
1673     if (mRasterizerDiscardEnabled != enabled)
1674     {
1675         mRasterizerDiscardEnabled = enabled;
1676         if (mRasterizerDiscardEnabled)
1677         {
1678             mFunctions->enable(GL_RASTERIZER_DISCARD);
1679         }
1680         else
1681         {
1682             mFunctions->disable(GL_RASTERIZER_DISCARD);
1683         }
1684 
1685         mLocalDirtyBits.set(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
1686     }
1687 }
1688 
setLineWidth(float width)1689 void StateManagerGL::setLineWidth(float width)
1690 {
1691     if (mLineWidth != width)
1692     {
1693         mLineWidth = width;
1694         mFunctions->lineWidth(mLineWidth);
1695 
1696         mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
1697     }
1698 }
1699 
setPrimitiveRestartEnabled(const gl::Context * context,bool enabled)1700 angle::Result StateManagerGL::setPrimitiveRestartEnabled(const gl::Context *context, bool enabled)
1701 {
1702     if (mPrimitiveRestartEnabled != enabled)
1703     {
1704         GLenum cap = mFeatures.emulatePrimitiveRestartFixedIndex.enabled
1705                          ? GL_PRIMITIVE_RESTART
1706                          : GL_PRIMITIVE_RESTART_FIXED_INDEX;
1707 
1708         if (enabled)
1709         {
1710             ANGLE_GL_TRY(context, mFunctions->enable(cap));
1711         }
1712         else
1713         {
1714             ANGLE_GL_TRY(context, mFunctions->disable(cap));
1715         }
1716         mPrimitiveRestartEnabled = enabled;
1717 
1718         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1719     }
1720 
1721     return angle::Result::Continue;
1722 }
1723 
setPrimitiveRestartIndex(const gl::Context * context,GLuint index)1724 angle::Result StateManagerGL::setPrimitiveRestartIndex(const gl::Context *context, GLuint index)
1725 {
1726     if (mPrimitiveRestartIndex != index)
1727     {
1728         ANGLE_GL_TRY(context, mFunctions->primitiveRestartIndex(index));
1729         mPrimitiveRestartIndex = index;
1730 
1731         // No dirty bit for this state, it is not exposed to the frontend.
1732     }
1733 
1734     return angle::Result::Continue;
1735 }
1736 
setClearDepth(float clearDepth)1737 void StateManagerGL::setClearDepth(float clearDepth)
1738 {
1739     if (mClearDepth != clearDepth)
1740     {
1741         mClearDepth = clearDepth;
1742 
1743         // The glClearDepthf function isn't available until OpenGL 4.1.  Prefer it when it is
1744         // available because OpenGL ES only works in floats.
1745         if (mFunctions->clearDepthf)
1746         {
1747             mFunctions->clearDepthf(mClearDepth);
1748         }
1749         else
1750         {
1751             ASSERT(mFunctions->clearDepth);
1752             mFunctions->clearDepth(mClearDepth);
1753         }
1754 
1755         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
1756     }
1757 }
1758 
setClearColor(const gl::ColorF & clearColor)1759 void StateManagerGL::setClearColor(const gl::ColorF &clearColor)
1760 {
1761     gl::ColorF modifiedClearColor = clearColor;
1762     if (mFeatures.clearToZeroOrOneBroken.enabled &&
1763         (clearColor.red == 1.0f || clearColor.red == 0.0f) &&
1764         (clearColor.green == 1.0f || clearColor.green == 0.0f) &&
1765         (clearColor.blue == 1.0f || clearColor.blue == 0.0f) &&
1766         (clearColor.alpha == 1.0f || clearColor.alpha == 0.0f))
1767     {
1768         if (clearColor.alpha == 1.0f)
1769         {
1770             modifiedClearColor.alpha = 2.0f;
1771         }
1772         else
1773         {
1774             modifiedClearColor.alpha = -1.0f;
1775         }
1776     }
1777 
1778     if (mClearColor != modifiedClearColor)
1779     {
1780         mClearColor = modifiedClearColor;
1781         mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue,
1782                                mClearColor.alpha);
1783 
1784         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
1785     }
1786 }
1787 
setClearStencil(GLint clearStencil)1788 void StateManagerGL::setClearStencil(GLint clearStencil)
1789 {
1790     if (mClearStencil != clearStencil)
1791     {
1792         mClearStencil = clearStencil;
1793         mFunctions->clearStencil(mClearStencil);
1794 
1795         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
1796     }
1797 }
1798 
syncState(const gl::Context * context,const gl::State::DirtyBits & glDirtyBits,const gl::State::DirtyBits & bitMask)1799 angle::Result StateManagerGL::syncState(const gl::Context *context,
1800                                         const gl::State::DirtyBits &glDirtyBits,
1801                                         const gl::State::DirtyBits &bitMask)
1802 {
1803     const gl::State &state = context->getState();
1804 
1805     const gl::State::DirtyBits glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits) & bitMask;
1806     if (!glAndLocalDirtyBits.any())
1807     {
1808         return angle::Result::Continue;
1809     }
1810 
1811     // TODO(jmadill): Investigate only syncing vertex state for active attributes
1812     for (auto iter = glAndLocalDirtyBits.begin(), endIter = glAndLocalDirtyBits.end();
1813          iter != endIter; ++iter)
1814     {
1815         switch (*iter)
1816         {
1817             case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
1818                 setScissorTestEnabled(state.isScissorTestEnabled());
1819                 break;
1820             case gl::State::DIRTY_BIT_SCISSOR:
1821             {
1822                 const gl::Rectangle &scissor = state.getScissor();
1823                 setScissor(scissor);
1824             }
1825             break;
1826             case gl::State::DIRTY_BIT_VIEWPORT:
1827             {
1828                 const gl::Rectangle &viewport = state.getViewport();
1829                 setViewport(viewport);
1830             }
1831             break;
1832             case gl::State::DIRTY_BIT_DEPTH_RANGE:
1833                 setDepthRange(state.getNearPlane(), state.getFarPlane());
1834                 break;
1835             case gl::State::DIRTY_BIT_BLEND_ENABLED:
1836                 if (mIndependentBlendStates)
1837                 {
1838                     setBlendEnabledIndexed(state.getBlendEnabledDrawBufferMask());
1839                 }
1840                 else
1841                 {
1842                     setBlendEnabled(state.isBlendEnabled());
1843                 }
1844                 break;
1845             case gl::State::DIRTY_BIT_BLEND_COLOR:
1846                 setBlendColor(state.getBlendColor());
1847                 break;
1848             case gl::State::DIRTY_BIT_BLEND_FUNCS:
1849             {
1850                 setBlendFuncs(state.getBlendStateExt());
1851                 break;
1852             }
1853             case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
1854             {
1855                 setBlendEquations(state.getBlendStateExt());
1856                 break;
1857             }
1858             case gl::State::DIRTY_BIT_COLOR_MASK:
1859             {
1860                 const gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1861                 const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1862                 const bool disableAlphaWrite =
1863                     framebufferGL->hasEmulatedAlphaChannelTextureAttachment();
1864 
1865                 setColorMaskForFramebuffer(state.getBlendStateExt(), disableAlphaWrite);
1866                 break;
1867             }
1868             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
1869                 setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
1870                 break;
1871             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
1872                 setSampleCoverageEnabled(state.isSampleCoverageEnabled());
1873                 break;
1874             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
1875                 setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
1876                 break;
1877             case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
1878                 setDepthTestEnabled(state.isDepthTestEnabled());
1879                 break;
1880             case gl::State::DIRTY_BIT_DEPTH_FUNC:
1881                 setDepthFunc(state.getDepthStencilState().depthFunc);
1882                 break;
1883             case gl::State::DIRTY_BIT_DEPTH_MASK:
1884                 setDepthMask(state.getDepthStencilState().depthMask);
1885                 break;
1886             case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
1887                 setStencilTestEnabled(state.isStencilTestEnabled());
1888                 break;
1889             case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
1890             {
1891                 const auto &depthStencilState = state.getDepthStencilState();
1892                 setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
1893                                      depthStencilState.stencilMask);
1894                 break;
1895             }
1896             case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
1897             {
1898                 const auto &depthStencilState = state.getDepthStencilState();
1899                 setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
1900                                     depthStencilState.stencilBackMask);
1901                 break;
1902             }
1903             case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
1904             {
1905                 const auto &depthStencilState = state.getDepthStencilState();
1906                 setStencilFrontOps(depthStencilState.stencilFail,
1907                                    depthStencilState.stencilPassDepthFail,
1908                                    depthStencilState.stencilPassDepthPass);
1909                 break;
1910             }
1911             case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
1912             {
1913                 const auto &depthStencilState = state.getDepthStencilState();
1914                 setStencilBackOps(depthStencilState.stencilBackFail,
1915                                   depthStencilState.stencilBackPassDepthFail,
1916                                   depthStencilState.stencilBackPassDepthPass);
1917                 break;
1918             }
1919             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
1920                 setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
1921                 break;
1922             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
1923                 setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
1924                 break;
1925             case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
1926                 setCullFaceEnabled(state.isCullFaceEnabled());
1927                 break;
1928             case gl::State::DIRTY_BIT_CULL_FACE:
1929                 setCullFace(state.getRasterizerState().cullMode);
1930                 break;
1931             case gl::State::DIRTY_BIT_FRONT_FACE:
1932                 setFrontFace(state.getRasterizerState().frontFace);
1933                 break;
1934             case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
1935                 setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
1936                 break;
1937             case gl::State::DIRTY_BIT_POLYGON_OFFSET:
1938             {
1939                 const auto &rasterizerState = state.getRasterizerState();
1940                 setPolygonOffset(rasterizerState.polygonOffsetFactor,
1941                                  rasterizerState.polygonOffsetUnits);
1942                 break;
1943             }
1944             case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
1945                 setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
1946                 break;
1947             case gl::State::DIRTY_BIT_LINE_WIDTH:
1948                 setLineWidth(state.getLineWidth());
1949                 break;
1950             case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
1951                 ANGLE_TRY(setPrimitiveRestartEnabled(context, state.isPrimitiveRestartEnabled()));
1952                 break;
1953             case gl::State::DIRTY_BIT_CLEAR_COLOR:
1954                 setClearColor(state.getColorClearValue());
1955                 break;
1956             case gl::State::DIRTY_BIT_CLEAR_DEPTH:
1957                 setClearDepth(state.getDepthClearValue());
1958                 break;
1959             case gl::State::DIRTY_BIT_CLEAR_STENCIL:
1960                 setClearStencil(state.getStencilClearValue());
1961                 break;
1962             case gl::State::DIRTY_BIT_UNPACK_STATE:
1963                 ANGLE_TRY(setPixelUnpackState(context, state.getUnpackState()));
1964                 break;
1965             case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
1966                 ANGLE_TRY(setPixelUnpackBuffer(
1967                     context, state.getTargetBuffer(gl::BufferBinding::PixelUnpack)));
1968                 break;
1969             case gl::State::DIRTY_BIT_PACK_STATE:
1970                 ANGLE_TRY(setPixelPackState(context, state.getPackState()));
1971                 break;
1972             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
1973                 ANGLE_TRY(setPixelPackBuffer(context,
1974                                              state.getTargetBuffer(gl::BufferBinding::PixelPack)));
1975                 break;
1976             case gl::State::DIRTY_BIT_DITHER_ENABLED:
1977                 setDitherEnabled(state.isDitherEnabled());
1978                 break;
1979             case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
1980             {
1981                 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
1982 
1983                 // Necessary for an Intel TexImage workaround.
1984                 if (!framebuffer)
1985                     continue;
1986 
1987                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1988                 bindFramebuffer(
1989                     mHasSeparateFramebufferBindings ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER,
1990                     framebufferGL->getFramebufferID());
1991                 break;
1992             }
1993             case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
1994             {
1995                 gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1996 
1997                 // Necessary for an Intel TexImage workaround.
1998                 if (!framebuffer)
1999                     continue;
2000 
2001                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
2002                 bindFramebuffer(
2003                     mHasSeparateFramebufferBindings ? GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER,
2004                     framebufferGL->getFramebufferID());
2005 
2006                 const gl::Program *program = state.getProgram();
2007                 if (program)
2008                 {
2009                     updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
2010                 }
2011 
2012                 // Changing the draw framebuffer binding sometimes requires resetting srgb blending.
2013                 iter.setLaterBit(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2014 
2015                 // If the framebuffer is emulating RGB on top of RGBA, the color mask has to be
2016                 // updated
2017                 iter.setLaterBit(gl::State::DIRTY_BIT_COLOR_MASK);
2018                 break;
2019             }
2020             case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
2021                 // TODO(jmadill): implement this
2022                 break;
2023             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
2024             {
2025                 VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
2026                 bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getNativeState());
2027 
2028                 ANGLE_TRY(propagateProgramToVAO(context, state.getProgram(),
2029                                                 GetImplAs<VertexArrayGL>(state.getVertexArray())));
2030 
2031                 if (mFeatures.syncVertexArraysToDefault.enabled)
2032                 {
2033                     // Re-sync the vertex array because all frontend VAOs share the same backend
2034                     // state. Only sync bits that can be set in ES2.0 or 3.0
2035                     gl::VertexArray::DirtyBits dirtyBits;
2036                     gl::VertexArray::DirtyAttribBitsArray dirtyAttribBits;
2037                     gl::VertexArray::DirtyBindingBitsArray dirtBindingBits;
2038 
2039                     dirtyBits.set(gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
2040                     for (size_t attrib = 0; attrib < mDefaultVAOState.attributes.size(); attrib++)
2041                     {
2042                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_ATTRIB_0 + attrib);
2043                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_ENABLED);
2044                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER);
2045                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER_BUFFER);
2046                     }
2047                     for (size_t binding = 0; binding < mDefaultVAOState.bindings.size(); binding++)
2048                     {
2049                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_BINDING_0 + binding);
2050                         dirtBindingBits[binding].set(gl::VertexArray::DIRTY_BINDING_DIVISOR);
2051                     }
2052 
2053                     ANGLE_TRY(
2054                         vaoGL->syncState(context, dirtyBits, &dirtyAttribBits, &dirtBindingBits));
2055                 }
2056                 break;
2057             }
2058             case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
2059                 updateDrawIndirectBufferBinding(context);
2060                 break;
2061             case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
2062                 updateDispatchIndirectBufferBinding(context);
2063                 break;
2064             case gl::State::DIRTY_BIT_PROGRAM_BINDING:
2065             {
2066                 gl::Program *program = state.getProgram();
2067                 if (program != nullptr)
2068                 {
2069                     useProgram(GetImplAs<ProgramGL>(program)->getProgramID());
2070                 }
2071                 break;
2072             }
2073             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
2074             {
2075                 const gl::Program *program              = state.getProgram();
2076                 const gl::ProgramExecutable *executable = state.getProgramExecutable();
2077 
2078                 if (program && executable)
2079                 {
2080                     iter.setLaterBit(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
2081 
2082                     if (executable->getActiveImagesMask().any())
2083                     {
2084                         iter.setLaterBit(gl::State::DIRTY_BIT_IMAGE_BINDINGS);
2085                     }
2086 
2087                     if (program->getActiveShaderStorageBlockCount() > 0)
2088                     {
2089                         iter.setLaterBit(gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
2090                     }
2091 
2092                     if (program->getActiveUniformBlockCount() > 0)
2093                     {
2094                         iter.setLaterBit(gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
2095                     }
2096 
2097                     if (program->getActiveAtomicCounterBufferCount() > 0)
2098                     {
2099                         iter.setLaterBit(gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
2100                     }
2101 
2102                     if (mIsMultiviewEnabled && program->usesMultiview())
2103                     {
2104                         updateMultiviewBaseViewLayerIndexUniform(
2105                             program, state.getDrawFramebuffer()->getImplementation()->getState());
2106                     }
2107                 }
2108 
2109                 if (!program ||
2110                     !program->getExecutable().hasLinkedShaderStage(gl::ShaderType::Compute))
2111                 {
2112                     ANGLE_TRY(propagateProgramToVAO(
2113                         context, program, GetImplAs<VertexArrayGL>(state.getVertexArray())));
2114                 }
2115                 break;
2116             }
2117             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
2118                 updateProgramTextureBindings(context);
2119                 break;
2120             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
2121                 syncSamplersState(context);
2122                 break;
2123             case gl::State::DIRTY_BIT_IMAGE_BINDINGS:
2124                 updateProgramImageBindings(context);
2125                 break;
2126             case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
2127                 syncTransformFeedbackState(context);
2128                 break;
2129             case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
2130                 updateProgramStorageBufferBindings(context);
2131                 break;
2132             case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
2133                 updateProgramUniformBufferBindings(context);
2134                 break;
2135             case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
2136                 updateProgramAtomicCounterBufferBindings(context);
2137                 break;
2138             case gl::State::DIRTY_BIT_MULTISAMPLING:
2139                 setMultisamplingStateEnabled(state.isMultisamplingEnabled());
2140                 break;
2141             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
2142                 setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
2143                 break;
2144             case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
2145                 setCoverageModulation(state.getCoverageModulation());
2146                 break;
2147             case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE:
2148                 setFramebufferSRGBEnabledForFramebuffer(
2149                     context, state.getFramebufferSRGB(),
2150                     GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
2151                 break;
2152             case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
2153                 setSampleMaskEnabled(state.isSampleMaskEnabled());
2154                 break;
2155             case gl::State::DIRTY_BIT_SAMPLE_MASK:
2156             {
2157                 for (GLuint maskNumber = 0; maskNumber < state.getMaxSampleMaskWords();
2158                      ++maskNumber)
2159                 {
2160                     setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
2161                 }
2162                 break;
2163             }
2164             case gl::State::DIRTY_BIT_CURRENT_VALUES:
2165             {
2166                 gl::AttributesMask combinedMask =
2167                     (state.getAndResetDirtyCurrentValues() | mLocalDirtyCurrentValues);
2168                 mLocalDirtyCurrentValues.reset();
2169 
2170                 for (auto attribIndex : combinedMask)
2171                 {
2172                     setAttributeCurrentData(attribIndex,
2173                                             state.getVertexAttribCurrentValue(attribIndex));
2174                 }
2175                 break;
2176             }
2177             case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
2178                 setProvokingVertex(ToGLenum(state.getProvokingVertex()));
2179                 break;
2180             case gl::State::DIRTY_BIT_EXTENDED:
2181                 // Handling clip distance enabled flags:
2182                 setClipDistancesEnable(state.getEnabledClipDistances());
2183                 // TODO(jmadill): handle mipmap generation hint
2184                 // TODO(jmadill): handle shader derivative hint
2185                 // Nothing to do until EXT_clip_contorl is implemented.
2186                 break;
2187             case gl::State::DIRTY_BIT_SAMPLE_SHADING:
2188                 // Nothing to do until OES_sample_shading is implemented.
2189                 break;
2190             case gl::State::DIRTY_BIT_PATCH_VERTICES:
2191                 // Nothing to do until EXT_tessellation_shader is implemented.
2192                 break;
2193             default:
2194                 UNREACHABLE();
2195                 break;
2196         }
2197     }
2198 
2199     mLocalDirtyBits &= ~(bitMask);
2200 
2201     return angle::Result::Continue;
2202 }
2203 
setFramebufferSRGBEnabled(const gl::Context * context,bool enabled)2204 void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
2205 {
2206     if (!mFramebufferSRGBAvailable)
2207     {
2208         return;
2209     }
2210 
2211     if (mFramebufferSRGBEnabled != enabled)
2212     {
2213         mFramebufferSRGBEnabled = enabled;
2214         if (mFramebufferSRGBEnabled)
2215         {
2216             mFunctions->enable(GL_FRAMEBUFFER_SRGB);
2217         }
2218         else
2219         {
2220             mFunctions->disable(GL_FRAMEBUFFER_SRGB);
2221         }
2222         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2223     }
2224 }
2225 
setFramebufferSRGBEnabledForFramebuffer(const gl::Context * context,bool enabled,const FramebufferGL * framebuffer)2226 void StateManagerGL::setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
2227                                                              bool enabled,
2228                                                              const FramebufferGL *framebuffer)
2229 {
2230     if (framebuffer->isDefault())
2231     {
2232         // Obey the framebuffer sRGB state for blending on all framebuffers except the default
2233         // framebuffer.
2234         // When SRGB blending is enabled, only SRGB capable formats will use it but the default
2235         // framebuffer will always use it if it is enabled.
2236         // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists.
2237         setFramebufferSRGBEnabled(context, false);
2238     }
2239     else
2240     {
2241         setFramebufferSRGBEnabled(context, enabled);
2242     }
2243 }
2244 
setColorMaskForFramebuffer(const gl::BlendStateExt & blendStateExt,const bool disableAlpha)2245 void StateManagerGL::setColorMaskForFramebuffer(const gl::BlendStateExt &blendStateExt,
2246                                                 const bool disableAlpha)
2247 {
2248     bool r, g, b, a;
2249 
2250     // Given that disableAlpha can be true only on macOS backbuffers and color mask is re-synced on
2251     // bound draw framebuffer change, switch all draw buffers color masks to avoid special case
2252     // later.
2253     if (!mIndependentBlendStates || disableAlpha)
2254     {
2255         blendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2256         setColorMask(r, g, b, disableAlpha ? false : a);
2257         return;
2258     }
2259 
2260     // Check if the current mask already matches the new state
2261     if (mBlendStateExt.mColorMask == blendStateExt.mColorMask)
2262     {
2263         return;
2264     }
2265 
2266     // Get DrawBufferMask of buffers with different color masks
2267     gl::DrawBufferMask diffMask = mBlendStateExt.compareColorMask(blendStateExt.mColorMask);
2268     size_t diffCount            = diffMask.count();
2269 
2270     // Check if setting all buffers to the same value reduces the number of subsequent indexed
2271     // commands. Implicitly handles the case when the new mask is the same for all buffers.
2272     // For instance, let's say that previously synced mask is ccccff00 and the new state is
2273     // ffeeeeee. Instead of calling colorMaski 8 times, ANGLE can set all buffers to `e` and then
2274     // use colorMaski only twice. On the other hand, if the new state is cceeee00, a non-indexed
2275     // call will increase the total number of GL commands.
2276     if (diffCount > 1)
2277     {
2278         bool found                                                = false;
2279         gl::BlendStateExt::ColorMaskStorage::Type commonColorMask = 0;
2280         for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
2281         {
2282             const gl::BlendStateExt::ColorMaskStorage::Type tempCommonColorMask =
2283                 blendStateExt.expandColorMaskIndexed(i);
2284             const gl::DrawBufferMask tempDiffMask =
2285                 blendStateExt.compareColorMask(tempCommonColorMask);
2286             const size_t tempDiffCount = tempDiffMask.count();
2287             if (tempDiffCount < diffCount)
2288             {
2289                 found           = true;
2290                 diffMask        = tempDiffMask;
2291                 diffCount       = tempDiffCount;
2292                 commonColorMask = tempCommonColorMask;
2293                 if (tempDiffCount == 0)
2294                 {
2295                     break;  // the new mask is the same for all buffers
2296                 }
2297             }
2298         }
2299         if (found)
2300         {
2301             gl::BlendStateExt::UnpackColorMask(commonColorMask, &r, &g, &b, &a);
2302             mFunctions->colorMask(r, g, b, a);
2303         }
2304     }
2305 
2306     for (size_t drawBufferIndex : diffMask)
2307     {
2308         blendStateExt.getColorMaskIndexed(drawBufferIndex, &r, &g, &b, &a);
2309         mFunctions->colorMaski(static_cast<GLuint>(drawBufferIndex), r, g, b, a);
2310     }
2311 
2312     mBlendStateExt.mColorMask = blendStateExt.mColorMask;
2313     mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
2314 }
2315 
setDitherEnabled(bool enabled)2316 void StateManagerGL::setDitherEnabled(bool enabled)
2317 {
2318     if (mDitherEnabled != enabled)
2319     {
2320         mDitherEnabled = enabled;
2321         if (mDitherEnabled)
2322         {
2323             mFunctions->enable(GL_DITHER);
2324         }
2325         else
2326         {
2327             mFunctions->disable(GL_DITHER);
2328         }
2329     }
2330 }
2331 
setMultisamplingStateEnabled(bool enabled)2332 void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
2333 {
2334     if (mMultisamplingEnabled != enabled)
2335     {
2336         mMultisamplingEnabled = enabled;
2337         if (mMultisamplingEnabled)
2338         {
2339             mFunctions->enable(GL_MULTISAMPLE_EXT);
2340         }
2341         else
2342         {
2343             mFunctions->disable(GL_MULTISAMPLE_EXT);
2344         }
2345         mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
2346     }
2347 }
2348 
setSampleAlphaToOneStateEnabled(bool enabled)2349 void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
2350 {
2351     if (mSampleAlphaToOneEnabled != enabled)
2352     {
2353         mSampleAlphaToOneEnabled = enabled;
2354         if (mSampleAlphaToOneEnabled)
2355         {
2356             mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
2357         }
2358         else
2359         {
2360             mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
2361         }
2362         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
2363     }
2364 }
2365 
setCoverageModulation(GLenum components)2366 void StateManagerGL::setCoverageModulation(GLenum components)
2367 {
2368     if (mCoverageModulation != components)
2369     {
2370         mCoverageModulation = components;
2371         mFunctions->coverageModulationNV(components);
2372 
2373         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COVERAGE_MODULATION);
2374     }
2375 }
2376 
setProvokingVertex(GLenum mode)2377 void StateManagerGL::setProvokingVertex(GLenum mode)
2378 {
2379     if (mode != mProvokingVertex)
2380     {
2381         mFunctions->provokingVertex(mode);
2382         mProvokingVertex = mode;
2383 
2384         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROVOKING_VERTEX);
2385     }
2386 }
2387 
setClipDistancesEnable(const gl::State::ClipDistanceEnableBits & enables)2388 void StateManagerGL::setClipDistancesEnable(const gl::State::ClipDistanceEnableBits &enables)
2389 {
2390     if (enables == mEnabledClipDistances)
2391     {
2392         return;
2393     }
2394     ASSERT(mMaxClipDistances <= gl::IMPLEMENTATION_MAX_CLIP_DISTANCES);
2395 
2396     gl::State::ClipDistanceEnableBits diff = enables ^ mEnabledClipDistances;
2397     for (size_t i : diff)
2398     {
2399         if (enables.test(i))
2400         {
2401             mFunctions->enable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2402         }
2403         else
2404         {
2405             mFunctions->disable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2406         }
2407     }
2408 
2409     mEnabledClipDistances = enables;
2410     mLocalDirtyBits.set(gl::State::DIRTY_BIT_EXTENDED);
2411 }
2412 
setTextureCubemapSeamlessEnabled(bool enabled)2413 void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
2414 {
2415     // TODO(jmadill): Also check for seamless extension.
2416     if (!mFunctions->isAtLeastGL(gl::Version(3, 2)))
2417     {
2418         return;
2419     }
2420 
2421     if (mTextureCubemapSeamlessEnabled != enabled)
2422     {
2423         mTextureCubemapSeamlessEnabled = enabled;
2424         if (mTextureCubemapSeamlessEnabled)
2425         {
2426             mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2427         }
2428         else
2429         {
2430             mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2431         }
2432     }
2433 }
2434 
propagateProgramToVAO(const gl::Context * context,const gl::Program * program,VertexArrayGL * vao)2435 angle::Result StateManagerGL::propagateProgramToVAO(const gl::Context *context,
2436                                                     const gl::Program *program,
2437                                                     VertexArrayGL *vao)
2438 {
2439     if (vao == nullptr)
2440     {
2441         return angle::Result::Continue;
2442     }
2443 
2444     // Number of views:
2445     if (mIsMultiviewEnabled)
2446     {
2447         int programNumViews = 1;
2448         if (program && program->usesMultiview())
2449         {
2450             programNumViews = program->getNumViews();
2451         }
2452         ANGLE_TRY(vao->applyNumViewsToDivisor(context, programNumViews));
2453     }
2454 
2455     // Attribute enabled mask:
2456     if (program)
2457     {
2458         ANGLE_TRY(vao->applyActiveAttribLocationsMask(
2459             context, program->getExecutable().getActiveAttribLocationsMask()));
2460     }
2461 
2462     return angle::Result::Continue;
2463 }
2464 
updateMultiviewBaseViewLayerIndexUniformImpl(const gl::Program * program,const gl::FramebufferState & drawFramebufferState) const2465 void StateManagerGL::updateMultiviewBaseViewLayerIndexUniformImpl(
2466     const gl::Program *program,
2467     const gl::FramebufferState &drawFramebufferState) const
2468 {
2469     ASSERT(mIsMultiviewEnabled && program && program->usesMultiview());
2470     const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
2471     if (drawFramebufferState.isMultiview())
2472     {
2473         programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
2474     }
2475 }
2476 
syncSamplersState(const gl::Context * context)2477 void StateManagerGL::syncSamplersState(const gl::Context *context)
2478 {
2479     const gl::SamplerBindingVector &samplers = context->getState().getSamplers();
2480 
2481     // This could be optimized by using a separate binding dirty bit per sampler.
2482     for (size_t samplerIndex = 0; samplerIndex < samplers.size(); ++samplerIndex)
2483     {
2484         const gl::Sampler *sampler = samplers[samplerIndex].get();
2485         if (sampler != nullptr)
2486         {
2487             SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
2488             bindSampler(samplerIndex, samplerGL->getSamplerID());
2489         }
2490         else
2491         {
2492             bindSampler(samplerIndex, 0);
2493         }
2494     }
2495 }
2496 
syncTransformFeedbackState(const gl::Context * context)2497 void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
2498 {
2499     // Set the current transform feedback state
2500     gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
2501     if (transformFeedback)
2502     {
2503         TransformFeedbackGL *transformFeedbackGL =
2504             GetImplAs<TransformFeedbackGL>(transformFeedback);
2505         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
2506         transformFeedbackGL->syncActiveState(context, transformFeedback->isActive(),
2507                                              transformFeedback->getPrimitiveMode());
2508         transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
2509         mCurrentTransformFeedback = transformFeedbackGL;
2510     }
2511     else
2512     {
2513         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
2514         mCurrentTransformFeedback = nullptr;
2515     }
2516 }
2517 
getDefaultVAO() const2518 GLuint StateManagerGL::getDefaultVAO() const
2519 {
2520     return mDefaultVAO;
2521 }
2522 
getDefaultVAOState()2523 VertexArrayStateGL *StateManagerGL::getDefaultVAOState()
2524 {
2525     return &mDefaultVAOState;
2526 }
2527 
validateState() const2528 void StateManagerGL::validateState() const
2529 {
2530     // Current program
2531     ValidateStateHelper(mFunctions, mProgram, GL_CURRENT_PROGRAM, "mProgram", "GL_CURRENT_PROGRAM");
2532 
2533     // Buffers
2534     for (gl::BufferBinding bindingType : angle::AllEnums<gl::BufferBinding>())
2535     {
2536         // These binding types need compute support to be queried
2537         if (bindingType == gl::BufferBinding::AtomicCounter ||
2538             bindingType == gl::BufferBinding::DispatchIndirect ||
2539             bindingType == gl::BufferBinding::ShaderStorage)
2540         {
2541             if (!nativegl::SupportsCompute(mFunctions))
2542             {
2543                 continue;
2544             }
2545         }
2546 
2547         // Transform feedback buffer bindings are tracked in TransformFeedbackGL
2548         if (bindingType == gl::BufferBinding::TransformFeedback)
2549         {
2550             continue;
2551         }
2552 
2553         GLenum bindingTypeGL  = nativegl::GetBufferBindingQuery(bindingType);
2554         std::string localName = "mBuffers[" + ToString(bindingType) + "]";
2555         ValidateStateHelper(mFunctions, mBuffers[bindingType], bindingTypeGL, localName.c_str(),
2556                             nativegl::GetBufferBindingString(bindingType).c_str());
2557     }
2558 
2559     // Vertex array object
2560     ValidateStateHelper(mFunctions, mVAO, GL_VERTEX_ARRAY_BINDING, "mVAO",
2561                         "GL_VERTEX_ARRAY_BINDING");
2562 }
2563 
2564 template <>
get(GLenum name,GLboolean * value)2565 void StateManagerGL::get(GLenum name, GLboolean *value)
2566 {
2567     mFunctions->getBooleanv(name, value);
2568 }
2569 
2570 template <>
get(GLenum name,bool * value)2571 void StateManagerGL::get(GLenum name, bool *value)
2572 {
2573     GLboolean v;
2574     get(name, &v);
2575     *value = (v == GL_TRUE);
2576 }
2577 
2578 template <>
get(GLenum name,std::array<bool,4> * values)2579 void StateManagerGL::get(GLenum name, std::array<bool, 4> *values)
2580 {
2581     GLboolean v[4];
2582     get(name, v);
2583     for (size_t i = 0; i < 4; i++)
2584     {
2585         (*values)[i] = (v[i] == GL_TRUE);
2586     }
2587 }
2588 
2589 template <>
get(GLenum name,GLint * value)2590 void StateManagerGL::get(GLenum name, GLint *value)
2591 {
2592     mFunctions->getIntegerv(name, value);
2593 }
2594 
2595 template <>
get(GLenum name,GLenum * value)2596 void StateManagerGL::get(GLenum name, GLenum *value)
2597 {
2598     GLint v;
2599     get(name, &v);
2600     *value = static_cast<GLenum>(v);
2601 }
2602 
2603 template <>
get(GLenum name,gl::Rectangle * rect)2604 void StateManagerGL::get(GLenum name, gl::Rectangle *rect)
2605 {
2606     GLint v[4];
2607     get(name, v);
2608     *rect = gl::Rectangle(v[0], v[1], v[2], v[3]);
2609 }
2610 
2611 template <>
get(GLenum name,GLfloat * value)2612 void StateManagerGL::get(GLenum name, GLfloat *value)
2613 {
2614     mFunctions->getFloatv(name, value);
2615 }
2616 
2617 template <>
get(GLenum name,gl::ColorF * color)2618 void StateManagerGL::get(GLenum name, gl::ColorF *color)
2619 {
2620     GLfloat v[4];
2621     get(name, v);
2622     *color = gl::ColorF(v[0], v[1], v[2], v[3]);
2623 }
2624 
syncFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2625 void StateManagerGL::syncFromNativeContext(const gl::Extensions &extensions,
2626                                            ExternalContextState *state)
2627 {
2628     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2629 
2630     get(GL_VIEWPORT, &state->viewport);
2631     if (mViewport != state->viewport)
2632     {
2633         mViewport = state->viewport;
2634         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
2635     }
2636 
2637     get(GL_SCISSOR_TEST, &state->scissorTest);
2638     if (mScissorTestEnabled != static_cast<bool>(state->scissorTest))
2639     {
2640         mScissorTestEnabled = state->scissorTest;
2641         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
2642     }
2643 
2644     get(GL_SCISSOR_BOX, &state->scissorBox);
2645     if (mScissor != state->scissorBox)
2646     {
2647         mScissor = state->scissorBox;
2648         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
2649     }
2650 
2651     get(GL_DEPTH_TEST, &state->depthTest);
2652     if (mDepthTestEnabled != state->depthTest)
2653     {
2654         mDepthTestEnabled = state->depthTest;
2655         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
2656     }
2657 
2658     get(GL_CULL_FACE, &state->cullFace);
2659     if (mCullFaceEnabled != state->cullFace)
2660     {
2661         mCullFaceEnabled = state->cullFace;
2662         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
2663     }
2664 
2665     get(GL_CULL_FACE_MODE, &state->cullFaceMode);
2666     if (mCullFace != gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode))
2667     {
2668         mCullFace = gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode);
2669         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
2670     }
2671 
2672     get(GL_COLOR_WRITEMASK, &state->colorMask);
2673     auto colorMask = mBlendStateExt.expandColorMaskValue(state->colorMask[0], state->colorMask[1],
2674                                                          state->colorMask[2], state->colorMask[3]);
2675     if (mBlendStateExt.mColorMask != colorMask)
2676     {
2677         mBlendStateExt.mColorMask = colorMask;
2678         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
2679     }
2680 
2681     get(GL_CURRENT_PROGRAM, &state->currentProgram);
2682     if (mProgram != static_cast<GLuint>(state->currentProgram))
2683     {
2684         mProgram = state->currentProgram;
2685         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
2686     }
2687 
2688     get(GL_COLOR_CLEAR_VALUE, &state->colorClear);
2689     if (mClearColor != state->colorClear)
2690     {
2691         mClearColor = state->colorClear;
2692         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
2693     }
2694 
2695     get(GL_DEPTH_CLEAR_VALUE, &state->depthClear);
2696     if (mClearDepth != state->depthClear)
2697     {
2698         mClearDepth = state->depthClear;
2699         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
2700     }
2701 
2702     get(GL_DEPTH_FUNC, &state->depthFunc);
2703     if (mDepthFunc != static_cast<GLenum>(state->depthFunc))
2704     {
2705         mDepthFunc = state->depthFunc;
2706         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
2707     }
2708 
2709     get(GL_DEPTH_WRITEMASK, &state->depthMask);
2710     if (mDepthMask != state->depthMask)
2711     {
2712         mDepthMask = state->depthMask;
2713         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
2714     }
2715 
2716     get(GL_DEPTH_RANGE, state->depthRage);
2717     if (mNear != state->depthRage[0] || mFar != state->depthRage[1])
2718     {
2719         mNear = state->depthRage[0];
2720         mFar  = state->depthRage[1];
2721         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
2722     }
2723 
2724     get(GL_FRONT_FACE, &state->frontFace);
2725     if (mFrontFace != static_cast<GLenum>(state->frontFace))
2726     {
2727         mFrontFace = state->frontFace;
2728         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
2729     }
2730 
2731     get(GL_LINE_WIDTH, &state->lineWidth);
2732     if (mLineWidth != state->lineWidth)
2733     {
2734         mLineWidth = state->lineWidth;
2735         mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
2736     }
2737 
2738     get(GL_POLYGON_OFFSET_FACTOR, &state->polygonOffsetFactor);
2739     get(GL_POLYGON_OFFSET_UNITS, &state->polygonOffsetUnits);
2740     if (mPolygonOffsetFactor != state->polygonOffsetFactor ||
2741         mPolygonOffsetUnits != state->polygonOffsetUnits)
2742     {
2743         mPolygonOffsetFactor = state->polygonOffsetFactor;
2744         mPolygonOffsetUnits  = state->polygonOffsetUnits;
2745         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
2746     }
2747 
2748     get(GL_SAMPLE_COVERAGE_VALUE, &state->sampleCoverageValue);
2749     get(GL_SAMPLE_COVERAGE_INVERT, &state->sampleCoverageInvert);
2750     if (mSampleCoverageValue != state->sampleCoverageValue ||
2751         mSampleCoverageInvert != state->sampleCoverageInvert)
2752     {
2753         mSampleCoverageValue  = state->sampleCoverageValue;
2754         mSampleCoverageInvert = state->sampleCoverageInvert;
2755         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
2756     }
2757 
2758     get(GL_DITHER, &state->enableDither);
2759     if (mDitherEnabled != state->enableDither)
2760     {
2761         mDitherEnabled = state->enableDither;
2762         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DITHER_ENABLED);
2763     }
2764 
2765     get(GL_POLYGON_OFFSET_FILL, &state->enablePolygonOffsetFill);
2766     if (mPolygonOffsetFillEnabled != state->enablePolygonOffsetFill)
2767     {
2768         mPolygonOffsetFillEnabled = state->enablePolygonOffsetFill;
2769         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
2770     }
2771 
2772     get(GL_SAMPLE_ALPHA_TO_COVERAGE, &state->enableSampleAlphaToCoverage);
2773     if (mSampleAlphaToOneEnabled != state->enableSampleAlphaToCoverage)
2774     {
2775         mSampleAlphaToOneEnabled = state->enableSampleAlphaToCoverage;
2776         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
2777     }
2778 
2779     get(GL_SAMPLE_COVERAGE, &state->enableSampleCoverage);
2780     if (mSampleCoverageEnabled != state->enableSampleCoverage)
2781     {
2782         mSampleCoverageEnabled = state->enableSampleCoverage;
2783         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
2784     }
2785 
2786     if (extensions.multisampleCompatibilityEXT)
2787     {
2788         get(GL_MULTISAMPLE, &state->multisampleEnabled);
2789         if (mMultisamplingEnabled != state->multisampleEnabled)
2790         {
2791             mMultisamplingEnabled = state->multisampleEnabled;
2792             mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
2793         }
2794     }
2795 
2796     syncBlendFromNativeContext(extensions, state);
2797     syncFramebufferFromNativeContext(extensions, state);
2798     syncPixelPackUnpackFromNativeContext(extensions, state);
2799     syncStencilFromNativeContext(extensions, state);
2800     syncVertexArraysFromNativeContext(extensions, state);
2801     syncBufferBindingsFromNativeContext(extensions, state);
2802     syncTextureUnitsFromNativeContext(extensions, state);
2803 
2804     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2805 }
2806 
restoreNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2807 void StateManagerGL::restoreNativeContext(const gl::Extensions &extensions,
2808                                           const ExternalContextState *state)
2809 {
2810     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2811 
2812     setViewport(state->viewport);
2813 
2814     setScissorTestEnabled(state->scissorTest);
2815     setScissor(state->scissorBox);
2816 
2817     setDepthTestEnabled(state->depthTest);
2818 
2819     setCullFaceEnabled(state->cullFace);
2820     setCullFace(gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode));
2821 
2822     setColorMask(state->colorMask[0], state->colorMask[1], state->colorMask[2],
2823                  state->colorMask[3]);
2824 
2825     forceUseProgram(state->currentProgram);
2826 
2827     setClearColor(state->colorClear);
2828 
2829     setClearDepth(state->depthClear);
2830     setDepthFunc(state->depthFunc);
2831     setDepthMask(state->depthMask);
2832     setDepthRange(state->depthRage[0], state->depthRage[1]);
2833 
2834     setFrontFace(state->frontFace);
2835 
2836     setLineWidth(state->lineWidth);
2837 
2838     setPolygonOffset(state->polygonOffsetFactor, state->polygonOffsetUnits);
2839 
2840     setSampleCoverage(state->sampleCoverageValue, state->sampleCoverageInvert);
2841 
2842     setDitherEnabled(state->enableDither);
2843 
2844     setPolygonOffsetFillEnabled(state->enablePolygonOffsetFill);
2845 
2846     setSampleAlphaToOneStateEnabled(state->enableSampleAlphaToCoverage);
2847 
2848     setSampleCoverageEnabled(state->enableSampleCoverage);
2849 
2850     if (extensions.multisampleCompatibilityEXT)
2851         setMultisamplingStateEnabled(state->multisampleEnabled);
2852 
2853     restoreBlendNativeContext(extensions, state);
2854     restoreFramebufferNativeContext(extensions, state);
2855     restorePixelPackUnpackNativeContext(extensions, state);
2856     restoreStencilNativeContext(extensions, state);
2857     restoreVertexArraysNativeContext(extensions, state);
2858     restoreBufferBindingsNativeContext(extensions, state);
2859     restoreTextureUnitsNativeContext(extensions, state);
2860 
2861     // if (mFunctions->coverageModulationNV) ?
2862     setCoverageModulation(GL_NONE);
2863 
2864     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2865 }
2866 
syncBlendFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2867 void StateManagerGL::syncBlendFromNativeContext(const gl::Extensions &extensions,
2868                                                 ExternalContextState *state)
2869 {
2870     get(GL_BLEND, &state->blendEnabled);
2871     if (mBlendStateExt.mEnabledMask !=
2872         (state->blendEnabled ? mBlendStateExt.mMaxEnabledMask : gl::DrawBufferMask::Zero()))
2873     {
2874         mBlendStateExt.setEnabled(state->blendEnabled);
2875         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
2876     }
2877 
2878     get(GL_BLEND_SRC_RGB, &state->blendSrcRgb);
2879     get(GL_BLEND_DST_RGB, &state->blendDestRgb);
2880     get(GL_BLEND_SRC_ALPHA, &state->blendSrcAlpha);
2881     get(GL_BLEND_DST_ALPHA, &state->blendDestAlpha);
2882     if (mBlendStateExt.mSrcColor != static_cast<uint64_t>(state->blendSrcRgb) ||
2883         mBlendStateExt.mDstColor != static_cast<uint64_t>(state->blendDestRgb) ||
2884         mBlendStateExt.mSrcAlpha != static_cast<uint64_t>(state->blendSrcAlpha) ||
2885         mBlendStateExt.mDstAlpha != static_cast<uint64_t>(state->blendDestAlpha))
2886     {
2887         mBlendStateExt.mSrcColor = state->blendSrcRgb;
2888         mBlendStateExt.mDstColor = state->blendDestRgb;
2889         mBlendStateExt.mSrcAlpha = state->blendSrcAlpha;
2890         mBlendStateExt.mDstAlpha = state->blendDestAlpha;
2891         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
2892     }
2893 
2894     get(GL_BLEND_COLOR, &state->blendColor);
2895     if (mBlendColor != state->blendColor)
2896     {
2897         mBlendColor = state->blendColor;
2898         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
2899     }
2900 
2901     get(GL_BLEND_EQUATION_RGB, &state->blendEquationRgb);
2902     get(GL_BLEND_EQUATION_ALPHA, &state->blendEquationAlpha);
2903 }
2904 
restoreBlendNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2905 void StateManagerGL::restoreBlendNativeContext(const gl::Extensions &extensions,
2906                                                const ExternalContextState *state)
2907 {
2908     setBlendEnabled(state->blendEnabled);
2909     // TODO: use setBlendFuncs()
2910     mFunctions->blendFuncSeparate(state->blendSrcRgb, state->blendDestRgb, state->blendSrcAlpha,
2911                                   state->blendDestAlpha);
2912     mBlendStateExt.mSrcColor = state->blendSrcRgb;
2913     mBlendStateExt.mDstColor = state->blendDestRgb;
2914     mBlendStateExt.mSrcAlpha = state->blendSrcAlpha;
2915     mBlendStateExt.mDstAlpha = state->blendDestAlpha;
2916     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
2917 
2918     setBlendColor(state->blendColor);
2919 
2920     // TODO: use setBlendEquations()
2921     mFunctions->blendEquationSeparate(state->blendEquationRgb, state->blendEquationAlpha);
2922     mBlendStateExt.mEquationColor = state->blendEquationRgb;
2923     mBlendStateExt.mEquationAlpha = state->blendEquationAlpha;
2924     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_EQUATIONS);
2925 }
2926 
syncFramebufferFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2927 void StateManagerGL::syncFramebufferFromNativeContext(const gl::Extensions &extensions,
2928                                                       ExternalContextState *state)
2929 {
2930     // TODO: wrap fbo into an EGLSurface
2931     get(GL_FRAMEBUFFER_BINDING, &state->framebufferBinding);
2932     if (mFramebuffers[angle::FramebufferBindingDraw] !=
2933         static_cast<GLenum>(state->framebufferBinding))
2934     {
2935         mFramebuffers[angle::FramebufferBindingDraw] =
2936             static_cast<GLenum>(state->framebufferBinding);
2937         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
2938     }
2939     if (mFramebuffers[angle::FramebufferBindingRead] !=
2940         static_cast<GLenum>(state->framebufferBinding))
2941     {
2942         mFramebuffers[angle::FramebufferBindingRead] =
2943             static_cast<GLenum>(state->framebufferBinding);
2944         mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
2945     }
2946 }
2947 
restoreFramebufferNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2948 void StateManagerGL::restoreFramebufferNativeContext(const gl::Extensions &extensions,
2949                                                      const ExternalContextState *state)
2950 {
2951     bindFramebuffer(GL_FRAMEBUFFER, state->framebufferBinding);
2952 }
2953 
syncPixelPackUnpackFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2954 void StateManagerGL::syncPixelPackUnpackFromNativeContext(const gl::Extensions &extensions,
2955                                                           ExternalContextState *state)
2956 {
2957     get(GL_PACK_ALIGNMENT, &state->packAlignment);
2958     if (mPackAlignment != state->packAlignment)
2959     {
2960         mPackAlignment = state->packAlignment;
2961         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
2962     }
2963 
2964     get(GL_UNPACK_ALIGNMENT, &state->unpackAlignment);
2965     if (mUnpackAlignment != state->unpackAlignment)
2966     {
2967         mUnpackAlignment = state->unpackAlignment;
2968         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
2969     }
2970 }
2971 
restorePixelPackUnpackNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2972 void StateManagerGL::restorePixelPackUnpackNativeContext(const gl::Extensions &extensions,
2973                                                          const ExternalContextState *state)
2974 {
2975     if (mPackAlignment != state->packAlignment)
2976     {
2977         mFunctions->pixelStorei(GL_PACK_ALIGNMENT, state->packAlignment);
2978         mPackAlignment = state->packAlignment;
2979         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
2980     }
2981 
2982     if (mUnpackAlignment != state->unpackAlignment)
2983     {
2984         mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, state->unpackAlignment);
2985         mUnpackAlignment = state->unpackAlignment;
2986         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
2987     }
2988 }
2989 
syncStencilFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2990 void StateManagerGL::syncStencilFromNativeContext(const gl::Extensions &extensions,
2991                                                   ExternalContextState *state)
2992 {
2993     get(GL_STENCIL_TEST, &state->stencilState.stencilTestEnabled);
2994     if (state->stencilState.stencilTestEnabled != mStencilTestEnabled)
2995     {
2996         mStencilTestEnabled = state->stencilState.stencilTestEnabled;
2997         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
2998     }
2999 
3000     get(GL_STENCIL_FUNC, &state->stencilState.stencilFrontFunc);
3001     get(GL_STENCIL_VALUE_MASK, &state->stencilState.stencilFrontMask);
3002     get(GL_STENCIL_REF, &state->stencilState.stencilFrontRef);
3003     if (state->stencilState.stencilFrontFunc != mStencilFrontFunc ||
3004         state->stencilState.stencilFrontMask != mStencilFrontValueMask ||
3005         state->stencilState.stencilFrontRef != mStencilFrontRef)
3006     {
3007         mStencilFrontFunc      = state->stencilState.stencilFrontFunc;
3008         mStencilFrontValueMask = state->stencilState.stencilFrontMask;
3009         mStencilFrontRef       = state->stencilState.stencilFrontRef;
3010         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
3011     }
3012 
3013     get(GL_STENCIL_BACK_FUNC, &state->stencilState.stencilBackFunc);
3014     get(GL_STENCIL_BACK_VALUE_MASK, &state->stencilState.stencilBackMask);
3015     get(GL_STENCIL_BACK_REF, &state->stencilState.stencilBackRef);
3016     if (state->stencilState.stencilBackFunc != mStencilBackFunc ||
3017         state->stencilState.stencilBackMask != mStencilBackValueMask ||
3018         state->stencilState.stencilBackRef != mStencilBackRef)
3019     {
3020         mStencilBackFunc      = state->stencilState.stencilBackFunc;
3021         mStencilBackValueMask = state->stencilState.stencilBackMask;
3022         mStencilBackRef       = state->stencilState.stencilBackRef;
3023         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
3024     }
3025 
3026     get(GL_STENCIL_CLEAR_VALUE, &state->stencilState.stencilClear);
3027     if (mClearStencil != state->stencilState.stencilClear)
3028     {
3029         mClearStencil = state->stencilState.stencilClear;
3030         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
3031     }
3032 
3033     get(GL_STENCIL_WRITEMASK, &state->stencilState.stencilFrontWritemask);
3034     if (mStencilFrontWritemask != static_cast<GLenum>(state->stencilState.stencilFrontWritemask))
3035     {
3036         mStencilFrontWritemask = state->stencilState.stencilFrontWritemask;
3037         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3038     }
3039 
3040     get(GL_STENCIL_BACK_WRITEMASK, &state->stencilState.stencilBackWritemask);
3041     if (mStencilBackWritemask != static_cast<GLenum>(state->stencilState.stencilBackWritemask))
3042     {
3043         mStencilBackWritemask = state->stencilState.stencilBackWritemask;
3044         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3045     }
3046 
3047     get(GL_STENCIL_FAIL, &state->stencilState.stencilFrontFailOp);
3048     get(GL_STENCIL_PASS_DEPTH_FAIL, &state->stencilState.stencilFrontZFailOp);
3049     get(GL_STENCIL_PASS_DEPTH_PASS, &state->stencilState.stencilFrontZPassOp);
3050     if (mStencilFrontStencilFailOp != static_cast<GLenum>(state->stencilState.stencilFrontFailOp) ||
3051         mStencilFrontStencilPassDepthFailOp !=
3052             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp) ||
3053         mStencilFrontStencilPassDepthPassOp !=
3054             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp))
3055     {
3056         mStencilFrontStencilFailOp = static_cast<GLenum>(state->stencilState.stencilFrontFailOp);
3057         mStencilFrontStencilPassDepthFailOp =
3058             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp);
3059         mStencilFrontStencilPassDepthPassOp =
3060             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp);
3061         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
3062     }
3063 
3064     get(GL_STENCIL_BACK_FAIL, &state->stencilState.stencilBackFailOp);
3065     get(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &state->stencilState.stencilBackZFailOp);
3066     get(GL_STENCIL_BACK_PASS_DEPTH_PASS, &state->stencilState.stencilBackZPassOp);
3067     if (mStencilBackStencilFailOp != static_cast<GLenum>(state->stencilState.stencilBackFailOp) ||
3068         mStencilBackStencilPassDepthFailOp !=
3069             static_cast<GLenum>(state->stencilState.stencilBackZFailOp) ||
3070         mStencilBackStencilPassDepthPassOp !=
3071             static_cast<GLenum>(state->stencilState.stencilBackZPassOp))
3072     {
3073         mStencilBackStencilFailOp = static_cast<GLenum>(state->stencilState.stencilBackFailOp);
3074         mStencilBackStencilPassDepthFailOp =
3075             static_cast<GLenum>(state->stencilState.stencilBackZFailOp);
3076         mStencilBackStencilPassDepthPassOp =
3077             static_cast<GLenum>(state->stencilState.stencilBackZPassOp);
3078         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
3079     }
3080 }
3081 
restoreStencilNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3082 void StateManagerGL::restoreStencilNativeContext(const gl::Extensions &extensions,
3083                                                  const ExternalContextState *state)
3084 {
3085     setStencilTestEnabled(state->stencilState.stencilTestEnabled);
3086     setStencilFrontFuncs(state->stencilState.stencilFrontFunc, state->stencilState.stencilFrontMask,
3087                          state->stencilState.stencilFrontRef);
3088     setStencilBackFuncs(state->stencilState.stencilBackFunc, state->stencilState.stencilBackMask,
3089                         state->stencilState.stencilBackRef);
3090     setClearStencil(state->stencilState.stencilClear);
3091     setStencilFrontWritemask(state->stencilState.stencilFrontWritemask);
3092     setStencilBackWritemask(state->stencilState.stencilBackWritemask);
3093     setStencilFrontOps(state->stencilState.stencilFrontFailOp,
3094                        state->stencilState.stencilFrontZFailOp,
3095                        state->stencilState.stencilFrontZPassOp);
3096     setStencilBackOps(state->stencilState.stencilBackFailOp, state->stencilState.stencilBackZFailOp,
3097                       state->stencilState.stencilBackZPassOp);
3098 }
3099 
syncBufferBindingsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3100 void StateManagerGL::syncBufferBindingsFromNativeContext(const gl::Extensions &extensions,
3101                                                          ExternalContextState *state)
3102 {
3103     get(GL_ARRAY_BUFFER_BINDING, &state->vertexArrayBufferBinding);
3104     mBuffers[gl::BufferBinding::Array] = state->vertexArrayBufferBinding;
3105 
3106     get(GL_ELEMENT_ARRAY_BUFFER_BINDING, &state->elementArrayBufferBinding);
3107     mBuffers[gl::BufferBinding::ElementArray] = state->elementArrayBufferBinding;
3108 }
3109 
restoreBufferBindingsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3110 void StateManagerGL::restoreBufferBindingsNativeContext(const gl::Extensions &extensions,
3111                                                         const ExternalContextState *state)
3112 {
3113     bindBuffer(gl::BufferBinding::Array, state->vertexArrayBufferBinding);
3114     bindBuffer(gl::BufferBinding::ElementArray, state->elementArrayBufferBinding);
3115 }
3116 
syncTextureUnitsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3117 void StateManagerGL::syncTextureUnitsFromNativeContext(const gl::Extensions &extensions,
3118                                                        ExternalContextState *state)
3119 {
3120     get(GL_ACTIVE_TEXTURE, &state->activeTexture);
3121 
3122     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3123     {
3124         auto &bindings = state->textureBindings[i];
3125         activeTexture(i);
3126         get(GL_TEXTURE_BINDING_2D, &bindings.texture2d);
3127         get(GL_TEXTURE_BINDING_CUBE_MAP, &bindings.textureCubeMap);
3128         get(GL_TEXTURE_BINDING_EXTERNAL_OES, &bindings.textureExternalOES);
3129         if (mTextures[gl::TextureType::_2D][i] != static_cast<GLuint>(bindings.texture2d) ||
3130             mTextures[gl::TextureType::CubeMap][i] !=
3131                 static_cast<GLuint>(bindings.textureCubeMap) ||
3132             mTextures[gl::TextureType::External][i] !=
3133                 static_cast<GLuint>(bindings.textureExternalOES))
3134         {
3135             mTextures[gl::TextureType::_2D][i]      = bindings.texture2d;
3136             mTextures[gl::TextureType::CubeMap][i]  = bindings.textureCubeMap;
3137             mTextures[gl::TextureType::External][i] = bindings.textureExternalOES;
3138             mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
3139         }
3140     }
3141 }
3142 
restoreTextureUnitsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3143 void StateManagerGL::restoreTextureUnitsNativeContext(const gl::Extensions &extensions,
3144                                                       const ExternalContextState *state)
3145 {
3146     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3147     {
3148         const auto &bindings = state->textureBindings[i];
3149         activeTexture(i);
3150         bindTexture(gl::TextureType::_2D, bindings.texture2d);
3151         bindTexture(gl::TextureType::CubeMap, bindings.textureCubeMap);
3152         bindTexture(gl::TextureType::External, bindings.textureExternalOES);
3153         bindSampler(i, 0);
3154     }
3155     activeTexture(state->activeTexture - GL_TEXTURE0);
3156 }
3157 
syncVertexArraysFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3158 void StateManagerGL::syncVertexArraysFromNativeContext(const gl::Extensions &extensions,
3159                                                        ExternalContextState *state)
3160 {
3161     get(GL_VERTEX_ARRAY_BINDING, &state->vertexArrayBinding);
3162     if (mVAO != static_cast<GLuint>(state->vertexArrayBinding))
3163     {
3164         mVAO                                      = state->vertexArrayBinding;
3165         mBuffers[gl::BufferBinding::ElementArray] = 0;
3166         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3167     }
3168 }
3169 
restoreVertexArraysNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3170 void StateManagerGL::restoreVertexArraysNativeContext(const gl::Extensions &extensions,
3171                                                       const ExternalContextState *state)
3172 {
3173     bindVertexArray(state->vertexArrayBinding, 0);
3174 }
3175 
setDefaultVAOStateDirty()3176 void StateManagerGL::setDefaultVAOStateDirty()
3177 {
3178     mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3179 }
3180 
3181 }  // namespace rx
3182