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