• 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.sRGBWriteControl),
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.multiview || extensions.multiview2),
159       mProvokingVertex(GL_LAST_VERTEX_CONVENTION),
160       mMaxClipDistances(rendererCaps.maxClipDistances),
161       mLocalDirtyBits()
162 {
163     ASSERT(mFunctions);
164     ASSERT(extensions.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             ASSERT(!texture->hasAnyDirtyBit());
929             ASSERT(!textureGL->hasAnyDirtyBit());
930 
931             activeTexture(textureUnitIndex);
932             bindTexture(textureType, textureGL->getTextureID());
933         }
934         else
935         {
936             activeTexture(textureUnitIndex);
937             bindTexture(textureType, 0);
938         }
939     }
940 }
941 
updateProgramStorageBufferBindings(const gl::Context * context)942 void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
943 {
944     const gl::State &glState   = context->getState();
945     const gl::Program *program = glState.getProgram();
946 
947     for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
948          blockIndex++)
949     {
950         GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
951         const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
952 
953         if (shaderStorageBuffer.get() != nullptr)
954         {
955             BufferGL *bufferGL = GetImplAs<BufferGL>(shaderStorageBuffer.get());
956 
957             if (shaderStorageBuffer.getSize() == 0)
958             {
959                 bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
960             }
961             else
962             {
963                 bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
964                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
965             }
966         }
967     }
968 }
969 
updateProgramUniformBufferBindings(const gl::Context * context)970 void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *context)
971 {
972     // Sync the current program state
973     const gl::State &glState   = context->getState();
974     const gl::Program *program = glState.getProgram();
975 
976     for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
977          uniformBlockIndex++)
978     {
979         GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
980         const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
981 
982         if (uniformBuffer.get() != nullptr)
983         {
984             BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
985 
986             if (uniformBuffer.getSize() == 0)
987             {
988                 bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
989             }
990             else
991             {
992                 bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
993                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
994             }
995         }
996     }
997 }
998 
updateProgramAtomicCounterBufferBindings(const gl::Context * context)999 void StateManagerGL::updateProgramAtomicCounterBufferBindings(const gl::Context *context)
1000 {
1001     const gl::State &glState   = context->getState();
1002     const gl::Program *program = glState.getProgram();
1003 
1004     for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
1005     {
1006         GLuint binding     = atomicCounterBuffer.binding;
1007         const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
1008 
1009         if (buffer.get() != nullptr)
1010         {
1011             BufferGL *bufferGL = GetImplAs<BufferGL>(buffer.get());
1012 
1013             if (buffer.getSize() == 0)
1014             {
1015                 bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
1016             }
1017             else
1018             {
1019                 bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
1020                                 buffer.getOffset(), buffer.getSize());
1021             }
1022         }
1023     }
1024 }
1025 
updateProgramImageBindings(const gl::Context * context)1026 void StateManagerGL::updateProgramImageBindings(const gl::Context *context)
1027 {
1028     const gl::State &glState                = context->getState();
1029     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1030     const gl::Program *program              = glState.getProgram();
1031 
1032     // It is possible there is no active program during a path operation.
1033     if (!executable || !program)
1034         return;
1035 
1036     ASSERT(context->getClientVersion() >= gl::ES_3_1 || program->getImageBindings().empty());
1037     for (size_t imageUnitIndex : executable->getActiveImagesMask())
1038     {
1039         const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
1040         const TextureGL *textureGL     = SafeGetImplAs<TextureGL>(imageUnit.texture.get());
1041         if (textureGL)
1042         {
1043             bindImageTexture(imageUnitIndex, textureGL->getTextureID(), imageUnit.level,
1044                              imageUnit.layered, imageUnit.layer, imageUnit.access,
1045                              imageUnit.format);
1046         }
1047         else
1048         {
1049             bindImageTexture(imageUnitIndex, 0, imageUnit.level, imageUnit.layered, imageUnit.layer,
1050                              imageUnit.access, imageUnit.format);
1051         }
1052     }
1053 }
1054 
setAttributeCurrentData(size_t index,const gl::VertexAttribCurrentValueData & data)1055 void StateManagerGL::setAttributeCurrentData(size_t index,
1056                                              const gl::VertexAttribCurrentValueData &data)
1057 {
1058     if (mVertexAttribCurrentValues[index] != data)
1059     {
1060         mVertexAttribCurrentValues[index] = data;
1061         switch (mVertexAttribCurrentValues[index].Type)
1062         {
1063             case gl::VertexAttribType::Float:
1064                 mFunctions->vertexAttrib4fv(static_cast<GLuint>(index),
1065                                             mVertexAttribCurrentValues[index].Values.FloatValues);
1066                 break;
1067             case gl::VertexAttribType::Int:
1068                 mFunctions->vertexAttribI4iv(static_cast<GLuint>(index),
1069                                              mVertexAttribCurrentValues[index].Values.IntValues);
1070                 break;
1071             case gl::VertexAttribType::UnsignedInt:
1072                 mFunctions->vertexAttribI4uiv(
1073                     static_cast<GLuint>(index),
1074                     mVertexAttribCurrentValues[index].Values.UnsignedIntValues);
1075                 break;
1076             default:
1077                 UNREACHABLE();
1078         }
1079 
1080         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUES);
1081         mLocalDirtyCurrentValues.set(index);
1082     }
1083 }
1084 
setScissorTestEnabled(bool enabled)1085 void StateManagerGL::setScissorTestEnabled(bool enabled)
1086 {
1087     if (mScissorTestEnabled != enabled)
1088     {
1089         mScissorTestEnabled = enabled;
1090         if (mScissorTestEnabled)
1091         {
1092             mFunctions->enable(GL_SCISSOR_TEST);
1093         }
1094         else
1095         {
1096             mFunctions->disable(GL_SCISSOR_TEST);
1097         }
1098 
1099         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
1100     }
1101 }
1102 
setScissor(const gl::Rectangle & scissor)1103 void StateManagerGL::setScissor(const gl::Rectangle &scissor)
1104 {
1105     if (scissor != mScissor)
1106     {
1107         mScissor = scissor;
1108         mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height);
1109 
1110         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
1111     }
1112 }
1113 
setViewport(const gl::Rectangle & viewport)1114 void StateManagerGL::setViewport(const gl::Rectangle &viewport)
1115 {
1116     if (viewport != mViewport)
1117     {
1118         mViewport = viewport;
1119         mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height);
1120 
1121         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
1122     }
1123 }
1124 
setDepthRange(float near,float far)1125 void StateManagerGL::setDepthRange(float near, float far)
1126 {
1127     mNear = near;
1128     mFar  = far;
1129 
1130     // The glDepthRangef function isn't available until OpenGL 4.1.  Prefer it when it is
1131     // available because OpenGL ES only works in floats.
1132     if (mFunctions->depthRangef)
1133     {
1134         mFunctions->depthRangef(mNear, mFar);
1135     }
1136     else
1137     {
1138         ASSERT(mFunctions->depthRange);
1139         mFunctions->depthRange(mNear, mFar);
1140     }
1141 
1142     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
1143 }
1144 
setBlendEnabled(bool enabled)1145 void StateManagerGL::setBlendEnabled(bool enabled)
1146 {
1147     const gl::DrawBufferMask mask =
1148         enabled ? mBlendStateExt.mMaxEnabledMask : gl::DrawBufferMask::Zero();
1149     if (mBlendStateExt.mEnabledMask == mask)
1150     {
1151         return;
1152     }
1153 
1154     if (enabled)
1155     {
1156         mFunctions->enable(GL_BLEND);
1157     }
1158     else
1159     {
1160         mFunctions->disable(GL_BLEND);
1161     }
1162 
1163     mBlendStateExt.setEnabled(enabled);
1164     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
1165 }
1166 
setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)1167 void StateManagerGL::setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)
1168 {
1169     if (mBlendStateExt.mEnabledMask == enabledMask)
1170     {
1171         return;
1172     }
1173 
1174     // Get DrawBufferMask of buffers with different blend enable state
1175     gl::DrawBufferMask diffMask = mBlendStateExt.mEnabledMask ^ enabledMask;
1176     const size_t diffCount      = diffMask.count();
1177 
1178     // Check if enabling or disabling blending for all buffers reduces the number of subsequent
1179     // indexed commands. Implicitly handles the case when the new blend enable state is the same for
1180     // all buffers.
1181     if (diffCount > 1)
1182     {
1183         // The number of indexed blend enable commands in case a mass disable is used.
1184         const size_t enabledCount = enabledMask.count();
1185 
1186         // The mask and the number of indexed blend disable commands in case a mass enable is used.
1187         const gl::DrawBufferMask disabledMask = enabledMask ^ mBlendStateExt.mMaxEnabledMask;
1188         const size_t disabledCount            = disabledMask.count();
1189 
1190         if (enabledCount < diffCount && enabledCount <= disabledCount)
1191         {
1192             diffMask = enabledMask;
1193             mFunctions->disable(GL_BLEND);
1194         }
1195         else if (disabledCount < diffCount && disabledCount <= enabledCount)
1196         {
1197             diffMask = disabledMask;
1198             mFunctions->enable(GL_BLEND);
1199         }
1200     }
1201 
1202     for (size_t drawBufferIndex : diffMask)
1203     {
1204         if (enabledMask.test(drawBufferIndex))
1205         {
1206             mFunctions->enablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1207         }
1208         else
1209         {
1210             mFunctions->disablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1211         }
1212     }
1213 
1214     mBlendStateExt.mEnabledMask = enabledMask;
1215     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
1216 }
1217 
setBlendColor(const gl::ColorF & blendColor)1218 void StateManagerGL::setBlendColor(const gl::ColorF &blendColor)
1219 {
1220     if (mBlendColor != blendColor)
1221     {
1222         mBlendColor = blendColor;
1223         mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue,
1224                                mBlendColor.alpha);
1225 
1226         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
1227     }
1228 }
1229 
setBlendFuncs(const gl::BlendStateExt & blendStateExt)1230 void StateManagerGL::setBlendFuncs(const gl::BlendStateExt &blendStateExt)
1231 {
1232     if (mBlendStateExt.mSrcColor == blendStateExt.mSrcColor &&
1233         mBlendStateExt.mDstColor == blendStateExt.mDstColor &&
1234         mBlendStateExt.mSrcAlpha == blendStateExt.mSrcAlpha &&
1235         mBlendStateExt.mDstAlpha == blendStateExt.mDstAlpha)
1236     {
1237         return;
1238     }
1239 
1240     if (!mIndependentBlendStates)
1241     {
1242         mFunctions->blendFuncSeparate(
1243             blendStateExt.getSrcColorIndexed(0), blendStateExt.getDstColorIndexed(0),
1244             blendStateExt.getSrcAlphaIndexed(0), blendStateExt.getDstAlphaIndexed(0));
1245     }
1246     else
1247     {
1248         // Get DrawBufferMask of buffers with different blend factors
1249         gl::DrawBufferMask diffMask =
1250             mBlendStateExt.compareFactors(blendStateExt.mSrcColor, blendStateExt.mDstColor,
1251                                           blendStateExt.mSrcAlpha, blendStateExt.mDstAlpha);
1252         size_t diffCount = diffMask.count();
1253 
1254         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1255         // commands. Implicitly handles the case when the new blend function state is the same for
1256         // all buffers.
1257         if (diffCount > 1)
1258         {
1259             bool found                                            = false;
1260             gl::BlendStateExt::FactorStorage::Type commonSrcColor = 0;
1261             gl::BlendStateExt::FactorStorage::Type commonDstColor = 0;
1262             gl::BlendStateExt::FactorStorage::Type commonSrcAlpha = 0;
1263             gl::BlendStateExt::FactorStorage::Type commonDstAlpha = 0;
1264             for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
1265             {
1266                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcColor =
1267                     blendStateExt.expandSrcColorIndexed(i);
1268                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstColor =
1269                     blendStateExt.expandDstColorIndexed(i);
1270                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcAlpha =
1271                     blendStateExt.expandSrcAlphaIndexed(i);
1272                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstAlpha =
1273                     blendStateExt.expandDstAlphaIndexed(i);
1274 
1275                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareFactors(
1276                     tempCommonSrcColor, tempCommonDstColor, tempCommonSrcAlpha, tempCommonDstAlpha);
1277 
1278                 const size_t tempDiffCount = tempDiffMask.count();
1279                 if (tempDiffCount < diffCount)
1280                 {
1281                     found          = true;
1282                     diffMask       = tempDiffMask;
1283                     diffCount      = tempDiffCount;
1284                     commonSrcColor = tempCommonSrcColor;
1285                     commonDstColor = tempCommonDstColor;
1286                     commonSrcAlpha = tempCommonSrcAlpha;
1287                     commonDstAlpha = tempCommonDstAlpha;
1288                     if (tempDiffCount == 0)
1289                     {
1290                         break;  // the blend factors are the same for all buffers
1291                     }
1292                 }
1293             }
1294             if (found)
1295             {
1296                 mFunctions->blendFuncSeparate(
1297                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcColor)),
1298                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstColor)),
1299                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcAlpha)),
1300                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstAlpha)));
1301             }
1302         }
1303 
1304         for (size_t drawBufferIndex : diffMask)
1305         {
1306             mFunctions->blendFuncSeparatei(static_cast<GLuint>(drawBufferIndex),
1307                                            blendStateExt.getSrcColorIndexed(drawBufferIndex),
1308                                            blendStateExt.getDstColorIndexed(drawBufferIndex),
1309                                            blendStateExt.getSrcAlphaIndexed(drawBufferIndex),
1310                                            blendStateExt.getDstAlphaIndexed(drawBufferIndex));
1311         }
1312     }
1313     mBlendStateExt.mSrcColor = blendStateExt.mSrcColor;
1314     mBlendStateExt.mDstColor = blendStateExt.mDstColor;
1315     mBlendStateExt.mSrcAlpha = blendStateExt.mSrcAlpha;
1316     mBlendStateExt.mDstAlpha = blendStateExt.mDstAlpha;
1317     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
1318 }
1319 
setBlendEquations(const gl::BlendStateExt & blendStateExt)1320 void StateManagerGL::setBlendEquations(const gl::BlendStateExt &blendStateExt)
1321 {
1322     if (mBlendStateExt.mEquationColor == blendStateExt.mEquationColor &&
1323         mBlendStateExt.mEquationAlpha == blendStateExt.mEquationAlpha)
1324     {
1325         return;
1326     }
1327 
1328     if (!mIndependentBlendStates)
1329     {
1330         mFunctions->blendEquationSeparate(blendStateExt.getEquationColorIndexed(0),
1331                                           blendStateExt.getEquationAlphaIndexed(0));
1332     }
1333     else
1334     {
1335         // Get DrawBufferMask of buffers with different blend equations
1336         gl::DrawBufferMask diffMask = mBlendStateExt.compareEquations(blendStateExt.mEquationColor,
1337                                                                       blendStateExt.mEquationAlpha);
1338         size_t diffCount            = diffMask.count();
1339 
1340         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1341         // commands. Implicitly handles the case when the new blend equation state is the same for
1342         // all buffers.
1343         if (diffCount > 1)
1344         {
1345             bool found                                                   = false;
1346             gl::BlendStateExt::EquationStorage::Type commonEquationColor = 0;
1347             gl::BlendStateExt::EquationStorage::Type commonEquationAlpha = 0;
1348             for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
1349             {
1350                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationColor =
1351                     blendStateExt.expandEquationColorIndexed(i);
1352                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationAlpha =
1353                     blendStateExt.expandEquationAlphaIndexed(i);
1354 
1355                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareEquations(
1356                     tempCommonEquationColor, tempCommonEquationAlpha);
1357 
1358                 const size_t tempDiffCount = tempDiffMask.count();
1359                 if (tempDiffCount < diffCount)
1360                 {
1361                     found               = true;
1362                     diffMask            = tempDiffMask;
1363                     diffCount           = tempDiffCount;
1364                     commonEquationColor = tempCommonEquationColor;
1365                     commonEquationAlpha = tempCommonEquationAlpha;
1366                     if (tempDiffCount == 0)
1367                     {
1368                         break;  // the new blend equations are the same for all buffers
1369                     }
1370                 }
1371             }
1372             if (found)
1373             {
1374                 mFunctions->blendEquationSeparate(
1375                     ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1376                         0, commonEquationColor)),
1377                     ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1378                         0, commonEquationAlpha)));
1379             }
1380         }
1381 
1382         for (size_t drawBufferIndex : diffMask)
1383         {
1384             mFunctions->blendEquationSeparatei(
1385                 static_cast<GLuint>(drawBufferIndex),
1386                 blendStateExt.getEquationColorIndexed(drawBufferIndex),
1387                 blendStateExt.getEquationAlphaIndexed(drawBufferIndex));
1388         }
1389     }
1390     mBlendStateExt.mEquationColor = blendStateExt.mEquationColor;
1391     mBlendStateExt.mEquationAlpha = blendStateExt.mEquationAlpha;
1392     mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
1393 }
1394 
setColorMask(bool red,bool green,bool blue,bool alpha)1395 void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha)
1396 {
1397     const gl::BlendStateExt::ColorMaskStorage::Type mask =
1398         mBlendStateExt.expandColorMaskValue(red, green, blue, alpha);
1399     if (mBlendStateExt.mColorMask != mask)
1400     {
1401         mFunctions->colorMask(red, green, blue, alpha);
1402         mBlendStateExt.mColorMask = mask;
1403         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
1404     }
1405 }
1406 
setSampleAlphaToCoverageEnabled(bool enabled)1407 void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled)
1408 {
1409     if (mSampleAlphaToCoverageEnabled != enabled)
1410     {
1411         mSampleAlphaToCoverageEnabled = enabled;
1412         if (mSampleAlphaToCoverageEnabled)
1413         {
1414             mFunctions->enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1415         }
1416         else
1417         {
1418             mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1419         }
1420 
1421         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1422     }
1423 }
1424 
setSampleCoverageEnabled(bool enabled)1425 void StateManagerGL::setSampleCoverageEnabled(bool enabled)
1426 {
1427     if (mSampleCoverageEnabled != enabled)
1428     {
1429         mSampleCoverageEnabled = enabled;
1430         if (mSampleCoverageEnabled)
1431         {
1432             mFunctions->enable(GL_SAMPLE_COVERAGE);
1433         }
1434         else
1435         {
1436             mFunctions->disable(GL_SAMPLE_COVERAGE);
1437         }
1438 
1439         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1440     }
1441 }
1442 
setSampleCoverage(float value,bool invert)1443 void StateManagerGL::setSampleCoverage(float value, bool invert)
1444 {
1445     if (mSampleCoverageValue != value || mSampleCoverageInvert != invert)
1446     {
1447         mSampleCoverageValue  = value;
1448         mSampleCoverageInvert = invert;
1449         mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert);
1450 
1451         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
1452     }
1453 }
1454 
setSampleMaskEnabled(bool enabled)1455 void StateManagerGL::setSampleMaskEnabled(bool enabled)
1456 {
1457     if (mSampleMaskEnabled != enabled)
1458     {
1459         mSampleMaskEnabled = enabled;
1460         if (mSampleMaskEnabled)
1461         {
1462             mFunctions->enable(GL_SAMPLE_MASK);
1463         }
1464         else
1465         {
1466             mFunctions->disable(GL_SAMPLE_MASK);
1467         }
1468 
1469         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED);
1470     }
1471 }
1472 
setSampleMaski(GLuint maskNumber,GLbitfield mask)1473 void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
1474 {
1475     ASSERT(maskNumber < mSampleMaskValues.size());
1476     if (mSampleMaskValues[maskNumber] != mask)
1477     {
1478         mSampleMaskValues[maskNumber] = mask;
1479         mFunctions->sampleMaski(maskNumber, mask);
1480 
1481         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK);
1482     }
1483 }
1484 
1485 // Depth and stencil redundant state changes are guarded in the
1486 // frontend so for related cases here just set the dirty bit
1487 // and update backend states.
setDepthTestEnabled(bool enabled)1488 void StateManagerGL::setDepthTestEnabled(bool enabled)
1489 {
1490     mDepthTestEnabled = enabled;
1491     if (mDepthTestEnabled)
1492     {
1493         mFunctions->enable(GL_DEPTH_TEST);
1494     }
1495     else
1496     {
1497         mFunctions->disable(GL_DEPTH_TEST);
1498     }
1499 
1500     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
1501 }
1502 
setDepthFunc(GLenum depthFunc)1503 void StateManagerGL::setDepthFunc(GLenum depthFunc)
1504 {
1505     mDepthFunc = depthFunc;
1506     mFunctions->depthFunc(mDepthFunc);
1507 
1508     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
1509 }
1510 
setDepthMask(bool mask)1511 void StateManagerGL::setDepthMask(bool mask)
1512 {
1513     mDepthMask = mask;
1514     mFunctions->depthMask(mDepthMask);
1515 
1516     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
1517 }
1518 
setStencilTestEnabled(bool enabled)1519 void StateManagerGL::setStencilTestEnabled(bool enabled)
1520 {
1521     mStencilTestEnabled = enabled;
1522     if (mStencilTestEnabled)
1523     {
1524         mFunctions->enable(GL_STENCIL_TEST);
1525     }
1526     else
1527     {
1528         mFunctions->disable(GL_STENCIL_TEST);
1529     }
1530 
1531     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
1532 }
1533 
setStencilFrontWritemask(GLuint mask)1534 void StateManagerGL::setStencilFrontWritemask(GLuint mask)
1535 {
1536     mStencilFrontWritemask = mask;
1537     mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask);
1538 
1539     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
1540 }
1541 
setStencilBackWritemask(GLuint mask)1542 void StateManagerGL::setStencilBackWritemask(GLuint mask)
1543 {
1544     mStencilBackWritemask = mask;
1545     mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask);
1546 
1547     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
1548 }
1549 
setStencilFrontFuncs(GLenum func,GLint ref,GLuint mask)1550 void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask)
1551 {
1552     mStencilFrontFunc      = func;
1553     mStencilFrontRef       = ref;
1554     mStencilFrontValueMask = mask;
1555     mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef,
1556                                     mStencilFrontValueMask);
1557 
1558     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
1559 }
1560 
setStencilBackFuncs(GLenum func,GLint ref,GLuint mask)1561 void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask)
1562 {
1563     mStencilBackFunc      = func;
1564     mStencilBackRef       = ref;
1565     mStencilBackValueMask = mask;
1566     mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef,
1567                                     mStencilBackValueMask);
1568 
1569     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
1570 }
1571 
setStencilFrontOps(GLenum sfail,GLenum dpfail,GLenum dppass)1572 void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1573 {
1574     mStencilFrontStencilFailOp          = sfail;
1575     mStencilFrontStencilPassDepthFailOp = dpfail;
1576     mStencilFrontStencilPassDepthPassOp = dppass;
1577     mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp,
1578                                   mStencilFrontStencilPassDepthFailOp,
1579                                   mStencilFrontStencilPassDepthPassOp);
1580 
1581     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
1582 }
1583 
setStencilBackOps(GLenum sfail,GLenum dpfail,GLenum dppass)1584 void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1585 {
1586     mStencilBackStencilFailOp          = sfail;
1587     mStencilBackStencilPassDepthFailOp = dpfail;
1588     mStencilBackStencilPassDepthPassOp = dppass;
1589     mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp,
1590                                   mStencilBackStencilPassDepthFailOp,
1591                                   mStencilBackStencilPassDepthPassOp);
1592 
1593     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
1594 }
1595 
setCullFaceEnabled(bool enabled)1596 void StateManagerGL::setCullFaceEnabled(bool enabled)
1597 {
1598     if (mCullFaceEnabled != enabled)
1599     {
1600         mCullFaceEnabled = enabled;
1601         if (mCullFaceEnabled)
1602         {
1603             mFunctions->enable(GL_CULL_FACE);
1604         }
1605         else
1606         {
1607             mFunctions->disable(GL_CULL_FACE);
1608         }
1609 
1610         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
1611     }
1612 }
1613 
setCullFace(gl::CullFaceMode cullFace)1614 void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
1615 {
1616     if (mCullFace != cullFace)
1617     {
1618         mCullFace = cullFace;
1619         mFunctions->cullFace(ToGLenum(mCullFace));
1620 
1621         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
1622     }
1623 }
1624 
setFrontFace(GLenum frontFace)1625 void StateManagerGL::setFrontFace(GLenum frontFace)
1626 {
1627     if (mFrontFace != frontFace)
1628     {
1629         mFrontFace = frontFace;
1630         mFunctions->frontFace(mFrontFace);
1631 
1632         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
1633     }
1634 }
1635 
setPolygonOffsetFillEnabled(bool enabled)1636 void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled)
1637 {
1638     if (mPolygonOffsetFillEnabled != enabled)
1639     {
1640         mPolygonOffsetFillEnabled = enabled;
1641         if (mPolygonOffsetFillEnabled)
1642         {
1643             mFunctions->enable(GL_POLYGON_OFFSET_FILL);
1644         }
1645         else
1646         {
1647             mFunctions->disable(GL_POLYGON_OFFSET_FILL);
1648         }
1649 
1650         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1651     }
1652 }
1653 
setPolygonOffset(float factor,float units)1654 void StateManagerGL::setPolygonOffset(float factor, float units)
1655 {
1656     if (mPolygonOffsetFactor != factor || mPolygonOffsetUnits != units)
1657     {
1658         mPolygonOffsetFactor = factor;
1659         mPolygonOffsetUnits  = units;
1660         mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits);
1661 
1662         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
1663     }
1664 }
1665 
setRasterizerDiscardEnabled(bool enabled)1666 void StateManagerGL::setRasterizerDiscardEnabled(bool enabled)
1667 {
1668     if (mRasterizerDiscardEnabled != enabled)
1669     {
1670         mRasterizerDiscardEnabled = enabled;
1671         if (mRasterizerDiscardEnabled)
1672         {
1673             mFunctions->enable(GL_RASTERIZER_DISCARD);
1674         }
1675         else
1676         {
1677             mFunctions->disable(GL_RASTERIZER_DISCARD);
1678         }
1679 
1680         mLocalDirtyBits.set(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
1681     }
1682 }
1683 
setLineWidth(float width)1684 void StateManagerGL::setLineWidth(float width)
1685 {
1686     if (mLineWidth != width)
1687     {
1688         mLineWidth = width;
1689         mFunctions->lineWidth(mLineWidth);
1690 
1691         mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
1692     }
1693 }
1694 
setPrimitiveRestartEnabled(const gl::Context * context,bool enabled)1695 angle::Result StateManagerGL::setPrimitiveRestartEnabled(const gl::Context *context, bool enabled)
1696 {
1697     if (mPrimitiveRestartEnabled != enabled)
1698     {
1699         GLenum cap = mFeatures.emulatePrimitiveRestartFixedIndex.enabled
1700                          ? GL_PRIMITIVE_RESTART
1701                          : GL_PRIMITIVE_RESTART_FIXED_INDEX;
1702 
1703         if (enabled)
1704         {
1705             ANGLE_GL_TRY(context, mFunctions->enable(cap));
1706         }
1707         else
1708         {
1709             ANGLE_GL_TRY(context, mFunctions->disable(cap));
1710         }
1711         mPrimitiveRestartEnabled = enabled;
1712 
1713         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1714     }
1715 
1716     return angle::Result::Continue;
1717 }
1718 
setPrimitiveRestartIndex(const gl::Context * context,GLuint index)1719 angle::Result StateManagerGL::setPrimitiveRestartIndex(const gl::Context *context, GLuint index)
1720 {
1721     if (mPrimitiveRestartIndex != index)
1722     {
1723         ANGLE_GL_TRY(context, mFunctions->primitiveRestartIndex(index));
1724         mPrimitiveRestartIndex = index;
1725 
1726         // No dirty bit for this state, it is not exposed to the frontend.
1727     }
1728 
1729     return angle::Result::Continue;
1730 }
1731 
setClearDepth(float clearDepth)1732 void StateManagerGL::setClearDepth(float clearDepth)
1733 {
1734     if (mClearDepth != clearDepth)
1735     {
1736         mClearDepth = clearDepth;
1737 
1738         // The glClearDepthf function isn't available until OpenGL 4.1.  Prefer it when it is
1739         // available because OpenGL ES only works in floats.
1740         if (mFunctions->clearDepthf)
1741         {
1742             mFunctions->clearDepthf(mClearDepth);
1743         }
1744         else
1745         {
1746             ASSERT(mFunctions->clearDepth);
1747             mFunctions->clearDepth(mClearDepth);
1748         }
1749 
1750         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
1751     }
1752 }
1753 
setClearColor(const gl::ColorF & clearColor)1754 void StateManagerGL::setClearColor(const gl::ColorF &clearColor)
1755 {
1756     gl::ColorF modifiedClearColor = clearColor;
1757     if (mFeatures.clearToZeroOrOneBroken.enabled &&
1758         (clearColor.red == 1.0f || clearColor.red == 0.0f) &&
1759         (clearColor.green == 1.0f || clearColor.green == 0.0f) &&
1760         (clearColor.blue == 1.0f || clearColor.blue == 0.0f) &&
1761         (clearColor.alpha == 1.0f || clearColor.alpha == 0.0f))
1762     {
1763         if (clearColor.alpha == 1.0f)
1764         {
1765             modifiedClearColor.alpha = 2.0f;
1766         }
1767         else
1768         {
1769             modifiedClearColor.alpha = -1.0f;
1770         }
1771     }
1772 
1773     if (mClearColor != modifiedClearColor)
1774     {
1775         mClearColor = modifiedClearColor;
1776         mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue,
1777                                mClearColor.alpha);
1778 
1779         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
1780     }
1781 }
1782 
setClearStencil(GLint clearStencil)1783 void StateManagerGL::setClearStencil(GLint clearStencil)
1784 {
1785     if (mClearStencil != clearStencil)
1786     {
1787         mClearStencil = clearStencil;
1788         mFunctions->clearStencil(mClearStencil);
1789 
1790         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
1791     }
1792 }
1793 
syncState(const gl::Context * context,const gl::State::DirtyBits & glDirtyBits,const gl::State::DirtyBits & bitMask)1794 angle::Result StateManagerGL::syncState(const gl::Context *context,
1795                                         const gl::State::DirtyBits &glDirtyBits,
1796                                         const gl::State::DirtyBits &bitMask)
1797 {
1798     const gl::State &state = context->getState();
1799 
1800     const gl::State::DirtyBits glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits) & bitMask;
1801     if (!glAndLocalDirtyBits.any())
1802     {
1803         return angle::Result::Continue;
1804     }
1805 
1806     // TODO(jmadill): Investigate only syncing vertex state for active attributes
1807     for (auto iter = glAndLocalDirtyBits.begin(), endIter = glAndLocalDirtyBits.end();
1808          iter != endIter; ++iter)
1809     {
1810         switch (*iter)
1811         {
1812             case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
1813                 setScissorTestEnabled(state.isScissorTestEnabled());
1814                 break;
1815             case gl::State::DIRTY_BIT_SCISSOR:
1816             {
1817                 const gl::Rectangle &scissor = state.getScissor();
1818                 setScissor(scissor);
1819             }
1820             break;
1821             case gl::State::DIRTY_BIT_VIEWPORT:
1822             {
1823                 const gl::Rectangle &viewport = state.getViewport();
1824                 setViewport(viewport);
1825             }
1826             break;
1827             case gl::State::DIRTY_BIT_DEPTH_RANGE:
1828                 setDepthRange(state.getNearPlane(), state.getFarPlane());
1829                 break;
1830             case gl::State::DIRTY_BIT_BLEND_ENABLED:
1831                 if (mIndependentBlendStates)
1832                 {
1833                     setBlendEnabledIndexed(state.getBlendEnabledDrawBufferMask());
1834                 }
1835                 else
1836                 {
1837                     setBlendEnabled(state.isBlendEnabled());
1838                 }
1839                 break;
1840             case gl::State::DIRTY_BIT_BLEND_COLOR:
1841                 setBlendColor(state.getBlendColor());
1842                 break;
1843             case gl::State::DIRTY_BIT_BLEND_FUNCS:
1844             {
1845                 setBlendFuncs(state.getBlendStateExt());
1846                 break;
1847             }
1848             case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
1849             {
1850                 setBlendEquations(state.getBlendStateExt());
1851                 break;
1852             }
1853             case gl::State::DIRTY_BIT_COLOR_MASK:
1854             {
1855                 const gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1856                 const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1857                 const bool disableAlphaWrite =
1858                     framebufferGL->hasEmulatedAlphaChannelTextureAttachment();
1859 
1860                 setColorMaskForFramebuffer(state.getBlendStateExt(), disableAlphaWrite);
1861                 break;
1862             }
1863             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
1864                 setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
1865                 break;
1866             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
1867                 setSampleCoverageEnabled(state.isSampleCoverageEnabled());
1868                 break;
1869             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
1870                 setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
1871                 break;
1872             case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
1873                 setDepthTestEnabled(state.isDepthTestEnabled());
1874                 break;
1875             case gl::State::DIRTY_BIT_DEPTH_FUNC:
1876                 setDepthFunc(state.getDepthStencilState().depthFunc);
1877                 break;
1878             case gl::State::DIRTY_BIT_DEPTH_MASK:
1879                 setDepthMask(state.getDepthStencilState().depthMask);
1880                 break;
1881             case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
1882                 setStencilTestEnabled(state.isStencilTestEnabled());
1883                 break;
1884             case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
1885             {
1886                 const auto &depthStencilState = state.getDepthStencilState();
1887                 setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
1888                                      depthStencilState.stencilMask);
1889                 break;
1890             }
1891             case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
1892             {
1893                 const auto &depthStencilState = state.getDepthStencilState();
1894                 setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
1895                                     depthStencilState.stencilBackMask);
1896                 break;
1897             }
1898             case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
1899             {
1900                 const auto &depthStencilState = state.getDepthStencilState();
1901                 setStencilFrontOps(depthStencilState.stencilFail,
1902                                    depthStencilState.stencilPassDepthFail,
1903                                    depthStencilState.stencilPassDepthPass);
1904                 break;
1905             }
1906             case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
1907             {
1908                 const auto &depthStencilState = state.getDepthStencilState();
1909                 setStencilBackOps(depthStencilState.stencilBackFail,
1910                                   depthStencilState.stencilBackPassDepthFail,
1911                                   depthStencilState.stencilBackPassDepthPass);
1912                 break;
1913             }
1914             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
1915                 setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
1916                 break;
1917             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
1918                 setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
1919                 break;
1920             case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
1921                 setCullFaceEnabled(state.isCullFaceEnabled());
1922                 break;
1923             case gl::State::DIRTY_BIT_CULL_FACE:
1924                 setCullFace(state.getRasterizerState().cullMode);
1925                 break;
1926             case gl::State::DIRTY_BIT_FRONT_FACE:
1927                 setFrontFace(state.getRasterizerState().frontFace);
1928                 break;
1929             case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
1930                 setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
1931                 break;
1932             case gl::State::DIRTY_BIT_POLYGON_OFFSET:
1933             {
1934                 const auto &rasterizerState = state.getRasterizerState();
1935                 setPolygonOffset(rasterizerState.polygonOffsetFactor,
1936                                  rasterizerState.polygonOffsetUnits);
1937                 break;
1938             }
1939             case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
1940                 setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
1941                 break;
1942             case gl::State::DIRTY_BIT_LINE_WIDTH:
1943                 setLineWidth(state.getLineWidth());
1944                 break;
1945             case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
1946                 ANGLE_TRY(setPrimitiveRestartEnabled(context, state.isPrimitiveRestartEnabled()));
1947                 break;
1948             case gl::State::DIRTY_BIT_CLEAR_COLOR:
1949                 setClearColor(state.getColorClearValue());
1950                 break;
1951             case gl::State::DIRTY_BIT_CLEAR_DEPTH:
1952                 setClearDepth(state.getDepthClearValue());
1953                 break;
1954             case gl::State::DIRTY_BIT_CLEAR_STENCIL:
1955                 setClearStencil(state.getStencilClearValue());
1956                 break;
1957             case gl::State::DIRTY_BIT_UNPACK_STATE:
1958                 ANGLE_TRY(setPixelUnpackState(context, state.getUnpackState()));
1959                 break;
1960             case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
1961                 ANGLE_TRY(setPixelUnpackBuffer(
1962                     context, state.getTargetBuffer(gl::BufferBinding::PixelUnpack)));
1963                 break;
1964             case gl::State::DIRTY_BIT_PACK_STATE:
1965                 ANGLE_TRY(setPixelPackState(context, state.getPackState()));
1966                 break;
1967             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
1968                 ANGLE_TRY(setPixelPackBuffer(context,
1969                                              state.getTargetBuffer(gl::BufferBinding::PixelPack)));
1970                 break;
1971             case gl::State::DIRTY_BIT_DITHER_ENABLED:
1972                 setDitherEnabled(state.isDitherEnabled());
1973                 break;
1974             case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
1975             {
1976                 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
1977 
1978                 // Necessary for an Intel TexImage workaround.
1979                 if (!framebuffer)
1980                     continue;
1981 
1982                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1983                 bindFramebuffer(
1984                     mHasSeparateFramebufferBindings ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER,
1985                     framebufferGL->getFramebufferID());
1986                 break;
1987             }
1988             case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
1989             {
1990                 gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1991 
1992                 // Necessary for an Intel TexImage workaround.
1993                 if (!framebuffer)
1994                     continue;
1995 
1996                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1997                 bindFramebuffer(
1998                     mHasSeparateFramebufferBindings ? GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER,
1999                     framebufferGL->getFramebufferID());
2000 
2001                 const gl::Program *program = state.getProgram();
2002                 if (program)
2003                 {
2004                     updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
2005                 }
2006 
2007                 // Changing the draw framebuffer binding sometimes requires resetting srgb blending.
2008                 iter.setLaterBit(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2009 
2010                 // If the framebuffer is emulating RGB on top of RGBA, the color mask has to be
2011                 // updated
2012                 iter.setLaterBit(gl::State::DIRTY_BIT_COLOR_MASK);
2013                 break;
2014             }
2015             case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
2016                 // TODO(jmadill): implement this
2017                 break;
2018             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
2019             {
2020                 VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
2021                 bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getNativeState());
2022 
2023                 propagateProgramToVAO(context, state.getProgram(),
2024                                       GetImplAs<VertexArrayGL>(state.getVertexArray()));
2025 
2026                 if (mFeatures.syncVertexArraysToDefault.enabled)
2027                 {
2028                     // Re-sync the vertex array because all frontend VAOs share the same backend
2029                     // state. Only sync bits that can be set in ES2.0 or 3.0
2030                     gl::VertexArray::DirtyBits dirtyBits;
2031                     gl::VertexArray::DirtyAttribBitsArray dirtyAttribBits;
2032                     gl::VertexArray::DirtyBindingBitsArray dirtBindingBits;
2033 
2034                     dirtyBits.set(gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
2035                     for (size_t attrib = 0; attrib < mDefaultVAOState.attributes.size(); attrib++)
2036                     {
2037                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_ATTRIB_0 + attrib);
2038                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_ENABLED);
2039                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER);
2040                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER_BUFFER);
2041                     }
2042                     for (size_t binding = 0; binding < mDefaultVAOState.bindings.size(); binding++)
2043                     {
2044                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_BINDING_0 + binding);
2045                         dirtBindingBits[binding].set(gl::VertexArray::DIRTY_BINDING_DIVISOR);
2046                     }
2047 
2048                     ANGLE_TRY(
2049                         vaoGL->syncState(context, dirtyBits, &dirtyAttribBits, &dirtBindingBits));
2050                 }
2051                 break;
2052             }
2053             case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
2054                 updateDrawIndirectBufferBinding(context);
2055                 break;
2056             case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
2057                 updateDispatchIndirectBufferBinding(context);
2058                 break;
2059             case gl::State::DIRTY_BIT_PROGRAM_BINDING:
2060             {
2061                 gl::Program *program = state.getProgram();
2062                 if (program != nullptr)
2063                 {
2064                     useProgram(GetImplAs<ProgramGL>(program)->getProgramID());
2065                 }
2066                 break;
2067             }
2068             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
2069             {
2070                 const gl::Program *program              = state.getProgram();
2071                 const gl::ProgramExecutable *executable = state.getProgramExecutable();
2072 
2073                 if (program && executable)
2074                 {
2075                     iter.setLaterBit(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
2076 
2077                     if (executable->getActiveImagesMask().any())
2078                     {
2079                         iter.setLaterBit(gl::State::DIRTY_BIT_IMAGE_BINDINGS);
2080                     }
2081 
2082                     if (program->getActiveShaderStorageBlockCount() > 0)
2083                     {
2084                         iter.setLaterBit(gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
2085                     }
2086 
2087                     if (program->getActiveUniformBlockCount() > 0)
2088                     {
2089                         iter.setLaterBit(gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
2090                     }
2091 
2092                     if (program->getActiveAtomicCounterBufferCount() > 0)
2093                     {
2094                         iter.setLaterBit(gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
2095                     }
2096 
2097                     if (mIsMultiviewEnabled && program->usesMultiview())
2098                     {
2099                         updateMultiviewBaseViewLayerIndexUniform(
2100                             program, state.getDrawFramebuffer()->getImplementation()->getState());
2101                     }
2102                 }
2103 
2104                 if (!program ||
2105                     !program->getExecutable().hasLinkedShaderStage(gl::ShaderType::Compute))
2106                 {
2107                     propagateProgramToVAO(context, program,
2108                                           GetImplAs<VertexArrayGL>(state.getVertexArray()));
2109                 }
2110                 break;
2111             }
2112             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
2113                 updateProgramTextureBindings(context);
2114                 break;
2115             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
2116                 syncSamplersState(context);
2117                 break;
2118             case gl::State::DIRTY_BIT_IMAGE_BINDINGS:
2119                 updateProgramImageBindings(context);
2120                 break;
2121             case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
2122                 syncTransformFeedbackState(context);
2123                 break;
2124             case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
2125                 updateProgramStorageBufferBindings(context);
2126                 break;
2127             case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
2128                 updateProgramUniformBufferBindings(context);
2129                 break;
2130             case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
2131                 updateProgramAtomicCounterBufferBindings(context);
2132                 break;
2133             case gl::State::DIRTY_BIT_MULTISAMPLING:
2134                 setMultisamplingStateEnabled(state.isMultisamplingEnabled());
2135                 break;
2136             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
2137                 setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
2138                 break;
2139             case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
2140                 setCoverageModulation(state.getCoverageModulation());
2141                 break;
2142             case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE:
2143                 setFramebufferSRGBEnabledForFramebuffer(
2144                     context, state.getFramebufferSRGB(),
2145                     GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
2146                 break;
2147             case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
2148                 setSampleMaskEnabled(state.isSampleMaskEnabled());
2149                 break;
2150             case gl::State::DIRTY_BIT_SAMPLE_MASK:
2151             {
2152                 for (GLuint maskNumber = 0; maskNumber < state.getMaxSampleMaskWords();
2153                      ++maskNumber)
2154                 {
2155                     setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
2156                 }
2157                 break;
2158             }
2159             case gl::State::DIRTY_BIT_CURRENT_VALUES:
2160             {
2161                 gl::AttributesMask combinedMask =
2162                     (state.getAndResetDirtyCurrentValues() | mLocalDirtyCurrentValues);
2163                 mLocalDirtyCurrentValues.reset();
2164 
2165                 for (auto attribIndex : combinedMask)
2166                 {
2167                     setAttributeCurrentData(attribIndex,
2168                                             state.getVertexAttribCurrentValue(attribIndex));
2169                 }
2170                 break;
2171             }
2172             case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
2173                 setProvokingVertex(ToGLenum(state.getProvokingVertex()));
2174                 break;
2175             case gl::State::DIRTY_BIT_EXTENDED:
2176                 // Handling clip distance enabled flags:
2177                 setClipDistancesEnable(state.getEnabledClipDistances());
2178                 // TODO(jmadill): handle mipmap generation hint
2179                 // TODO(jmadill): handle shader derivative hint
2180                 // Nothing to do until EXT_clip_contorl is implemented.
2181                 break;
2182             case gl::State::DIRTY_BIT_SAMPLE_SHADING:
2183                 // Nothing to do until OES_sample_shading is implemented.
2184                 break;
2185             case gl::State::DIRTY_BIT_PATCH_VERTICES:
2186                 // Nothing to do until EXT_tessellation_shader is implemented.
2187                 break;
2188             default:
2189                 UNREACHABLE();
2190                 break;
2191         }
2192     }
2193 
2194     mLocalDirtyBits &= ~(bitMask);
2195 
2196     return angle::Result::Continue;
2197 }
2198 
setFramebufferSRGBEnabled(const gl::Context * context,bool enabled)2199 void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
2200 {
2201     if (!mFramebufferSRGBAvailable)
2202     {
2203         return;
2204     }
2205 
2206     if (mFramebufferSRGBEnabled != enabled)
2207     {
2208         mFramebufferSRGBEnabled = enabled;
2209         if (mFramebufferSRGBEnabled)
2210         {
2211             mFunctions->enable(GL_FRAMEBUFFER_SRGB);
2212         }
2213         else
2214         {
2215             mFunctions->disable(GL_FRAMEBUFFER_SRGB);
2216         }
2217         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2218     }
2219 }
2220 
setFramebufferSRGBEnabledForFramebuffer(const gl::Context * context,bool enabled,const FramebufferGL * framebuffer)2221 void StateManagerGL::setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
2222                                                              bool enabled,
2223                                                              const FramebufferGL *framebuffer)
2224 {
2225     if (framebuffer->isDefault())
2226     {
2227         // Obey the framebuffer sRGB state for blending on all framebuffers except the default
2228         // framebuffer.
2229         // When SRGB blending is enabled, only SRGB capable formats will use it but the default
2230         // framebuffer will always use it if it is enabled.
2231         // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists.
2232         setFramebufferSRGBEnabled(context, false);
2233     }
2234     else
2235     {
2236         setFramebufferSRGBEnabled(context, enabled);
2237     }
2238 }
2239 
setColorMaskForFramebuffer(const gl::BlendStateExt & blendStateExt,const bool disableAlpha)2240 void StateManagerGL::setColorMaskForFramebuffer(const gl::BlendStateExt &blendStateExt,
2241                                                 const bool disableAlpha)
2242 {
2243     bool r, g, b, a;
2244 
2245     // Given that disableAlpha can be true only on macOS backbuffers and color mask is re-synced on
2246     // bound draw framebuffer change, switch all draw buffers color masks to avoid special case
2247     // later.
2248     if (!mIndependentBlendStates || disableAlpha)
2249     {
2250         blendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2251         setColorMask(r, g, b, disableAlpha ? false : a);
2252         return;
2253     }
2254 
2255     // Check if the current mask already matches the new state
2256     if (mBlendStateExt.mColorMask == blendStateExt.mColorMask)
2257     {
2258         return;
2259     }
2260 
2261     // Get DrawBufferMask of buffers with different color masks
2262     gl::DrawBufferMask diffMask = mBlendStateExt.compareColorMask(blendStateExt.mColorMask);
2263     size_t diffCount            = diffMask.count();
2264 
2265     // Check if setting all buffers to the same value reduces the number of subsequent indexed
2266     // commands. Implicitly handles the case when the new mask is the same for all buffers.
2267     // For instance, let's say that previously synced mask is ccccff00 and the new state is
2268     // ffeeeeee. Instead of calling colorMaski 8 times, ANGLE can set all buffers to `e` and then
2269     // use colorMaski only twice. On the other hand, if the new state is cceeee00, a non-indexed
2270     // call will increase the total number of GL commands.
2271     if (diffCount > 1)
2272     {
2273         bool found                                                = false;
2274         gl::BlendStateExt::ColorMaskStorage::Type commonColorMask = 0;
2275         for (size_t i = 0; i < mBlendStateExt.mMaxDrawBuffers - 1; i++)
2276         {
2277             const gl::BlendStateExt::ColorMaskStorage::Type tempCommonColorMask =
2278                 blendStateExt.expandColorMaskIndexed(i);
2279             const gl::DrawBufferMask tempDiffMask =
2280                 blendStateExt.compareColorMask(tempCommonColorMask);
2281             const size_t tempDiffCount = tempDiffMask.count();
2282             if (tempDiffCount < diffCount)
2283             {
2284                 found           = true;
2285                 diffMask        = tempDiffMask;
2286                 diffCount       = tempDiffCount;
2287                 commonColorMask = tempCommonColorMask;
2288                 if (tempDiffCount == 0)
2289                 {
2290                     break;  // the new mask is the same for all buffers
2291                 }
2292             }
2293         }
2294         if (found)
2295         {
2296             gl::BlendStateExt::UnpackColorMask(commonColorMask, &r, &g, &b, &a);
2297             mFunctions->colorMask(r, g, b, a);
2298         }
2299     }
2300 
2301     for (size_t drawBufferIndex : diffMask)
2302     {
2303         blendStateExt.getColorMaskIndexed(drawBufferIndex, &r, &g, &b, &a);
2304         mFunctions->colorMaski(static_cast<GLuint>(drawBufferIndex), r, g, b, a);
2305     }
2306 
2307     mBlendStateExt.mColorMask = blendStateExt.mColorMask;
2308     mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
2309 }
2310 
setDitherEnabled(bool enabled)2311 void StateManagerGL::setDitherEnabled(bool enabled)
2312 {
2313     if (mDitherEnabled != enabled)
2314     {
2315         mDitherEnabled = enabled;
2316         if (mDitherEnabled)
2317         {
2318             mFunctions->enable(GL_DITHER);
2319         }
2320         else
2321         {
2322             mFunctions->disable(GL_DITHER);
2323         }
2324     }
2325 }
2326 
setMultisamplingStateEnabled(bool enabled)2327 void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
2328 {
2329     if (mMultisamplingEnabled != enabled)
2330     {
2331         mMultisamplingEnabled = enabled;
2332         if (mMultisamplingEnabled)
2333         {
2334             mFunctions->enable(GL_MULTISAMPLE_EXT);
2335         }
2336         else
2337         {
2338             mFunctions->disable(GL_MULTISAMPLE_EXT);
2339         }
2340         mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
2341     }
2342 }
2343 
setSampleAlphaToOneStateEnabled(bool enabled)2344 void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
2345 {
2346     if (mSampleAlphaToOneEnabled != enabled)
2347     {
2348         mSampleAlphaToOneEnabled = enabled;
2349         if (mSampleAlphaToOneEnabled)
2350         {
2351             mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
2352         }
2353         else
2354         {
2355             mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
2356         }
2357         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
2358     }
2359 }
2360 
setCoverageModulation(GLenum components)2361 void StateManagerGL::setCoverageModulation(GLenum components)
2362 {
2363     if (mCoverageModulation != components)
2364     {
2365         mCoverageModulation = components;
2366         mFunctions->coverageModulationNV(components);
2367 
2368         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COVERAGE_MODULATION);
2369     }
2370 }
2371 
setProvokingVertex(GLenum mode)2372 void StateManagerGL::setProvokingVertex(GLenum mode)
2373 {
2374     if (mode != mProvokingVertex)
2375     {
2376         mFunctions->provokingVertex(mode);
2377         mProvokingVertex = mode;
2378 
2379         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROVOKING_VERTEX);
2380     }
2381 }
2382 
setClipDistancesEnable(const gl::State::ClipDistanceEnableBits & enables)2383 void StateManagerGL::setClipDistancesEnable(const gl::State::ClipDistanceEnableBits &enables)
2384 {
2385     if (enables == mEnabledClipDistances)
2386     {
2387         return;
2388     }
2389     ASSERT(mMaxClipDistances <= gl::IMPLEMENTATION_MAX_CLIP_DISTANCES);
2390 
2391     gl::State::ClipDistanceEnableBits diff = enables ^ mEnabledClipDistances;
2392     for (size_t i : diff)
2393     {
2394         if (enables.test(i))
2395         {
2396             mFunctions->enable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2397         }
2398         else
2399         {
2400             mFunctions->disable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2401         }
2402     }
2403 
2404     mEnabledClipDistances = enables;
2405     mLocalDirtyBits.set(gl::State::DIRTY_BIT_EXTENDED);
2406 }
2407 
setTextureCubemapSeamlessEnabled(bool enabled)2408 void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
2409 {
2410     // TODO(jmadill): Also check for seamless extension.
2411     if (!mFunctions->isAtLeastGL(gl::Version(3, 2)))
2412     {
2413         return;
2414     }
2415 
2416     if (mTextureCubemapSeamlessEnabled != enabled)
2417     {
2418         mTextureCubemapSeamlessEnabled = enabled;
2419         if (mTextureCubemapSeamlessEnabled)
2420         {
2421             mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2422         }
2423         else
2424         {
2425             mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2426         }
2427     }
2428 }
2429 
propagateProgramToVAO(const gl::Context * context,const gl::Program * program,VertexArrayGL * vao)2430 void StateManagerGL::propagateProgramToVAO(const gl::Context *context,
2431                                            const gl::Program *program,
2432                                            VertexArrayGL *vao)
2433 {
2434     if (vao == nullptr)
2435     {
2436         return;
2437     }
2438 
2439     // Number of views:
2440     if (mIsMultiviewEnabled)
2441     {
2442         int programNumViews = 1;
2443         if (program && program->usesMultiview())
2444         {
2445             programNumViews = program->getNumViews();
2446         }
2447         vao->applyNumViewsToDivisor(context, programNumViews);
2448     }
2449 
2450     // Attribute enabled mask:
2451     if (program)
2452     {
2453         vao->applyActiveAttribLocationsMask(
2454             context, program->getExecutable().getActiveAttribLocationsMask());
2455     }
2456 }
2457 
updateMultiviewBaseViewLayerIndexUniformImpl(const gl::Program * program,const gl::FramebufferState & drawFramebufferState) const2458 void StateManagerGL::updateMultiviewBaseViewLayerIndexUniformImpl(
2459     const gl::Program *program,
2460     const gl::FramebufferState &drawFramebufferState) const
2461 {
2462     ASSERT(mIsMultiviewEnabled && program && program->usesMultiview());
2463     const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
2464     if (drawFramebufferState.isMultiview())
2465     {
2466         programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
2467     }
2468 }
2469 
syncSamplersState(const gl::Context * context)2470 void StateManagerGL::syncSamplersState(const gl::Context *context)
2471 {
2472     const gl::SamplerBindingVector &samplers = context->getState().getSamplers();
2473 
2474     // This could be optimized by using a separate binding dirty bit per sampler.
2475     for (size_t samplerIndex = 0; samplerIndex < samplers.size(); ++samplerIndex)
2476     {
2477         const gl::Sampler *sampler = samplers[samplerIndex].get();
2478         if (sampler != nullptr)
2479         {
2480             SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
2481             bindSampler(samplerIndex, samplerGL->getSamplerID());
2482         }
2483         else
2484         {
2485             bindSampler(samplerIndex, 0);
2486         }
2487     }
2488 }
2489 
syncTransformFeedbackState(const gl::Context * context)2490 void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
2491 {
2492     // Set the current transform feedback state
2493     gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
2494     if (transformFeedback)
2495     {
2496         TransformFeedbackGL *transformFeedbackGL =
2497             GetImplAs<TransformFeedbackGL>(transformFeedback);
2498         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
2499         transformFeedbackGL->syncActiveState(context, transformFeedback->isActive(),
2500                                              transformFeedback->getPrimitiveMode());
2501         transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
2502         mCurrentTransformFeedback = transformFeedbackGL;
2503     }
2504     else
2505     {
2506         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
2507         mCurrentTransformFeedback = nullptr;
2508     }
2509 }
2510 
getDefaultVAO() const2511 GLuint StateManagerGL::getDefaultVAO() const
2512 {
2513     return mDefaultVAO;
2514 }
2515 
getDefaultVAOState()2516 VertexArrayStateGL *StateManagerGL::getDefaultVAOState()
2517 {
2518     return &mDefaultVAOState;
2519 }
2520 
validateState() const2521 void StateManagerGL::validateState() const
2522 {
2523     // Current program
2524     ValidateStateHelper(mFunctions, mProgram, GL_CURRENT_PROGRAM, "mProgram", "GL_CURRENT_PROGRAM");
2525 
2526     // Buffers
2527     for (gl::BufferBinding bindingType : angle::AllEnums<gl::BufferBinding>())
2528     {
2529         // These binding types need compute support to be queried
2530         if (bindingType == gl::BufferBinding::AtomicCounter ||
2531             bindingType == gl::BufferBinding::DispatchIndirect ||
2532             bindingType == gl::BufferBinding::ShaderStorage)
2533         {
2534             if (!nativegl::SupportsCompute(mFunctions))
2535             {
2536                 continue;
2537             }
2538         }
2539 
2540         // Transform feedback buffer bindings are tracked in TransformFeedbackGL
2541         if (bindingType == gl::BufferBinding::TransformFeedback)
2542         {
2543             continue;
2544         }
2545 
2546         GLenum bindingTypeGL  = nativegl::GetBufferBindingQuery(bindingType);
2547         std::string localName = "mBuffers[" + ToString(bindingType) + "]";
2548         ValidateStateHelper(mFunctions, mBuffers[bindingType], bindingTypeGL, localName.c_str(),
2549                             nativegl::GetBufferBindingString(bindingType).c_str());
2550     }
2551 
2552     // Vertex array object
2553     ValidateStateHelper(mFunctions, mVAO, GL_VERTEX_ARRAY_BINDING, "mVAO",
2554                         "GL_VERTEX_ARRAY_BINDING");
2555 }
2556 
2557 template <>
get(GLenum name,GLboolean * value)2558 void StateManagerGL::get(GLenum name, GLboolean *value)
2559 {
2560     mFunctions->getBooleanv(name, value);
2561 }
2562 
2563 template <>
get(GLenum name,bool * value)2564 void StateManagerGL::get(GLenum name, bool *value)
2565 {
2566     GLboolean v;
2567     get(name, &v);
2568     *value = (v == GL_TRUE);
2569 }
2570 
2571 template <>
get(GLenum name,std::array<bool,4> * values)2572 void StateManagerGL::get(GLenum name, std::array<bool, 4> *values)
2573 {
2574     GLboolean v[4];
2575     get(name, v);
2576     for (size_t i = 0; i < 4; i++)
2577     {
2578         (*values)[i] = (v[i] == GL_TRUE);
2579     }
2580 }
2581 
2582 template <>
get(GLenum name,GLint * value)2583 void StateManagerGL::get(GLenum name, GLint *value)
2584 {
2585     mFunctions->getIntegerv(name, value);
2586 }
2587 
2588 template <>
get(GLenum name,GLenum * value)2589 void StateManagerGL::get(GLenum name, GLenum *value)
2590 {
2591     GLint v;
2592     get(name, &v);
2593     *value = static_cast<GLenum>(v);
2594 }
2595 
2596 template <>
get(GLenum name,gl::Rectangle * rect)2597 void StateManagerGL::get(GLenum name, gl::Rectangle *rect)
2598 {
2599     GLint v[4];
2600     get(name, v);
2601     *rect = gl::Rectangle(v[0], v[1], v[2], v[3]);
2602 }
2603 
2604 template <>
get(GLenum name,GLfloat * value)2605 void StateManagerGL::get(GLenum name, GLfloat *value)
2606 {
2607     mFunctions->getFloatv(name, value);
2608 }
2609 
2610 template <>
get(GLenum name,gl::ColorF * color)2611 void StateManagerGL::get(GLenum name, gl::ColorF *color)
2612 {
2613     GLfloat v[4];
2614     get(name, v);
2615     *color = gl::ColorF(v[0], v[1], v[2], v[3]);
2616 }
2617 
syncFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2618 void StateManagerGL::syncFromNativeContext(const gl::Extensions &extensions,
2619                                            ExternalContextState *state)
2620 {
2621     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2622 
2623     get(GL_VIEWPORT, &state->viewport);
2624     if (mViewport != state->viewport)
2625     {
2626         mViewport = state->viewport;
2627         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
2628     }
2629 
2630     get(GL_SCISSOR_TEST, &state->scissorTest);
2631     if (mScissorTestEnabled != static_cast<bool>(state->scissorTest))
2632     {
2633         mScissorTestEnabled = state->scissorTest;
2634         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
2635     }
2636 
2637     get(GL_SCISSOR_BOX, &state->scissorBox);
2638     if (mScissor != state->scissorBox)
2639     {
2640         mScissor = state->scissorBox;
2641         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
2642     }
2643 
2644     get(GL_DEPTH_TEST, &state->depthTest);
2645     if (mDepthTestEnabled != state->depthTest)
2646     {
2647         mDepthTestEnabled = state->depthTest;
2648         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
2649     }
2650 
2651     get(GL_CULL_FACE, &state->cullFace);
2652     if (mCullFaceEnabled != state->cullFace)
2653     {
2654         mCullFaceEnabled = state->cullFace;
2655         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
2656     }
2657 
2658     get(GL_CULL_FACE_MODE, &state->cullFaceMode);
2659     if (mCullFace != gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode))
2660     {
2661         mCullFace = gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode);
2662         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
2663     }
2664 
2665     get(GL_COLOR_WRITEMASK, &state->colorMask);
2666     auto colorMask = mBlendStateExt.expandColorMaskValue(state->colorMask[0], state->colorMask[1],
2667                                                          state->colorMask[2], state->colorMask[3]);
2668     if (mBlendStateExt.mColorMask != colorMask)
2669     {
2670         mBlendStateExt.mColorMask = colorMask;
2671         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
2672     }
2673 
2674     get(GL_CURRENT_PROGRAM, &state->currentProgram);
2675     if (mProgram != static_cast<GLuint>(state->currentProgram))
2676     {
2677         mProgram = state->currentProgram;
2678         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
2679     }
2680 
2681     get(GL_COLOR_CLEAR_VALUE, &state->colorClear);
2682     if (mClearColor != state->colorClear)
2683     {
2684         mClearColor = state->colorClear;
2685         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
2686     }
2687 
2688     get(GL_DEPTH_CLEAR_VALUE, &state->depthClear);
2689     if (mClearDepth != state->depthClear)
2690     {
2691         mClearDepth = state->depthClear;
2692         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
2693     }
2694 
2695     get(GL_DEPTH_FUNC, &state->depthFunc);
2696     if (mDepthFunc != static_cast<GLenum>(state->depthFunc))
2697     {
2698         mDepthFunc = state->depthFunc;
2699         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
2700     }
2701 
2702     get(GL_DEPTH_WRITEMASK, &state->depthMask);
2703     if (mDepthMask != state->depthMask)
2704     {
2705         mDepthMask = state->depthMask;
2706         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
2707     }
2708 
2709     get(GL_DEPTH_RANGE, state->depthRage);
2710     if (mNear != state->depthRage[0] || mFar != state->depthRage[1])
2711     {
2712         mNear = state->depthRage[0];
2713         mFar  = state->depthRage[1];
2714         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
2715     }
2716 
2717     get(GL_FRONT_FACE, &state->frontFace);
2718     if (mFrontFace != static_cast<GLenum>(state->frontFace))
2719     {
2720         mFrontFace = state->frontFace;
2721         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
2722     }
2723 
2724     get(GL_LINE_WIDTH, &state->lineWidth);
2725     if (mLineWidth != state->lineWidth)
2726     {
2727         mLineWidth = state->lineWidth;
2728         mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
2729     }
2730 
2731     get(GL_POLYGON_OFFSET_FACTOR, &state->polygonOffsetFactor);
2732     get(GL_POLYGON_OFFSET_UNITS, &state->polygonOffsetUnits);
2733     if (mPolygonOffsetFactor != state->polygonOffsetFactor ||
2734         mPolygonOffsetUnits != state->polygonOffsetUnits)
2735     {
2736         mPolygonOffsetFactor = state->polygonOffsetFactor;
2737         mPolygonOffsetUnits  = state->polygonOffsetUnits;
2738         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
2739     }
2740 
2741     get(GL_SAMPLE_COVERAGE_VALUE, &state->sampleCoverageValue);
2742     get(GL_SAMPLE_COVERAGE_INVERT, &state->sampleCoverageInvert);
2743     if (mSampleCoverageValue != state->sampleCoverageValue ||
2744         mSampleCoverageInvert != state->sampleCoverageInvert)
2745     {
2746         mSampleCoverageValue  = state->sampleCoverageValue;
2747         mSampleCoverageInvert = state->sampleCoverageInvert;
2748         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
2749     }
2750 
2751     get(GL_DITHER, &state->enableDither);
2752     if (mDitherEnabled != state->enableDither)
2753     {
2754         mDitherEnabled = state->enableDither;
2755         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DITHER_ENABLED);
2756     }
2757 
2758     get(GL_POLYGON_OFFSET_FILL, &state->enablePolygonOffsetFill);
2759     if (mPolygonOffsetFillEnabled != state->enablePolygonOffsetFill)
2760     {
2761         mPolygonOffsetFillEnabled = state->enablePolygonOffsetFill;
2762         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
2763     }
2764 
2765     get(GL_SAMPLE_ALPHA_TO_COVERAGE, &state->enableSampleAlphaToCoverage);
2766     if (mSampleAlphaToOneEnabled != state->enableSampleAlphaToCoverage)
2767     {
2768         mSampleAlphaToOneEnabled = state->enableSampleAlphaToCoverage;
2769         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
2770     }
2771 
2772     get(GL_SAMPLE_COVERAGE, &state->enableSampleCoverage);
2773     if (mSampleCoverageEnabled != state->enableSampleCoverage)
2774     {
2775         mSampleCoverageEnabled = state->enableSampleCoverage;
2776         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
2777     }
2778 
2779     if (extensions.multisampleCompatibility)
2780     {
2781         get(GL_MULTISAMPLE, &state->multisampleEnabled);
2782         if (mMultisamplingEnabled != state->multisampleEnabled)
2783         {
2784             mMultisamplingEnabled = state->multisampleEnabled;
2785             mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
2786         }
2787     }
2788 
2789     syncBlendFromNativeContext(extensions, state);
2790     syncFramebufferFromNativeContext(extensions, state);
2791     syncPixelPackUnpackFromNativeContext(extensions, state);
2792     syncStencilFromNativeContext(extensions, state);
2793     syncVertexArraysFromNativeContext(extensions, state);
2794     syncBufferBindingsFromNativeContext(extensions, state);
2795     syncTextureUnitsFromNativeContext(extensions, state);
2796 
2797     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2798 }
2799 
restoreNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2800 void StateManagerGL::restoreNativeContext(const gl::Extensions &extensions,
2801                                           const ExternalContextState *state)
2802 {
2803     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2804 
2805     setViewport(state->viewport);
2806 
2807     setScissorTestEnabled(state->scissorTest);
2808     setScissor(state->scissorBox);
2809 
2810     setDepthTestEnabled(state->depthTest);
2811 
2812     setCullFaceEnabled(state->cullFace);
2813     setCullFace(gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode));
2814 
2815     setColorMask(state->colorMask[0], state->colorMask[1], state->colorMask[2],
2816                  state->colorMask[3]);
2817 
2818     forceUseProgram(state->currentProgram);
2819 
2820     setClearColor(state->colorClear);
2821 
2822     setClearDepth(state->depthClear);
2823     setDepthFunc(state->depthFunc);
2824     setDepthMask(state->depthMask);
2825     setDepthRange(state->depthRage[0], state->depthRage[1]);
2826 
2827     setFrontFace(state->frontFace);
2828 
2829     setLineWidth(state->lineWidth);
2830 
2831     setPolygonOffset(state->polygonOffsetFactor, state->polygonOffsetUnits);
2832 
2833     setSampleCoverage(state->sampleCoverageValue, state->sampleCoverageInvert);
2834 
2835     setDitherEnabled(state->enableDither);
2836 
2837     setPolygonOffsetFillEnabled(state->enablePolygonOffsetFill);
2838 
2839     setSampleAlphaToOneStateEnabled(state->enableSampleAlphaToCoverage);
2840 
2841     setSampleCoverageEnabled(state->enableSampleCoverage);
2842 
2843     if (extensions.multisampleCompatibility)
2844         setMultisamplingStateEnabled(state->multisampleEnabled);
2845 
2846     restoreBlendNativeContext(extensions, state);
2847     restoreFramebufferNativeContext(extensions, state);
2848     restorePixelPackUnpackNativeContext(extensions, state);
2849     restoreStencilNativeContext(extensions, state);
2850     restoreVertexArraysNativeContext(extensions, state);
2851     restoreBufferBindingsNativeContext(extensions, state);
2852     restoreTextureUnitsNativeContext(extensions, state);
2853 
2854     // if (mFunctions->coverageModulationNV) ?
2855     setCoverageModulation(GL_NONE);
2856 
2857     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2858 }
2859 
syncBlendFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2860 void StateManagerGL::syncBlendFromNativeContext(const gl::Extensions &extensions,
2861                                                 ExternalContextState *state)
2862 {
2863     get(GL_BLEND, &state->blendEnabled);
2864     if (mBlendStateExt.mEnabledMask !=
2865         (state->blendEnabled ? mBlendStateExt.mMaxEnabledMask : gl::DrawBufferMask::Zero()))
2866     {
2867         mBlendStateExt.setEnabled(state->blendEnabled);
2868         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
2869     }
2870 
2871     get(GL_BLEND_SRC_RGB, &state->blendSrcRgb);
2872     get(GL_BLEND_DST_RGB, &state->blendDestRgb);
2873     get(GL_BLEND_SRC_ALPHA, &state->blendSrcAlpha);
2874     get(GL_BLEND_DST_ALPHA, &state->blendDestAlpha);
2875     if (mBlendStateExt.mSrcColor != static_cast<uint64_t>(state->blendSrcRgb) ||
2876         mBlendStateExt.mDstColor != static_cast<uint64_t>(state->blendDestRgb) ||
2877         mBlendStateExt.mSrcAlpha != static_cast<uint64_t>(state->blendSrcAlpha) ||
2878         mBlendStateExt.mDstAlpha != static_cast<uint64_t>(state->blendDestAlpha))
2879     {
2880         mBlendStateExt.mSrcColor = state->blendSrcRgb;
2881         mBlendStateExt.mDstColor = state->blendDestRgb;
2882         mBlendStateExt.mSrcAlpha = state->blendSrcAlpha;
2883         mBlendStateExt.mDstAlpha = state->blendDestAlpha;
2884         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
2885     }
2886 
2887     get(GL_BLEND_COLOR, &state->blendColor);
2888     if (mBlendColor != state->blendColor)
2889     {
2890         mBlendColor = state->blendColor;
2891         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
2892     }
2893 
2894     get(GL_BLEND_EQUATION_RGB, &state->blendEquationRgb);
2895     get(GL_BLEND_EQUATION_ALPHA, &state->blendEquationAlpha);
2896 }
2897 
restoreBlendNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2898 void StateManagerGL::restoreBlendNativeContext(const gl::Extensions &extensions,
2899                                                const ExternalContextState *state)
2900 {
2901     setBlendEnabled(state->blendEnabled);
2902     // TODO: use setBlendFuncs()
2903     mFunctions->blendFuncSeparate(state->blendSrcRgb, state->blendDestRgb, state->blendSrcAlpha,
2904                                   state->blendDestAlpha);
2905     mBlendStateExt.mSrcColor = state->blendSrcRgb;
2906     mBlendStateExt.mDstColor = state->blendDestRgb;
2907     mBlendStateExt.mSrcAlpha = state->blendSrcAlpha;
2908     mBlendStateExt.mDstAlpha = state->blendDestAlpha;
2909     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
2910 
2911     setBlendColor(state->blendColor);
2912 
2913     // TODO: use setBlendEquations()
2914     mFunctions->blendEquationSeparate(state->blendEquationRgb, state->blendEquationAlpha);
2915     mBlendStateExt.mEquationColor = state->blendEquationRgb;
2916     mBlendStateExt.mEquationAlpha = state->blendEquationAlpha;
2917     mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_EQUATIONS);
2918 }
2919 
syncFramebufferFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2920 void StateManagerGL::syncFramebufferFromNativeContext(const gl::Extensions &extensions,
2921                                                       ExternalContextState *state)
2922 {
2923     // TODO: wrap fbo into an EGLSurface
2924     get(GL_FRAMEBUFFER_BINDING, &state->framebufferBinding);
2925     if (mFramebuffers[angle::FramebufferBindingDraw] !=
2926         static_cast<GLenum>(state->framebufferBinding))
2927     {
2928         mFramebuffers[angle::FramebufferBindingDraw] =
2929             static_cast<GLenum>(state->framebufferBinding);
2930         mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
2931     }
2932     if (mFramebuffers[angle::FramebufferBindingRead] !=
2933         static_cast<GLenum>(state->framebufferBinding))
2934     {
2935         mFramebuffers[angle::FramebufferBindingRead] =
2936             static_cast<GLenum>(state->framebufferBinding);
2937         mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
2938     }
2939 }
2940 
restoreFramebufferNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2941 void StateManagerGL::restoreFramebufferNativeContext(const gl::Extensions &extensions,
2942                                                      const ExternalContextState *state)
2943 {
2944     bindFramebuffer(GL_FRAMEBUFFER, state->framebufferBinding);
2945 }
2946 
syncPixelPackUnpackFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2947 void StateManagerGL::syncPixelPackUnpackFromNativeContext(const gl::Extensions &extensions,
2948                                                           ExternalContextState *state)
2949 {
2950     get(GL_PACK_ALIGNMENT, &state->packAlignment);
2951     if (mPackAlignment != state->packAlignment)
2952     {
2953         mPackAlignment = state->packAlignment;
2954         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
2955     }
2956 
2957     get(GL_UNPACK_ALIGNMENT, &state->unpackAlignment);
2958     if (mUnpackAlignment != state->unpackAlignment)
2959     {
2960         mUnpackAlignment = state->unpackAlignment;
2961         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
2962     }
2963 }
2964 
restorePixelPackUnpackNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)2965 void StateManagerGL::restorePixelPackUnpackNativeContext(const gl::Extensions &extensions,
2966                                                          const ExternalContextState *state)
2967 {
2968     if (mPackAlignment != state->packAlignment)
2969     {
2970         mFunctions->pixelStorei(GL_PACK_ALIGNMENT, state->packAlignment);
2971         mPackAlignment = state->packAlignment;
2972         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
2973     }
2974 
2975     if (mUnpackAlignment != state->unpackAlignment)
2976     {
2977         mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, state->unpackAlignment);
2978         mUnpackAlignment = state->unpackAlignment;
2979         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
2980     }
2981 }
2982 
syncStencilFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)2983 void StateManagerGL::syncStencilFromNativeContext(const gl::Extensions &extensions,
2984                                                   ExternalContextState *state)
2985 {
2986     get(GL_STENCIL_TEST, &state->stencilState.stencilTestEnabled);
2987     if (state->stencilState.stencilTestEnabled != mStencilTestEnabled)
2988     {
2989         mStencilTestEnabled = state->stencilState.stencilTestEnabled;
2990         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
2991     }
2992 
2993     get(GL_STENCIL_FUNC, &state->stencilState.stencilFrontFunc);
2994     get(GL_STENCIL_VALUE_MASK, &state->stencilState.stencilFrontMask);
2995     get(GL_STENCIL_REF, &state->stencilState.stencilFrontRef);
2996     if (state->stencilState.stencilFrontFunc != mStencilFrontFunc ||
2997         state->stencilState.stencilFrontMask != mStencilFrontValueMask ||
2998         state->stencilState.stencilFrontRef != mStencilFrontRef)
2999     {
3000         mStencilFrontFunc      = state->stencilState.stencilFrontFunc;
3001         mStencilFrontValueMask = state->stencilState.stencilFrontMask;
3002         mStencilFrontRef       = state->stencilState.stencilFrontRef;
3003         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
3004     }
3005 
3006     get(GL_STENCIL_BACK_FUNC, &state->stencilState.stencilBackFunc);
3007     get(GL_STENCIL_BACK_VALUE_MASK, &state->stencilState.stencilBackMask);
3008     get(GL_STENCIL_BACK_REF, &state->stencilState.stencilBackRef);
3009     if (state->stencilState.stencilBackFunc != mStencilBackFunc ||
3010         state->stencilState.stencilBackMask != mStencilBackValueMask ||
3011         state->stencilState.stencilBackRef != mStencilBackRef)
3012     {
3013         mStencilBackFunc      = state->stencilState.stencilBackFunc;
3014         mStencilBackValueMask = state->stencilState.stencilBackMask;
3015         mStencilBackRef       = state->stencilState.stencilBackRef;
3016         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
3017     }
3018 
3019     get(GL_STENCIL_CLEAR_VALUE, &state->stencilState.stencilClear);
3020     if (mClearStencil != state->stencilState.stencilClear)
3021     {
3022         mClearStencil = state->stencilState.stencilClear;
3023         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
3024     }
3025 
3026     get(GL_STENCIL_WRITEMASK, &state->stencilState.stencilFrontWritemask);
3027     if (mStencilFrontWritemask != static_cast<GLenum>(state->stencilState.stencilFrontWritemask))
3028     {
3029         mStencilFrontWritemask = state->stencilState.stencilFrontWritemask;
3030         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3031     }
3032 
3033     get(GL_STENCIL_BACK_WRITEMASK, &state->stencilState.stencilBackWritemask);
3034     if (mStencilBackWritemask != static_cast<GLenum>(state->stencilState.stencilBackWritemask))
3035     {
3036         mStencilBackWritemask = state->stencilState.stencilBackWritemask;
3037         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3038     }
3039 
3040     get(GL_STENCIL_FAIL, &state->stencilState.stencilFrontFailOp);
3041     get(GL_STENCIL_PASS_DEPTH_FAIL, &state->stencilState.stencilFrontZFailOp);
3042     get(GL_STENCIL_PASS_DEPTH_PASS, &state->stencilState.stencilFrontZPassOp);
3043     if (mStencilFrontStencilFailOp != static_cast<GLenum>(state->stencilState.stencilFrontFailOp) ||
3044         mStencilFrontStencilPassDepthFailOp !=
3045             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp) ||
3046         mStencilFrontStencilPassDepthPassOp !=
3047             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp))
3048     {
3049         mStencilFrontStencilFailOp = static_cast<GLenum>(state->stencilState.stencilFrontFailOp);
3050         mStencilFrontStencilPassDepthFailOp =
3051             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp);
3052         mStencilFrontStencilPassDepthPassOp =
3053             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp);
3054         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
3055     }
3056 
3057     get(GL_STENCIL_BACK_FAIL, &state->stencilState.stencilBackFailOp);
3058     get(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &state->stencilState.stencilBackZFailOp);
3059     get(GL_STENCIL_BACK_PASS_DEPTH_PASS, &state->stencilState.stencilBackZPassOp);
3060     if (mStencilBackStencilFailOp != static_cast<GLenum>(state->stencilState.stencilBackFailOp) ||
3061         mStencilBackStencilPassDepthFailOp !=
3062             static_cast<GLenum>(state->stencilState.stencilBackZFailOp) ||
3063         mStencilBackStencilPassDepthPassOp !=
3064             static_cast<GLenum>(state->stencilState.stencilBackZPassOp))
3065     {
3066         mStencilBackStencilFailOp = static_cast<GLenum>(state->stencilState.stencilBackFailOp);
3067         mStencilBackStencilPassDepthFailOp =
3068             static_cast<GLenum>(state->stencilState.stencilBackZFailOp);
3069         mStencilBackStencilPassDepthPassOp =
3070             static_cast<GLenum>(state->stencilState.stencilBackZPassOp);
3071         mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
3072     }
3073 }
3074 
restoreStencilNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3075 void StateManagerGL::restoreStencilNativeContext(const gl::Extensions &extensions,
3076                                                  const ExternalContextState *state)
3077 {
3078     setStencilTestEnabled(state->stencilState.stencilTestEnabled);
3079     setStencilFrontFuncs(state->stencilState.stencilFrontFunc, state->stencilState.stencilFrontMask,
3080                          state->stencilState.stencilFrontRef);
3081     setStencilBackFuncs(state->stencilState.stencilBackFunc, state->stencilState.stencilBackMask,
3082                         state->stencilState.stencilBackRef);
3083     setClearStencil(state->stencilState.stencilClear);
3084     setStencilFrontWritemask(state->stencilState.stencilFrontWritemask);
3085     setStencilBackWritemask(state->stencilState.stencilBackWritemask);
3086     setStencilFrontOps(state->stencilState.stencilFrontFailOp,
3087                        state->stencilState.stencilFrontZFailOp,
3088                        state->stencilState.stencilFrontZPassOp);
3089     setStencilBackOps(state->stencilState.stencilBackFailOp, state->stencilState.stencilBackZFailOp,
3090                       state->stencilState.stencilBackZPassOp);
3091 }
3092 
syncBufferBindingsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3093 void StateManagerGL::syncBufferBindingsFromNativeContext(const gl::Extensions &extensions,
3094                                                          ExternalContextState *state)
3095 {
3096     get(GL_ARRAY_BUFFER_BINDING, &state->vertexArrayBufferBinding);
3097     mBuffers[gl::BufferBinding::Array] = state->vertexArrayBufferBinding;
3098 
3099     get(GL_ELEMENT_ARRAY_BUFFER_BINDING, &state->elementArrayBufferBinding);
3100     mBuffers[gl::BufferBinding::ElementArray] = state->elementArrayBufferBinding;
3101 }
3102 
restoreBufferBindingsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3103 void StateManagerGL::restoreBufferBindingsNativeContext(const gl::Extensions &extensions,
3104                                                         const ExternalContextState *state)
3105 {
3106     bindBuffer(gl::BufferBinding::Array, state->vertexArrayBufferBinding);
3107     bindBuffer(gl::BufferBinding::ElementArray, state->elementArrayBufferBinding);
3108 }
3109 
syncTextureUnitsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3110 void StateManagerGL::syncTextureUnitsFromNativeContext(const gl::Extensions &extensions,
3111                                                        ExternalContextState *state)
3112 {
3113     get(GL_ACTIVE_TEXTURE, &state->activeTexture);
3114 
3115     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3116     {
3117         auto &bindings = state->textureBindings[i];
3118         activeTexture(i);
3119         get(GL_TEXTURE_BINDING_2D, &bindings.texture2d);
3120         get(GL_TEXTURE_BINDING_CUBE_MAP, &bindings.textureCubeMap);
3121         get(GL_TEXTURE_BINDING_EXTERNAL_OES, &bindings.textureExternalOES);
3122         if (mTextures[gl::TextureType::_2D][i] != static_cast<GLuint>(bindings.texture2d) ||
3123             mTextures[gl::TextureType::CubeMap][i] !=
3124                 static_cast<GLuint>(bindings.textureCubeMap) ||
3125             mTextures[gl::TextureType::External][i] !=
3126                 static_cast<GLuint>(bindings.textureExternalOES))
3127         {
3128             mTextures[gl::TextureType::_2D][i]      = bindings.texture2d;
3129             mTextures[gl::TextureType::CubeMap][i]  = bindings.textureCubeMap;
3130             mTextures[gl::TextureType::External][i] = bindings.textureExternalOES;
3131             mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
3132         }
3133     }
3134 }
3135 
restoreTextureUnitsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3136 void StateManagerGL::restoreTextureUnitsNativeContext(const gl::Extensions &extensions,
3137                                                       const ExternalContextState *state)
3138 {
3139     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3140     {
3141         const auto &bindings = state->textureBindings[i];
3142         activeTexture(i);
3143         bindTexture(gl::TextureType::_2D, bindings.texture2d);
3144         bindTexture(gl::TextureType::CubeMap, bindings.textureCubeMap);
3145         bindTexture(gl::TextureType::External, bindings.textureExternalOES);
3146         bindSampler(i, 0);
3147     }
3148     activeTexture(state->activeTexture - GL_TEXTURE0);
3149 }
3150 
syncVertexArraysFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3151 void StateManagerGL::syncVertexArraysFromNativeContext(const gl::Extensions &extensions,
3152                                                        ExternalContextState *state)
3153 {
3154     get(GL_VERTEX_ARRAY_BINDING, &state->vertexArrayBinding);
3155     if (mVAO != static_cast<GLuint>(state->vertexArrayBinding))
3156     {
3157         mVAO                                      = state->vertexArrayBinding;
3158         mBuffers[gl::BufferBinding::ElementArray] = 0;
3159         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3160     }
3161 }
3162 
restoreVertexArraysNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3163 void StateManagerGL::restoreVertexArraysNativeContext(const gl::Extensions &extensions,
3164                                                       const ExternalContextState *state)
3165 {
3166     bindVertexArray(state->vertexArrayBinding, 0);
3167 }
3168 
setDefaultVAOStateDirty()3169 void StateManagerGL::setDefaultVAOStateDirty()
3170 {
3171     mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3172 }
3173 
3174 }  // namespace rx
3175