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 context->getStateCache().onActiveTransformFeedbackChange(context);
2178 }
2179
2180 if (getVertexArray()->detachBuffer(context, bufferID))
2181 {
2182 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2183 context->getStateCache().onVertexArrayStateChange(context);
2184 }
2185
2186 for (size_t uniformBufferIndex : mBoundUniformBuffersMask)
2187 {
2188 OffsetBindingPointer<Buffer> &binding = mUniformBuffers[uniformBufferIndex];
2189
2190 if (binding.id() == bufferID)
2191 {
2192 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::Uniform, 0, 0);
2193 mBoundUniformBuffersMask.reset(uniformBufferIndex);
2194 }
2195 }
2196
2197 for (size_t atomicCounterBufferIndex : mBoundAtomicCounterBuffersMask)
2198 {
2199 OffsetBindingPointer<Buffer> &binding = mAtomicCounterBuffers[atomicCounterBufferIndex];
2200
2201 if (binding.id() == bufferID)
2202 {
2203 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::AtomicCounter, 0,
2204 0);
2205 mBoundAtomicCounterBuffersMask.reset(atomicCounterBufferIndex);
2206 }
2207 }
2208
2209 for (size_t shaderStorageBufferIndex : mBoundShaderStorageBuffersMask)
2210 {
2211 OffsetBindingPointer<Buffer> &binding = mShaderStorageBuffers[shaderStorageBufferIndex];
2212
2213 if (binding.id() == bufferID)
2214 {
2215 UpdateIndexedBufferBinding(context, &binding, nullptr, BufferBinding::ShaderStorage, 0,
2216 0);
2217 mBoundShaderStorageBuffersMask.reset(shaderStorageBufferIndex);
2218 }
2219 }
2220
2221 return angle::Result::Continue;
2222 }
2223
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)2224 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
2225 {
2226 getVertexArray()->enableAttribute(attribNum, enabled);
2227 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2228 }
2229
setVertexAttribf(GLuint index,const GLfloat values[4])2230 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
2231 {
2232 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2233 mVertexAttribCurrentValues[index].setFloatValues(values);
2234 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2235 mDirtyCurrentValues.set(index);
2236 SetComponentTypeMask(ComponentType::Float, index, &mCurrentValuesTypeMask);
2237 }
2238
setVertexAttribu(GLuint index,const GLuint values[4])2239 void State::setVertexAttribu(GLuint index, const GLuint values[4])
2240 {
2241 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2242 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
2243 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2244 mDirtyCurrentValues.set(index);
2245 SetComponentTypeMask(ComponentType::UnsignedInt, index, &mCurrentValuesTypeMask);
2246 }
2247
setVertexAttribi(GLuint index,const GLint values[4])2248 void State::setVertexAttribi(GLuint index, const GLint values[4])
2249 {
2250 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
2251 mVertexAttribCurrentValues[index].setIntValues(values);
2252 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
2253 mDirtyCurrentValues.set(index);
2254 SetComponentTypeMask(ComponentType::Int, index, &mCurrentValuesTypeMask);
2255 }
2256
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)2257 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
2258 {
2259 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
2260 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2261 }
2262
getVertexAttribPointer(unsigned int attribNum) const2263 const void *State::getVertexAttribPointer(unsigned int attribNum) const
2264 {
2265 return getVertexArray()->getVertexAttribute(attribNum).pointer;
2266 }
2267
setPackAlignment(GLint alignment)2268 void State::setPackAlignment(GLint alignment)
2269 {
2270 mPack.alignment = alignment;
2271 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2272 }
2273
setPackReverseRowOrder(bool reverseRowOrder)2274 void State::setPackReverseRowOrder(bool reverseRowOrder)
2275 {
2276 mPack.reverseRowOrder = reverseRowOrder;
2277 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2278 }
2279
setPackRowLength(GLint rowLength)2280 void State::setPackRowLength(GLint rowLength)
2281 {
2282 mPack.rowLength = rowLength;
2283 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2284 }
2285
setPackSkipRows(GLint skipRows)2286 void State::setPackSkipRows(GLint skipRows)
2287 {
2288 mPack.skipRows = skipRows;
2289 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2290 }
2291
setPackSkipPixels(GLint skipPixels)2292 void State::setPackSkipPixels(GLint skipPixels)
2293 {
2294 mPack.skipPixels = skipPixels;
2295 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
2296 }
2297
setUnpackAlignment(GLint alignment)2298 void State::setUnpackAlignment(GLint alignment)
2299 {
2300 mUnpack.alignment = alignment;
2301 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2302 }
2303
setUnpackRowLength(GLint rowLength)2304 void State::setUnpackRowLength(GLint rowLength)
2305 {
2306 mUnpack.rowLength = rowLength;
2307 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2308 }
2309
setUnpackImageHeight(GLint imageHeight)2310 void State::setUnpackImageHeight(GLint imageHeight)
2311 {
2312 mUnpack.imageHeight = imageHeight;
2313 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2314 }
2315
setUnpackSkipImages(GLint skipImages)2316 void State::setUnpackSkipImages(GLint skipImages)
2317 {
2318 mUnpack.skipImages = skipImages;
2319 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2320 }
2321
setUnpackSkipRows(GLint skipRows)2322 void State::setUnpackSkipRows(GLint skipRows)
2323 {
2324 mUnpack.skipRows = skipRows;
2325 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2326 }
2327
setUnpackSkipPixels(GLint skipPixels)2328 void State::setUnpackSkipPixels(GLint skipPixels)
2329 {
2330 mUnpack.skipPixels = skipPixels;
2331 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
2332 }
2333
setCoverageModulation(GLenum components)2334 void State::setCoverageModulation(GLenum components)
2335 {
2336 if (mCoverageModulation != components)
2337 {
2338 mCoverageModulation = components;
2339 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
2340 }
2341 }
2342
setFramebufferSRGB(bool sRGB)2343 void State::setFramebufferSRGB(bool sRGB)
2344 {
2345 if (mFramebufferSRGB != sRGB)
2346 {
2347 mFramebufferSRGB = sRGB;
2348 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2349 setDrawFramebufferDirty();
2350 }
2351 }
2352
setMaxShaderCompilerThreads(GLuint count)2353 void State::setMaxShaderCompilerThreads(GLuint count)
2354 {
2355 mMaxShaderCompilerThreads = count;
2356 }
2357
setPatchVertices(GLuint value)2358 void State::setPatchVertices(GLuint value)
2359 {
2360 if (mPatchVertices != value)
2361 {
2362 mPatchVertices = value;
2363 mDirtyBits.set(DIRTY_BIT_PATCH_VERTICES);
2364 }
2365 }
2366
getBooleanv(GLenum pname,GLboolean * params) const2367 void State::getBooleanv(GLenum pname, GLboolean *params) const
2368 {
2369 switch (pname)
2370 {
2371 case GL_SAMPLE_COVERAGE_INVERT:
2372 *params = mSampleCoverageInvert;
2373 break;
2374 case GL_DEPTH_WRITEMASK:
2375 *params = mDepthStencil.depthMask;
2376 break;
2377 case GL_COLOR_WRITEMASK:
2378 {
2379 // non-indexed get returns the state of draw buffer zero
2380 bool r, g, b, a;
2381 mBlendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2382 params[0] = r;
2383 params[1] = g;
2384 params[2] = b;
2385 params[3] = a;
2386 break;
2387 }
2388 case GL_CULL_FACE:
2389 *params = mRasterizer.cullFace;
2390 break;
2391 case GL_POLYGON_OFFSET_FILL:
2392 *params = mRasterizer.polygonOffsetFill;
2393 break;
2394 case GL_SAMPLE_ALPHA_TO_COVERAGE:
2395 *params = mSampleAlphaToCoverage;
2396 break;
2397 case GL_SAMPLE_COVERAGE:
2398 *params = mSampleCoverage;
2399 break;
2400 case GL_SAMPLE_MASK:
2401 *params = mSampleMask;
2402 break;
2403 case GL_SCISSOR_TEST:
2404 *params = mScissorTest;
2405 break;
2406 case GL_STENCIL_TEST:
2407 *params = mDepthStencil.stencilTest;
2408 break;
2409 case GL_DEPTH_TEST:
2410 *params = mDepthStencil.depthTest;
2411 break;
2412 case GL_BLEND:
2413 // non-indexed get returns the state of draw buffer zero
2414 *params = mBlendStateExt.mEnabledMask.test(0);
2415 break;
2416 case GL_DITHER:
2417 *params = mRasterizer.dither;
2418 break;
2419 case GL_TRANSFORM_FEEDBACK_ACTIVE:
2420 *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE;
2421 break;
2422 case GL_TRANSFORM_FEEDBACK_PAUSED:
2423 *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE;
2424 break;
2425 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2426 *params = mPrimitiveRestart;
2427 break;
2428 case GL_RASTERIZER_DISCARD:
2429 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
2430 break;
2431 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
2432 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
2433 break;
2434 case GL_DEBUG_OUTPUT:
2435 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
2436 break;
2437 case GL_MULTISAMPLE_EXT:
2438 *params = mMultiSampling;
2439 break;
2440 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2441 *params = mSampleAlphaToOne;
2442 break;
2443 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
2444 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
2445 break;
2446 case GL_CLIENT_ARRAYS_ANGLE:
2447 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
2448 break;
2449 case GL_FRAMEBUFFER_SRGB_EXT:
2450 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
2451 break;
2452 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
2453 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
2454 break;
2455 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
2456 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
2457 break;
2458 case GL_TEXTURE_RECTANGLE_ANGLE:
2459 *params = mTextureRectangleEnabled ? GL_TRUE : GL_FALSE;
2460 break;
2461 case GL_LIGHT_MODEL_TWO_SIDE:
2462 *params = IsLightModelTwoSided(&mGLES1State);
2463 break;
2464 case GL_SAMPLE_SHADING:
2465 *params = mIsSampleShadingEnabled;
2466 break;
2467 case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
2468 *params = isPrimitiveRestartEnabled() && getExtensions().tessellationShaderEXT;
2469 break;
2470 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2471 // If a command returning boolean data is called, such as GetBooleanv, a floating-point or
2472 // integer value converts to FALSE if and only if it is zero. Otherwise it converts to TRUE.
2473 // GL_EXT_clip_control
2474 case GL_CLIP_ORIGIN_EXT:
2475 *params = GL_TRUE;
2476 break;
2477 case GL_CLIP_DEPTH_MODE_EXT:
2478 *params = GL_TRUE;
2479 break;
2480 case GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE:
2481 *params = mExtensions.robustFragmentShaderOutputANGLE ? GL_TRUE : GL_FALSE;
2482 break;
2483 default:
2484 UNREACHABLE();
2485 break;
2486 }
2487 }
2488
getFloatv(GLenum pname,GLfloat * params) const2489 void State::getFloatv(GLenum pname, GLfloat *params) const
2490 {
2491 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
2492 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2493 // GetIntegerv as its native query function. As it would require conversion in any
2494 // case, this should make no difference to the calling application.
2495 switch (pname)
2496 {
2497 case GL_LINE_WIDTH:
2498 *params = mLineWidth;
2499 break;
2500 case GL_SAMPLE_COVERAGE_VALUE:
2501 *params = mSampleCoverageValue;
2502 break;
2503 case GL_DEPTH_CLEAR_VALUE:
2504 *params = mDepthClearValue;
2505 break;
2506 case GL_POLYGON_OFFSET_FACTOR:
2507 *params = mRasterizer.polygonOffsetFactor;
2508 break;
2509 case GL_POLYGON_OFFSET_UNITS:
2510 *params = mRasterizer.polygonOffsetUnits;
2511 break;
2512 case GL_DEPTH_RANGE:
2513 params[0] = mNearZ;
2514 params[1] = mFarZ;
2515 break;
2516 case GL_COLOR_CLEAR_VALUE:
2517 params[0] = mColorClearValue.red;
2518 params[1] = mColorClearValue.green;
2519 params[2] = mColorClearValue.blue;
2520 params[3] = mColorClearValue.alpha;
2521 break;
2522 case GL_BLEND_COLOR:
2523 params[0] = mBlendColor.red;
2524 params[1] = mBlendColor.green;
2525 params[2] = mBlendColor.blue;
2526 params[3] = mBlendColor.alpha;
2527 break;
2528 case GL_MULTISAMPLE_EXT:
2529 *params = static_cast<GLfloat>(mMultiSampling);
2530 break;
2531 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2532 *params = static_cast<GLfloat>(mSampleAlphaToOne);
2533 break;
2534 case GL_COVERAGE_MODULATION_CHROMIUM:
2535 params[0] = static_cast<GLfloat>(mCoverageModulation);
2536 break;
2537 case GL_ALPHA_TEST_REF:
2538 *params = mGLES1State.mAlphaTestRef;
2539 break;
2540 case GL_CURRENT_COLOR:
2541 {
2542 const auto &color = mGLES1State.mCurrentColor;
2543 params[0] = color.red;
2544 params[1] = color.green;
2545 params[2] = color.blue;
2546 params[3] = color.alpha;
2547 break;
2548 }
2549 case GL_CURRENT_NORMAL:
2550 {
2551 const auto &normal = mGLES1State.mCurrentNormal;
2552 params[0] = normal[0];
2553 params[1] = normal[1];
2554 params[2] = normal[2];
2555 break;
2556 }
2557 case GL_CURRENT_TEXTURE_COORDS:
2558 {
2559 const auto &texcoord = mGLES1State.mCurrentTextureCoords[mActiveSampler];
2560 params[0] = texcoord.s;
2561 params[1] = texcoord.t;
2562 params[2] = texcoord.r;
2563 params[3] = texcoord.q;
2564 break;
2565 }
2566 case GL_MODELVIEW_MATRIX:
2567 memcpy(params, mGLES1State.mModelviewMatrices.back().constData(), 16 * sizeof(GLfloat));
2568 break;
2569 case GL_PROJECTION_MATRIX:
2570 memcpy(params, mGLES1State.mProjectionMatrices.back().constData(),
2571 16 * sizeof(GLfloat));
2572 break;
2573 case GL_TEXTURE_MATRIX:
2574 memcpy(params, mGLES1State.mTextureMatrices[mActiveSampler].back().constData(),
2575 16 * sizeof(GLfloat));
2576 break;
2577 case GL_LIGHT_MODEL_AMBIENT:
2578 GetLightModelParameters(&mGLES1State, pname, params);
2579 break;
2580 case GL_FOG_MODE:
2581 case GL_FOG_DENSITY:
2582 case GL_FOG_START:
2583 case GL_FOG_END:
2584 case GL_FOG_COLOR:
2585 GetFogParameters(&mGLES1State, pname, params);
2586 break;
2587 case GL_POINT_SIZE:
2588 GetPointSize(&mGLES1State, params);
2589 break;
2590 case GL_POINT_SIZE_MIN:
2591 case GL_POINT_SIZE_MAX:
2592 case GL_POINT_FADE_THRESHOLD_SIZE:
2593 case GL_POINT_DISTANCE_ATTENUATION:
2594 GetPointParameter(&mGLES1State, FromGLenum<PointParameter>(pname), params);
2595 break;
2596 case GL_MIN_SAMPLE_SHADING_VALUE:
2597 *params = mMinSampleShading;
2598 break;
2599 // 2.2.2 Data Conversions For State Query Commands, in GLES 3.2 spec.
2600 // If a command returning floating-point data is called, such as GetFloatv, ... An integer
2601 // value is coerced to floating-point.
2602 case GL_CLIP_ORIGIN_EXT:
2603 *params = static_cast<float>(mClipControlOrigin);
2604 break;
2605 case GL_CLIP_DEPTH_MODE_EXT:
2606 *params = static_cast<float>(mClipControlDepth);
2607 break;
2608 default:
2609 UNREACHABLE();
2610 break;
2611 }
2612 }
2613
getIntegerv(const Context * context,GLenum pname,GLint * params) const2614 angle::Result State::getIntegerv(const Context *context, GLenum pname, GLint *params) const
2615 {
2616 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2617 {
2618 size_t drawBuffer = (pname - GL_DRAW_BUFFER0_EXT);
2619 ASSERT(drawBuffer < static_cast<size_t>(mCaps.maxDrawBuffers));
2620 Framebuffer *framebuffer = mDrawFramebuffer;
2621 // The default framebuffer may have fewer draw buffer states than a user-created one. The
2622 // user is always allowed to query up to GL_MAX_DRAWBUFFERS so just return GL_NONE here if
2623 // the draw buffer is out of range for this framebuffer.
2624 *params = drawBuffer < framebuffer->getDrawbufferStateCount()
2625 ? framebuffer->getDrawBufferState(drawBuffer)
2626 : GL_NONE;
2627 return angle::Result::Continue;
2628 }
2629
2630 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
2631 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
2632 // GetIntegerv as its native query function. As it would require conversion in any
2633 // case, this should make no difference to the calling application. You may find it in
2634 // State::getFloatv.
2635 switch (pname)
2636 {
2637 case GL_ARRAY_BUFFER_BINDING:
2638 *params = mBoundBuffers[BufferBinding::Array].id().value;
2639 break;
2640 case GL_DRAW_INDIRECT_BUFFER_BINDING:
2641 *params = mBoundBuffers[BufferBinding::DrawIndirect].id().value;
2642 break;
2643 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2644 {
2645 Buffer *elementArrayBuffer = getVertexArray()->getElementArrayBuffer();
2646 *params = elementArrayBuffer ? elementArrayBuffer->id().value : 0;
2647 break;
2648 }
2649 case GL_DRAW_FRAMEBUFFER_BINDING:
2650 static_assert(GL_DRAW_FRAMEBUFFER_BINDING == GL_DRAW_FRAMEBUFFER_BINDING_ANGLE,
2651 "Enum mismatch");
2652 *params = mDrawFramebuffer->id().value;
2653 break;
2654 case GL_READ_FRAMEBUFFER_BINDING:
2655 static_assert(GL_READ_FRAMEBUFFER_BINDING == GL_READ_FRAMEBUFFER_BINDING_ANGLE,
2656 "Enum mismatch");
2657 *params = mReadFramebuffer->id().value;
2658 break;
2659 case GL_RENDERBUFFER_BINDING:
2660 *params = mRenderbuffer.id().value;
2661 break;
2662 case GL_VERTEX_ARRAY_BINDING:
2663 *params = mVertexArray->id().value;
2664 break;
2665 case GL_CURRENT_PROGRAM:
2666 *params = mProgram ? mProgram->id().value : 0;
2667 break;
2668 case GL_PACK_ALIGNMENT:
2669 *params = mPack.alignment;
2670 break;
2671 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2672 *params = mPack.reverseRowOrder;
2673 break;
2674 case GL_PACK_ROW_LENGTH:
2675 *params = mPack.rowLength;
2676 break;
2677 case GL_PACK_SKIP_ROWS:
2678 *params = mPack.skipRows;
2679 break;
2680 case GL_PACK_SKIP_PIXELS:
2681 *params = mPack.skipPixels;
2682 break;
2683 case GL_UNPACK_ALIGNMENT:
2684 *params = mUnpack.alignment;
2685 break;
2686 case GL_UNPACK_ROW_LENGTH:
2687 *params = mUnpack.rowLength;
2688 break;
2689 case GL_UNPACK_IMAGE_HEIGHT:
2690 *params = mUnpack.imageHeight;
2691 break;
2692 case GL_UNPACK_SKIP_IMAGES:
2693 *params = mUnpack.skipImages;
2694 break;
2695 case GL_UNPACK_SKIP_ROWS:
2696 *params = mUnpack.skipRows;
2697 break;
2698 case GL_UNPACK_SKIP_PIXELS:
2699 *params = mUnpack.skipPixels;
2700 break;
2701 case GL_GENERATE_MIPMAP_HINT:
2702 *params = mGenerateMipmapHint;
2703 break;
2704 case GL_TEXTURE_FILTERING_HINT_CHROMIUM:
2705 *params = mTextureFilteringHint;
2706 break;
2707 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2708 *params = mFragmentShaderDerivativeHint;
2709 break;
2710 case GL_ACTIVE_TEXTURE:
2711 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
2712 break;
2713 case GL_STENCIL_FUNC:
2714 *params = mDepthStencil.stencilFunc;
2715 break;
2716 case GL_STENCIL_REF:
2717 *params = mStencilRef;
2718 break;
2719 case GL_STENCIL_VALUE_MASK:
2720 *params = CastMaskValue(mDepthStencil.stencilMask);
2721 break;
2722 case GL_STENCIL_BACK_FUNC:
2723 *params = mDepthStencil.stencilBackFunc;
2724 break;
2725 case GL_STENCIL_BACK_REF:
2726 *params = mStencilBackRef;
2727 break;
2728 case GL_STENCIL_BACK_VALUE_MASK:
2729 *params = CastMaskValue(mDepthStencil.stencilBackMask);
2730 break;
2731 case GL_STENCIL_FAIL:
2732 *params = mDepthStencil.stencilFail;
2733 break;
2734 case GL_STENCIL_PASS_DEPTH_FAIL:
2735 *params = mDepthStencil.stencilPassDepthFail;
2736 break;
2737 case GL_STENCIL_PASS_DEPTH_PASS:
2738 *params = mDepthStencil.stencilPassDepthPass;
2739 break;
2740 case GL_STENCIL_BACK_FAIL:
2741 *params = mDepthStencil.stencilBackFail;
2742 break;
2743 case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2744 *params = mDepthStencil.stencilBackPassDepthFail;
2745 break;
2746 case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2747 *params = mDepthStencil.stencilBackPassDepthPass;
2748 break;
2749 case GL_DEPTH_FUNC:
2750 *params = mDepthStencil.depthFunc;
2751 break;
2752 case GL_BLEND_SRC_RGB:
2753 // non-indexed get returns the state of draw buffer zero
2754 *params = mBlendStateExt.getSrcColorIndexed(0);
2755 break;
2756 case GL_BLEND_SRC_ALPHA:
2757 *params = mBlendStateExt.getSrcAlphaIndexed(0);
2758 break;
2759 case GL_BLEND_DST_RGB:
2760 *params = mBlendStateExt.getDstColorIndexed(0);
2761 break;
2762 case GL_BLEND_DST_ALPHA:
2763 *params = mBlendStateExt.getDstAlphaIndexed(0);
2764 break;
2765 case GL_BLEND_EQUATION_RGB:
2766 *params = mBlendStateExt.getEquationColorIndexed(0);
2767 break;
2768 case GL_BLEND_EQUATION_ALPHA:
2769 *params = mBlendStateExt.getEquationAlphaIndexed(0);
2770 break;
2771 case GL_STENCIL_WRITEMASK:
2772 *params = CastMaskValue(mDepthStencil.stencilWritemask);
2773 break;
2774 case GL_STENCIL_BACK_WRITEMASK:
2775 *params = CastMaskValue(mDepthStencil.stencilBackWritemask);
2776 break;
2777 case GL_STENCIL_CLEAR_VALUE:
2778 *params = mStencilClearValue;
2779 break;
2780 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2781 *params = mReadFramebuffer->getImplementationColorReadType(context);
2782 break;
2783 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2784 *params = mReadFramebuffer->getImplementationColorReadFormat(context);
2785 break;
2786 case GL_SAMPLE_BUFFERS:
2787 case GL_SAMPLES:
2788 {
2789 Framebuffer *framebuffer = mDrawFramebuffer;
2790 if (framebuffer->isComplete(context))
2791 {
2792 GLint samples = framebuffer->getSamples(context);
2793 switch (pname)
2794 {
2795 case GL_SAMPLE_BUFFERS:
2796 if (samples != 0)
2797 {
2798 *params = 1;
2799 }
2800 else
2801 {
2802 *params = 0;
2803 }
2804 break;
2805 case GL_SAMPLES:
2806 *params = samples;
2807 break;
2808 }
2809 }
2810 else
2811 {
2812 *params = 0;
2813 }
2814 }
2815 break;
2816 case GL_VIEWPORT:
2817 params[0] = mViewport.x;
2818 params[1] = mViewport.y;
2819 params[2] = mViewport.width;
2820 params[3] = mViewport.height;
2821 break;
2822 case GL_SCISSOR_BOX:
2823 params[0] = mScissor.x;
2824 params[1] = mScissor.y;
2825 params[2] = mScissor.width;
2826 params[3] = mScissor.height;
2827 break;
2828 case GL_CULL_FACE_MODE:
2829 *params = ToGLenum(mRasterizer.cullMode);
2830 break;
2831 case GL_FRONT_FACE:
2832 *params = mRasterizer.frontFace;
2833 break;
2834 case GL_RED_BITS:
2835 case GL_GREEN_BITS:
2836 case GL_BLUE_BITS:
2837 case GL_ALPHA_BITS:
2838 {
2839 Framebuffer *framebuffer = getDrawFramebuffer();
2840 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorAttachment();
2841
2842 if (colorbuffer)
2843 {
2844 switch (pname)
2845 {
2846 case GL_RED_BITS:
2847 *params = colorbuffer->getRedSize();
2848 break;
2849 case GL_GREEN_BITS:
2850 *params = colorbuffer->getGreenSize();
2851 break;
2852 case GL_BLUE_BITS:
2853 *params = colorbuffer->getBlueSize();
2854 break;
2855 case GL_ALPHA_BITS:
2856 *params = colorbuffer->getAlphaSize();
2857 break;
2858 }
2859 }
2860 else
2861 {
2862 *params = 0;
2863 }
2864 }
2865 break;
2866 case GL_DEPTH_BITS:
2867 {
2868 const Framebuffer *framebuffer = getDrawFramebuffer();
2869 const FramebufferAttachment *depthbuffer = framebuffer->getDepthAttachment();
2870
2871 if (depthbuffer)
2872 {
2873 *params = depthbuffer->getDepthSize();
2874 }
2875 else
2876 {
2877 *params = 0;
2878 }
2879 }
2880 break;
2881 case GL_STENCIL_BITS:
2882 {
2883 const Framebuffer *framebuffer = getDrawFramebuffer();
2884 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilAttachment();
2885
2886 if (stencilbuffer)
2887 {
2888 *params = stencilbuffer->getStencilSize();
2889 }
2890 else
2891 {
2892 *params = 0;
2893 }
2894 }
2895 break;
2896 case GL_TEXTURE_BINDING_2D:
2897 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2898 *params =
2899 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_2D)
2900 .value;
2901 break;
2902 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
2903 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2904 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2905 TextureType::Rectangle)
2906 .value;
2907 break;
2908 case GL_TEXTURE_BINDING_CUBE_MAP:
2909 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2910 *params =
2911 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::CubeMap)
2912 .value;
2913 break;
2914 case GL_TEXTURE_BINDING_3D:
2915 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2916 *params =
2917 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::_3D)
2918 .value;
2919 break;
2920 case GL_TEXTURE_BINDING_2D_ARRAY:
2921 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2922 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2923 TextureType::_2DArray)
2924 .value;
2925 break;
2926 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
2927 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2928 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2929 TextureType::_2DMultisample)
2930 .value;
2931 break;
2932 case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
2933 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2934 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2935 TextureType::_2DMultisampleArray)
2936 .value;
2937 break;
2938 case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
2939 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2940 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2941 TextureType::CubeMapArray)
2942 .value;
2943 break;
2944 case GL_TEXTURE_BINDING_EXTERNAL_OES:
2945 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2946 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2947 TextureType::External)
2948 .value;
2949 break;
2950
2951 // GL_OES_texture_buffer
2952 case GL_TEXTURE_BINDING_BUFFER:
2953 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2954 *params =
2955 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), TextureType::Buffer)
2956 .value;
2957 break;
2958 case GL_TEXTURE_BUFFER_BINDING:
2959 *params = mBoundBuffers[BufferBinding::Texture].id().value;
2960 break;
2961
2962 case GL_UNIFORM_BUFFER_BINDING:
2963 *params = mBoundBuffers[BufferBinding::Uniform].id().value;
2964 break;
2965 case GL_TRANSFORM_FEEDBACK_BINDING:
2966 *params = mTransformFeedback.id().value;
2967 break;
2968 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2969 *params = mBoundBuffers[BufferBinding::TransformFeedback].id().value;
2970 break;
2971 case GL_COPY_READ_BUFFER_BINDING:
2972 *params = mBoundBuffers[BufferBinding::CopyRead].id().value;
2973 break;
2974 case GL_COPY_WRITE_BUFFER_BINDING:
2975 *params = mBoundBuffers[BufferBinding::CopyWrite].id().value;
2976 break;
2977 case GL_PIXEL_PACK_BUFFER_BINDING:
2978 *params = mBoundBuffers[BufferBinding::PixelPack].id().value;
2979 break;
2980 case GL_PIXEL_UNPACK_BUFFER_BINDING:
2981 *params = mBoundBuffers[BufferBinding::PixelUnpack].id().value;
2982 break;
2983
2984 case GL_READ_BUFFER:
2985 *params = mReadFramebuffer->getReadBufferState();
2986 break;
2987 case GL_SAMPLER_BINDING:
2988 ASSERT(mActiveSampler < mCaps.maxCombinedTextureImageUnits);
2989 *params = getSamplerId(static_cast<GLuint>(mActiveSampler)).value;
2990 break;
2991 case GL_DEBUG_LOGGED_MESSAGES:
2992 *params = static_cast<GLint>(mDebug.getMessageCount());
2993 break;
2994 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2995 *params = static_cast<GLint>(mDebug.getNextMessageLength());
2996 break;
2997 case GL_DEBUG_GROUP_STACK_DEPTH:
2998 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2999 break;
3000 case GL_MULTISAMPLE_EXT:
3001 *params = static_cast<GLint>(mMultiSampling);
3002 break;
3003 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3004 *params = static_cast<GLint>(mSampleAlphaToOne);
3005 break;
3006 case GL_COVERAGE_MODULATION_CHROMIUM:
3007 *params = static_cast<GLint>(mCoverageModulation);
3008 break;
3009 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3010 *params = mBoundBuffers[BufferBinding::AtomicCounter].id().value;
3011 break;
3012 case GL_SHADER_STORAGE_BUFFER_BINDING:
3013 *params = mBoundBuffers[BufferBinding::ShaderStorage].id().value;
3014 break;
3015 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
3016 *params = mBoundBuffers[BufferBinding::DispatchIndirect].id().value;
3017 break;
3018 case GL_ALPHA_TEST_FUNC:
3019 *params = ToGLenum(mGLES1State.mAlphaTestFunc);
3020 break;
3021 case GL_CLIENT_ACTIVE_TEXTURE:
3022 *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
3023 break;
3024 case GL_MATRIX_MODE:
3025 *params = ToGLenum(mGLES1State.mMatrixMode);
3026 break;
3027 case GL_SHADE_MODEL:
3028 *params = ToGLenum(mGLES1State.mShadeModel);
3029 break;
3030 case GL_MODELVIEW_STACK_DEPTH:
3031 case GL_PROJECTION_STACK_DEPTH:
3032 case GL_TEXTURE_STACK_DEPTH:
3033 *params = mGLES1State.getCurrentMatrixStackDepth(pname);
3034 break;
3035 case GL_LOGIC_OP_MODE:
3036 *params = ToGLenum(mGLES1State.mLogicOp);
3037 break;
3038 case GL_BLEND_SRC:
3039 // non-indexed get returns the state of draw buffer zero
3040 *params = mBlendStateExt.getSrcColorIndexed(0);
3041 break;
3042 case GL_BLEND_DST:
3043 *params = mBlendStateExt.getDstColorIndexed(0);
3044 break;
3045 case GL_PERSPECTIVE_CORRECTION_HINT:
3046 case GL_POINT_SMOOTH_HINT:
3047 case GL_LINE_SMOOTH_HINT:
3048 case GL_FOG_HINT:
3049 *params = mGLES1State.getHint(pname);
3050 break;
3051
3052 // GL_ANGLE_provoking_vertex
3053 case GL_PROVOKING_VERTEX:
3054 *params = ToGLenum(mProvokingVertex);
3055 break;
3056
3057 case GL_PROGRAM_PIPELINE_BINDING:
3058 {
3059 ProgramPipeline *pipeline = getProgramPipeline();
3060 if (pipeline)
3061 {
3062 *params = pipeline->id().value;
3063 }
3064 else
3065 {
3066 *params = 0;
3067 }
3068 break;
3069 }
3070 case GL_PATCH_VERTICES:
3071 *params = mPatchVertices;
3072 break;
3073
3074 // GL_EXT_clip_control
3075 case GL_CLIP_ORIGIN_EXT:
3076 *params = mClipControlOrigin;
3077 break;
3078 case GL_CLIP_DEPTH_MODE_EXT:
3079 *params = mClipControlDepth;
3080 break;
3081 default:
3082 UNREACHABLE();
3083 break;
3084 }
3085
3086 return angle::Result::Continue;
3087 }
3088
getPointerv(const Context * context,GLenum pname,void ** params) const3089 void State::getPointerv(const Context *context, GLenum pname, void **params) const
3090 {
3091 switch (pname)
3092 {
3093 case GL_DEBUG_CALLBACK_FUNCTION:
3094 *params = reinterpret_cast<void *>(mDebug.getCallback());
3095 break;
3096 case GL_DEBUG_CALLBACK_USER_PARAM:
3097 *params = const_cast<void *>(mDebug.getUserParam());
3098 break;
3099 case GL_VERTEX_ARRAY_POINTER:
3100 case GL_NORMAL_ARRAY_POINTER:
3101 case GL_COLOR_ARRAY_POINTER:
3102 case GL_TEXTURE_COORD_ARRAY_POINTER:
3103 case GL_POINT_SIZE_ARRAY_POINTER_OES:
3104 QueryVertexAttribPointerv(getVertexArray()->getVertexAttribute(
3105 context->vertexArrayIndex(ParamToVertexArrayType(pname))),
3106 GL_VERTEX_ATTRIB_ARRAY_POINTER, params);
3107 return;
3108 default:
3109 UNREACHABLE();
3110 break;
3111 }
3112 }
3113
getIntegeri_v(GLenum target,GLuint index,GLint * data) const3114 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data) const
3115 {
3116 switch (target)
3117 {
3118 case GL_BLEND_SRC_RGB:
3119 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3120 *data = mBlendStateExt.getSrcColorIndexed(index);
3121 break;
3122 case GL_BLEND_SRC_ALPHA:
3123 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3124 *data = mBlendStateExt.getSrcAlphaIndexed(index);
3125 break;
3126 case GL_BLEND_DST_RGB:
3127 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3128 *data = mBlendStateExt.getDstColorIndexed(index);
3129 break;
3130 case GL_BLEND_DST_ALPHA:
3131 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3132 *data = mBlendStateExt.getDstAlphaIndexed(index);
3133 break;
3134 case GL_BLEND_EQUATION_RGB:
3135 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3136 *data = mBlendStateExt.getEquationColorIndexed(index);
3137 break;
3138 case GL_BLEND_EQUATION_ALPHA:
3139 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3140 *data = mBlendStateExt.getEquationAlphaIndexed(index);
3141 break;
3142 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3143 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3144 *data = mTransformFeedback->getIndexedBuffer(index).id().value;
3145 break;
3146 case GL_UNIFORM_BUFFER_BINDING:
3147 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3148 *data = mUniformBuffers[index].id().value;
3149 break;
3150 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3151 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3152 *data = mAtomicCounterBuffers[index].id().value;
3153 break;
3154 case GL_SHADER_STORAGE_BUFFER_BINDING:
3155 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3156 *data = mShaderStorageBuffers[index].id().value;
3157 break;
3158 case GL_VERTEX_BINDING_BUFFER:
3159 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3160 *data = mVertexArray->getVertexBinding(index).getBuffer().id().value;
3161 break;
3162 case GL_VERTEX_BINDING_DIVISOR:
3163 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3164 *data = mVertexArray->getVertexBinding(index).getDivisor();
3165 break;
3166 case GL_VERTEX_BINDING_OFFSET:
3167 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3168 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
3169 break;
3170 case GL_VERTEX_BINDING_STRIDE:
3171 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
3172 *data = mVertexArray->getVertexBinding(index).getStride();
3173 break;
3174 case GL_SAMPLE_MASK_VALUE:
3175 ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
3176 *data = mSampleMaskValues[index];
3177 break;
3178 case GL_IMAGE_BINDING_NAME:
3179 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3180 *data = mImageUnits[index].texture.id().value;
3181 break;
3182 case GL_IMAGE_BINDING_LEVEL:
3183 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3184 *data = mImageUnits[index].level;
3185 break;
3186 case GL_IMAGE_BINDING_LAYER:
3187 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3188 *data = mImageUnits[index].layer;
3189 break;
3190 case GL_IMAGE_BINDING_ACCESS:
3191 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3192 *data = mImageUnits[index].access;
3193 break;
3194 case GL_IMAGE_BINDING_FORMAT:
3195 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3196 *data = mImageUnits[index].format;
3197 break;
3198 default:
3199 UNREACHABLE();
3200 break;
3201 }
3202 }
3203
getInteger64i_v(GLenum target,GLuint index,GLint64 * data) const3204 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data) const
3205 {
3206 switch (target)
3207 {
3208 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
3209 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3210 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
3211 break;
3212 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
3213 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
3214 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
3215 break;
3216 case GL_UNIFORM_BUFFER_START:
3217 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3218 *data = mUniformBuffers[index].getOffset();
3219 break;
3220 case GL_UNIFORM_BUFFER_SIZE:
3221 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
3222 *data = mUniformBuffers[index].getSize();
3223 break;
3224 case GL_ATOMIC_COUNTER_BUFFER_START:
3225 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3226 *data = mAtomicCounterBuffers[index].getOffset();
3227 break;
3228 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
3229 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
3230 *data = mAtomicCounterBuffers[index].getSize();
3231 break;
3232 case GL_SHADER_STORAGE_BUFFER_START:
3233 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3234 *data = mShaderStorageBuffers[index].getOffset();
3235 break;
3236 case GL_SHADER_STORAGE_BUFFER_SIZE:
3237 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
3238 *data = mShaderStorageBuffers[index].getSize();
3239 break;
3240 default:
3241 UNREACHABLE();
3242 break;
3243 }
3244 }
3245
getBooleani_v(GLenum target,GLuint index,GLboolean * data) const3246 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data) const
3247 {
3248 switch (target)
3249 {
3250 case GL_COLOR_WRITEMASK:
3251 {
3252 ASSERT(static_cast<size_t>(index) < mBlendStateExt.mMaxDrawBuffers);
3253 bool r, g, b, a;
3254 mBlendStateExt.getColorMaskIndexed(index, &r, &g, &b, &a);
3255 data[0] = r;
3256 data[1] = g;
3257 data[2] = b;
3258 data[3] = a;
3259 break;
3260 }
3261 case GL_IMAGE_BINDING_LAYERED:
3262 ASSERT(static_cast<size_t>(index) < mImageUnits.size());
3263 *data = mImageUnits[index].layered;
3264 break;
3265 default:
3266 UNREACHABLE();
3267 break;
3268 }
3269 }
3270
3271 // TODO(http://anglebug.com/3889): Remove this helper function after blink and chromium part
3272 // refactor done.
getTextureForActiveSampler(TextureType type,size_t index)3273 Texture *State::getTextureForActiveSampler(TextureType type, size_t index)
3274 {
3275 if (type != TextureType::VideoImage)
3276 {
3277 return mSamplerTextures[type][index].get();
3278 }
3279
3280 ASSERT(type == TextureType::VideoImage);
3281
3282 Texture *candidateTexture = mSamplerTextures[type][index].get();
3283 if (candidateTexture->getWidth(TextureTarget::VideoImage, 0) == 0 ||
3284 candidateTexture->getHeight(TextureTarget::VideoImage, 0) == 0 ||
3285 candidateTexture->getDepth(TextureTarget::VideoImage, 0) == 0)
3286 {
3287 return mSamplerTextures[TextureType::_2D][index].get();
3288 }
3289
3290 return mSamplerTextures[type][index].get();
3291 }
3292
syncActiveTextures(const Context * context,Command command)3293 angle::Result State::syncActiveTextures(const Context *context, Command command)
3294 {
3295 if (mDirtyActiveTextures.none())
3296 {
3297 return angle::Result::Continue;
3298 }
3299
3300 for (size_t textureUnit : mDirtyActiveTextures)
3301 {
3302 if (mExecutable)
3303 {
3304 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3305 Texture *activeTexture = (type != TextureType::InvalidEnum)
3306 ? getTextureForActiveSampler(type, textureUnit)
3307 : nullptr;
3308 const Sampler *sampler = mSamplers[textureUnit].get();
3309
3310 updateActiveTextureStateOnSync(context, textureUnit, sampler, activeTexture);
3311 }
3312 }
3313
3314 mDirtyActiveTextures.reset();
3315 return angle::Result::Continue;
3316 }
3317
syncTexturesInit(const Context * context,Command command)3318 angle::Result State::syncTexturesInit(const Context *context, Command command)
3319 {
3320 ASSERT(mRobustResourceInit);
3321
3322 if (!mProgram)
3323 return angle::Result::Continue;
3324
3325 for (size_t textureUnitIndex : mExecutable->getActiveSamplersMask())
3326 {
3327 Texture *texture = mActiveTexturesCache[textureUnitIndex];
3328 if (texture)
3329 {
3330 ANGLE_TRY(texture->ensureInitialized(context));
3331 }
3332 }
3333 return angle::Result::Continue;
3334 }
3335
syncImagesInit(const Context * context,Command command)3336 angle::Result State::syncImagesInit(const Context *context, Command command)
3337 {
3338 ASSERT(mRobustResourceInit);
3339 ASSERT(mExecutable);
3340 for (size_t imageUnitIndex : mExecutable->getActiveImagesMask())
3341 {
3342 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3343 if (texture)
3344 {
3345 ANGLE_TRY(texture->ensureInitialized(context));
3346 }
3347 }
3348 return angle::Result::Continue;
3349 }
3350
syncReadAttachments(const Context * context,Command command)3351 angle::Result State::syncReadAttachments(const Context *context, Command command)
3352 {
3353 ASSERT(mReadFramebuffer);
3354 ASSERT(mRobustResourceInit);
3355 return mReadFramebuffer->ensureReadAttachmentsInitialized(context);
3356 }
3357
syncDrawAttachments(const Context * context,Command command)3358 angle::Result State::syncDrawAttachments(const Context *context, Command command)
3359 {
3360 ASSERT(mDrawFramebuffer);
3361 ASSERT(mRobustResourceInit);
3362 return mDrawFramebuffer->ensureDrawAttachmentsInitialized(context);
3363 }
3364
syncReadFramebuffer(const Context * context,Command command)3365 angle::Result State::syncReadFramebuffer(const Context *context, Command command)
3366 {
3367 ASSERT(mReadFramebuffer);
3368 return mReadFramebuffer->syncState(context, GL_READ_FRAMEBUFFER, command);
3369 }
3370
syncDrawFramebuffer(const Context * context,Command command)3371 angle::Result State::syncDrawFramebuffer(const Context *context, Command command)
3372 {
3373 ASSERT(mDrawFramebuffer);
3374 mDrawFramebuffer->setWriteControlMode(context->getState().getFramebufferSRGB()
3375 ? SrgbWriteControlMode::Default
3376 : SrgbWriteControlMode::Linear);
3377 return mDrawFramebuffer->syncState(context, GL_DRAW_FRAMEBUFFER, command);
3378 }
3379
syncTextures(const Context * context,Command command)3380 angle::Result State::syncTextures(const Context *context, Command command)
3381 {
3382 if (mDirtyTextures.none())
3383 return angle::Result::Continue;
3384
3385 for (size_t textureIndex : mDirtyTextures)
3386 {
3387 Texture *texture = mActiveTexturesCache[textureIndex];
3388 if (texture && texture->hasAnyDirtyBit())
3389 {
3390 ANGLE_TRY(texture->syncState(context, Command::Other));
3391 }
3392 }
3393
3394 mDirtyTextures.reset();
3395 return angle::Result::Continue;
3396 }
3397
syncImages(const Context * context,Command command)3398 angle::Result State::syncImages(const Context *context, Command command)
3399 {
3400 if (mDirtyImages.none())
3401 return angle::Result::Continue;
3402
3403 for (size_t imageUnitIndex : mDirtyImages)
3404 {
3405 Texture *texture = mImageUnits[imageUnitIndex].texture.get();
3406 if (texture && texture->hasAnyDirtyBit())
3407 {
3408 ANGLE_TRY(texture->syncState(context, Command::Other));
3409 }
3410 }
3411
3412 mDirtyImages.reset();
3413 return angle::Result::Continue;
3414 }
3415
syncSamplers(const Context * context,Command command)3416 angle::Result State::syncSamplers(const Context *context, Command command)
3417 {
3418 if (mDirtySamplers.none())
3419 return angle::Result::Continue;
3420
3421 for (size_t samplerIndex : mDirtySamplers)
3422 {
3423 BindingPointer<Sampler> &sampler = mSamplers[samplerIndex];
3424 if (sampler.get() && sampler->isDirty())
3425 {
3426 ANGLE_TRY(sampler->syncState(context));
3427 }
3428 }
3429
3430 mDirtySamplers.reset();
3431
3432 return angle::Result::Continue;
3433 }
3434
syncVertexArray(const Context * context,Command command)3435 angle::Result State::syncVertexArray(const Context *context, Command command)
3436 {
3437 ASSERT(mVertexArray);
3438 return mVertexArray->syncState(context);
3439 }
3440
syncProgram(const Context * context,Command command)3441 angle::Result State::syncProgram(const Context *context, Command command)
3442 {
3443 // There may not be a program if the calling application only uses program pipelines.
3444 if (mProgram)
3445 {
3446 return mProgram->syncState(context);
3447 }
3448 return angle::Result::Continue;
3449 }
3450
syncDirtyObject(const Context * context,GLenum target)3451 angle::Result State::syncDirtyObject(const Context *context, GLenum target)
3452 {
3453 DirtyObjects localSet;
3454
3455 switch (target)
3456 {
3457 case GL_READ_FRAMEBUFFER:
3458 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3459 break;
3460 case GL_DRAW_FRAMEBUFFER:
3461 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3462 break;
3463 case GL_FRAMEBUFFER:
3464 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3465 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
3466 break;
3467 case GL_VERTEX_ARRAY:
3468 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
3469 break;
3470 case GL_TEXTURE:
3471 localSet.set(DIRTY_OBJECT_TEXTURES);
3472 break;
3473 case GL_SAMPLER:
3474 localSet.set(DIRTY_OBJECT_SAMPLERS);
3475 break;
3476 case GL_PROGRAM:
3477 localSet.set(DIRTY_OBJECT_PROGRAM);
3478 break;
3479 }
3480
3481 return syncDirtyObjects(context, localSet, Command::Other);
3482 }
3483
setObjectDirty(GLenum target)3484 void State::setObjectDirty(GLenum target)
3485 {
3486 switch (target)
3487 {
3488 case GL_READ_FRAMEBUFFER:
3489 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3490 break;
3491 case GL_DRAW_FRAMEBUFFER:
3492 setDrawFramebufferDirty();
3493 break;
3494 case GL_FRAMEBUFFER:
3495 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
3496 setDrawFramebufferDirty();
3497 break;
3498 case GL_VERTEX_ARRAY:
3499 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
3500 break;
3501 case GL_PROGRAM:
3502 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3503 break;
3504 default:
3505 break;
3506 }
3507 }
3508
onProgramExecutableChange(const Context * context,Program * program)3509 angle::Result State::onProgramExecutableChange(const Context *context, Program *program)
3510 {
3511 // OpenGL Spec:
3512 // "If LinkProgram or ProgramBinary successfully re-links a program object
3513 // that was already in use as a result of a previous call to UseProgram, then the
3514 // generated executable code will be installed as part of the current rendering state."
3515 ASSERT(program->isLinked());
3516
3517 // If this Program is currently active, we need to update the State's pointer to the current
3518 // ProgramExecutable if we just changed it.
3519 if (mProgram == program)
3520 {
3521 mExecutable = &program->getExecutable();
3522 }
3523
3524 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3525
3526 if (program->hasAnyDirtyBit())
3527 {
3528 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
3529 }
3530
3531 // Set any bound textures.
3532 const ProgramExecutable &executable = program->getExecutable();
3533 const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3534 for (size_t textureIndex : executable.getActiveSamplersMask())
3535 {
3536 TextureType type = textureTypes[textureIndex];
3537
3538 // This can happen if there is a conflicting texture type.
3539 if (type == TextureType::InvalidEnum)
3540 continue;
3541
3542 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3543 updateTextureBinding(context, textureIndex, texture);
3544 }
3545
3546 for (size_t imageUnitIndex : executable.getActiveImagesMask())
3547 {
3548 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3549 if (!image)
3550 continue;
3551
3552 if (image->hasAnyDirtyBit())
3553 {
3554 ANGLE_TRY(image->syncState(context, Command::Other));
3555 }
3556
3557 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3558 {
3559 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3560 }
3561 }
3562
3563 return angle::Result::Continue;
3564 }
3565
onProgramPipelineExecutableChange(const Context * context)3566 angle::Result State::onProgramPipelineExecutableChange(const Context *context)
3567 {
3568 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
3569
3570 // Set any bound textures.
3571 const ProgramExecutable &executable = mProgramPipeline->getExecutable();
3572 const ActiveTextureTypeArray &textureTypes = executable.getActiveSamplerTypes();
3573
3574 for (size_t textureIndex : executable.getActiveSamplersMask())
3575 {
3576 TextureType type = textureTypes[textureIndex];
3577
3578 // This can happen if there is a conflicting texture type.
3579 if (type == TextureType::InvalidEnum)
3580 continue;
3581
3582 Texture *texture = getTextureForActiveSampler(type, textureIndex);
3583 updateTextureBinding(context, textureIndex, texture);
3584 }
3585
3586 for (size_t imageUnitIndex : executable.getActiveImagesMask())
3587 {
3588 Texture *image = mImageUnits[imageUnitIndex].texture.get();
3589 if (!image)
3590 continue;
3591
3592 if (image->hasAnyDirtyBit())
3593 {
3594 ANGLE_TRY(image->syncState(context, Command::Other));
3595 }
3596
3597 if (mRobustResourceInit && image->initState() == InitState::MayNeedInit)
3598 {
3599 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3600 }
3601 }
3602
3603 return angle::Result::Continue;
3604 }
3605
setTextureDirty(size_t textureUnitIndex)3606 void State::setTextureDirty(size_t textureUnitIndex)
3607 {
3608 mDirtyObjects.set(DIRTY_OBJECT_TEXTURES);
3609 mDirtyTextures.set(textureUnitIndex);
3610 }
3611
setSamplerDirty(size_t samplerIndex)3612 void State::setSamplerDirty(size_t samplerIndex)
3613 {
3614 mDirtyObjects.set(DIRTY_OBJECT_SAMPLERS);
3615 mDirtySamplers.set(samplerIndex);
3616 }
3617
setImageUnit(const Context * context,size_t unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)3618 void State::setImageUnit(const Context *context,
3619 size_t unit,
3620 Texture *texture,
3621 GLint level,
3622 GLboolean layered,
3623 GLint layer,
3624 GLenum access,
3625 GLenum format)
3626 {
3627 ASSERT(!mImageUnits.empty());
3628
3629 ImageUnit &imageUnit = mImageUnits[unit];
3630
3631 if (texture)
3632 {
3633 texture->onBindAsImageTexture();
3634 }
3635 imageUnit.texture.set(context, texture);
3636 imageUnit.level = level;
3637 imageUnit.layered = layered;
3638 imageUnit.layer = layer;
3639 imageUnit.access = access;
3640 imageUnit.format = format;
3641 mDirtyBits.set(DIRTY_BIT_IMAGE_BINDINGS);
3642
3643 onImageStateChange(context, unit);
3644 }
3645
3646 // Handle a dirty texture event.
onActiveTextureChange(const Context * context,size_t textureUnit)3647 void State::onActiveTextureChange(const Context *context, size_t textureUnit)
3648 {
3649 if (mExecutable)
3650 {
3651 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3652 Texture *activeTexture = (type != TextureType::InvalidEnum)
3653 ? getTextureForActiveSampler(type, textureUnit)
3654 : nullptr;
3655 updateTextureBinding(context, textureUnit, activeTexture);
3656
3657 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3658 }
3659 }
3660
onActiveTextureStateChange(const Context * context,size_t textureUnit)3661 void State::onActiveTextureStateChange(const Context *context, size_t textureUnit)
3662 {
3663 if (mExecutable)
3664 {
3665 TextureType type = mExecutable->getActiveSamplerTypes()[textureUnit];
3666 Texture *activeTexture = (type != TextureType::InvalidEnum)
3667 ? getTextureForActiveSampler(type, textureUnit)
3668 : nullptr;
3669 setActiveTextureDirty(textureUnit, activeTexture);
3670 }
3671 }
3672
onImageStateChange(const Context * context,size_t unit)3673 void State::onImageStateChange(const Context *context, size_t unit)
3674 {
3675 if (mExecutable)
3676 {
3677 const ImageUnit &image = mImageUnits[unit];
3678
3679 // Have nothing to do here if no texture bound
3680 if (!image.texture.get())
3681 return;
3682
3683 if (image.texture->hasAnyDirtyBit())
3684 {
3685 mDirtyImages.set(unit);
3686 mDirtyObjects.set(DIRTY_OBJECT_IMAGES);
3687 }
3688
3689 if (mRobustResourceInit && image.texture->initState() == InitState::MayNeedInit)
3690 {
3691 mDirtyObjects.set(DIRTY_OBJECT_IMAGES_INIT);
3692 }
3693
3694 mExecutable->onStateChange(angle::SubjectMessage::ProgramTextureOrImageBindingChanged);
3695 }
3696 }
3697
onUniformBufferStateChange(size_t uniformBufferIndex)3698 void State::onUniformBufferStateChange(size_t uniformBufferIndex)
3699 {
3700 // This could be represented by a different dirty bit. Using the same one keeps it simple.
3701 mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
3702 }
3703
onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)3704 void State::onAtomicCounterBufferStateChange(size_t atomicCounterBufferIndex)
3705 {
3706 mDirtyBits.set(DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
3707 }
3708
onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)3709 void State::onShaderStorageBufferStateChange(size_t shaderStorageBufferIndex)
3710 {
3711 mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
3712 }
3713
getAndResetDirtyCurrentValues() const3714 AttributesMask State::getAndResetDirtyCurrentValues() const
3715 {
3716 AttributesMask retVal = mDirtyCurrentValues;
3717 mDirtyCurrentValues.reset();
3718 return retVal;
3719 }
3720
getAndResetExtendedDirtyBits() const3721 State::ExtendedDirtyBits State::getAndResetExtendedDirtyBits() const
3722 {
3723 ExtendedDirtyBits retVal = mExtendedDirtyBits;
3724 mExtendedDirtyBits.reset();
3725 return retVal;
3726 }
3727
initializeForCapture(const Context * context)3728 void State::initializeForCapture(const Context *context)
3729 {
3730 mCaps = context->getCaps();
3731 mExtensions = context->getExtensions();
3732
3733 // This little kludge gets around the frame capture "constness". It should be safe because
3734 // nothing in the context is modified in a non-compatible way during capture.
3735 Context *mutableContext = const_cast<Context *>(context);
3736 initialize(mutableContext);
3737 }
3738
3739 constexpr State::DirtyObjectHandler State::kDirtyObjectHandlers[DIRTY_OBJECT_MAX];
3740
3741 } // namespace gl
3742