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