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