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