blob: ec75fa974b9951d6a5a9a37a3ae92b2c0130ca56 [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;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500144
145 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400146}
147
Geoff Lang76b10c92014-09-05 16:28:14 -0400148void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400149{
Geoff Lang76b10c92014-09-05 16:28:14 -0400150 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400151 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400152 TextureBindingVector &textureVector = bindingVec->second;
153 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400154 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400155 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400156 }
157 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400158 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
159 {
160 mSamplers[samplerIdx].set(NULL);
161 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400162
Shannon Woods53a94a82014-06-24 15:20:36 -0400163 mArrayBuffer.set(NULL);
164 mRenderbuffer.set(NULL);
165
Geoff Lang7dd2e102014-11-10 15:19:26 -0500166 if (mProgram)
167 {
168 mProgram->release();
169 }
170 mProgram = NULL;
171
Shannon Woods53a94a82014-06-24 15:20:36 -0400172 mTransformFeedback.set(NULL);
173
174 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
175 {
176 i->second.set(NULL);
177 }
178
179 mGenericUniformBuffer.set(NULL);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400180 mGenericTransformFeedbackBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400181 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400182 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400183 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400184 }
185
Shannon Woods8299bb02014-09-26 18:55:43 -0400186 for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400187 {
Shannon Woods8299bb02014-09-26 18:55:43 -0400188 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400189 }
190
191 mCopyReadBuffer.set(NULL);
192 mCopyWriteBuffer.set(NULL);
193
194 mPack.pixelBuffer.set(NULL);
195 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500196
197 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400198}
199
200const RasterizerState &State::getRasterizerState() const
201{
202 return mRasterizer;
203}
204
205const BlendState &State::getBlendState() const
206{
207 return mBlend;
208}
209
210const DepthStencilState &State::getDepthStencilState() const
211{
212 return mDepthStencil;
213}
214
215void State::setClearColor(float red, float green, float blue, float alpha)
216{
217 mColorClearValue.red = red;
218 mColorClearValue.green = green;
219 mColorClearValue.blue = blue;
220 mColorClearValue.alpha = alpha;
221}
222
223void State::setClearDepth(float depth)
224{
225 mDepthClearValue = depth;
226}
227
228void State::setClearStencil(int stencil)
229{
230 mStencilClearValue = stencil;
231}
232
233ClearParameters State::getClearParameters(GLbitfield mask) const
234{
Jamie Madill639db122014-12-03 11:36:43 -0500235 ClearParameters clearParams;
236 memset(&clearParams, 0, sizeof(ClearParameters));
Shannon Woods53a94a82014-06-24 15:20:36 -0400237 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
238 {
239 clearParams.clearColor[i] = false;
240 }
241 clearParams.colorFClearValue = mColorClearValue;
242 clearParams.colorClearType = GL_FLOAT;
243 clearParams.colorMaskRed = mBlend.colorMaskRed;
244 clearParams.colorMaskGreen = mBlend.colorMaskGreen;
245 clearParams.colorMaskBlue = mBlend.colorMaskBlue;
246 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
247 clearParams.clearDepth = false;
248 clearParams.depthClearValue = mDepthClearValue;
249 clearParams.clearStencil = false;
250 clearParams.stencilClearValue = mStencilClearValue;
251 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
252 clearParams.scissorEnabled = mScissorTest;
253 clearParams.scissor = mScissor;
254
255 const Framebuffer *framebufferObject = getDrawFramebuffer();
256 if (mask & GL_COLOR_BUFFER_BIT)
257 {
258 if (framebufferObject->hasEnabledColorAttachment())
259 {
260 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
261 {
262 clearParams.clearColor[i] = true;
263 }
264 }
265 }
266
267 if (mask & GL_DEPTH_BUFFER_BIT)
268 {
269 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
270 {
271 clearParams.clearDepth = true;
272 }
273 }
274
275 if (mask & GL_STENCIL_BUFFER_BIT)
276 {
Geoff Langd8a22582014-12-17 15:28:23 -0500277 if (framebufferObject->getStencilbuffer() != NULL &&
278 framebufferObject->getStencilbuffer()->getStencilSize() > 0)
Shannon Woods53a94a82014-06-24 15:20:36 -0400279 {
Geoff Langd8a22582014-12-17 15:28:23 -0500280 clearParams.clearStencil = true;
Shannon Woods53a94a82014-06-24 15:20:36 -0400281 }
282 }
283
284 return clearParams;
285}
286
287void State::setColorMask(bool red, bool green, bool blue, bool alpha)
288{
289 mBlend.colorMaskRed = red;
290 mBlend.colorMaskGreen = green;
291 mBlend.colorMaskBlue = blue;
292 mBlend.colorMaskAlpha = alpha;
293}
294
295void State::setDepthMask(bool mask)
296{
297 mDepthStencil.depthMask = mask;
298}
299
300bool State::isRasterizerDiscardEnabled() const
301{
302 return mRasterizer.rasterizerDiscard;
303}
304
305void State::setRasterizerDiscard(bool enabled)
306{
307 mRasterizer.rasterizerDiscard = enabled;
308}
309
310bool State::isCullFaceEnabled() const
311{
312 return mRasterizer.cullFace;
313}
314
315void State::setCullFace(bool enabled)
316{
317 mRasterizer.cullFace = enabled;
318}
319
320void State::setCullMode(GLenum mode)
321{
322 mRasterizer.cullMode = mode;
323}
324
325void State::setFrontFace(GLenum front)
326{
327 mRasterizer.frontFace = front;
328}
329
330bool State::isDepthTestEnabled() const
331{
332 return mDepthStencil.depthTest;
333}
334
335void State::setDepthTest(bool enabled)
336{
337 mDepthStencil.depthTest = enabled;
338}
339
340void State::setDepthFunc(GLenum depthFunc)
341{
342 mDepthStencil.depthFunc = depthFunc;
343}
344
345void State::setDepthRange(float zNear, float zFar)
346{
347 mNearZ = zNear;
348 mFarZ = zFar;
349}
350
351void State::getDepthRange(float *zNear, float *zFar) const
352{
353 *zNear = mNearZ;
354 *zFar = mFarZ;
355}
356
357bool State::isBlendEnabled() const
358{
359 return mBlend.blend;
360}
361
362void State::setBlend(bool enabled)
363{
364 mBlend.blend = enabled;
365}
366
367void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
368{
369 mBlend.sourceBlendRGB = sourceRGB;
370 mBlend.destBlendRGB = destRGB;
371 mBlend.sourceBlendAlpha = sourceAlpha;
372 mBlend.destBlendAlpha = destAlpha;
373}
374
375void State::setBlendColor(float red, float green, float blue, float alpha)
376{
377 mBlendColor.red = red;
378 mBlendColor.green = green;
379 mBlendColor.blue = blue;
380 mBlendColor.alpha = alpha;
381}
382
383void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
384{
385 mBlend.blendEquationRGB = rgbEquation;
386 mBlend.blendEquationAlpha = alphaEquation;
387}
388
389const ColorF &State::getBlendColor() const
390{
391 return mBlendColor;
392}
393
394bool State::isStencilTestEnabled() const
395{
396 return mDepthStencil.stencilTest;
397}
398
399void State::setStencilTest(bool enabled)
400{
401 mDepthStencil.stencilTest = enabled;
402}
403
404void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
405{
406 mDepthStencil.stencilFunc = stencilFunc;
407 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
408 mDepthStencil.stencilMask = stencilMask;
409}
410
411void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
412{
413 mDepthStencil.stencilBackFunc = stencilBackFunc;
414 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
415 mDepthStencil.stencilBackMask = stencilBackMask;
416}
417
418void State::setStencilWritemask(GLuint stencilWritemask)
419{
420 mDepthStencil.stencilWritemask = stencilWritemask;
421}
422
423void State::setStencilBackWritemask(GLuint stencilBackWritemask)
424{
425 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
426}
427
428void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
429{
430 mDepthStencil.stencilFail = stencilFail;
431 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
432 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
433}
434
435void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
436{
437 mDepthStencil.stencilBackFail = stencilBackFail;
438 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
439 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
440}
441
442GLint State::getStencilRef() const
443{
444 return mStencilRef;
445}
446
447GLint State::getStencilBackRef() const
448{
449 return mStencilBackRef;
450}
451
452bool State::isPolygonOffsetFillEnabled() const
453{
454 return mRasterizer.polygonOffsetFill;
455}
456
457void State::setPolygonOffsetFill(bool enabled)
458{
459 mRasterizer.polygonOffsetFill = enabled;
460}
461
462void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
463{
464 // An application can pass NaN values here, so handle this gracefully
465 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
466 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
467}
468
469bool State::isSampleAlphaToCoverageEnabled() const
470{
471 return mBlend.sampleAlphaToCoverage;
472}
473
474void State::setSampleAlphaToCoverage(bool enabled)
475{
476 mBlend.sampleAlphaToCoverage = enabled;
477}
478
479bool State::isSampleCoverageEnabled() const
480{
481 return mSampleCoverage;
482}
483
484void State::setSampleCoverage(bool enabled)
485{
486 mSampleCoverage = enabled;
487}
488
489void State::setSampleCoverageParams(GLclampf value, bool invert)
490{
491 mSampleCoverageValue = value;
492 mSampleCoverageInvert = invert;
493}
494
Jamie Madilld9e58302014-11-06 15:27:26 -0500495void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400496{
497 ASSERT(value != NULL && invert != NULL);
498
499 *value = mSampleCoverageValue;
500 *invert = mSampleCoverageInvert;
501}
502
503bool State::isScissorTestEnabled() const
504{
505 return mScissorTest;
506}
507
508void State::setScissorTest(bool enabled)
509{
510 mScissorTest = enabled;
511}
512
513void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
514{
515 mScissor.x = x;
516 mScissor.y = y;
517 mScissor.width = width;
518 mScissor.height = height;
519}
520
521const Rectangle &State::getScissor() const
522{
523 return mScissor;
524}
525
526bool State::isDitherEnabled() const
527{
528 return mBlend.dither;
529}
530
531void State::setDither(bool enabled)
532{
533 mBlend.dither = enabled;
534}
535
Jamie Madillb4b53c52015-02-03 15:22:48 -0500536bool State::isPrimitiveRestartEnabled() const
537{
538 return mPrimitiveRestart;
539}
540
541void State::setPrimitiveRestart(bool enabled)
542{
543 mPrimitiveRestart = enabled;
544}
545
Shannon Woods53a94a82014-06-24 15:20:36 -0400546void State::setEnableFeature(GLenum feature, bool enabled)
547{
548 switch (feature)
549 {
550 case GL_CULL_FACE: setCullFace(enabled); break;
551 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
552 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
553 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
554 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
555 case GL_STENCIL_TEST: setStencilTest(enabled); break;
556 case GL_DEPTH_TEST: setDepthTest(enabled); break;
557 case GL_BLEND: setBlend(enabled); break;
558 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500559 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400560 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
561 default: UNREACHABLE();
562 }
563}
564
565bool State::getEnableFeature(GLenum feature)
566{
567 switch (feature)
568 {
569 case GL_CULL_FACE: return isCullFaceEnabled();
570 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
571 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
572 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
573 case GL_SCISSOR_TEST: return isScissorTestEnabled();
574 case GL_STENCIL_TEST: return isStencilTestEnabled();
575 case GL_DEPTH_TEST: return isDepthTestEnabled();
576 case GL_BLEND: return isBlendEnabled();
577 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500578 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400579 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
580 default: UNREACHABLE(); return false;
581 }
582}
583
584void State::setLineWidth(GLfloat width)
585{
586 mLineWidth = width;
587}
588
589void State::setGenerateMipmapHint(GLenum hint)
590{
591 mGenerateMipmapHint = hint;
592}
593
594void State::setFragmentShaderDerivativeHint(GLenum hint)
595{
596 mFragmentShaderDerivativeHint = hint;
597 // TODO: Propagate the hint to shader translator so we can write
598 // ddx, ddx_coarse, or ddx_fine depending on the hint.
599 // Ignore for now. It is valid for implementations to ignore hint.
600}
601
602void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
603{
604 mViewport.x = x;
605 mViewport.y = y;
606 mViewport.width = width;
607 mViewport.height = height;
608}
609
610const Rectangle &State::getViewport() const
611{
612 return mViewport;
613}
614
615void State::setActiveSampler(unsigned int active)
616{
617 mActiveSampler = active;
618}
619
620unsigned int State::getActiveSampler() const
621{
622 return mActiveSampler;
623}
624
Geoff Lang76b10c92014-09-05 16:28:14 -0400625void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400626{
Geoff Lang76b10c92014-09-05 16:28:14 -0400627 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400628}
629
Geoff Lang76b10c92014-09-05 16:28:14 -0400630Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400631{
Jamie Madill5864ac22015-01-12 14:43:07 -0500632 const auto it = mSamplerTextures.find(type);
633 ASSERT(it != mSamplerTextures.end());
634 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400635}
636
Geoff Lang76b10c92014-09-05 16:28:14 -0400637GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400638{
Jamie Madill5864ac22015-01-12 14:43:07 -0500639 const auto it = mSamplerTextures.find(type);
640 ASSERT(it != mSamplerTextures.end());
641 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400642}
643
Jamie Madille6382c32014-11-07 15:05:26 -0500644void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400645{
646 // Textures have a detach method on State rather than a simple
647 // removeBinding, because the zero/null texture objects are managed
648 // separately, and don't have to go through the Context's maps or
649 // the ResourceManager.
650
651 // [OpenGL ES 2.0.24] section 3.8 page 84:
652 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
653 // rebound to texture object zero
654
Geoff Lang76b10c92014-09-05 16:28:14 -0400655 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400656 {
Jamie Madille6382c32014-11-07 15:05:26 -0500657 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400658 TextureBindingVector &textureVector = bindingVec->second;
659 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400660 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400661 BindingPointer<Texture> &binding = textureVector[textureIdx];
662 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400663 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500664 auto it = zeroTextures.find(textureType);
665 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500666 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500667 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400668 }
669 }
670 }
671
672 // [OpenGL ES 2.0.24] section 4.4 page 112:
673 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
674 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
675 // image was attached in the currently bound framebuffer.
676
677 if (mReadFramebuffer)
678 {
679 mReadFramebuffer->detachTexture(texture);
680 }
681
682 if (mDrawFramebuffer)
683 {
684 mDrawFramebuffer->detachTexture(texture);
685 }
686}
687
Jamie Madille6382c32014-11-07 15:05:26 -0500688void State::initializeZeroTextures(const TextureMap &zeroTextures)
689{
690 for (const auto &zeroTexture : zeroTextures)
691 {
692 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
693
694 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
695 {
696 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
697 }
698 }
699}
700
Shannon Woods53a94a82014-06-24 15:20:36 -0400701void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
702{
703 mSamplers[textureUnit].set(sampler);
704}
705
706GLuint State::getSamplerId(GLuint textureUnit) const
707{
Geoff Lang76b10c92014-09-05 16:28:14 -0400708 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400709 return mSamplers[textureUnit].id();
710}
711
712Sampler *State::getSampler(GLuint textureUnit) const
713{
714 return mSamplers[textureUnit].get();
715}
716
717void State::detachSampler(GLuint sampler)
718{
719 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
720 // If a sampler object that is currently bound to one or more texture units is
721 // deleted, it is as though BindSampler is called once for each texture unit to
722 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400723 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400724 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400725 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
726 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400727 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400728 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400729 }
730 }
731}
732
733void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
734{
735 mRenderbuffer.set(renderbuffer);
736}
737
738GLuint State::getRenderbufferId() const
739{
740 return mRenderbuffer.id();
741}
742
743Renderbuffer *State::getCurrentRenderbuffer()
744{
745 return mRenderbuffer.get();
746}
747
748void State::detachRenderbuffer(GLuint renderbuffer)
749{
750 // [OpenGL ES 2.0.24] section 4.4 page 109:
751 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
752 // had been executed with the target RENDERBUFFER and name of zero.
753
754 if (mRenderbuffer.id() == renderbuffer)
755 {
756 mRenderbuffer.set(NULL);
757 }
758
759 // [OpenGL ES 2.0.24] section 4.4 page 111:
760 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
761 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
762 // point to which this image was attached in the currently bound framebuffer.
763
764 Framebuffer *readFramebuffer = mReadFramebuffer;
765 Framebuffer *drawFramebuffer = mDrawFramebuffer;
766
767 if (readFramebuffer)
768 {
769 readFramebuffer->detachRenderbuffer(renderbuffer);
770 }
771
772 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
773 {
774 drawFramebuffer->detachRenderbuffer(renderbuffer);
775 }
776
777}
778
779void State::setReadFramebufferBinding(Framebuffer *framebuffer)
780{
781 mReadFramebuffer = framebuffer;
782}
783
784void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
785{
786 mDrawFramebuffer = framebuffer;
787}
788
789Framebuffer *State::getTargetFramebuffer(GLenum target) const
790{
791 switch (target)
792 {
793 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
794 case GL_DRAW_FRAMEBUFFER_ANGLE:
795 case GL_FRAMEBUFFER: return mDrawFramebuffer;
796 default: UNREACHABLE(); return NULL;
797 }
798}
799
800Framebuffer *State::getReadFramebuffer()
801{
802 return mReadFramebuffer;
803}
804
805Framebuffer *State::getDrawFramebuffer()
806{
807 return mDrawFramebuffer;
808}
809
810const Framebuffer *State::getReadFramebuffer() const
811{
812 return mReadFramebuffer;
813}
814
815const Framebuffer *State::getDrawFramebuffer() const
816{
817 return mDrawFramebuffer;
818}
819
820bool State::removeReadFramebufferBinding(GLuint framebuffer)
821{
822 if (mReadFramebuffer->id() == framebuffer)
823 {
824 mReadFramebuffer = NULL;
825 return true;
826 }
827
828 return false;
829}
830
831bool State::removeDrawFramebufferBinding(GLuint framebuffer)
832{
833 if (mDrawFramebuffer->id() == framebuffer)
834 {
835 mDrawFramebuffer = NULL;
836 return true;
837 }
838
839 return false;
840}
841
842void State::setVertexArrayBinding(VertexArray *vertexArray)
843{
844 mVertexArray = vertexArray;
845}
846
847GLuint State::getVertexArrayId() const
848{
849 ASSERT(mVertexArray != NULL);
850 return mVertexArray->id();
851}
852
853VertexArray *State::getVertexArray() const
854{
855 ASSERT(mVertexArray != NULL);
856 return mVertexArray;
857}
858
859bool State::removeVertexArrayBinding(GLuint vertexArray)
860{
861 if (mVertexArray->id() == vertexArray)
862 {
863 mVertexArray = NULL;
864 return true;
865 }
866
867 return false;
868}
869
Geoff Lang7dd2e102014-11-10 15:19:26 -0500870void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400871{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500872 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400873 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500874 if (mProgram)
875 {
876 mProgram->release();
877 }
878
879 mProgram = newProgram;
880
881 if (mProgram)
882 {
883 newProgram->addRef();
884 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400885 }
886}
887
Geoff Lang7dd2e102014-11-10 15:19:26 -0500888Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400889{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500890 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400891}
892
893void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
894{
895 mTransformFeedback.set(transformFeedback);
896}
897
898TransformFeedback *State::getCurrentTransformFeedback() const
899{
900 return mTransformFeedback.get();
901}
902
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000903bool State::isTransformFeedbackActiveUnpaused() const
904{
905 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
906 return curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused();
907}
908
Shannon Woods53a94a82014-06-24 15:20:36 -0400909void State::detachTransformFeedback(GLuint transformFeedback)
910{
911 if (mTransformFeedback.id() == transformFeedback)
912 {
913 mTransformFeedback.set(NULL);
914 }
915}
916
917bool State::isQueryActive() const
918{
919 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
920 i != mActiveQueries.end(); i++)
921 {
922 if (i->second.get() != NULL)
923 {
924 return true;
925 }
926 }
927
928 return false;
929}
930
931void State::setActiveQuery(GLenum target, Query *query)
932{
933 mActiveQueries[target].set(query);
934}
935
936GLuint State::getActiveQueryId(GLenum target) const
937{
938 const Query *query = getActiveQuery(target);
939 return (query ? query->id() : 0u);
940}
941
942Query *State::getActiveQuery(GLenum target) const
943{
Jamie Madill5864ac22015-01-12 14:43:07 -0500944 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400945
Jamie Madill5864ac22015-01-12 14:43:07 -0500946 // All query types should already exist in the activeQueries map
947 ASSERT(it != mActiveQueries.end());
948
949 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400950}
951
952void State::setArrayBufferBinding(Buffer *buffer)
953{
954 mArrayBuffer.set(buffer);
955}
956
957GLuint State::getArrayBufferId() const
958{
959 return mArrayBuffer.id();
960}
961
962bool State::removeArrayBufferBinding(GLuint buffer)
963{
964 if (mArrayBuffer.id() == buffer)
965 {
966 mArrayBuffer.set(NULL);
967 return true;
968 }
969
970 return false;
971}
972
973void State::setGenericUniformBufferBinding(Buffer *buffer)
974{
975 mGenericUniformBuffer.set(buffer);
976}
977
978void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
979{
980 mUniformBuffers[index].set(buffer, offset, size);
981}
982
983GLuint State::getIndexedUniformBufferId(GLuint index) const
984{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400985 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400986
987 return mUniformBuffers[index].id();
988}
989
990Buffer *State::getIndexedUniformBuffer(GLuint index) const
991{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400992 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400993
994 return mUniformBuffers[index].get();
995}
996
997void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
998{
999 mGenericTransformFeedbackBuffer.set(buffer);
1000}
1001
1002void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1003{
1004 mTransformFeedbackBuffers[index].set(buffer, offset, size);
1005}
1006
1007GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
1008{
Shannon Woods8299bb02014-09-26 18:55:43 -04001009 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001010
1011 return mTransformFeedbackBuffers[index].id();
1012}
1013
1014Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
1015{
Shannon Woods8299bb02014-09-26 18:55:43 -04001016 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001017
1018 return mTransformFeedbackBuffers[index].get();
1019}
1020
1021GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
1022{
Shannon Woods8299bb02014-09-26 18:55:43 -04001023 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001024
1025 return mTransformFeedbackBuffers[index].getOffset();
1026}
1027
Shannon Woods8299bb02014-09-26 18:55:43 -04001028size_t State::getTransformFeedbackBufferIndexRange() const
1029{
1030 return mTransformFeedbackBuffers.size();
1031}
1032
Shannon Woods53a94a82014-06-24 15:20:36 -04001033void State::setCopyReadBufferBinding(Buffer *buffer)
1034{
1035 mCopyReadBuffer.set(buffer);
1036}
1037
1038void State::setCopyWriteBufferBinding(Buffer *buffer)
1039{
1040 mCopyWriteBuffer.set(buffer);
1041}
1042
1043void State::setPixelPackBufferBinding(Buffer *buffer)
1044{
1045 mPack.pixelBuffer.set(buffer);
1046}
1047
1048void State::setPixelUnpackBufferBinding(Buffer *buffer)
1049{
1050 mUnpack.pixelBuffer.set(buffer);
1051}
1052
1053Buffer *State::getTargetBuffer(GLenum target) const
1054{
1055 switch (target)
1056 {
1057 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1058 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1059 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1060 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1061 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1062 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1063 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1064 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1065 default: UNREACHABLE(); return NULL;
1066 }
1067}
1068
1069void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1070{
1071 getVertexArray()->enableAttribute(attribNum, enabled);
1072}
1073
1074void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1075{
Shannon Woods23e05002014-09-22 19:07:27 -04001076 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001077 mVertexAttribCurrentValues[index].setFloatValues(values);
1078}
1079
1080void State::setVertexAttribu(GLuint index, const GLuint values[4])
1081{
Shannon Woods23e05002014-09-22 19:07:27 -04001082 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001083 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1084}
1085
1086void State::setVertexAttribi(GLuint index, const GLint values[4])
1087{
Shannon Woods23e05002014-09-22 19:07:27 -04001088 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001089 mVertexAttribCurrentValues[index].setIntValues(values);
1090}
1091
1092void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1093 bool pureInteger, GLsizei stride, const void *pointer)
1094{
1095 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1096}
1097
1098const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1099{
1100 return getVertexArray()->getVertexAttribute(attribNum);
1101}
1102
1103const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1104{
Shannon Woods23e05002014-09-22 19:07:27 -04001105 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001106 return mVertexAttribCurrentValues[attribNum];
1107}
1108
Shannon Woods53a94a82014-06-24 15:20:36 -04001109const void *State::getVertexAttribPointer(unsigned int attribNum) const
1110{
1111 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1112}
1113
1114void State::setPackAlignment(GLint alignment)
1115{
1116 mPack.alignment = alignment;
1117}
1118
1119GLint State::getPackAlignment() const
1120{
1121 return mPack.alignment;
1122}
1123
1124void State::setPackReverseRowOrder(bool reverseRowOrder)
1125{
1126 mPack.reverseRowOrder = reverseRowOrder;
1127}
1128
1129bool State::getPackReverseRowOrder() const
1130{
1131 return mPack.reverseRowOrder;
1132}
1133
1134const PixelPackState &State::getPackState() const
1135{
1136 return mPack;
1137}
1138
1139void State::setUnpackAlignment(GLint alignment)
1140{
1141 mUnpack.alignment = alignment;
1142}
1143
1144GLint State::getUnpackAlignment() const
1145{
1146 return mUnpack.alignment;
1147}
1148
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001149void State::setUnpackRowLength(GLint rowLength)
1150{
1151 mUnpack.rowLength = rowLength;
1152}
1153
1154GLint State::getUnpackRowLength() const
1155{
1156 return mUnpack.rowLength;
1157}
1158
Shannon Woods53a94a82014-06-24 15:20:36 -04001159const PixelUnpackState &State::getUnpackState() const
1160{
1161 return mUnpack;
1162}
1163
1164void State::getBooleanv(GLenum pname, GLboolean *params)
1165{
1166 switch (pname)
1167 {
1168 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1169 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1170 case GL_COLOR_WRITEMASK:
1171 params[0] = mBlend.colorMaskRed;
1172 params[1] = mBlend.colorMaskGreen;
1173 params[2] = mBlend.colorMaskBlue;
1174 params[3] = mBlend.colorMaskAlpha;
1175 break;
1176 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1177 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1178 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1179 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1180 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1181 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1182 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1183 case GL_BLEND: *params = mBlend.blend; break;
1184 case GL_DITHER: *params = mBlend.dither; break;
1185 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1186 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1187 default:
1188 UNREACHABLE();
1189 break;
1190 }
1191}
1192
1193void State::getFloatv(GLenum pname, GLfloat *params)
1194{
1195 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1196 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1197 // GetIntegerv as its native query function. As it would require conversion in any
1198 // case, this should make no difference to the calling application.
1199 switch (pname)
1200 {
1201 case GL_LINE_WIDTH: *params = mLineWidth; break;
1202 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1203 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1204 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1205 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1206 case GL_DEPTH_RANGE:
1207 params[0] = mNearZ;
1208 params[1] = mFarZ;
1209 break;
1210 case GL_COLOR_CLEAR_VALUE:
1211 params[0] = mColorClearValue.red;
1212 params[1] = mColorClearValue.green;
1213 params[2] = mColorClearValue.blue;
1214 params[3] = mColorClearValue.alpha;
1215 break;
1216 case GL_BLEND_COLOR:
1217 params[0] = mBlendColor.red;
1218 params[1] = mBlendColor.green;
1219 params[2] = mBlendColor.blue;
1220 params[3] = mBlendColor.alpha;
1221 break;
1222 default:
1223 UNREACHABLE();
1224 break;
1225 }
1226}
1227
Jamie Madill48faf802014-11-06 15:27:22 -05001228void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001229{
1230 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1231 {
1232 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001233 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001234 Framebuffer *framebuffer = mDrawFramebuffer;
1235 *params = framebuffer->getDrawBufferState(colorAttachment);
1236 return;
1237 }
1238
1239 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1240 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1241 // GetIntegerv as its native query function. As it would require conversion in any
1242 // case, this should make no difference to the calling application. You may find it in
1243 // State::getFloatv.
1244 switch (pname)
1245 {
1246 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1247 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1248 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1249 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1250 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1251 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1252 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001253 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001254 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1255 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1256 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001257 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001258 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1259 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1260 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1261 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1262 case GL_STENCIL_REF: *params = mStencilRef; break;
1263 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1264 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1265 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1266 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1267 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1268 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1269 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1270 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1271 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1272 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1273 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1274 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1275 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1276 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1277 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1278 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1279 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1280 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1281 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1282 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001283 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1284 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001285 case GL_SAMPLE_BUFFERS:
1286 case GL_SAMPLES:
1287 {
1288 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001289 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001290 {
1291 switch (pname)
1292 {
1293 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001294 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001295 {
1296 *params = 1;
1297 }
1298 else
1299 {
1300 *params = 0;
1301 }
1302 break;
1303 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001304 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001305 break;
1306 }
1307 }
1308 else
1309 {
1310 *params = 0;
1311 }
1312 }
1313 break;
1314 case GL_VIEWPORT:
1315 params[0] = mViewport.x;
1316 params[1] = mViewport.y;
1317 params[2] = mViewport.width;
1318 params[3] = mViewport.height;
1319 break;
1320 case GL_SCISSOR_BOX:
1321 params[0] = mScissor.x;
1322 params[1] = mScissor.y;
1323 params[2] = mScissor.width;
1324 params[3] = mScissor.height;
1325 break;
1326 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1327 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1328 case GL_RED_BITS:
1329 case GL_GREEN_BITS:
1330 case GL_BLUE_BITS:
1331 case GL_ALPHA_BITS:
1332 {
1333 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1334 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1335
1336 if (colorbuffer)
1337 {
1338 switch (pname)
1339 {
1340 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1341 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1342 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1343 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1344 }
1345 }
1346 else
1347 {
1348 *params = 0;
1349 }
1350 }
1351 break;
1352 case GL_DEPTH_BITS:
1353 {
1354 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1355 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1356
1357 if (depthbuffer)
1358 {
1359 *params = depthbuffer->getDepthSize();
1360 }
1361 else
1362 {
1363 *params = 0;
1364 }
1365 }
1366 break;
1367 case GL_STENCIL_BITS:
1368 {
1369 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1370 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1371
1372 if (stencilbuffer)
1373 {
1374 *params = stencilbuffer->getStencilSize();
1375 }
1376 else
1377 {
1378 *params = 0;
1379 }
1380 }
1381 break;
1382 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001383 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001384 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001385 break;
1386 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001387 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001388 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001389 break;
1390 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001391 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001392 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001393 break;
1394 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001395 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001396 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001397 break;
1398 case GL_UNIFORM_BUFFER_BINDING:
1399 *params = mGenericUniformBuffer.id();
1400 break;
1401 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1402 *params = mGenericTransformFeedbackBuffer.id();
1403 break;
1404 case GL_COPY_READ_BUFFER_BINDING:
1405 *params = mCopyReadBuffer.id();
1406 break;
1407 case GL_COPY_WRITE_BUFFER_BINDING:
1408 *params = mCopyWriteBuffer.id();
1409 break;
1410 case GL_PIXEL_PACK_BUFFER_BINDING:
1411 *params = mPack.pixelBuffer.id();
1412 break;
1413 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1414 *params = mUnpack.pixelBuffer.id();
1415 break;
1416 default:
1417 UNREACHABLE();
1418 break;
1419 }
1420}
1421
1422bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1423{
1424 switch (target)
1425 {
1426 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Shannon Woods8299bb02014-09-26 18:55:43 -04001427 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001428 {
1429 *data = mTransformFeedbackBuffers[index].id();
1430 }
1431 break;
1432 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001433 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001434 {
1435 *data = mUniformBuffers[index].id();
1436 }
1437 break;
1438 default:
1439 return false;
1440 }
1441
1442 return true;
1443}
1444
1445bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1446{
1447 switch (target)
1448 {
1449 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Shannon Woods8299bb02014-09-26 18:55:43 -04001450 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001451 {
1452 *data = mTransformFeedbackBuffers[index].getOffset();
1453 }
1454 break;
1455 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Shannon Woods8299bb02014-09-26 18:55:43 -04001456 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001457 {
1458 *data = mTransformFeedbackBuffers[index].getSize();
1459 }
1460 break;
1461 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001462 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001463 {
1464 *data = mUniformBuffers[index].getOffset();
1465 }
1466 break;
1467 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001468 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001469 {
1470 *data = mUniformBuffers[index].getSize();
1471 }
1472 break;
1473 default:
1474 return false;
1475 }
1476
1477 return true;
1478}
1479
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001480bool State::hasMappedBuffer(GLenum target) const
1481{
1482 if (target == GL_ARRAY_BUFFER)
1483 {
Shannon Woods23e05002014-09-22 19:07:27 -04001484 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001485 {
Shannon Woods23e05002014-09-22 19:07:27 -04001486 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001487 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1488 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1489 {
1490 return true;
1491 }
1492 }
1493
1494 return false;
1495 }
1496 else
1497 {
1498 Buffer *buffer = getTargetBuffer(target);
1499 return (buffer && buffer->isMapped());
1500 }
1501}
1502
Shannon Woods53a94a82014-06-24 15:20:36 -04001503}