1 //
2 // Copyright 2014 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 // State.cpp: Implements the State class, encapsulating raw GL state.
8
9 #include "libANGLE/State.h"
10
11 #include <string.h>
12 #include <limits>
13
14 #include "common/bitset_utils.h"
15 #include "common/mathutil.h"
16 #include "common/matrix_utils.h"
17 #include "libANGLE/Buffer.h"
18 #include "libANGLE/Caps.h"
19 #include "libANGLE/Context.h"
20 #include "libANGLE/Debug.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/FramebufferAttachment.h"
23 #include "libANGLE/Query.h"
24 #include "libANGLE/VertexArray.h"
25 #include "libANGLE/formatutils.h"
26 #include "libANGLE/queryconversions.h"
27 #include "libANGLE/queryutils.h"
28 #include "libANGLE/renderer/ContextImpl.h"
29 #include "libANGLE/renderer/TextureImpl.h"
30
31 namespace gl
32 {
33
34 namespace
35 {
GetAlternativeQueryType(QueryType type,QueryType * alternativeType)36 bool GetAlternativeQueryType(QueryType type, QueryType *alternativeType)
37 {
38 switch (type)
39 {
40 case QueryType::AnySamples:
41 *alternativeType = QueryType::AnySamplesConservative;
42 return true;
43 case QueryType::AnySamplesConservative:
44 *alternativeType = QueryType::AnySamples;
45 return true;
46 default:
47 return false;
48 }
49 }
50
51 // Mapping from a buffer binding type to a dirty bit type.
52 constexpr angle::PackedEnumMap<BufferBinding, size_t> kBufferBindingDirtyBits = {{
53 {BufferBinding::AtomicCounter, State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING},
54 {BufferBinding::DispatchIndirect, State::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING},
55 {BufferBinding::DrawIndirect, State::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING},
56 {BufferBinding::PixelPack, State::DIRTY_BIT_PACK_BUFFER_BINDING},
57 {BufferBinding::PixelUnpack, State::DIRTY_BIT_UNPACK_BUFFER_BINDING},
58 {BufferBinding::ShaderStorage, State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING},
59 {BufferBinding::Uniform, State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS},
60 }};
61
62 // Returns a buffer binding function depending on if a dirty bit is set.
63 template <BufferBinding Target>
GetBufferBindingSetter()64 constexpr std::pair<BufferBinding, State::BufferBindingSetter> GetBufferBindingSetter()
65 {
66 return std::make_pair(Target, kBufferBindingDirtyBits[Target] != 0
67 ? &State::setGenericBufferBindingWithBit<Target>
68 : &State::setGenericBufferBinding<Target>);
69 }
70
71 template <typename T>
72 using ContextStateMember = T *(State::*);
73
74 template <typename T>
AllocateOrGetSharedResourceManager(const State * shareContextState,ContextStateMember<T> member)75 T *AllocateOrGetSharedResourceManager(const State *shareContextState, ContextStateMember<T> member)
76 {
77 if (shareContextState)
78 {
79 T *resourceManager = (*shareContextState).*member;
80 resourceManager->addRef();
81 return resourceManager;
82 }
83 else
84 {
85 return new T();
86 }
87 }
88
AllocateOrGetSharedTextureManager(const State * shareContextState,TextureManager * shareTextures,ContextStateMember<TextureManager> member)89 TextureManager *AllocateOrGetSharedTextureManager(const State *shareContextState,
90 TextureManager *shareTextures,
91 ContextStateMember<TextureManager> member)
92 {
93 if (shareContextState)
94 {
95 TextureManager *textureManager = (*shareContextState).*member;
96 ASSERT(shareTextures == nullptr || textureManager == shareTextures);
97 textureManager->addRef();
98 return textureManager;
99 }
100 else if (shareTextures)
101 {
102 TextureManager *textureManager = shareTextures;
103 textureManager->addRef();
104 return textureManager;
105 }
106 else
107 {
108 return new TextureManager();
109 }
110 }
111 } // namespace
112
113 template <typename BindingT, typename... ArgsT>
UpdateNonTFBufferBinding(const Context * context,BindingT * binding,Buffer * buffer,ArgsT...args)114 ANGLE_INLINE void UpdateNonTFBufferBinding(const Context *context,
115 BindingT *binding,
116 Buffer *buffer,
117 ArgsT... args)
118 {
119 Buffer *oldBuffer = binding->get();
120 if (oldBuffer)
121 {
122 oldBuffer->onNonTFBindingChanged(-1);
123 oldBuffer->release(context);
124 }
125 binding->assign(buffer, args...);
126 if (buffer)
127 {
128 buffer->addRef();
129 buffer->onNonTFBindingChanged(1);
130 }
131 }
132
133 template <typename BindingT, typename... ArgsT>
UpdateTFBufferBinding(const Context * context,BindingT * binding,bool indexed,ArgsT...args)134 void UpdateTFBufferBinding(const Context *context, BindingT *binding, bool indexed, ArgsT... args)
135 {
136 if (binding->get())
137 (*binding)->onTFBindingChanged(context, false, indexed);
138 binding->set(context, args...);
139 if (binding->get())
140 (*binding)->onTFBindingChanged(context, true, indexed);
141 }
142
UpdateBufferBinding(const Context * context,BindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target)143 void UpdateBufferBinding(const Context *context,
144 BindingPointer<Buffer> *binding,
145 Buffer *buffer,
146 BufferBinding target)
147 {
148 if (target == BufferBinding::TransformFeedback)
149 {
150 UpdateTFBufferBinding(context, binding, false, buffer);
151 }
152 else
153 {
154 UpdateNonTFBufferBinding(context, binding, buffer);
155 }
156 }
157
UpdateIndexedBufferBinding(const Context * context,OffsetBindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target,GLintptr offset,GLsizeiptr size)158 void UpdateIndexedBufferBinding(const Context *context,
159 OffsetBindingPointer<Buffer> *binding,
160 Buffer *buffer,
161 BufferBinding target,
162 GLintptr offset,
163 GLsizeiptr size)
164 {
165 if (target == BufferBinding::TransformFeedback)
166 {
167 UpdateTFBufferBinding(context, binding, true, buffer, offset, size);
168 }
169 else
170 {
171 UpdateNonTFBufferBinding(context, binding, buffer, offset, size);
172 }
173 }
174
175 // These template functions must be defined before they are instantiated in kBufferSetters.
176 template <BufferBinding Target>
setGenericBufferBindingWithBit(const Context * context,Buffer * buffer)177 void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer)
178 {
179 UpdateNonTFBufferBinding(context, &mBoundBuffers[Target], buffer);
180 mDirtyBits.set(kBufferBindingDirtyBits[Target]);
181 }
182
183 template <BufferBinding Target>
setGenericBufferBinding(const Context * context,Buffer * buffer)184 void State::setGenericBufferBinding(const Context *context, Buffer *buffer)
185 {
186 UpdateNonTFBufferBinding(context, &mBoundBuffers[Target], buffer);
187 }
188
189 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)190 void State::setGenericBufferBinding<BufferBinding::TransformFeedback>(const Context *context,
191 Buffer *buffer)
192 {
193 UpdateTFBufferBinding(context, &mBoundBuffers[BufferBinding::TransformFeedback], false, buffer);
194 }
195
196 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)197 void State::setGenericBufferBinding<BufferBinding::ElementArray>(const Context *context,
198 Buffer *buffer)
199 {
200 Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get();
201 if (oldBuffer)
202 {
203 oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer);
204 oldBuffer->onNonTFBindingChanged(-1);
205 oldBuffer->release(context);
206 }
207 mVertexArray->mState.mElementArrayBuffer.assign(buffer);
208 if (buffer)
209 {
210 buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer);
211 buffer->onNonTFBindingChanged(1);
212 buffer->addRef();
213 }
214 mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
215 mVertexArray->mIndexRangeCache.invalidate();
216 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
217 }
218
219 const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBufferSetters = {{
220 GetBufferBindingSetter<BufferBinding::Array>(),
221 GetBufferBindingSetter<BufferBinding::AtomicCounter>(),
222 GetBufferBindingSetter<BufferBinding::CopyRead>(),
223 GetBufferBindingSetter<BufferBinding::CopyWrite>(),
224 GetBufferBindingSetter<BufferBinding::DispatchIndirect>(),
225 GetBufferBindingSetter<BufferBinding::DrawIndirect>(),
226 GetBufferBindingSetter<BufferBinding::ElementArray>(),
227 GetBufferBindingSetter<BufferBinding::PixelPack>(),
228 GetBufferBindingSetter<BufferBinding::PixelUnpack>(),
229 GetBufferBindingSetter<BufferBinding::ShaderStorage>(),
230 GetBufferBindingSetter<BufferBinding::TransformFeedback>(),
231 GetBufferBindingSetter<BufferBinding::Uniform>(),
232 }};
233
State(ContextID contextIn,const State * shareContextState,TextureManager * shareTextures,const EGLenum clientType,const Version & clientVersion,bool debug,bool bindGeneratesResource,bool clientArraysEnabled,bool robustResourceInit,bool programBinaryCacheEnabled)234 State::State(ContextID contextIn,
235 const State *shareContextState,
236 TextureManager *shareTextures,
237 const EGLenum clientType,
238 const Version &clientVersion,
239 bool debug,
240 bool bindGeneratesResource,
241 bool clientArraysEnabled,
242 bool robustResourceInit,
243 bool programBinaryCacheEnabled)
244 : mClientType(clientType),
245 mClientVersion(clientVersion),
246 mContext(contextIn),
247 mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
248 mShaderProgramManager(
249 AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
250 mTextureManager(AllocateOrGetSharedTextureManager(shareContextState,
251 shareTextures,
252 &State::mTextureManager)),
253 mRenderbufferManager(
254 AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
255 mSamplerManager(
256 AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)),
257 mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)),
258 mPathManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mPathManager)),
259 mFramebufferManager(new FramebufferManager()),
260 mProgramPipelineManager(new ProgramPipelineManager()),
261 mMemoryObjectManager(
262 AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
263 mSemaphoreManager(
264 AllocateOrGetSharedResourceManager(shareContextState, &State::mSemaphoreManager)),
265 mMaxDrawBuffers(0),
266 mMaxCombinedTextureImageUnits(0),
267 mDepthClearValue(0),
268 mStencilClearValue(0),
269 mScissorTest(false),
270 mSampleCoverage(false),
271 mSampleCoverageValue(0),
272 mSampleCoverageInvert(false),
273 mSampleMask(false),
274 mMaxSampleMaskWords(0),
275 mStencilRef(0),
276 mStencilBackRef(0),
277 mLineWidth(0),
278 mGenerateMipmapHint(GL_NONE),
279 mFragmentShaderDerivativeHint(GL_NONE),
280 mBindGeneratesResource(bindGeneratesResource),
281 mClientArraysEnabled(clientArraysEnabled),
282 mNearZ(0),
283 mFarZ(0),
284 mReadFramebuffer(nullptr),
285 mDrawFramebuffer(nullptr),
286 mProgram(nullptr),
287 mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention),
288 mVertexArray(nullptr),
289 mActiveSampler(0),
290 mActiveTexturesCache{},
291 mTexturesIncompatibleWithSamplers(0),
292 mPrimitiveRestart(false),
293 mDebug(debug),
294 mMultiSampling(false),
295 mSampleAlphaToOne(false),
296 mFramebufferSRGB(true),
297 mRobustResourceInit(robustResourceInit),
298 mProgramBinaryCacheEnabled(programBinaryCacheEnabled),
299 mMaxShaderCompilerThreads(std::numeric_limits<GLuint>::max())
300 {}
301
~State()302 State::~State() {}
303
initialize(Context * context)304 void State::initialize(Context *context)
305 {
306 const Caps &caps = context->getCaps();
307 const Extensions &extensions = context->getExtensions();
308 const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
309 const Version &clientVersion = context->getClientVersion();
310
311 mMaxDrawBuffers = caps.maxDrawBuffers;
312 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
313
314 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
315
316 mDepthClearValue = 1.0f;
317 mStencilClearValue = 0;
318
319 mScissorTest = false;
320 mScissor.x = 0;
321 mScissor.y = 0;
322 mScissor.width = 0;
323 mScissor.height = 0;
324
325 mBlendColor.red = 0;
326 mBlendColor.green = 0;
327 mBlendColor.blue = 0;
328 mBlendColor.alpha = 0;
329
330 mStencilRef = 0;
331 mStencilBackRef = 0;
332
333 mSampleCoverage = false;
334 mSampleCoverageValue = 1.0f;
335 mSampleCoverageInvert = false;
336
337 mMaxSampleMaskWords = caps.maxSampleMaskWords;
338 mSampleMask = false;
339 mSampleMaskValues.fill(~GLbitfield(0));
340
341 mGenerateMipmapHint = GL_DONT_CARE;
342 mFragmentShaderDerivativeHint = GL_DONT_CARE;
343
344 mLineWidth = 1.0f;
345
346 mViewport.x = 0;
347 mViewport.y = 0;
348 mViewport.width = 0;
349 mViewport.height = 0;
350 mNearZ = 0.0f;
351 mFarZ = 1.0f;
352
353 mBlend.colorMaskRed = true;
354 mBlend.colorMaskGreen = true;
355 mBlend.colorMaskBlue = true;
356 mBlend.colorMaskAlpha = true;
357
358 mActiveSampler = 0;
359
360 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
361
362 // Set all indexes in state attributes type mask to float (default)
363 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
364 {
365 SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
366 }
367
368 mUniformBuffers.resize(caps.maxUniformBufferBindings);
369
370 mSamplerTextures[TextureType::_2D].resize(caps.maxCombinedTextureImageUnits);
371 mSamplerTextures[TextureType::CubeMap].resize(caps.maxCombinedTextureImageUnits);
372 if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES)
373 {
374 mSamplerTextures[TextureType::_3D].resize(caps.maxCombinedTextureImageUnits);
375 }
376 if (clientVersion >= Version(3, 0))
377 {
378 mSamplerTextures[TextureType::_2DArray].resize(caps.maxCombinedTextureImageUnits);
379 }
380 if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisample)
381 {
382 mSamplerTextures[TextureType::_2DMultisample].resize(caps.maxCombinedTextureImageUnits);
383 }
384 if (clientVersion >= Version(3, 1))
385 {
386 mSamplerTextures[TextureType::_2DMultisampleArray].resize(
387 caps.maxCombinedTextureImageUnits);
388
389 mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
390 mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
391 mImageUnits.resize(caps.maxImageUnits);
392 }
393 if (nativeExtensions.textureRectangle)
394 {
395 mSamplerTextures[TextureType::Rectangle].resize(caps.maxCombinedTextureImageUnits);
396 }
397 if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
398 {
399 mSamplerTextures[TextureType::External].resize(caps.maxCombinedTextureImageUnits);
400 }
401 mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
402 for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
403 ++textureIndex)
404 {
405 mCompleteTextureBindings.emplace_back(context, textureIndex);
406 }
407
408 mSamplers.resize(caps.maxCombinedTextureImageUnits);
409
410 for (QueryType type : angle::AllEnums<QueryType>())
411 {
412 mActiveQueries[type].set(context, nullptr);
413 }
414
415 mProgram = nullptr;
416
417 mReadFramebuffer = nullptr;
418 mDrawFramebuffer = nullptr;
419
420 mPrimitiveRestart = false;
421
422 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
423
424 mMultiSampling = true;
425 mSampleAlphaToOne = false;
426
427 mCoverageModulation = GL_NONE;
428
429 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
430 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
431 mPathStencilFunc = GL_ALWAYS;
432 mPathStencilRef = 0;
433 mPathStencilMask = std::numeric_limits<GLuint>::max();
434
435 // GLES1 emulation: Initialize state for GLES1 if version applies
436 // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile
437 if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API)
438 {
439 mGLES1State.initialize(context, this);
440 }
441 }
442
reset(const Context * context)443 void State::reset(const Context *context)
444 {
445 for (auto &bindingVec : mSamplerTextures)
446 {
447 for (size_t textureIdx = 0; textureIdx < bindingVec.size(); textureIdx++)
448 {
449 bindingVec[textureIdx].set(context, nullptr);
450 }
451 }
452 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
453 {
454 mSamplers[samplerIdx].set(context, nullptr);
455 }
456
457 for (auto &imageUnit : mImageUnits)
458 {
459 imageUnit.texture.set(context, nullptr);
460 imageUnit.level = 0;
461 imageUnit.layered = false;
462 imageUnit.layer = 0;
463 imageUnit.access = GL_READ_ONLY;
464 imageUnit.format = GL_R32UI;
465 }
466
467 mRenderbuffer.set(context, nullptr);
468
469 for (auto type : angle::AllEnums<BufferBinding>())
470 {
471 UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
472 }
473
474 if (mProgram)
475 {
476 mProgram->release(context);
477 }
478 mProgram = nullptr;
479
480 mProgramPipeline.set(context, nullptr);
481
482 if (mTransformFeedback.get())
483 mTransformFeedback->onBindingChanged(context, false);
484 mTransformFeedback.set(context, nullptr);
485
486 for (QueryType type : angle::AllEnums<QueryType>())
487 {
488 mActiveQueries[type].set(context, nullptr);
489 }
490
491 for (auto &buf : mUniformBuffers)
492 {
493 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
494 }
495
496 for (auto &buf : mAtomicCounterBuffers)
497 {
498 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
499 }
500
501 for (auto &buf : mShaderStorageBuffers)
502 {
503 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
504 }
505
506 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
507 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
508 mPathStencilFunc = GL_ALWAYS;
509 mPathStencilRef = 0;
510 mPathStencilMask = std::numeric_limits<GLuint>::max();
511
512 setAllDirtyBits();
513 }
514
unsetActiveTextures(ActiveTextureMask textureMask)515 ANGLE_INLINE void State::unsetActiveTextures(ActiveTextureMask textureMask)
516 {
517 // Unset any relevant bound textures.
518 for (size_t textureIndex : mProgram->getActiveSamplersMask())
519 {
520 mActiveTexturesCache[textureIndex] = nullptr;
521 mCompleteTextureBindings[textureIndex].reset();
522 }
523 }
524
updateActiveTextureState(const Context * context,size_t textureIndex,const Sampler * sampler,Texture * texture)525 ANGLE_INLINE void State::updateActiveTextureState(const Context *context,
526 size_t textureIndex,
527 const Sampler *sampler,
528 Texture *texture)
529 {
530 if (!texture->isSamplerComplete(context, sampler))
531 {
532 mActiveTexturesCache[textureIndex] = nullptr;
533 }
534 else
535 {
536 mActiveTexturesCache[textureIndex] = texture;
537
538 if (texture->hasAnyDirtyBit())
539 {
540 setTextureDirty(textureIndex);
541 }
542
543 if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit)
544 {
545 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT);
546 }
547 }
548
549 if (mProgram)
550 {
551 const SamplerState &samplerState =
552 sampler ? sampler->getSamplerState() : texture->getSamplerState();
553 mTexturesIncompatibleWithSamplers[textureIndex] =
554 !texture->getTextureState().compatibleWithSamplerFormat(
555 mProgram->getState().getSamplerFormatForTextureUnitIndex(textureIndex),
556 samplerState);
557 }
558 else
559 {
560 mTexturesIncompatibleWithSamplers[textureIndex] = false;
561 }
562
563 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
564 }
565
updateActiveTexture(const Context * context,size_t textureIndex,Texture * texture)566 ANGLE_INLINE void State::updateActiveTexture(const Context *context,
567 size_t textureIndex,
568 Texture *texture)
569 {
570 const Sampler *sampler = mSamplers[textureIndex].get();
571
572 mCompleteTextureBindings[textureIndex].bind(texture);
573
574 if (!texture)
575 {
576 mActiveTexturesCache[textureIndex] = nullptr;
577 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
578 return;
579 }
580
581 updateActiveTextureState(context, textureIndex, sampler, texture);
582 }
583
getRasterizerState() const584 const RasterizerState &State::getRasterizerState() const
585 {
586 return mRasterizer;
587 }
588
getDepthStencilState() const589 const DepthStencilState &State::getDepthStencilState() const
590 {
591 return mDepthStencil;
592 }
593
setColorClearValue(float red,float green,float blue,float alpha)594 void State::setColorClearValue(float red, float green, float blue, float alpha)
595 {
596 mColorClearValue.red = red;
597 mColorClearValue.green = green;
598 mColorClearValue.blue = blue;
599 mColorClearValue.alpha = alpha;
600 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
601 }
602
setDepthClearValue(float depth)603 void State::setDepthClearValue(float depth)
604 {
605 mDepthClearValue = depth;
606 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
607 }
608
setStencilClearValue(int stencil)609 void State::setStencilClearValue(int stencil)
610 {
611 mStencilClearValue = stencil;
612 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
613 }
614
setColorMask(bool red,bool green,bool blue,bool alpha)615 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
616 {
617 mBlend.colorMaskRed = red;
618 mBlend.colorMaskGreen = green;
619 mBlend.colorMaskBlue = blue;
620 mBlend.colorMaskAlpha = alpha;
621 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
622 }
623
setDepthMask(bool mask)624 void State::setDepthMask(bool mask)
625 {
626 if (mDepthStencil.depthMask != mask)
627 {
628 mDepthStencil.depthMask = mask;
629 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
630 }
631 }
632
setRasterizerDiscard(bool enabled)633 void State::setRasterizerDiscard(bool enabled)
634 {
635 mRasterizer.rasterizerDiscard = enabled;
636 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
637 }
638
setCullFace(bool enabled)639 void State::setCullFace(bool enabled)
640 {
641 mRasterizer.cullFace = enabled;
642 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
643 }
644
setCullMode(CullFaceMode mode)645 void State::setCullMode(CullFaceMode mode)
646 {
647 mRasterizer.cullMode = mode;
648 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
649 }
650
setFrontFace(GLenum front)651 void State::setFrontFace(GLenum front)
652 {
653 mRasterizer.frontFace = front;
654 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
655 }
656
setDepthTest(bool enabled)657 void State::setDepthTest(bool enabled)
658 {
659 if (mDepthStencil.depthTest != enabled)
660 {
661 mDepthStencil.depthTest = enabled;
662 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
663 }
664 }
665
setDepthFunc(GLenum depthFunc)666 void State::setDepthFunc(GLenum depthFunc)
667 {
668 if (mDepthStencil.depthFunc != depthFunc)
669 {
670 mDepthStencil.depthFunc = depthFunc;
671 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
672 }
673 }
674
setDepthRange(float zNear,float zFar)675 void State::setDepthRange(float zNear, float zFar)
676 {
677 if (mNearZ != zNear || mFarZ != zFar)
678 {
679 mNearZ = zNear;
680 mFarZ = zFar;
681 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
682 }
683 }
684
setBlend(bool enabled)685 void State::setBlend(bool enabled)
686 {
687 mBlend.blend = enabled;
688 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
689 }
690
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)691 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
692 {
693 mBlend.sourceBlendRGB = sourceRGB;
694 mBlend.destBlendRGB = destRGB;
695 mBlend.sourceBlendAlpha = sourceAlpha;
696 mBlend.destBlendAlpha = destAlpha;
697 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
698 }
699
setBlendColor(float red,float green,float blue,float alpha)700 void State::setBlendColor(float red, float green, float blue, float alpha)
701 {
702 mBlendColor.red = red;
703 mBlendColor.green = green;
704 mBlendColor.blue = blue;
705 mBlendColor.alpha = alpha;
706 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
707 }
708
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)709 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
710 {
711 mBlend.blendEquationRGB = rgbEquation;
712 mBlend.blendEquationAlpha = alphaEquation;
713 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
714 }
715
setStencilTest(bool enabled)716 void State::setStencilTest(bool enabled)
717 {
718 if (mDepthStencil.stencilTest != enabled)
719 {
720 mDepthStencil.stencilTest = enabled;
721 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
722 }
723 }
724
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)725 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
726 {
727 if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef ||
728 mDepthStencil.stencilMask != stencilMask)
729 {
730 mDepthStencil.stencilFunc = stencilFunc;
731 mStencilRef = stencilRef;
732 mDepthStencil.stencilMask = stencilMask;
733 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
734 }
735 }
736
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)737 void State::setStencilBackParams(GLenum stencilBackFunc,
738 GLint stencilBackRef,
739 GLuint stencilBackMask)
740 {
741 if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef ||
742 mDepthStencil.stencilBackMask != stencilBackMask)
743 {
744 mDepthStencil.stencilBackFunc = stencilBackFunc;
745 mStencilBackRef = stencilBackRef;
746 mDepthStencil.stencilBackMask = stencilBackMask;
747 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
748 }
749 }
750
setStencilWritemask(GLuint stencilWritemask)751 void State::setStencilWritemask(GLuint stencilWritemask)
752 {
753 if (mDepthStencil.stencilWritemask != stencilWritemask)
754 {
755 mDepthStencil.stencilWritemask = stencilWritemask;
756 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
757 }
758 }
759
setStencilBackWritemask(GLuint stencilBackWritemask)760 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
761 {
762 if (mDepthStencil.stencilBackWritemask != stencilBackWritemask)
763 {
764 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
765 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
766 }
767 }
768
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)769 void State::setStencilOperations(GLenum stencilFail,
770 GLenum stencilPassDepthFail,
771 GLenum stencilPassDepthPass)
772 {
773 if (mDepthStencil.stencilFail != stencilFail ||
774 mDepthStencil.stencilPassDepthFail != stencilPassDepthFail ||
775 mDepthStencil.stencilPassDepthPass != stencilPassDepthPass)
776 {
777 mDepthStencil.stencilFail = stencilFail;
778 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
779 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
780 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
781 }
782 }
783
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)784 void State::setStencilBackOperations(GLenum stencilBackFail,
785 GLenum stencilBackPassDepthFail,
786 GLenum stencilBackPassDepthPass)
787 {
788 if (mDepthStencil.stencilBackFail != stencilBackFail ||
789 mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail ||
790 mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass)
791 {
792 mDepthStencil.stencilBackFail = stencilBackFail;
793 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
794 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
795 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
796 }
797 }
798
setPolygonOffsetFill(bool enabled)799 void State::setPolygonOffsetFill(bool enabled)
800 {
801 mRasterizer.polygonOffsetFill = enabled;
802 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
803 }
804
setPolygonOffsetParams(GLfloat factor,GLfloat units)805 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
806 {
807 // An application can pass NaN values here, so handle this gracefully
808 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
809 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
810 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
811 }
812
setSampleAlphaToCoverage(bool enabled)813 void State::setSampleAlphaToCoverage(bool enabled)
814 {
815 mBlend.sampleAlphaToCoverage = enabled;
816 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
817 }
818
setSampleCoverage(bool enabled)819 void State::setSampleCoverage(bool enabled)
820 {
821 mSampleCoverage = enabled;
822 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
823 }
824
setSampleCoverageParams(GLclampf value,bool invert)825 void State::setSampleCoverageParams(GLclampf value, bool invert)
826 {
827 mSampleCoverageValue = value;
828 mSampleCoverageInvert = invert;
829 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
830 }
831
setSampleMaskEnabled(bool enabled)832 void State::setSampleMaskEnabled(bool enabled)
833 {
834 mSampleMask = enabled;
835 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
836 }
837
setSampleMaskParams(GLuint maskNumber,GLbitfield mask)838 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
839 {
840 ASSERT(maskNumber < mMaxSampleMaskWords);
841 mSampleMaskValues[maskNumber] = mask;
842 // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
843 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
844 }
845
setSampleAlphaToOne(bool enabled)846 void State::setSampleAlphaToOne(bool enabled)
847 {
848 mSampleAlphaToOne = enabled;
849 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
850 }
851
setMultisampling(bool enabled)852 void State::setMultisampling(bool enabled)
853 {
854 mMultiSampling = enabled;
855 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
856 }
857
setScissorTest(bool enabled)858 void State::setScissorTest(bool enabled)
859 {
860 mScissorTest = enabled;
861 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
862 }
863
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)864 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
865 {
866 mScissor.x = x;
867 mScissor.y = y;
868 mScissor.width = width;
869 mScissor.height = height;
870 mDirtyBits.set(DIRTY_BIT_SCISSOR);
871 }
872
setDither(bool enabled)873 void State::setDither(bool enabled)
874 {
875 mBlend.dither = enabled;
876 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
877 }
878
setPrimitiveRestart(bool enabled)879 void State::setPrimitiveRestart(bool enabled)
880 {
881 mPrimitiveRestart = enabled;
882 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
883 }
884
setEnableFeature(GLenum feature,bool enabled)885 void State::setEnableFeature(GLenum feature, bool enabled)
886 {
887 switch (feature)
888 {
889 case GL_MULTISAMPLE_EXT:
890 setMultisampling(enabled);
891 break;
892 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
893 setSampleAlphaToOne(enabled);
894 break;
895 case GL_CULL_FACE:
896 setCullFace(enabled);
897 break;
898 case GL_POLYGON_OFFSET_FILL:
899 setPolygonOffsetFill(enabled);
900 break;
901 case GL_SAMPLE_ALPHA_TO_COVERAGE:
902 setSampleAlphaToCoverage(enabled);
903 break;
904 case GL_SAMPLE_COVERAGE:
905 setSampleCoverage(enabled);
906 break;
907 case GL_SCISSOR_TEST:
908 setScissorTest(enabled);
909 break;
910 case GL_STENCIL_TEST:
911 setStencilTest(enabled);
912 break;
913 case GL_DEPTH_TEST:
914 setDepthTest(enabled);
915 break;
916 case GL_BLEND:
917 setBlend(enabled);
918 break;
919 case GL_DITHER:
920 setDither(enabled);
921 break;
922 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
923 setPrimitiveRestart(enabled);
924 break;
925 case GL_RASTERIZER_DISCARD:
926 setRasterizerDiscard(enabled);
927 break;
928 case GL_SAMPLE_MASK:
929 setSampleMaskEnabled(enabled);
930 break;
931 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
932 mDebug.setOutputSynchronous(enabled);
933 break;
934 case GL_DEBUG_OUTPUT:
935 mDebug.setOutputEnabled(enabled);
936 break;
937 case GL_FRAMEBUFFER_SRGB_EXT:
938 setFramebufferSRGB(enabled);
939 break;
940
941 // GLES1 emulation
942 case GL_ALPHA_TEST:
943 mGLES1State.mAlphaTestEnabled = enabled;
944 break;
945 case GL_TEXTURE_2D:
946 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled);
947 break;
948 case GL_TEXTURE_CUBE_MAP:
949 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled);
950 break;
951 case GL_LIGHTING:
952 mGLES1State.mLightingEnabled = enabled;
953 break;
954 case GL_LIGHT0:
955 case GL_LIGHT1:
956 case GL_LIGHT2:
957 case GL_LIGHT3:
958 case GL_LIGHT4:
959 case GL_LIGHT5:
960 case GL_LIGHT6:
961 case GL_LIGHT7:
962 mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled;
963 break;
964 case GL_NORMALIZE:
965 mGLES1State.mNormalizeEnabled = enabled;
966 break;
967 case GL_RESCALE_NORMAL:
968 mGLES1State.mRescaleNormalEnabled = enabled;
969 break;
970 case GL_COLOR_MATERIAL:
971 mGLES1State.mColorMaterialEnabled = enabled;
972 break;
973 case GL_CLIP_PLANE0:
974 case GL_CLIP_PLANE1:
975 case GL_CLIP_PLANE2:
976 case GL_CLIP_PLANE3:
977 case GL_CLIP_PLANE4:
978 case GL_CLIP_PLANE5:
979 mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
980 break;
981 case GL_FOG:
982 mGLES1State.mFogEnabled = enabled;
983 break;
984 case GL_POINT_SMOOTH:
985 mGLES1State.mPointSmoothEnabled = enabled;
986 break;
987 case GL_LINE_SMOOTH:
988 mGLES1State.mLineSmoothEnabled = enabled;
989 break;
990 case GL_POINT_SPRITE_OES:
991 mGLES1State.mPointSpriteEnabled = enabled;
992 break;
993 case GL_COLOR_LOGIC_OP:
994 mGLES1State.mLogicOpEnabled = enabled;
995 break;
996 default:
997 UNREACHABLE();
998 }
999 }
1000
getEnableFeature(GLenum feature) const1001 bool State::getEnableFeature(GLenum feature) const
1002 {
1003 switch (feature)
1004 {
1005 case GL_MULTISAMPLE_EXT:
1006 return isMultisamplingEnabled();
1007 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1008 return isSampleAlphaToOneEnabled();
1009 case GL_CULL_FACE:
1010 return isCullFaceEnabled();
1011 case GL_POLYGON_OFFSET_FILL:
1012 return isPolygonOffsetFillEnabled();
1013 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1014 return isSampleAlphaToCoverageEnabled();
1015 case GL_SAMPLE_COVERAGE:
1016 return isSampleCoverageEnabled();
1017 case GL_SCISSOR_TEST:
1018 return isScissorTestEnabled();
1019 case GL_STENCIL_TEST:
1020 return isStencilTestEnabled();
1021 case GL_DEPTH_TEST:
1022 return isDepthTestEnabled();
1023 case GL_BLEND:
1024 return isBlendEnabled();
1025 case GL_DITHER:
1026 return isDitherEnabled();
1027 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1028 return isPrimitiveRestartEnabled();
1029 case GL_RASTERIZER_DISCARD:
1030 return isRasterizerDiscardEnabled();
1031 case GL_SAMPLE_MASK:
1032 return isSampleMaskEnabled();
1033 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1034 return mDebug.isOutputSynchronous();
1035 case GL_DEBUG_OUTPUT:
1036 return mDebug.isOutputEnabled();
1037 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1038 return isBindGeneratesResourceEnabled();
1039 case GL_CLIENT_ARRAYS_ANGLE:
1040 return areClientArraysEnabled();
1041 case GL_FRAMEBUFFER_SRGB_EXT:
1042 return getFramebufferSRGB();
1043 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1044 return mRobustResourceInit;
1045 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1046 return mProgramBinaryCacheEnabled;
1047
1048 // GLES1 emulation
1049 case GL_ALPHA_TEST:
1050 return mGLES1State.mAlphaTestEnabled;
1051 case GL_VERTEX_ARRAY:
1052 return mGLES1State.mVertexArrayEnabled;
1053 case GL_NORMAL_ARRAY:
1054 return mGLES1State.mNormalArrayEnabled;
1055 case GL_COLOR_ARRAY:
1056 return mGLES1State.mColorArrayEnabled;
1057 case GL_POINT_SIZE_ARRAY_OES:
1058 return mGLES1State.mPointSizeArrayEnabled;
1059 case GL_TEXTURE_COORD_ARRAY:
1060 return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture];
1061 case GL_TEXTURE_2D:
1062 return mGLES1State.mTexUnitEnables[mActiveSampler].test(TextureType::_2D);
1063 case GL_TEXTURE_CUBE_MAP:
1064 return mGLES1State.mTexUnitEnables[mActiveSampler].test(TextureType::CubeMap);
1065 case GL_LIGHTING:
1066 return mGLES1State.mLightingEnabled;
1067 case GL_LIGHT0:
1068 case GL_LIGHT1:
1069 case GL_LIGHT2:
1070 case GL_LIGHT3:
1071 case GL_LIGHT4:
1072 case GL_LIGHT5:
1073 case GL_LIGHT6:
1074 case GL_LIGHT7:
1075 return mGLES1State.mLights[feature - GL_LIGHT0].enabled;
1076 case GL_NORMALIZE:
1077 return mGLES1State.mNormalizeEnabled;
1078 case GL_RESCALE_NORMAL:
1079 return mGLES1State.mRescaleNormalEnabled;
1080 case GL_COLOR_MATERIAL:
1081 return mGLES1State.mColorMaterialEnabled;
1082 case GL_CLIP_PLANE0:
1083 case GL_CLIP_PLANE1:
1084 case GL_CLIP_PLANE2:
1085 case GL_CLIP_PLANE3:
1086 case GL_CLIP_PLANE4:
1087 case GL_CLIP_PLANE5:
1088 return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
1089 case GL_FOG:
1090 return mGLES1State.mFogEnabled;
1091 case GL_POINT_SMOOTH:
1092 return mGLES1State.mPointSmoothEnabled;
1093 case GL_LINE_SMOOTH:
1094 return mGLES1State.mLineSmoothEnabled;
1095 case GL_POINT_SPRITE_OES:
1096 return mGLES1State.mPointSpriteEnabled;
1097 case GL_COLOR_LOGIC_OP:
1098 return mGLES1State.mLogicOpEnabled;
1099 default:
1100 UNREACHABLE();
1101 return false;
1102 }
1103 }
1104
setLineWidth(GLfloat width)1105 void State::setLineWidth(GLfloat width)
1106 {
1107 mLineWidth = width;
1108 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
1109 }
1110
setGenerateMipmapHint(GLenum hint)1111 void State::setGenerateMipmapHint(GLenum hint)
1112 {
1113 mGenerateMipmapHint = hint;
1114 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
1115 }
1116
setFragmentShaderDerivativeHint(GLenum hint)1117 void State::setFragmentShaderDerivativeHint(GLenum hint)
1118 {
1119 mFragmentShaderDerivativeHint = hint;
1120 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
1121 // TODO: Propagate the hint to shader translator so we can write
1122 // ddx, ddx_coarse, or ddx_fine depending on the hint.
1123 // Ignore for now. It is valid for implementations to ignore hint.
1124 }
1125
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)1126 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
1127 {
1128 mViewport.x = x;
1129 mViewport.y = y;
1130 mViewport.width = width;
1131 mViewport.height = height;
1132 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
1133 }
1134
setActiveSampler(unsigned int active)1135 void State::setActiveSampler(unsigned int active)
1136 {
1137 mActiveSampler = active;
1138 }
1139
setSamplerTexture(const Context * context,TextureType type,Texture * texture)1140 void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
1141 {
1142 mSamplerTextures[type][mActiveSampler].set(context, texture);
1143
1144 if (mProgram && mProgram->getActiveSamplersMask()[mActiveSampler] &&
1145 mProgram->getActiveSamplerTypes()[mActiveSampler] == type)
1146 {
1147 updateActiveTexture(context, mActiveSampler, texture);
1148 }
1149
1150 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1151 }
1152
getTargetTexture(TextureType type) const1153 Texture *State::getTargetTexture(TextureType type) const
1154 {
1155 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
1156 }
1157
getSamplerTextureId(unsigned int sampler,TextureType type) const1158 GLuint State::getSamplerTextureId(unsigned int sampler, TextureType type) const
1159 {
1160 ASSERT(sampler < mSamplerTextures[type].size());
1161 return mSamplerTextures[type][sampler].id();
1162 }
1163
detachTexture(const Context * context,const TextureMap & zeroTextures,TextureID texture)1164 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
1165 {
1166 // Textures have a detach method on State rather than a simple
1167 // removeBinding, because the zero/null texture objects are managed
1168 // separately, and don't have to go through the Context's maps or
1169 // the ResourceManager.
1170
1171 // [OpenGL ES 2.0.24] section 3.8 page 84:
1172 // If a texture object is deleted, it is as if all texture units which are bound to that texture
1173 // object are rebound to texture object zero
1174
1175 for (TextureType type : angle::AllEnums<TextureType>())
1176 {
1177 TextureBindingVector &textureVector = mSamplerTextures[type];
1178
1179 for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
1180 {
1181 BindingPointer<Texture> &binding = textureVector[bindingIndex];
1182 if (binding.id() == texture.value)
1183 {
1184 // Zero textures are the "default" textures instead of NULL
1185 Texture *zeroTexture = zeroTextures[type].get();
1186 ASSERT(zeroTexture != nullptr);
1187 if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get())
1188 {
1189 updateActiveTexture(context, bindingIndex, zeroTexture);
1190 }
1191 binding.set(context, zeroTexture);
1192 }
1193 }
1194 }
1195
1196 for (auto &bindingImageUnit : mImageUnits)
1197 {
1198 if (bindingImageUnit.texture.id() == texture.value)
1199 {
1200 bindingImageUnit.texture.set(context, nullptr);
1201 bindingImageUnit.level = 0;
1202 bindingImageUnit.layered = false;
1203 bindingImageUnit.layer = 0;
1204 bindingImageUnit.access = GL_READ_ONLY;
1205 bindingImageUnit.format = GL_R32UI;
1206 break;
1207 }
1208 }
1209
1210 // [OpenGL ES 2.0.24] section 4.4 page 112:
1211 // If a texture object is deleted while its image is attached to the currently bound
1212 // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
1213 // each attachment point to which this image was attached in the currently bound framebuffer.
1214
1215 if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
1216 {
1217 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1218 }
1219
1220 if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
1221 {
1222 setDrawFramebufferDirty();
1223 }
1224 }
1225
initializeZeroTextures(const Context * context,const TextureMap & zeroTextures)1226 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
1227 {
1228 for (TextureType type : angle::AllEnums<TextureType>())
1229 {
1230 for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
1231 {
1232 mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
1233 }
1234 }
1235 }
1236
invalidateTexture(TextureType type)1237 void State::invalidateTexture(TextureType type)
1238 {
1239 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1240 }
1241
setSamplerBinding(const Context * context,GLuint textureUnit,Sampler * sampler)1242 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
1243 {
1244 mSamplers[textureUnit].set(context, sampler);
1245 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
1246 // This is overly conservative as it assumes the sampler has never been bound.
1247 setSamplerDirty(textureUnit);
1248 onActiveTextureChange(context, textureUnit);
1249 onActiveTextureStateChange(context, textureUnit);
1250 }
1251
detachSampler(const Context * context,GLuint sampler)1252 void State::detachSampler(const Context *context, GLuint sampler)
1253 {
1254 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
1255 // If a sampler object that is currently bound to one or more texture units is
1256 // deleted, it is as though BindSampler is called once for each texture unit to
1257 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
1258 for (size_t i = 0; i < mSamplers.size(); i++)
1259 {
1260 if (mSamplers[i].id() == sampler)
1261 {
1262 setSamplerBinding(context, static_cast<GLuint>(i), nullptr);
1263 }
1264 }
1265 }
1266
setRenderbufferBinding(const Context * context,Renderbuffer * renderbuffer)1267 void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
1268 {
1269 mRenderbuffer.set(context, renderbuffer);
1270 mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
1271 }
1272
detachRenderbuffer(const Context * context,RenderbufferID renderbuffer)1273 void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
1274 {
1275 // [OpenGL ES 2.0.24] section 4.4 page 109:
1276 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
1277 // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
1278
1279 if (mRenderbuffer.id() == renderbuffer.value)
1280 {
1281 setRenderbufferBinding(context, nullptr);
1282 }
1283
1284 // [OpenGL ES 2.0.24] section 4.4 page 111:
1285 // If a renderbuffer object is deleted while its image is attached to the currently bound
1286 // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
1287 // 0, for each attachment point to which this image was attached in the currently bound
1288 // framebuffer.
1289
1290 Framebuffer *readFramebuffer = mReadFramebuffer;
1291 Framebuffer *drawFramebuffer = mDrawFramebuffer;
1292
1293 if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
1294 {
1295 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1296 }
1297
1298 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
1299 {
1300 if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
1301 {
1302 setDrawFramebufferDirty();
1303 }
1304 }
1305 }
1306
setReadFramebufferBinding(Framebuffer * framebuffer)1307 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
1308 {
1309 if (mReadFramebuffer == framebuffer)
1310 return;
1311
1312 mReadFramebuffer = framebuffer;
1313 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
1314
1315 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
1316 {
1317 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1318 }
1319 }
1320
setDrawFramebufferBinding(Framebuffer * framebuffer)1321 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
1322 {
1323 if (mDrawFramebuffer == framebuffer)
1324 return;
1325
1326 mDrawFramebuffer = framebuffer;
1327 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1328
1329 if (mDrawFramebuffer)
1330 {
1331 if (mDrawFramebuffer->hasAnyDirtyBit())
1332 {
1333 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1334 }
1335
1336 if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit())
1337 {
1338 mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
1339 }
1340 }
1341 }
1342
getTargetFramebuffer(GLenum target) const1343 Framebuffer *State::getTargetFramebuffer(GLenum target) const
1344 {
1345 switch (target)
1346 {
1347 case GL_READ_FRAMEBUFFER_ANGLE:
1348 return mReadFramebuffer;
1349 case GL_DRAW_FRAMEBUFFER_ANGLE:
1350 case GL_FRAMEBUFFER:
1351 return mDrawFramebuffer;
1352 default:
1353 UNREACHABLE();
1354 return nullptr;
1355 }
1356 }
1357
removeReadFramebufferBinding(GLuint framebuffer)1358 bool State::removeReadFramebufferBinding(GLuint framebuffer)
1359 {
1360 if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
1361 {
1362 setReadFramebufferBinding(nullptr);
1363 return true;
1364 }
1365
1366 return false;
1367 }
1368
removeDrawFramebufferBinding(GLuint framebuffer)1369 bool State::removeDrawFramebufferBinding(GLuint framebuffer)
1370 {
1371 if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
1372 {
1373 setDrawFramebufferBinding(nullptr);
1374 return true;
1375 }
1376
1377 return false;
1378 }
1379
setVertexArrayBinding(const Context * context,VertexArray * vertexArray)1380 void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray)
1381 {
1382 if (mVertexArray == vertexArray)
1383 return;
1384 if (mVertexArray)
1385 mVertexArray->onBindingChanged(context, -1);
1386 mVertexArray = vertexArray;
1387 if (vertexArray)
1388 vertexArray->onBindingChanged(context, 1);
1389 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1390
1391 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1392 {
1393 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1394 }
1395 }
1396
removeVertexArrayBinding(const Context * context,GLuint vertexArray)1397 bool State::removeVertexArrayBinding(const Context *context, GLuint vertexArray)
1398 {
1399 if (mVertexArray && mVertexArray->id() == vertexArray)
1400 {
1401 mVertexArray->onBindingChanged(context, -1);
1402 mVertexArray = nullptr;
1403 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1404 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1405 return true;
1406 }
1407
1408 return false;
1409 }
1410
getVertexArrayId() const1411 GLuint State::getVertexArrayId() const
1412 {
1413 ASSERT(mVertexArray != nullptr);
1414 return mVertexArray->id();
1415 }
1416
bindVertexBuffer(const Context * context,GLuint bindingIndex,Buffer * boundBuffer,GLintptr offset,GLsizei stride)1417 void State::bindVertexBuffer(const Context *context,
1418 GLuint bindingIndex,
1419 Buffer *boundBuffer,
1420 GLintptr offset,
1421 GLsizei stride)
1422 {
1423 getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
1424 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1425 }
1426
setVertexAttribFormat(GLuint attribIndex,GLint size,VertexAttribType type,bool normalized,bool pureInteger,GLuint relativeOffset)1427 void State::setVertexAttribFormat(GLuint attribIndex,
1428 GLint size,
1429 VertexAttribType type,
1430 bool normalized,
1431 bool pureInteger,
1432 GLuint relativeOffset)
1433 {
1434 getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1435 relativeOffset);
1436 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1437 }
1438
setVertexBindingDivisor(GLuint bindingIndex,GLuint divisor)1439 void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1440 {
1441 getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
1442 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1443 }
1444
setProgram(const Context * context,Program * newProgram)1445 angle::Result State::setProgram(const Context *context, Program *newProgram)
1446 {
1447 if (mProgram != newProgram)
1448 {
1449 if (mProgram)
1450 {
1451 unsetActiveTextures(mProgram->getActiveSamplersMask());
1452 mProgram->release(context);
1453 }
1454
1455 mProgram = newProgram;
1456
1457 if (mProgram)
1458 {
1459 newProgram->addRef();
1460 ANGLE_TRY(onProgramExecutableChange(context, newProgram));
1461 }
1462
1463 // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate
1464 // an error if the app tries to draw in this case.
1465
1466 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
1467 }
1468
1469 return angle::Result::Continue;
1470 }
1471
setTransformFeedbackBinding(const Context * context,TransformFeedback * transformFeedback)1472 void State::setTransformFeedbackBinding(const Context *context,
1473 TransformFeedback *transformFeedback)
1474 {
1475 if (transformFeedback == mTransformFeedback.get())
1476 return;
1477 if (mTransformFeedback.get())
1478 mTransformFeedback->onBindingChanged(context, false);
1479 mTransformFeedback.set(context, transformFeedback);
1480 if (mTransformFeedback.get())
1481 mTransformFeedback->onBindingChanged(context, true);
1482 mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
1483 }
1484
removeTransformFeedbackBinding(const Context * context,GLuint transformFeedback)1485 bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback)
1486 {
1487 if (mTransformFeedback.id() == transformFeedback)
1488 {
1489 if (mTransformFeedback.get())
1490 mTransformFeedback->onBindingChanged(context, false);
1491 mTransformFeedback.set(context, nullptr);
1492 return true;
1493 }
1494
1495 return false;
1496 }
1497
setProgramPipelineBinding(const Context * context,ProgramPipeline * pipeline)1498 void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
1499 {
1500 mProgramPipeline.set(context, pipeline);
1501 }
1502
detachProgramPipeline(const Context * context,GLuint pipeline)1503 void State::detachProgramPipeline(const Context *context, GLuint pipeline)
1504 {
1505 mProgramPipeline.set(context, nullptr);
1506 }
1507
isQueryActive(QueryType type) const1508 bool State::isQueryActive(QueryType type) const
1509 {
1510 const Query *query = mActiveQueries[type].get();
1511 if (query != nullptr)
1512 {
1513 return true;
1514 }
1515
1516 QueryType alternativeType;
1517 if (GetAlternativeQueryType(type, &alternativeType))
1518 {
1519 query = mActiveQueries[alternativeType].get();
1520 return query != nullptr;
1521 }
1522
1523 return false;
1524 }
1525
isQueryActive(Query * query) const1526 bool State::isQueryActive(Query *query) const
1527 {
1528 for (auto &queryPointer : mActiveQueries)
1529 {
1530 if (queryPointer.get() == query)
1531 {
1532 return true;
1533 }
1534 }
1535
1536 return false;
1537 }
1538
setActiveQuery(const Context * context,QueryType type,Query * query)1539 void State::setActiveQuery(const Context *context, QueryType type, Query *query)
1540 {
1541 mActiveQueries[type].set(context, query);
1542 }
1543
getActiveQueryId(QueryType type) const1544 GLuint State::getActiveQueryId(QueryType type) const
1545 {
1546 const Query *query = getActiveQuery(type);
1547 return (query ? query->id() : 0u);
1548 }
1549
getActiveQuery(QueryType type) const1550 Query *State::getActiveQuery(QueryType type) const
1551 {
1552 return mActiveQueries[type].get();
1553 }
1554
setIndexedBufferBinding(const Context * context,BufferBinding target,GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)1555 angle::Result State::setIndexedBufferBinding(const Context *context,
1556 BufferBinding target,
1557 GLuint index,
1558 Buffer *buffer,
1559 GLintptr offset,
1560 GLsizeiptr size)
1561 {
1562 setBufferBinding(context, target, buffer);
1563
1564 switch (target)
1565 {
1566 case BufferBinding::TransformFeedback:
1567 ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size));
1568 setBufferBinding(context, target, buffer);
1569 break;
1570 case BufferBinding::Uniform:
1571 UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
1572 size);
1573 break;
1574 case BufferBinding::AtomicCounter:
1575 UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
1576 offset, size);
1577 break;
1578 case BufferBinding::ShaderStorage:
1579 UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
1580 offset, size);
1581 break;
1582 default:
1583 UNREACHABLE();
1584 break;
1585 }
1586
1587 return angle::Result::Continue;
1588 }
1589
getIndexedUniformBuffer(size_t index) const1590 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
1591 {
1592 ASSERT(index < mUniformBuffers.size());
1593 return mUniformBuffers[index];
1594 }
1595
getIndexedAtomicCounterBuffer(size_t index) const1596 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
1597 {
1598 ASSERT(index < mAtomicCounterBuffers.size());
1599 return mAtomicCounterBuffers[index];
1600 }
1601
getIndexedShaderStorageBuffer(size_t index) const1602 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
1603 {
1604 ASSERT(index < mShaderStorageBuffers.size());
1605 return mShaderStorageBuffers[index];
1606 }
1607
detachBuffer(Context * context,const Buffer * buffer)1608 angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
1609 {
1610 if (!buffer->isBound())
1611 {
1612 return angle::Result::Continue;
1613 }
1614 GLuint bufferName = buffer->id();
1615 for (auto target : angle::AllEnums<BufferBinding>())
1616 {
1617 if (mBoundBuffers[target].id() == bufferName)
1618 {
1619 UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
1620 }
1621 }
1622
1623 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1624 if (curTransformFeedback)
1625 {
1626 ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferName));
1627 }
1628
1629 if (getVertexArray()->detachBuffer(context, bufferName))
1630 {
1631 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1632 context->getStateCache().onVertexArrayStateChange(context);
1633 }
1634
1635 for (auto &buf : mUniformBuffers)
1636 {
1637 if (buf.id() == bufferName)
1638 {
1639 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
1640 }
1641 }
1642
1643 for (auto &buf : mAtomicCounterBuffers)
1644 {
1645 if (buf.id() == bufferName)
1646 {
1647 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
1648 }
1649 }
1650
1651 for (auto &buf : mShaderStorageBuffers)
1652 {
1653 if (buf.id() == bufferName)
1654 {
1655 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
1656 }
1657 }
1658
1659 return angle::Result::Continue;
1660 }
1661
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)1662 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1663 {
1664 getVertexArray()->enableAttribute(attribNum, enabled);
1665 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1666 }
1667
setVertexAttribf(GLuint index,const GLfloat values[4])1668 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1669 {
1670 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1671 mVertexAttribCurrentValues[index].setFloatValues(values);
1672 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1673 mDirtyCurrentValues.set(index);
1674 SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
1675 }
1676
setVertexAttribu(GLuint index,const GLuint values[4])1677 void State::setVertexAttribu(GLuint index, const GLuint values[4])
1678 {
1679 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1680 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1681 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1682 mDirtyCurrentValues.set(index);
1683 SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
1684 }
1685
setVertexAttribi(GLuint index,const GLint values[4])1686 void State::setVertexAttribi(GLuint index, const GLint values[4])
1687 {
1688 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1689 mVertexAttribCurrentValues[index].setIntValues(values);
1690 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1691 mDirtyCurrentValues.set(index);
1692 SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
1693 }
1694
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)1695 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
1696 {
1697 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
1698 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1699 }
1700
getVertexAttribPointer(unsigned int attribNum) const1701 const void *State::getVertexAttribPointer(unsigned int attribNum) const
1702 {
1703 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1704 }
1705
setPackAlignment(GLint alignment)1706 void State::setPackAlignment(GLint alignment)
1707 {
1708 mPack.alignment = alignment;
1709 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1710 }
1711
setPackReverseRowOrder(bool reverseRowOrder)1712 void State::setPackReverseRowOrder(bool reverseRowOrder)
1713 {
1714 mPack.reverseRowOrder = reverseRowOrder;
1715 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1716 }
1717
setPackRowLength(GLint rowLength)1718 void State::setPackRowLength(GLint rowLength)
1719 {
1720 mPack.rowLength = rowLength;
1721 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1722 }
1723
setPackSkipRows(GLint skipRows)1724 void State::setPackSkipRows(GLint skipRows)
1725 {
1726 mPack.skipRows = skipRows;
1727 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1728 }
1729
setPackSkipPixels(GLint skipPixels)1730 void State::setPackSkipPixels(GLint skipPixels)
1731 {
1732 mPack.skipPixels = skipPixels;
1733 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1734 }
1735
setUnpackAlignment(GLint alignment)1736 void State::setUnpackAlignment(GLint alignment)
1737 {
1738 mUnpack.alignment = alignment;
1739 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1740 }
1741
setUnpackRowLength(GLint rowLength)1742 void State::setUnpackRowLength(GLint rowLength)
1743 {
1744 mUnpack.rowLength = rowLength;
1745 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1746 }
1747
setUnpackImageHeight(GLint imageHeight)1748 void State::setUnpackImageHeight(GLint imageHeight)
1749 {
1750 mUnpack.imageHeight = imageHeight;
1751 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1752 }
1753
setUnpackSkipImages(GLint skipImages)1754 void State::setUnpackSkipImages(GLint skipImages)
1755 {
1756 mUnpack.skipImages = skipImages;
1757 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1758 }
1759
setUnpackSkipRows(GLint skipRows)1760 void State::setUnpackSkipRows(GLint skipRows)
1761 {
1762 mUnpack.skipRows = skipRows;
1763 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1764 }
1765
setUnpackSkipPixels(GLint skipPixels)1766 void State::setUnpackSkipPixels(GLint skipPixels)
1767 {
1768 mUnpack.skipPixels = skipPixels;
1769 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1770 }
1771
setCoverageModulation(GLenum components)1772 void State::setCoverageModulation(GLenum components)
1773 {
1774 mCoverageModulation = components;
1775 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1776 }
1777
loadPathRenderingMatrix(GLenum matrixMode,const GLfloat * matrix)1778 void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1779 {
1780 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1781 {
1782 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1783 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING);
1784 }
1785 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1786 {
1787 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1788 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING);
1789 }
1790 else
1791 {
1792 UNREACHABLE();
1793 }
1794 }
1795
getPathRenderingMatrix(GLenum which) const1796 const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1797 {
1798 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1799 {
1800 return mPathMatrixMV;
1801 }
1802 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1803 {
1804 return mPathMatrixProj;
1805 }
1806
1807 UNREACHABLE();
1808 return nullptr;
1809 }
1810
setPathStencilFunc(GLenum func,GLint ref,GLuint mask)1811 void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1812 {
1813 mPathStencilFunc = func;
1814 mPathStencilRef = ref;
1815 mPathStencilMask = mask;
1816 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING);
1817 }
1818
setFramebufferSRGB(bool sRGB)1819 void State::setFramebufferSRGB(bool sRGB)
1820 {
1821 mFramebufferSRGB = sRGB;
1822 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1823 }
1824
setMaxShaderCompilerThreads(GLuint count)1825 void State::setMaxShaderCompilerThreads(GLuint count)
1826 {
1827 mMaxShaderCompilerThreads = count;
1828 }
1829
getBooleanv(GLenum pname,GLboolean * params)1830 void State::getBooleanv(GLenum pname, GLboolean *params)
1831 {
1832 switch (pname)
1833 {
1834 case GL_SAMPLE_COVERAGE_INVERT:
1835 *params = mSampleCoverageInvert;
1836 break;
1837 case GL_DEPTH_WRITEMASK:
1838 *params = mDepthStencil.depthMask;
1839 break;
1840 case GL_COLOR_WRITEMASK:
1841 params[0] = mBlend.colorMaskRed;
1842 params[1] = mBlend.colorMaskGreen;
1843 params[2] = mBlend.colorMaskBlue;
1844 params[3] = mBlend.colorMaskAlpha;
1845 break;
1846 case GL_CULL_FACE:
1847 *params = mRasterizer.cullFace;
1848 break;
1849 case GL_POLYGON_OFFSET_FILL:
1850 *params = mRasterizer.polygonOffsetFill;
1851 break;
1852 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1853 *params = mBlend.sampleAlphaToCoverage;
1854 break;
1855 case GL_SAMPLE_COVERAGE:
1856 *params = mSampleCoverage;
1857 break;
1858 case GL_SAMPLE_MASK:
1859 *params = mSampleMask;
1860 break;
1861 case GL_SCISSOR_TEST:
1862 *params = mScissorTest;
1863 break;
1864 case GL_STENCIL_TEST:
1865 *params = mDepthStencil.stencilTest;
1866 break;
1867 case GL_DEPTH_TEST:
1868 *params = mDepthStencil.depthTest;
1869 break;
1870 case GL_BLEND:
1871 *params = mBlend.blend;
1872 break;
1873 case GL_DITHER:
1874 *params = mBlend.dither;
1875 break;
1876 case GL_TRANSFORM_FEEDBACK_ACTIVE:
1877 *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
1878 break;
1879 case GL_TRANSFORM_FEEDBACK_PAUSED:
1880 *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
1881 break;
1882 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1883 *params = mPrimitiveRestart;
1884 break;
1885 case GL_RASTERIZER_DISCARD:
1886 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1887 break;
1888 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1889 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1890 break;
1891 case GL_DEBUG_OUTPUT:
1892 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1893 break;
1894 case GL_MULTISAMPLE_EXT:
1895 *params = mMultiSampling;
1896 break;
1897 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1898 *params = mSampleAlphaToOne;
1899 break;
1900 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1901 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1902 break;
1903 case GL_CLIENT_ARRAYS_ANGLE:
1904 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1905 break;
1906 case GL_FRAMEBUFFER_SRGB_EXT:
1907 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1908 break;
1909 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1910 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
1911 break;
1912 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1913 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
1914 break;
1915 case GL_LIGHT_MODEL_TWO_SIDE:
1916 *params = IsLightModelTwoSided(&mGLES1State);
1917 break;
1918
1919 default:
1920 UNREACHABLE();
1921 break;
1922 }
1923 }
1924
getFloatv(GLenum pname,GLfloat * params)1925 void State::getFloatv(GLenum pname, GLfloat *params)
1926 {
1927 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1928 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1929 // GetIntegerv as its native query function. As it would require conversion in any
1930 // case, this should make no difference to the calling application.
1931 switch (pname)
1932 {
1933 case GL_LINE_WIDTH:
1934 *params = mLineWidth;
1935 break;
1936 case GL_SAMPLE_COVERAGE_VALUE:
1937 *params = mSampleCoverageValue;
1938 break;
1939 case GL_DEPTH_CLEAR_VALUE:
1940 *params = mDepthClearValue;
1941 break;
1942 case GL_POLYGON_OFFSET_FACTOR:
1943 *params = mRasterizer.polygonOffsetFactor;
1944 break;
1945 case GL_POLYGON_OFFSET_UNITS:
1946 *params = mRasterizer.polygonOffsetUnits;
1947 break;
1948 case GL_DEPTH_RANGE:
1949 params[0] = mNearZ;
1950 params[1] = mFarZ;
1951 break;
1952 case GL_COLOR_CLEAR_VALUE:
1953 params[0] = mColorClearValue.red;
1954 params[1] = mColorClearValue.green;
1955 params[2] = mColorClearValue.blue;
1956 params[3] = mColorClearValue.alpha;
1957 break;
1958 case GL_BLEND_COLOR:
1959 params[0] = mBlendColor.red;
1960 params[1] = mBlendColor.green;
1961 params[2] = mBlendColor.blue;
1962 params[3] = mBlendColor.alpha;
1963 break;
1964 case GL_MULTISAMPLE_EXT:
1965 *params = static_cast<GLfloat>(mMultiSampling);
1966 break;
1967 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1968 *params = static_cast<GLfloat>(mSampleAlphaToOne);
1969 break;
1970 case GL_COVERAGE_MODULATION_CHROMIUM:
1971 params[0] = static_cast<GLfloat>(mCoverageModulation);
1972 break;
1973 case GL_ALPHA_TEST_REF:
1974 *params = mGLES1State.mAlphaTestRef;
1975 break;
1976 case GL_CURRENT_COLOR:
1977 {
1978 const auto &color = mGLES1State.mCurrentColor;
1979 params[0] = color.red;
1980 params[1] = color.green;
1981 params[2] = color.blue;
1982 params[3] = color.alpha;
1983 break;
1984 }
1985 case GL_CURRENT_NORMAL:
1986 {
1987 const auto &normal = mGLES1State.mCurrentNormal;
1988 params[0] = normal[0];
1989 params[1] = normal[1];
1990 params[2] = normal[2];
1991 break;
1992 }
1993 case GL_CURRENT_TEXTURE_COORDS:
1994 {
1995 const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
1996 params[0] = texcoord.s;
1997 params[1] = texcoord.t;
1998 params[2] = texcoord.r;
1999 params[3] = texcoord.q;
2000 break;
2001 }
2002 case GL_MODELVIEW_MATRIX:
2003 memcpy(params, mGLES1State.mModelviewMatrices.back().data(), 16 * sizeof(GLfloat));
2004 break;
2005 case GL_PROJECTION_MATRIX:
2006 memcpy(params, mGLES1State.mProjectionMatrices.back().data(), 16 * sizeof(GLfloat));
2007 break;
2008 case GL_TEXTURE_MATRIX:
2009 memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().data(),
2010 16 * sizeof(GLfloat));
2011 break;
2012 case GL_LIGHT_MODEL_AMBIENT:
2013 GetLightModelParameters(&mGLES1State, pname, params);
2014 break;
2015 case GL_FOG_MODE:
2016 case GL_FOG_DENSITY:
2017 case GL_FOG_START:
2018 case GL_FOG_END:
2019 case GL_FOG_COLOR:
2020 GetFogParameters(&mGLES1State, pname, params);
2021 break;
2022 case GL_POINT_SIZE:
2023 GetPointSize(&mGLES1State, params);
2024 break;
2025 case GL_POINT_SIZE_MIN:
2026 case GL_POINT_SIZE_MAX:
2027 case GL_POINT_FADE_THRESHOLD_SIZE:
2028 case GL_POINT_DISTANCE_ATTENUATION:
2029 GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
2030 break;
2031 default:
2032 UNREACHABLE();
2033 break;
2034 }
2035 }
2036
getIntegerv(const Context * context,GLenum pname,GLint * params)2037 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params)
2038 {
2039 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2040 {
2041 size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
2042 ASSERT(drawBuffer < mMaxDrawBuffers);
2043 Framebuffer *framebuffer = mDrawFramebuffer;
2044 // The default framebuffer may have fewer draw buffer states than a user-created one. The
2045 // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
2046 // the draw buffer is out of range for this framebuffer.
2047 *params = drawBuffer < framebuffer->getDrawbufferStateCount()
2048 ? framebuffer->getDrawBufferState(drawBuffer)
2049 : GL_NONE;
2050 return angle::Result::Continue;
2051 }
2052
2053 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
2054 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2055 // GetIntegerv as its native query function. As it would require conversion in any
2056 // case, this should make no difference to the calling application. You may find it in
2057 // State::getFloatv.
2058 switch (pname)
2059 {
2060 case GL_ARRAY_BUFFER_BINDING:
2061 *params = mBoundBuffers[BufferBinding::Array].id();
2062 break;
2063 case GL_DRAW_INDIRECT_BUFFER_BINDING:
2064 *params = mBoundBuffers[BufferBinding::DrawIndirect].id();
2065 break;
2066 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2067 {
2068 Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
2069 *params = elementArrayBuffer ? elementArrayBuffer->id() : 0;
2070 break;
2071 }
2072 case GL_DRAW_FRAMEBUFFER_BINDING:
2073 static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
2074 "Enum mismatch");
2075 *params = mDrawFramebuffer->id();
2076 break;
2077 case GL_READ_FRAMEBUFFER_BINDING:
2078 static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
2079 "Enum mismatch");
2080 *params = mReadFramebuffer->id();
2081 break;
2082 case GL_RENDERBUFFER_BINDING:
2083 *params = mRenderbuffer.id();
2084 break;
2085 case GL_VERTEX_ARRAY_BINDING:
2086 *params = mVertexArray->id();
2087 break;
2088 case GL_CURRENT_PROGRAM:
2089 *params = mProgram ? mProgram->id() : 0;
2090 break;
2091 case GL_PACK_ALIGNMENT:
2092 *params = mPack.alignment;
2093 break;
2094 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2095 *params = mPack.reverseRowOrder;
2096 break;
2097 case GL_PACK_ROW_LENGTH:
2098 *params = mPack.rowLength;
2099 break;
2100 case GL_PACK_SKIP_ROWS:
2101 *params = mPack.skipRows;
2102 break;
2103 case GL_PACK_SKIP_PIXELS:
2104 *params = mPack.skipPixels;
2105 break;
2106 case GL_UNPACK_ALIGNMENT:
2107 *params = mUnpack.alignment;
2108 break;
2109 case GL_UNPACK_ROW_LENGTH:
2110 *params = mUnpack.rowLength;
2111 break;
2112 case GL_UNPACK_IMAGE_HEIGHT:
2113 *params = mUnpack.imageHeight;
2114 break;
2115 case GL_UNPACK_SKIP_IMAGES:
2116 *params = mUnpack.skipImages;
2117 break;
2118 case GL_UNPACK_SKIP_ROWS:
2119 *params = mUnpack.skipRows;
2120 break;
2121 case GL_UNPACK_SKIP_PIXELS:
2122 *params = mUnpack.skipPixels;
2123 break;
2124 case GL_GENERATE_MIPMAP_HINT:
2125 *params = mGenerateMipmapHint;
2126 break;
2127 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2128 *params = mFragmentShaderDerivativeHint;
2129 break;
2130 case GL_ACTIVE_TEXTURE:
2131 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
2132 break;
2133 case GL_STENCIL_FUNC:
2134 *params = mDepthStencil.stencilFunc;
2135 break;
2136 case GL_STENCIL_REF:
2137 *params = mStencilRef;
2138 break;
2139 case GL_STENCIL_VALUE_MASK:
2140 *params = CastMaskValue(mDepthStencil.stencilMask);
2141 break;
2142 case GL_STENCIL_BACK_FUNC:
2143 *params = mDepthStencil.stencilBackFunc;
2144 break;
2145 case GL_STENCIL_BACK_REF:
2146 *params = mStencilBackRef;
2147 break;
2148 case GL_STENCIL_BACK_VALUE_MASK:
2149 *params = CastMaskValue(mDepthStencil.stencilBackMask);
2150 break;
2151 case GL_STENCIL_FAIL:
2152 *params = mDepthStencil.stencilFail;
2153 break;
2154 case GL_STENCIL_PASS_DEPTH_FAIL:
2155 *params = mDepthStencil.stencilPassDepthFail;
2156 break;
2157 case GL_STENCIL_PASS_DEPTH_PASS:
2158 *params = mDepthStencil.stencilPassDepthPass;
2159 break;
2160 case GL_STENCIL_BACK_FAIL:
2161 *params = mDepthStencil.stencilBackFail;
2162 break;
2163 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2164 *params = mDepthStencil.stencilBackPassDepthFail;
2165 break;
2166 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2167 *params = mDepthStencil.stencilBackPassDepthPass;
2168 break;
2169 case GL_DEPTH_FUNC:
2170 *params = mDepthStencil.depthFunc;
2171 break;
2172 case GL_BLEND_SRC_RGB:
2173 *params = mBlend.sourceBlendRGB;
2174 break;
2175 case GL_BLEND_SRC_ALPHA:
2176 *params = mBlend.sourceBlendAlpha;
2177 break;
2178 case GL_BLEND_DST_RGB:
2179 *params = mBlend.destBlendRGB;
2180 break;
2181 case GL_BLEND_DST_ALPHA:
2182 *params = mBlend.destBlendAlpha;
2183 break;
2184 case GL_BLEND_EQUATION_RGB:
2185 *params = mBlend.blendEquationRGB;
2186 break;
2187 case GL_BLEND_EQUATION_ALPHA:
2188 *params = mBlend.blendEquationAlpha;
2189 break;
2190 case GL_STENCIL_WRITEMASK:
2191 *params = CastMaskValue(mDepthStencil.stencilWritemask);
2192 break;
2193 case GL_STENCIL_BACK_WRITEMASK:
2194 *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
2195 break;
2196 case GL_STENCIL_CLEAR_VALUE:
2197 *params = mStencilClearValue;
2198 break;
2199 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2200 ANGLE_TRY(mReadFramebuffer->getImplementationColorReadType(
2201 context, reinterpret_cast<GLenum *>(params)));
2202 break;
2203 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2204 ANGLE_TRY(mReadFramebuffer->getImplementationColorReadFormat(
2205 context, reinterpret_cast<GLenum *>(params)));
2206 break;
2207 case GL_SAMPLE_BUFFERS:
2208 case GL_SAMPLES:
2209 {
2210 Framebuffer *framebuffer = mDrawFramebuffer;
2211 if (framebuffer->isComplete(context))
2212 {
2213 GLint samples = framebuffer->getSamples(context);
2214 switch (pname)
2215 {
2216 case GL_SAMPLE_BUFFERS:
2217 if (samples != 0)
2218 {
2219 *params = 1;
2220 }
2221 else
2222 {
2223 *params = 0;
2224 }
2225 break;
2226 case GL_SAMPLES:
2227 *params = samples;
2228 break;
2229 }
2230 }
2231 else
2232 {
2233 *params = 0;
2234 }
2235 }
2236 break;
2237 case GL_VIEWPORT:
2238 params[0] = mViewport.x;
2239 params[1] = mViewport.y;
2240 params[2] = mViewport.width;
2241 params[3] = mViewport.height;
2242 break;
2243 case GL_SCISSOR_BOX:
2244 params[0] = mScissor.x;
2245 params[1] = mScissor.y;
2246 params[2] = mScissor.width;
2247 params[3] = mScissor.height;
2248 break;
2249 case GL_CULL_FACE_MODE:
2250 *params = ToGLenum(mRasterizer.cullMode);
2251 break;
2252 case GL_FRONT_FACE:
2253 *params = mRasterizer.frontFace;
2254 break;
2255 case GL_RED_BITS:
2256 case GL_GREEN_BITS:
2257 case GL_BLUE_BITS:
2258 case GL_ALPHA_BITS:
2259 {
2260 Framebuffer *framebuffer = getDrawFramebuffer();
2261 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
2262
2263 if (colorbuffer)
2264 {
2265 switch (pname)
2266 {
2267 case GL_RED_BITS:
2268 *params = colorbuffer->getRedSize();
2269 break;
2270 case GL_GREEN_BITS:
2271 *params = colorbuffer->getGreenSize();
2272 break;
2273 case GL_BLUE_BITS:
2274 *params = colorbuffer->getBlueSize();
2275 break;
2276 case GL_ALPHA_BITS:
2277 *params = colorbuffer->getAlphaSize();
2278 break;
2279 }
2280 }
2281 else
2282 {
2283 *params = 0;
2284 }
2285 }
2286 break;
2287 case GL_DEPTH_BITS:
2288 {
2289 const Framebuffer *framebuffer = getDrawFramebuffer();
2290 const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
2291
2292 if (depthbuffer)
2293 {
2294 *params = depthbuffer->getDepthSize();
2295 }
2296 else
2297 {
2298 *params = 0;
2299 }
2300 }
2301 break;
2302 case GL_STENCIL_BITS:
2303 {
2304 const Framebuffer *framebuffer = getDrawFramebuffer();
2305 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
2306
2307 if (stencilbuffer)
2308 {
2309 *params = stencilbuffer->getStencilSize();
2310 }
2311 else
2312 {
2313 *params = 0;
2314 }
2315 }
2316 break;
2317 case GL_TEXTURE_BINDING_2D:
2318 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2319 *params =
2320 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D);
2321 break;
2322 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2323 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2324 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2325 TextureType::Rectangle);
2326 break;
2327 case GL_TEXTURE_BINDING_CUBE_MAP:
2328 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2329 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2330 TextureType::CubeMap);
2331 break;
2332 case GL_TEXTURE_BINDING_3D:
2333 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2334 *params =
2335 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D);
2336 break;
2337 case GL_TEXTURE_BINDING_2D_ARRAY:
2338 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2339 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2340 TextureType::_2DArray);
2341 break;
2342 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2343 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2344 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2345 TextureType::_2DMultisample);
2346 break;
2347 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
2348 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2349 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2350 TextureType::_2DMultisampleArray);
2351 break;
2352 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2353 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2354 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2355 TextureType::External);
2356 break;
2357 case GL_UNIFORM_BUFFER_BINDING:
2358 *params = mBoundBuffers[BufferBinding::Uniform].id();
2359 break;
2360 case GL_TRANSFORM_FEEDBACK_BINDING:
2361 *params = mTransformFeedback.id();
2362 break;
2363 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2364 *params = mBoundBuffers[BufferBinding::TransformFeedback].id();
2365 break;
2366 case GL_COPY_READ_BUFFER_BINDING:
2367 *params = mBoundBuffers[BufferBinding::CopyRead].id();
2368 break;
2369 case GL_COPY_WRITE_BUFFER_BINDING:
2370 *params = mBoundBuffers[BufferBinding::CopyWrite].id();
2371 break;
2372 case GL_PIXEL_PACK_BUFFER_BINDING:
2373 *params = mBoundBuffers[BufferBinding::PixelPack].id();
2374 break;
2375 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2376 *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
2377 break;
2378 case GL_READ_BUFFER:
2379 *params = mReadFramebuffer->getReadBufferState();
2380 break;
2381 case GL_SAMPLER_BINDING:
2382 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2383 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
2384 break;
2385 case GL_DEBUG_LOGGED_MESSAGES:
2386 *params = static_cast<GLint>(mDebug.getMessageCount());
2387 break;
2388 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2389 *params = static_cast<GLint>(mDebug.getNextMessageLength());
2390 break;
2391 case GL_DEBUG_GROUP_STACK_DEPTH:
2392 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2393 break;
2394 case GL_MULTISAMPLE_EXT:
2395 *params = static_cast<GLint>(mMultiSampling);
2396 break;
2397 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2398 *params = static_cast<GLint>(mSampleAlphaToOne);
2399 break;
2400 case GL_COVERAGE_MODULATION_CHROMIUM:
2401 *params = static_cast<GLint>(mCoverageModulation);
2402 break;
2403 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2404 *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
2405 break;
2406 case GL_SHADER_STORAGE_BUFFER_BINDING:
2407 *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
2408 break;
2409 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
2410 *params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
2411 break;
2412 case GL_ALPHA_TEST_FUNC:
2413 *params = ToGLenum(mGLES1State.mAlphaTestFunc);
2414 break;
2415 case GL_CLIENT_ACTIVE_TEXTURE:
2416 *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
2417 break;
2418 case GL_MATRIX_MODE:
2419 *params = ToGLenum(mGLES1State.mMatrixMode);
2420 break;
2421 case GL_SHADE_MODEL:
2422 *params = ToGLenum(mGLES1State.mShadeModel);
2423 break;
2424 case GL_MODELVIEW_STACK_DEPTH:
2425 case GL_PROJECTION_STACK_DEPTH:
2426 case GL_TEXTURE_STACK_DEPTH:
2427 *params = mGLES1State.getCurrentMatrixStackDepth(pname);
2428 break;
2429 case GL_LOGIC_OP_MODE:
2430 *params = ToGLenum(mGLES1State.mLogicOp);
2431 break;
2432 case GL_BLEND_SRC:
2433 *params = mBlend.sourceBlendRGB;
2434 break;
2435 case GL_BLEND_DST:
2436 *params = mBlend.destBlendRGB;
2437 break;
2438 case GL_PERSPECTIVE_CORRECTION_HINT:
2439 case GL_POINT_SMOOTH_HINT:
2440 case GL_LINE_SMOOTH_HINT:
2441 case GL_FOG_HINT:
2442 *params = mGLES1State.getHint(pname);
2443 break;
2444
2445 // GL_ANGLE_provoking_vertex
2446 case GL_PROVOKING_VERTEX:
2447 *params = ToGLenum(mProvokingVertex);
2448 break;
2449
2450 default:
2451 UNREACHABLE();
2452 break;
2453 }
2454
2455 return angle::Result::Continue;
2456 }
2457
getPointerv(const Context * context,GLenum pname,void ** params) const2458 void State::getPointerv(const Context *context, GLenum pname, void **params) const
2459 {
2460 switch (pname)
2461 {
2462 case GL_DEBUG_CALLBACK_FUNCTION:
2463 *params = reinterpret_cast<void *>(mDebug.getCallback());
2464 break;
2465 case GL_DEBUG_CALLBACK_USER_PARAM:
2466 *params = const_cast<void *>(mDebug.getUserParam());
2467 break;
2468 case GL_VERTEX_ARRAY_POINTER:
2469 case GL_NORMAL_ARRAY_POINTER:
2470 case GL_COLOR_ARRAY_POINTER:
2471 case GL_TEXTURE_COORD_ARRAY_POINTER:
2472 case GL_POINT_SIZE_ARRAY_POINTER_OES:
2473 QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
2474 context->vertexArrayIndex(ParamToVertexArrayType(pname))),
2475 GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
2476 return;
2477 default:
2478 UNREACHABLE();
2479 break;
2480 }
2481 }
2482
getIntegeri_v(GLenum target,GLuint index,GLint * data)2483 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
2484 {
2485 switch (target)
2486 {
2487 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2488 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2489 *data = mTransformFeedback->getIndexedBuffer(index).id();
2490 break;
2491 case GL_UNIFORM_BUFFER_BINDING:
2492 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2493 *data = mUniformBuffers[index].id();
2494 break;
2495 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2496 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2497 *data = mAtomicCounterBuffers[index].id();
2498 break;
2499 case GL_SHADER_STORAGE_BUFFER_BINDING:
2500 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2501 *data = mShaderStorageBuffers[index].id();
2502 break;
2503 case GL_VERTEX_BINDING_BUFFER:
2504 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2505 *data = mVertexArray->getVertexBinding(index).getBuffer().id();
2506 break;
2507 case GL_VERTEX_BINDING_DIVISOR:
2508 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2509 *data = mVertexArray->getVertexBinding(index).getDivisor();
2510 break;
2511 case GL_VERTEX_BINDING_OFFSET:
2512 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2513 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
2514 break;
2515 case GL_VERTEX_BINDING_STRIDE:
2516 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2517 *data = mVertexArray->getVertexBinding(index).getStride();
2518 break;
2519 case GL_SAMPLE_MASK_VALUE:
2520 ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
2521 *data = mSampleMaskValues[index];
2522 break;
2523 case GL_IMAGE_BINDING_NAME:
2524 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2525 *data = mImageUnits[index].texture.id();
2526 break;
2527 case GL_IMAGE_BINDING_LEVEL:
2528 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2529 *data = mImageUnits[index].level;
2530 break;
2531 case GL_IMAGE_BINDING_LAYER:
2532 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2533 *data = mImageUnits[index].layer;
2534 break;
2535 case GL_IMAGE_BINDING_ACCESS:
2536 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2537 *data = mImageUnits[index].access;
2538 break;
2539 case GL_IMAGE_BINDING_FORMAT:
2540 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2541 *data = mImageUnits[index].format;
2542 break;
2543 default:
2544 UNREACHABLE();
2545 break;
2546 }
2547 }
2548
getInteger64i_v(GLenum target,GLuint index,GLint64 * data)2549 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
2550 {
2551 switch (target)
2552 {
2553 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2554 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2555 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
2556 break;
2557 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2558 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2559 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
2560 break;
2561 case GL_UNIFORM_BUFFER_START:
2562 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2563 *data = mUniformBuffers[index].getOffset();
2564 break;
2565 case GL_UNIFORM_BUFFER_SIZE:
2566 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2567 *data = mUniformBuffers[index].getSize();
2568 break;
2569 case GL_ATOMIC_COUNTER_BUFFER_START:
2570 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2571 *data = mAtomicCounterBuffers[index].getOffset();
2572 break;
2573 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2574 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2575 *data = mAtomicCounterBuffers[index].getSize();
2576 break;
2577 case GL_SHADER_STORAGE_BUFFER_START:
2578 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2579 *data = mShaderStorageBuffers[index].getOffset();
2580 break;
2581 case GL_SHADER_STORAGE_BUFFER_SIZE:
2582 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2583 *data = mShaderStorageBuffers[index].getSize();
2584 break;
2585 default:
2586 UNREACHABLE();
2587 break;
2588 }
2589 }
2590
getBooleani_v(GLenum target,GLuint index,GLboolean * data)2591 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
2592 {
2593 switch (target)
2594 {
2595 case GL_IMAGE_BINDING_LAYERED:
2596 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
2597 *data = mImageUnits[index].layered;
2598 break;
2599 default:
2600 UNREACHABLE();
2601 break;
2602 }
2603 }
2604
syncTexturesInit(const Context * context)2605 angle::Result State::syncTexturesInit(const Context *context)
2606 {
2607 ASSERT(mRobustResourceInit);
2608
2609 if (!mProgram)
2610 return angle::Result::Continue;
2611
2612 for (size_t textureUnitIndex : mProgram->getActiveSamplersMask())
2613 {
2614 Texture *texture = mActiveTexturesCache[textureUnitIndex];
2615 if (texture)
2616 {
2617 ANGLE_TRY(texture->ensureInitialized(context));
2618 }
2619 }
2620 return angle::Result::Continue;
2621 }
2622
syncImagesInit(const Context * context)2623 angle::Result State::syncImagesInit(const Context *context)
2624 {
2625 ASSERT(mRobustResourceInit);
2626 ASSERT(mProgram);
2627 for (size_t imageUnitIndex : mProgram->getActiveImagesMask())
2628 {
2629 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
2630 if (texture)
2631 {
2632 ANGLE_TRY(texture->ensureInitialized(context));
2633 }
2634 }
2635 return angle::Result::Continue;
2636 }
2637
syncReadAttachments(const Context * context)2638 angle::Result State::syncReadAttachments(const Context *context)
2639 {
2640 ASSERT(mReadFramebuffer);
2641 ASSERT(mRobustResourceInit);
2642 return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
2643 }
2644
syncDrawAttachments(const Context * context)2645 angle::Result State::syncDrawAttachments(const Context *context)
2646 {
2647 ASSERT(mDrawFramebuffer);
2648 ASSERT(mRobustResourceInit);
2649 return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
2650 }
2651
syncReadFramebuffer(const Context * context)2652 angle::Result State::syncReadFramebuffer(const Context *context)
2653 {
2654 ASSERT(mReadFramebuffer);
2655 return mReadFramebuffer->syncState(context);
2656 }
2657
syncDrawFramebuffer(const Context * context)2658 angle::Result State::syncDrawFramebuffer(const Context *context)
2659 {
2660 ASSERT(mDrawFramebuffer);
2661 return mDrawFramebuffer->syncState(context);
2662 }
2663
syncTextures(const Context * context)2664 angle::Result State::syncTextures(const Context *context)
2665 {
2666 if (mDirtyTextures.none())
2667 return angle::Result::Continue;
2668
2669 for (size_t textureIndex : mDirtyTextures)
2670 {
2671 Texture *texture = mActiveTexturesCache[textureIndex];
2672 if (texture && texture->hasAnyDirtyBit())
2673 {
2674 ANGLE_TRY(texture->syncState(context));
2675 }
2676 }
2677
2678 mDirtyTextures.reset();
2679 return angle::Result::Continue;
2680 }
2681
syncSamplers(const Context * context)2682 angle::Result State::syncSamplers(const Context *context)
2683 {
2684 if (mDirtySamplers.none())
2685 return angle::Result::Continue;
2686
2687 for (size_t samplerIndex : mDirtySamplers)
2688 {
2689 BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
2690 if (sampler.get() && sampler->isDirty())
2691 {
2692 ANGLE_TRY(sampler->syncState(context));
2693 }
2694 }
2695
2696 mDirtySamplers.reset();
2697
2698 return angle::Result::Continue;
2699 }
2700
syncVertexArray(const Context * context)2701 angle::Result State::syncVertexArray(const Context *context)
2702 {
2703 ASSERT(mVertexArray);
2704 return mVertexArray->syncState(context);
2705 }
2706
syncProgram(const Context * context)2707 angle::Result State::syncProgram(const Context *context)
2708 {
2709 return mProgram->syncState(context);
2710 }
2711
syncDirtyObject(const Context * context,GLenum target)2712 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
2713 {
2714 DirtyObjects localSet;
2715
2716 switch (target)
2717 {
2718 case GL_READ_FRAMEBUFFER:
2719 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2720 break;
2721 case GL_DRAW_FRAMEBUFFER:
2722 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2723 break;
2724 case GL_FRAMEBUFFER:
2725 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2726 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2727 break;
2728 case GL_VERTEX_ARRAY:
2729 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2730 break;
2731 case GL_TEXTURE:
2732 localSet.set(DIRTY_OBJECT_TEXTURES);
2733 break;
2734 case GL_SAMPLER:
2735 localSet.set(DIRTY_OBJECT_SAMPLERS);
2736 break;
2737 case GL_PROGRAM:
2738 localSet.set(DIRTY_OBJECT_PROGRAM);
2739 break;
2740 }
2741
2742 return syncDirtyObjects(context, localSet);
2743 }
2744
setObjectDirty(GLenum target)2745 void State::setObjectDirty(GLenum target)
2746 {
2747 switch (target)
2748 {
2749 case GL_READ_FRAMEBUFFER:
2750 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2751 break;
2752 case GL_DRAW_FRAMEBUFFER:
2753 setDrawFramebufferDirty();
2754 break;
2755 case GL_FRAMEBUFFER:
2756 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2757 setDrawFramebufferDirty();
2758 break;
2759 case GL_VERTEX_ARRAY:
2760 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2761 break;
2762 case GL_PROGRAM:
2763 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
2764 break;
2765 default:
2766 break;
2767 }
2768 }
2769
onProgramExecutableChange(const Context * context,Program * program)2770 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
2771 {
2772 // OpenGL Spec:
2773 // "If LinkProgram or ProgramBinary successfully re-links a program object
2774 // that was already in use as a result of a previous call to UseProgram, then the
2775 // generated executable code will be installed as part of the current rendering state."
2776 ASSERT(program->isLinked());
2777
2778 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
2779
2780 if (program->hasAnyDirtyBit())
2781 {
2782 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
2783 }
2784
2785 // Set any bound textures.
2786 const ActiveTextureTypeArray &textureTypes = program->getActiveSamplerTypes();
2787 for (size_t textureIndex : program->getActiveSamplersMask())
2788 {
2789 TextureType type = textureTypes[textureIndex];
2790
2791 // This can happen if there is a conflicting texture type.
2792 if (type == TextureType::InvalidEnum)
2793 continue;
2794
2795 Texture *texture = mSamplerTextures[type][textureIndex].get();
2796 updateActiveTexture(context, textureIndex, texture);
2797 }
2798
2799 for (size_t imageUnitIndex : program->getActiveImagesMask())
2800 {
2801 Texture *image = mImageUnits[imageUnitIndex].texture.get();
2802 if (!image)
2803 continue;
2804
2805 if (image->hasAnyDirtyBit())
2806 {
2807 ANGLE_TRY(image->syncState(context));
2808 }
2809
2810 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
2811 {
2812 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
2813 }
2814 }
2815
2816 return angle::Result::Continue;
2817 }
2818
setTextureDirty(size_t textureUnitIndex)2819 void State::setTextureDirty(size_t textureUnitIndex)
2820 {
2821 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
2822 mDirtyTextures.set(textureUnitIndex);
2823 }
2824
setSamplerDirty(size_t samplerIndex)2825 void State::setSamplerDirty(size_t samplerIndex)
2826 {
2827 mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
2828 mDirtySamplers.set(samplerIndex);
2829 }
2830
setImageUnit(const Context * context,size_t unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)2831 void State::setImageUnit(const Context *context,
2832 size_t unit,
2833 Texture *texture,
2834 GLint level,
2835 GLboolean layered,
2836 GLint layer,
2837 GLenum access,
2838 GLenum format)
2839 {
2840 mImageUnits[unit].texture.set(context, texture);
2841 mImageUnits[unit].level = level;
2842 mImageUnits[unit].layered = layered;
2843 mImageUnits[unit].layer = layer;
2844 mImageUnits[unit].access = access;
2845 mImageUnits[unit].format = format;
2846 mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
2847
2848 onImageStateChange(context, unit);
2849 }
2850
2851 // Handle a dirty texture event.
onActiveTextureChange(const Context * context,size_t textureUnit)2852 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
2853 {
2854 if (mProgram)
2855 {
2856 TextureType type = mProgram->getActiveSamplerTypes()[textureUnit];
2857 if (type != TextureType::InvalidEnum)
2858 {
2859 Texture *activeTexture = mSamplerTextures[type][textureUnit].get();
2860 updateActiveTexture(context, textureUnit, activeTexture);
2861 }
2862 }
2863 }
2864
onActiveTextureStateChange(const Context * context,size_t textureUnit)2865 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
2866 {
2867 if (mProgram)
2868 {
2869 TextureType type = mProgram->getActiveSamplerTypes()[textureUnit];
2870 if (type != TextureType::InvalidEnum)
2871 {
2872 Texture *activeTexture = mSamplerTextures[type][textureUnit].get();
2873 const Sampler *sampler = mSamplers[textureUnit].get();
2874 updateActiveTextureState(context, textureUnit, sampler, activeTexture);
2875 }
2876 }
2877 }
2878
onImageStateChange(const Context * context,size_t unit)2879 void State::onImageStateChange(const Context *context, size_t unit)
2880 {
2881 if (mProgram)
2882 {
2883 const ImageUnit &image = mImageUnits[unit];
2884 ASSERT(image.texture.get());
2885 if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
2886 {
2887 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
2888 }
2889 }
2890 }
2891
onUniformBufferStateChange(size_t uniformBufferIndex)2892 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
2893 {
2894 // This could be represented by a different dirty bit. Using the same one keeps it simple.
2895 mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
2896 }
2897
getAndResetDirtyCurrentValues() const2898 AttributesMask State::getAndResetDirtyCurrentValues() const
2899 {
2900 AttributesMask retVal = mDirtyCurrentValues;
2901 mDirtyCurrentValues.reset();
2902 return retVal;
2903 }
2904
2905 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
2906
2907 } // namespace gl
2908