1 //
2 // Copyright (c) 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 <limits>
12 #include <string.h>
13 
14 #include "common/bitset_utils.h"
15 #include "common/mathutil.h"
16 #include "common/matrix_utils.h"
17 #include "libANGLE/Caps.h"
18 #include "libANGLE/Context.h"
19 #include "libANGLE/Debug.h"
20 #include "libANGLE/Framebuffer.h"
21 #include "libANGLE/FramebufferAttachment.h"
22 #include "libANGLE/Query.h"
23 #include "libANGLE/VertexArray.h"
24 #include "libANGLE/formatutils.h"
25 #include "libANGLE/queryconversions.h"
26 #include "libANGLE/renderer/ContextImpl.h"
27 
28 namespace
29 {
30 
ActiveQueryType(const GLenum type)31 GLenum ActiveQueryType(const GLenum type)
32 {
33     return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
34 }
35 
36 }  // anonymous namepace
37 
38 namespace gl
39 {
40 
State()41 State::State()
42     : mMaxDrawBuffers(0),
43       mMaxCombinedTextureImageUnits(0),
44       mDepthClearValue(0),
45       mStencilClearValue(0),
46       mScissorTest(false),
47       mSampleCoverage(false),
48       mSampleCoverageValue(0),
49       mSampleCoverageInvert(false),
50       mSampleMask(false),
51       mMaxSampleMaskWords(0),
52       mStencilRef(0),
53       mStencilBackRef(0),
54       mLineWidth(0),
55       mGenerateMipmapHint(GL_NONE),
56       mFragmentShaderDerivativeHint(GL_NONE),
57       mBindGeneratesResource(true),
58       mClientArraysEnabled(true),
59       mNearZ(0),
60       mFarZ(0),
61       mReadFramebuffer(nullptr),
62       mDrawFramebuffer(nullptr),
63       mProgram(nullptr),
64       mVertexArray(nullptr),
65       mActiveSampler(0),
66       mPrimitiveRestart(false),
67       mMultiSampling(false),
68       mSampleAlphaToOne(false),
69       mFramebufferSRGB(true),
70       mRobustResourceInit(false),
71       mProgramBinaryCacheEnabled(false)
72 {
73 }
74 
~State()75 State::~State()
76 {
77 }
78 
initialize(const Context * context,bool debug,bool bindGeneratesResource,bool clientArraysEnabled,bool robustResourceInit,bool programBinaryCacheEnabled)79 void State::initialize(const Context *context,
80                        bool debug,
81                        bool bindGeneratesResource,
82                        bool clientArraysEnabled,
83                        bool robustResourceInit,
84                        bool programBinaryCacheEnabled)
85 {
86     const Caps &caps             = context->getCaps();
87     const Extensions &extensions = context->getExtensions();
88     const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
89     const Version &clientVersion = context->getClientVersion();
90 
91     mMaxDrawBuffers = caps.maxDrawBuffers;
92     mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
93 
94     setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
95 
96     mDepthClearValue = 1.0f;
97     mStencilClearValue = 0;
98 
99     mScissorTest = false;
100     mScissor.x = 0;
101     mScissor.y = 0;
102     mScissor.width = 0;
103     mScissor.height = 0;
104 
105     mBlendColor.red = 0;
106     mBlendColor.green = 0;
107     mBlendColor.blue = 0;
108     mBlendColor.alpha = 0;
109 
110     mStencilRef = 0;
111     mStencilBackRef = 0;
112 
113     mSampleCoverage = false;
114     mSampleCoverageValue = 1.0f;
115     mSampleCoverageInvert = false;
116 
117     mMaxSampleMaskWords = caps.maxSampleMaskWords;
118     mSampleMask         = false;
119     mSampleMaskValues.fill(~GLbitfield(0));
120 
121     mGenerateMipmapHint = GL_DONT_CARE;
122     mFragmentShaderDerivativeHint = GL_DONT_CARE;
123 
124     mBindGeneratesResource = bindGeneratesResource;
125     mClientArraysEnabled   = clientArraysEnabled;
126 
127     mLineWidth = 1.0f;
128 
129     mViewport.x = 0;
130     mViewport.y = 0;
131     mViewport.width = 0;
132     mViewport.height = 0;
133     mNearZ = 0.0f;
134     mFarZ = 1.0f;
135 
136     mBlend.colorMaskRed = true;
137     mBlend.colorMaskGreen = true;
138     mBlend.colorMaskBlue = true;
139     mBlend.colorMaskAlpha = true;
140 
141     mActiveSampler = 0;
142 
143     mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
144 
145     mUniformBuffers.resize(caps.maxUniformBufferBindings);
146 
147     mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
148     mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
149     if (clientVersion >= Version(3, 0))
150     {
151         // TODO: These could also be enabled via extension
152         mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
153         mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
154     }
155     if (clientVersion >= Version(3, 1))
156     {
157         mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
158 
159         mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
160         mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
161         mImageUnits.resize(caps.maxImageUnits);
162     }
163     if (nativeExtensions.textureRectangle)
164     {
165         mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
166     }
167     if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
168     {
169         mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
170     }
171     mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
172     mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
173     mCachedTexturesInitState = InitState::MayNeedInit;
174     for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
175          ++textureIndex)
176     {
177         mCompleteTextureBindings.emplace_back(OnAttachmentDirtyBinding(this, textureIndex));
178     }
179 
180     mSamplers.resize(caps.maxCombinedTextureImageUnits);
181 
182     mActiveQueries[GL_ANY_SAMPLES_PASSED].set(context, nullptr);
183     mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(context, nullptr);
184     mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(context, nullptr);
185     mActiveQueries[GL_TIME_ELAPSED_EXT].set(context, nullptr);
186     mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(context, nullptr);
187 
188     mProgram = nullptr;
189 
190     mReadFramebuffer = nullptr;
191     mDrawFramebuffer = nullptr;
192 
193     mPrimitiveRestart = false;
194 
195     mDebug.setOutputEnabled(debug);
196     mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
197 
198     mMultiSampling    = true;
199     mSampleAlphaToOne = false;
200 
201     mCoverageModulation = GL_NONE;
202 
203     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
204     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
205     mPathStencilFunc = GL_ALWAYS;
206     mPathStencilRef  = 0;
207     mPathStencilMask = std::numeric_limits<GLuint>::max();
208 
209     mRobustResourceInit = robustResourceInit;
210     mProgramBinaryCacheEnabled = programBinaryCacheEnabled;
211 }
212 
reset(const Context * context)213 void State::reset(const Context *context)
214 {
215     for (auto &bindingVec : mSamplerTextures)
216     {
217         TextureBindingVector &textureVector = bindingVec.second;
218         for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
219         {
220             textureVector[textureIdx].set(context, nullptr);
221         }
222     }
223     for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
224     {
225         mSamplers[samplerIdx].set(context, nullptr);
226     }
227 
228     for (auto &imageUnit : mImageUnits)
229     {
230         imageUnit.texture.set(context, nullptr);
231         imageUnit.level   = 0;
232         imageUnit.layered = false;
233         imageUnit.layer   = 0;
234         imageUnit.access  = GL_READ_ONLY;
235         imageUnit.format  = GL_R32UI;
236     }
237 
238     mRenderbuffer.set(context, nullptr);
239 
240     for (auto type : angle::AllEnums<BufferBinding>())
241     {
242         mBoundBuffers[type].set(context, nullptr);
243     }
244 
245     if (mProgram)
246     {
247         mProgram->release(context);
248     }
249     mProgram = nullptr;
250 
251     mProgramPipeline.set(context, nullptr);
252 
253     mTransformFeedback.set(context, nullptr);
254 
255     for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
256     {
257         i->second.set(context, nullptr);
258     }
259 
260     for (auto &buf : mUniformBuffers)
261     {
262         buf.set(context, nullptr);
263     }
264 
265     for (auto &buf : mAtomicCounterBuffers)
266     {
267         buf.set(context, nullptr);
268     }
269 
270     for (auto &buf : mShaderStorageBuffers)
271     {
272         buf.set(context, nullptr);
273     }
274 
275     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
276     angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
277     mPathStencilFunc = GL_ALWAYS;
278     mPathStencilRef  = 0;
279     mPathStencilMask = std::numeric_limits<GLuint>::max();
280 
281     // TODO(jmadill): Is this necessary?
282     setAllDirtyBits();
283 }
284 
getRasterizerState() const285 const RasterizerState &State::getRasterizerState() const
286 {
287     return mRasterizer;
288 }
289 
getBlendState() const290 const BlendState &State::getBlendState() const
291 {
292     return mBlend;
293 }
294 
getDepthStencilState() const295 const DepthStencilState &State::getDepthStencilState() const
296 {
297     return mDepthStencil;
298 }
299 
setColorClearValue(float red,float green,float blue,float alpha)300 void State::setColorClearValue(float red, float green, float blue, float alpha)
301 {
302     mColorClearValue.red = red;
303     mColorClearValue.green = green;
304     mColorClearValue.blue = blue;
305     mColorClearValue.alpha = alpha;
306     mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
307 }
308 
setDepthClearValue(float depth)309 void State::setDepthClearValue(float depth)
310 {
311     mDepthClearValue = depth;
312     mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
313 }
314 
setStencilClearValue(int stencil)315 void State::setStencilClearValue(int stencil)
316 {
317     mStencilClearValue = stencil;
318     mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
319 }
320 
setColorMask(bool red,bool green,bool blue,bool alpha)321 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
322 {
323     mBlend.colorMaskRed = red;
324     mBlend.colorMaskGreen = green;
325     mBlend.colorMaskBlue = blue;
326     mBlend.colorMaskAlpha = alpha;
327     mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
328 }
329 
setDepthMask(bool mask)330 void State::setDepthMask(bool mask)
331 {
332     mDepthStencil.depthMask = mask;
333     mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
334 }
335 
isRasterizerDiscardEnabled() const336 bool State::isRasterizerDiscardEnabled() const
337 {
338     return mRasterizer.rasterizerDiscard;
339 }
340 
setRasterizerDiscard(bool enabled)341 void State::setRasterizerDiscard(bool enabled)
342 {
343     mRasterizer.rasterizerDiscard = enabled;
344     mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
345 }
346 
isCullFaceEnabled() const347 bool State::isCullFaceEnabled() const
348 {
349     return mRasterizer.cullFace;
350 }
351 
setCullFace(bool enabled)352 void State::setCullFace(bool enabled)
353 {
354     mRasterizer.cullFace = enabled;
355     mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
356 }
357 
setCullMode(CullFaceMode mode)358 void State::setCullMode(CullFaceMode mode)
359 {
360     mRasterizer.cullMode = mode;
361     mDirtyBits.set(DIRTY_BIT_CULL_FACE);
362 }
363 
setFrontFace(GLenum front)364 void State::setFrontFace(GLenum front)
365 {
366     mRasterizer.frontFace = front;
367     mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
368 }
369 
isDepthTestEnabled() const370 bool State::isDepthTestEnabled() const
371 {
372     return mDepthStencil.depthTest;
373 }
374 
setDepthTest(bool enabled)375 void State::setDepthTest(bool enabled)
376 {
377     mDepthStencil.depthTest = enabled;
378     mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
379 }
380 
setDepthFunc(GLenum depthFunc)381 void State::setDepthFunc(GLenum depthFunc)
382 {
383      mDepthStencil.depthFunc = depthFunc;
384      mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
385 }
386 
setDepthRange(float zNear,float zFar)387 void State::setDepthRange(float zNear, float zFar)
388 {
389     mNearZ = zNear;
390     mFarZ = zFar;
391     mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
392 }
393 
getNearPlane() const394 float State::getNearPlane() const
395 {
396     return mNearZ;
397 }
398 
getFarPlane() const399 float State::getFarPlane() const
400 {
401     return mFarZ;
402 }
403 
isBlendEnabled() const404 bool State::isBlendEnabled() const
405 {
406     return mBlend.blend;
407 }
408 
setBlend(bool enabled)409 void State::setBlend(bool enabled)
410 {
411     mBlend.blend = enabled;
412     mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
413 }
414 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)415 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
416 {
417     mBlend.sourceBlendRGB = sourceRGB;
418     mBlend.destBlendRGB = destRGB;
419     mBlend.sourceBlendAlpha = sourceAlpha;
420     mBlend.destBlendAlpha = destAlpha;
421     mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
422 }
423 
setBlendColor(float red,float green,float blue,float alpha)424 void State::setBlendColor(float red, float green, float blue, float alpha)
425 {
426     mBlendColor.red = red;
427     mBlendColor.green = green;
428     mBlendColor.blue = blue;
429     mBlendColor.alpha = alpha;
430     mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
431 }
432 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)433 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
434 {
435     mBlend.blendEquationRGB = rgbEquation;
436     mBlend.blendEquationAlpha = alphaEquation;
437     mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
438 }
439 
getBlendColor() const440 const ColorF &State::getBlendColor() const
441 {
442     return mBlendColor;
443 }
444 
isStencilTestEnabled() const445 bool State::isStencilTestEnabled() const
446 {
447     return mDepthStencil.stencilTest;
448 }
449 
setStencilTest(bool enabled)450 void State::setStencilTest(bool enabled)
451 {
452     mDepthStencil.stencilTest = enabled;
453     mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
454 }
455 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)456 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
457 {
458     mDepthStencil.stencilFunc = stencilFunc;
459     mStencilRef = (stencilRef > 0) ? stencilRef : 0;
460     mDepthStencil.stencilMask = stencilMask;
461     mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
462 }
463 
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)464 void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
465 {
466     mDepthStencil.stencilBackFunc = stencilBackFunc;
467     mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
468     mDepthStencil.stencilBackMask = stencilBackMask;
469     mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
470 }
471 
setStencilWritemask(GLuint stencilWritemask)472 void State::setStencilWritemask(GLuint stencilWritemask)
473 {
474     mDepthStencil.stencilWritemask = stencilWritemask;
475     mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
476 }
477 
setStencilBackWritemask(GLuint stencilBackWritemask)478 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
479 {
480     mDepthStencil.stencilBackWritemask = stencilBackWritemask;
481     mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
482 }
483 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)484 void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
485 {
486     mDepthStencil.stencilFail = stencilFail;
487     mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
488     mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
489     mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
490 }
491 
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)492 void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
493 {
494     mDepthStencil.stencilBackFail = stencilBackFail;
495     mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
496     mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
497     mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
498 }
499 
getStencilRef() const500 GLint State::getStencilRef() const
501 {
502     return mStencilRef;
503 }
504 
getStencilBackRef() const505 GLint State::getStencilBackRef() const
506 {
507     return mStencilBackRef;
508 }
509 
isPolygonOffsetFillEnabled() const510 bool State::isPolygonOffsetFillEnabled() const
511 {
512     return mRasterizer.polygonOffsetFill;
513 }
514 
setPolygonOffsetFill(bool enabled)515 void State::setPolygonOffsetFill(bool enabled)
516 {
517     mRasterizer.polygonOffsetFill = enabled;
518     mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
519 }
520 
setPolygonOffsetParams(GLfloat factor,GLfloat units)521 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
522 {
523     // An application can pass NaN values here, so handle this gracefully
524     mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
525     mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
526     mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
527 }
528 
isSampleAlphaToCoverageEnabled() const529 bool State::isSampleAlphaToCoverageEnabled() const
530 {
531     return mBlend.sampleAlphaToCoverage;
532 }
533 
setSampleAlphaToCoverage(bool enabled)534 void State::setSampleAlphaToCoverage(bool enabled)
535 {
536     mBlend.sampleAlphaToCoverage = enabled;
537     mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
538 }
539 
isSampleCoverageEnabled() const540 bool State::isSampleCoverageEnabled() const
541 {
542     return mSampleCoverage;
543 }
544 
setSampleCoverage(bool enabled)545 void State::setSampleCoverage(bool enabled)
546 {
547     mSampleCoverage = enabled;
548     mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
549 }
550 
setSampleCoverageParams(GLclampf value,bool invert)551 void State::setSampleCoverageParams(GLclampf value, bool invert)
552 {
553     mSampleCoverageValue = value;
554     mSampleCoverageInvert = invert;
555     mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
556 }
557 
getSampleCoverageValue() const558 GLclampf State::getSampleCoverageValue() const
559 {
560     return mSampleCoverageValue;
561 }
562 
getSampleCoverageInvert() const563 bool State::getSampleCoverageInvert() const
564 {
565     return mSampleCoverageInvert;
566 }
567 
isSampleMaskEnabled() const568 bool State::isSampleMaskEnabled() const
569 {
570     return mSampleMask;
571 }
572 
setSampleMaskEnabled(bool enabled)573 void State::setSampleMaskEnabled(bool enabled)
574 {
575     mSampleMask = enabled;
576     mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
577 }
578 
setSampleMaskParams(GLuint maskNumber,GLbitfield mask)579 void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
580 {
581     ASSERT(maskNumber < mMaxSampleMaskWords);
582     mSampleMaskValues[maskNumber] = mask;
583     // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
584     mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
585 }
586 
getSampleMaskWord(GLuint maskNumber) const587 GLbitfield State::getSampleMaskWord(GLuint maskNumber) const
588 {
589     ASSERT(maskNumber < mMaxSampleMaskWords);
590     return mSampleMaskValues[maskNumber];
591 }
592 
getMaxSampleMaskWords() const593 GLuint State::getMaxSampleMaskWords() const
594 {
595     return mMaxSampleMaskWords;
596 }
597 
setSampleAlphaToOne(bool enabled)598 void State::setSampleAlphaToOne(bool enabled)
599 {
600     mSampleAlphaToOne = enabled;
601     mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
602 }
603 
isSampleAlphaToOneEnabled() const604 bool State::isSampleAlphaToOneEnabled() const
605 {
606     return mSampleAlphaToOne;
607 }
608 
setMultisampling(bool enabled)609 void State::setMultisampling(bool enabled)
610 {
611     mMultiSampling = enabled;
612     mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
613 }
614 
isMultisamplingEnabled() const615 bool State::isMultisamplingEnabled() const
616 {
617     return mMultiSampling;
618 }
619 
isScissorTestEnabled() const620 bool State::isScissorTestEnabled() const
621 {
622     return mScissorTest;
623 }
624 
setScissorTest(bool enabled)625 void State::setScissorTest(bool enabled)
626 {
627     mScissorTest = enabled;
628     mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
629 }
630 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)631 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
632 {
633     mScissor.x = x;
634     mScissor.y = y;
635     mScissor.width = width;
636     mScissor.height = height;
637     mDirtyBits.set(DIRTY_BIT_SCISSOR);
638 }
639 
getScissor() const640 const Rectangle &State::getScissor() const
641 {
642     return mScissor;
643 }
644 
isDitherEnabled() const645 bool State::isDitherEnabled() const
646 {
647     return mBlend.dither;
648 }
649 
setDither(bool enabled)650 void State::setDither(bool enabled)
651 {
652     mBlend.dither = enabled;
653     mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
654 }
655 
isPrimitiveRestartEnabled() const656 bool State::isPrimitiveRestartEnabled() const
657 {
658     return mPrimitiveRestart;
659 }
660 
setPrimitiveRestart(bool enabled)661 void State::setPrimitiveRestart(bool enabled)
662 {
663     mPrimitiveRestart = enabled;
664     mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
665 }
666 
setEnableFeature(GLenum feature,bool enabled)667 void State::setEnableFeature(GLenum feature, bool enabled)
668 {
669     switch (feature)
670     {
671       case GL_MULTISAMPLE_EXT:               setMultisampling(enabled);         break;
672       case GL_SAMPLE_ALPHA_TO_ONE_EXT:       setSampleAlphaToOne(enabled);      break;
673       case GL_CULL_FACE:                     setCullFace(enabled);              break;
674       case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
675       case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
676       case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
677       case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
678       case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
679       case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
680       case GL_BLEND:                         setBlend(enabled);                 break;
681       case GL_DITHER:                        setDither(enabled);                break;
682       case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled);      break;
683       case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
684       case GL_SAMPLE_MASK:
685           setSampleMaskEnabled(enabled);
686           break;
687       case GL_DEBUG_OUTPUT_SYNCHRONOUS:
688           mDebug.setOutputSynchronous(enabled);
689           break;
690       case GL_DEBUG_OUTPUT:
691           mDebug.setOutputEnabled(enabled);
692           break;
693       case GL_FRAMEBUFFER_SRGB_EXT:
694           setFramebufferSRGB(enabled);
695           break;
696       default:                               UNREACHABLE();
697     }
698 }
699 
getEnableFeature(GLenum feature) const700 bool State::getEnableFeature(GLenum feature) const
701 {
702     switch (feature)
703     {
704       case GL_MULTISAMPLE_EXT:               return isMultisamplingEnabled();
705       case GL_SAMPLE_ALPHA_TO_ONE_EXT:       return isSampleAlphaToOneEnabled();
706       case GL_CULL_FACE:                     return isCullFaceEnabled();
707       case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
708       case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
709       case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
710       case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
711       case GL_STENCIL_TEST:                  return isStencilTestEnabled();
712       case GL_DEPTH_TEST:                    return isDepthTestEnabled();
713       case GL_BLEND:                         return isBlendEnabled();
714       case GL_DITHER:                        return isDitherEnabled();
715       case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
716       case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
717       case GL_SAMPLE_MASK:
718           return isSampleMaskEnabled();
719       case GL_DEBUG_OUTPUT_SYNCHRONOUS:
720           return mDebug.isOutputSynchronous();
721       case GL_DEBUG_OUTPUT:
722           return mDebug.isOutputEnabled();
723       case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
724           return isBindGeneratesResourceEnabled();
725       case GL_CLIENT_ARRAYS_ANGLE:
726           return areClientArraysEnabled();
727       case GL_FRAMEBUFFER_SRGB_EXT:
728           return getFramebufferSRGB();
729       case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
730           return mRobustResourceInit;
731       case GL_PROGRAM_CACHE_ENABLED_ANGLE:
732           return mProgramBinaryCacheEnabled;
733 
734       default:
735           UNREACHABLE();
736           return false;
737     }
738 }
739 
setLineWidth(GLfloat width)740 void State::setLineWidth(GLfloat width)
741 {
742     mLineWidth = width;
743     mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
744 }
745 
getLineWidth() const746 float State::getLineWidth() const
747 {
748     return mLineWidth;
749 }
750 
setGenerateMipmapHint(GLenum hint)751 void State::setGenerateMipmapHint(GLenum hint)
752 {
753     mGenerateMipmapHint = hint;
754     mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
755 }
756 
setFragmentShaderDerivativeHint(GLenum hint)757 void State::setFragmentShaderDerivativeHint(GLenum hint)
758 {
759     mFragmentShaderDerivativeHint = hint;
760     mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
761     // TODO: Propagate the hint to shader translator so we can write
762     // ddx, ddx_coarse, or ddx_fine depending on the hint.
763     // Ignore for now. It is valid for implementations to ignore hint.
764 }
765 
isBindGeneratesResourceEnabled() const766 bool State::isBindGeneratesResourceEnabled() const
767 {
768     return mBindGeneratesResource;
769 }
770 
areClientArraysEnabled() const771 bool State::areClientArraysEnabled() const
772 {
773     return mClientArraysEnabled;
774 }
775 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)776 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
777 {
778     mViewport.x = x;
779     mViewport.y = y;
780     mViewport.width = width;
781     mViewport.height = height;
782     mDirtyBits.set(DIRTY_BIT_VIEWPORT);
783 }
784 
getViewport() const785 const Rectangle &State::getViewport() const
786 {
787     return mViewport;
788 }
789 
setActiveSampler(unsigned int active)790 void State::setActiveSampler(unsigned int active)
791 {
792     mActiveSampler = active;
793 }
794 
getActiveSampler() const795 unsigned int State::getActiveSampler() const
796 {
797     return static_cast<unsigned int>(mActiveSampler);
798 }
799 
setSamplerTexture(const Context * context,GLenum type,Texture * texture)800 void State::setSamplerTexture(const Context *context, GLenum type, Texture *texture)
801 {
802     mSamplerTextures[type][mActiveSampler].set(context, texture);
803     mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
804     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
805 }
806 
getTargetTexture(GLenum target) const807 Texture *State::getTargetTexture(GLenum target) const
808 {
809     return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
810 }
811 
getSamplerTexture(unsigned int sampler,GLenum type) const812 Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
813 {
814     const auto it = mSamplerTextures.find(type);
815     ASSERT(it != mSamplerTextures.end());
816     ASSERT(sampler < it->second.size());
817     return it->second[sampler].get();
818 }
819 
getSamplerTextureId(unsigned int sampler,GLenum type) const820 GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
821 {
822     const auto it = mSamplerTextures.find(type);
823     ASSERT(it != mSamplerTextures.end());
824     ASSERT(sampler < it->second.size());
825     return it->second[sampler].id();
826 }
827 
detachTexture(const Context * context,const TextureMap & zeroTextures,GLuint texture)828 void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
829 {
830     // Textures have a detach method on State rather than a simple
831     // removeBinding, because the zero/null texture objects are managed
832     // separately, and don't have to go through the Context's maps or
833     // the ResourceManager.
834 
835     // [OpenGL ES 2.0.24] section 3.8 page 84:
836     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
837     // rebound to texture object zero
838 
839     for (auto &bindingVec : mSamplerTextures)
840     {
841         GLenum textureType = bindingVec.first;
842         TextureBindingVector &textureVector = bindingVec.second;
843         for (BindingPointer<Texture> &binding : textureVector)
844         {
845             if (binding.id() == texture)
846             {
847                 auto it = zeroTextures.find(textureType);
848                 ASSERT(it != zeroTextures.end());
849                 // Zero textures are the "default" textures instead of NULL
850                 binding.set(context, it->second.get());
851                 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
852             }
853         }
854     }
855 
856     for (auto &bindingImageUnit : mImageUnits)
857     {
858         if (bindingImageUnit.texture.id() == texture)
859         {
860             bindingImageUnit.texture.set(context, nullptr);
861             bindingImageUnit.level   = 0;
862             bindingImageUnit.layered = false;
863             bindingImageUnit.layer   = 0;
864             bindingImageUnit.access  = GL_READ_ONLY;
865             bindingImageUnit.format  = GL_R32UI;
866             break;
867         }
868     }
869 
870     // [OpenGL ES 2.0.24] section 4.4 page 112:
871     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
872     // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
873     // image was attached in the currently bound framebuffer.
874 
875     if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
876     {
877         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
878     }
879 
880     if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
881     {
882         mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
883     }
884 }
885 
initializeZeroTextures(const Context * context,const TextureMap & zeroTextures)886 void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
887 {
888     for (const auto &zeroTexture : zeroTextures)
889     {
890         auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
891 
892         for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
893         {
894             samplerTextureArray[textureUnit].set(context, zeroTexture.second.get());
895         }
896     }
897 }
898 
setSamplerBinding(const Context * context,GLuint textureUnit,Sampler * sampler)899 void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
900 {
901     mSamplers[textureUnit].set(context, sampler);
902     mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
903     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
904 }
905 
getSamplerId(GLuint textureUnit) const906 GLuint State::getSamplerId(GLuint textureUnit) const
907 {
908     ASSERT(textureUnit < mSamplers.size());
909     return mSamplers[textureUnit].id();
910 }
911 
getSampler(GLuint textureUnit) const912 Sampler *State::getSampler(GLuint textureUnit) const
913 {
914     return mSamplers[textureUnit].get();
915 }
916 
detachSampler(const Context * context,GLuint sampler)917 void State::detachSampler(const Context *context, GLuint sampler)
918 {
919     // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
920     // If a sampler object that is currently bound to one or more texture units is
921     // deleted, it is as though BindSampler is called once for each texture unit to
922     // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
923     for (BindingPointer<Sampler> &samplerBinding : mSamplers)
924     {
925         if (samplerBinding.id() == sampler)
926         {
927             samplerBinding.set(context, nullptr);
928             mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
929         }
930     }
931 }
932 
setRenderbufferBinding(const Context * context,Renderbuffer * renderbuffer)933 void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
934 {
935     mRenderbuffer.set(context, renderbuffer);
936     mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
937 }
938 
getRenderbufferId() const939 GLuint State::getRenderbufferId() const
940 {
941     return mRenderbuffer.id();
942 }
943 
getCurrentRenderbuffer() const944 Renderbuffer *State::getCurrentRenderbuffer() const
945 {
946     return mRenderbuffer.get();
947 }
948 
detachRenderbuffer(const Context * context,GLuint renderbuffer)949 void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
950 {
951     // [OpenGL ES 2.0.24] section 4.4 page 109:
952     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
953     // had been executed with the target RENDERBUFFER and name of zero.
954 
955     if (mRenderbuffer.id() == renderbuffer)
956     {
957         setRenderbufferBinding(context, nullptr);
958     }
959 
960     // [OpenGL ES 2.0.24] section 4.4 page 111:
961     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
962     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
963     // point to which this image was attached in the currently bound framebuffer.
964 
965     Framebuffer *readFramebuffer = mReadFramebuffer;
966     Framebuffer *drawFramebuffer = mDrawFramebuffer;
967 
968     if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
969     {
970         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
971     }
972 
973     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
974     {
975         if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
976         {
977             mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
978         }
979     }
980 
981 }
982 
setReadFramebufferBinding(Framebuffer * framebuffer)983 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
984 {
985     if (mReadFramebuffer == framebuffer)
986         return;
987 
988     mReadFramebuffer = framebuffer;
989     mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
990 
991     if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
992     {
993         mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
994     }
995 }
996 
setDrawFramebufferBinding(Framebuffer * framebuffer)997 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
998 {
999     if (mDrawFramebuffer == framebuffer)
1000         return;
1001 
1002     mDrawFramebuffer = framebuffer;
1003     mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1004 
1005     if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
1006     {
1007         mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1008     }
1009 }
1010 
getTargetFramebuffer(GLenum target) const1011 Framebuffer *State::getTargetFramebuffer(GLenum target) const
1012 {
1013     switch (target)
1014     {
1015         case GL_READ_FRAMEBUFFER_ANGLE:
1016             return mReadFramebuffer;
1017         case GL_DRAW_FRAMEBUFFER_ANGLE:
1018         case GL_FRAMEBUFFER:
1019             return mDrawFramebuffer;
1020         default:
1021             UNREACHABLE();
1022             return nullptr;
1023     }
1024 }
1025 
getReadFramebuffer() const1026 Framebuffer *State::getReadFramebuffer() const
1027 {
1028     return mReadFramebuffer;
1029 }
1030 
getDrawFramebuffer() const1031 Framebuffer *State::getDrawFramebuffer() const
1032 {
1033     return mDrawFramebuffer;
1034 }
1035 
removeReadFramebufferBinding(GLuint framebuffer)1036 bool State::removeReadFramebufferBinding(GLuint framebuffer)
1037 {
1038     if (mReadFramebuffer != nullptr &&
1039         mReadFramebuffer->id() == framebuffer)
1040     {
1041         setReadFramebufferBinding(nullptr);
1042         return true;
1043     }
1044 
1045     return false;
1046 }
1047 
removeDrawFramebufferBinding(GLuint framebuffer)1048 bool State::removeDrawFramebufferBinding(GLuint framebuffer)
1049 {
1050     if (mReadFramebuffer != nullptr &&
1051         mDrawFramebuffer->id() == framebuffer)
1052     {
1053         setDrawFramebufferBinding(nullptr);
1054         return true;
1055     }
1056 
1057     return false;
1058 }
1059 
setVertexArrayBinding(VertexArray * vertexArray)1060 void State::setVertexArrayBinding(VertexArray *vertexArray)
1061 {
1062     mVertexArray = vertexArray;
1063     mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1064 
1065     if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1066     {
1067         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1068     }
1069 }
1070 
getVertexArrayId() const1071 GLuint State::getVertexArrayId() const
1072 {
1073     ASSERT(mVertexArray != nullptr);
1074     return mVertexArray->id();
1075 }
1076 
getVertexArray() const1077 VertexArray *State::getVertexArray() const
1078 {
1079     ASSERT(mVertexArray != nullptr);
1080     return mVertexArray;
1081 }
1082 
removeVertexArrayBinding(GLuint vertexArray)1083 bool State::removeVertexArrayBinding(GLuint vertexArray)
1084 {
1085     if (mVertexArray->id() == vertexArray)
1086     {
1087         mVertexArray = nullptr;
1088         mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
1089         mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1090         return true;
1091     }
1092 
1093     return false;
1094 }
1095 
bindVertexBuffer(const Context * context,GLuint bindingIndex,Buffer * boundBuffer,GLintptr offset,GLsizei stride)1096 void State::bindVertexBuffer(const Context *context,
1097                              GLuint bindingIndex,
1098                              Buffer *boundBuffer,
1099                              GLintptr offset,
1100                              GLsizei stride)
1101 {
1102     getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
1103     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1104 }
1105 
setVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1106 void State::setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1107 {
1108     getVertexArray()->setVertexAttribBinding(context, attribIndex, bindingIndex);
1109     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1110 }
1111 
setVertexAttribFormat(GLuint attribIndex,GLint size,GLenum type,bool normalized,bool pureInteger,GLuint relativeOffset)1112 void State::setVertexAttribFormat(GLuint attribIndex,
1113                                   GLint size,
1114                                   GLenum type,
1115                                   bool normalized,
1116                                   bool pureInteger,
1117                                   GLuint relativeOffset)
1118 {
1119     getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1120                                             relativeOffset);
1121     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1122 }
1123 
setVertexBindingDivisor(GLuint bindingIndex,GLuint divisor)1124 void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1125 {
1126     getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
1127     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1128 }
1129 
setProgram(const Context * context,Program * newProgram)1130 void State::setProgram(const Context *context, Program *newProgram)
1131 {
1132     if (mProgram != newProgram)
1133     {
1134         if (mProgram)
1135         {
1136             mProgram->release(context);
1137         }
1138 
1139         mProgram = newProgram;
1140 
1141         if (mProgram)
1142         {
1143             newProgram->addRef();
1144             mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
1145         }
1146         mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
1147         mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
1148     }
1149 }
1150 
getProgram() const1151 Program *State::getProgram() const
1152 {
1153     return mProgram;
1154 }
1155 
setTransformFeedbackBinding(const Context * context,TransformFeedback * transformFeedback)1156 void State::setTransformFeedbackBinding(const Context *context,
1157                                         TransformFeedback *transformFeedback)
1158 {
1159     mTransformFeedback.set(context, transformFeedback);
1160 }
1161 
getCurrentTransformFeedback() const1162 TransformFeedback *State::getCurrentTransformFeedback() const
1163 {
1164     return mTransformFeedback.get();
1165 }
1166 
isTransformFeedbackActiveUnpaused() const1167 bool State::isTransformFeedbackActiveUnpaused() const
1168 {
1169     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1170     return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
1171 }
1172 
removeTransformFeedbackBinding(const Context * context,GLuint transformFeedback)1173 bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback)
1174 {
1175     if (mTransformFeedback.id() == transformFeedback)
1176     {
1177         mTransformFeedback.set(context, nullptr);
1178         return true;
1179     }
1180 
1181     return false;
1182 }
1183 
setProgramPipelineBinding(const Context * context,ProgramPipeline * pipeline)1184 void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
1185 {
1186     mProgramPipeline.set(context, pipeline);
1187 }
1188 
detachProgramPipeline(const Context * context,GLuint pipeline)1189 void State::detachProgramPipeline(const Context *context, GLuint pipeline)
1190 {
1191     mProgramPipeline.set(context, nullptr);
1192 }
1193 
isQueryActive(const GLenum type) const1194 bool State::isQueryActive(const GLenum type) const
1195 {
1196     for (auto &iter : mActiveQueries)
1197     {
1198         const Query *query = iter.second.get();
1199         if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
1200         {
1201             return true;
1202         }
1203     }
1204 
1205     return false;
1206 }
1207 
isQueryActive(Query * query) const1208 bool State::isQueryActive(Query *query) const
1209 {
1210     for (auto &iter : mActiveQueries)
1211     {
1212         if (iter.second.get() == query)
1213         {
1214             return true;
1215         }
1216     }
1217 
1218     return false;
1219 }
1220 
setActiveQuery(const Context * context,GLenum target,Query * query)1221 void State::setActiveQuery(const Context *context, GLenum target, Query *query)
1222 {
1223     mActiveQueries[target].set(context, query);
1224 }
1225 
getActiveQueryId(GLenum target) const1226 GLuint State::getActiveQueryId(GLenum target) const
1227 {
1228     const Query *query = getActiveQuery(target);
1229     return (query ? query->id() : 0u);
1230 }
1231 
getActiveQuery(GLenum target) const1232 Query *State::getActiveQuery(GLenum target) const
1233 {
1234     const auto it = mActiveQueries.find(target);
1235 
1236     // All query types should already exist in the activeQueries map
1237     ASSERT(it != mActiveQueries.end());
1238 
1239     return it->second.get();
1240 }
1241 
setBufferBinding(const Context * context,BufferBinding target,Buffer * buffer)1242 void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
1243 {
1244     switch (target)
1245     {
1246         case BufferBinding::PixelPack:
1247             mBoundBuffers[target].set(context, buffer);
1248             mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
1249             break;
1250         case BufferBinding::PixelUnpack:
1251             mBoundBuffers[target].set(context, buffer);
1252             mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
1253             break;
1254         case BufferBinding::DrawIndirect:
1255             mBoundBuffers[target].set(context, buffer);
1256             mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
1257             break;
1258         case BufferBinding::TransformFeedback:
1259             if (mTransformFeedback.get() != nullptr)
1260             {
1261                 mTransformFeedback->bindGenericBuffer(context, buffer);
1262             }
1263             break;
1264         case BufferBinding::ElementArray:
1265             getVertexArray()->setElementArrayBuffer(context, buffer);
1266             mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1267             break;
1268         default:
1269             mBoundBuffers[target].set(context, buffer);
1270             break;
1271     }
1272 }
setIndexedBufferBinding(const Context * context,BufferBinding target,GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)1273 void State::setIndexedBufferBinding(const Context *context,
1274                                     BufferBinding target,
1275                                     GLuint index,
1276                                     Buffer *buffer,
1277                                     GLintptr offset,
1278                                     GLsizeiptr size)
1279 {
1280     setBufferBinding(context, target, buffer);
1281 
1282     switch (target)
1283     {
1284         case BufferBinding::TransformFeedback:
1285             mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size);
1286             break;
1287         case BufferBinding::Uniform:
1288             mUniformBuffers[index].set(context, buffer, offset, size);
1289             break;
1290         case BufferBinding::AtomicCounter:
1291             mAtomicCounterBuffers[index].set(context, buffer, offset, size);
1292             break;
1293         case BufferBinding::ShaderStorage:
1294             mShaderStorageBuffers[index].set(context, buffer, offset, size);
1295             break;
1296         default:
1297             UNREACHABLE();
1298             break;
1299     }
1300 }
1301 
getIndexedUniformBuffer(size_t index) const1302 const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
1303 {
1304     ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1305     return mUniformBuffers[index];
1306 }
1307 
getIndexedAtomicCounterBuffer(size_t index) const1308 const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
1309 {
1310     ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1311     return mAtomicCounterBuffers[index];
1312 }
1313 
getIndexedShaderStorageBuffer(size_t index) const1314 const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
1315 {
1316     ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
1317     return mShaderStorageBuffers[index];
1318 }
1319 
getTargetBuffer(BufferBinding target) const1320 Buffer *State::getTargetBuffer(BufferBinding target) const
1321 {
1322     switch (target)
1323     {
1324         case BufferBinding::ElementArray:
1325             return getVertexArray()->getElementArrayBuffer().get();
1326         case BufferBinding::TransformFeedback:
1327             return mTransformFeedback->getGenericBuffer().get();
1328         default:
1329             return mBoundBuffers[target].get();
1330     }
1331 }
1332 
detachBuffer(const Context * context,GLuint bufferName)1333 void State::detachBuffer(const Context *context, GLuint bufferName)
1334 {
1335     for (auto &buffer : mBoundBuffers)
1336     {
1337         if (buffer.id() == bufferName)
1338         {
1339             buffer.set(context, nullptr);
1340         }
1341     }
1342 
1343     TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1344     if (curTransformFeedback)
1345     {
1346         curTransformFeedback->detachBuffer(context, bufferName);
1347     }
1348 
1349     getVertexArray()->detachBuffer(context, bufferName);
1350 }
1351 
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)1352 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1353 {
1354     getVertexArray()->enableAttribute(attribNum, enabled);
1355     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1356 }
1357 
setVertexAttribf(GLuint index,const GLfloat values[4])1358 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1359 {
1360     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1361     mVertexAttribCurrentValues[index].setFloatValues(values);
1362     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1363     mDirtyCurrentValues.set(index);
1364 }
1365 
setVertexAttribu(GLuint index,const GLuint values[4])1366 void State::setVertexAttribu(GLuint index, const GLuint values[4])
1367 {
1368     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1369     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1370     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1371     mDirtyCurrentValues.set(index);
1372 }
1373 
setVertexAttribi(GLuint index,const GLint values[4])1374 void State::setVertexAttribi(GLuint index, const GLint values[4])
1375 {
1376     ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
1377     mVertexAttribCurrentValues[index].setIntValues(values);
1378     mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1379     mDirtyCurrentValues.set(index);
1380 }
1381 
setVertexAttribPointer(const Context * context,unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,bool pureInteger,GLsizei stride,const void * pointer)1382 void State::setVertexAttribPointer(const Context *context,
1383                                    unsigned int attribNum,
1384                                    Buffer *boundBuffer,
1385                                    GLint size,
1386                                    GLenum type,
1387                                    bool normalized,
1388                                    bool pureInteger,
1389                                    GLsizei stride,
1390                                    const void *pointer)
1391 {
1392     getVertexArray()->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
1393                                              normalized, pureInteger, stride, pointer);
1394     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1395 }
1396 
setVertexAttribDivisor(const Context * context,GLuint index,GLuint divisor)1397 void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
1398 {
1399     getVertexArray()->setVertexAttribDivisor(context, index, divisor);
1400     mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1401 }
1402 
getVertexAttribCurrentValue(size_t attribNum) const1403 const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
1404 {
1405     ASSERT(attribNum < mVertexAttribCurrentValues.size());
1406     return mVertexAttribCurrentValues[attribNum];
1407 }
1408 
getVertexAttribCurrentValues() const1409 const std::vector<VertexAttribCurrentValueData> &State::getVertexAttribCurrentValues() const
1410 {
1411     return mVertexAttribCurrentValues;
1412 }
1413 
getVertexAttribPointer(unsigned int attribNum) const1414 const void *State::getVertexAttribPointer(unsigned int attribNum) const
1415 {
1416     return getVertexArray()->getVertexAttribute(attribNum).pointer;
1417 }
1418 
setPackAlignment(GLint alignment)1419 void State::setPackAlignment(GLint alignment)
1420 {
1421     mPack.alignment = alignment;
1422     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1423 }
1424 
getPackAlignment() const1425 GLint State::getPackAlignment() const
1426 {
1427     return mPack.alignment;
1428 }
1429 
setPackReverseRowOrder(bool reverseRowOrder)1430 void State::setPackReverseRowOrder(bool reverseRowOrder)
1431 {
1432     mPack.reverseRowOrder = reverseRowOrder;
1433     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1434 }
1435 
getPackReverseRowOrder() const1436 bool State::getPackReverseRowOrder() const
1437 {
1438     return mPack.reverseRowOrder;
1439 }
1440 
setPackRowLength(GLint rowLength)1441 void State::setPackRowLength(GLint rowLength)
1442 {
1443     mPack.rowLength = rowLength;
1444     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1445 }
1446 
getPackRowLength() const1447 GLint State::getPackRowLength() const
1448 {
1449     return mPack.rowLength;
1450 }
1451 
setPackSkipRows(GLint skipRows)1452 void State::setPackSkipRows(GLint skipRows)
1453 {
1454     mPack.skipRows = skipRows;
1455     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1456 }
1457 
getPackSkipRows() const1458 GLint State::getPackSkipRows() const
1459 {
1460     return mPack.skipRows;
1461 }
1462 
setPackSkipPixels(GLint skipPixels)1463 void State::setPackSkipPixels(GLint skipPixels)
1464 {
1465     mPack.skipPixels = skipPixels;
1466     mDirtyBits.set(DIRTY_BIT_PACK_STATE);
1467 }
1468 
getPackSkipPixels() const1469 GLint State::getPackSkipPixels() const
1470 {
1471     return mPack.skipPixels;
1472 }
1473 
getPackState() const1474 const PixelPackState &State::getPackState() const
1475 {
1476     return mPack;
1477 }
1478 
getPackState()1479 PixelPackState &State::getPackState()
1480 {
1481     return mPack;
1482 }
1483 
setUnpackAlignment(GLint alignment)1484 void State::setUnpackAlignment(GLint alignment)
1485 {
1486     mUnpack.alignment = alignment;
1487     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1488 }
1489 
getUnpackAlignment() const1490 GLint State::getUnpackAlignment() const
1491 {
1492     return mUnpack.alignment;
1493 }
1494 
setUnpackRowLength(GLint rowLength)1495 void State::setUnpackRowLength(GLint rowLength)
1496 {
1497     mUnpack.rowLength = rowLength;
1498     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1499 }
1500 
getUnpackRowLength() const1501 GLint State::getUnpackRowLength() const
1502 {
1503     return mUnpack.rowLength;
1504 }
1505 
setUnpackImageHeight(GLint imageHeight)1506 void State::setUnpackImageHeight(GLint imageHeight)
1507 {
1508     mUnpack.imageHeight = imageHeight;
1509     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1510 }
1511 
getUnpackImageHeight() const1512 GLint State::getUnpackImageHeight() const
1513 {
1514     return mUnpack.imageHeight;
1515 }
1516 
setUnpackSkipImages(GLint skipImages)1517 void State::setUnpackSkipImages(GLint skipImages)
1518 {
1519     mUnpack.skipImages = skipImages;
1520     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1521 }
1522 
getUnpackSkipImages() const1523 GLint State::getUnpackSkipImages() const
1524 {
1525     return mUnpack.skipImages;
1526 }
1527 
setUnpackSkipRows(GLint skipRows)1528 void State::setUnpackSkipRows(GLint skipRows)
1529 {
1530     mUnpack.skipRows = skipRows;
1531     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1532 }
1533 
getUnpackSkipRows() const1534 GLint State::getUnpackSkipRows() const
1535 {
1536     return mUnpack.skipRows;
1537 }
1538 
setUnpackSkipPixels(GLint skipPixels)1539 void State::setUnpackSkipPixels(GLint skipPixels)
1540 {
1541     mUnpack.skipPixels = skipPixels;
1542     mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
1543 }
1544 
getUnpackSkipPixels() const1545 GLint State::getUnpackSkipPixels() const
1546 {
1547     return mUnpack.skipPixels;
1548 }
1549 
getUnpackState() const1550 const PixelUnpackState &State::getUnpackState() const
1551 {
1552     return mUnpack;
1553 }
1554 
getUnpackState()1555 PixelUnpackState &State::getUnpackState()
1556 {
1557     return mUnpack;
1558 }
1559 
getDebug() const1560 const Debug &State::getDebug() const
1561 {
1562     return mDebug;
1563 }
1564 
getDebug()1565 Debug &State::getDebug()
1566 {
1567     return mDebug;
1568 }
1569 
setCoverageModulation(GLenum components)1570 void State::setCoverageModulation(GLenum components)
1571 {
1572     mCoverageModulation = components;
1573     mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1574 }
1575 
getCoverageModulation() const1576 GLenum State::getCoverageModulation() const
1577 {
1578     return mCoverageModulation;
1579 }
1580 
loadPathRenderingMatrix(GLenum matrixMode,const GLfloat * matrix)1581 void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1582 {
1583     if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1584     {
1585         memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1586         mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1587     }
1588     else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1589     {
1590         memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1591         mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1592     }
1593     else
1594     {
1595         UNREACHABLE();
1596     }
1597 }
1598 
getPathRenderingMatrix(GLenum which) const1599 const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1600 {
1601     if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1602     {
1603         return mPathMatrixMV;
1604     }
1605     else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1606     {
1607         return mPathMatrixProj;
1608     }
1609 
1610     UNREACHABLE();
1611     return nullptr;
1612 }
1613 
setPathStencilFunc(GLenum func,GLint ref,GLuint mask)1614 void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1615 {
1616     mPathStencilFunc = func;
1617     mPathStencilRef  = ref;
1618     mPathStencilMask = mask;
1619     mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1620 }
1621 
getPathStencilFunc() const1622 GLenum State::getPathStencilFunc() const
1623 {
1624     return mPathStencilFunc;
1625 }
1626 
getPathStencilRef() const1627 GLint State::getPathStencilRef() const
1628 {
1629     return mPathStencilRef;
1630 }
1631 
getPathStencilMask() const1632 GLuint State::getPathStencilMask() const
1633 {
1634     return mPathStencilMask;
1635 }
1636 
setFramebufferSRGB(bool sRGB)1637 void State::setFramebufferSRGB(bool sRGB)
1638 {
1639     mFramebufferSRGB = sRGB;
1640     mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1641 }
1642 
getFramebufferSRGB() const1643 bool State::getFramebufferSRGB() const
1644 {
1645     return mFramebufferSRGB;
1646 }
1647 
getBooleanv(GLenum pname,GLboolean * params)1648 void State::getBooleanv(GLenum pname, GLboolean *params)
1649 {
1650     switch (pname)
1651     {
1652       case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
1653       case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
1654       case GL_COLOR_WRITEMASK:
1655         params[0] = mBlend.colorMaskRed;
1656         params[1] = mBlend.colorMaskGreen;
1657         params[2] = mBlend.colorMaskBlue;
1658         params[3] = mBlend.colorMaskAlpha;
1659         break;
1660       case GL_CULL_FACE:
1661           *params = mRasterizer.cullFace;
1662           break;
1663       case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
1664       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
1665       case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
1666       case GL_SAMPLE_MASK:
1667           *params = mSampleMask;
1668           break;
1669       case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
1670       case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
1671       case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
1672       case GL_BLEND:                     *params = mBlend.blend;                  break;
1673       case GL_DITHER:                    *params = mBlend.dither;                 break;
1674       case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1675       case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
1676       case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1677           *params = mPrimitiveRestart;
1678           break;
1679       case GL_RASTERIZER_DISCARD:
1680           *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1681           break;
1682       case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1683           *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1684           break;
1685       case GL_DEBUG_OUTPUT:
1686           *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1687           break;
1688       case GL_MULTISAMPLE_EXT:
1689           *params = mMultiSampling;
1690           break;
1691       case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1692           *params = mSampleAlphaToOne;
1693           break;
1694       case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1695           *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1696           break;
1697       case GL_CLIENT_ARRAYS_ANGLE:
1698           *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1699           break;
1700       case GL_FRAMEBUFFER_SRGB_EXT:
1701           *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1702           break;
1703       case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1704           *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
1705           break;
1706       case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1707           *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
1708           break;
1709 
1710       default:
1711         UNREACHABLE();
1712         break;
1713     }
1714 }
1715 
getFloatv(GLenum pname,GLfloat * params)1716 void State::getFloatv(GLenum pname, GLfloat *params)
1717 {
1718     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1719     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1720     // GetIntegerv as its native query function. As it would require conversion in any
1721     // case, this should make no difference to the calling application.
1722     switch (pname)
1723     {
1724       case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
1725       case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
1726       case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
1727       case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
1728       case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
1729       case GL_DEPTH_RANGE:
1730         params[0] = mNearZ;
1731         params[1] = mFarZ;
1732         break;
1733       case GL_COLOR_CLEAR_VALUE:
1734         params[0] = mColorClearValue.red;
1735         params[1] = mColorClearValue.green;
1736         params[2] = mColorClearValue.blue;
1737         params[3] = mColorClearValue.alpha;
1738         break;
1739       case GL_BLEND_COLOR:
1740         params[0] = mBlendColor.red;
1741         params[1] = mBlendColor.green;
1742         params[2] = mBlendColor.blue;
1743         params[3] = mBlendColor.alpha;
1744         break;
1745       case GL_MULTISAMPLE_EXT:
1746         *params = static_cast<GLfloat>(mMultiSampling);
1747         break;
1748       case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1749         *params = static_cast<GLfloat>(mSampleAlphaToOne);
1750       case GL_COVERAGE_MODULATION_CHROMIUM:
1751           params[0] = static_cast<GLfloat>(mCoverageModulation);
1752           break;
1753       default:
1754         UNREACHABLE();
1755         break;
1756     }
1757 }
1758 
getIntegerv(const Context * context,GLenum pname,GLint * params)1759 void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
1760 {
1761     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1762     {
1763         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1764         ASSERT(colorAttachment < mMaxDrawBuffers);
1765         Framebuffer *framebuffer = mDrawFramebuffer;
1766         *params = framebuffer->getDrawBufferState(colorAttachment);
1767         return;
1768     }
1769 
1770     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1771     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1772     // GetIntegerv as its native query function. As it would require conversion in any
1773     // case, this should make no difference to the calling application. You may find it in
1774     // State::getFloatv.
1775     switch (pname)
1776     {
1777         case GL_ARRAY_BUFFER_BINDING:
1778             *params = mBoundBuffers[BufferBinding::Array].id();
1779             break;
1780         case GL_DRAW_INDIRECT_BUFFER_BINDING:
1781             *params = mBoundBuffers[BufferBinding::DrawIndirect].id();
1782             break;
1783         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1784             *params = getVertexArray()->getElementArrayBuffer().id();
1785             break;
1786         //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1787       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
1788       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
1789       case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
1790       case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
1791       case GL_CURRENT_PROGRAM:                          *params = mProgram ? mProgram->id() : 0;                  break;
1792       case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
1793       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
1794       case GL_PACK_ROW_LENGTH:
1795           *params = mPack.rowLength;
1796           break;
1797       case GL_PACK_SKIP_ROWS:
1798           *params = mPack.skipRows;
1799           break;
1800       case GL_PACK_SKIP_PIXELS:
1801           *params = mPack.skipPixels;
1802           break;
1803       case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
1804       case GL_UNPACK_ROW_LENGTH:                        *params = mUnpack.rowLength;                              break;
1805       case GL_UNPACK_IMAGE_HEIGHT:
1806           *params = mUnpack.imageHeight;
1807           break;
1808       case GL_UNPACK_SKIP_IMAGES:
1809           *params = mUnpack.skipImages;
1810           break;
1811       case GL_UNPACK_SKIP_ROWS:
1812           *params = mUnpack.skipRows;
1813           break;
1814       case GL_UNPACK_SKIP_PIXELS:
1815           *params = mUnpack.skipPixels;
1816           break;
1817       case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
1818       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
1819       case GL_ACTIVE_TEXTURE:
1820           *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1821           break;
1822       case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
1823       case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
1824       case GL_STENCIL_VALUE_MASK:
1825           *params = CastMaskValue(context, mDepthStencil.stencilMask);
1826           break;
1827       case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
1828       case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
1829       case GL_STENCIL_BACK_VALUE_MASK:
1830           *params = CastMaskValue(context, mDepthStencil.stencilBackMask);
1831           break;
1832       case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
1833       case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
1834       case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
1835       case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
1836       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
1837       case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
1838       case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
1839       case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
1840       case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
1841       case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
1842       case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
1843       case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
1844       case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
1845       case GL_STENCIL_WRITEMASK:
1846           *params = CastMaskValue(context, mDepthStencil.stencilWritemask);
1847           break;
1848       case GL_STENCIL_BACK_WRITEMASK:
1849           *params = CastMaskValue(context, mDepthStencil.stencilBackWritemask);
1850           break;
1851       case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
1852       case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1853           *params = mReadFramebuffer->getImplementationColorReadType(context);
1854           break;
1855       case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1856           *params = mReadFramebuffer->getImplementationColorReadFormat(context);
1857           break;
1858       case GL_SAMPLE_BUFFERS:
1859       case GL_SAMPLES:
1860         {
1861             Framebuffer *framebuffer = mDrawFramebuffer;
1862             if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE)
1863             {
1864                 switch (pname)
1865                 {
1866                     case GL_SAMPLE_BUFFERS:
1867                         if (framebuffer->getSamples(context) != 0)
1868                         {
1869                             *params = 1;
1870                         }
1871                         else
1872                         {
1873                             *params = 0;
1874                         }
1875                         break;
1876                     case GL_SAMPLES:
1877                         *params = framebuffer->getSamples(context);
1878                         break;
1879                 }
1880             }
1881             else
1882             {
1883                 *params = 0;
1884             }
1885         }
1886         break;
1887       case GL_VIEWPORT:
1888         params[0] = mViewport.x;
1889         params[1] = mViewport.y;
1890         params[2] = mViewport.width;
1891         params[3] = mViewport.height;
1892         break;
1893       case GL_SCISSOR_BOX:
1894         params[0] = mScissor.x;
1895         params[1] = mScissor.y;
1896         params[2] = mScissor.width;
1897         params[3] = mScissor.height;
1898         break;
1899       case GL_CULL_FACE_MODE:
1900           *params = ToGLenum(mRasterizer.cullMode);
1901           break;
1902       case GL_FRONT_FACE:
1903           *params = mRasterizer.frontFace;
1904           break;
1905       case GL_RED_BITS:
1906       case GL_GREEN_BITS:
1907       case GL_BLUE_BITS:
1908       case GL_ALPHA_BITS:
1909         {
1910             Framebuffer *framebuffer                 = getDrawFramebuffer();
1911             const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1912 
1913             if (colorbuffer)
1914             {
1915                 switch (pname)
1916                 {
1917                 case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
1918                 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
1919                 case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
1920                 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
1921                 }
1922             }
1923             else
1924             {
1925                 *params = 0;
1926             }
1927         }
1928         break;
1929       case GL_DEPTH_BITS:
1930         {
1931             const Framebuffer *framebuffer           = getDrawFramebuffer();
1932             const FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1933 
1934             if (depthbuffer)
1935             {
1936                 *params = depthbuffer->getDepthSize();
1937             }
1938             else
1939             {
1940                 *params = 0;
1941             }
1942         }
1943         break;
1944       case GL_STENCIL_BITS:
1945         {
1946             const Framebuffer *framebuffer             = getDrawFramebuffer();
1947             const FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1948 
1949             if (stencilbuffer)
1950             {
1951                 *params = stencilbuffer->getStencilSize();
1952             }
1953             else
1954             {
1955                 *params = 0;
1956             }
1957         }
1958         break;
1959       case GL_TEXTURE_BINDING_2D:
1960         ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1961         *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
1962         break;
1963       case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
1964           ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1965           *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1966                                         GL_TEXTURE_RECTANGLE_ANGLE);
1967           break;
1968       case GL_TEXTURE_BINDING_CUBE_MAP:
1969         ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1970         *params =
1971             getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
1972         break;
1973       case GL_TEXTURE_BINDING_3D:
1974         ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1975         *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
1976         break;
1977       case GL_TEXTURE_BINDING_2D_ARRAY:
1978         ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1979         *params =
1980             getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
1981         break;
1982       case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
1983           ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1984           *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1985                                         GL_TEXTURE_2D_MULTISAMPLE);
1986           break;
1987       case GL_TEXTURE_BINDING_EXTERNAL_OES:
1988           ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1989           *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1990                                         GL_TEXTURE_EXTERNAL_OES);
1991           break;
1992       case GL_UNIFORM_BUFFER_BINDING:
1993           *params = mBoundBuffers[BufferBinding::Uniform].id();
1994           break;
1995       case GL_TRANSFORM_FEEDBACK_BINDING:
1996         *params = mTransformFeedback.id();
1997         break;
1998       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1999           ASSERT(mTransformFeedback.get() != nullptr);
2000           *params = mTransformFeedback->getGenericBuffer().id();
2001           break;
2002       case GL_COPY_READ_BUFFER_BINDING:
2003           *params = mBoundBuffers[BufferBinding::CopyRead].id();
2004           break;
2005       case GL_COPY_WRITE_BUFFER_BINDING:
2006           *params = mBoundBuffers[BufferBinding::CopyWrite].id();
2007           break;
2008       case GL_PIXEL_PACK_BUFFER_BINDING:
2009           *params = mBoundBuffers[BufferBinding::PixelPack].id();
2010           break;
2011       case GL_PIXEL_UNPACK_BUFFER_BINDING:
2012           *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
2013           break;
2014       case GL_READ_BUFFER:
2015           *params = mReadFramebuffer->getReadBufferState();
2016           break;
2017       case GL_SAMPLER_BINDING:
2018           ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2019           *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
2020           break;
2021       case GL_DEBUG_LOGGED_MESSAGES:
2022           *params = static_cast<GLint>(mDebug.getMessageCount());
2023           break;
2024       case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2025           *params = static_cast<GLint>(mDebug.getNextMessageLength());
2026           break;
2027       case GL_DEBUG_GROUP_STACK_DEPTH:
2028           *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2029           break;
2030       case GL_MULTISAMPLE_EXT:
2031           *params = static_cast<GLint>(mMultiSampling);
2032           break;
2033       case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2034           *params = static_cast<GLint>(mSampleAlphaToOne);
2035       case GL_COVERAGE_MODULATION_CHROMIUM:
2036           *params = static_cast<GLint>(mCoverageModulation);
2037           break;
2038       case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2039           *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
2040           break;
2041       case GL_SHADER_STORAGE_BUFFER_BINDING:
2042           *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
2043           break;
2044       default:
2045         UNREACHABLE();
2046         break;
2047     }
2048 }
2049 
getPointerv(GLenum pname,void ** params) const2050 void State::getPointerv(GLenum pname, void **params) const
2051 {
2052     switch (pname)
2053     {
2054         case GL_DEBUG_CALLBACK_FUNCTION:
2055             *params = reinterpret_cast<void *>(mDebug.getCallback());
2056             break;
2057         case GL_DEBUG_CALLBACK_USER_PARAM:
2058             *params = const_cast<void *>(mDebug.getUserParam());
2059             break;
2060         default:
2061             UNREACHABLE();
2062             break;
2063     }
2064 }
2065 
getIntegeri_v(GLenum target,GLuint index,GLint * data)2066 void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
2067 {
2068     switch (target)
2069     {
2070       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2071           ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2072           *data = mTransformFeedback->getIndexedBuffer(index).id();
2073           break;
2074       case GL_UNIFORM_BUFFER_BINDING:
2075           ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2076           *data = mUniformBuffers[index].id();
2077           break;
2078       case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2079           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2080           *data = mAtomicCounterBuffers[index].id();
2081           break;
2082       case GL_SHADER_STORAGE_BUFFER_BINDING:
2083           ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2084           *data = mShaderStorageBuffers[index].id();
2085           break;
2086       case GL_VERTEX_BINDING_BUFFER:
2087           ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2088           *data = mVertexArray->getVertexBinding(index).getBuffer().id();
2089           break;
2090       case GL_VERTEX_BINDING_DIVISOR:
2091           ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2092           *data = mVertexArray->getVertexBinding(index).getDivisor();
2093           break;
2094       case GL_VERTEX_BINDING_OFFSET:
2095           ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2096           *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
2097           break;
2098       case GL_VERTEX_BINDING_STRIDE:
2099           ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
2100           *data = mVertexArray->getVertexBinding(index).getStride();
2101           break;
2102       case GL_SAMPLE_MASK_VALUE:
2103           ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
2104           *data = mSampleMaskValues[index];
2105           break;
2106       default:
2107           UNREACHABLE();
2108           break;
2109     }
2110 }
2111 
getInteger64i_v(GLenum target,GLuint index,GLint64 * data)2112 void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
2113 {
2114     switch (target)
2115     {
2116       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2117           ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2118           *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
2119           break;
2120       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2121           ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2122           *data = mTransformFeedback->getIndexedBuffer(index).getSize();
2123           break;
2124       case GL_UNIFORM_BUFFER_START:
2125           ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2126           *data = mUniformBuffers[index].getOffset();
2127           break;
2128       case GL_UNIFORM_BUFFER_SIZE:
2129           ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2130           *data = mUniformBuffers[index].getSize();
2131           break;
2132       case GL_ATOMIC_COUNTER_BUFFER_START:
2133           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2134           *data = mAtomicCounterBuffers[index].getOffset();
2135           break;
2136       case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2137           ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2138           *data = mAtomicCounterBuffers[index].getSize();
2139           break;
2140       case GL_SHADER_STORAGE_BUFFER_START:
2141           ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2142           *data = mShaderStorageBuffers[index].getOffset();
2143           break;
2144       case GL_SHADER_STORAGE_BUFFER_SIZE:
2145           ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2146           *data = mShaderStorageBuffers[index].getSize();
2147           break;
2148       default:
2149           UNREACHABLE();
2150           break;
2151     }
2152 }
2153 
getBooleani_v(GLenum target,GLuint index,GLboolean * data)2154 void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
2155 {
2156     UNREACHABLE();
2157 }
2158 
hasMappedBuffer(BufferBinding target) const2159 bool State::hasMappedBuffer(BufferBinding target) const
2160 {
2161     if (target == BufferBinding::Array)
2162     {
2163         const VertexArray *vao     = getVertexArray();
2164         const auto &vertexAttribs = vao->getVertexAttributes();
2165         const auto &vertexBindings = vao->getVertexBindings();
2166         size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
2167         for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
2168         {
2169             const VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
2170             auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].getBuffer().get();
2171             if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
2172             {
2173                 return true;
2174             }
2175         }
2176 
2177         return false;
2178     }
2179     else
2180     {
2181         Buffer *buffer = getTargetBuffer(target);
2182         return (buffer && buffer->isMapped());
2183     }
2184 }
2185 
syncDirtyObjects(const Context * context)2186 void State::syncDirtyObjects(const Context *context)
2187 {
2188     if (!mDirtyObjects.any())
2189         return;
2190 
2191     syncDirtyObjects(context, mDirtyObjects);
2192 }
2193 
syncDirtyObjects(const Context * context,const DirtyObjects & bitset)2194 void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
2195 {
2196     for (auto dirtyObject : bitset)
2197     {
2198         switch (dirtyObject)
2199         {
2200             case DIRTY_OBJECT_READ_FRAMEBUFFER:
2201                 ASSERT(mReadFramebuffer);
2202                 mReadFramebuffer->syncState(context);
2203                 break;
2204             case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
2205                 ASSERT(mDrawFramebuffer);
2206                 mDrawFramebuffer->syncState(context);
2207                 break;
2208             case DIRTY_OBJECT_VERTEX_ARRAY:
2209                 ASSERT(mVertexArray);
2210                 mVertexArray->syncState(context);
2211                 break;
2212             case DIRTY_OBJECT_PROGRAM_TEXTURES:
2213                 syncProgramTextures(context);
2214                 break;
2215 
2216             default:
2217                 UNREACHABLE();
2218                 break;
2219         }
2220     }
2221 
2222     mDirtyObjects &= ~bitset;
2223 }
2224 
syncProgramTextures(const Context * context)2225 void State::syncProgramTextures(const Context *context)
2226 {
2227     // TODO(jmadill): Fine-grained updates.
2228     if (!mProgram)
2229     {
2230         return;
2231     }
2232 
2233     ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
2234     mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2235 
2236     ActiveTextureMask newActiveTextures;
2237 
2238     // Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not
2239     // initialized.
2240     mCachedTexturesInitState = InitState::Initialized;
2241 
2242     for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
2243     {
2244         if (samplerBinding.unreferenced)
2245             continue;
2246 
2247         GLenum textureType = samplerBinding.textureType;
2248         for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
2249         {
2250             Texture *texture = getSamplerTexture(textureUnitIndex, textureType);
2251             Sampler *sampler = getSampler(textureUnitIndex);
2252             ASSERT(static_cast<size_t>(textureUnitIndex) < mCompleteTextureCache.size());
2253             ASSERT(static_cast<size_t>(textureUnitIndex) < newActiveTextures.size());
2254 
2255             ASSERT(texture);
2256 
2257             // Mark the texture binding bit as dirty if the texture completeness changes.
2258             // TODO(jmadill): Use specific dirty bit for completeness change.
2259             if (texture->isSamplerComplete(context, sampler) &&
2260                 !mDrawFramebuffer->hasTextureAttachment(texture))
2261             {
2262                 texture->syncState();
2263                 mCompleteTextureCache[textureUnitIndex] = texture;
2264             }
2265             else
2266             {
2267                 mCompleteTextureCache[textureUnitIndex] = nullptr;
2268             }
2269 
2270             // Bind the texture unconditionally, to recieve completeness change notifications.
2271             mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
2272             mActiveTexturesMask.set(textureUnitIndex);
2273             newActiveTextures.set(textureUnitIndex);
2274 
2275             if (sampler != nullptr)
2276             {
2277                 sampler->syncState(context);
2278             }
2279 
2280             if (texture->initState() == InitState::MayNeedInit)
2281             {
2282                 mCachedTexturesInitState = InitState::MayNeedInit;
2283             }
2284         }
2285     }
2286 
2287     // Unset now missing textures.
2288     ActiveTextureMask negativeMask = mActiveTexturesMask & ~newActiveTextures;
2289     if (negativeMask.any())
2290     {
2291         for (auto textureIndex : negativeMask)
2292         {
2293             mCompleteTextureBindings[textureIndex].reset();
2294             mCompleteTextureCache[textureIndex] = nullptr;
2295             mActiveTexturesMask.reset(textureIndex);
2296         }
2297     }
2298 }
2299 
syncDirtyObject(const Context * context,GLenum target)2300 void State::syncDirtyObject(const Context *context, GLenum target)
2301 {
2302     DirtyObjects localSet;
2303 
2304     switch (target)
2305     {
2306         case GL_READ_FRAMEBUFFER:
2307             localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2308             break;
2309         case GL_DRAW_FRAMEBUFFER:
2310             localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2311             break;
2312         case GL_FRAMEBUFFER:
2313             localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2314             localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2315             break;
2316         case GL_VERTEX_ARRAY:
2317             localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2318             break;
2319         case GL_TEXTURE:
2320         case GL_SAMPLER:
2321         case GL_PROGRAM:
2322             localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2323             break;
2324     }
2325 
2326     syncDirtyObjects(context, localSet);
2327 }
2328 
setObjectDirty(GLenum target)2329 void State::setObjectDirty(GLenum target)
2330 {
2331     switch (target)
2332     {
2333         case GL_READ_FRAMEBUFFER:
2334             mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2335             break;
2336         case GL_DRAW_FRAMEBUFFER:
2337             mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2338             break;
2339         case GL_FRAMEBUFFER:
2340             mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2341             mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2342             break;
2343         case GL_VERTEX_ARRAY:
2344             mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2345             break;
2346         case GL_TEXTURE:
2347         case GL_SAMPLER:
2348         case GL_PROGRAM:
2349             mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2350             mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2351             break;
2352     }
2353 }
2354 
onProgramExecutableChange(Program * program)2355 void State::onProgramExecutableChange(Program *program)
2356 {
2357     // OpenGL Spec:
2358     // "If LinkProgram or ProgramBinary successfully re-links a program object
2359     //  that was already in use as a result of a previous call to UseProgram, then the
2360     //  generated executable code will be installed as part of the current rendering state."
2361     if (program->isLinked() && mProgram == program)
2362     {
2363         mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
2364         mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2365     }
2366 }
2367 
setImageUnit(const Context * context,GLuint unit,Texture * texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)2368 void State::setImageUnit(const Context *context,
2369                          GLuint unit,
2370                          Texture *texture,
2371                          GLint level,
2372                          GLboolean layered,
2373                          GLint layer,
2374                          GLenum access,
2375                          GLenum format)
2376 {
2377     mImageUnits[unit].texture.set(context, texture);
2378     mImageUnits[unit].level   = level;
2379     mImageUnits[unit].layered = layered;
2380     mImageUnits[unit].layer   = layer;
2381     mImageUnits[unit].access  = access;
2382     mImageUnits[unit].format  = format;
2383 }
2384 
getImageUnit(GLuint unit) const2385 const ImageUnit &State::getImageUnit(GLuint unit) const
2386 {
2387     return mImageUnits[unit];
2388 }
2389 
2390 // Handle a dirty texture event.
signal(size_t textureIndex,InitState initState)2391 void State::signal(size_t textureIndex, InitState initState)
2392 {
2393     // Conservatively assume all textures are dirty.
2394     // TODO(jmadill): More fine-grained update.
2395     mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2396 
2397     if (initState == InitState::MayNeedInit)
2398     {
2399         mCachedTexturesInitState = InitState::MayNeedInit;
2400     }
2401 }
2402 
clearUnclearedActiveTextures(const Context * context)2403 Error State::clearUnclearedActiveTextures(const Context *context)
2404 {
2405     ASSERT(mRobustResourceInit);
2406 
2407     if (mCachedTexturesInitState == InitState::Initialized)
2408     {
2409         return NoError();
2410     }
2411 
2412     for (auto textureIndex : mActiveTexturesMask)
2413     {
2414         Texture *texture = mCompleteTextureCache[textureIndex];
2415         if (texture)
2416         {
2417             ANGLE_TRY(texture->ensureInitialized(context));
2418         }
2419     }
2420 
2421     mCachedTexturesInitState = InitState::Initialized;
2422 
2423     return NoError();
2424 }
2425 
getAndResetDirtyCurrentValues() const2426 AttributesMask State::getAndResetDirtyCurrentValues() const
2427 {
2428     AttributesMask retVal = mDirtyCurrentValues;
2429     mDirtyCurrentValues.reset();
2430     return retVal;
2431 }
2432 
2433 }  // namespace gl
2434