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