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