blob: ae7978211de016fa8446359f154557b7de052456 [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
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/State.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040010
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
12#include "libANGLE/Caps.h"
13#include "libANGLE/Framebuffer.h"
14#include "libANGLE/FramebufferAttachment.h"
15#include "libANGLE/Query.h"
16#include "libANGLE/VertexArray.h"
17#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040018
19namespace gl
20{
Geoff Lang76b10c92014-09-05 16:28:14 -040021
Shannon Woods53a94a82014-06-24 15:20:36 -040022State::State()
23{
Shannon Woods2df6a602014-09-26 16:12:07 -040024 mMaxDrawBuffers = 0;
25 mMaxCombinedTextureImageUnits = 0;
Geoff Lang76b10c92014-09-05 16:28:14 -040026}
27
28State::~State()
29{
30 reset();
31}
32
33void State::initialize(const Caps& caps, GLuint clientVersion)
34{
Shannon Woods2df6a602014-09-26 16:12:07 -040035 mMaxDrawBuffers = caps.maxDrawBuffers;
36 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040037
38 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
39
40 mDepthClearValue = 1.0f;
41 mStencilClearValue = 0;
42
43 mRasterizer.rasterizerDiscard = false;
44 mRasterizer.cullFace = false;
45 mRasterizer.cullMode = GL_BACK;
46 mRasterizer.frontFace = GL_CCW;
47 mRasterizer.polygonOffsetFill = false;
48 mRasterizer.polygonOffsetFactor = 0.0f;
49 mRasterizer.polygonOffsetUnits = 0.0f;
50 mRasterizer.pointDrawMode = false;
51 mRasterizer.multiSample = false;
52 mScissorTest = false;
53 mScissor.x = 0;
54 mScissor.y = 0;
55 mScissor.width = 0;
56 mScissor.height = 0;
57
58 mBlend.blend = false;
59 mBlend.sourceBlendRGB = GL_ONE;
60 mBlend.sourceBlendAlpha = GL_ONE;
61 mBlend.destBlendRGB = GL_ZERO;
62 mBlend.destBlendAlpha = GL_ZERO;
63 mBlend.blendEquationRGB = GL_FUNC_ADD;
64 mBlend.blendEquationAlpha = GL_FUNC_ADD;
65 mBlend.sampleAlphaToCoverage = false;
66 mBlend.dither = true;
67
68 mBlendColor.red = 0;
69 mBlendColor.green = 0;
70 mBlendColor.blue = 0;
71 mBlendColor.alpha = 0;
72
73 mDepthStencil.depthTest = false;
74 mDepthStencil.depthFunc = GL_LESS;
75 mDepthStencil.depthMask = true;
76 mDepthStencil.stencilTest = false;
77 mDepthStencil.stencilFunc = GL_ALWAYS;
78 mDepthStencil.stencilMask = -1;
79 mDepthStencil.stencilWritemask = -1;
80 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Geoff Lang76b10c92014-09-05 16:28:14 -040081 mDepthStencil.stencilBackMask = -1;
Shannon Woods53a94a82014-06-24 15:20:36 -040082 mDepthStencil.stencilBackWritemask = -1;
83 mDepthStencil.stencilFail = GL_KEEP;
84 mDepthStencil.stencilPassDepthFail = GL_KEEP;
85 mDepthStencil.stencilPassDepthPass = GL_KEEP;
86 mDepthStencil.stencilBackFail = GL_KEEP;
87 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
88 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
89
90 mStencilRef = 0;
91 mStencilBackRef = 0;
92
93 mSampleCoverage = false;
94 mSampleCoverageValue = 1.0f;
95 mSampleCoverageInvert = false;
96 mGenerateMipmapHint = GL_DONT_CARE;
97 mFragmentShaderDerivativeHint = GL_DONT_CARE;
98
99 mLineWidth = 1.0f;
100
101 mViewport.x = 0;
102 mViewport.y = 0;
103 mViewport.width = 0;
104 mViewport.height = 0;
105 mNearZ = 0.0f;
106 mFarZ = 1.0f;
107
108 mBlend.colorMaskRed = true;
109 mBlend.colorMaskGreen = true;
110 mBlend.colorMaskBlue = true;
111 mBlend.colorMaskAlpha = true;
112
Geoff Lang76b10c92014-09-05 16:28:14 -0400113 mActiveSampler = 0;
114
Shannon Woods53a94a82014-06-24 15:20:36 -0400115 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
Shannon Woods23e05002014-09-22 19:07:27 -0400116 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
117 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
Shannon Woods53a94a82014-06-24 15:20:36 -0400118 {
119 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
120 }
121
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400122 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
Shannon Woods8299bb02014-09-26 18:55:43 -0400123 mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400124
Geoff Lang76b10c92014-09-05 16:28:14 -0400125 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
126 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
127 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400128 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400129 // TODO: These could also be enabled via extension
130 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
131 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400132 }
133
Geoff Lang76b10c92014-09-05 16:28:14 -0400134 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400135
136 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
137 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
138 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
139
Geoff Lang7dd2e102014-11-10 15:19:26 -0500140 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400141
142 mReadFramebuffer = NULL;
143 mDrawFramebuffer = NULL;
144}
145
Geoff Lang76b10c92014-09-05 16:28:14 -0400146void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400147{
Geoff Lang76b10c92014-09-05 16:28:14 -0400148 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400149 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400150 TextureBindingVector &textureVector = bindingVec->second;
151 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400152 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400153 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400154 }
155 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400156 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
157 {
158 mSamplers[samplerIdx].set(NULL);
159 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400160
Shannon Woods53a94a82014-06-24 15:20:36 -0400161 mArrayBuffer.set(NULL);
162 mRenderbuffer.set(NULL);
163
Geoff Lang7dd2e102014-11-10 15:19:26 -0500164 if (mProgram)
165 {
166 mProgram->release();
167 }
168 mProgram = NULL;
169
Shannon Woods53a94a82014-06-24 15:20:36 -0400170 mTransformFeedback.set(NULL);
171
172 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
173 {
174 i->second.set(NULL);
175 }
176
177 mGenericUniformBuffer.set(NULL);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400178 mGenericTransformFeedbackBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400179 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400180 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400181 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400182 }
183
Shannon Woods8299bb02014-09-26 18:55:43 -0400184 for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400185 {
Shannon Woods8299bb02014-09-26 18:55:43 -0400186 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400187 }
188
189 mCopyReadBuffer.set(NULL);
190 mCopyWriteBuffer.set(NULL);
191
192 mPack.pixelBuffer.set(NULL);
193 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500194
195 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400196}
197
198const RasterizerState &State::getRasterizerState() const
199{
200 return mRasterizer;
201}
202
203const BlendState &State::getBlendState() const
204{
205 return mBlend;
206}
207
208const DepthStencilState &State::getDepthStencilState() const
209{
210 return mDepthStencil;
211}
212
213void State::setClearColor(float red, float green, float blue, float alpha)
214{
215 mColorClearValue.red = red;
216 mColorClearValue.green = green;
217 mColorClearValue.blue = blue;
218 mColorClearValue.alpha = alpha;
219}
220
221void State::setClearDepth(float depth)
222{
223 mDepthClearValue = depth;
224}
225
226void State::setClearStencil(int stencil)
227{
228 mStencilClearValue = stencil;
229}
230
231ClearParameters State::getClearParameters(GLbitfield mask) const
232{
Jamie Madill639db122014-12-03 11:36:43 -0500233 ClearParameters clearParams;
234 memset(&clearParams, 0, sizeof(ClearParameters));
Shannon Woods53a94a82014-06-24 15:20:36 -0400235 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
236 {
237 clearParams.clearColor[i] = false;
238 }
239 clearParams.colorFClearValue = mColorClearValue;
240 clearParams.colorClearType = GL_FLOAT;
241 clearParams.colorMaskRed = mBlend.colorMaskRed;
242 clearParams.colorMaskGreen = mBlend.colorMaskGreen;
243 clearParams.colorMaskBlue = mBlend.colorMaskBlue;
244 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
245 clearParams.clearDepth = false;
246 clearParams.depthClearValue = mDepthClearValue;
247 clearParams.clearStencil = false;
248 clearParams.stencilClearValue = mStencilClearValue;
249 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
250 clearParams.scissorEnabled = mScissorTest;
251 clearParams.scissor = mScissor;
252
253 const Framebuffer *framebufferObject = getDrawFramebuffer();
254 if (mask & GL_COLOR_BUFFER_BIT)
255 {
256 if (framebufferObject->hasEnabledColorAttachment())
257 {
258 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
259 {
260 clearParams.clearColor[i] = true;
261 }
262 }
263 }
264
265 if (mask & GL_DEPTH_BUFFER_BIT)
266 {
267 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
268 {
269 clearParams.clearDepth = true;
270 }
271 }
272
273 if (mask & GL_STENCIL_BUFFER_BIT)
274 {
Geoff Langd8a22582014-12-17 15:28:23 -0500275 if (framebufferObject->getStencilbuffer() != NULL &&
276 framebufferObject->getStencilbuffer()->getStencilSize() > 0)
Shannon Woods53a94a82014-06-24 15:20:36 -0400277 {
Geoff Langd8a22582014-12-17 15:28:23 -0500278 clearParams.clearStencil = true;
Shannon Woods53a94a82014-06-24 15:20:36 -0400279 }
280 }
281
282 return clearParams;
283}
284
285void State::setColorMask(bool red, bool green, bool blue, bool alpha)
286{
287 mBlend.colorMaskRed = red;
288 mBlend.colorMaskGreen = green;
289 mBlend.colorMaskBlue = blue;
290 mBlend.colorMaskAlpha = alpha;
291}
292
293void State::setDepthMask(bool mask)
294{
295 mDepthStencil.depthMask = mask;
296}
297
298bool State::isRasterizerDiscardEnabled() const
299{
300 return mRasterizer.rasterizerDiscard;
301}
302
303void State::setRasterizerDiscard(bool enabled)
304{
305 mRasterizer.rasterizerDiscard = enabled;
306}
307
308bool State::isCullFaceEnabled() const
309{
310 return mRasterizer.cullFace;
311}
312
313void State::setCullFace(bool enabled)
314{
315 mRasterizer.cullFace = enabled;
316}
317
318void State::setCullMode(GLenum mode)
319{
320 mRasterizer.cullMode = mode;
321}
322
323void State::setFrontFace(GLenum front)
324{
325 mRasterizer.frontFace = front;
326}
327
328bool State::isDepthTestEnabled() const
329{
330 return mDepthStencil.depthTest;
331}
332
333void State::setDepthTest(bool enabled)
334{
335 mDepthStencil.depthTest = enabled;
336}
337
338void State::setDepthFunc(GLenum depthFunc)
339{
340 mDepthStencil.depthFunc = depthFunc;
341}
342
343void State::setDepthRange(float zNear, float zFar)
344{
345 mNearZ = zNear;
346 mFarZ = zFar;
347}
348
349void State::getDepthRange(float *zNear, float *zFar) const
350{
351 *zNear = mNearZ;
352 *zFar = mFarZ;
353}
354
355bool State::isBlendEnabled() const
356{
357 return mBlend.blend;
358}
359
360void State::setBlend(bool enabled)
361{
362 mBlend.blend = enabled;
363}
364
365void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
366{
367 mBlend.sourceBlendRGB = sourceRGB;
368 mBlend.destBlendRGB = destRGB;
369 mBlend.sourceBlendAlpha = sourceAlpha;
370 mBlend.destBlendAlpha = destAlpha;
371}
372
373void State::setBlendColor(float red, float green, float blue, float alpha)
374{
375 mBlendColor.red = red;
376 mBlendColor.green = green;
377 mBlendColor.blue = blue;
378 mBlendColor.alpha = alpha;
379}
380
381void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
382{
383 mBlend.blendEquationRGB = rgbEquation;
384 mBlend.blendEquationAlpha = alphaEquation;
385}
386
387const ColorF &State::getBlendColor() const
388{
389 return mBlendColor;
390}
391
392bool State::isStencilTestEnabled() const
393{
394 return mDepthStencil.stencilTest;
395}
396
397void State::setStencilTest(bool enabled)
398{
399 mDepthStencil.stencilTest = enabled;
400}
401
402void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
403{
404 mDepthStencil.stencilFunc = stencilFunc;
405 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
406 mDepthStencil.stencilMask = stencilMask;
407}
408
409void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
410{
411 mDepthStencil.stencilBackFunc = stencilBackFunc;
412 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
413 mDepthStencil.stencilBackMask = stencilBackMask;
414}
415
416void State::setStencilWritemask(GLuint stencilWritemask)
417{
418 mDepthStencil.stencilWritemask = stencilWritemask;
419}
420
421void State::setStencilBackWritemask(GLuint stencilBackWritemask)
422{
423 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
424}
425
426void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
427{
428 mDepthStencil.stencilFail = stencilFail;
429 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
430 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
431}
432
433void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
434{
435 mDepthStencil.stencilBackFail = stencilBackFail;
436 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
437 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
438}
439
440GLint State::getStencilRef() const
441{
442 return mStencilRef;
443}
444
445GLint State::getStencilBackRef() const
446{
447 return mStencilBackRef;
448}
449
450bool State::isPolygonOffsetFillEnabled() const
451{
452 return mRasterizer.polygonOffsetFill;
453}
454
455void State::setPolygonOffsetFill(bool enabled)
456{
457 mRasterizer.polygonOffsetFill = enabled;
458}
459
460void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
461{
462 // An application can pass NaN values here, so handle this gracefully
463 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
464 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
465}
466
467bool State::isSampleAlphaToCoverageEnabled() const
468{
469 return mBlend.sampleAlphaToCoverage;
470}
471
472void State::setSampleAlphaToCoverage(bool enabled)
473{
474 mBlend.sampleAlphaToCoverage = enabled;
475}
476
477bool State::isSampleCoverageEnabled() const
478{
479 return mSampleCoverage;
480}
481
482void State::setSampleCoverage(bool enabled)
483{
484 mSampleCoverage = enabled;
485}
486
487void State::setSampleCoverageParams(GLclampf value, bool invert)
488{
489 mSampleCoverageValue = value;
490 mSampleCoverageInvert = invert;
491}
492
Jamie Madilld9e58302014-11-06 15:27:26 -0500493void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400494{
495 ASSERT(value != NULL && invert != NULL);
496
497 *value = mSampleCoverageValue;
498 *invert = mSampleCoverageInvert;
499}
500
501bool State::isScissorTestEnabled() const
502{
503 return mScissorTest;
504}
505
506void State::setScissorTest(bool enabled)
507{
508 mScissorTest = enabled;
509}
510
511void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
512{
513 mScissor.x = x;
514 mScissor.y = y;
515 mScissor.width = width;
516 mScissor.height = height;
517}
518
519const Rectangle &State::getScissor() const
520{
521 return mScissor;
522}
523
524bool State::isDitherEnabled() const
525{
526 return mBlend.dither;
527}
528
529void State::setDither(bool enabled)
530{
531 mBlend.dither = enabled;
532}
533
534void State::setEnableFeature(GLenum feature, bool enabled)
535{
536 switch (feature)
537 {
538 case GL_CULL_FACE: setCullFace(enabled); break;
539 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
540 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
541 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
542 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
543 case GL_STENCIL_TEST: setStencilTest(enabled); break;
544 case GL_DEPTH_TEST: setDepthTest(enabled); break;
545 case GL_BLEND: setBlend(enabled); break;
546 case GL_DITHER: setDither(enabled); break;
547 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
548 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
549 default: UNREACHABLE();
550 }
551}
552
553bool State::getEnableFeature(GLenum feature)
554{
555 switch (feature)
556 {
557 case GL_CULL_FACE: return isCullFaceEnabled();
558 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
559 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
560 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
561 case GL_SCISSOR_TEST: return isScissorTestEnabled();
562 case GL_STENCIL_TEST: return isStencilTestEnabled();
563 case GL_DEPTH_TEST: return isDepthTestEnabled();
564 case GL_BLEND: return isBlendEnabled();
565 case GL_DITHER: return isDitherEnabled();
566 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
567 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
568 default: UNREACHABLE(); return false;
569 }
570}
571
572void State::setLineWidth(GLfloat width)
573{
574 mLineWidth = width;
575}
576
577void State::setGenerateMipmapHint(GLenum hint)
578{
579 mGenerateMipmapHint = hint;
580}
581
582void State::setFragmentShaderDerivativeHint(GLenum hint)
583{
584 mFragmentShaderDerivativeHint = hint;
585 // TODO: Propagate the hint to shader translator so we can write
586 // ddx, ddx_coarse, or ddx_fine depending on the hint.
587 // Ignore for now. It is valid for implementations to ignore hint.
588}
589
590void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
591{
592 mViewport.x = x;
593 mViewport.y = y;
594 mViewport.width = width;
595 mViewport.height = height;
596}
597
598const Rectangle &State::getViewport() const
599{
600 return mViewport;
601}
602
603void State::setActiveSampler(unsigned int active)
604{
605 mActiveSampler = active;
606}
607
608unsigned int State::getActiveSampler() const
609{
610 return mActiveSampler;
611}
612
Geoff Lang76b10c92014-09-05 16:28:14 -0400613void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400614{
Geoff Lang76b10c92014-09-05 16:28:14 -0400615 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400616}
617
Geoff Lang76b10c92014-09-05 16:28:14 -0400618Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400619{
Jamie Madill5864ac22015-01-12 14:43:07 -0500620 const auto it = mSamplerTextures.find(type);
621 ASSERT(it != mSamplerTextures.end());
622 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400623}
624
Geoff Lang76b10c92014-09-05 16:28:14 -0400625GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400626{
Jamie Madill5864ac22015-01-12 14:43:07 -0500627 const auto it = mSamplerTextures.find(type);
628 ASSERT(it != mSamplerTextures.end());
629 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400630}
631
Jamie Madille6382c32014-11-07 15:05:26 -0500632void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400633{
634 // Textures have a detach method on State rather than a simple
635 // removeBinding, because the zero/null texture objects are managed
636 // separately, and don't have to go through the Context's maps or
637 // the ResourceManager.
638
639 // [OpenGL ES 2.0.24] section 3.8 page 84:
640 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
641 // rebound to texture object zero
642
Geoff Lang76b10c92014-09-05 16:28:14 -0400643 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400644 {
Jamie Madille6382c32014-11-07 15:05:26 -0500645 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400646 TextureBindingVector &textureVector = bindingVec->second;
647 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400648 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400649 BindingPointer<Texture> &binding = textureVector[textureIdx];
650 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400651 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500652 auto it = zeroTextures.find(textureType);
653 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500654 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500655 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400656 }
657 }
658 }
659
660 // [OpenGL ES 2.0.24] section 4.4 page 112:
661 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
662 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
663 // image was attached in the currently bound framebuffer.
664
665 if (mReadFramebuffer)
666 {
667 mReadFramebuffer->detachTexture(texture);
668 }
669
670 if (mDrawFramebuffer)
671 {
672 mDrawFramebuffer->detachTexture(texture);
673 }
674}
675
Jamie Madille6382c32014-11-07 15:05:26 -0500676void State::initializeZeroTextures(const TextureMap &zeroTextures)
677{
678 for (const auto &zeroTexture : zeroTextures)
679 {
680 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
681
682 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
683 {
684 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
685 }
686 }
687}
688
Shannon Woods53a94a82014-06-24 15:20:36 -0400689void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
690{
691 mSamplers[textureUnit].set(sampler);
692}
693
694GLuint State::getSamplerId(GLuint textureUnit) const
695{
Geoff Lang76b10c92014-09-05 16:28:14 -0400696 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400697 return mSamplers[textureUnit].id();
698}
699
700Sampler *State::getSampler(GLuint textureUnit) const
701{
702 return mSamplers[textureUnit].get();
703}
704
705void State::detachSampler(GLuint sampler)
706{
707 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
708 // If a sampler object that is currently bound to one or more texture units is
709 // deleted, it is as though BindSampler is called once for each texture unit to
710 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400711 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400712 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400713 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
714 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400715 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400716 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400717 }
718 }
719}
720
721void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
722{
723 mRenderbuffer.set(renderbuffer);
724}
725
726GLuint State::getRenderbufferId() const
727{
728 return mRenderbuffer.id();
729}
730
731Renderbuffer *State::getCurrentRenderbuffer()
732{
733 return mRenderbuffer.get();
734}
735
736void State::detachRenderbuffer(GLuint renderbuffer)
737{
738 // [OpenGL ES 2.0.24] section 4.4 page 109:
739 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
740 // had been executed with the target RENDERBUFFER and name of zero.
741
742 if (mRenderbuffer.id() == renderbuffer)
743 {
744 mRenderbuffer.set(NULL);
745 }
746
747 // [OpenGL ES 2.0.24] section 4.4 page 111:
748 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
749 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
750 // point to which this image was attached in the currently bound framebuffer.
751
752 Framebuffer *readFramebuffer = mReadFramebuffer;
753 Framebuffer *drawFramebuffer = mDrawFramebuffer;
754
755 if (readFramebuffer)
756 {
757 readFramebuffer->detachRenderbuffer(renderbuffer);
758 }
759
760 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
761 {
762 drawFramebuffer->detachRenderbuffer(renderbuffer);
763 }
764
765}
766
767void State::setReadFramebufferBinding(Framebuffer *framebuffer)
768{
769 mReadFramebuffer = framebuffer;
770}
771
772void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
773{
774 mDrawFramebuffer = framebuffer;
775}
776
777Framebuffer *State::getTargetFramebuffer(GLenum target) const
778{
779 switch (target)
780 {
781 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
782 case GL_DRAW_FRAMEBUFFER_ANGLE:
783 case GL_FRAMEBUFFER: return mDrawFramebuffer;
784 default: UNREACHABLE(); return NULL;
785 }
786}
787
788Framebuffer *State::getReadFramebuffer()
789{
790 return mReadFramebuffer;
791}
792
793Framebuffer *State::getDrawFramebuffer()
794{
795 return mDrawFramebuffer;
796}
797
798const Framebuffer *State::getReadFramebuffer() const
799{
800 return mReadFramebuffer;
801}
802
803const Framebuffer *State::getDrawFramebuffer() const
804{
805 return mDrawFramebuffer;
806}
807
808bool State::removeReadFramebufferBinding(GLuint framebuffer)
809{
810 if (mReadFramebuffer->id() == framebuffer)
811 {
812 mReadFramebuffer = NULL;
813 return true;
814 }
815
816 return false;
817}
818
819bool State::removeDrawFramebufferBinding(GLuint framebuffer)
820{
821 if (mDrawFramebuffer->id() == framebuffer)
822 {
823 mDrawFramebuffer = NULL;
824 return true;
825 }
826
827 return false;
828}
829
830void State::setVertexArrayBinding(VertexArray *vertexArray)
831{
832 mVertexArray = vertexArray;
833}
834
835GLuint State::getVertexArrayId() const
836{
837 ASSERT(mVertexArray != NULL);
838 return mVertexArray->id();
839}
840
841VertexArray *State::getVertexArray() const
842{
843 ASSERT(mVertexArray != NULL);
844 return mVertexArray;
845}
846
847bool State::removeVertexArrayBinding(GLuint vertexArray)
848{
849 if (mVertexArray->id() == vertexArray)
850 {
851 mVertexArray = NULL;
852 return true;
853 }
854
855 return false;
856}
857
Geoff Lang7dd2e102014-11-10 15:19:26 -0500858void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400859{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500860 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400861 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500862 if (mProgram)
863 {
864 mProgram->release();
865 }
866
867 mProgram = newProgram;
868
869 if (mProgram)
870 {
871 newProgram->addRef();
872 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400873 }
874}
875
Geoff Lang7dd2e102014-11-10 15:19:26 -0500876Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400877{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500878 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400879}
880
881void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
882{
883 mTransformFeedback.set(transformFeedback);
884}
885
886TransformFeedback *State::getCurrentTransformFeedback() const
887{
888 return mTransformFeedback.get();
889}
890
891void State::detachTransformFeedback(GLuint transformFeedback)
892{
893 if (mTransformFeedback.id() == transformFeedback)
894 {
895 mTransformFeedback.set(NULL);
896 }
897}
898
899bool State::isQueryActive() const
900{
901 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
902 i != mActiveQueries.end(); i++)
903 {
904 if (i->second.get() != NULL)
905 {
906 return true;
907 }
908 }
909
910 return false;
911}
912
913void State::setActiveQuery(GLenum target, Query *query)
914{
915 mActiveQueries[target].set(query);
916}
917
918GLuint State::getActiveQueryId(GLenum target) const
919{
920 const Query *query = getActiveQuery(target);
921 return (query ? query->id() : 0u);
922}
923
924Query *State::getActiveQuery(GLenum target) const
925{
Jamie Madill5864ac22015-01-12 14:43:07 -0500926 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400927
Jamie Madill5864ac22015-01-12 14:43:07 -0500928 // All query types should already exist in the activeQueries map
929 ASSERT(it != mActiveQueries.end());
930
931 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400932}
933
934void State::setArrayBufferBinding(Buffer *buffer)
935{
936 mArrayBuffer.set(buffer);
937}
938
939GLuint State::getArrayBufferId() const
940{
941 return mArrayBuffer.id();
942}
943
944bool State::removeArrayBufferBinding(GLuint buffer)
945{
946 if (mArrayBuffer.id() == buffer)
947 {
948 mArrayBuffer.set(NULL);
949 return true;
950 }
951
952 return false;
953}
954
955void State::setGenericUniformBufferBinding(Buffer *buffer)
956{
957 mGenericUniformBuffer.set(buffer);
958}
959
960void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
961{
962 mUniformBuffers[index].set(buffer, offset, size);
963}
964
965GLuint State::getIndexedUniformBufferId(GLuint index) const
966{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400967 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400968
969 return mUniformBuffers[index].id();
970}
971
972Buffer *State::getIndexedUniformBuffer(GLuint index) const
973{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400974 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400975
976 return mUniformBuffers[index].get();
977}
978
979void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
980{
981 mGenericTransformFeedbackBuffer.set(buffer);
982}
983
984void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
985{
986 mTransformFeedbackBuffers[index].set(buffer, offset, size);
987}
988
989GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
990{
Shannon Woods8299bb02014-09-26 18:55:43 -0400991 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400992
993 return mTransformFeedbackBuffers[index].id();
994}
995
996Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
997{
Shannon Woods8299bb02014-09-26 18:55:43 -0400998 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400999
1000 return mTransformFeedbackBuffers[index].get();
1001}
1002
1003GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
1004{
Shannon Woods8299bb02014-09-26 18:55:43 -04001005 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001006
1007 return mTransformFeedbackBuffers[index].getOffset();
1008}
1009
Shannon Woods8299bb02014-09-26 18:55:43 -04001010size_t State::getTransformFeedbackBufferIndexRange() const
1011{
1012 return mTransformFeedbackBuffers.size();
1013}
1014
Shannon Woods53a94a82014-06-24 15:20:36 -04001015void State::setCopyReadBufferBinding(Buffer *buffer)
1016{
1017 mCopyReadBuffer.set(buffer);
1018}
1019
1020void State::setCopyWriteBufferBinding(Buffer *buffer)
1021{
1022 mCopyWriteBuffer.set(buffer);
1023}
1024
1025void State::setPixelPackBufferBinding(Buffer *buffer)
1026{
1027 mPack.pixelBuffer.set(buffer);
1028}
1029
1030void State::setPixelUnpackBufferBinding(Buffer *buffer)
1031{
1032 mUnpack.pixelBuffer.set(buffer);
1033}
1034
1035Buffer *State::getTargetBuffer(GLenum target) const
1036{
1037 switch (target)
1038 {
1039 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1040 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1041 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1042 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1043 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1044 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1045 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1046 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1047 default: UNREACHABLE(); return NULL;
1048 }
1049}
1050
1051void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1052{
1053 getVertexArray()->enableAttribute(attribNum, enabled);
1054}
1055
1056void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1057{
Shannon Woods23e05002014-09-22 19:07:27 -04001058 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001059 mVertexAttribCurrentValues[index].setFloatValues(values);
1060}
1061
1062void State::setVertexAttribu(GLuint index, const GLuint values[4])
1063{
Shannon Woods23e05002014-09-22 19:07:27 -04001064 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001065 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1066}
1067
1068void State::setVertexAttribi(GLuint index, const GLint values[4])
1069{
Shannon Woods23e05002014-09-22 19:07:27 -04001070 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001071 mVertexAttribCurrentValues[index].setIntValues(values);
1072}
1073
1074void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1075 bool pureInteger, GLsizei stride, const void *pointer)
1076{
1077 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1078}
1079
1080const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1081{
1082 return getVertexArray()->getVertexAttribute(attribNum);
1083}
1084
1085const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1086{
Shannon Woods23e05002014-09-22 19:07:27 -04001087 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001088 return mVertexAttribCurrentValues[attribNum];
1089}
1090
Shannon Woods53a94a82014-06-24 15:20:36 -04001091const void *State::getVertexAttribPointer(unsigned int attribNum) const
1092{
1093 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1094}
1095
1096void State::setPackAlignment(GLint alignment)
1097{
1098 mPack.alignment = alignment;
1099}
1100
1101GLint State::getPackAlignment() const
1102{
1103 return mPack.alignment;
1104}
1105
1106void State::setPackReverseRowOrder(bool reverseRowOrder)
1107{
1108 mPack.reverseRowOrder = reverseRowOrder;
1109}
1110
1111bool State::getPackReverseRowOrder() const
1112{
1113 return mPack.reverseRowOrder;
1114}
1115
1116const PixelPackState &State::getPackState() const
1117{
1118 return mPack;
1119}
1120
1121void State::setUnpackAlignment(GLint alignment)
1122{
1123 mUnpack.alignment = alignment;
1124}
1125
1126GLint State::getUnpackAlignment() const
1127{
1128 return mUnpack.alignment;
1129}
1130
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001131void State::setUnpackRowLength(GLint rowLength)
1132{
1133 mUnpack.rowLength = rowLength;
1134}
1135
1136GLint State::getUnpackRowLength() const
1137{
1138 return mUnpack.rowLength;
1139}
1140
Shannon Woods53a94a82014-06-24 15:20:36 -04001141const PixelUnpackState &State::getUnpackState() const
1142{
1143 return mUnpack;
1144}
1145
1146void State::getBooleanv(GLenum pname, GLboolean *params)
1147{
1148 switch (pname)
1149 {
1150 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1151 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1152 case GL_COLOR_WRITEMASK:
1153 params[0] = mBlend.colorMaskRed;
1154 params[1] = mBlend.colorMaskGreen;
1155 params[2] = mBlend.colorMaskBlue;
1156 params[3] = mBlend.colorMaskAlpha;
1157 break;
1158 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1159 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1160 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1161 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1162 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1163 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1164 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1165 case GL_BLEND: *params = mBlend.blend; break;
1166 case GL_DITHER: *params = mBlend.dither; break;
1167 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1168 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1169 default:
1170 UNREACHABLE();
1171 break;
1172 }
1173}
1174
1175void State::getFloatv(GLenum pname, GLfloat *params)
1176{
1177 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv 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.
1181 switch (pname)
1182 {
1183 case GL_LINE_WIDTH: *params = mLineWidth; break;
1184 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1185 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1186 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1187 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1188 case GL_DEPTH_RANGE:
1189 params[0] = mNearZ;
1190 params[1] = mFarZ;
1191 break;
1192 case GL_COLOR_CLEAR_VALUE:
1193 params[0] = mColorClearValue.red;
1194 params[1] = mColorClearValue.green;
1195 params[2] = mColorClearValue.blue;
1196 params[3] = mColorClearValue.alpha;
1197 break;
1198 case GL_BLEND_COLOR:
1199 params[0] = mBlendColor.red;
1200 params[1] = mBlendColor.green;
1201 params[2] = mBlendColor.blue;
1202 params[3] = mBlendColor.alpha;
1203 break;
1204 default:
1205 UNREACHABLE();
1206 break;
1207 }
1208}
1209
Jamie Madill48faf802014-11-06 15:27:22 -05001210void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001211{
1212 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1213 {
1214 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001215 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001216 Framebuffer *framebuffer = mDrawFramebuffer;
1217 *params = framebuffer->getDrawBufferState(colorAttachment);
1218 return;
1219 }
1220
1221 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1222 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1223 // GetIntegerv as its native query function. As it would require conversion in any
1224 // case, this should make no difference to the calling application. You may find it in
1225 // State::getFloatv.
1226 switch (pname)
1227 {
1228 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1229 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1230 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1231 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1232 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1233 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1234 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001235 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001236 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1237 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1238 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001239 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001240 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1241 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1242 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1243 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1244 case GL_STENCIL_REF: *params = mStencilRef; break;
1245 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1246 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1247 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1248 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1249 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1250 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1251 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1252 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1253 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1254 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1255 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1256 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1257 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1258 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1259 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1260 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1261 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1262 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1263 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1264 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001265 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1266 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001267 case GL_SAMPLE_BUFFERS:
1268 case GL_SAMPLES:
1269 {
1270 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001271 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001272 {
1273 switch (pname)
1274 {
1275 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001276 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001277 {
1278 *params = 1;
1279 }
1280 else
1281 {
1282 *params = 0;
1283 }
1284 break;
1285 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001286 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001287 break;
1288 }
1289 }
1290 else
1291 {
1292 *params = 0;
1293 }
1294 }
1295 break;
1296 case GL_VIEWPORT:
1297 params[0] = mViewport.x;
1298 params[1] = mViewport.y;
1299 params[2] = mViewport.width;
1300 params[3] = mViewport.height;
1301 break;
1302 case GL_SCISSOR_BOX:
1303 params[0] = mScissor.x;
1304 params[1] = mScissor.y;
1305 params[2] = mScissor.width;
1306 params[3] = mScissor.height;
1307 break;
1308 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1309 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1310 case GL_RED_BITS:
1311 case GL_GREEN_BITS:
1312 case GL_BLUE_BITS:
1313 case GL_ALPHA_BITS:
1314 {
1315 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1316 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1317
1318 if (colorbuffer)
1319 {
1320 switch (pname)
1321 {
1322 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1323 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1324 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1325 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1326 }
1327 }
1328 else
1329 {
1330 *params = 0;
1331 }
1332 }
1333 break;
1334 case GL_DEPTH_BITS:
1335 {
1336 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1337 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1338
1339 if (depthbuffer)
1340 {
1341 *params = depthbuffer->getDepthSize();
1342 }
1343 else
1344 {
1345 *params = 0;
1346 }
1347 }
1348 break;
1349 case GL_STENCIL_BITS:
1350 {
1351 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1352 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1353
1354 if (stencilbuffer)
1355 {
1356 *params = stencilbuffer->getStencilSize();
1357 }
1358 else
1359 {
1360 *params = 0;
1361 }
1362 }
1363 break;
1364 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001365 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001366 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001367 break;
1368 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001369 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001370 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001371 break;
1372 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001373 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001374 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001375 break;
1376 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001377 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001378 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001379 break;
1380 case GL_UNIFORM_BUFFER_BINDING:
1381 *params = mGenericUniformBuffer.id();
1382 break;
1383 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1384 *params = mGenericTransformFeedbackBuffer.id();
1385 break;
1386 case GL_COPY_READ_BUFFER_BINDING:
1387 *params = mCopyReadBuffer.id();
1388 break;
1389 case GL_COPY_WRITE_BUFFER_BINDING:
1390 *params = mCopyWriteBuffer.id();
1391 break;
1392 case GL_PIXEL_PACK_BUFFER_BINDING:
1393 *params = mPack.pixelBuffer.id();
1394 break;
1395 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1396 *params = mUnpack.pixelBuffer.id();
1397 break;
1398 default:
1399 UNREACHABLE();
1400 break;
1401 }
1402}
1403
1404bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1405{
1406 switch (target)
1407 {
1408 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Shannon Woods8299bb02014-09-26 18:55:43 -04001409 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001410 {
1411 *data = mTransformFeedbackBuffers[index].id();
1412 }
1413 break;
1414 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001415 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001416 {
1417 *data = mUniformBuffers[index].id();
1418 }
1419 break;
1420 default:
1421 return false;
1422 }
1423
1424 return true;
1425}
1426
1427bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1428{
1429 switch (target)
1430 {
1431 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Shannon Woods8299bb02014-09-26 18:55:43 -04001432 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001433 {
1434 *data = mTransformFeedbackBuffers[index].getOffset();
1435 }
1436 break;
1437 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Shannon Woods8299bb02014-09-26 18:55:43 -04001438 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001439 {
1440 *data = mTransformFeedbackBuffers[index].getSize();
1441 }
1442 break;
1443 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001444 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001445 {
1446 *data = mUniformBuffers[index].getOffset();
1447 }
1448 break;
1449 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001450 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001451 {
1452 *data = mUniformBuffers[index].getSize();
1453 }
1454 break;
1455 default:
1456 return false;
1457 }
1458
1459 return true;
1460}
1461
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001462bool State::hasMappedBuffer(GLenum target) const
1463{
1464 if (target == GL_ARRAY_BUFFER)
1465 {
Shannon Woods23e05002014-09-22 19:07:27 -04001466 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001467 {
Shannon Woods23e05002014-09-22 19:07:27 -04001468 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001469 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1470 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1471 {
1472 return true;
1473 }
1474 }
1475
1476 return false;
1477 }
1478 else
1479 {
1480 Buffer *buffer = getTargetBuffer(target);
1481 return (buffer && buffer->isMapped());
1482 }
1483}
1484
Shannon Woods53a94a82014-06-24 15:20:36 -04001485}