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