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