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