• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // StateManagerGL.h: Defines a class for caching applied OpenGL state
8 
9 #include "libANGLE/renderer/gl/StateManagerGL.h"
10 
11 #include <string.h>
12 #include <algorithm>
13 #include <limits>
14 
15 #include "anglebase/numerics/safe_conversions.h"
16 #include "common/bitset_utils.h"
17 #include "common/mathutil.h"
18 #include "common/matrix_utils.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/Framebuffer.h"
21 #include "libANGLE/Query.h"
22 #include "libANGLE/TransformFeedback.h"
23 #include "libANGLE/VertexArray.h"
24 #include "libANGLE/renderer/gl/BufferGL.h"
25 #include "libANGLE/renderer/gl/FramebufferGL.h"
26 #include "libANGLE/renderer/gl/FunctionsGL.h"
27 #include "libANGLE/renderer/gl/ProgramGL.h"
28 #include "libANGLE/renderer/gl/QueryGL.h"
29 #include "libANGLE/renderer/gl/SamplerGL.h"
30 #include "libANGLE/renderer/gl/TextureGL.h"
31 #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
32 #include "libANGLE/renderer/gl/VertexArrayGL.h"
33 
34 namespace rx
35 {
36 
IndexedBufferBinding()37 StateManagerGL::IndexedBufferBinding::IndexedBufferBinding() : offset(0), size(0), buffer(0) {}
38 
StateManagerGL(const FunctionsGL * functions,const gl::Caps & rendererCaps,const gl::Extensions & extensions,const angle::FeaturesGL & features)39 StateManagerGL::StateManagerGL(const FunctionsGL *functions,
40                                const gl::Caps &rendererCaps,
41                                const gl::Extensions &extensions,
42                                const angle::FeaturesGL &features)
43     : mFunctions(functions),
44       mFeatures(features),
45       mProgram(0),
46       mVAO(0),
47       mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes),
48       mBuffers(),
49       mIndexedBuffers(),
50       mTextureUnitIndex(0),
51       mTextures{},
52       mSamplers{},
53       mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
54       mTransformFeedback(0),
55       mCurrentTransformFeedback(nullptr),
56       mQueries(),
57       mPrevDrawContext(0),
58       mUnpackAlignment(4),
59       mUnpackRowLength(0),
60       mUnpackSkipRows(0),
61       mUnpackSkipPixels(0),
62       mUnpackImageHeight(0),
63       mUnpackSkipImages(0),
64       mPackAlignment(4),
65       mPackRowLength(0),
66       mPackSkipRows(0),
67       mPackSkipPixels(0),
68       mFramebuffers(angle::FramebufferBindingSingletonMax, 0),
69       mRenderbuffer(0),
70       mScissorTestEnabled(false),
71       mScissor(0, 0, 0, 0),
72       mViewport(0, 0, 0, 0),
73       mNear(0.0f),
74       mFar(1.0f),
75       mBlendEnabled(false),
76       mBlendColor(0, 0, 0, 0),
77       mSourceBlendRGB(GL_ONE),
78       mDestBlendRGB(GL_ZERO),
79       mSourceBlendAlpha(GL_ONE),
80       mDestBlendAlpha(GL_ZERO),
81       mBlendEquationRGB(GL_FUNC_ADD),
82       mBlendEquationAlpha(GL_FUNC_ADD),
83       mColorMaskRed(true),
84       mColorMaskGreen(true),
85       mColorMaskBlue(true),
86       mColorMaskAlpha(true),
87       mSampleAlphaToCoverageEnabled(false),
88       mSampleCoverageEnabled(false),
89       mSampleCoverageValue(1.0f),
90       mSampleCoverageInvert(false),
91       mSampleMaskEnabled(false),
92       mDepthTestEnabled(false),
93       mDepthFunc(GL_LESS),
94       mDepthMask(true),
95       mStencilTestEnabled(false),
96       mStencilFrontFunc(GL_ALWAYS),
97       mStencilFrontRef(0),
98       mStencilFrontValueMask(static_cast<GLuint>(-1)),
99       mStencilFrontStencilFailOp(GL_KEEP),
100       mStencilFrontStencilPassDepthFailOp(GL_KEEP),
101       mStencilFrontStencilPassDepthPassOp(GL_KEEP),
102       mStencilFrontWritemask(static_cast<GLuint>(-1)),
103       mStencilBackFunc(GL_ALWAYS),
104       mStencilBackRef(0),
105       mStencilBackValueMask(static_cast<GLuint>(-1)),
106       mStencilBackStencilFailOp(GL_KEEP),
107       mStencilBackStencilPassDepthFailOp(GL_KEEP),
108       mStencilBackStencilPassDepthPassOp(GL_KEEP),
109       mStencilBackWritemask(static_cast<GLuint>(-1)),
110       mCullFaceEnabled(false),
111       mCullFace(gl::CullFaceMode::Back),
112       mFrontFace(GL_CCW),
113       mPolygonOffsetFillEnabled(false),
114       mPolygonOffsetFactor(0.0f),
115       mPolygonOffsetUnits(0.0f),
116       mRasterizerDiscardEnabled(false),
117       mLineWidth(1.0f),
118       mPrimitiveRestartEnabled(false),
119       mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
120       mClearDepth(1.0f),
121       mClearStencil(0),
122       mFramebufferSRGBEnabled(false),
123       mDitherEnabled(true),
124       mTextureCubemapSeamlessEnabled(false),
125       mMultisamplingEnabled(true),
126       mSampleAlphaToOneEnabled(false),
127       mCoverageModulation(GL_NONE),
128       mPathStencilFunc(GL_ALWAYS),
129       mPathStencilRef(0),
130       mPathStencilMask(std::numeric_limits<GLuint>::max()),
131       mIsMultiviewEnabled(extensions.multiview || extensions.multiview2),
132       mProvokingVertex(GL_LAST_VERTEX_CONVENTION),
133       mLocalDirtyBits()
134 {
135     ASSERT(mFunctions);
136     ASSERT(extensions.maxViews >= 1u);
137 
138     mIndexedBuffers[gl::BufferBinding::Uniform].resize(rendererCaps.maxUniformBufferBindings);
139     mIndexedBuffers[gl::BufferBinding::AtomicCounter].resize(
140         rendererCaps.maxAtomicCounterBufferBindings);
141     mIndexedBuffers[gl::BufferBinding::ShaderStorage].resize(
142         rendererCaps.maxShaderStorageBufferBindings);
143 
144     mSampleMaskValues.fill(~GLbitfield(0));
145 
146     mQueries.fill(nullptr);
147     mTemporaryPausedQueries.fill(nullptr);
148 
149     // Initialize point sprite state for desktop GL
150     if (mFunctions->standard == STANDARD_GL_DESKTOP)
151     {
152         mFunctions->enable(GL_PROGRAM_POINT_SIZE);
153 
154         // GL_POINT_SPRITE was deprecated in the core profile. Point rasterization is always
155         // performed
156         // as though POINT_SPRITE were enabled.
157         if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0)
158         {
159             mFunctions->enable(GL_POINT_SPRITE);
160         }
161     }
162 
163     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
164     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
165 }
166 
~StateManagerGL()167 StateManagerGL::~StateManagerGL() {}
168 
deleteProgram(GLuint program)169 void StateManagerGL::deleteProgram(GLuint program)
170 {
171     if (program != 0)
172     {
173         if (mProgram == program)
174         {
175             useProgram(0);
176         }
177 
178         mFunctions->deleteProgram(program);
179     }
180 }
181 
deleteVertexArray(GLuint vao)182 void StateManagerGL::deleteVertexArray(GLuint vao)
183 {
184     if (vao != 0)
185     {
186         if (mVAO == vao)
187         {
188             bindVertexArray(0, 0);
189         }
190 
191         mFunctions->deleteVertexArrays(1, &vao);
192     }
193 }
194 
deleteTexture(GLuint texture)195 void StateManagerGL::deleteTexture(GLuint texture)
196 {
197     if (texture != 0)
198     {
199         for (gl::TextureType type : angle::AllEnums<gl::TextureType>())
200         {
201             const auto &textureVector = mTextures[type];
202             for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size();
203                  textureUnitIndex++)
204             {
205                 if (textureVector[textureUnitIndex] == texture)
206                 {
207                     activeTexture(textureUnitIndex);
208                     bindTexture(type, 0);
209                 }
210             }
211         }
212 
213         for (size_t imageUnitIndex = 0; imageUnitIndex < mImages.size(); imageUnitIndex++)
214         {
215             if (mImages[imageUnitIndex].texture == texture)
216             {
217                 bindImageTexture(imageUnitIndex, 0, 0, false, 0, GL_READ_ONLY, GL_R32UI);
218             }
219         }
220 
221         mFunctions->deleteTextures(1, &texture);
222     }
223 }
224 
deleteSampler(GLuint sampler)225 void StateManagerGL::deleteSampler(GLuint sampler)
226 {
227     if (sampler != 0)
228     {
229         for (size_t unit = 0; unit < mSamplers.size(); unit++)
230         {
231             if (mSamplers[unit] == sampler)
232             {
233                 bindSampler(unit, 0);
234             }
235         }
236 
237         mFunctions->deleteSamplers(1, &sampler);
238     }
239 }
240 
deleteBuffer(GLuint buffer)241 void StateManagerGL::deleteBuffer(GLuint buffer)
242 {
243     if (buffer == 0)
244     {
245         return;
246     }
247 
248     for (auto target : angle::AllEnums<gl::BufferBinding>())
249     {
250         if (mBuffers[target] == buffer)
251         {
252             bindBuffer(target, 0);
253         }
254 
255         auto &indexedTarget = mIndexedBuffers[target];
256         for (size_t bindIndex = 0; bindIndex < indexedTarget.size(); ++bindIndex)
257         {
258             if (indexedTarget[bindIndex].buffer == buffer)
259             {
260                 bindBufferBase(target, bindIndex, 0);
261             }
262         }
263     }
264 
265     mFunctions->deleteBuffers(1, &buffer);
266 }
267 
deleteFramebuffer(GLuint fbo)268 void StateManagerGL::deleteFramebuffer(GLuint fbo)
269 {
270     if (fbo != 0)
271     {
272         for (size_t binding = 0; binding < mFramebuffers.size(); ++binding)
273         {
274             if (mFramebuffers[binding] == fbo)
275             {
276                 GLenum enumValue = angle::FramebufferBindingToEnum(
277                     static_cast<angle::FramebufferBinding>(binding));
278                 bindFramebuffer(enumValue, 0);
279             }
280         }
281         mFunctions->deleteFramebuffers(1, &fbo);
282     }
283 }
284 
deleteRenderbuffer(GLuint rbo)285 void StateManagerGL::deleteRenderbuffer(GLuint rbo)
286 {
287     if (rbo != 0)
288     {
289         if (mRenderbuffer == rbo)
290         {
291             bindRenderbuffer(GL_RENDERBUFFER, 0);
292         }
293 
294         mFunctions->deleteRenderbuffers(1, &rbo);
295     }
296 }
297 
deleteTransformFeedback(GLuint transformFeedback)298 void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
299 {
300     if (transformFeedback != 0)
301     {
302         if (mTransformFeedback == transformFeedback)
303         {
304             bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
305         }
306 
307         if (mCurrentTransformFeedback != nullptr &&
308             mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
309         {
310             mCurrentTransformFeedback = nullptr;
311         }
312 
313         mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
314     }
315 }
316 
useProgram(GLuint program)317 void StateManagerGL::useProgram(GLuint program)
318 {
319     if (mProgram != program)
320     {
321         forceUseProgram(program);
322     }
323 }
324 
forceUseProgram(GLuint program)325 void StateManagerGL::forceUseProgram(GLuint program)
326 {
327     mProgram = program;
328     mFunctions->useProgram(mProgram);
329     mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROGRAM_BINDING);
330 }
331 
bindVertexArray(GLuint vao,GLuint elementArrayBuffer)332 void StateManagerGL::bindVertexArray(GLuint vao, GLuint elementArrayBuffer)
333 {
334     if (mVAO != vao)
335     {
336         mVAO                                      = vao;
337         mBuffers[gl::BufferBinding::ElementArray] = elementArrayBuffer;
338         mFunctions->bindVertexArray(vao);
339 
340         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING);
341     }
342 }
343 
bindBuffer(gl::BufferBinding target,GLuint buffer)344 void StateManagerGL::bindBuffer(gl::BufferBinding target, GLuint buffer)
345 {
346     // GL drivers differ in whether the transform feedback bind point is modified when
347     // glBindTransformFeedback is called. To avoid these behavior differences we shouldn't try to
348     // use it.
349     ASSERT(target != gl::BufferBinding::TransformFeedback);
350     if (mBuffers[target] != buffer)
351     {
352         mBuffers[target] = buffer;
353         mFunctions->bindBuffer(gl::ToGLenum(target), buffer);
354     }
355 }
356 
bindBufferBase(gl::BufferBinding target,size_t index,GLuint buffer)357 void StateManagerGL::bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer)
358 {
359     ASSERT(index < mIndexedBuffers[target].size());
360     auto &binding = mIndexedBuffers[target][index];
361     if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
362         binding.size != static_cast<size_t>(-1))
363     {
364         binding.buffer = buffer;
365         binding.offset = static_cast<size_t>(-1);
366         binding.size   = static_cast<size_t>(-1);
367         mFunctions->bindBufferBase(gl::ToGLenum(target), static_cast<GLuint>(index), buffer);
368     }
369 }
370 
bindBufferRange(gl::BufferBinding target,size_t index,GLuint buffer,size_t offset,size_t size)371 void StateManagerGL::bindBufferRange(gl::BufferBinding target,
372                                      size_t index,
373                                      GLuint buffer,
374                                      size_t offset,
375                                      size_t size)
376 {
377     auto &binding = mIndexedBuffers[target][index];
378     if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
379     {
380         binding.buffer = buffer;
381         binding.offset = offset;
382         binding.size   = size;
383         mFunctions->bindBufferRange(gl::ToGLenum(target), static_cast<GLuint>(index), buffer,
384                                     offset, size);
385     }
386 }
387 
activeTexture(size_t unit)388 void StateManagerGL::activeTexture(size_t unit)
389 {
390     if (mTextureUnitIndex != unit)
391     {
392         mTextureUnitIndex = unit;
393         mFunctions->activeTexture(GL_TEXTURE0 + static_cast<GLenum>(mTextureUnitIndex));
394     }
395 }
396 
bindTexture(gl::TextureType type,GLuint texture)397 void StateManagerGL::bindTexture(gl::TextureType type, GLuint texture)
398 {
399     if (mTextures[type][mTextureUnitIndex] != texture)
400     {
401         mTextures[type][mTextureUnitIndex] = texture;
402         mFunctions->bindTexture(ToGLenum(type), texture);
403         mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
404     }
405 }
406 
invalidateTexture(gl::TextureType type)407 void StateManagerGL::invalidateTexture(gl::TextureType type)
408 {
409     // Assume the tracked texture binding is incorrect, query the real bound texture from GL.
410     GLint boundTexture = 0;
411     mFunctions->getIntegerv(nativegl::GetTextureBindingQuery(type), &boundTexture);
412     mTextures[type][mTextureUnitIndex] = static_cast<GLuint>(boundTexture);
413     mLocalDirtyBits.set(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
414 }
415 
bindSampler(size_t unit,GLuint sampler)416 void StateManagerGL::bindSampler(size_t unit, GLuint sampler)
417 {
418     if (mSamplers[unit] != sampler)
419     {
420         mSamplers[unit] = sampler;
421         mFunctions->bindSampler(static_cast<GLuint>(unit), sampler);
422         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLER_BINDINGS);
423     }
424 }
425 
bindImageTexture(size_t unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)426 void StateManagerGL::bindImageTexture(size_t unit,
427                                       GLuint texture,
428                                       GLint level,
429                                       GLboolean layered,
430                                       GLint layer,
431                                       GLenum access,
432                                       GLenum format)
433 {
434     auto &binding = mImages[unit];
435     if (binding.texture != texture || binding.level != level || binding.layered != layered ||
436         binding.layer != layer || binding.access != access || binding.format != format)
437     {
438         binding.texture = texture;
439         binding.level   = level;
440         binding.layered = layered;
441         binding.layer   = layer;
442         binding.access  = access;
443         binding.format  = format;
444         mFunctions->bindImageTexture(angle::base::checked_cast<GLuint>(unit), texture, level,
445                                      layered, layer, access, format);
446     }
447 }
448 
setPixelUnpackState(const gl::PixelUnpackState & unpack)449 void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack)
450 {
451     if (mUnpackAlignment != unpack.alignment)
452     {
453         mUnpackAlignment = unpack.alignment;
454         mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment);
455 
456         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
457     }
458 
459     if (mUnpackRowLength != unpack.rowLength)
460     {
461         mUnpackRowLength = unpack.rowLength;
462         mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength);
463 
464         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
465     }
466 
467     if (mUnpackSkipRows != unpack.skipRows)
468     {
469         mUnpackSkipRows = unpack.skipRows;
470         mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows);
471 
472         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
473     }
474 
475     if (mUnpackSkipPixels != unpack.skipPixels)
476     {
477         mUnpackSkipPixels = unpack.skipPixels;
478         mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels);
479 
480         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
481     }
482 
483     if (mUnpackImageHeight != unpack.imageHeight)
484     {
485         mUnpackImageHeight = unpack.imageHeight;
486         mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight);
487 
488         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
489     }
490 
491     if (mUnpackSkipImages != unpack.skipImages)
492     {
493         mUnpackSkipImages = unpack.skipImages;
494         mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages);
495 
496         mLocalDirtyBits.set(gl::State::DIRTY_BIT_UNPACK_STATE);
497     }
498 }
499 
setPixelUnpackBuffer(const gl::Buffer * pixelBuffer)500 void StateManagerGL::setPixelUnpackBuffer(const gl::Buffer *pixelBuffer)
501 {
502     GLuint bufferID = 0;
503     if (pixelBuffer != nullptr)
504     {
505         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
506     }
507     bindBuffer(gl::BufferBinding::PixelUnpack, bufferID);
508 }
509 
setPixelPackState(const gl::PixelPackState & pack)510 void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
511 {
512     if (mPackAlignment != pack.alignment)
513     {
514         mPackAlignment = pack.alignment;
515         mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment);
516 
517         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
518     }
519 
520     if (mPackRowLength != pack.rowLength)
521     {
522         mPackRowLength = pack.rowLength;
523         mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength);
524 
525         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
526     }
527 
528     if (mPackSkipRows != pack.skipRows)
529     {
530         mPackSkipRows = pack.skipRows;
531         mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows);
532 
533         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
534     }
535 
536     if (mPackSkipPixels != pack.skipPixels)
537     {
538         mPackSkipPixels = pack.skipPixels;
539         mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels);
540 
541         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PACK_STATE);
542     }
543 }
544 
setPixelPackBuffer(const gl::Buffer * pixelBuffer)545 void StateManagerGL::setPixelPackBuffer(const gl::Buffer *pixelBuffer)
546 {
547     GLuint bufferID = 0;
548     if (pixelBuffer != nullptr)
549     {
550         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
551     }
552     bindBuffer(gl::BufferBinding::PixelPack, bufferID);
553 }
554 
bindFramebuffer(GLenum type,GLuint framebuffer)555 void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
556 {
557     switch (type)
558     {
559         case GL_FRAMEBUFFER:
560             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer ||
561                 mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
562             {
563                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
564                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
565                 mFunctions->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
566 
567                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
568                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
569             }
570             break;
571 
572         case GL_READ_FRAMEBUFFER:
573             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer)
574             {
575                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
576                 mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
577 
578                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
579             }
580             break;
581 
582         case GL_DRAW_FRAMEBUFFER:
583             if (mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
584             {
585                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
586                 mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
587 
588                 mLocalDirtyBits.set(gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
589             }
590             break;
591 
592         default:
593             UNREACHABLE();
594             break;
595     }
596 }
597 
bindRenderbuffer(GLenum type,GLuint renderbuffer)598 void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
599 {
600     ASSERT(type == GL_RENDERBUFFER);
601     if (mRenderbuffer != renderbuffer)
602     {
603         mRenderbuffer = renderbuffer;
604         mFunctions->bindRenderbuffer(type, mRenderbuffer);
605     }
606 }
607 
bindTransformFeedback(GLenum type,GLuint transformFeedback)608 void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback)
609 {
610     ASSERT(type == GL_TRANSFORM_FEEDBACK);
611     if (mTransformFeedback != transformFeedback)
612     {
613         // Pause the current transform feedback if one is active.
614         // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
615         // feedback at any time, even if there is one active.
616         if (mCurrentTransformFeedback != nullptr &&
617             mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
618         {
619             mCurrentTransformFeedback->syncPausedState(true);
620             mCurrentTransformFeedback = nullptr;
621         }
622 
623         mTransformFeedback = transformFeedback;
624         mFunctions->bindTransformFeedback(type, mTransformFeedback);
625         onTransformFeedbackStateChange();
626     }
627 }
628 
onTransformFeedbackStateChange()629 void StateManagerGL::onTransformFeedbackStateChange()
630 {
631     mLocalDirtyBits.set(gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
632 }
633 
beginQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)634 void StateManagerGL::beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
635 {
636     // Make sure this is a valid query type and there is no current active query of this type
637     ASSERT(mQueries[type] == nullptr);
638     ASSERT(queryId != 0);
639 
640     mQueries[type] = queryObject;
641     mFunctions->beginQuery(ToGLenum(type), queryId);
642 }
643 
endQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)644 void StateManagerGL::endQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
645 {
646     ASSERT(queryObject != nullptr);
647     ASSERT(mQueries[type] == queryObject);
648     mQueries[type] = nullptr;
649     mFunctions->endQuery(ToGLenum(type));
650 }
651 
updateDrawIndirectBufferBinding(const gl::Context * context)652 void StateManagerGL::updateDrawIndirectBufferBinding(const gl::Context *context)
653 {
654     gl::Buffer *drawIndirectBuffer =
655         context->getState().getTargetBuffer(gl::BufferBinding::DrawIndirect);
656     if (drawIndirectBuffer != nullptr)
657     {
658         const BufferGL *bufferGL = GetImplAs<BufferGL>(drawIndirectBuffer);
659         bindBuffer(gl::BufferBinding::DrawIndirect, bufferGL->getBufferID());
660     }
661 }
662 
updateDispatchIndirectBufferBinding(const gl::Context * context)663 void StateManagerGL::updateDispatchIndirectBufferBinding(const gl::Context *context)
664 {
665     gl::Buffer *dispatchIndirectBuffer =
666         context->getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
667     if (dispatchIndirectBuffer != nullptr)
668     {
669         const BufferGL *bufferGL = GetImplAs<BufferGL>(dispatchIndirectBuffer);
670         bindBuffer(gl::BufferBinding::DispatchIndirect, bufferGL->getBufferID());
671     }
672 }
673 
pauseTransformFeedback()674 void StateManagerGL::pauseTransformFeedback()
675 {
676     if (mCurrentTransformFeedback != nullptr)
677     {
678         mCurrentTransformFeedback->syncPausedState(true);
679         onTransformFeedbackStateChange();
680     }
681 }
682 
pauseAllQueries(const gl::Context * context)683 angle::Result StateManagerGL::pauseAllQueries(const gl::Context *context)
684 {
685     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
686     {
687         QueryGL *previousQuery = mQueries[type];
688 
689         if (previousQuery != nullptr)
690         {
691             ANGLE_TRY(previousQuery->pause(context));
692             mTemporaryPausedQueries[type] = previousQuery;
693             mQueries[type]                = nullptr;
694         }
695     }
696 
697     return angle::Result::Continue;
698 }
699 
pauseQuery(const gl::Context * context,gl::QueryType type)700 angle::Result StateManagerGL::pauseQuery(const gl::Context *context, gl::QueryType type)
701 {
702     QueryGL *previousQuery = mQueries[type];
703 
704     if (previousQuery)
705     {
706         ANGLE_TRY(previousQuery->pause(context));
707         mTemporaryPausedQueries[type] = previousQuery;
708         mQueries[type]                = nullptr;
709     }
710 
711     return angle::Result::Continue;
712 }
713 
resumeAllQueries(const gl::Context * context)714 angle::Result StateManagerGL::resumeAllQueries(const gl::Context *context)
715 {
716     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
717     {
718         QueryGL *pausedQuery = mTemporaryPausedQueries[type];
719 
720         if (pausedQuery != nullptr)
721         {
722             ASSERT(mQueries[type] == nullptr);
723             ANGLE_TRY(pausedQuery->resume(context));
724             mTemporaryPausedQueries[type] = nullptr;
725         }
726     }
727 
728     return angle::Result::Continue;
729 }
730 
resumeQuery(const gl::Context * context,gl::QueryType type)731 angle::Result StateManagerGL::resumeQuery(const gl::Context *context, gl::QueryType type)
732 {
733     QueryGL *pausedQuery = mTemporaryPausedQueries[type];
734 
735     if (pausedQuery != nullptr)
736     {
737         ANGLE_TRY(pausedQuery->resume(context));
738         mTemporaryPausedQueries[type] = nullptr;
739     }
740 
741     return angle::Result::Continue;
742 }
743 
onMakeCurrent(const gl::Context * context)744 angle::Result StateManagerGL::onMakeCurrent(const gl::Context *context)
745 {
746     const gl::State &glState = context->getState();
747 
748 #if defined(ANGLE_ENABLE_ASSERTS)
749     // Temporarily pausing queries during context switch is not supported
750     for (QueryGL *pausedQuery : mTemporaryPausedQueries)
751     {
752         ASSERT(pausedQuery == nullptr);
753     }
754 #endif
755 
756     // If the context has changed, pause the previous context's queries
757     auto contextID = context->getState().getContextID();
758     if (contextID != mPrevDrawContext)
759     {
760         for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
761         {
762             QueryGL *currentQuery = mQueries[type];
763             // Pause any old query object
764             if (currentQuery != nullptr)
765             {
766                 ANGLE_TRY(currentQuery->pause(context));
767                 mQueries[type] = nullptr;
768             }
769 
770             // Check if this new context needs to resume a query
771             gl::Query *newQuery = glState.getActiveQuery(type);
772             if (newQuery != nullptr)
773             {
774                 QueryGL *queryGL = GetImplAs<QueryGL>(newQuery);
775                 ANGLE_TRY(queryGL->resume(context));
776             }
777         }
778     }
779     onTransformFeedbackStateChange();
780     mPrevDrawContext = contextID;
781 
782     // Seamless cubemaps are required for ES3 and higher contexts. It should be the cheapest to set
783     // this state here since MakeCurrent is expected to be called less frequently than draw calls.
784     setTextureCubemapSeamlessEnabled(context->getClientMajorVersion() >= 3);
785 
786     return angle::Result::Continue;
787 }
788 
updateProgramTextureBindings(const gl::Context * context)789 void StateManagerGL::updateProgramTextureBindings(const gl::Context *context)
790 {
791     const gl::State &glState   = context->getState();
792     const gl::Program *program = glState.getProgram();
793 
794     // It is possible there is no active program during a path operation.
795     if (!program)
796         return;
797 
798     const gl::ActiveTexturePointerArray &textures  = glState.getActiveTexturesCache();
799     const gl::ActiveTextureMask &activeTextures    = program->getActiveSamplersMask();
800     const gl::ActiveTextureTypeArray &textureTypes = program->getActiveSamplerTypes();
801 
802     for (size_t textureUnitIndex : activeTextures)
803     {
804         gl::TextureType textureType = textureTypes[textureUnitIndex];
805         gl::Texture *texture        = textures[textureUnitIndex];
806 
807         // A nullptr texture indicates incomplete.
808         if (texture != nullptr)
809         {
810             const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
811             ASSERT(!texture->hasAnyDirtyBit());
812             ASSERT(!textureGL->hasAnyDirtyBit());
813 
814             activeTexture(textureUnitIndex);
815             bindTexture(textureType, textureGL->getTextureID());
816         }
817         else
818         {
819             activeTexture(textureUnitIndex);
820             bindTexture(textureType, 0);
821         }
822     }
823 }
824 
updateProgramStorageBufferBindings(const gl::Context * context)825 void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
826 {
827     const gl::State &glState   = context->getState();
828     const gl::Program *program = glState.getProgram();
829 
830     // It is possible there is no active program during a path operation.
831     if (!program)
832         return;
833 
834     for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
835          blockIndex++)
836     {
837         GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
838         const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
839 
840         if (shaderStorageBuffer.get() != nullptr)
841         {
842             BufferGL *bufferGL = GetImplAs<BufferGL>(shaderStorageBuffer.get());
843 
844             if (shaderStorageBuffer.getSize() == 0)
845             {
846                 bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
847             }
848             else
849             {
850                 bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
851                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
852             }
853         }
854     }
855 }
856 
updateProgramUniformBufferBindings(const gl::Context * context)857 void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *context)
858 {
859     // Sync the current program state
860     const gl::State &glState   = context->getState();
861     const gl::Program *program = glState.getProgram();
862 
863     // It is possible there is no active program during a path operation.
864     if (!program)
865         return;
866 
867     for (size_t uniformBlockIndex = 0; uniformBlockIndex < program->getActiveUniformBlockCount();
868          uniformBlockIndex++)
869     {
870         GLuint binding = program->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
871         const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
872 
873         if (uniformBuffer.get() != nullptr)
874         {
875             BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
876 
877             if (uniformBuffer.getSize() == 0)
878             {
879                 bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
880             }
881             else
882             {
883                 bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
884                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
885             }
886         }
887     }
888 }
889 
updateProgramAtomicCounterBufferBindings(const gl::Context * context)890 void StateManagerGL::updateProgramAtomicCounterBufferBindings(const gl::Context *context)
891 {
892     const gl::State &glState   = context->getState();
893     const gl::Program *program = glState.getProgram();
894 
895     // It is possible there is no active program during a path operation.
896     if (!program)
897         return;
898 
899     for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
900     {
901         GLuint binding     = atomicCounterBuffer.binding;
902         const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
903 
904         if (buffer.get() != nullptr)
905         {
906             BufferGL *bufferGL = GetImplAs<BufferGL>(buffer.get());
907 
908             if (buffer.getSize() == 0)
909             {
910                 bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
911             }
912             else
913             {
914                 bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
915                                 buffer.getOffset(), buffer.getSize());
916             }
917         }
918     }
919 }
920 
updateProgramImageBindings(const gl::Context * context)921 void StateManagerGL::updateProgramImageBindings(const gl::Context *context)
922 {
923     const gl::State &glState   = context->getState();
924     const gl::Program *program = glState.getProgram();
925 
926     // It is possible there is no active program during a path operation.
927     if (!program)
928         return;
929 
930     ASSERT(context->getClientVersion() >= gl::ES_3_1 || program->getImageBindings().size() == 0);
931     for (size_t imageUnitIndex : program->getActiveImagesMask())
932     {
933         const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
934         const TextureGL *textureGL     = SafeGetImplAs<TextureGL>(imageUnit.texture.get());
935         if (textureGL)
936         {
937             bindImageTexture(imageUnitIndex, textureGL->getTextureID(), imageUnit.level,
938                              imageUnit.layered, imageUnit.layer, imageUnit.access,
939                              imageUnit.format);
940         }
941         else
942         {
943             bindImageTexture(imageUnitIndex, 0, imageUnit.level, imageUnit.layered, imageUnit.layer,
944                              imageUnit.access, imageUnit.format);
945         }
946     }
947 }
948 
setAttributeCurrentData(size_t index,const gl::VertexAttribCurrentValueData & data)949 void StateManagerGL::setAttributeCurrentData(size_t index,
950                                              const gl::VertexAttribCurrentValueData &data)
951 {
952     if (mVertexAttribCurrentValues[index] != data)
953     {
954         mVertexAttribCurrentValues[index] = data;
955         switch (mVertexAttribCurrentValues[index].Type)
956         {
957             case gl::VertexAttribType::Float:
958                 mFunctions->vertexAttrib4fv(static_cast<GLuint>(index),
959                                             mVertexAttribCurrentValues[index].Values.FloatValues);
960                 break;
961             case gl::VertexAttribType::Int:
962                 mFunctions->vertexAttribI4iv(static_cast<GLuint>(index),
963                                              mVertexAttribCurrentValues[index].Values.IntValues);
964                 break;
965             case gl::VertexAttribType::UnsignedInt:
966                 mFunctions->vertexAttribI4uiv(
967                     static_cast<GLuint>(index),
968                     mVertexAttribCurrentValues[index].Values.UnsignedIntValues);
969                 break;
970             default:
971                 UNREACHABLE();
972         }
973 
974         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CURRENT_VALUES);
975         mLocalDirtyCurrentValues.set(index);
976     }
977 }
978 
setScissorTestEnabled(bool enabled)979 void StateManagerGL::setScissorTestEnabled(bool enabled)
980 {
981     if (mScissorTestEnabled != enabled)
982     {
983         mScissorTestEnabled = enabled;
984         if (mScissorTestEnabled)
985         {
986             mFunctions->enable(GL_SCISSOR_TEST);
987         }
988         else
989         {
990             mFunctions->disable(GL_SCISSOR_TEST);
991         }
992 
993         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED);
994     }
995 }
996 
setScissor(const gl::Rectangle & scissor)997 void StateManagerGL::setScissor(const gl::Rectangle &scissor)
998 {
999     if (scissor != mScissor)
1000     {
1001         mScissor = scissor;
1002         mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height);
1003 
1004         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SCISSOR);
1005     }
1006 }
1007 
setViewport(const gl::Rectangle & viewport)1008 void StateManagerGL::setViewport(const gl::Rectangle &viewport)
1009 {
1010     if (viewport != mViewport)
1011     {
1012         mViewport = viewport;
1013         mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height);
1014 
1015         mLocalDirtyBits.set(gl::State::DIRTY_BIT_VIEWPORT);
1016     }
1017 }
1018 
setDepthRange(float near,float far)1019 void StateManagerGL::setDepthRange(float near, float far)
1020 {
1021     mNear = near;
1022     mFar  = far;
1023 
1024     // The glDepthRangef function isn't available until OpenGL 4.1.  Prefer it when it is
1025     // available because OpenGL ES only works in floats.
1026     if (mFunctions->depthRangef)
1027     {
1028         mFunctions->depthRangef(mNear, mFar);
1029     }
1030     else
1031     {
1032         ASSERT(mFunctions->depthRange);
1033         mFunctions->depthRange(mNear, mFar);
1034     }
1035 
1036     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_RANGE);
1037 }
1038 
setBlendEnabled(bool enabled)1039 void StateManagerGL::setBlendEnabled(bool enabled)
1040 {
1041     if (mBlendEnabled != enabled)
1042     {
1043         mBlendEnabled = enabled;
1044         if (mBlendEnabled)
1045         {
1046             mFunctions->enable(GL_BLEND);
1047         }
1048         else
1049         {
1050             mFunctions->disable(GL_BLEND);
1051         }
1052 
1053         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_ENABLED);
1054     }
1055 }
1056 
setBlendColor(const gl::ColorF & blendColor)1057 void StateManagerGL::setBlendColor(const gl::ColorF &blendColor)
1058 {
1059     if (mBlendColor != blendColor)
1060     {
1061         mBlendColor = blendColor;
1062         mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue,
1063                                mBlendColor.alpha);
1064 
1065         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_COLOR);
1066     }
1067 }
1068 
setBlendFuncs(GLenum sourceBlendRGB,GLenum destBlendRGB,GLenum sourceBlendAlpha,GLenum destBlendAlpha)1069 void StateManagerGL::setBlendFuncs(GLenum sourceBlendRGB,
1070                                    GLenum destBlendRGB,
1071                                    GLenum sourceBlendAlpha,
1072                                    GLenum destBlendAlpha)
1073 {
1074     if (mSourceBlendRGB != sourceBlendRGB || mDestBlendRGB != destBlendRGB ||
1075         mSourceBlendAlpha != sourceBlendAlpha || mDestBlendAlpha != destBlendAlpha)
1076     {
1077         mSourceBlendRGB   = sourceBlendRGB;
1078         mDestBlendRGB     = destBlendRGB;
1079         mSourceBlendAlpha = sourceBlendAlpha;
1080         mDestBlendAlpha   = destBlendAlpha;
1081 
1082         mFunctions->blendFuncSeparate(mSourceBlendRGB, mDestBlendRGB, mSourceBlendAlpha,
1083                                       mDestBlendAlpha);
1084 
1085         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_FUNCS);
1086     }
1087 }
1088 
setBlendEquations(GLenum blendEquationRGB,GLenum blendEquationAlpha)1089 void StateManagerGL::setBlendEquations(GLenum blendEquationRGB, GLenum blendEquationAlpha)
1090 {
1091     if (mBlendEquationRGB != blendEquationRGB || mBlendEquationAlpha != blendEquationAlpha)
1092     {
1093         mBlendEquationRGB   = blendEquationRGB;
1094         mBlendEquationAlpha = blendEquationAlpha;
1095 
1096         mFunctions->blendEquationSeparate(mBlendEquationRGB, mBlendEquationAlpha);
1097 
1098         mLocalDirtyBits.set(gl::State::DIRTY_BIT_BLEND_EQUATIONS);
1099     }
1100 }
1101 
setColorMask(bool red,bool green,bool blue,bool alpha)1102 void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha)
1103 {
1104     if (mColorMaskRed != red || mColorMaskGreen != green || mColorMaskBlue != blue ||
1105         mColorMaskAlpha != alpha)
1106     {
1107         mColorMaskRed   = red;
1108         mColorMaskGreen = green;
1109         mColorMaskBlue  = blue;
1110         mColorMaskAlpha = alpha;
1111         mFunctions->colorMask(mColorMaskRed, mColorMaskGreen, mColorMaskBlue, mColorMaskAlpha);
1112 
1113         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COLOR_MASK);
1114     }
1115 }
1116 
setSampleAlphaToCoverageEnabled(bool enabled)1117 void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled)
1118 {
1119     if (mSampleAlphaToCoverageEnabled != enabled)
1120     {
1121         mSampleAlphaToCoverageEnabled = enabled;
1122         if (mSampleAlphaToCoverageEnabled)
1123         {
1124             mFunctions->enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1125         }
1126         else
1127         {
1128             mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1129         }
1130 
1131         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1132     }
1133 }
1134 
setSampleCoverageEnabled(bool enabled)1135 void StateManagerGL::setSampleCoverageEnabled(bool enabled)
1136 {
1137     if (mSampleCoverageEnabled != enabled)
1138     {
1139         mSampleCoverageEnabled = enabled;
1140         if (mSampleCoverageEnabled)
1141         {
1142             mFunctions->enable(GL_SAMPLE_COVERAGE);
1143         }
1144         else
1145         {
1146             mFunctions->disable(GL_SAMPLE_COVERAGE);
1147         }
1148 
1149         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1150     }
1151 }
1152 
setSampleCoverage(float value,bool invert)1153 void StateManagerGL::setSampleCoverage(float value, bool invert)
1154 {
1155     if (mSampleCoverageValue != value || mSampleCoverageInvert != invert)
1156     {
1157         mSampleCoverageValue  = value;
1158         mSampleCoverageInvert = invert;
1159         mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert);
1160 
1161         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_COVERAGE);
1162     }
1163 }
1164 
setSampleMaskEnabled(bool enabled)1165 void StateManagerGL::setSampleMaskEnabled(bool enabled)
1166 {
1167     if (mSampleMaskEnabled != enabled)
1168     {
1169         mSampleMaskEnabled = enabled;
1170         if (mSampleMaskEnabled)
1171         {
1172             mFunctions->enable(GL_SAMPLE_MASK);
1173         }
1174         else
1175         {
1176             mFunctions->disable(GL_SAMPLE_MASK);
1177         }
1178 
1179         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED);
1180     }
1181 }
1182 
setSampleMaski(GLuint maskNumber,GLbitfield mask)1183 void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
1184 {
1185     ASSERT(maskNumber < mSampleMaskValues.size());
1186     if (mSampleMaskValues[maskNumber] != mask)
1187     {
1188         mSampleMaskValues[maskNumber] = mask;
1189         mFunctions->sampleMaski(maskNumber, mask);
1190 
1191         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_MASK);
1192     }
1193 }
1194 
1195 // Depth and stencil redundant state changes are guarded in the
1196 // frontend so for related cases here just set the dirty bit
1197 // and update backend states.
setDepthTestEnabled(bool enabled)1198 void StateManagerGL::setDepthTestEnabled(bool enabled)
1199 {
1200     mDepthTestEnabled = enabled;
1201     if (mDepthTestEnabled)
1202     {
1203         mFunctions->enable(GL_DEPTH_TEST);
1204     }
1205     else
1206     {
1207         mFunctions->disable(GL_DEPTH_TEST);
1208     }
1209 
1210     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED);
1211 }
1212 
setDepthFunc(GLenum depthFunc)1213 void StateManagerGL::setDepthFunc(GLenum depthFunc)
1214 {
1215     mDepthFunc = depthFunc;
1216     mFunctions->depthFunc(mDepthFunc);
1217 
1218     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_FUNC);
1219 }
1220 
setDepthMask(bool mask)1221 void StateManagerGL::setDepthMask(bool mask)
1222 {
1223     mDepthMask = mask;
1224     mFunctions->depthMask(mDepthMask);
1225 
1226     mLocalDirtyBits.set(gl::State::DIRTY_BIT_DEPTH_MASK);
1227 }
1228 
setStencilTestEnabled(bool enabled)1229 void StateManagerGL::setStencilTestEnabled(bool enabled)
1230 {
1231     mStencilTestEnabled = enabled;
1232     if (mStencilTestEnabled)
1233     {
1234         mFunctions->enable(GL_STENCIL_TEST);
1235     }
1236     else
1237     {
1238         mFunctions->disable(GL_STENCIL_TEST);
1239     }
1240 
1241     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED);
1242 }
1243 
setStencilFrontWritemask(GLuint mask)1244 void StateManagerGL::setStencilFrontWritemask(GLuint mask)
1245 {
1246     mStencilFrontWritemask = mask;
1247     mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask);
1248 
1249     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
1250 }
1251 
setStencilBackWritemask(GLuint mask)1252 void StateManagerGL::setStencilBackWritemask(GLuint mask)
1253 {
1254     mStencilBackWritemask = mask;
1255     mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask);
1256 
1257     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
1258 }
1259 
setStencilFrontFuncs(GLenum func,GLint ref,GLuint mask)1260 void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask)
1261 {
1262     mStencilFrontFunc      = func;
1263     mStencilFrontRef       = ref;
1264     mStencilFrontValueMask = mask;
1265     mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef,
1266                                     mStencilFrontValueMask);
1267 
1268     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT);
1269 }
1270 
setStencilBackFuncs(GLenum func,GLint ref,GLuint mask)1271 void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask)
1272 {
1273     mStencilBackFunc      = func;
1274     mStencilBackRef       = ref;
1275     mStencilBackValueMask = mask;
1276     mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef,
1277                                     mStencilBackValueMask);
1278 
1279     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK);
1280 }
1281 
setStencilFrontOps(GLenum sfail,GLenum dpfail,GLenum dppass)1282 void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1283 {
1284     mStencilFrontStencilFailOp          = sfail;
1285     mStencilFrontStencilPassDepthFailOp = dpfail;
1286     mStencilFrontStencilPassDepthPassOp = dppass;
1287     mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp,
1288                                   mStencilFrontStencilPassDepthFailOp,
1289                                   mStencilFrontStencilPassDepthPassOp);
1290 
1291     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_FRONT);
1292 }
1293 
setStencilBackOps(GLenum sfail,GLenum dpfail,GLenum dppass)1294 void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1295 {
1296     mStencilBackStencilFailOp          = sfail;
1297     mStencilBackStencilPassDepthFailOp = dpfail;
1298     mStencilBackStencilPassDepthPassOp = dppass;
1299     mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp,
1300                                   mStencilBackStencilPassDepthFailOp,
1301                                   mStencilBackStencilPassDepthPassOp);
1302 
1303     mLocalDirtyBits.set(gl::State::DIRTY_BIT_STENCIL_OPS_BACK);
1304 }
1305 
setCullFaceEnabled(bool enabled)1306 void StateManagerGL::setCullFaceEnabled(bool enabled)
1307 {
1308     if (mCullFaceEnabled != enabled)
1309     {
1310         mCullFaceEnabled = enabled;
1311         if (mCullFaceEnabled)
1312         {
1313             mFunctions->enable(GL_CULL_FACE);
1314         }
1315         else
1316         {
1317             mFunctions->disable(GL_CULL_FACE);
1318         }
1319 
1320         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE_ENABLED);
1321     }
1322 }
1323 
setCullFace(gl::CullFaceMode cullFace)1324 void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
1325 {
1326     if (mCullFace != cullFace)
1327     {
1328         mCullFace = cullFace;
1329         mFunctions->cullFace(ToGLenum(mCullFace));
1330 
1331         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CULL_FACE);
1332     }
1333 }
1334 
setFrontFace(GLenum frontFace)1335 void StateManagerGL::setFrontFace(GLenum frontFace)
1336 {
1337     if (mFrontFace != frontFace)
1338     {
1339         mFrontFace = frontFace;
1340         mFunctions->frontFace(mFrontFace);
1341 
1342         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRONT_FACE);
1343     }
1344 }
1345 
setPolygonOffsetFillEnabled(bool enabled)1346 void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled)
1347 {
1348     if (mPolygonOffsetFillEnabled != enabled)
1349     {
1350         mPolygonOffsetFillEnabled = enabled;
1351         if (mPolygonOffsetFillEnabled)
1352         {
1353             mFunctions->enable(GL_POLYGON_OFFSET_FILL);
1354         }
1355         else
1356         {
1357             mFunctions->disable(GL_POLYGON_OFFSET_FILL);
1358         }
1359 
1360         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1361     }
1362 }
1363 
setPolygonOffset(float factor,float units)1364 void StateManagerGL::setPolygonOffset(float factor, float units)
1365 {
1366     if (mPolygonOffsetFactor != factor || mPolygonOffsetUnits != units)
1367     {
1368         mPolygonOffsetFactor = factor;
1369         mPolygonOffsetUnits  = units;
1370         mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits);
1371 
1372         mLocalDirtyBits.set(gl::State::DIRTY_BIT_POLYGON_OFFSET);
1373     }
1374 }
1375 
setRasterizerDiscardEnabled(bool enabled)1376 void StateManagerGL::setRasterizerDiscardEnabled(bool enabled)
1377 {
1378     if (mRasterizerDiscardEnabled != enabled)
1379     {
1380         mRasterizerDiscardEnabled = enabled;
1381         if (mRasterizerDiscardEnabled)
1382         {
1383             mFunctions->enable(GL_RASTERIZER_DISCARD);
1384         }
1385         else
1386         {
1387             mFunctions->disable(GL_RASTERIZER_DISCARD);
1388         }
1389 
1390         mLocalDirtyBits.set(gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
1391     }
1392 }
1393 
setLineWidth(float width)1394 void StateManagerGL::setLineWidth(float width)
1395 {
1396     if (mLineWidth != width)
1397     {
1398         mLineWidth = width;
1399         mFunctions->lineWidth(mLineWidth);
1400 
1401         mLocalDirtyBits.set(gl::State::DIRTY_BIT_LINE_WIDTH);
1402     }
1403 }
1404 
setPrimitiveRestartEnabled(bool enabled)1405 void StateManagerGL::setPrimitiveRestartEnabled(bool enabled)
1406 {
1407     if (mPrimitiveRestartEnabled != enabled)
1408     {
1409         mPrimitiveRestartEnabled = enabled;
1410 
1411         if (mPrimitiveRestartEnabled)
1412         {
1413             mFunctions->enable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
1414         }
1415         else
1416         {
1417             mFunctions->disable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
1418         }
1419 
1420         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1421     }
1422 }
1423 
setClearDepth(float clearDepth)1424 void StateManagerGL::setClearDepth(float clearDepth)
1425 {
1426     if (mClearDepth != clearDepth)
1427     {
1428         mClearDepth = clearDepth;
1429 
1430         // The glClearDepthf function isn't available until OpenGL 4.1.  Prefer it when it is
1431         // available because OpenGL ES only works in floats.
1432         if (mFunctions->clearDepthf)
1433         {
1434             mFunctions->clearDepthf(mClearDepth);
1435         }
1436         else
1437         {
1438             ASSERT(mFunctions->clearDepth);
1439             mFunctions->clearDepth(mClearDepth);
1440         }
1441 
1442         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_DEPTH);
1443     }
1444 }
1445 
setClearColor(const gl::ColorF & clearColor)1446 void StateManagerGL::setClearColor(const gl::ColorF &clearColor)
1447 {
1448     gl::ColorF modifiedClearColor = clearColor;
1449     if (mFeatures.clearToZeroOrOneBroken.enabled &&
1450         (clearColor.red == 1.0f || clearColor.red == 0.0f) &&
1451         (clearColor.green == 1.0f || clearColor.green == 0.0f) &&
1452         (clearColor.blue == 1.0f || clearColor.blue == 0.0f) &&
1453         (clearColor.alpha == 1.0f || clearColor.alpha == 0.0f))
1454     {
1455         if (clearColor.alpha == 1.0f)
1456         {
1457             modifiedClearColor.alpha = 2.0f;
1458         }
1459         else
1460         {
1461             modifiedClearColor.alpha = -1.0f;
1462         }
1463     }
1464 
1465     if (mClearColor != modifiedClearColor)
1466     {
1467         mClearColor = modifiedClearColor;
1468         mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue,
1469                                mClearColor.alpha);
1470 
1471         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_COLOR);
1472     }
1473 }
1474 
setClearStencil(GLint clearStencil)1475 void StateManagerGL::setClearStencil(GLint clearStencil)
1476 {
1477     if (mClearStencil != clearStencil)
1478     {
1479         mClearStencil = clearStencil;
1480         mFunctions->clearStencil(mClearStencil);
1481 
1482         mLocalDirtyBits.set(gl::State::DIRTY_BIT_CLEAR_STENCIL);
1483     }
1484 }
1485 
syncState(const gl::Context * context,const gl::State::DirtyBits & glDirtyBits,const gl::State::DirtyBits & bitMask)1486 void StateManagerGL::syncState(const gl::Context *context,
1487                                const gl::State::DirtyBits &glDirtyBits,
1488                                const gl::State::DirtyBits &bitMask)
1489 {
1490     const gl::State &state = context->getState();
1491 
1492     const gl::State::DirtyBits glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits) & bitMask;
1493     if (!glAndLocalDirtyBits.any())
1494     {
1495         return;
1496     }
1497 
1498     // TODO(jmadill): Investigate only syncing vertex state for active attributes
1499     for (auto iter = glAndLocalDirtyBits.begin(), endIter = glAndLocalDirtyBits.end();
1500          iter != endIter; ++iter)
1501     {
1502         switch (*iter)
1503         {
1504             case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
1505                 setScissorTestEnabled(state.isScissorTestEnabled());
1506                 break;
1507             case gl::State::DIRTY_BIT_SCISSOR:
1508             {
1509                 const gl::Rectangle &scissor = state.getScissor();
1510                 setScissor(scissor);
1511             }
1512             break;
1513             case gl::State::DIRTY_BIT_VIEWPORT:
1514             {
1515                 const gl::Rectangle &viewport = state.getViewport();
1516                 setViewport(viewport);
1517             }
1518             break;
1519             case gl::State::DIRTY_BIT_DEPTH_RANGE:
1520                 setDepthRange(state.getNearPlane(), state.getFarPlane());
1521                 break;
1522             case gl::State::DIRTY_BIT_BLEND_ENABLED:
1523                 setBlendEnabled(state.isBlendEnabled());
1524                 break;
1525             case gl::State::DIRTY_BIT_BLEND_COLOR:
1526                 setBlendColor(state.getBlendColor());
1527                 break;
1528             case gl::State::DIRTY_BIT_BLEND_FUNCS:
1529             {
1530                 const auto &blendState = state.getBlendState();
1531                 setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB,
1532                               blendState.sourceBlendAlpha, blendState.destBlendAlpha);
1533                 break;
1534             }
1535             case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
1536             {
1537                 const auto &blendState = state.getBlendState();
1538                 setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha);
1539                 break;
1540             }
1541             case gl::State::DIRTY_BIT_COLOR_MASK:
1542             {
1543                 gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1544                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1545 
1546                 const auto &blendState = state.getBlendState();
1547                 setColorMaskForFramebuffer(blendState.colorMaskRed, blendState.colorMaskGreen,
1548                                            blendState.colorMaskBlue, blendState.colorMaskAlpha,
1549                                            framebufferGL);
1550                 break;
1551             }
1552             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
1553                 setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
1554                 break;
1555             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
1556                 setSampleCoverageEnabled(state.isSampleCoverageEnabled());
1557                 break;
1558             case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
1559                 setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
1560                 break;
1561             case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
1562                 setDepthTestEnabled(state.isDepthTestEnabled());
1563                 break;
1564             case gl::State::DIRTY_BIT_DEPTH_FUNC:
1565                 setDepthFunc(state.getDepthStencilState().depthFunc);
1566                 break;
1567             case gl::State::DIRTY_BIT_DEPTH_MASK:
1568                 setDepthMask(state.getDepthStencilState().depthMask);
1569                 break;
1570             case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
1571                 setStencilTestEnabled(state.isStencilTestEnabled());
1572                 break;
1573             case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
1574             {
1575                 const auto &depthStencilState = state.getDepthStencilState();
1576                 setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
1577                                      depthStencilState.stencilMask);
1578                 break;
1579             }
1580             case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
1581             {
1582                 const auto &depthStencilState = state.getDepthStencilState();
1583                 setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
1584                                     depthStencilState.stencilBackMask);
1585                 break;
1586             }
1587             case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
1588             {
1589                 const auto &depthStencilState = state.getDepthStencilState();
1590                 setStencilFrontOps(depthStencilState.stencilFail,
1591                                    depthStencilState.stencilPassDepthFail,
1592                                    depthStencilState.stencilPassDepthPass);
1593                 break;
1594             }
1595             case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
1596             {
1597                 const auto &depthStencilState = state.getDepthStencilState();
1598                 setStencilBackOps(depthStencilState.stencilBackFail,
1599                                   depthStencilState.stencilBackPassDepthFail,
1600                                   depthStencilState.stencilBackPassDepthPass);
1601                 break;
1602             }
1603             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
1604                 setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
1605                 break;
1606             case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
1607                 setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
1608                 break;
1609             case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
1610                 setCullFaceEnabled(state.isCullFaceEnabled());
1611                 break;
1612             case gl::State::DIRTY_BIT_CULL_FACE:
1613                 setCullFace(state.getRasterizerState().cullMode);
1614                 break;
1615             case gl::State::DIRTY_BIT_FRONT_FACE:
1616                 setFrontFace(state.getRasterizerState().frontFace);
1617                 break;
1618             case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
1619                 setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
1620                 break;
1621             case gl::State::DIRTY_BIT_POLYGON_OFFSET:
1622             {
1623                 const auto &rasterizerState = state.getRasterizerState();
1624                 setPolygonOffset(rasterizerState.polygonOffsetFactor,
1625                                  rasterizerState.polygonOffsetUnits);
1626                 break;
1627             }
1628             case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
1629                 setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
1630                 break;
1631             case gl::State::DIRTY_BIT_LINE_WIDTH:
1632                 setLineWidth(state.getLineWidth());
1633                 break;
1634             case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
1635                 setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled());
1636                 break;
1637             case gl::State::DIRTY_BIT_CLEAR_COLOR:
1638                 setClearColor(state.getColorClearValue());
1639                 break;
1640             case gl::State::DIRTY_BIT_CLEAR_DEPTH:
1641                 setClearDepth(state.getDepthClearValue());
1642                 break;
1643             case gl::State::DIRTY_BIT_CLEAR_STENCIL:
1644                 setClearStencil(state.getStencilClearValue());
1645                 break;
1646             case gl::State::DIRTY_BIT_UNPACK_STATE:
1647                 setPixelUnpackState(state.getUnpackState());
1648                 break;
1649             case gl::State::DIRTY_BIT_UNPACK_BUFFER_BINDING:
1650                 setPixelUnpackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelUnpack));
1651                 break;
1652             case gl::State::DIRTY_BIT_PACK_STATE:
1653                 setPixelPackState(state.getPackState());
1654                 break;
1655             case gl::State::DIRTY_BIT_PACK_BUFFER_BINDING:
1656                 setPixelPackBuffer(state.getTargetBuffer(gl::BufferBinding::PixelPack));
1657                 break;
1658             case gl::State::DIRTY_BIT_DITHER_ENABLED:
1659                 setDitherEnabled(state.isDitherEnabled());
1660                 break;
1661             case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT:
1662                 // TODO(jmadill): implement this
1663                 break;
1664             case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT:
1665                 // TODO(jmadill): implement this
1666                 break;
1667             case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
1668             {
1669                 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
1670 
1671                 // Necessary for an Intel TexImage workaround.
1672                 if (!framebuffer)
1673                     continue;
1674 
1675                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1676                 bindFramebuffer(GL_READ_FRAMEBUFFER, framebufferGL->getFramebufferID());
1677                 break;
1678             }
1679             case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
1680             {
1681                 gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
1682 
1683                 // Necessary for an Intel TexImage workaround.
1684                 if (!framebuffer)
1685                     continue;
1686 
1687                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
1688                 bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
1689 
1690                 const gl::Program *program = state.getProgram();
1691                 if (program)
1692                 {
1693                     updateMultiviewBaseViewLayerIndexUniform(program, framebufferGL->getState());
1694                 }
1695 
1696                 // Changing the draw framebuffer binding sometimes requires resetting srgb blending.
1697                 if (mFunctions->standard == STANDARD_GL_DESKTOP)
1698                 {
1699                     iter.setLaterBit(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
1700                 }
1701 
1702                 // If the framebuffer is emulating RGB on top of RGBA, the color mask has to be
1703                 // updated
1704                 iter.setLaterBit(gl::State::DIRTY_BIT_COLOR_MASK);
1705                 break;
1706             }
1707             case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
1708                 // TODO(jmadill): implement this
1709                 break;
1710             case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
1711             {
1712                 const VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
1713                 bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getAppliedElementArrayBufferID());
1714 
1715                 propagateProgramToVAO(state.getProgram(),
1716                                       GetImplAs<VertexArrayGL>(state.getVertexArray()));
1717                 break;
1718             }
1719             case gl::State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
1720                 updateDrawIndirectBufferBinding(context);
1721                 break;
1722             case gl::State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
1723                 updateDispatchIndirectBufferBinding(context);
1724                 break;
1725             case gl::State::DIRTY_BIT_PROGRAM_BINDING:
1726             {
1727                 gl::Program *program = state.getProgram();
1728                 if (program != nullptr)
1729                 {
1730                     useProgram(GetImplAs<ProgramGL>(program)->getProgramID());
1731                 }
1732                 break;
1733             }
1734             case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
1735             {
1736                 const gl::Program *program = state.getProgram();
1737                 if (program)
1738                 {
1739                     iter.setLaterBit(gl::State::DIRTY_BIT_TEXTURE_BINDINGS);
1740 
1741                     if (program->getActiveImagesMask().any())
1742                     {
1743                         iter.setLaterBit(gl::State::DIRTY_BIT_IMAGE_BINDINGS);
1744                     }
1745 
1746                     if (program->getActiveShaderStorageBlockCount() > 0)
1747                     {
1748                         iter.setLaterBit(gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
1749                     }
1750 
1751                     if (program->getActiveUniformBlockCount() > 0)
1752                     {
1753                         iter.setLaterBit(gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
1754                     }
1755 
1756                     if (program->getActiveAtomicCounterBufferCount() > 0)
1757                     {
1758                         iter.setLaterBit(gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
1759                     }
1760 
1761                     if (mIsMultiviewEnabled && program->usesMultiview())
1762                     {
1763                         updateMultiviewBaseViewLayerIndexUniform(
1764                             program, state.getDrawFramebuffer()->getImplementation()->getState());
1765                     }
1766                 }
1767 
1768                 if (!program || !program->hasLinkedShaderStage(gl::ShaderType::Compute))
1769                 {
1770                     propagateProgramToVAO(program,
1771                                           GetImplAs<VertexArrayGL>(state.getVertexArray()));
1772                 }
1773                 break;
1774             }
1775             case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
1776                 updateProgramTextureBindings(context);
1777                 break;
1778             case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
1779                 syncSamplersState(context);
1780                 break;
1781             case gl::State::DIRTY_BIT_IMAGE_BINDINGS:
1782                 updateProgramImageBindings(context);
1783                 break;
1784             case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
1785                 syncTransformFeedbackState(context);
1786                 break;
1787             case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
1788                 updateProgramStorageBufferBindings(context);
1789                 break;
1790             case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
1791                 updateProgramUniformBufferBindings(context);
1792                 break;
1793             case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
1794                 updateProgramAtomicCounterBufferBindings(context);
1795                 break;
1796             case gl::State::DIRTY_BIT_MULTISAMPLING:
1797                 setMultisamplingStateEnabled(state.isMultisamplingEnabled());
1798                 break;
1799             case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
1800                 setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
1801                 break;
1802             case gl::State::DIRTY_BIT_COVERAGE_MODULATION:
1803                 setCoverageModulation(state.getCoverageModulation());
1804                 break;
1805             case gl::State::DIRTY_BIT_PATH_RENDERING:
1806                 setPathRenderingModelViewMatrix(
1807                     state.getPathRenderingMatrix(GL_PATH_MODELVIEW_MATRIX_CHROMIUM));
1808                 setPathRenderingProjectionMatrix(
1809                     state.getPathRenderingMatrix(GL_PATH_PROJECTION_MATRIX_CHROMIUM));
1810                 setPathRenderingStencilState(state.getPathStencilFunc(), state.getPathStencilRef(),
1811                                              state.getPathStencilMask());
1812                 break;
1813             case gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB:
1814                 setFramebufferSRGBEnabledForFramebuffer(
1815                     context, state.getFramebufferSRGB(),
1816                     GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
1817                 break;
1818             case gl::State::DIRTY_BIT_SAMPLE_MASK_ENABLED:
1819                 setSampleMaskEnabled(state.isSampleMaskEnabled());
1820                 break;
1821             case gl::State::DIRTY_BIT_SAMPLE_MASK:
1822             {
1823                 for (GLuint maskNumber = 0; maskNumber < state.getMaxSampleMaskWords();
1824                      ++maskNumber)
1825                 {
1826                     setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
1827                 }
1828                 break;
1829             }
1830             case gl::State::DIRTY_BIT_CURRENT_VALUES:
1831             {
1832                 gl::AttributesMask combinedMask =
1833                     (state.getAndResetDirtyCurrentValues() | mLocalDirtyCurrentValues);
1834                 mLocalDirtyCurrentValues.reset();
1835 
1836                 for (auto attribIndex : combinedMask)
1837                 {
1838                     setAttributeCurrentData(attribIndex,
1839                                             state.getVertexAttribCurrentValue(attribIndex));
1840                 }
1841                 break;
1842             }
1843             case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
1844                 setProvokingVertex(ToGLenum(state.getProvokingVertex()));
1845                 break;
1846             default:
1847                 UNREACHABLE();
1848                 break;
1849         }
1850     }
1851 
1852     mLocalDirtyBits &= ~(bitMask);
1853 }
1854 
setFramebufferSRGBEnabled(const gl::Context * context,bool enabled)1855 void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
1856 {
1857     if (!context->getExtensions().sRGBWriteControl)
1858     {
1859         return;
1860     }
1861 
1862     if (mFramebufferSRGBEnabled != enabled)
1863     {
1864         mFramebufferSRGBEnabled = enabled;
1865         if (mFramebufferSRGBEnabled)
1866         {
1867             mFunctions->enable(GL_FRAMEBUFFER_SRGB);
1868         }
1869         else
1870         {
1871             mFunctions->disable(GL_FRAMEBUFFER_SRGB);
1872         }
1873         mLocalDirtyBits.set(gl::State::DIRTY_BIT_FRAMEBUFFER_SRGB);
1874     }
1875 }
1876 
setFramebufferSRGBEnabledForFramebuffer(const gl::Context * context,bool enabled,const FramebufferGL * framebuffer)1877 void StateManagerGL::setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
1878                                                              bool enabled,
1879                                                              const FramebufferGL *framebuffer)
1880 {
1881     if (mFunctions->standard == STANDARD_GL_DESKTOP && framebuffer->isDefault())
1882     {
1883         // Obey the framebuffer sRGB state for blending on all framebuffers except the default
1884         // framebuffer on Desktop OpenGL.
1885         // When SRGB blending is enabled, only SRGB capable formats will use it but the default
1886         // framebuffer will always use it if it is enabled.
1887         // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists.
1888         setFramebufferSRGBEnabled(context, false);
1889     }
1890     else
1891     {
1892         setFramebufferSRGBEnabled(context, enabled);
1893     }
1894 }
1895 
setColorMaskForFramebuffer(bool red,bool green,bool blue,bool alpha,const FramebufferGL * framebuffer)1896 void StateManagerGL::setColorMaskForFramebuffer(bool red,
1897                                                 bool green,
1898                                                 bool blue,
1899                                                 bool alpha,
1900                                                 const FramebufferGL *framebuffer)
1901 {
1902     bool modifiedAlphaMask = alpha;
1903     if (framebuffer->hasEmulatedAlphaChannelTextureAttachment())
1904     {
1905         modifiedAlphaMask = false;
1906     }
1907     setColorMask(red, green, blue, modifiedAlphaMask);
1908 }
1909 
setDitherEnabled(bool enabled)1910 void StateManagerGL::setDitherEnabled(bool enabled)
1911 {
1912     if (mDitherEnabled != enabled)
1913     {
1914         mDitherEnabled = enabled;
1915         if (mDitherEnabled)
1916         {
1917             mFunctions->enable(GL_DITHER);
1918         }
1919         else
1920         {
1921             mFunctions->disable(GL_DITHER);
1922         }
1923     }
1924 }
1925 
setMultisamplingStateEnabled(bool enabled)1926 void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
1927 {
1928     if (mMultisamplingEnabled != enabled)
1929     {
1930         mMultisamplingEnabled = enabled;
1931         if (mMultisamplingEnabled)
1932         {
1933             mFunctions->enable(GL_MULTISAMPLE_EXT);
1934         }
1935         else
1936         {
1937             mFunctions->disable(GL_MULTISAMPLE_EXT);
1938         }
1939         mLocalDirtyBits.set(gl::State::DIRTY_BIT_MULTISAMPLING);
1940     }
1941 }
1942 
setSampleAlphaToOneStateEnabled(bool enabled)1943 void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
1944 {
1945     if (mSampleAlphaToOneEnabled != enabled)
1946     {
1947         mSampleAlphaToOneEnabled = enabled;
1948         if (mSampleAlphaToOneEnabled)
1949         {
1950             mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
1951         }
1952         else
1953         {
1954             mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
1955         }
1956         mLocalDirtyBits.set(gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
1957     }
1958 }
1959 
setCoverageModulation(GLenum components)1960 void StateManagerGL::setCoverageModulation(GLenum components)
1961 {
1962     if (mCoverageModulation != components)
1963     {
1964         mCoverageModulation = components;
1965         mFunctions->coverageModulationNV(components);
1966 
1967         mLocalDirtyBits.set(gl::State::DIRTY_BIT_COVERAGE_MODULATION);
1968     }
1969 }
1970 
setPathRenderingModelViewMatrix(const GLfloat * m)1971 void StateManagerGL::setPathRenderingModelViewMatrix(const GLfloat *m)
1972 {
1973     if (memcmp(mPathMatrixMV, m, sizeof(mPathMatrixMV)) != 0)
1974     {
1975         memcpy(mPathMatrixMV, m, sizeof(mPathMatrixMV));
1976         mFunctions->matrixLoadfEXT(GL_PATH_MODELVIEW_CHROMIUM, m);
1977 
1978         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING);
1979     }
1980 }
1981 
setPathRenderingProjectionMatrix(const GLfloat * m)1982 void StateManagerGL::setPathRenderingProjectionMatrix(const GLfloat *m)
1983 {
1984     if (memcmp(mPathMatrixProj, m, sizeof(mPathMatrixProj)) != 0)
1985     {
1986         memcpy(mPathMatrixProj, m, sizeof(mPathMatrixProj));
1987         mFunctions->matrixLoadfEXT(GL_PATH_PROJECTION_CHROMIUM, m);
1988 
1989         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING);
1990     }
1991 }
1992 
setPathRenderingStencilState(GLenum func,GLint ref,GLuint mask)1993 void StateManagerGL::setPathRenderingStencilState(GLenum func, GLint ref, GLuint mask)
1994 {
1995     if (func != mPathStencilFunc || ref != mPathStencilRef || mask != mPathStencilMask)
1996     {
1997         mPathStencilFunc = func;
1998         mPathStencilRef  = ref;
1999         mPathStencilMask = mask;
2000         mFunctions->pathStencilFuncNV(func, ref, mask);
2001 
2002         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PATH_RENDERING);
2003     }
2004 }
2005 
setProvokingVertex(GLenum mode)2006 void StateManagerGL::setProvokingVertex(GLenum mode)
2007 {
2008     if (mode != mProvokingVertex)
2009     {
2010         mFunctions->provokingVertex(mode);
2011         mProvokingVertex = mode;
2012 
2013         mLocalDirtyBits.set(gl::State::DIRTY_BIT_PROVOKING_VERTEX);
2014     }
2015 }
2016 
setTextureCubemapSeamlessEnabled(bool enabled)2017 void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
2018 {
2019     // TODO(jmadill): Also check for seamless extension.
2020     if (!mFunctions->isAtLeastGL(gl::Version(3, 2)))
2021     {
2022         return;
2023     }
2024 
2025     if (mTextureCubemapSeamlessEnabled != enabled)
2026     {
2027         mTextureCubemapSeamlessEnabled = enabled;
2028         if (mTextureCubemapSeamlessEnabled)
2029         {
2030             mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2031         }
2032         else
2033         {
2034             mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2035         }
2036     }
2037 }
2038 
propagateProgramToVAO(const gl::Program * program,VertexArrayGL * vao)2039 void StateManagerGL::propagateProgramToVAO(const gl::Program *program, VertexArrayGL *vao)
2040 {
2041     if (vao == nullptr)
2042     {
2043         return;
2044     }
2045 
2046     // Number of views:
2047     if (mIsMultiviewEnabled)
2048     {
2049         int programNumViews = 1;
2050         if (program && program->usesMultiview())
2051         {
2052             programNumViews = program->getNumViews();
2053         }
2054         vao->applyNumViewsToDivisor(programNumViews);
2055     }
2056 
2057     // Attribute enabled mask:
2058     if (program)
2059     {
2060         vao->applyActiveAttribLocationsMask(program->getActiveAttribLocationsMask());
2061     }
2062 }
2063 
updateMultiviewBaseViewLayerIndexUniformImpl(const gl::Program * program,const gl::FramebufferState & drawFramebufferState) const2064 void StateManagerGL::updateMultiviewBaseViewLayerIndexUniformImpl(
2065     const gl::Program *program,
2066     const gl::FramebufferState &drawFramebufferState) const
2067 {
2068     ASSERT(mIsMultiviewEnabled && program && program->usesMultiview());
2069     const ProgramGL *programGL = GetImplAs<ProgramGL>(program);
2070     if (drawFramebufferState.isMultiview())
2071     {
2072         programGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
2073     }
2074 }
2075 
syncSamplersState(const gl::Context * context)2076 void StateManagerGL::syncSamplersState(const gl::Context *context)
2077 {
2078     const gl::State::SamplerBindingVector &samplers = context->getState().getSamplers();
2079 
2080     // This could be optimized by using a separate binding dirty bit per sampler.
2081     for (size_t samplerIndex = 0; samplerIndex < samplers.size(); ++samplerIndex)
2082     {
2083         const gl::Sampler *sampler = samplers[samplerIndex].get();
2084         if (sampler != nullptr)
2085         {
2086             SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
2087             bindSampler(samplerIndex, samplerGL->getSamplerID());
2088         }
2089         else
2090         {
2091             bindSampler(samplerIndex, 0);
2092         }
2093     }
2094 }
2095 
syncTransformFeedbackState(const gl::Context * context)2096 void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
2097 {
2098     // Set the current transform feedback state
2099     gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
2100     if (transformFeedback)
2101     {
2102         TransformFeedbackGL *transformFeedbackGL =
2103             GetImplAs<TransformFeedbackGL>(transformFeedback);
2104         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
2105         transformFeedbackGL->syncActiveState(context, transformFeedback->isActive(),
2106                                              transformFeedback->getPrimitiveMode());
2107         transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
2108         mCurrentTransformFeedback = transformFeedbackGL;
2109     }
2110     else
2111     {
2112         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
2113         mCurrentTransformFeedback = nullptr;
2114     }
2115 }
2116 }  // namespace rx
2117