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