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