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,T * shareResources=nullptr)75 T *AllocateOrGetSharedResourceManager(const State *shareContextState,
76 ContextStateMember<T> member,
77 T *shareResources = nullptr)
78 {
79 if (shareContextState)
80 {
81 T *resourceManager = (*shareContextState).*member;
82 ASSERT(!resourceManager || resourceManager == shareResources || !shareResources);
83 resourceManager->addRef();
84 return resourceManager;
85 }
86 else if (shareResources)
87 {
88 shareResources->addRef();
89 return shareResources;
90 }
91 else
92 {
93 return new T();
94 }
95 }
96
97 // TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
98 // refactory done.
IsTextureCompatibleWithSampler(TextureType texture,TextureType sampler)99 bool IsTextureCompatibleWithSampler(TextureType texture, TextureType sampler)
100 {
101 if (sampler == texture)
102 {
103 return true;
104 }
105
106 if (sampler == TextureType::VideoImage)
107 {
108 if (texture == TextureType::VideoImage || texture == TextureType::_2D)
109 {
110 return true;
111 }
112 }
113
114 return false;
115 }
116
117 uint32_t gIDCounter = 1;
118 } // namespace
119
120 template <typename BindingT, typename... ArgsT>
UpdateNonTFBufferBinding(const Context * context,BindingT * binding,Buffer * buffer,ArgsT...args)121 ANGLE_INLINE void UpdateNonTFBufferBinding(const Context *context,
122 BindingT *binding,
123 Buffer *buffer,
124 ArgsT... args)
125 {
126 Buffer *oldBuffer = binding->get();
127 if (oldBuffer)
128 {
129 oldBuffer->onNonTFBindingChanged(-1);
130 oldBuffer->release(context);
131 }
132 binding->assign(buffer, args...);
133 if (buffer)
134 {
135 buffer->addRef();
136 buffer->onNonTFBindingChanged(1);
137 }
138 }
139
140 template <typename BindingT, typename... ArgsT>
UpdateTFBufferBinding(const Context * context,BindingT * binding,bool indexed,ArgsT...args)141 void UpdateTFBufferBinding(const Context *context, BindingT *binding, bool indexed, ArgsT... args)
142 {
143 if (binding->get())
144 (*binding)->onTFBindingChanged(context, false, indexed);
145 binding->set(context, args...);
146 if (binding->get())
147 (*binding)->onTFBindingChanged(context, true, indexed);
148 }
149
UpdateBufferBinding(const Context * context,BindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target)150 void UpdateBufferBinding(const Context *context,
151 BindingPointer<Buffer> *binding,
152 Buffer *buffer,
153 BufferBinding target)
154 {
155 if (target == BufferBinding::TransformFeedback)
156 {
157 UpdateTFBufferBinding(context, binding, false, buffer);
158 }
159 else
160 {
161 UpdateNonTFBufferBinding(context, binding, buffer);
162 }
163 }
164
UpdateIndexedBufferBinding(const Context * context,OffsetBindingPointer<Buffer> * binding,Buffer * buffer,BufferBinding target,GLintptr offset,GLsizeiptr size)165 void UpdateIndexedBufferBinding(const Context *context,
166 OffsetBindingPointer<Buffer> *binding,
167 Buffer *buffer,
168 BufferBinding target,
169 GLintptr offset,
170 GLsizeiptr size)
171 {
172 if (target == BufferBinding::TransformFeedback)
173 {
174 UpdateTFBufferBinding(context, binding, true, buffer, offset, size);
175 }
176 else
177 {
178 UpdateNonTFBufferBinding(context, binding, buffer, offset, size);
179 }
180 }
181
182 // These template functions must be defined before they are instantiated in kBufferSetters.
183 template <BufferBinding Target>
setGenericBufferBindingWithBit(const Context * context,Buffer * buffer)184 void State::setGenericBufferBindingWithBit(const Context *context, Buffer *buffer)
185 {
186 UpdateNonTFBufferBinding(context, &mBoundBuffers[Target], buffer);
187 mDirtyBits.set(kBufferBindingDirtyBits[Target]);
188 }
189
190 template <BufferBinding Target>
setGenericBufferBinding(const Context * context,Buffer * buffer)191 void State::setGenericBufferBinding(const Context *context, Buffer *buffer)
192 {
193 UpdateNonTFBufferBinding(context, &mBoundBuffers[Target], buffer);
194 }
195
196 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)197 void State::setGenericBufferBinding<BufferBinding::TransformFeedback>(const Context *context,
198 Buffer *buffer)
199 {
200 UpdateTFBufferBinding(context, &mBoundBuffers[BufferBinding::TransformFeedback], false, buffer);
201 }
202
203 template <>
setGenericBufferBinding(const Context * context,Buffer * buffer)204 void State::setGenericBufferBinding<BufferBinding::ElementArray>(const Context *context,
205 Buffer *buffer)
206 {
207 Buffer *oldBuffer = mVertexArray->mState.mElementArrayBuffer.get();
208 if (oldBuffer)
209 {
210 oldBuffer->removeObserver(&mVertexArray->mState.mElementArrayBuffer);
211 oldBuffer->onNonTFBindingChanged(-1);
212 oldBuffer->release(context);
213 }
214 mVertexArray->mState.mElementArrayBuffer.assign(buffer);
215 if (buffer)
216 {
217 buffer->addObserver(&mVertexArray->mState.mElementArrayBuffer);
218 buffer->onNonTFBindingChanged(1);
219 buffer->addRef();
220 }
221 mVertexArray->mDirtyBits.set(VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
222 mVertexArray->mIndexRangeCache.invalidate();
223 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
224 }
225
226 const angle::PackedEnumMap<BufferBinding, State::BufferBindingSetter> State::kBufferSetters = {{
227 GetBufferBindingSetter<BufferBinding::Array>(),
228 GetBufferBindingSetter<BufferBinding::AtomicCounter>(),
229 GetBufferBindingSetter<BufferBinding::CopyRead>(),
230 GetBufferBindingSetter<BufferBinding::CopyWrite>(),
231 GetBufferBindingSetter<BufferBinding::DispatchIndirect>(),
232 GetBufferBindingSetter<BufferBinding::DrawIndirect>(),
233 GetBufferBindingSetter<BufferBinding::ElementArray>(),
234 GetBufferBindingSetter<BufferBinding::PixelPack>(),
235 GetBufferBindingSetter<BufferBinding::PixelUnpack>(),
236 GetBufferBindingSetter<BufferBinding::ShaderStorage>(),
237 GetBufferBindingSetter<BufferBinding::Texture>(),
238 GetBufferBindingSetter<BufferBinding::TransformFeedback>(),
239 GetBufferBindingSetter<BufferBinding::Uniform>(),
240 }};
241
ActiveTexturesCache()242 ActiveTexturesCache::ActiveTexturesCache() : mTextures{} {}
243
~ActiveTexturesCache()244 ActiveTexturesCache::~ActiveTexturesCache()
245 {
246 ASSERT(empty());
247 }
248
clear()249 void ActiveTexturesCache::clear()
250 {
251 for (size_t textureIndex = 0; textureIndex < mTextures.size(); ++textureIndex)
252 {
253 reset(textureIndex);
254 }
255 }
256
empty() const257 bool ActiveTexturesCache::empty() const
258 {
259 for (Texture *texture : mTextures)
260 {
261 if (texture)
262 {
263 return false;
264 }
265 }
266
267 return true;
268 }
269
reset(size_t textureIndex)270 ANGLE_INLINE void ActiveTexturesCache::reset(size_t textureIndex)
271 {
272 if (mTextures[textureIndex])
273 {
274 mTextures[textureIndex] = nullptr;
275 }
276 }
277
set(size_t textureIndex,Texture * texture)278 ANGLE_INLINE void ActiveTexturesCache::set(size_t textureIndex, Texture *texture)
279 {
280 ASSERT(texture);
281 mTextures[textureIndex] = texture;
282 }
283
State(const State * shareContextState,egl::ShareGroup * shareGroup,TextureManager * shareTextures,SemaphoreManager * shareSemaphores,const OverlayType * overlay,const EGLenum clientType,const Version & clientVersion,bool debug,bool bindGeneratesResource,bool clientArraysEnabled,bool robustResourceInit,bool programBinaryCacheEnabled,EGLenum contextPriority)284 State::State(const State *shareContextState,
285 egl::ShareGroup *shareGroup,
286 TextureManager *shareTextures,
287 SemaphoreManager *shareSemaphores,
288 const OverlayType *overlay,
289 const EGLenum clientType,
290 const Version &clientVersion,
291 bool debug,
292 bool bindGeneratesResource,
293 bool clientArraysEnabled,
294 bool robustResourceInit,
295 bool programBinaryCacheEnabled,
296 EGLenum contextPriority)
297 : mID({gIDCounter++}),
298 mClientType(clientType),
299 mContextPriority(contextPriority),
300 mClientVersion(clientVersion),
301 mShareGroup(shareGroup),
302 mBufferManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mBufferManager)),
303 mShaderProgramManager(
304 AllocateOrGetSharedResourceManager(shareContextState, &State::mShaderProgramManager)),
305 mTextureManager(AllocateOrGetSharedResourceManager(shareContextState,
306 &State::mTextureManager,
307 shareTextures)),
308 mRenderbufferManager(
309 AllocateOrGetSharedResourceManager(shareContextState, &State::mRenderbufferManager)),
310 mSamplerManager(
311 AllocateOrGetSharedResourceManager(shareContextState, &State::mSamplerManager)),
312 mSyncManager(AllocateOrGetSharedResourceManager(shareContextState, &State::mSyncManager)),
313 mFramebufferManager(new FramebufferManager()),
314 mProgramPipelineManager(new ProgramPipelineManager()),
315 mMemoryObjectManager(
316 AllocateOrGetSharedResourceManager(shareContextState, &State::mMemoryObjectManager)),
317 mSemaphoreManager(AllocateOrGetSharedResourceManager(shareContextState,
318 &State::mSemaphoreManager,
319 shareSemaphores)),
320 mMaxDrawBuffers(0),
321 mMaxCombinedTextureImageUnits(0),
322 mDepthClearValue(0),
323 mStencilClearValue(0),
324 mScissorTest(false),
325 mSampleAlphaToCoverage(false),
326 mSampleCoverage(false),
327 mSampleCoverageValue(0),
328 mSampleCoverageInvert(false),
329 mSampleMask(false),
330 mMaxSampleMaskWords(0),
331 mIsSampleShadingEnabled(false),
332 mMinSampleShading(0.0f),
333 mStencilRef(0),
334 mStencilBackRef(0),
335 mLineWidth(0),
336 mGenerateMipmapHint(GL_NONE),
337 mTextureFilteringHint(GL_NONE),
338 mFragmentShaderDerivativeHint(GL_NONE),
339 mBindGeneratesResource(bindGeneratesResource),
340 mClientArraysEnabled(clientArraysEnabled),
341 mNearZ(0),
342 mFarZ(0),
343 mReadFramebuffer(nullptr),
344 mDrawFramebuffer(nullptr),
345 mProgram(nullptr),
346 mExecutable(nullptr),
347 mProvokingVertex(gl::ProvokingVertexConvention::LastVertexConvention),
348 mVertexArray(nullptr),
349 mActiveSampler(0),
350 mPrimitiveRestart(false),
351 mDebug(debug),
352 mMultiSampling(false),
353 mSampleAlphaToOne(false),
354 mFramebufferSRGB(true),
355 mRobustResourceInit(robustResourceInit),
356 mProgramBinaryCacheEnabled(programBinaryCacheEnabled),
357 mTextureRectangleEnabled(true),
358 mMaxShaderCompilerThreads(std::numeric_limits<GLuint>::max()),
359 mPatchVertices(3),
360 mOverlay(overlay),
361 mNoSimultaneousConstantColorAndAlphaBlendFunc(false)
362 {}
363
~State()364 State::~State() {}
365
initialize(Context * context)366 void State::initialize(Context *context)
367 {
368 const Caps &caps = context->getCaps();
369 const Extensions &extensions = context->getExtensions();
370 const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
371 const Version &clientVersion = context->getClientVersion();
372
373 mMaxDrawBuffers = static_cast<GLuint>(caps.maxDrawBuffers);
374 mBlendStateExt = BlendStateExt(mMaxDrawBuffers);
375 mMaxCombinedTextureImageUnits = static_cast<GLuint>(caps.maxCombinedTextureImageUnits);
376
377 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
378
379 mDepthClearValue = 1.0f;
380 mStencilClearValue = 0;
381
382 mScissorTest = false;
383 mScissor.x = 0;
384 mScissor.y = 0;
385 mScissor.width = 0;
386 mScissor.height = 0;
387
388 mBlendColor.red = 0;
389 mBlendColor.green = 0;
390 mBlendColor.blue = 0;
391 mBlendColor.alpha = 0;
392
393 mStencilRef = 0;
394 mStencilBackRef = 0;
395
396 mSampleCoverage = false;
397 mSampleCoverageValue = 1.0f;
398 mSampleCoverageInvert = false;
399
400 mMaxSampleMaskWords = static_cast<GLuint>(caps.maxSampleMaskWords);
401 mSampleMask = false;
402 mSampleMaskValues.fill(~GLbitfield(0));
403
404 mGenerateMipmapHint = GL_DONT_CARE;
405 mTextureFilteringHint = GL_DONT_CARE;
406 mFragmentShaderDerivativeHint = GL_DONT_CARE;
407
408 mLineWidth = 1.0f;
409
410 mViewport.x = 0;
411 mViewport.y = 0;
412 mViewport.width = 0;
413 mViewport.height = 0;
414 mNearZ = 0.0f;
415 mFarZ = 1.0f;
416
417 mClipControlOrigin = GL_LOWER_LEFT_EXT;
418 mClipControlDepth = GL_NEGATIVE_ONE_TO_ONE_EXT;
419
420 mActiveSampler = 0;
421
422 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
423
424 // Set all indexes in state attributes type mask to float (default)
425 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
426 {
427 SetComponentTypeMask(ComponentType::Float, i, &mCurrentValuesTypeMask);
428 }
429
430 mUniformBuffers.resize(caps.maxUniformBufferBindings);
431
432 mSamplerTextures[TextureType::_2D].resize(caps.maxCombinedTextureImageUnits);
433 mSamplerTextures[TextureType::CubeMap].resize(caps.maxCombinedTextureImageUnits);
434 if (clientVersion >= Version(3, 0) || nativeExtensions.texture3DOES)
435 {
436 mSamplerTextures[TextureType::_3D].resize(caps.maxCombinedTextureImageUnits);
437 }
438 if (clientVersion >= Version(3, 0))
439 {
440 mSamplerTextures[TextureType::_2DArray].resize(caps.maxCombinedTextureImageUnits);
441 }
442 if (clientVersion >= Version(3, 1) || nativeExtensions.textureMultisample)
443 {
444 mSamplerTextures[TextureType::_2DMultisample].resize(caps.maxCombinedTextureImageUnits);
445 }
446 if (clientVersion >= Version(3, 1))
447 {
448 mSamplerTextures[TextureType::_2DMultisampleArray].resize(
449 caps.maxCombinedTextureImageUnits);
450
451 mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
452 mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
453 mImageUnits.resize(caps.maxImageUnits);
454 }
455 if (clientVersion >= Version(3, 2) || extensions.textureCubeMapArrayAny())
456 {
457 mSamplerTextures[TextureType::CubeMapArray].resize(caps.maxCombinedTextureImageUnits);
458 }
459 if (clientVersion >= Version(3, 2) || extensions.textureBufferAny())
460 {
461 mSamplerTextures[TextureType::Buffer].resize(caps.maxCombinedTextureImageUnits);
462 }
463 if (nativeExtensions.textureRectangle)
464 {
465 mSamplerTextures[TextureType::Rectangle].resize(caps.maxCombinedTextureImageUnits);
466 }
467 if (nativeExtensions.eglImageExternalOES || nativeExtensions.eglStreamConsumerExternalNV)
468 {
469 mSamplerTextures[TextureType::External].resize(caps.maxCombinedTextureImageUnits);
470 }
471 if (nativeExtensions.webglVideoTexture)
472 {
473 mSamplerTextures[TextureType::VideoImage].resize(caps.maxCombinedTextureImageUnits);
474 }
475 mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
476 for (int32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits; ++textureIndex)
477 {
478 mCompleteTextureBindings.emplace_back(context, textureIndex);
479 }
480
481 mSamplers.resize(caps.maxCombinedTextureImageUnits);
482
483 for (QueryType type : angle::AllEnums<QueryType>())
484 {
485 mActiveQueries[type].set(context, nullptr);
486 }
487
488 mProgram = nullptr;
489 mExecutable = nullptr;
490
491 mReadFramebuffer = nullptr;
492 mDrawFramebuffer = nullptr;
493
494 mPrimitiveRestart = false;
495
496 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
497
498 mMultiSampling = true;
499 mSampleAlphaToOne = false;
500
501 mCoverageModulation = GL_NONE;
502
503 mNoSimultaneousConstantColorAndAlphaBlendFunc =
504 context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
505 context->getExtensions().webglCompatibility;
506
507 // GLES1 emulation: Initialize state for GLES1 if version applies
508 // TODO(http://anglebug.com/3745): When on desktop client only do this in compatibility profile
509 if (clientVersion < Version(2, 0) || mClientType == EGL_OPENGL_API)
510 {
511 mGLES1State.initialize(context, this);
512 }
513 }
514
reset(const Context * context)515 void State::reset(const Context *context)
516 {
517 // Force a sync so clear doesn't end up deferencing stale pointers.
518 (void)syncActiveTextures(context, Command::Other);
519 mActiveTexturesCache.clear();
520
521 for (TextureBindingVector &bindingVec : mSamplerTextures)
522 {
523 for (BindingPointer<Texture> &texBinding : bindingVec)
524 {
525 texBinding.set(context, nullptr);
526 }
527 }
528 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
529 {
530 mSamplers[samplerIdx].set(context, nullptr);
531 }
532
533 for (ImageUnit &imageUnit : mImageUnits)
534 {
535 imageUnit.texture.set(context, nullptr);
536 imageUnit.level = 0;
537 imageUnit.layered = false;
538 imageUnit.layer = 0;
539 imageUnit.access = GL_READ_ONLY;
540 imageUnit.format = GL_R32UI;
541 }
542
543 mRenderbuffer.set(context, nullptr);
544
545 for (BufferBinding type : angle::AllEnums<BufferBinding>())
546 {
547 UpdateBufferBinding(context, &mBoundBuffers[type], nullptr, type);
548 }
549
550 if (mProgram)
551 {
552 mProgram->release(context);
553 }
554 mProgram = nullptr;
555 mProgramPipeline.set(context, nullptr);
556 mExecutable = nullptr;
557
558 if (mTransformFeedback.get())
559 {
560 mTransformFeedback->onBindingChanged(context, false);
561 }
562 mTransformFeedback.set(context, nullptr);
563
564 for (QueryType type : angle::AllEnums<QueryType>())
565 {
566 mActiveQueries[type].set(context, nullptr);
567 }
568
569 for (OffsetBindingPointer<Buffer> &buf : mUniformBuffers)
570 {
571 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::Uniform, 0, 0);
572 }
573 mBoundUniformBuffersMask.reset();
574
575 for (OffsetBindingPointer<Buffer> &buf : mAtomicCounterBuffers)
576 {
577 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::AtomicCounter, 0, 0);
578 }
579 mBoundAtomicCounterBuffersMask.reset();
580
581 for (OffsetBindingPointer<Buffer> &buf : mShaderStorageBuffers)
582 {
583 UpdateIndexedBufferBinding(context, &buf, nullptr, BufferBinding::ShaderStorage, 0, 0);
584 }
585 mBoundShaderStorageBuffersMask.reset();
586
587 mClipDistancesEnabled.reset();
588
589 setAllDirtyBits();
590 }
591
unsetActiveTextures(const ActiveTextureMask & textureMask)592 ANGLE_INLINE void State::unsetActiveTextures(const ActiveTextureMask &textureMask)
593 {
594 // Unset any relevant bound textures.
595 for (size_t textureIndex : textureMask)
596 {
597 mActiveTexturesCache.reset(textureIndex);
598 mCompleteTextureBindings[textureIndex].reset();
599 }
600 }
601
updateActiveTextureStateOnSync(const Context * context,size_t textureIndex,const Sampler * sampler,Texture * texture)602 ANGLE_INLINE void State::updateActiveTextureStateOnSync(const Context *context,
603 size_t textureIndex,
604 const Sampler *sampler,
605 Texture *texture)
606 {
607 if (!texture || !texture->isSamplerComplete(context, sampler))
608 {
609 mActiveTexturesCache.reset(textureIndex);
610 }
611 else
612 {
613 mActiveTexturesCache.set(textureIndex, texture);
614 }
615
616 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
617 }
618
setActiveTextureDirty(size_t textureIndex,Texture * texture)619 ANGLE_INLINE void State::setActiveTextureDirty(size_t textureIndex, Texture *texture)
620 {
621 mDirtyObjects.set(DIRTY_OBJECT_ACTIVE_TEXTURES);
622 mDirtyActiveTextures.set(textureIndex);
623
624 if (!texture)
625 {
626 return;
627 }
628
629 if (texture->hasAnyDirtyBit())
630 {
631 setTextureDirty(textureIndex);
632 }
633
634 if (mRobustResourceInit && texture->initState() == InitState::MayNeedInit)
635 {
636 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES_INIT);
637 }
638
639 // This cache is updated immediately because we use the cache in the validation layer.
640 // If we defer the update until syncState it's too late and we've already passed validation.
641 if (texture && mExecutable)
642 {
643 // It is invalid to try to sample a non-yuv texture with a yuv sampler.
644 mTexturesIncompatibleWithSamplers[textureIndex] =
645 mExecutable->getActiveYUVSamplers().test(textureIndex) && !texture->isYUV();
646
647 if (isWebGL())
648 {
649 const Sampler *sampler = mSamplers[textureIndex].get();
650 const SamplerState &samplerState =
651 sampler ? sampler->getSamplerState() : texture->getSamplerState();
652 if (!texture->getTextureState().compatibleWithSamplerFormatForWebGL(
653 mExecutable->getSamplerFormatForTextureUnitIndex(textureIndex), samplerState))
654 {
655 mTexturesIncompatibleWithSamplers[textureIndex] = true;
656 }
657 }
658 }
659 else
660 {
661 mTexturesIncompatibleWithSamplers[textureIndex] = false;
662 }
663 }
664
updateTextureBinding(const Context * context,size_t textureIndex,Texture * texture)665 ANGLE_INLINE void State::updateTextureBinding(const Context *context,
666 size_t textureIndex,
667 Texture *texture)
668 {
669 mCompleteTextureBindings[textureIndex].bind(texture);
670 mActiveTexturesCache.reset(textureIndex);
671 setActiveTextureDirty(textureIndex, texture);
672 }
673
hasConstantColor(GLenum sourceRGB,GLenum destRGB) const674 ANGLE_INLINE bool State::hasConstantColor(GLenum sourceRGB, GLenum destRGB) const
675 {
676 return sourceRGB == GL_CONSTANT_COLOR || sourceRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
677 destRGB == GL_CONSTANT_COLOR || destRGB == GL_ONE_MINUS_CONSTANT_COLOR;
678 }
679
hasConstantAlpha(GLenum sourceRGB,GLenum destRGB) const680 ANGLE_INLINE bool State::hasConstantAlpha(GLenum sourceRGB, GLenum destRGB) const
681 {
682 return sourceRGB == GL_CONSTANT_ALPHA || sourceRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
683 destRGB == GL_CONSTANT_ALPHA || destRGB == GL_ONE_MINUS_CONSTANT_ALPHA;
684 }
685
getRasterizerState() const686 const RasterizerState &State::getRasterizerState() const
687 {
688 return mRasterizer;
689 }
690
getDepthStencilState() const691 const DepthStencilState &State::getDepthStencilState() const
692 {
693 return mDepthStencil;
694 }
695
setColorClearValue(float red,float green,float blue,float alpha)696 void State::setColorClearValue(float red, float green, float blue, float alpha)
697 {
698 mColorClearValue.red = red;
699 mColorClearValue.green = green;
700 mColorClearValue.blue = blue;
701 mColorClearValue.alpha = alpha;
702 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
703 }
704
setDepthClearValue(float depth)705 void State::setDepthClearValue(float depth)
706 {
707 mDepthClearValue = depth;
708 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
709 }
710
setStencilClearValue(int stencil)711 void State::setStencilClearValue(int stencil)
712 {
713 mStencilClearValue = stencil;
714 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
715 }
716
setColorMask(bool red,bool green,bool blue,bool alpha)717 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
718 {
719 mBlendState.colorMaskRed = red;
720 mBlendState.colorMaskGreen = green;
721 mBlendState.colorMaskBlue = blue;
722 mBlendState.colorMaskAlpha = alpha;
723
724 mBlendStateExt.setColorMask(red, green, blue, alpha);
725 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
726 }
727
setColorMaskIndexed(bool red,bool green,bool blue,bool alpha,GLuint index)728 void State::setColorMaskIndexed(bool red, bool green, bool blue, bool alpha, GLuint index)
729 {
730 mBlendStateExt.setColorMaskIndexed(index, red, green, blue, alpha);
731 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
732 }
733
allActiveDrawBufferChannelsMasked() const734 bool State::allActiveDrawBufferChannelsMasked() const
735 {
736 // Compare current color mask with all-disabled color mask, while ignoring disabled draw
737 // buffers.
738 return (mBlendStateExt.compareColorMask(0) & mDrawFramebuffer->getDrawBufferMask()).none();
739 }
740
anyActiveDrawBufferChannelMasked() const741 bool State::anyActiveDrawBufferChannelMasked() const
742 {
743 // Compare current color mask with all-enabled color mask, while ignoring disabled draw
744 // buffers.
745 return (mBlendStateExt.compareColorMask(mBlendStateExt.mMaxColorMask) &
746 mDrawFramebuffer->getDrawBufferMask())
747 .any();
748 }
749
setDepthMask(bool mask)750 void State::setDepthMask(bool mask)
751 {
752 if (mDepthStencil.depthMask != mask)
753 {
754 mDepthStencil.depthMask = mask;
755 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
756 }
757 }
758
setRasterizerDiscard(bool enabled)759 void State::setRasterizerDiscard(bool enabled)
760 {
761 if (mRasterizer.rasterizerDiscard != enabled)
762 {
763 mRasterizer.rasterizerDiscard = enabled;
764 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
765 }
766 }
767
setCullFace(bool enabled)768 void State::setCullFace(bool enabled)
769 {
770 if (mRasterizer.cullFace != enabled)
771 {
772 mRasterizer.cullFace = enabled;
773 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
774 }
775 }
776
setCullMode(CullFaceMode mode)777 void State::setCullMode(CullFaceMode mode)
778 {
779 if (mRasterizer.cullMode != mode)
780 {
781 mRasterizer.cullMode = mode;
782 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
783 }
784 }
785
setFrontFace(GLenum front)786 void State::setFrontFace(GLenum front)
787 {
788 if (mRasterizer.frontFace != front)
789 {
790 mRasterizer.frontFace = front;
791 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
792 }
793 }
794
setDepthTest(bool enabled)795 void State::setDepthTest(bool enabled)
796 {
797 if (mDepthStencil.depthTest != enabled)
798 {
799 mDepthStencil.depthTest = enabled;
800 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
801 }
802 }
803
setDepthFunc(GLenum depthFunc)804 void State::setDepthFunc(GLenum depthFunc)
805 {
806 if (mDepthStencil.depthFunc != depthFunc)
807 {
808 mDepthStencil.depthFunc = depthFunc;
809 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
810 }
811 }
812
setDepthRange(float zNear,float zFar)813 void State::setDepthRange(float zNear, float zFar)
814 {
815 if (mNearZ != zNear || mFarZ != zFar)
816 {
817 mNearZ = zNear;
818 mFarZ = zFar;
819 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
820 }
821 }
822
setClipControl(GLenum origin,GLenum depth)823 void State::setClipControl(GLenum origin, GLenum depth)
824 {
825 bool updated = false;
826 if (mClipControlOrigin != origin)
827 {
828 mClipControlOrigin = origin;
829 updated = true;
830 }
831
832 if (mClipControlDepth != depth)
833 {
834 mClipControlDepth = depth;
835 updated = true;
836 }
837
838 if (updated)
839 {
840 mDirtyBits.set(DIRTY_BIT_EXTENDED);
841 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_CONTROL);
842 }
843 }
844
setBlend(bool enabled)845 void State::setBlend(bool enabled)
846 {
847 mBlendState.blend = enabled;
848
849 mBlendStateExt.setEnabled(enabled);
850 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
851 }
852
setBlendIndexed(bool enabled,GLuint index)853 void State::setBlendIndexed(bool enabled, GLuint index)
854 {
855 mBlendStateExt.setEnabledIndexed(index, enabled);
856 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
857 }
858
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)859 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
860 {
861
862 mBlendState.sourceBlendRGB = sourceRGB;
863 mBlendState.destBlendRGB = destRGB;
864 mBlendState.sourceBlendAlpha = sourceAlpha;
865 mBlendState.destBlendAlpha = destAlpha;
866
867 if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
868 {
869 if (hasConstantColor(sourceRGB, destRGB))
870 {
871 mBlendFuncConstantColorDrawBuffers.set();
872 }
873 else
874 {
875 mBlendFuncConstantColorDrawBuffers.reset();
876 }
877
878 if (hasConstantAlpha(sourceRGB, destRGB))
879 {
880 mBlendFuncConstantAlphaDrawBuffers.set();
881 }
882 else
883 {
884 mBlendFuncConstantAlphaDrawBuffers.reset();
885 }
886 }
887
888 mBlendStateExt.setFactors(sourceRGB, destRGB, sourceAlpha, destAlpha);
889 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
890 }
891
setBlendFactorsIndexed(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha,GLuint index)892 void State::setBlendFactorsIndexed(GLenum sourceRGB,
893 GLenum destRGB,
894 GLenum sourceAlpha,
895 GLenum destAlpha,
896 GLuint index)
897 {
898 if (mNoSimultaneousConstantColorAndAlphaBlendFunc)
899 {
900 mBlendFuncConstantColorDrawBuffers.set(index, hasConstantColor(sourceRGB, destRGB));
901 mBlendFuncConstantAlphaDrawBuffers.set(index, hasConstantAlpha(sourceRGB, destRGB));
902 }
903
904 mBlendStateExt.setFactorsIndexed(index, sourceRGB, destRGB, sourceAlpha, destAlpha);
905 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
906 }
907
setBlendColor(float red,float green,float blue,float alpha)908 void State::setBlendColor(float red, float green, float blue, float alpha)
909 {
910 // In ES2 without render-to-float extensions, BlendColor clamps to [0,1] on store.
911 // On ES3+, or with render-to-float exts enabled, it does not clamp on store.
912 const bool isES2 = mClientVersion.major == 2;
913 const bool hasFloatBlending =
914 mExtensions.colorBufferFloat || mExtensions.colorBufferHalfFloat ||
915 mExtensions.colorBufferFloatRGB || mExtensions.colorBufferFloatRGBA;
916 if (isES2 && !hasFloatBlending)
917 {
918 red = clamp01(red);
919 green = clamp01(green);
920 blue = clamp01(blue);
921 alpha = clamp01(alpha);
922 }
923
924 mBlendColor.red = red;
925 mBlendColor.green = green;
926 mBlendColor.blue = blue;
927 mBlendColor.alpha = alpha;
928 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
929 }
930
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)931 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
932 {
933 mBlendState.blendEquationRGB = rgbEquation;
934 mBlendState.blendEquationAlpha = alphaEquation;
935
936 mBlendStateExt.setEquations(rgbEquation, alphaEquation);
937 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
938 }
939
setBlendEquationIndexed(GLenum rgbEquation,GLenum alphaEquation,GLuint index)940 void State::setBlendEquationIndexed(GLenum rgbEquation, GLenum alphaEquation, GLuint index)
941 {
942 mBlendStateExt.setEquationsIndexed(index, rgbEquation, alphaEquation);
943 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
944 }
945
setStencilTest(bool enabled)946 void State::setStencilTest(bool enabled)
947 {
948 if (mDepthStencil.stencilTest != enabled)
949 {
950 mDepthStencil.stencilTest = enabled;
951 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
952 }
953 }
954
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)955 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
956 {
957 if (mDepthStencil.stencilFunc != stencilFunc || mStencilRef != stencilRef ||
958 mDepthStencil.stencilMask != stencilMask)
959 {
960 mDepthStencil.stencilFunc = stencilFunc;
961 mStencilRef = stencilRef;
962 mDepthStencil.stencilMask = stencilMask;
963 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
964 }
965 }
966
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)967 void State::setStencilBackParams(GLenum stencilBackFunc,
968 GLint stencilBackRef,
969 GLuint stencilBackMask)
970 {
971 if (mDepthStencil.stencilBackFunc != stencilBackFunc || mStencilBackRef != stencilBackRef ||
972 mDepthStencil.stencilBackMask != stencilBackMask)
973 {
974 mDepthStencil.stencilBackFunc = stencilBackFunc;
975 mStencilBackRef = stencilBackRef;
976 mDepthStencil.stencilBackMask = stencilBackMask;
977 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
978 }
979 }
980
setStencilWritemask(GLuint stencilWritemask)981 void State::setStencilWritemask(GLuint stencilWritemask)
982 {
983 if (mDepthStencil.stencilWritemask != stencilWritemask)
984 {
985 mDepthStencil.stencilWritemask = stencilWritemask;
986 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
987 }
988 }
989
setStencilBackWritemask(GLuint stencilBackWritemask)990 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
991 {
992 if (mDepthStencil.stencilBackWritemask != stencilBackWritemask)
993 {
994 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
995 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
996 }
997 }
998
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)999 void State::setStencilOperations(GLenum stencilFail,
1000 GLenum stencilPassDepthFail,
1001 GLenum stencilPassDepthPass)
1002 {
1003 if (mDepthStencil.stencilFail != stencilFail ||
1004 mDepthStencil.stencilPassDepthFail != stencilPassDepthFail ||
1005 mDepthStencil.stencilPassDepthPass != stencilPassDepthPass)
1006 {
1007 mDepthStencil.stencilFail = stencilFail;
1008 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
1009 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
1010 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
1011 }
1012 }
1013
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)1014 void State::setStencilBackOperations(GLenum stencilBackFail,
1015 GLenum stencilBackPassDepthFail,
1016 GLenum stencilBackPassDepthPass)
1017 {
1018 if (mDepthStencil.stencilBackFail != stencilBackFail ||
1019 mDepthStencil.stencilBackPassDepthFail != stencilBackPassDepthFail ||
1020 mDepthStencil.stencilBackPassDepthPass != stencilBackPassDepthPass)
1021 {
1022 mDepthStencil.stencilBackFail = stencilBackFail;
1023 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
1024 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
1025 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
1026 }
1027 }
1028
setPolygonOffsetFill(bool enabled)1029 void State::setPolygonOffsetFill(bool enabled)
1030 {
1031 if (mRasterizer.polygonOffsetFill != enabled)
1032 {
1033 mRasterizer.polygonOffsetFill = enabled;
1034 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1035 }
1036 }
1037
setPolygonOffsetParams(GLfloat factor,GLfloat units)1038 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
1039 {
1040 // An application can pass NaN values here, so handle this gracefully
1041 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
1042 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
1043 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
1044 }
1045
setSampleAlphaToCoverage(bool enabled)1046 void State::setSampleAlphaToCoverage(bool enabled)
1047 {
1048 if (mSampleAlphaToCoverage != enabled)
1049 {
1050 mSampleAlphaToCoverage = enabled;
1051 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1052 }
1053 }
1054
setSampleCoverage(bool enabled)1055 void State::setSampleCoverage(bool enabled)
1056 {
1057 if (mSampleCoverage != enabled)
1058 {
1059 mSampleCoverage = enabled;
1060 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1061 }
1062 }
1063
setSampleCoverageParams(GLclampf value,bool invert)1064 void State::setSampleCoverageParams(GLclampf value, bool invert)
1065 {
1066 mSampleCoverageValue = value;
1067 mSampleCoverageInvert = invert;
1068 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
1069 }
1070
setSampleMaskEnabled(bool enabled)1071 void State::setSampleMaskEnabled(bool enabled)
1072 {
1073 if (mSampleMask != enabled)
1074 {
1075 mSampleMask = enabled;
1076 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
1077 }
1078 }
1079
setSampleMaskParams(GLuint maskNumber,GLbitfield mask)1080 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
1081 {
1082 ASSERT(maskNumber < mMaxSampleMaskWords);
1083 mSampleMaskValues[maskNumber] = mask;
1084 // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
1085 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
1086 }
1087
setSampleAlphaToOne(bool enabled)1088 void State::setSampleAlphaToOne(bool enabled)
1089 {
1090 if (mSampleAlphaToOne != enabled)
1091 {
1092 mSampleAlphaToOne = enabled;
1093 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
1094 }
1095 }
1096
setMultisampling(bool enabled)1097 void State::setMultisampling(bool enabled)
1098 {
1099 if (mMultiSampling != enabled)
1100 {
1101 mMultiSampling = enabled;
1102 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
1103 }
1104 }
1105
setSampleShading(bool enabled)1106 void State::setSampleShading(bool enabled)
1107 {
1108 if (mIsSampleShadingEnabled != enabled)
1109 {
1110 mIsSampleShadingEnabled = enabled;
1111 mMinSampleShading = (enabled) ? 1.0f : mMinSampleShading;
1112 mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
1113 }
1114 }
1115
setMinSampleShading(float value)1116 void State::setMinSampleShading(float value)
1117 {
1118 value = gl::clamp01(value);
1119
1120 if (mMinSampleShading != value)
1121 {
1122 mMinSampleShading = value;
1123 mDirtyBits.set(DIRTY_BIT_SAMPLE_SHADING);
1124 }
1125 }
1126
setScissorTest(bool enabled)1127 void State::setScissorTest(bool enabled)
1128 {
1129 if (mScissorTest != enabled)
1130 {
1131 mScissorTest = enabled;
1132 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
1133 }
1134 }
1135
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)1136 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
1137 {
1138 // Skip if same scissor info
1139 if (mScissor.x != x || mScissor.y != y || mScissor.width != width || mScissor.height != height)
1140 {
1141 mScissor.x = x;
1142 mScissor.y = y;
1143 mScissor.width = width;
1144 mScissor.height = height;
1145 mDirtyBits.set(DIRTY_BIT_SCISSOR);
1146 }
1147 }
1148
setDither(bool enabled)1149 void State::setDither(bool enabled)
1150 {
1151 if (mRasterizer.dither != enabled)
1152 {
1153 mRasterizer.dither = enabled;
1154 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
1155 }
1156 }
1157
setPrimitiveRestart(bool enabled)1158 void State::setPrimitiveRestart(bool enabled)
1159 {
1160 if (mPrimitiveRestart != enabled)
1161 {
1162 mPrimitiveRestart = enabled;
1163 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1164 }
1165 }
1166
setClipDistanceEnable(int idx,bool enable)1167 void State::setClipDistanceEnable(int idx, bool enable)
1168 {
1169 if (enable)
1170 {
1171 mClipDistancesEnabled.set(idx);
1172 }
1173 else
1174 {
1175 mClipDistancesEnabled.reset(idx);
1176 }
1177
1178 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1179 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
1180 }
1181
setEnableFeature(GLenum feature,bool enabled)1182 void State::setEnableFeature(GLenum feature, bool enabled)
1183 {
1184 switch (feature)
1185 {
1186 case GL_MULTISAMPLE_EXT:
1187 setMultisampling(enabled);
1188 return;
1189 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1190 setSampleAlphaToOne(enabled);
1191 return;
1192 case GL_CULL_FACE:
1193 setCullFace(enabled);
1194 return;
1195 case GL_POLYGON_OFFSET_FILL:
1196 setPolygonOffsetFill(enabled);
1197 return;
1198 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1199 setSampleAlphaToCoverage(enabled);
1200 return;
1201 case GL_SAMPLE_COVERAGE:
1202 setSampleCoverage(enabled);
1203 return;
1204 case GL_SCISSOR_TEST:
1205 setScissorTest(enabled);
1206 return;
1207 case GL_STENCIL_TEST:
1208 setStencilTest(enabled);
1209 return;
1210 case GL_DEPTH_TEST:
1211 setDepthTest(enabled);
1212 return;
1213 case GL_BLEND:
1214 setBlend(enabled);
1215 return;
1216 case GL_DITHER:
1217 setDither(enabled);
1218 return;
1219 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1220 setPrimitiveRestart(enabled);
1221 return;
1222 case GL_RASTERIZER_DISCARD:
1223 setRasterizerDiscard(enabled);
1224 return;
1225 case GL_SAMPLE_MASK:
1226 setSampleMaskEnabled(enabled);
1227 return;
1228 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1229 mDebug.setOutputSynchronous(enabled);
1230 return;
1231 case GL_DEBUG_OUTPUT:
1232 mDebug.setOutputEnabled(enabled);
1233 return;
1234 case GL_FRAMEBUFFER_SRGB_EXT:
1235 setFramebufferSRGB(enabled);
1236 return;
1237 case GL_TEXTURE_RECTANGLE_ANGLE:
1238 mTextureRectangleEnabled = enabled;
1239 return;
1240 case GL_SAMPLE_SHADING:
1241 setSampleShading(enabled);
1242 return;
1243 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1244 case GL_CLIP_DISTANCE0_EXT:
1245 case GL_CLIP_DISTANCE1_EXT:
1246 case GL_CLIP_DISTANCE2_EXT:
1247 case GL_CLIP_DISTANCE3_EXT:
1248 case GL_CLIP_DISTANCE4_EXT:
1249 case GL_CLIP_DISTANCE5_EXT:
1250 case GL_CLIP_DISTANCE6_EXT:
1251 case GL_CLIP_DISTANCE7_EXT:
1252 // NOTE(hqle): These enums are conflicted with GLES1's enums, need
1253 // to do additional check here:
1254 if (mClientVersion.major >= 2)
1255 {
1256 setClipDistanceEnable(feature - GL_CLIP_DISTANCE0_EXT, enabled);
1257 return;
1258 }
1259 }
1260
1261 ASSERT(mClientVersion.major == 1);
1262
1263 // GLES1 emulation. Need to separate from main switch due to conflict enum between
1264 // GL_CLIP_DISTANCE0_EXT & GL_CLIP_PLANE0
1265 switch (feature)
1266 {
1267 case GL_ALPHA_TEST:
1268 mGLES1State.mAlphaTestEnabled = enabled;
1269 break;
1270 case GL_TEXTURE_2D:
1271 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::_2D, enabled);
1272 break;
1273 case GL_TEXTURE_CUBE_MAP:
1274 mGLES1State.mTexUnitEnables[mActiveSampler].set(TextureType::CubeMap, enabled);
1275 break;
1276 case GL_LIGHTING:
1277 mGLES1State.mLightingEnabled = enabled;
1278 break;
1279 case GL_LIGHT0:
1280 case GL_LIGHT1:
1281 case GL_LIGHT2:
1282 case GL_LIGHT3:
1283 case GL_LIGHT4:
1284 case GL_LIGHT5:
1285 case GL_LIGHT6:
1286 case GL_LIGHT7:
1287 mGLES1State.mLights[feature - GL_LIGHT0].enabled = enabled;
1288 break;
1289 case GL_NORMALIZE:
1290 mGLES1State.mNormalizeEnabled = enabled;
1291 break;
1292 case GL_RESCALE_NORMAL:
1293 mGLES1State.mRescaleNormalEnabled = enabled;
1294 break;
1295 case GL_COLOR_MATERIAL:
1296 mGLES1State.mColorMaterialEnabled = enabled;
1297 break;
1298 case GL_CLIP_PLANE0:
1299 case GL_CLIP_PLANE1:
1300 case GL_CLIP_PLANE2:
1301 case GL_CLIP_PLANE3:
1302 case GL_CLIP_PLANE4:
1303 case GL_CLIP_PLANE5:
1304 mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled = enabled;
1305 break;
1306 case GL_FOG:
1307 mGLES1State.mFogEnabled = enabled;
1308 break;
1309 case GL_POINT_SMOOTH:
1310 mGLES1State.mPointSmoothEnabled = enabled;
1311 break;
1312 case GL_LINE_SMOOTH:
1313 mGLES1State.mLineSmoothEnabled = enabled;
1314 break;
1315 case GL_POINT_SPRITE_OES:
1316 mGLES1State.mPointSpriteEnabled = enabled;
1317 break;
1318 case GL_COLOR_LOGIC_OP:
1319 mGLES1State.mLogicOpEnabled = enabled;
1320 break;
1321 default:
1322 UNREACHABLE();
1323 }
1324 }
1325
setEnableFeatureIndexed(GLenum feature,bool enabled,GLuint index)1326 void State::setEnableFeatureIndexed(GLenum feature, bool enabled, GLuint index)
1327 {
1328 switch (feature)
1329 {
1330 case GL_BLEND:
1331 setBlendIndexed(enabled, index);
1332 break;
1333 default:
1334 UNREACHABLE();
1335 }
1336 }
1337
getEnableFeature(GLenum feature) const1338 bool State::getEnableFeature(GLenum feature) const
1339 {
1340 switch (feature)
1341 {
1342 case GL_MULTISAMPLE_EXT:
1343 return isMultisamplingEnabled();
1344 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1345 return isSampleAlphaToOneEnabled();
1346 case GL_CULL_FACE:
1347 return isCullFaceEnabled();
1348 case GL_POLYGON_OFFSET_FILL:
1349 return isPolygonOffsetFillEnabled();
1350 case GL_SAMPLE_ALPHA_TO_COVERAGE:
1351 return isSampleAlphaToCoverageEnabled();
1352 case GL_SAMPLE_COVERAGE:
1353 return isSampleCoverageEnabled();
1354 case GL_SCISSOR_TEST:
1355 return isScissorTestEnabled();
1356 case GL_STENCIL_TEST:
1357 return isStencilTestEnabled();
1358 case GL_DEPTH_TEST:
1359 return isDepthTestEnabled();
1360 case GL_BLEND:
1361 return isBlendEnabled();
1362 case GL_DITHER:
1363 return isDitherEnabled();
1364 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1365 return isPrimitiveRestartEnabled();
1366 case GL_RASTERIZER_DISCARD:
1367 return isRasterizerDiscardEnabled();
1368 case GL_SAMPLE_MASK:
1369 return isSampleMaskEnabled();
1370 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1371 return mDebug.isOutputSynchronous();
1372 case GL_DEBUG_OUTPUT:
1373 return mDebug.isOutputEnabled();
1374 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1375 return isBindGeneratesResourceEnabled();
1376 case GL_CLIENT_ARRAYS_ANGLE:
1377 return areClientArraysEnabled();
1378 case GL_FRAMEBUFFER_SRGB_EXT:
1379 return getFramebufferSRGB();
1380 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1381 return mRobustResourceInit;
1382 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1383 return mProgramBinaryCacheEnabled;
1384 case GL_TEXTURE_RECTANGLE_ANGLE:
1385 return mTextureRectangleEnabled;
1386 case GL_SAMPLE_SHADING:
1387 return isSampleShadingEnabled();
1388 // GL_APPLE_clip_distance/GL_EXT_clip_cull_distance
1389 case GL_CLIP_DISTANCE0_EXT:
1390 case GL_CLIP_DISTANCE1_EXT:
1391 case GL_CLIP_DISTANCE2_EXT:
1392 case GL_CLIP_DISTANCE3_EXT:
1393 case GL_CLIP_DISTANCE4_EXT:
1394 case GL_CLIP_DISTANCE5_EXT:
1395 case GL_CLIP_DISTANCE6_EXT:
1396 case GL_CLIP_DISTANCE7_EXT:
1397 if (mClientVersion.major >= 2)
1398 {
1399 // If GLES version is 1, the GL_CLIP_DISTANCE0_EXT enum will be used as
1400 // GL_CLIP_PLANE0 instead.
1401 return mClipDistancesEnabled.test(feature - GL_CLIP_DISTANCE0_EXT);
1402 }
1403 break;
1404 }
1405
1406 ASSERT(mClientVersion.major == 1);
1407
1408 switch (feature)
1409 {
1410 // GLES1 emulation
1411 case GL_ALPHA_TEST:
1412 return mGLES1State.mAlphaTestEnabled;
1413 case GL_VERTEX_ARRAY:
1414 return mGLES1State.mVertexArrayEnabled;
1415 case GL_NORMAL_ARRAY:
1416 return mGLES1State.mNormalArrayEnabled;
1417 case GL_COLOR_ARRAY:
1418 return mGLES1State.mColorArrayEnabled;
1419 case GL_POINT_SIZE_ARRAY_OES:
1420 return mGLES1State.mPointSizeArrayEnabled;
1421 case GL_TEXTURE_COORD_ARRAY:
1422 return mGLES1State.mTexCoordArrayEnabled[mGLES1State.mClientActiveTexture];
1423 case GL_TEXTURE_2D:
1424 return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::_2D);
1425 case GL_TEXTURE_CUBE_MAP:
1426 return mGLES1State.isTextureTargetEnabled(getActiveSampler(), TextureType::CubeMap);
1427 case GL_LIGHTING:
1428 return mGLES1State.mLightingEnabled;
1429 case GL_LIGHT0:
1430 case GL_LIGHT1:
1431 case GL_LIGHT2:
1432 case GL_LIGHT3:
1433 case GL_LIGHT4:
1434 case GL_LIGHT5:
1435 case GL_LIGHT6:
1436 case GL_LIGHT7:
1437 return mGLES1State.mLights[feature - GL_LIGHT0].enabled;
1438 case GL_NORMALIZE:
1439 return mGLES1State.mNormalizeEnabled;
1440 case GL_RESCALE_NORMAL:
1441 return mGLES1State.mRescaleNormalEnabled;
1442 case GL_COLOR_MATERIAL:
1443 return mGLES1State.mColorMaterialEnabled;
1444 case GL_CLIP_PLANE0:
1445 case GL_CLIP_PLANE1:
1446 case GL_CLIP_PLANE2:
1447 case GL_CLIP_PLANE3:
1448 case GL_CLIP_PLANE4:
1449 case GL_CLIP_PLANE5:
1450 return mGLES1State.mClipPlanes[feature - GL_CLIP_PLANE0].enabled;
1451 case GL_FOG:
1452 return mGLES1State.mFogEnabled;
1453 case GL_POINT_SMOOTH:
1454 return mGLES1State.mPointSmoothEnabled;
1455 case GL_LINE_SMOOTH:
1456 return mGLES1State.mLineSmoothEnabled;
1457 case GL_POINT_SPRITE_OES:
1458 return mGLES1State.mPointSpriteEnabled;
1459 case GL_COLOR_LOGIC_OP:
1460 return mGLES1State.mLogicOpEnabled;
1461 default:
1462 UNREACHABLE();
1463 return false;
1464 }
1465 }
1466
getEnableFeatureIndexed(GLenum feature,GLuint index) const1467 bool State::getEnableFeatureIndexed(GLenum feature, GLuint index) const
1468 {
1469 switch (feature)
1470 {
1471 case GL_BLEND:
1472 return isBlendEnabledIndexed(index);
1473 default:
1474 UNREACHABLE();
1475 return false;
1476 }
1477 }
1478
setLineWidth(GLfloat width)1479 void State::setLineWidth(GLfloat width)
1480 {
1481 mLineWidth = width;
1482 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
1483 }
1484
setGenerateMipmapHint(GLenum hint)1485 void State::setGenerateMipmapHint(GLenum hint)
1486 {
1487 mGenerateMipmapHint = hint;
1488 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1489 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT);
1490 }
1491
getGenerateMipmapHint() const1492 GLenum State::getGenerateMipmapHint() const
1493 {
1494 return mGenerateMipmapHint;
1495 }
1496
setTextureFilteringHint(GLenum hint)1497 void State::setTextureFilteringHint(GLenum hint)
1498 {
1499 mTextureFilteringHint = hint;
1500 // Note: we don't add a dirty bit for this flag as it's not expected to be toggled at
1501 // runtime.
1502 }
1503
getTextureFilteringHint() const1504 GLenum State::getTextureFilteringHint() const
1505 {
1506 return mTextureFilteringHint;
1507 }
1508
setFragmentShaderDerivativeHint(GLenum hint)1509 void State::setFragmentShaderDerivativeHint(GLenum hint)
1510 {
1511 mFragmentShaderDerivativeHint = hint;
1512 mDirtyBits.set(DIRTY_BIT_EXTENDED);
1513 mExtendedDirtyBits.set(EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT);
1514 // TODO: Propagate the hint to shader translator so we can write
1515 // ddx, ddx_coarse, or ddx_fine depending on the hint.
1516 // Ignore for now. It is valid for implementations to ignore hint.
1517 }
1518
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)1519 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
1520 {
1521 // Skip if same viewport info
1522 if (mViewport.x != x || mViewport.y != y || mViewport.width != width ||
1523 mViewport.height != height)
1524 {
1525 mViewport.x = x;
1526 mViewport.y = y;
1527 mViewport.width = width;
1528 mViewport.height = height;
1529 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
1530 }
1531 }
1532
setActiveSampler(unsigned int active)1533 void State::setActiveSampler(unsigned int active)
1534 {
1535 mActiveSampler = active;
1536 }
1537
setSamplerTexture(const Context * context,TextureType type,Texture * texture)1538 void State::setSamplerTexture(const Context *context, TextureType type, Texture *texture)
1539 {
1540 if (mExecutable && mExecutable->getActiveSamplersMask()[mActiveSampler] &&
1541 IsTextureCompatibleWithSampler(type, mExecutable->getActiveSamplerTypes()[mActiveSampler]))
1542 {
1543 updateTextureBinding(context, mActiveSampler, texture);
1544 }
1545
1546 mSamplerTextures[type][mActiveSampler].set(context, texture);
1547
1548 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1549 }
1550
getTargetTexture(TextureType type) const1551 Texture *State::getTargetTexture(TextureType type) const
1552 {
1553 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), type);
1554 }
1555
getSamplerTextureId(unsigned int sampler,TextureType type) const1556 TextureID State::getSamplerTextureId(unsigned int sampler, TextureType type) const
1557 {
1558 ASSERT(sampler < mSamplerTextures[type].size());
1559 return mSamplerTextures[type][sampler].id();
1560 }
1561
detachTexture(const Context * context,const TextureMap & zeroTextures,TextureID texture)1562 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, TextureID texture)
1563 {
1564 // Textures have a detach method on State rather than a simple
1565 // removeBinding, because the zero/null texture objects are managed
1566 // separately, and don't have to go through the Context's maps or
1567 // the ResourceManager.
1568
1569 // [OpenGL ES 2.0.24] section 3.8 page 84:
1570 // If a texture object is deleted, it is as if all texture units which are bound to that texture
1571 // object are rebound to texture object zero
1572
1573 for (TextureType type : angle::AllEnums<TextureType>())
1574 {
1575 TextureBindingVector &textureVector = mSamplerTextures[type];
1576
1577 for (size_t bindingIndex = 0; bindingIndex < textureVector.size(); ++bindingIndex)
1578 {
1579 BindingPointer<Texture> &binding = textureVector[bindingIndex];
1580 if (binding.id() == texture)
1581 {
1582 // Zero textures are the "default" textures instead of NULL
1583 Texture *zeroTexture = zeroTextures[type].get();
1584 ASSERT(zeroTexture != nullptr);
1585 if (mCompleteTextureBindings[bindingIndex].getSubject() == binding.get())
1586 {
1587 updateTextureBinding(context, bindingIndex, zeroTexture);
1588 }
1589 binding.set(context, zeroTexture);
1590 }
1591 }
1592 }
1593
1594 for (auto &bindingImageUnit : mImageUnits)
1595 {
1596 if (bindingImageUnit.texture.id() == texture)
1597 {
1598 bindingImageUnit.texture.set(context, nullptr);
1599 bindingImageUnit.level = 0;
1600 bindingImageUnit.layered = false;
1601 bindingImageUnit.layer = 0;
1602 bindingImageUnit.access = GL_READ_ONLY;
1603 bindingImageUnit.format = GL_R32UI;
1604 }
1605 }
1606
1607 // [OpenGL ES 2.0.24] section 4.4 page 112:
1608 // If a texture object is deleted while its image is attached to the currently bound
1609 // framebuffer, then it is as if Texture2DAttachment had been called, with a texture of 0, for
1610 // each attachment point to which this image was attached in the currently bound framebuffer.
1611
1612 if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
1613 {
1614 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1615 }
1616
1617 if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
1618 {
1619 setDrawFramebufferDirty();
1620 }
1621 }
1622
initializeZeroTextures(const Context * context,const TextureMap & zeroTextures)1623 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
1624 {
1625 for (TextureType type : angle::AllEnums<TextureType>())
1626 {
1627 for (size_t textureUnit = 0; textureUnit < mSamplerTextures[type].size(); ++textureUnit)
1628 {
1629 mSamplerTextures[type][textureUnit].set(context, zeroTextures[type].get());
1630 }
1631 }
1632 }
1633
invalidateTextureBindings(TextureType type)1634 void State::invalidateTextureBindings(TextureType type)
1635 {
1636 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
1637 }
1638
setSamplerBinding(const Context * context,GLuint textureUnit,Sampler * sampler)1639 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
1640 {
1641 if (mSamplers[textureUnit].get() == sampler)
1642 {
1643 return;
1644 }
1645
1646 mSamplers[textureUnit].set(context, sampler);
1647 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
1648 // This is overly conservative as it assumes the sampler has never been bound.
1649 setSamplerDirty(textureUnit);
1650 onActiveTextureChange(context, textureUnit);
1651 }
1652
detachSampler(const Context * context,SamplerID sampler)1653 void State::detachSampler(const Context *context, SamplerID sampler)
1654 {
1655 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
1656 // If a sampler object that is currently bound to one or more texture units is
1657 // deleted, it is as though BindSampler is called once for each texture unit to
1658 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
1659 for (size_t i = 0; i < mSamplers.size(); i++)
1660 {
1661 if (mSamplers[i].id() == sampler)
1662 {
1663 setSamplerBinding(context, static_cast<GLuint>(i), nullptr);
1664 }
1665 }
1666 }
1667
setRenderbufferBinding(const Context * context,Renderbuffer * renderbuffer)1668 void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
1669 {
1670 mRenderbuffer.set(context, renderbuffer);
1671 mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
1672 }
1673
detachRenderbuffer(const Context * context,RenderbufferID renderbuffer)1674 void State::detachRenderbuffer(const Context *context, RenderbufferID renderbuffer)
1675 {
1676 // [OpenGL ES 2.0.24] section 4.4 page 109:
1677 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though
1678 // BindRenderbuffer had been executed with the target RENDERBUFFER and name of zero.
1679
1680 if (mRenderbuffer.id() == renderbuffer)
1681 {
1682 setRenderbufferBinding(context, nullptr);
1683 }
1684
1685 // [OpenGL ES 2.0.24] section 4.4 page 111:
1686 // If a renderbuffer object is deleted while its image is attached to the currently bound
1687 // framebuffer, then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of
1688 // 0, for each attachment point to which this image was attached in the currently bound
1689 // framebuffer.
1690
1691 Framebuffer *readFramebuffer = mReadFramebuffer;
1692 Framebuffer *drawFramebuffer = mDrawFramebuffer;
1693
1694 if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
1695 {
1696 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1697 }
1698
1699 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
1700 {
1701 if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
1702 {
1703 setDrawFramebufferDirty();
1704 }
1705 }
1706 }
1707
setReadFramebufferBinding(Framebuffer * framebuffer)1708 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
1709 {
1710 if (mReadFramebuffer == framebuffer)
1711 return;
1712
1713 mReadFramebuffer = framebuffer;
1714 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
1715
1716 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
1717 {
1718 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1719 }
1720 }
1721
setDrawFramebufferBinding(Framebuffer * framebuffer)1722 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
1723 {
1724 if (mDrawFramebuffer == framebuffer)
1725 return;
1726
1727 mDrawFramebuffer = framebuffer;
1728 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1729
1730 if (mDrawFramebuffer)
1731 {
1732 mDrawFramebuffer->setWriteControlMode(getFramebufferSRGB() ? SrgbWriteControlMode::Default
1733 : SrgbWriteControlMode::Linear);
1734
1735 if (mDrawFramebuffer->hasAnyDirtyBit())
1736 {
1737 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1738 }
1739
1740 if (mRobustResourceInit && mDrawFramebuffer->hasResourceThatNeedsInit())
1741 {
1742 mDirtyObjects.set(DIRTY_OBJECT_DRAW_ATTACHMENTS);
1743 }
1744 }
1745 }
1746
getTargetFramebuffer(GLenum target) const1747 Framebuffer *State::getTargetFramebuffer(GLenum target) const
1748 {
1749 switch (target)
1750 {
1751 case GL_READ_FRAMEBUFFER_ANGLE:
1752 return mReadFramebuffer;
1753 case GL_DRAW_FRAMEBUFFER_ANGLE:
1754 case GL_FRAMEBUFFER:
1755 return mDrawFramebuffer;
1756 default:
1757 UNREACHABLE();
1758 return nullptr;
1759 }
1760 }
1761
getDefaultFramebuffer() const1762 Framebuffer *State::getDefaultFramebuffer() const
1763 {
1764 return mFramebufferManager->getDefaultFramebuffer();
1765 }
1766
removeReadFramebufferBinding(FramebufferID framebuffer)1767 bool State::removeReadFramebufferBinding(FramebufferID framebuffer)
1768 {
1769 if (mReadFramebuffer != nullptr && mReadFramebuffer->id() == framebuffer)
1770 {
1771 setReadFramebufferBinding(nullptr);
1772 return true;
1773 }
1774
1775 return false;
1776 }
1777
removeDrawFramebufferBinding(FramebufferID framebuffer)1778 bool State::removeDrawFramebufferBinding(FramebufferID framebuffer)
1779 {
1780 if (mReadFramebuffer != nullptr && mDrawFramebuffer->id() == framebuffer)
1781 {
1782 setDrawFramebufferBinding(nullptr);
1783 return true;
1784 }
1785
1786 return false;
1787 }
1788
setVertexArrayBinding(const Context * context,VertexArray * vertexArray)1789 void State::setVertexArrayBinding(const Context *context, VertexArray *vertexArray)
1790 {
1791 if (mVertexArray == vertexArray)
1792 return;
1793 if (mVertexArray)
1794 mVertexArray->onBindingChanged(context, -1);
1795 mVertexArray = vertexArray;
1796 if (vertexArray)
1797 vertexArray->onBindingChanged(context, 1);
1798 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1799
1800 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1801 {
1802 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1803 }
1804 }
1805
removeVertexArrayBinding(const Context * context,VertexArrayID vertexArray)1806 bool State::removeVertexArrayBinding(const Context *context, VertexArrayID vertexArray)
1807 {
1808 if (mVertexArray && mVertexArray->id().value == vertexArray.value)
1809 {
1810 mVertexArray->onBindingChanged(context, -1);
1811 mVertexArray = nullptr;
1812 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1813 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1814 return true;
1815 }
1816
1817 return false;
1818 }
1819
getVertexArrayId() const1820 VertexArrayID State::getVertexArrayId() const
1821 {
1822 ASSERT(mVertexArray != nullptr);
1823 return mVertexArray->id();
1824 }
1825
bindVertexBuffer(const Context * context,GLuint bindingIndex,Buffer * boundBuffer,GLintptr offset,GLsizei stride)1826 void State::bindVertexBuffer(const Context *context,
1827 GLuint bindingIndex,
1828 Buffer *boundBuffer,
1829 GLintptr offset,
1830 GLsizei stride)
1831 {
1832 getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
1833 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1834 }
1835
setVertexAttribFormat(GLuint attribIndex,GLint size,VertexAttribType type,bool normalized,bool pureInteger,GLuint relativeOffset)1836 void State::setVertexAttribFormat(GLuint attribIndex,
1837 GLint size,
1838 VertexAttribType type,
1839 bool normalized,
1840 bool pureInteger,
1841 GLuint relativeOffset)
1842 {
1843 getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1844 relativeOffset);
1845 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1846 }
1847
setVertexBindingDivisor(GLuint bindingIndex,GLuint divisor)1848 void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1849 {
1850 getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
1851 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1852 }
1853
setProgram(const Context * context,Program * newProgram)1854 angle::Result State::setProgram(const Context *context, Program *newProgram)
1855 {
1856 if (newProgram && !newProgram->isLinked())
1857 {
1858 // Protect against applications that disable validation and try to use a program that was
1859 // not successfully linked.
1860 WARN() << "Attempted to use a program that was not successfully linked";
1861 return angle::Result::Continue;
1862 }
1863
1864 if (mProgram != newProgram)
1865 {
1866 if (mProgram)
1867 {
1868 unsetActiveTextures(mExecutable->getActiveSamplersMask());
1869 mProgram->release(context);
1870 }
1871
1872 mProgram = newProgram;
1873 mExecutable = nullptr;
1874
1875 if (mProgram)
1876 {
1877 mExecutable = &mProgram->getExecutable();
1878 newProgram->addRef();
1879 ANGLE_TRY(onProgramExecutableChange(context, newProgram));
1880 }
1881 else if (mProgramPipeline.get())
1882 {
1883 mExecutable = &mProgramPipeline->getExecutable();
1884 }
1885
1886 // Note that rendering is undefined if glUseProgram(0) is called. But ANGLE will generate
1887 // an error if the app tries to draw in this case.
1888
1889 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
1890 }
1891
1892 return angle::Result::Continue;
1893 }
1894
setTransformFeedbackBinding(const Context * context,TransformFeedback * transformFeedback)1895 void State::setTransformFeedbackBinding(const Context *context,
1896 TransformFeedback *transformFeedback)
1897 {
1898 if (transformFeedback == mTransformFeedback.get())
1899 return;
1900 if (mTransformFeedback.get())
1901 mTransformFeedback->onBindingChanged(context, false);
1902 mTransformFeedback.set(context, transformFeedback);
1903 if (mTransformFeedback.get())
1904 mTransformFeedback->onBindingChanged(context, true);
1905 mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
1906 }
1907
removeTransformFeedbackBinding(const Context * context,TransformFeedbackID transformFeedback)1908 bool State::removeTransformFeedbackBinding(const Context *context,
1909 TransformFeedbackID transformFeedback)
1910 {
1911 if (mTransformFeedback.id() == transformFeedback)
1912 {
1913 if (mTransformFeedback.get())
1914 mTransformFeedback->onBindingChanged(context, false);
1915 mTransformFeedback.set(context, nullptr);
1916 return true;
1917 }
1918
1919 return false;
1920 }
1921
useProgramStages(const Context * context,ProgramPipeline * programPipeline,GLbitfield stages,Program * shaderProgram)1922 angle::Result State::useProgramStages(const Context *context,
1923 ProgramPipeline *programPipeline,
1924 GLbitfield stages,
1925 Program *shaderProgram)
1926 {
1927 programPipeline->useProgramStages(context, stages, shaderProgram);
1928 ANGLE_TRY(onProgramPipelineExecutableChange(context, programPipeline));
1929
1930 return angle::Result::Continue;
1931 }
1932
setProgramPipelineBinding(const Context * context,ProgramPipeline * pipeline)1933 angle::Result State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
1934 {
1935 if (mProgramPipeline.get() == pipeline)
1936 {
1937 return angle::Result::Continue;
1938 }
1939
1940 if (mProgramPipeline.get())
1941 {
1942 unsetActiveTextures(mProgramPipeline->getExecutable().getActiveSamplersMask());
1943 }
1944
1945 mProgramPipeline.set(context, pipeline);
1946 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
1947
1948 // A bound Program always overrides the ProgramPipeline, so only update the
1949 // current ProgramExecutable if there isn't currently a Program bound.
1950 if (!mProgram)
1951 {
1952 if (mProgramPipeline.get())
1953 {
1954 mExecutable = &mProgramPipeline->getExecutable();
1955 }
1956 else
1957 {
1958 mExecutable = nullptr;
1959 }
1960 }
1961
1962 if (mProgramPipeline.get())
1963 {
1964 ANGLE_TRY(onProgramPipelineExecutableChange(context, mProgramPipeline.get()));
1965 }
1966
1967 return angle::Result::Continue;
1968 }
1969
detachProgramPipeline(const Context * context,ProgramPipelineID pipeline)1970 void State::detachProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1971 {
1972 mProgramPipeline.set(context, nullptr);
1973
1974 // A bound Program always overrides the ProgramPipeline, so only update the
1975 // current ProgramExecutable if there isn't currently a Program bound.
1976 if (!mProgram)
1977 {
1978 mExecutable = nullptr;
1979 }
1980 }
1981
isQueryActive(QueryType type) const1982 bool State::isQueryActive(QueryType type) const
1983 {
1984 const Query *query = mActiveQueries[type].get();
1985 if (query != nullptr)
1986 {
1987 return true;
1988 }
1989
1990 QueryType alternativeType;
1991 if (GetAlternativeQueryType(type, &alternativeType))
1992 {
1993 query = mActiveQueries[alternativeType].get();
1994 return query != nullptr;
1995 }
1996
1997 return false;
1998 }
1999
isQueryActive(Query * query) const2000 bool State::isQueryActive(Query *query) const
2001 {
2002 for (auto &queryPointer : mActiveQueries)
2003 {
2004 if (queryPointer.get() == query)
2005 {
2006 return true;
2007 }
2008 }
2009
2010 return false;
2011 }
2012
setActiveQuery(const Context * context,QueryType type,Query * query)2013 void State::setActiveQuery(const Context *context, QueryType type, Query *query)
2014 {
2015 mActiveQueries[type].set(context, query);
2016 }
2017
getActiveQueryId(QueryType type) const2018 QueryID State::getActiveQueryId(QueryType type) const
2019 {
2020 const Query *query = getActiveQuery(type);
2021 if (query)
2022 {
2023 return query->id();
2024 }
2025 return {0};
2026 }
2027
getActiveQuery(QueryType type) const2028 Query *State::getActiveQuery(QueryType type) const
2029 {
2030 return mActiveQueries[type].get();
2031 }
2032
setIndexedBufferBinding(const Context * context,BufferBinding target,GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)2033 angle::Result State::setIndexedBufferBinding(const Context *context,
2034 BufferBinding target,
2035 GLuint index,
2036 Buffer *buffer,
2037 GLintptr offset,
2038 GLsizeiptr size)
2039 {
2040 setBufferBinding(context, target, buffer);
2041
2042 switch (target)
2043 {
2044 case BufferBinding::TransformFeedback:
2045 ANGLE_TRY(mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size));
2046 setBufferBinding(context, target, buffer);
2047 break;
2048 case BufferBinding::Uniform:
2049 mBoundUniformBuffersMask.set(index, buffer != nullptr);
2050 UpdateIndexedBufferBinding(context, &mUniformBuffers[index], buffer, target, offset,
2051 size);
2052 break;
2053 case BufferBinding::AtomicCounter:
2054 mBoundAtomicCounterBuffersMask.set(index, buffer != nullptr);
2055 UpdateIndexedBufferBinding(context, &mAtomicCounterBuffers[index], buffer, target,
2056 offset, size);
2057 break;
2058 case BufferBinding::ShaderStorage:
2059 mBoundShaderStorageBuffersMask.set(index, buffer != nullptr);
2060 UpdateIndexedBufferBinding(context, &mShaderStorageBuffers[index], buffer, target,
2061 offset, size);
2062 break;
2063 default:
2064 UNREACHABLE();
2065 break;
2066 }
2067
2068 return angle::Result::Continue;
2069 }
2070
getIndexedUniformBuffer(size_t index) const2071 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
2072 {
2073 ASSERT(index < mUniformBuffers.size());
2074 return mUniformBuffers[index];
2075 }
2076
getIndexedAtomicCounterBuffer(size_t index) const2077 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
2078 {
2079 ASSERT(index < mAtomicCounterBuffers.size());
2080 return mAtomicCounterBuffers[index];
2081 }
2082
getIndexedShaderStorageBuffer(size_t index) const2083 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
2084 {
2085 ASSERT(index < mShaderStorageBuffers.size());
2086 return mShaderStorageBuffers[index];
2087 }
2088
detachBuffer(Context * context,const Buffer * buffer)2089 angle::Result State::detachBuffer(Context *context, const Buffer *buffer)
2090 {
2091 if (!buffer->isBound())
2092 {
2093 return angle::Result::Continue;
2094 }
2095 BufferID bufferID = buffer->id();
2096 for (gl::BufferBinding target : angle::AllEnums<BufferBinding>())
2097 {
2098 if (mBoundBuffers[target].id() == bufferID)
2099 {
2100 UpdateBufferBinding(context, &mBoundBuffers[target], nullptr, target);
2101 }
2102 }
2103
2104 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
2105 if (curTransformFeedback)
2106 {
2107 ANGLE_TRY(curTransformFeedback->detachBuffer(context, bufferID));
2108 }
2109
2110 if (getVertexArray()->detachBuffer(context, bufferID))
2111 {
2112 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2113 context->getStateCache().onVertexArrayStateChange(context);
2114 }
2115
2116 for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
2117 {
2118 OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
2119
2120 if (binding.id() == bufferID)
2121 {
2122 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
2123 mBoundUniformBuffersMask.reset(uniformBufferIndex);
2124 }
2125 }
2126
2127 for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
2128 {
2129 OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
2130
2131 if (binding.id() == bufferID)
2132 {
2133 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
2134 0);
2135 mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
2136 }
2137 }
2138
2139 for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
2140 {
2141 OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
2142
2143 if (binding.id() == bufferID)
2144 {
2145 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
2146 0);
2147 mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
2148 }
2149 }
2150
2151 return angle::Result::Continue;
2152 }
2153
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)2154 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
2155 {
2156 getVertexArray()->enableAttribute(attribNum, enabled);
2157 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2158 }
2159
setVertexAttribf(GLuint index,const GLfloat values[4])2160 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
2161 {
2162 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2163 mVertexAttribCurrentValues[index].setFloatValues(values);
2164 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2165 mDirtyCurrentValues.set(index);
2166 SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
2167 }
2168
setVertexAttribu(GLuint index,const GLuint values[4])2169 void State::setVertexAttribu(GLuint index, const GLuint values[4])
2170 {
2171 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2172 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
2173 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2174 mDirtyCurrentValues.set(index);
2175 SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
2176 }
2177
setVertexAttribi(GLuint index,const GLint values[4])2178 void State::setVertexAttribi(GLuint index, const GLint values[4])
2179 {
2180 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2181 mVertexAttribCurrentValues[index].setIntValues(values);
2182 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2183 mDirtyCurrentValues.set(index);
2184 SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
2185 }
2186
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)2187 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
2188 {
2189 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
2190 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2191 }
2192
getVertexAttribPointer(unsigned int attribNum) const2193 const void *State::getVertexAttribPointer(unsigned int attribNum) const
2194 {
2195 return getVertexArray()->getVertexAttribute(attribNum).pointer;
2196 }
2197
setPackAlignment(GLint alignment)2198 void State::setPackAlignment(GLint alignment)
2199 {
2200 mPack.alignment = alignment;
2201 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2202 }
2203
setPackReverseRowOrder(bool reverseRowOrder)2204 void State::setPackReverseRowOrder(bool reverseRowOrder)
2205 {
2206 mPack.reverseRowOrder = reverseRowOrder;
2207 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2208 }
2209
setPackRowLength(GLint rowLength)2210 void State::setPackRowLength(GLint rowLength)
2211 {
2212 mPack.rowLength = rowLength;
2213 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2214 }
2215
setPackSkipRows(GLint skipRows)2216 void State::setPackSkipRows(GLint skipRows)
2217 {
2218 mPack.skipRows = skipRows;
2219 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2220 }
2221
setPackSkipPixels(GLint skipPixels)2222 void State::setPackSkipPixels(GLint skipPixels)
2223 {
2224 mPack.skipPixels = skipPixels;
2225 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2226 }
2227
setUnpackAlignment(GLint alignment)2228 void State::setUnpackAlignment(GLint alignment)
2229 {
2230 mUnpack.alignment = alignment;
2231 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2232 }
2233
setUnpackRowLength(GLint rowLength)2234 void State::setUnpackRowLength(GLint rowLength)
2235 {
2236 mUnpack.rowLength = rowLength;
2237 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2238 }
2239
setUnpackImageHeight(GLint imageHeight)2240 void State::setUnpackImageHeight(GLint imageHeight)
2241 {
2242 mUnpack.imageHeight = imageHeight;
2243 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2244 }
2245
setUnpackSkipImages(GLint skipImages)2246 void State::setUnpackSkipImages(GLint skipImages)
2247 {
2248 mUnpack.skipImages = skipImages;
2249 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2250 }
2251
setUnpackSkipRows(GLint skipRows)2252 void State::setUnpackSkipRows(GLint skipRows)
2253 {
2254 mUnpack.skipRows = skipRows;
2255 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2256 }
2257
setUnpackSkipPixels(GLint skipPixels)2258 void State::setUnpackSkipPixels(GLint skipPixels)
2259 {
2260 mUnpack.skipPixels = skipPixels;
2261 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2262 }
2263
setCoverageModulation(GLenum components)2264 void State::setCoverageModulation(GLenum components)
2265 {
2266 if (mCoverageModulation != components)
2267 {
2268 mCoverageModulation = components;
2269 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
2270 }
2271 }
2272
setFramebufferSRGB(bool sRGB)2273 void State::setFramebufferSRGB(bool sRGB)
2274 {
2275 if (mFramebufferSRGB != sRGB)
2276 {
2277 mFramebufferSRGB = sRGB;
2278 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2279 setDrawFramebufferDirty();
2280 }
2281 }
2282
setMaxShaderCompilerThreads(GLuint count)2283 void State::setMaxShaderCompilerThreads(GLuint count)
2284 {
2285 mMaxShaderCompilerThreads = count;
2286 }
2287
setPatchVertices(GLuint value)2288 void State::setPatchVertices(GLuint value)
2289 {
2290 if (mPatchVertices != value)
2291 {
2292 mPatchVertices = value;
2293 mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
2294 }
2295 }
2296
getBooleanv(GLenum pname,GLboolean * params) const2297 void State::getBooleanv(GLenum pname, GLboolean *params) const
2298 {
2299 switch (pname)
2300 {
2301 case GL_SAMPLE_COVERAGE_INVERT:
2302 *params = mSampleCoverageInvert;
2303 break;
2304 case GL_DEPTH_WRITEMASK:
2305 *params = mDepthStencil.depthMask;
2306 break;
2307 case GL_COLOR_WRITEMASK:
2308 {
2309 // non-indexed get returns the state of draw buffer zero
2310 bool r, g, b, a;
2311 mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2312 params[0] = r;
2313 params[1] = g;
2314 params[2] = b;
2315 params[3] = a;
2316 break;
2317 }
2318 case GL_CULL_FACE:
2319 *params = mRasterizer.cullFace;
2320 break;
2321 case GL_POLYGON_OFFSET_FILL:
2322 *params = mRasterizer.polygonOffsetFill;
2323 break;
2324 case GL_SAMPLE_ALPHA_TO_COVERAGE:
2325 *params = mSampleAlphaToCoverage;
2326 break;
2327 case GL_SAMPLE_COVERAGE:
2328 *params = mSampleCoverage;
2329 break;
2330 case GL_SAMPLE_MASK:
2331 *params = mSampleMask;
2332 break;
2333 case GL_SCISSOR_TEST:
2334 *params = mScissorTest;
2335 break;
2336 case GL_STENCIL_TEST:
2337 *params = mDepthStencil.stencilTest;
2338 break;
2339 case GL_DEPTH_TEST:
2340 *params = mDepthStencil.depthTest;
2341 break;
2342 case GL_BLEND:
2343 // non-indexed get returns the state of draw buffer zero
2344 *params = mBlendStateExt.mEnabledMask.test(0);
2345 break;
2346 case GL_DITHER:
2347 *params = mRasterizer.dither;
2348 break;
2349 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2350 *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
2351 break;
2352 case GL_TRANSFORM_FEEDBACK_PAUSED:
2353 *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
2354 break;
2355 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2356 *params = mPrimitiveRestart;
2357 break;
2358 case GL_RASTERIZER_DISCARD:
2359 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
2360 break;
2361 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
2362 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
2363 break;
2364 case GL_DEBUG_OUTPUT:
2365 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
2366 break;
2367 case GL_MULTISAMPLE_EXT:
2368 *params = mMultiSampling;
2369 break;
2370 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2371 *params = mSampleAlphaToOne;
2372 break;
2373 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
2374 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
2375 break;
2376 case GL_CLIENT_ARRAYS_ANGLE:
2377 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
2378 break;
2379 case GL_FRAMEBUFFER_SRGB_EXT:
2380 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
2381 break;
2382 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2383 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
2384 break;
2385 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
2386 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
2387 break;
2388 case GL_TEXTURE_RECTANGLE_ANGLE:
2389 *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
2390 break;
2391 case GL_LIGHT_MODEL_TWO_SIDE:
2392 *params = IsLightModelTwoSided(&mGLES1State);
2393 break;
2394 case GL_SAMPLE_SHADING:
2395 *params = mIsSampleShadingEnabled;
2396 break;
2397 case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
2398 *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
2399 break;
2400 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2401 // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
2402 // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
2403 // GL_EXT_clip_control
2404 case GL_CLIP_ORIGIN_EXT:
2405 *params = GL_TRUE;
2406 break;
2407 case GL_CLIP_DEPTH_MODE_EXT:
2408 *params = GL_TRUE;
2409 break;
2410 default:
2411 UNREACHABLE();
2412 break;
2413 }
2414 }
2415
getFloatv(GLenum pname,GLfloat * params) const2416 void State::getFloatv(GLenum pname, GLfloat *params) const
2417 {
2418 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
2419 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2420 // GetIntegerv as its native query function. As it would require conversion in any
2421 // case, this should make no difference to the calling application.
2422 switch (pname)
2423 {
2424 case GL_LINE_WIDTH:
2425 *params = mLineWidth;
2426 break;
2427 case GL_SAMPLE_COVERAGE_VALUE:
2428 *params = mSampleCoverageValue;
2429 break;
2430 case GL_DEPTH_CLEAR_VALUE:
2431 *params = mDepthClearValue;
2432 break;
2433 case GL_POLYGON_OFFSET_FACTOR:
2434 *params = mRasterizer.polygonOffsetFactor;
2435 break;
2436 case GL_POLYGON_OFFSET_UNITS:
2437 *params = mRasterizer.polygonOffsetUnits;
2438 break;
2439 case GL_DEPTH_RANGE:
2440 params[0] = mNearZ;
2441 params[1] = mFarZ;
2442 break;
2443 case GL_COLOR_CLEAR_VALUE:
2444 params[0] = mColorClearValue.red;
2445 params[1] = mColorClearValue.green;
2446 params[2] = mColorClearValue.blue;
2447 params[3] = mColorClearValue.alpha;
2448 break;
2449 case GL_BLEND_COLOR:
2450 params[0] = mBlendColor.red;
2451 params[1] = mBlendColor.green;
2452 params[2] = mBlendColor.blue;
2453 params[3] = mBlendColor.alpha;
2454 break;
2455 case GL_MULTISAMPLE_EXT:
2456 *params = static_cast<GLfloat>(mMultiSampling);
2457 break;
2458 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2459 *params = static_cast<GLfloat>(mSampleAlphaToOne);
2460 break;
2461 case GL_COVERAGE_MODULATION_CHROMIUM:
2462 params[0] = static_cast<GLfloat>(mCoverageModulation);
2463 break;
2464 case GL_ALPHA_TEST_REF:
2465 *params = mGLES1State.mAlphaTestRef;
2466 break;
2467 case GL_CURRENT_COLOR:
2468 {
2469 const auto &color = mGLES1State.mCurrentColor;
2470 params[0] = color.red;
2471 params[1] = color.green;
2472 params[2] = color.blue;
2473 params[3] = color.alpha;
2474 break;
2475 }
2476 case GL_CURRENT_NORMAL:
2477 {
2478 const auto &normal = mGLES1State.mCurrentNormal;
2479 params[0] = normal[0];
2480 params[1] = normal[1];
2481 params[2] = normal[2];
2482 break;
2483 }
2484 case GL_CURRENT_TEXTURE_COORDS:
2485 {
2486 const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
2487 params[0] = texcoord.s;
2488 params[1] = texcoord.t;
2489 params[2] = texcoord.r;
2490 params[3] = texcoord.q;
2491 break;
2492 }
2493 case GL_MODELVIEW_MATRIX:
2494 memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
2495 break;
2496 case GL_PROJECTION_MATRIX:
2497 memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
2498 16 * sizeof(GLfloat));
2499 break;
2500 case GL_TEXTURE_MATRIX:
2501 memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
2502 16 * sizeof(GLfloat));
2503 break;
2504 case GL_LIGHT_MODEL_AMBIENT:
2505 GetLightModelParameters(&mGLES1State, pname, params);
2506 break;
2507 case GL_FOG_MODE:
2508 case GL_FOG_DENSITY:
2509 case GL_FOG_START:
2510 case GL_FOG_END:
2511 case GL_FOG_COLOR:
2512 GetFogParameters(&mGLES1State, pname, params);
2513 break;
2514 case GL_POINT_SIZE:
2515 GetPointSize(&mGLES1State, params);
2516 break;
2517 case GL_POINT_SIZE_MIN:
2518 case GL_POINT_SIZE_MAX:
2519 case GL_POINT_FADE_THRESHOLD_SIZE:
2520 case GL_POINT_DISTANCE_ATTENUATION:
2521 GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
2522 break;
2523 case GL_MIN_SAMPLE_SHADING_VALUE:
2524 *params = mMinSampleShading;
2525 break;
2526 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2527 // If a command returning floating-point data is called, such as GetFloatv, ... An integer
2528 // value is coerced to floating-point.
2529 case GL_CLIP_ORIGIN_EXT:
2530 *params = static_cast<float>(mClipControlOrigin);
2531 break;
2532 case GL_CLIP_DEPTH_MODE_EXT:
2533 *params = static_cast<float>(mClipControlDepth);
2534 break;
2535 default:
2536 UNREACHABLE();
2537 break;
2538 }
2539 }
2540
getIntegerv(const Context * context,GLenum pname,GLint * params) const2541 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
2542 {
2543 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2544 {
2545 size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
2546 ASSERT(drawBuffer < mMaxDrawBuffers);
2547 Framebuffer *framebuffer = mDrawFramebuffer;
2548 // The default framebuffer may have fewer draw buffer states than a user-created one. The
2549 // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
2550 // the draw buffer is out of range for this framebuffer.
2551 *params = drawBuffer < framebuffer->getDrawbufferStateCount()
2552 ? framebuffer->getDrawBufferState(drawBuffer)
2553 : GL_NONE;
2554 return angle::Result::Continue;
2555 }
2556
2557 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
2558 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2559 // GetIntegerv as its native query function. As it would require conversion in any
2560 // case, this should make no difference to the calling application. You may find it in
2561 // State::getFloatv.
2562 switch (pname)
2563 {
2564 case GL_ARRAY_BUFFER_BINDING:
2565 *params = mBoundBuffers[BufferBinding::Array].id().value;
2566 break;
2567 case GL_DRAW_INDIRECT_BUFFER_BINDING:
2568 *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
2569 break;
2570 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2571 {
2572 Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
2573 *params = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
2574 break;
2575 }
2576 case GL_DRAW_FRAMEBUFFER_BINDING:
2577 static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
2578 "Enum mismatch");
2579 *params = mDrawFramebuffer->id().value;
2580 break;
2581 case GL_READ_FRAMEBUFFER_BINDING:
2582 static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
2583 "Enum mismatch");
2584 *params = mReadFramebuffer->id().value;
2585 break;
2586 case GL_RENDERBUFFER_BINDING:
2587 *params = mRenderbuffer.id().value;
2588 break;
2589 case GL_VERTEX_ARRAY_BINDING:
2590 *params = mVertexArray->id().value;
2591 break;
2592 case GL_CURRENT_PROGRAM:
2593 *params = mProgram ? mProgram->id().value : 0;
2594 break;
2595 case GL_PACK_ALIGNMENT:
2596 *params = mPack.alignment;
2597 break;
2598 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2599 *params = mPack.reverseRowOrder;
2600 break;
2601 case GL_PACK_ROW_LENGTH:
2602 *params = mPack.rowLength;
2603 break;
2604 case GL_PACK_SKIP_ROWS:
2605 *params = mPack.skipRows;
2606 break;
2607 case GL_PACK_SKIP_PIXELS:
2608 *params = mPack.skipPixels;
2609 break;
2610 case GL_UNPACK_ALIGNMENT:
2611 *params = mUnpack.alignment;
2612 break;
2613 case GL_UNPACK_ROW_LENGTH:
2614 *params = mUnpack.rowLength;
2615 break;
2616 case GL_UNPACK_IMAGE_HEIGHT:
2617 *params = mUnpack.imageHeight;
2618 break;
2619 case GL_UNPACK_SKIP_IMAGES:
2620 *params = mUnpack.skipImages;
2621 break;
2622 case GL_UNPACK_SKIP_ROWS:
2623 *params = mUnpack.skipRows;
2624 break;
2625 case GL_UNPACK_SKIP_PIXELS:
2626 *params = mUnpack.skipPixels;
2627 break;
2628 case GL_GENERATE_MIPMAP_HINT:
2629 *params = mGenerateMipmapHint;
2630 break;
2631 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2632 *params = mTextureFilteringHint;
2633 break;
2634 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2635 *params = mFragmentShaderDerivativeHint;
2636 break;
2637 case GL_ACTIVE_TEXTURE:
2638 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
2639 break;
2640 case GL_STENCIL_FUNC:
2641 *params = mDepthStencil.stencilFunc;
2642 break;
2643 case GL_STENCIL_REF:
2644 *params = mStencilRef;
2645 break;
2646 case GL_STENCIL_VALUE_MASK:
2647 *params = CastMaskValue(mDepthStencil.stencilMask);
2648 break;
2649 case GL_STENCIL_BACK_FUNC:
2650 *params = mDepthStencil.stencilBackFunc;
2651 break;
2652 case GL_STENCIL_BACK_REF:
2653 *params = mStencilBackRef;
2654 break;
2655 case GL_STENCIL_BACK_VALUE_MASK:
2656 *params = CastMaskValue(mDepthStencil.stencilBackMask);
2657 break;
2658 case GL_STENCIL_FAIL:
2659 *params = mDepthStencil.stencilFail;
2660 break;
2661 case GL_STENCIL_PASS_DEPTH_FAIL:
2662 *params = mDepthStencil.stencilPassDepthFail;
2663 break;
2664 case GL_STENCIL_PASS_DEPTH_PASS:
2665 *params = mDepthStencil.stencilPassDepthPass;
2666 break;
2667 case GL_STENCIL_BACK_FAIL:
2668 *params = mDepthStencil.stencilBackFail;
2669 break;
2670 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2671 *params = mDepthStencil.stencilBackPassDepthFail;
2672 break;
2673 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2674 *params = mDepthStencil.stencilBackPassDepthPass;
2675 break;
2676 case GL_DEPTH_FUNC:
2677 *params = mDepthStencil.depthFunc;
2678 break;
2679 case GL_BLEND_SRC_RGB:
2680 // non-indexed get returns the state of draw buffer zero
2681 *params = mBlendStateExt.getSrcColorIndexed(0);
2682 break;
2683 case GL_BLEND_SRC_ALPHA:
2684 *params = mBlendStateExt.getSrcAlphaIndexed(0);
2685 break;
2686 case GL_BLEND_DST_RGB:
2687 *params = mBlendStateExt.getDstColorIndexed(0);
2688 break;
2689 case GL_BLEND_DST_ALPHA:
2690 *params = mBlendStateExt.getDstAlphaIndexed(0);
2691 break;
2692 case GL_BLEND_EQUATION_RGB:
2693 *params = mBlendStateExt.getEquationColorIndexed(0);
2694 break;
2695 case GL_BLEND_EQUATION_ALPHA:
2696 *params = mBlendStateExt.getEquationAlphaIndexed(0);
2697 break;
2698 case GL_STENCIL_WRITEMASK:
2699 *params = CastMaskValue(mDepthStencil.stencilWritemask);
2700 break;
2701 case GL_STENCIL_BACK_WRITEMASK:
2702 *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
2703 break;
2704 case GL_STENCIL_CLEAR_VALUE:
2705 *params = mStencilClearValue;
2706 break;
2707 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2708 *params = mReadFramebuffer->getImplementationColorReadType(context);
2709 break;
2710 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2711 *params = mReadFramebuffer->getImplementationColorReadFormat(context);
2712 break;
2713 case GL_SAMPLE_BUFFERS:
2714 case GL_SAMPLES:
2715 {
2716 Framebuffer *framebuffer = mDrawFramebuffer;
2717 if (framebuffer->isComplete(context))
2718 {
2719 GLint samples = framebuffer->getSamples(context);
2720 switch (pname)
2721 {
2722 case GL_SAMPLE_BUFFERS:
2723 if (samples != 0)
2724 {
2725 *params = 1;
2726 }
2727 else
2728 {
2729 *params = 0;
2730 }
2731 break;
2732 case GL_SAMPLES:
2733 *params = samples;
2734 break;
2735 }
2736 }
2737 else
2738 {
2739 *params = 0;
2740 }
2741 }
2742 break;
2743 case GL_VIEWPORT:
2744 params[0] = mViewport.x;
2745 params[1] = mViewport.y;
2746 params[2] = mViewport.width;
2747 params[3] = mViewport.height;
2748 break;
2749 case GL_SCISSOR_BOX:
2750 params[0] = mScissor.x;
2751 params[1] = mScissor.y;
2752 params[2] = mScissor.width;
2753 params[3] = mScissor.height;
2754 break;
2755 case GL_CULL_FACE_MODE:
2756 *params = ToGLenum(mRasterizer.cullMode);
2757 break;
2758 case GL_FRONT_FACE:
2759 *params = mRasterizer.frontFace;
2760 break;
2761 case GL_RED_BITS:
2762 case GL_GREEN_BITS:
2763 case GL_BLUE_BITS:
2764 case GL_ALPHA_BITS:
2765 {
2766 Framebuffer *framebuffer = getDrawFramebuffer();
2767 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
2768
2769 if (colorbuffer)
2770 {
2771 switch (pname)
2772 {
2773 case GL_RED_BITS:
2774 *params = colorbuffer->getRedSize();
2775 break;
2776 case GL_GREEN_BITS:
2777 *params = colorbuffer->getGreenSize();
2778 break;
2779 case GL_BLUE_BITS:
2780 *params = colorbuffer->getBlueSize();
2781 break;
2782 case GL_ALPHA_BITS:
2783 *params = colorbuffer->getAlphaSize();
2784 break;
2785 }
2786 }
2787 else
2788 {
2789 *params = 0;
2790 }
2791 }
2792 break;
2793 case GL_DEPTH_BITS:
2794 {
2795 const Framebuffer *framebuffer = getDrawFramebuffer();
2796 const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
2797
2798 if (depthbuffer)
2799 {
2800 *params = depthbuffer->getDepthSize();
2801 }
2802 else
2803 {
2804 *params = 0;
2805 }
2806 }
2807 break;
2808 case GL_STENCIL_BITS:
2809 {
2810 const Framebuffer *framebuffer = getDrawFramebuffer();
2811 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
2812
2813 if (stencilbuffer)
2814 {
2815 *params = stencilbuffer->getStencilSize();
2816 }
2817 else
2818 {
2819 *params = 0;
2820 }
2821 }
2822 break;
2823 case GL_TEXTURE_BINDING_2D:
2824 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2825 *params =
2826 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
2827 .value;
2828 break;
2829 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2830 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2831 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2832 TextureType::Rectangle)
2833 .value;
2834 break;
2835 case GL_TEXTURE_BINDING_CUBE_MAP:
2836 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2837 *params =
2838 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
2839 .value;
2840 break;
2841 case GL_TEXTURE_BINDING_3D:
2842 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2843 *params =
2844 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
2845 .value;
2846 break;
2847 case GL_TEXTURE_BINDING_2D_ARRAY:
2848 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2849 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2850 TextureType::_2DArray)
2851 .value;
2852 break;
2853 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2854 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2855 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2856 TextureType::_2DMultisample)
2857 .value;
2858 break;
2859 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
2860 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2861 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2862 TextureType::_2DMultisampleArray)
2863 .value;
2864 break;
2865 case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
2866 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2867 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2868 TextureType::CubeMapArray)
2869 .value;
2870 break;
2871 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2872 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2873 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2874 TextureType::External)
2875 .value;
2876 break;
2877
2878 // GL_OES_texture_buffer
2879 case GL_TEXTURE_BINDING_BUFFER:
2880 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2881 *params =
2882 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
2883 .value;
2884 break;
2885 case GL_TEXTURE_BUFFER_BINDING:
2886 *params = mBoundBuffers[BufferBinding::Texture].id().value;
2887 break;
2888
2889 case GL_UNIFORM_BUFFER_BINDING:
2890 *params = mBoundBuffers[BufferBinding::Uniform].id().value;
2891 break;
2892 case GL_TRANSFORM_FEEDBACK_BINDING:
2893 *params = mTransformFeedback.id().value;
2894 break;
2895 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2896 *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
2897 break;
2898 case GL_COPY_READ_BUFFER_BINDING:
2899 *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
2900 break;
2901 case GL_COPY_WRITE_BUFFER_BINDING:
2902 *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
2903 break;
2904 case GL_PIXEL_PACK_BUFFER_BINDING:
2905 *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
2906 break;
2907 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2908 *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
2909 break;
2910
2911 case GL_READ_BUFFER:
2912 *params = mReadFramebuffer->getReadBufferState();
2913 break;
2914 case GL_SAMPLER_BINDING:
2915 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2916 *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
2917 break;
2918 case GL_DEBUG_LOGGED_MESSAGES:
2919 *params = static_cast<GLint>(mDebug.getMessageCount());
2920 break;
2921 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2922 *params = static_cast<GLint>(mDebug.getNextMessageLength());
2923 break;
2924 case GL_DEBUG_GROUP_STACK_DEPTH:
2925 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2926 break;
2927 case GL_MULTISAMPLE_EXT:
2928 *params = static_cast<GLint>(mMultiSampling);
2929 break;
2930 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2931 *params = static_cast<GLint>(mSampleAlphaToOne);
2932 break;
2933 case GL_COVERAGE_MODULATION_CHROMIUM:
2934 *params = static_cast<GLint>(mCoverageModulation);
2935 break;
2936 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2937 *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
2938 break;
2939 case GL_SHADER_STORAGE_BUFFER_BINDING:
2940 *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
2941 break;
2942 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
2943 *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
2944 break;
2945 case GL_ALPHA_TEST_FUNC:
2946 *params = ToGLenum(mGLES1State.mAlphaTestFunc);
2947 break;
2948 case GL_CLIENT_ACTIVE_TEXTURE:
2949 *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
2950 break;
2951 case GL_MATRIX_MODE:
2952 *params = ToGLenum(mGLES1State.mMatrixMode);
2953 break;
2954 case GL_SHADE_MODEL:
2955 *params = ToGLenum(mGLES1State.mShadeModel);
2956 break;
2957 case GL_MODELVIEW_STACK_DEPTH:
2958 case GL_PROJECTION_STACK_DEPTH:
2959 case GL_TEXTURE_STACK_DEPTH:
2960 *params = mGLES1State.getCurrentMatrixStackDepth(pname);
2961 break;
2962 case GL_LOGIC_OP_MODE:
2963 *params = ToGLenum(mGLES1State.mLogicOp);
2964 break;
2965 case GL_BLEND_SRC:
2966 // non-indexed get returns the state of draw buffer zero
2967 *params = mBlendStateExt.getSrcColorIndexed(0);
2968 break;
2969 case GL_BLEND_DST:
2970 *params = mBlendStateExt.getDstColorIndexed(0);
2971 break;
2972 case GL_PERSPECTIVE_CORRECTION_HINT:
2973 case GL_POINT_SMOOTH_HINT:
2974 case GL_LINE_SMOOTH_HINT:
2975 case GL_FOG_HINT:
2976 *params = mGLES1State.getHint(pname);
2977 break;
2978
2979 // GL_ANGLE_provoking_vertex
2980 case GL_PROVOKING_VERTEX:
2981 *params = ToGLenum(mProvokingVertex);
2982 break;
2983
2984 case GL_PROGRAM_PIPELINE_BINDING:
2985 {
2986 ProgramPipeline *pipeline = getProgramPipeline();
2987 if (pipeline)
2988 {
2989 *params = pipeline->id().value;
2990 }
2991 else
2992 {
2993 *params = 0;
2994 }
2995 break;
2996 }
2997 case GL_PATCH_VERTICES:
2998 *params = mPatchVertices;
2999 break;
3000
3001 // GL_EXT_clip_control
3002 case GL_CLIP_ORIGIN_EXT:
3003 *params = mClipControlOrigin;
3004 break;
3005 case GL_CLIP_DEPTH_MODE_EXT:
3006 *params = mClipControlDepth;
3007 break;
3008 default:
3009 UNREACHABLE();
3010 break;
3011 }
3012
3013 return angle::Result::Continue;
3014 }
3015
getPointerv(const Context * context,GLenum pname,void ** params) const3016 void State::getPointerv(const Context *context, GLenum pname, void **params) const
3017 {
3018 switch (pname)
3019 {
3020 case GL_DEBUG_CALLBACK_FUNCTION:
3021 *params = reinterpret_cast<void *>(mDebug.getCallback());
3022 break;
3023 case GL_DEBUG_CALLBACK_USER_PARAM:
3024 *params = const_cast<void *>(mDebug.getUserParam());
3025 break;
3026 case GL_VERTEX_ARRAY_POINTER:
3027 case GL_NORMAL_ARRAY_POINTER:
3028 case GL_COLOR_ARRAY_POINTER:
3029 case GL_TEXTURE_COORD_ARRAY_POINTER:
3030 case GL_POINT_SIZE_ARRAY_POINTER_OES:
3031 QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
3032 context->vertexArrayIndex(ParamToVertexArrayType(pname))),
3033 GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
3034 return;
3035 default:
3036 UNREACHABLE();
3037 break;
3038 }
3039 }
3040
getIntegeri_v(GLenum target,GLuint index,GLint * data) const3041 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) const
3042 {
3043 switch (target)
3044 {
3045 case GL_BLEND_SRC_RGB:
3046 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3047 *data = mBlendStateExt.getSrcColorIndexed(index);
3048 break;
3049 case GL_BLEND_SRC_ALPHA:
3050 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3051 *data = mBlendStateExt.getSrcAlphaIndexed(index);
3052 break;
3053 case GL_BLEND_DST_RGB:
3054 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3055 *data = mBlendStateExt.getDstColorIndexed(index);
3056 break;
3057 case GL_BLEND_DST_ALPHA:
3058 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3059 *data = mBlendStateExt.getDstAlphaIndexed(index);
3060 break;
3061 case GL_BLEND_EQUATION_RGB:
3062 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3063 *data = mBlendStateExt.getEquationColorIndexed(index);
3064 break;
3065 case GL_BLEND_EQUATION_ALPHA:
3066 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3067 *data = mBlendStateExt.getEquationAlphaIndexed(index);
3068 break;
3069 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3070 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3071 *data = mTransformFeedback->getIndexedBuffer(index).id().value;
3072 break;
3073 case GL_UNIFORM_BUFFER_BINDING:
3074 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3075 *data = mUniformBuffers[index].id().value;
3076 break;
3077 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3078 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3079 *data = mAtomicCounterBuffers[index].id().value;
3080 break;
3081 case GL_SHADER_STORAGE_BUFFER_BINDING:
3082 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3083 *data = mShaderStorageBuffers[index].id().value;
3084 break;
3085 case GL_VERTEX_BINDING_BUFFER:
3086 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3087 *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
3088 break;
3089 case GL_VERTEX_BINDING_DIVISOR:
3090 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3091 *data = mVertexArray->getVertexBinding(index).getDivisor();
3092 break;
3093 case GL_VERTEX_BINDING_OFFSET:
3094 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3095 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
3096 break;
3097 case GL_VERTEX_BINDING_STRIDE:
3098 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3099 *data = mVertexArray->getVertexBinding(index).getStride();
3100 break;
3101 case GL_SAMPLE_MASK_VALUE:
3102 ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
3103 *data = mSampleMaskValues[index];
3104 break;
3105 case GL_IMAGE_BINDING_NAME:
3106 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3107 *data = mImageUnits[index].texture.id().value;
3108 break;
3109 case GL_IMAGE_BINDING_LEVEL:
3110 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3111 *data = mImageUnits[index].level;
3112 break;
3113 case GL_IMAGE_BINDING_LAYER:
3114 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3115 *data = mImageUnits[index].layer;
3116 break;
3117 case GL_IMAGE_BINDING_ACCESS:
3118 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3119 *data = mImageUnits[index].access;
3120 break;
3121 case GL_IMAGE_BINDING_FORMAT:
3122 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3123 *data = mImageUnits[index].format;
3124 break;
3125 default:
3126 UNREACHABLE();
3127 break;
3128 }
3129 }
3130
getInteger64i_v(GLenum target,GLuint index,GLint64 * data) const3131 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
3132 {
3133 switch (target)
3134 {
3135 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
3136 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3137 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
3138 break;
3139 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
3140 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3141 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
3142 break;
3143 case GL_UNIFORM_BUFFER_START:
3144 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3145 *data = mUniformBuffers[index].getOffset();
3146 break;
3147 case GL_UNIFORM_BUFFER_SIZE:
3148 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3149 *data = mUniformBuffers[index].getSize();
3150 break;
3151 case GL_ATOMIC_COUNTER_BUFFER_START:
3152 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3153 *data = mAtomicCounterBuffers[index].getOffset();
3154 break;
3155 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
3156 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3157 *data = mAtomicCounterBuffers[index].getSize();
3158 break;
3159 case GL_SHADER_STORAGE_BUFFER_START:
3160 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3161 *data = mShaderStorageBuffers[index].getOffset();
3162 break;
3163 case GL_SHADER_STORAGE_BUFFER_SIZE:
3164 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3165 *data = mShaderStorageBuffers[index].getSize();
3166 break;
3167 default:
3168 UNREACHABLE();
3169 break;
3170 }
3171 }
3172
getBooleani_v(GLenum target,GLuint index,GLboolean * data) const3173 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
3174 {
3175 switch (target)
3176 {
3177 case GL_COLOR_WRITEMASK:
3178 {
3179 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3180 bool r, g, b, a;
3181 mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
3182 data[0] = r;
3183 data[1] = g;
3184 data[2] = b;
3185 data[3] = a;
3186 break;
3187 }
3188 case GL_IMAGE_BINDING_LAYERED:
3189 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3190 *data = mImageUnits[index].layered;
3191 break;
3192 default:
3193 UNREACHABLE();
3194 break;
3195 }
3196 }
3197
3198 // TODO(https://anglebug.com/3889): Remove this helper function after blink and chromium part
3199 // refactory done.
getTextureForActiveSampler(TextureType type,size_t index)3200 Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
3201 {
3202 if (type != TextureType::VideoImage)
3203 {
3204 return mSamplerTextures[type][index].get();
3205 }
3206
3207 ASSERT(type == TextureType::VideoImage);
3208
3209 Texture *candidateTexture = mSamplerTextures[type][index].get();
3210 if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
3211 candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
3212 candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
3213 {
3214 return mSamplerTextures[TextureType::_2D][index].get();
3215 }
3216
3217 return mSamplerTextures[type][index].get();
3218 }
3219
syncActiveTextures(const Context * context,Command command)3220 angle::Result State::syncActiveTextures(const Context *context, Command command)
3221 {
3222 if (mDirtyActiveTextures.none())
3223 {
3224 return angle::Result::Continue;
3225 }
3226
3227 for (size_t textureUnit : mDirtyActiveTextures)
3228 {
3229 if (mExecutable)
3230 {
3231 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3232 Texture *activeTexture = (type != TextureType::InvalidEnum)
3233 ? getTextureForActiveSampler(type, textureUnit)
3234 : nullptr;
3235 const Sampler *sampler = mSamplers[textureUnit].get();
3236
3237 updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
3238 }
3239 }
3240
3241 mDirtyActiveTextures.reset();
3242 return angle::Result::Continue;
3243 }
3244
syncTexturesInit(const Context * context,Command command)3245 angle::Result State::syncTexturesInit(const Context *context, Command command)
3246 {
3247 ASSERT(mRobustResourceInit);
3248
3249 if (!mProgram)
3250 return angle::Result::Continue;
3251
3252 for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
3253 {
3254 Texture *texture = mActiveTexturesCache[textureUnitIndex];
3255 if (texture)
3256 {
3257 ANGLE_TRY(texture->ensureInitialized(context));
3258 }
3259 }
3260 return angle::Result::Continue;
3261 }
3262
syncImagesInit(const Context * context,Command command)3263 angle::Result State::syncImagesInit(const Context *context, Command command)
3264 {
3265 ASSERT(mRobustResourceInit);
3266 ASSERT(mProgram);
3267 for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
3268 {
3269 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3270 if (texture)
3271 {
3272 ANGLE_TRY(texture->ensureInitialized(context));
3273 }
3274 }
3275 return angle::Result::Continue;
3276 }
3277
syncReadAttachments(const Context * context,Command command)3278 angle::Result State::syncReadAttachments(const Context *context, Command command)
3279 {
3280 ASSERT(mReadFramebuffer);
3281 ASSERT(mRobustResourceInit);
3282 return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
3283 }
3284
syncDrawAttachments(const Context * context,Command command)3285 angle::Result State::syncDrawAttachments(const Context *context, Command command)
3286 {
3287 ASSERT(mDrawFramebuffer);
3288 ASSERT(mRobustResourceInit);
3289 return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
3290 }
3291
syncReadFramebuffer(const Context * context,Command command)3292 angle::Result State::syncReadFramebuffer(const Context *context, Command command)
3293 {
3294 ASSERT(mReadFramebuffer);
3295 return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
3296 }
3297
syncDrawFramebuffer(const Context * context,Command command)3298 angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
3299 {
3300 ASSERT(mDrawFramebuffer);
3301 mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
3302 ? SrgbWriteControlMode::Default
3303 : SrgbWriteControlMode::Linear);
3304 return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
3305 }
3306
syncTextures(const Context * context,Command command)3307 angle::Result State::syncTextures(const Context *context, Command command)
3308 {
3309 if (mDirtyTextures.none())
3310 return angle::Result::Continue;
3311
3312 for (size_t textureIndex : mDirtyTextures)
3313 {
3314 Texture *texture = mActiveTexturesCache[textureIndex];
3315 if (texture && texture->hasAnyDirtyBit())
3316 {
3317 ANGLE_TRY(texture->syncState(context, Command::Other));
3318 }
3319 }
3320
3321 mDirtyTextures.reset();
3322 return angle::Result::Continue;
3323 }
3324
syncImages(const Context * context,Command command)3325 angle::Result State::syncImages(const Context *context, Command command)
3326 {
3327 if (mDirtyImages.none())
3328 return angle::Result::Continue;
3329
3330 for (size_t imageUnitIndex : mDirtyImages)
3331 {
3332 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3333 if (texture && texture->hasAnyDirtyBit())
3334 {
3335 ANGLE_TRY(texture->syncState(context, Command::Other));
3336 }
3337 }
3338
3339 mDirtyImages.reset();
3340 return angle::Result::Continue;
3341 }
3342
syncSamplers(const Context * context,Command command)3343 angle::Result State::syncSamplers(const Context *context, Command command)
3344 {
3345 if (mDirtySamplers.none())
3346 return angle::Result::Continue;
3347
3348 for (size_t samplerIndex : mDirtySamplers)
3349 {
3350 BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
3351 if (sampler.get() && sampler->isDirty())
3352 {
3353 ANGLE_TRY(sampler->syncState(context));
3354 }
3355 }
3356
3357 mDirtySamplers.reset();
3358
3359 return angle::Result::Continue;
3360 }
3361
syncVertexArray(const Context * context,Command command)3362 angle::Result State::syncVertexArray(const Context *context, Command command)
3363 {
3364 ASSERT(mVertexArray);
3365 return mVertexArray->syncState(context);
3366 }
3367
syncProgram(const Context * context,Command command)3368 angle::Result State::syncProgram(const Context *context, Command command)
3369 {
3370 // There may not be a program if the calling application only uses program pipelines.
3371 if (mProgram)
3372 {
3373 return mProgram->syncState(context);
3374 }
3375 return angle::Result::Continue;
3376 }
3377
syncDirtyObject(const Context * context,GLenum target)3378 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
3379 {
3380 DirtyObjects localSet;
3381
3382 switch (target)
3383 {
3384 case GL_READ_FRAMEBUFFER:
3385 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3386 break;
3387 case GL_DRAW_FRAMEBUFFER:
3388 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3389 break;
3390 case GL_FRAMEBUFFER:
3391 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3392 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3393 break;
3394 case GL_VERTEX_ARRAY:
3395 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
3396 break;
3397 case GL_TEXTURE:
3398 localSet.set(DIRTY_OBJECT_TEXTURES);
3399 break;
3400 case GL_SAMPLER:
3401 localSet.set(DIRTY_OBJECT_SAMPLERS);
3402 break;
3403 case GL_PROGRAM:
3404 localSet.set(DIRTY_OBJECT_PROGRAM);
3405 break;
3406 }
3407
3408 return syncDirtyObjects(context, localSet, Command::Other);
3409 }
3410
setObjectDirty(GLenum target)3411 void State::setObjectDirty(GLenum target)
3412 {
3413 switch (target)
3414 {
3415 case GL_READ_FRAMEBUFFER:
3416 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3417 break;
3418 case GL_DRAW_FRAMEBUFFER:
3419 setDrawFramebufferDirty();
3420 break;
3421 case GL_FRAMEBUFFER:
3422 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3423 setDrawFramebufferDirty();
3424 break;
3425 case GL_VERTEX_ARRAY:
3426 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
3427 break;
3428 case GL_PROGRAM:
3429 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3430 break;
3431 default:
3432 break;
3433 }
3434 }
3435
onProgramExecutableChange(const Context * context,Program * program)3436 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
3437 {
3438 // OpenGL Spec:
3439 // "If LinkProgram or ProgramBinary successfully re-links a program object
3440 // that was already in use as a result of a previous call to UseProgram, then the
3441 // generated executable code will be installed as part of the current rendering state."
3442 ASSERT(program->isLinked());
3443
3444 // If this Program is currently active, we need to update the State's pointer to the current
3445 // ProgramExecutable if we just changed it.
3446 if (mProgram == program)
3447 {
3448 mExecutable = &program->getExecutable();
3449 }
3450
3451 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3452
3453 if (program->hasAnyDirtyBit())
3454 {
3455 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3456 }
3457
3458 // Set any bound textures.
3459 const ProgramExecutable &executable = program->getExecutable();
3460 const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3461 for (size_t textureIndex : executable.getActiveSamplersMask())
3462 {
3463 TextureType type = textureTypes[textureIndex];
3464
3465 // This can happen if there is a conflicting texture type.
3466 if (type == TextureType::InvalidEnum)
3467 continue;
3468
3469 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3470 updateTextureBinding(context, textureIndex, texture);
3471 }
3472
3473 for (size_t imageUnitIndex : executable.getActiveImagesMask())
3474 {
3475 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3476 if (!image)
3477 continue;
3478
3479 if (image->hasAnyDirtyBit())
3480 {
3481 ANGLE_TRY(image->syncState(context, Command::Other));
3482 }
3483
3484 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3485 {
3486 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3487 }
3488 }
3489
3490 return angle::Result::Continue;
3491 }
3492
onProgramPipelineExecutableChange(const Context * context,ProgramPipeline * programPipeline)3493 angle::Result State::onProgramPipelineExecutableChange(const Context *context,
3494 ProgramPipeline *programPipeline)
3495 {
3496 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3497
3498 // Set any bound textures.
3499 const ActiveTextureTypeArray &textureTypes =
3500 programPipeline->getExecutable().getActiveSamplerTypes();
3501 for (size_t textureIndex : programPipeline->getExecutable().getActiveSamplersMask())
3502 {
3503 TextureType type = textureTypes[textureIndex];
3504
3505 // This can happen if there is a conflicting texture type.
3506 if (type == TextureType::InvalidEnum)
3507 continue;
3508
3509 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3510 updateTextureBinding(context, textureIndex, texture);
3511 }
3512
3513 for (size_t imageUnitIndex : programPipeline->getExecutable().getActiveImagesMask())
3514 {
3515 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3516 if (!image)
3517 continue;
3518
3519 if (image->hasAnyDirtyBit())
3520 {
3521 ANGLE_TRY(image->syncState(context, Command::Other));
3522 }
3523
3524 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3525 {
3526 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3527 }
3528 }
3529
3530 return angle::Result::Continue;
3531 }
3532
setTextureDirty(size_t textureUnitIndex)3533 void State::setTextureDirty(size_t textureUnitIndex)
3534 {
3535 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
3536 mDirtyTextures.set(textureUnitIndex);
3537 }
3538
setSamplerDirty(size_t samplerIndex)3539 void State::setSamplerDirty(size_t samplerIndex)
3540 {
3541 mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
3542 mDirtySamplers.set(samplerIndex);
3543 }
3544
setImageUnit(const Context * context,size_t unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)3545 void State::setImageUnit(const Context *context,
3546 size_t unit,
3547 Texture *texture,
3548 GLint level,
3549 GLboolean layered,
3550 GLint layer,
3551 GLenum access,
3552 GLenum format)
3553 {
3554 ASSERT(!mImageUnits.empty());
3555
3556 ImageUnit &imageUnit = mImageUnits[unit];
3557
3558 if (texture)
3559 {
3560 texture->onBindAsImageTexture();
3561 }
3562 imageUnit.texture.set(context, texture);
3563 imageUnit.level = level;
3564 imageUnit.layered = layered;
3565 imageUnit.layer = layer;
3566 imageUnit.access = access;
3567 imageUnit.format = format;
3568 mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
3569
3570 onImageStateChange(context, unit);
3571 }
3572
3573 // Handle a dirty texture event.
onActiveTextureChange(const Context * context,size_t textureUnit)3574 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
3575 {
3576 if (mExecutable)
3577 {
3578 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3579 Texture *activeTexture = (type != TextureType::InvalidEnum)
3580 ? getTextureForActiveSampler(type, textureUnit)
3581 : nullptr;
3582 updateTextureBinding(context, textureUnit, activeTexture);
3583
3584 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3585 }
3586 }
3587
onActiveTextureStateChange(const Context * context,size_t textureUnit)3588 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
3589 {
3590 if (mExecutable)
3591 {
3592 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3593 Texture *activeTexture = (type != TextureType::InvalidEnum)
3594 ? getTextureForActiveSampler(type, textureUnit)
3595 : nullptr;
3596 setActiveTextureDirty(textureUnit, activeTexture);
3597 }
3598 }
3599
onImageStateChange(const Context * context,size_t unit)3600 void State::onImageStateChange(const Context *context, size_t unit)
3601 {
3602 if (mExecutable)
3603 {
3604 const ImageUnit &image = mImageUnits[unit];
3605
3606 // Have nothing to do here if no texture bound
3607 if (!image.texture.get())
3608 return;
3609
3610 if (image.texture->hasAnyDirtyBit())
3611 {
3612 mDirtyImages.set(unit);
3613 mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
3614 }
3615
3616 if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
3617 {
3618 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3619 }
3620
3621 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3622 }
3623 }
3624
onUniformBufferStateChange(size_t uniformBufferIndex)3625 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
3626 {
3627 // This could be represented by a different dirty bit. Using the same one keeps it simple.
3628 mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
3629 }
3630
getAndResetDirtyCurrentValues() const3631 AttributesMask State::getAndResetDirtyCurrentValues() const
3632 {
3633 AttributesMask retVal = mDirtyCurrentValues;
3634 mDirtyCurrentValues.reset();
3635 return retVal;
3636 }
3637
getAndResetExtendedDirtyBits() const3638 State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
3639 {
3640 ExtendedDirtyBits retVal = mExtendedDirtyBits;
3641 mExtendedDirtyBits.reset();
3642 return retVal;
3643 }
3644
3645 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
3646
3647 } // namespace gl
3648