• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "libGLESv2/State.h"
10 
11 #include "libGLESv2/Context.h"
12 #include "libGLESv2/Caps.h"
13 #include "libGLESv2/VertexArray.h"
14 #include "libGLESv2/Query.h"
15 #include "libGLESv2/Framebuffer.h"
16 #include "libGLESv2/FramebufferAttachment.h"
17 #include "libGLESv2/renderer/RenderTarget.h"
18 #include "libGLESv2/formatutils.h"
19 
20 namespace gl
21 {
22 
State()23 State::State()
24 {
25 }
26 
~State()27 State::~State()
28 {
29     reset();
30 }
31 
initialize(const Caps & caps,GLuint clientVersion)32 void State::initialize(const Caps& caps, GLuint clientVersion)
33 {
34     mContext = NULL;
35 
36     setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
37 
38     mDepthClearValue = 1.0f;
39     mStencilClearValue = 0;
40 
41     mRasterizer.rasterizerDiscard = false;
42     mRasterizer.cullFace = false;
43     mRasterizer.cullMode = GL_BACK;
44     mRasterizer.frontFace = GL_CCW;
45     mRasterizer.polygonOffsetFill = false;
46     mRasterizer.polygonOffsetFactor = 0.0f;
47     mRasterizer.polygonOffsetUnits = 0.0f;
48     mRasterizer.pointDrawMode = false;
49     mRasterizer.multiSample = false;
50     mScissorTest = false;
51     mScissor.x = 0;
52     mScissor.y = 0;
53     mScissor.width = 0;
54     mScissor.height = 0;
55 
56     mBlend.blend = false;
57     mBlend.sourceBlendRGB = GL_ONE;
58     mBlend.sourceBlendAlpha = GL_ONE;
59     mBlend.destBlendRGB = GL_ZERO;
60     mBlend.destBlendAlpha = GL_ZERO;
61     mBlend.blendEquationRGB = GL_FUNC_ADD;
62     mBlend.blendEquationAlpha = GL_FUNC_ADD;
63     mBlend.sampleAlphaToCoverage = false;
64     mBlend.dither = true;
65 
66     mBlendColor.red = 0;
67     mBlendColor.green = 0;
68     mBlendColor.blue = 0;
69     mBlendColor.alpha = 0;
70 
71     mDepthStencil.depthTest = false;
72     mDepthStencil.depthFunc = GL_LESS;
73     mDepthStencil.depthMask = true;
74     mDepthStencil.stencilTest = false;
75     mDepthStencil.stencilFunc = GL_ALWAYS;
76     mDepthStencil.stencilMask = -1;
77     mDepthStencil.stencilWritemask = -1;
78     mDepthStencil.stencilBackFunc = GL_ALWAYS;
79     mDepthStencil.stencilBackMask = -1;
80     mDepthStencil.stencilBackWritemask = -1;
81     mDepthStencil.stencilFail = GL_KEEP;
82     mDepthStencil.stencilPassDepthFail = GL_KEEP;
83     mDepthStencil.stencilPassDepthPass = GL_KEEP;
84     mDepthStencil.stencilBackFail = GL_KEEP;
85     mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
86     mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
87 
88     mStencilRef = 0;
89     mStencilBackRef = 0;
90 
91     mSampleCoverage = false;
92     mSampleCoverageValue = 1.0f;
93     mSampleCoverageInvert = false;
94     mGenerateMipmapHint = GL_DONT_CARE;
95     mFragmentShaderDerivativeHint = GL_DONT_CARE;
96 
97     mLineWidth = 1.0f;
98 
99     mViewport.x = 0;
100     mViewport.y = 0;
101     mViewport.width = 0;
102     mViewport.height = 0;
103     mNearZ = 0.0f;
104     mFarZ = 1.0f;
105 
106     mBlend.colorMaskRed = true;
107     mBlend.colorMaskGreen = true;
108     mBlend.colorMaskBlue = true;
109     mBlend.colorMaskAlpha = true;
110 
111     mActiveSampler = 0;
112 
113     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
114     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
115     {
116         mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
117     }
118 
119     mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
120     mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
121     if (clientVersion >= 3)
122     {
123         // TODO: These could also be enabled via extension
124         mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
125         mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
126     }
127 
128     mSamplers.resize(caps.maxCombinedTextureImageUnits);
129 
130     mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
131     mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
132     mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
133 
134     mCurrentProgramId = 0;
135     mCurrentProgramBinary.set(NULL);
136 
137     mReadFramebuffer = NULL;
138     mDrawFramebuffer = NULL;
139 }
140 
reset()141 void State::reset()
142 {
143     for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
144     {
145         TextureBindingVector &textureVector = bindingVec->second;
146         for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
147         {
148             textureVector[textureIdx].set(NULL);
149         }
150     }
151     for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
152     {
153         mSamplers[samplerIdx].set(NULL);
154     }
155 
156     const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
157     for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
158     {
159         mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
160     }
161 
162     mArrayBuffer.set(NULL);
163     mRenderbuffer.set(NULL);
164 
165     mTransformFeedback.set(NULL);
166 
167     for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
168     {
169         i->second.set(NULL);
170     }
171 
172     mGenericUniformBuffer.set(NULL);
173     for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
174     {
175         mUniformBuffers[i].set(NULL);
176     }
177 
178     mGenericTransformFeedbackBuffer.set(NULL);
179     for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
180     {
181         mTransformFeedbackBuffers[i].set(NULL);
182     }
183 
184     mCopyReadBuffer.set(NULL);
185     mCopyWriteBuffer.set(NULL);
186 
187     mPack.pixelBuffer.set(NULL);
188     mUnpack.pixelBuffer.set(NULL);
189 }
190 
getRasterizerState() const191 const RasterizerState &State::getRasterizerState() const
192 {
193     return mRasterizer;
194 }
195 
getBlendState() const196 const BlendState &State::getBlendState() const
197 {
198     return mBlend;
199 }
200 
getDepthStencilState() const201 const DepthStencilState &State::getDepthStencilState() const
202 {
203     return mDepthStencil;
204 }
205 
setClearColor(float red,float green,float blue,float alpha)206 void State::setClearColor(float red, float green, float blue, float alpha)
207 {
208     mColorClearValue.red = red;
209     mColorClearValue.green = green;
210     mColorClearValue.blue = blue;
211     mColorClearValue.alpha = alpha;
212 }
213 
setClearDepth(float depth)214 void State::setClearDepth(float depth)
215 {
216     mDepthClearValue = depth;
217 }
218 
setClearStencil(int stencil)219 void State::setClearStencil(int stencil)
220 {
221     mStencilClearValue = stencil;
222 }
223 
getClearParameters(GLbitfield mask) const224 ClearParameters State::getClearParameters(GLbitfield mask) const
225 {
226     ClearParameters clearParams = { 0 };
227     for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
228     {
229         clearParams.clearColor[i] = false;
230     }
231     clearParams.colorFClearValue = mColorClearValue;
232     clearParams.colorClearType = GL_FLOAT;
233     clearParams.colorMaskRed = mBlend.colorMaskRed;
234     clearParams.colorMaskGreen = mBlend.colorMaskGreen;
235     clearParams.colorMaskBlue = mBlend.colorMaskBlue;
236     clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
237     clearParams.clearDepth = false;
238     clearParams.depthClearValue = mDepthClearValue;
239     clearParams.clearStencil = false;
240     clearParams.stencilClearValue = mStencilClearValue;
241     clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
242     clearParams.scissorEnabled = mScissorTest;
243     clearParams.scissor = mScissor;
244 
245     const Framebuffer *framebufferObject = getDrawFramebuffer();
246     if (mask & GL_COLOR_BUFFER_BIT)
247     {
248         if (framebufferObject->hasEnabledColorAttachment())
249         {
250             for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
251             {
252                 clearParams.clearColor[i] = true;
253             }
254         }
255     }
256 
257     if (mask & GL_DEPTH_BUFFER_BIT)
258     {
259         if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
260         {
261             clearParams.clearDepth = true;
262         }
263     }
264 
265     if (mask & GL_STENCIL_BUFFER_BIT)
266     {
267         if (framebufferObject->getStencilbuffer() != NULL)
268         {
269             GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
270             if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
271             {
272                 clearParams.clearStencil = true;
273             }
274         }
275     }
276 
277     return clearParams;
278 }
279 
setColorMask(bool red,bool green,bool blue,bool alpha)280 void State::setColorMask(bool red, bool green, bool blue, bool alpha)
281 {
282     mBlend.colorMaskRed = red;
283     mBlend.colorMaskGreen = green;
284     mBlend.colorMaskBlue = blue;
285     mBlend.colorMaskAlpha = alpha;
286 }
287 
setDepthMask(bool mask)288 void State::setDepthMask(bool mask)
289 {
290     mDepthStencil.depthMask = mask;
291 }
292 
isRasterizerDiscardEnabled() const293 bool State::isRasterizerDiscardEnabled() const
294 {
295     return mRasterizer.rasterizerDiscard;
296 }
297 
setRasterizerDiscard(bool enabled)298 void State::setRasterizerDiscard(bool enabled)
299 {
300     mRasterizer.rasterizerDiscard = enabled;
301 }
302 
isCullFaceEnabled() const303 bool State::isCullFaceEnabled() const
304 {
305     return mRasterizer.cullFace;
306 }
307 
setCullFace(bool enabled)308 void State::setCullFace(bool enabled)
309 {
310     mRasterizer.cullFace = enabled;
311 }
312 
setCullMode(GLenum mode)313 void State::setCullMode(GLenum mode)
314 {
315     mRasterizer.cullMode = mode;
316 }
317 
setFrontFace(GLenum front)318 void State::setFrontFace(GLenum front)
319 {
320     mRasterizer.frontFace = front;
321 }
322 
isDepthTestEnabled() const323 bool State::isDepthTestEnabled() const
324 {
325     return mDepthStencil.depthTest;
326 }
327 
setDepthTest(bool enabled)328 void State::setDepthTest(bool enabled)
329 {
330     mDepthStencil.depthTest = enabled;
331 }
332 
setDepthFunc(GLenum depthFunc)333 void State::setDepthFunc(GLenum depthFunc)
334 {
335      mDepthStencil.depthFunc = depthFunc;
336 }
337 
setDepthRange(float zNear,float zFar)338 void State::setDepthRange(float zNear, float zFar)
339 {
340     mNearZ = zNear;
341     mFarZ = zFar;
342 }
343 
getDepthRange(float * zNear,float * zFar) const344 void State::getDepthRange(float *zNear, float *zFar) const
345 {
346     *zNear = mNearZ;
347     *zFar = mFarZ;
348 }
349 
isBlendEnabled() const350 bool State::isBlendEnabled() const
351 {
352     return mBlend.blend;
353 }
354 
setBlend(bool enabled)355 void State::setBlend(bool enabled)
356 {
357     mBlend.blend = enabled;
358 }
359 
setBlendFactors(GLenum sourceRGB,GLenum destRGB,GLenum sourceAlpha,GLenum destAlpha)360 void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
361 {
362     mBlend.sourceBlendRGB = sourceRGB;
363     mBlend.destBlendRGB = destRGB;
364     mBlend.sourceBlendAlpha = sourceAlpha;
365     mBlend.destBlendAlpha = destAlpha;
366 }
367 
setBlendColor(float red,float green,float blue,float alpha)368 void State::setBlendColor(float red, float green, float blue, float alpha)
369 {
370     mBlendColor.red = red;
371     mBlendColor.green = green;
372     mBlendColor.blue = blue;
373     mBlendColor.alpha = alpha;
374 }
375 
setBlendEquation(GLenum rgbEquation,GLenum alphaEquation)376 void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
377 {
378     mBlend.blendEquationRGB = rgbEquation;
379     mBlend.blendEquationAlpha = alphaEquation;
380 }
381 
getBlendColor() const382 const ColorF &State::getBlendColor() const
383 {
384     return mBlendColor;
385 }
386 
isStencilTestEnabled() const387 bool State::isStencilTestEnabled() const
388 {
389     return mDepthStencil.stencilTest;
390 }
391 
setStencilTest(bool enabled)392 void State::setStencilTest(bool enabled)
393 {
394     mDepthStencil.stencilTest = enabled;
395 }
396 
setStencilParams(GLenum stencilFunc,GLint stencilRef,GLuint stencilMask)397 void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
398 {
399     mDepthStencil.stencilFunc = stencilFunc;
400     mStencilRef = (stencilRef > 0) ? stencilRef : 0;
401     mDepthStencil.stencilMask = stencilMask;
402 }
403 
setStencilBackParams(GLenum stencilBackFunc,GLint stencilBackRef,GLuint stencilBackMask)404 void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
405 {
406     mDepthStencil.stencilBackFunc = stencilBackFunc;
407     mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
408     mDepthStencil.stencilBackMask = stencilBackMask;
409 }
410 
setStencilWritemask(GLuint stencilWritemask)411 void State::setStencilWritemask(GLuint stencilWritemask)
412 {
413     mDepthStencil.stencilWritemask = stencilWritemask;
414 }
415 
setStencilBackWritemask(GLuint stencilBackWritemask)416 void State::setStencilBackWritemask(GLuint stencilBackWritemask)
417 {
418     mDepthStencil.stencilBackWritemask = stencilBackWritemask;
419 }
420 
setStencilOperations(GLenum stencilFail,GLenum stencilPassDepthFail,GLenum stencilPassDepthPass)421 void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
422 {
423     mDepthStencil.stencilFail = stencilFail;
424     mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
425     mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
426 }
427 
setStencilBackOperations(GLenum stencilBackFail,GLenum stencilBackPassDepthFail,GLenum stencilBackPassDepthPass)428 void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
429 {
430     mDepthStencil.stencilBackFail = stencilBackFail;
431     mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
432     mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
433 }
434 
getStencilRef() const435 GLint State::getStencilRef() const
436 {
437     return mStencilRef;
438 }
439 
getStencilBackRef() const440 GLint State::getStencilBackRef() const
441 {
442     return mStencilBackRef;
443 }
444 
isPolygonOffsetFillEnabled() const445 bool State::isPolygonOffsetFillEnabled() const
446 {
447     return mRasterizer.polygonOffsetFill;
448 }
449 
setPolygonOffsetFill(bool enabled)450 void State::setPolygonOffsetFill(bool enabled)
451 {
452      mRasterizer.polygonOffsetFill = enabled;
453 }
454 
setPolygonOffsetParams(GLfloat factor,GLfloat units)455 void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
456 {
457     // An application can pass NaN values here, so handle this gracefully
458     mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
459     mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
460 }
461 
isSampleAlphaToCoverageEnabled() const462 bool State::isSampleAlphaToCoverageEnabled() const
463 {
464     return mBlend.sampleAlphaToCoverage;
465 }
466 
setSampleAlphaToCoverage(bool enabled)467 void State::setSampleAlphaToCoverage(bool enabled)
468 {
469     mBlend.sampleAlphaToCoverage = enabled;
470 }
471 
isSampleCoverageEnabled() const472 bool State::isSampleCoverageEnabled() const
473 {
474     return mSampleCoverage;
475 }
476 
setSampleCoverage(bool enabled)477 void State::setSampleCoverage(bool enabled)
478 {
479     mSampleCoverage = enabled;
480 }
481 
setSampleCoverageParams(GLclampf value,bool invert)482 void State::setSampleCoverageParams(GLclampf value, bool invert)
483 {
484     mSampleCoverageValue = value;
485     mSampleCoverageInvert = invert;
486 }
487 
getSampleCoverageParams(GLclampf * value,bool * invert)488 void State::getSampleCoverageParams(GLclampf *value, bool *invert)
489 {
490     ASSERT(value != NULL && invert != NULL);
491 
492     *value = mSampleCoverageValue;
493     *invert = mSampleCoverageInvert;
494 }
495 
isScissorTestEnabled() const496 bool State::isScissorTestEnabled() const
497 {
498     return mScissorTest;
499 }
500 
setScissorTest(bool enabled)501 void State::setScissorTest(bool enabled)
502 {
503     mScissorTest = enabled;
504 }
505 
setScissorParams(GLint x,GLint y,GLsizei width,GLsizei height)506 void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
507 {
508     mScissor.x = x;
509     mScissor.y = y;
510     mScissor.width = width;
511     mScissor.height = height;
512 }
513 
getScissor() const514 const Rectangle &State::getScissor() const
515 {
516     return mScissor;
517 }
518 
isDitherEnabled() const519 bool State::isDitherEnabled() const
520 {
521     return mBlend.dither;
522 }
523 
setDither(bool enabled)524 void State::setDither(bool enabled)
525 {
526     mBlend.dither = enabled;
527 }
528 
setEnableFeature(GLenum feature,bool enabled)529 void State::setEnableFeature(GLenum feature, bool enabled)
530 {
531     switch (feature)
532     {
533       case GL_CULL_FACE:                     setCullFace(enabled);              break;
534       case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
535       case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
536       case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
537       case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
538       case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
539       case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
540       case GL_BLEND:                         setBlend(enabled);                 break;
541       case GL_DITHER:                        setDither(enabled);                break;
542       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
543       case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
544       default:                               UNREACHABLE();
545     }
546 }
547 
getEnableFeature(GLenum feature)548 bool State::getEnableFeature(GLenum feature)
549 {
550     switch (feature)
551     {
552       case GL_CULL_FACE:                     return isCullFaceEnabled();
553       case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
554       case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
555       case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
556       case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
557       case GL_STENCIL_TEST:                  return isStencilTestEnabled();
558       case GL_DEPTH_TEST:                    return isDepthTestEnabled();
559       case GL_BLEND:                         return isBlendEnabled();
560       case GL_DITHER:                        return isDitherEnabled();
561       case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
562       case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
563       default:                               UNREACHABLE(); return false;
564     }
565 }
566 
setLineWidth(GLfloat width)567 void State::setLineWidth(GLfloat width)
568 {
569     mLineWidth = width;
570 }
571 
setGenerateMipmapHint(GLenum hint)572 void State::setGenerateMipmapHint(GLenum hint)
573 {
574     mGenerateMipmapHint = hint;
575 }
576 
setFragmentShaderDerivativeHint(GLenum hint)577 void State::setFragmentShaderDerivativeHint(GLenum hint)
578 {
579     mFragmentShaderDerivativeHint = hint;
580     // TODO: Propagate the hint to shader translator so we can write
581     // ddx, ddx_coarse, or ddx_fine depending on the hint.
582     // Ignore for now. It is valid for implementations to ignore hint.
583 }
584 
setViewportParams(GLint x,GLint y,GLsizei width,GLsizei height)585 void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
586 {
587     mViewport.x = x;
588     mViewport.y = y;
589     mViewport.width = width;
590     mViewport.height = height;
591 }
592 
getViewport() const593 const Rectangle &State::getViewport() const
594 {
595     return mViewport;
596 }
597 
setActiveSampler(unsigned int active)598 void State::setActiveSampler(unsigned int active)
599 {
600     mActiveSampler = active;
601 }
602 
getActiveSampler() const603 unsigned int State::getActiveSampler() const
604 {
605     return mActiveSampler;
606 }
607 
setSamplerTexture(GLenum type,Texture * texture)608 void State::setSamplerTexture(GLenum type, Texture *texture)
609 {
610     mSamplerTextures[type][mActiveSampler].set(texture);
611 }
612 
getSamplerTexture(unsigned int sampler,GLenum type) const613 Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
614 {
615     const BindingPointer<Texture>& binding = mSamplerTextures.at(type)[sampler];
616 
617     if (binding.id() == 0)   // Special case: 0 refers to default textures held by Context
618     {
619         return NULL;
620     }
621 
622     return binding.get();
623 }
624 
getSamplerTextureId(unsigned int sampler,GLenum type) const625 GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
626 {
627     return mSamplerTextures.at(type)[sampler].id();
628 }
629 
detachTexture(GLuint texture)630 void State::detachTexture(GLuint texture)
631 {
632     // Textures have a detach method on State rather than a simple
633     // removeBinding, because the zero/null texture objects are managed
634     // separately, and don't have to go through the Context's maps or
635     // the ResourceManager.
636 
637     // [OpenGL ES 2.0.24] section 3.8 page 84:
638     // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
639     // rebound to texture object zero
640 
641     for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
642     {
643         TextureBindingVector &textureVector = bindingVec->second;
644         for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
645         {
646             BindingPointer<Texture> &binding = textureVector[textureIdx];
647             if (binding.id() == texture)
648             {
649                 binding.set(NULL);
650             }
651         }
652     }
653 
654     // [OpenGL ES 2.0.24] section 4.4 page 112:
655     // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
656     // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
657     // image was attached in the currently bound framebuffer.
658 
659     if (mReadFramebuffer)
660     {
661         mReadFramebuffer->detachTexture(texture);
662     }
663 
664     if (mDrawFramebuffer)
665     {
666         mDrawFramebuffer->detachTexture(texture);
667     }
668 }
669 
setSamplerBinding(GLuint textureUnit,Sampler * sampler)670 void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
671 {
672     mSamplers[textureUnit].set(sampler);
673 }
674 
getSamplerId(GLuint textureUnit) const675 GLuint State::getSamplerId(GLuint textureUnit) const
676 {
677     ASSERT(textureUnit < mSamplers.size());
678     return mSamplers[textureUnit].id();
679 }
680 
getSampler(GLuint textureUnit) const681 Sampler *State::getSampler(GLuint textureUnit) const
682 {
683     return mSamplers[textureUnit].get();
684 }
685 
detachSampler(GLuint sampler)686 void State::detachSampler(GLuint sampler)
687 {
688     // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
689     // If a sampler object that is currently bound to one or more texture units is
690     // deleted, it is as though BindSampler is called once for each texture unit to
691     // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
692     for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
693     {
694         BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
695         if (samplerBinding.id() == sampler)
696         {
697             samplerBinding.set(NULL);
698         }
699     }
700 }
701 
setRenderbufferBinding(Renderbuffer * renderbuffer)702 void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
703 {
704     mRenderbuffer.set(renderbuffer);
705 }
706 
getRenderbufferId() const707 GLuint State::getRenderbufferId() const
708 {
709     return mRenderbuffer.id();
710 }
711 
getCurrentRenderbuffer()712 Renderbuffer *State::getCurrentRenderbuffer()
713 {
714     return mRenderbuffer.get();
715 }
716 
detachRenderbuffer(GLuint renderbuffer)717 void State::detachRenderbuffer(GLuint renderbuffer)
718 {
719     // [OpenGL ES 2.0.24] section 4.4 page 109:
720     // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
721     // had been executed with the target RENDERBUFFER and name of zero.
722 
723     if (mRenderbuffer.id() == renderbuffer)
724     {
725         mRenderbuffer.set(NULL);
726     }
727 
728     // [OpenGL ES 2.0.24] section 4.4 page 111:
729     // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
730     // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
731     // point to which this image was attached in the currently bound framebuffer.
732 
733     Framebuffer *readFramebuffer = mReadFramebuffer;
734     Framebuffer *drawFramebuffer = mDrawFramebuffer;
735 
736     if (readFramebuffer)
737     {
738         readFramebuffer->detachRenderbuffer(renderbuffer);
739     }
740 
741     if (drawFramebuffer && drawFramebuffer != readFramebuffer)
742     {
743         drawFramebuffer->detachRenderbuffer(renderbuffer);
744     }
745 
746 }
747 
setReadFramebufferBinding(Framebuffer * framebuffer)748 void State::setReadFramebufferBinding(Framebuffer *framebuffer)
749 {
750     mReadFramebuffer = framebuffer;
751 }
752 
setDrawFramebufferBinding(Framebuffer * framebuffer)753 void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
754 {
755     mDrawFramebuffer = framebuffer;
756 }
757 
getTargetFramebuffer(GLenum target) const758 Framebuffer *State::getTargetFramebuffer(GLenum target) const
759 {
760     switch (target)
761     {
762     case GL_READ_FRAMEBUFFER_ANGLE:  return mReadFramebuffer;
763     case GL_DRAW_FRAMEBUFFER_ANGLE:
764     case GL_FRAMEBUFFER:             return mDrawFramebuffer;
765     default:                         UNREACHABLE(); return NULL;
766     }
767 }
768 
getReadFramebuffer()769 Framebuffer *State::getReadFramebuffer()
770 {
771     return mReadFramebuffer;
772 }
773 
getDrawFramebuffer()774 Framebuffer *State::getDrawFramebuffer()
775 {
776     return mDrawFramebuffer;
777 }
778 
getReadFramebuffer() const779 const Framebuffer *State::getReadFramebuffer() const
780 {
781     return mReadFramebuffer;
782 }
783 
getDrawFramebuffer() const784 const Framebuffer *State::getDrawFramebuffer() const
785 {
786     return mDrawFramebuffer;
787 }
788 
removeReadFramebufferBinding(GLuint framebuffer)789 bool State::removeReadFramebufferBinding(GLuint framebuffer)
790 {
791     if (mReadFramebuffer->id() == framebuffer)
792     {
793         mReadFramebuffer = NULL;
794         return true;
795     }
796 
797     return false;
798 }
799 
removeDrawFramebufferBinding(GLuint framebuffer)800 bool State::removeDrawFramebufferBinding(GLuint framebuffer)
801 {
802     if (mDrawFramebuffer->id() == framebuffer)
803     {
804         mDrawFramebuffer = NULL;
805         return true;
806     }
807 
808     return false;
809 }
810 
setVertexArrayBinding(VertexArray * vertexArray)811 void State::setVertexArrayBinding(VertexArray *vertexArray)
812 {
813     mVertexArray = vertexArray;
814 }
815 
getVertexArrayId() const816 GLuint State::getVertexArrayId() const
817 {
818     ASSERT(mVertexArray != NULL);
819     return mVertexArray->id();
820 }
821 
getVertexArray() const822 VertexArray *State::getVertexArray() const
823 {
824     ASSERT(mVertexArray != NULL);
825     return mVertexArray;
826 }
827 
removeVertexArrayBinding(GLuint vertexArray)828 bool State::removeVertexArrayBinding(GLuint vertexArray)
829 {
830     if (mVertexArray->id() == vertexArray)
831     {
832         mVertexArray = NULL;
833         return true;
834     }
835 
836     return false;
837 }
838 
setCurrentProgram(GLuint programId,Program * newProgram)839 void State::setCurrentProgram(GLuint programId, Program *newProgram)
840 {
841     mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
842     mCurrentProgramBinary.set(NULL);
843 
844     if (newProgram)
845     {
846         newProgram->addRef();
847         mCurrentProgramBinary.set(newProgram->getProgramBinary());
848     }
849 }
850 
setCurrentProgramBinary(ProgramBinary * binary)851 void State::setCurrentProgramBinary(ProgramBinary *binary)
852 {
853     mCurrentProgramBinary.set(binary);
854 }
855 
getCurrentProgramId() const856 GLuint State::getCurrentProgramId() const
857 {
858     return mCurrentProgramId;
859 }
860 
getCurrentProgramBinary() const861 ProgramBinary *State::getCurrentProgramBinary() const
862 {
863     return mCurrentProgramBinary.get();
864 }
865 
setTransformFeedbackBinding(TransformFeedback * transformFeedback)866 void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
867 {
868     mTransformFeedback.set(transformFeedback);
869 }
870 
getCurrentTransformFeedback() const871 TransformFeedback *State::getCurrentTransformFeedback() const
872 {
873     return mTransformFeedback.get();
874 }
875 
detachTransformFeedback(GLuint transformFeedback)876 void State::detachTransformFeedback(GLuint transformFeedback)
877 {
878     if (mTransformFeedback.id() == transformFeedback)
879     {
880         mTransformFeedback.set(NULL);
881     }
882 }
883 
isQueryActive() const884 bool State::isQueryActive() const
885 {
886     for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
887         i != mActiveQueries.end(); i++)
888     {
889         if (i->second.get() != NULL)
890         {
891             return true;
892         }
893     }
894 
895     return false;
896 }
897 
setActiveQuery(GLenum target,Query * query)898 void State::setActiveQuery(GLenum target, Query *query)
899 {
900     mActiveQueries[target].set(query);
901 }
902 
getActiveQueryId(GLenum target) const903 GLuint State::getActiveQueryId(GLenum target) const
904 {
905     const Query *query = getActiveQuery(target);
906     return (query ? query->id() : 0u);
907 }
908 
getActiveQuery(GLenum target) const909 Query *State::getActiveQuery(GLenum target) const
910 {
911     // All query types should already exist in the activeQueries map
912     ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
913 
914     return mActiveQueries.at(target).get();
915 }
916 
setArrayBufferBinding(Buffer * buffer)917 void State::setArrayBufferBinding(Buffer *buffer)
918 {
919     mArrayBuffer.set(buffer);
920 }
921 
getArrayBufferId() const922 GLuint State::getArrayBufferId() const
923 {
924     return mArrayBuffer.id();
925 }
926 
removeArrayBufferBinding(GLuint buffer)927 bool State::removeArrayBufferBinding(GLuint buffer)
928 {
929     if (mArrayBuffer.id() == buffer)
930     {
931         mArrayBuffer.set(NULL);
932         return true;
933     }
934 
935     return false;
936 }
937 
setGenericUniformBufferBinding(Buffer * buffer)938 void State::setGenericUniformBufferBinding(Buffer *buffer)
939 {
940     mGenericUniformBuffer.set(buffer);
941 }
942 
setIndexedUniformBufferBinding(GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)943 void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
944 {
945     mUniformBuffers[index].set(buffer, offset, size);
946 }
947 
getIndexedUniformBufferId(GLuint index) const948 GLuint State::getIndexedUniformBufferId(GLuint index) const
949 {
950     ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
951 
952     return mUniformBuffers[index].id();
953 }
954 
getIndexedUniformBuffer(GLuint index) const955 Buffer *State::getIndexedUniformBuffer(GLuint index) const
956 {
957     ASSERT(index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS);
958 
959     return mUniformBuffers[index].get();
960 }
961 
setGenericTransformFeedbackBufferBinding(Buffer * buffer)962 void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
963 {
964     mGenericTransformFeedbackBuffer.set(buffer);
965 }
966 
setIndexedTransformFeedbackBufferBinding(GLuint index,Buffer * buffer,GLintptr offset,GLsizeiptr size)967 void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
968 {
969     mTransformFeedbackBuffers[index].set(buffer, offset, size);
970 }
971 
getIndexedTransformFeedbackBufferId(GLuint index) const972 GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
973 {
974     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
975 
976     return mTransformFeedbackBuffers[index].id();
977 }
978 
getIndexedTransformFeedbackBuffer(GLuint index) const979 Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
980 {
981     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
982 
983     return mTransformFeedbackBuffers[index].get();
984 }
985 
getIndexedTransformFeedbackBufferOffset(GLuint index) const986 GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
987 {
988     ASSERT(index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS);
989 
990     return mTransformFeedbackBuffers[index].getOffset();
991 }
992 
setCopyReadBufferBinding(Buffer * buffer)993 void State::setCopyReadBufferBinding(Buffer *buffer)
994 {
995     mCopyReadBuffer.set(buffer);
996 }
997 
setCopyWriteBufferBinding(Buffer * buffer)998 void State::setCopyWriteBufferBinding(Buffer *buffer)
999 {
1000     mCopyWriteBuffer.set(buffer);
1001 }
1002 
setPixelPackBufferBinding(Buffer * buffer)1003 void State::setPixelPackBufferBinding(Buffer *buffer)
1004 {
1005     mPack.pixelBuffer.set(buffer);
1006 }
1007 
setPixelUnpackBufferBinding(Buffer * buffer)1008 void State::setPixelUnpackBufferBinding(Buffer *buffer)
1009 {
1010     mUnpack.pixelBuffer.set(buffer);
1011 }
1012 
getTargetBuffer(GLenum target) const1013 Buffer *State::getTargetBuffer(GLenum target) const
1014 {
1015     switch (target)
1016     {
1017       case GL_ARRAY_BUFFER:              return mArrayBuffer.get();
1018       case GL_COPY_READ_BUFFER:          return mCopyReadBuffer.get();
1019       case GL_COPY_WRITE_BUFFER:         return mCopyWriteBuffer.get();
1020       case GL_ELEMENT_ARRAY_BUFFER:      return getVertexArray()->getElementArrayBuffer();
1021       case GL_PIXEL_PACK_BUFFER:         return mPack.pixelBuffer.get();
1022       case GL_PIXEL_UNPACK_BUFFER:       return mUnpack.pixelBuffer.get();
1023       case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1024       case GL_UNIFORM_BUFFER:            return mGenericUniformBuffer.get();
1025       default: UNREACHABLE();            return NULL;
1026     }
1027 }
1028 
setEnableVertexAttribArray(unsigned int attribNum,bool enabled)1029 void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1030 {
1031     getVertexArray()->enableAttribute(attribNum, enabled);
1032 }
1033 
setVertexAttribf(GLuint index,const GLfloat values[4])1034 void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1035 {
1036     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
1037     mVertexAttribCurrentValues[index].setFloatValues(values);
1038 }
1039 
setVertexAttribu(GLuint index,const GLuint values[4])1040 void State::setVertexAttribu(GLuint index, const GLuint values[4])
1041 {
1042     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
1043     mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1044 }
1045 
setVertexAttribi(GLuint index,const GLint values[4])1046 void State::setVertexAttribi(GLuint index, const GLint values[4])
1047 {
1048     ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
1049     mVertexAttribCurrentValues[index].setIntValues(values);
1050 }
1051 
setVertexAttribState(unsigned int attribNum,Buffer * boundBuffer,GLint size,GLenum type,bool normalized,bool pureInteger,GLsizei stride,const void * pointer)1052 void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1053     bool pureInteger, GLsizei stride, const void *pointer)
1054 {
1055     getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1056 }
1057 
getVertexAttribState(unsigned int attribNum) const1058 const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1059 {
1060     return getVertexArray()->getVertexAttribute(attribNum);
1061 }
1062 
getVertexAttribCurrentValue(unsigned int attribNum) const1063 const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1064 {
1065     ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
1066     return mVertexAttribCurrentValues[attribNum];
1067 }
1068 
getVertexAttribCurrentValues() const1069 const VertexAttribCurrentValueData *State::getVertexAttribCurrentValues() const
1070 {
1071     return mVertexAttribCurrentValues;
1072 }
1073 
getVertexAttribPointer(unsigned int attribNum) const1074 const void *State::getVertexAttribPointer(unsigned int attribNum) const
1075 {
1076     return getVertexArray()->getVertexAttribute(attribNum).pointer;
1077 }
1078 
setPackAlignment(GLint alignment)1079 void State::setPackAlignment(GLint alignment)
1080 {
1081     mPack.alignment = alignment;
1082 }
1083 
getPackAlignment() const1084 GLint State::getPackAlignment() const
1085 {
1086     return mPack.alignment;
1087 }
1088 
setPackReverseRowOrder(bool reverseRowOrder)1089 void State::setPackReverseRowOrder(bool reverseRowOrder)
1090 {
1091     mPack.reverseRowOrder = reverseRowOrder;
1092 }
1093 
getPackReverseRowOrder() const1094 bool State::getPackReverseRowOrder() const
1095 {
1096     return mPack.reverseRowOrder;
1097 }
1098 
getPackState() const1099 const PixelPackState &State::getPackState() const
1100 {
1101     return mPack;
1102 }
1103 
setUnpackAlignment(GLint alignment)1104 void State::setUnpackAlignment(GLint alignment)
1105 {
1106     mUnpack.alignment = alignment;
1107 }
1108 
getUnpackAlignment() const1109 GLint State::getUnpackAlignment() const
1110 {
1111     return mUnpack.alignment;
1112 }
1113 
getUnpackState() const1114 const PixelUnpackState &State::getUnpackState() const
1115 {
1116     return mUnpack;
1117 }
1118 
getBooleanv(GLenum pname,GLboolean * params)1119 void State::getBooleanv(GLenum pname, GLboolean *params)
1120 {
1121     switch (pname)
1122     {
1123       case GL_SAMPLE_COVERAGE_INVERT:    *params = mSampleCoverageInvert;         break;
1124       case GL_DEPTH_WRITEMASK:           *params = mDepthStencil.depthMask;       break;
1125       case GL_COLOR_WRITEMASK:
1126         params[0] = mBlend.colorMaskRed;
1127         params[1] = mBlend.colorMaskGreen;
1128         params[2] = mBlend.colorMaskBlue;
1129         params[3] = mBlend.colorMaskAlpha;
1130         break;
1131       case GL_CULL_FACE:                 *params = mRasterizer.cullFace;          break;
1132       case GL_POLYGON_OFFSET_FILL:       *params = mRasterizer.polygonOffsetFill; break;
1133       case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mBlend.sampleAlphaToCoverage;  break;
1134       case GL_SAMPLE_COVERAGE:           *params = mSampleCoverage;               break;
1135       case GL_SCISSOR_TEST:              *params = mScissorTest;                  break;
1136       case GL_STENCIL_TEST:              *params = mDepthStencil.stencilTest;     break;
1137       case GL_DEPTH_TEST:                *params = mDepthStencil.depthTest;       break;
1138       case GL_BLEND:                     *params = mBlend.blend;                  break;
1139       case GL_DITHER:                    *params = mBlend.dither;                 break;
1140       case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1141       case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
1142       default:
1143         UNREACHABLE();
1144         break;
1145     }
1146 }
1147 
getFloatv(GLenum pname,GLfloat * params)1148 void State::getFloatv(GLenum pname, GLfloat *params)
1149 {
1150     // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1151     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1152     // GetIntegerv as its native query function. As it would require conversion in any
1153     // case, this should make no difference to the calling application.
1154     switch (pname)
1155     {
1156       case GL_LINE_WIDTH:               *params = mLineWidth;                         break;
1157       case GL_SAMPLE_COVERAGE_VALUE:    *params = mSampleCoverageValue;               break;
1158       case GL_DEPTH_CLEAR_VALUE:        *params = mDepthClearValue;                   break;
1159       case GL_POLYGON_OFFSET_FACTOR:    *params = mRasterizer.polygonOffsetFactor;    break;
1160       case GL_POLYGON_OFFSET_UNITS:     *params = mRasterizer.polygonOffsetUnits;     break;
1161       case GL_DEPTH_RANGE:
1162         params[0] = mNearZ;
1163         params[1] = mFarZ;
1164         break;
1165       case GL_COLOR_CLEAR_VALUE:
1166         params[0] = mColorClearValue.red;
1167         params[1] = mColorClearValue.green;
1168         params[2] = mColorClearValue.blue;
1169         params[3] = mColorClearValue.alpha;
1170         break;
1171       case GL_BLEND_COLOR:
1172         params[0] = mBlendColor.red;
1173         params[1] = mBlendColor.green;
1174         params[2] = mBlendColor.blue;
1175         params[3] = mBlendColor.alpha;
1176         break;
1177       default:
1178         UNREACHABLE();
1179         break;
1180     }
1181 }
1182 
getIntegerv(GLenum pname,GLint * params)1183 void State::getIntegerv(GLenum pname, GLint *params)
1184 {
1185     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1186     {
1187         unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1188         ASSERT(colorAttachment < mContext->getCaps().maxDrawBuffers);
1189         Framebuffer *framebuffer = mDrawFramebuffer;
1190         *params = framebuffer->getDrawBufferState(colorAttachment);
1191         return;
1192     }
1193 
1194     // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1195     // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1196     // GetIntegerv as its native query function. As it would require conversion in any
1197     // case, this should make no difference to the calling application. You may find it in
1198     // State::getFloatv.
1199     switch (pname)
1200     {
1201       case GL_ARRAY_BUFFER_BINDING:                     *params = mArrayBuffer.id();                              break;
1202       case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getVertexArray()->getElementArrayBufferId();    break;
1203         //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1204       case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mDrawFramebuffer->id();                         break;
1205       case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mReadFramebuffer->id();                         break;
1206       case GL_RENDERBUFFER_BINDING:                     *params = mRenderbuffer.id();                             break;
1207       case GL_VERTEX_ARRAY_BINDING:                     *params = mVertexArray->id();                             break;
1208       case GL_CURRENT_PROGRAM:                          *params = mCurrentProgramId;                              break;
1209       case GL_PACK_ALIGNMENT:                           *params = mPack.alignment;                                break;
1210       case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mPack.reverseRowOrder;                          break;
1211       case GL_UNPACK_ALIGNMENT:                         *params = mUnpack.alignment;                              break;
1212       case GL_GENERATE_MIPMAP_HINT:                     *params = mGenerateMipmapHint;                            break;
1213       case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mFragmentShaderDerivativeHint;                  break;
1214       case GL_ACTIVE_TEXTURE:                           *params = (mActiveSampler + GL_TEXTURE0);                 break;
1215       case GL_STENCIL_FUNC:                             *params = mDepthStencil.stencilFunc;                      break;
1216       case GL_STENCIL_REF:                              *params = mStencilRef;                                    break;
1217       case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mDepthStencil.stencilMask);          break;
1218       case GL_STENCIL_BACK_FUNC:                        *params = mDepthStencil.stencilBackFunc;                  break;
1219       case GL_STENCIL_BACK_REF:                         *params = mStencilBackRef;                                break;
1220       case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mDepthStencil.stencilBackMask);      break;
1221       case GL_STENCIL_FAIL:                             *params = mDepthStencil.stencilFail;                      break;
1222       case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mDepthStencil.stencilPassDepthFail;             break;
1223       case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mDepthStencil.stencilPassDepthPass;             break;
1224       case GL_STENCIL_BACK_FAIL:                        *params = mDepthStencil.stencilBackFail;                  break;
1225       case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mDepthStencil.stencilBackPassDepthFail;         break;
1226       case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mDepthStencil.stencilBackPassDepthPass;         break;
1227       case GL_DEPTH_FUNC:                               *params = mDepthStencil.depthFunc;                        break;
1228       case GL_BLEND_SRC_RGB:                            *params = mBlend.sourceBlendRGB;                          break;
1229       case GL_BLEND_SRC_ALPHA:                          *params = mBlend.sourceBlendAlpha;                        break;
1230       case GL_BLEND_DST_RGB:                            *params = mBlend.destBlendRGB;                            break;
1231       case GL_BLEND_DST_ALPHA:                          *params = mBlend.destBlendAlpha;                          break;
1232       case GL_BLEND_EQUATION_RGB:                       *params = mBlend.blendEquationRGB;                        break;
1233       case GL_BLEND_EQUATION_ALPHA:                     *params = mBlend.blendEquationAlpha;                      break;
1234       case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mDepthStencil.stencilWritemask);     break;
1235       case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1236       case GL_STENCIL_CLEAR_VALUE:                      *params = mStencilClearValue;                             break;
1237       case GL_SAMPLE_BUFFERS:
1238       case GL_SAMPLES:
1239         {
1240             gl::Framebuffer *framebuffer = mDrawFramebuffer;
1241             if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1242             {
1243                 switch (pname)
1244                 {
1245                   case GL_SAMPLE_BUFFERS:
1246                     if (framebuffer->getSamples() != 0)
1247                     {
1248                         *params = 1;
1249                     }
1250                     else
1251                     {
1252                         *params = 0;
1253                     }
1254                     break;
1255                   case GL_SAMPLES:
1256                     *params = framebuffer->getSamples();
1257                     break;
1258                 }
1259             }
1260             else
1261             {
1262                 *params = 0;
1263             }
1264         }
1265         break;
1266       case GL_VIEWPORT:
1267         params[0] = mViewport.x;
1268         params[1] = mViewport.y;
1269         params[2] = mViewport.width;
1270         params[3] = mViewport.height;
1271         break;
1272       case GL_SCISSOR_BOX:
1273         params[0] = mScissor.x;
1274         params[1] = mScissor.y;
1275         params[2] = mScissor.width;
1276         params[3] = mScissor.height;
1277         break;
1278       case GL_CULL_FACE_MODE:                   *params = mRasterizer.cullMode;   break;
1279       case GL_FRONT_FACE:                       *params = mRasterizer.frontFace;  break;
1280       case GL_RED_BITS:
1281       case GL_GREEN_BITS:
1282       case GL_BLUE_BITS:
1283       case GL_ALPHA_BITS:
1284         {
1285             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1286             gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1287 
1288             if (colorbuffer)
1289             {
1290                 switch (pname)
1291                 {
1292                 case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
1293                 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
1294                 case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
1295                 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
1296                 }
1297             }
1298             else
1299             {
1300                 *params = 0;
1301             }
1302         }
1303         break;
1304       case GL_DEPTH_BITS:
1305         {
1306             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1307             gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1308 
1309             if (depthbuffer)
1310             {
1311                 *params = depthbuffer->getDepthSize();
1312             }
1313             else
1314             {
1315                 *params = 0;
1316             }
1317         }
1318         break;
1319       case GL_STENCIL_BITS:
1320         {
1321             gl::Framebuffer *framebuffer = getDrawFramebuffer();
1322             gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1323 
1324             if (stencilbuffer)
1325             {
1326                 *params = stencilbuffer->getStencilSize();
1327             }
1328             else
1329             {
1330                 *params = 0;
1331             }
1332         }
1333         break;
1334       case GL_TEXTURE_BINDING_2D:
1335         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
1336         *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
1337         break;
1338       case GL_TEXTURE_BINDING_CUBE_MAP:
1339         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
1340         *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
1341         break;
1342       case GL_TEXTURE_BINDING_3D:
1343         ASSERT(mActiveSampler <mContext->getCaps().maxCombinedTextureImageUnits);
1344         *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
1345         break;
1346       case GL_TEXTURE_BINDING_2D_ARRAY:
1347         ASSERT(mActiveSampler < mContext->getCaps().maxCombinedTextureImageUnits);
1348         *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
1349         break;
1350       case GL_UNIFORM_BUFFER_BINDING:
1351         *params = mGenericUniformBuffer.id();
1352         break;
1353       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1354         *params = mGenericTransformFeedbackBuffer.id();
1355         break;
1356       case GL_COPY_READ_BUFFER_BINDING:
1357         *params = mCopyReadBuffer.id();
1358         break;
1359       case GL_COPY_WRITE_BUFFER_BINDING:
1360         *params = mCopyWriteBuffer.id();
1361         break;
1362       case GL_PIXEL_PACK_BUFFER_BINDING:
1363         *params = mPack.pixelBuffer.id();
1364         break;
1365       case GL_PIXEL_UNPACK_BUFFER_BINDING:
1366         *params = mUnpack.pixelBuffer.id();
1367         break;
1368       default:
1369         UNREACHABLE();
1370         break;
1371     }
1372 }
1373 
getIndexedIntegerv(GLenum target,GLuint index,GLint * data)1374 bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1375 {
1376     switch (target)
1377     {
1378       case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1379         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1380         {
1381             *data = mTransformFeedbackBuffers[index].id();
1382         }
1383         break;
1384       case GL_UNIFORM_BUFFER_BINDING:
1385         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1386         {
1387             *data = mUniformBuffers[index].id();
1388         }
1389         break;
1390       default:
1391         return false;
1392     }
1393 
1394     return true;
1395 }
1396 
getIndexedInteger64v(GLenum target,GLuint index,GLint64 * data)1397 bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1398 {
1399     switch (target)
1400     {
1401       case GL_TRANSFORM_FEEDBACK_BUFFER_START:
1402         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1403         {
1404             *data = mTransformFeedbackBuffers[index].getOffset();
1405         }
1406         break;
1407       case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
1408         if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
1409         {
1410             *data = mTransformFeedbackBuffers[index].getSize();
1411         }
1412         break;
1413       case GL_UNIFORM_BUFFER_START:
1414         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1415         {
1416             *data = mUniformBuffers[index].getOffset();
1417         }
1418         break;
1419       case GL_UNIFORM_BUFFER_SIZE:
1420         if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
1421         {
1422             *data = mUniformBuffers[index].getSize();
1423         }
1424         break;
1425       default:
1426         return false;
1427     }
1428 
1429     return true;
1430 }
1431 
hasMappedBuffer(GLenum target) const1432 bool State::hasMappedBuffer(GLenum target) const
1433 {
1434     if (target == GL_ARRAY_BUFFER)
1435     {
1436         for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
1437         {
1438             const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
1439             gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1440             if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1441             {
1442                 return true;
1443             }
1444         }
1445 
1446         return false;
1447     }
1448     else
1449     {
1450         Buffer *buffer = getTargetBuffer(target);
1451         return (buffer && buffer->isMapped());
1452     }
1453 }
1454 
1455 }
1456