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