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