blob: 1e34c633c88a896e73205c917456c0a9e7c7bff9 [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
Jamie Madillf75ab352015-03-16 10:46:52 -040038 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040039
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;
Austin Kinrossb8af7232015-03-16 22:33:25 -070078 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
79 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040080 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070081 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
82 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040083 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
Jamie Madillf75ab352015-03-16 10:46:52 -0400215void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400216{
217 mColorClearValue.red = red;
218 mColorClearValue.green = green;
219 mColorClearValue.blue = blue;
220 mColorClearValue.alpha = alpha;
221}
222
Jamie Madillf75ab352015-03-16 10:46:52 -0400223void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400224{
225 mDepthClearValue = depth;
226}
227
Jamie Madillf75ab352015-03-16 10:46:52 -0400228void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400229{
230 mStencilClearValue = stencil;
231}
232
Shannon Woods53a94a82014-06-24 15:20:36 -0400233void State::setColorMask(bool red, bool green, bool blue, bool alpha)
234{
235 mBlend.colorMaskRed = red;
236 mBlend.colorMaskGreen = green;
237 mBlend.colorMaskBlue = blue;
238 mBlend.colorMaskAlpha = alpha;
239}
240
241void State::setDepthMask(bool mask)
242{
243 mDepthStencil.depthMask = mask;
244}
245
246bool State::isRasterizerDiscardEnabled() const
247{
248 return mRasterizer.rasterizerDiscard;
249}
250
251void State::setRasterizerDiscard(bool enabled)
252{
253 mRasterizer.rasterizerDiscard = enabled;
254}
255
256bool State::isCullFaceEnabled() const
257{
258 return mRasterizer.cullFace;
259}
260
261void State::setCullFace(bool enabled)
262{
263 mRasterizer.cullFace = enabled;
264}
265
266void State::setCullMode(GLenum mode)
267{
268 mRasterizer.cullMode = mode;
269}
270
271void State::setFrontFace(GLenum front)
272{
273 mRasterizer.frontFace = front;
274}
275
276bool State::isDepthTestEnabled() const
277{
278 return mDepthStencil.depthTest;
279}
280
281void State::setDepthTest(bool enabled)
282{
283 mDepthStencil.depthTest = enabled;
284}
285
286void State::setDepthFunc(GLenum depthFunc)
287{
288 mDepthStencil.depthFunc = depthFunc;
289}
290
291void State::setDepthRange(float zNear, float zFar)
292{
293 mNearZ = zNear;
294 mFarZ = zFar;
295}
296
297void State::getDepthRange(float *zNear, float *zFar) const
298{
299 *zNear = mNearZ;
300 *zFar = mFarZ;
301}
302
303bool State::isBlendEnabled() const
304{
305 return mBlend.blend;
306}
307
308void State::setBlend(bool enabled)
309{
310 mBlend.blend = enabled;
311}
312
313void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
314{
315 mBlend.sourceBlendRGB = sourceRGB;
316 mBlend.destBlendRGB = destRGB;
317 mBlend.sourceBlendAlpha = sourceAlpha;
318 mBlend.destBlendAlpha = destAlpha;
319}
320
321void State::setBlendColor(float red, float green, float blue, float alpha)
322{
323 mBlendColor.red = red;
324 mBlendColor.green = green;
325 mBlendColor.blue = blue;
326 mBlendColor.alpha = alpha;
327}
328
329void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
330{
331 mBlend.blendEquationRGB = rgbEquation;
332 mBlend.blendEquationAlpha = alphaEquation;
333}
334
335const ColorF &State::getBlendColor() const
336{
337 return mBlendColor;
338}
339
340bool State::isStencilTestEnabled() const
341{
342 return mDepthStencil.stencilTest;
343}
344
345void State::setStencilTest(bool enabled)
346{
347 mDepthStencil.stencilTest = enabled;
348}
349
350void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
351{
352 mDepthStencil.stencilFunc = stencilFunc;
353 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
354 mDepthStencil.stencilMask = stencilMask;
355}
356
357void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
358{
359 mDepthStencil.stencilBackFunc = stencilBackFunc;
360 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
361 mDepthStencil.stencilBackMask = stencilBackMask;
362}
363
364void State::setStencilWritemask(GLuint stencilWritemask)
365{
366 mDepthStencil.stencilWritemask = stencilWritemask;
367}
368
369void State::setStencilBackWritemask(GLuint stencilBackWritemask)
370{
371 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
372}
373
374void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
375{
376 mDepthStencil.stencilFail = stencilFail;
377 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
378 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
379}
380
381void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
382{
383 mDepthStencil.stencilBackFail = stencilBackFail;
384 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
385 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
386}
387
388GLint State::getStencilRef() const
389{
390 return mStencilRef;
391}
392
393GLint State::getStencilBackRef() const
394{
395 return mStencilBackRef;
396}
397
398bool State::isPolygonOffsetFillEnabled() const
399{
400 return mRasterizer.polygonOffsetFill;
401}
402
403void State::setPolygonOffsetFill(bool enabled)
404{
405 mRasterizer.polygonOffsetFill = enabled;
406}
407
408void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
409{
410 // An application can pass NaN values here, so handle this gracefully
411 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
412 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
413}
414
415bool State::isSampleAlphaToCoverageEnabled() const
416{
417 return mBlend.sampleAlphaToCoverage;
418}
419
420void State::setSampleAlphaToCoverage(bool enabled)
421{
422 mBlend.sampleAlphaToCoverage = enabled;
423}
424
425bool State::isSampleCoverageEnabled() const
426{
427 return mSampleCoverage;
428}
429
430void State::setSampleCoverage(bool enabled)
431{
432 mSampleCoverage = enabled;
433}
434
435void State::setSampleCoverageParams(GLclampf value, bool invert)
436{
437 mSampleCoverageValue = value;
438 mSampleCoverageInvert = invert;
439}
440
Jamie Madilld9e58302014-11-06 15:27:26 -0500441void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400442{
443 ASSERT(value != NULL && invert != NULL);
444
445 *value = mSampleCoverageValue;
446 *invert = mSampleCoverageInvert;
447}
448
449bool State::isScissorTestEnabled() const
450{
451 return mScissorTest;
452}
453
454void State::setScissorTest(bool enabled)
455{
456 mScissorTest = enabled;
457}
458
459void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
460{
461 mScissor.x = x;
462 mScissor.y = y;
463 mScissor.width = width;
464 mScissor.height = height;
465}
466
467const Rectangle &State::getScissor() const
468{
469 return mScissor;
470}
471
472bool State::isDitherEnabled() const
473{
474 return mBlend.dither;
475}
476
477void State::setDither(bool enabled)
478{
479 mBlend.dither = enabled;
480}
481
Jamie Madillb4b53c52015-02-03 15:22:48 -0500482bool State::isPrimitiveRestartEnabled() const
483{
484 return mPrimitiveRestart;
485}
486
487void State::setPrimitiveRestart(bool enabled)
488{
489 mPrimitiveRestart = enabled;
490}
491
Shannon Woods53a94a82014-06-24 15:20:36 -0400492void State::setEnableFeature(GLenum feature, bool enabled)
493{
494 switch (feature)
495 {
496 case GL_CULL_FACE: setCullFace(enabled); break;
497 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
498 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
499 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
500 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
501 case GL_STENCIL_TEST: setStencilTest(enabled); break;
502 case GL_DEPTH_TEST: setDepthTest(enabled); break;
503 case GL_BLEND: setBlend(enabled); break;
504 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500505 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400506 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
507 default: UNREACHABLE();
508 }
509}
510
511bool State::getEnableFeature(GLenum feature)
512{
513 switch (feature)
514 {
515 case GL_CULL_FACE: return isCullFaceEnabled();
516 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
517 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
518 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
519 case GL_SCISSOR_TEST: return isScissorTestEnabled();
520 case GL_STENCIL_TEST: return isStencilTestEnabled();
521 case GL_DEPTH_TEST: return isDepthTestEnabled();
522 case GL_BLEND: return isBlendEnabled();
523 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500524 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400525 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
526 default: UNREACHABLE(); return false;
527 }
528}
529
530void State::setLineWidth(GLfloat width)
531{
532 mLineWidth = width;
533}
534
535void State::setGenerateMipmapHint(GLenum hint)
536{
537 mGenerateMipmapHint = hint;
538}
539
540void State::setFragmentShaderDerivativeHint(GLenum hint)
541{
542 mFragmentShaderDerivativeHint = hint;
543 // TODO: Propagate the hint to shader translator so we can write
544 // ddx, ddx_coarse, or ddx_fine depending on the hint.
545 // Ignore for now. It is valid for implementations to ignore hint.
546}
547
548void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
549{
550 mViewport.x = x;
551 mViewport.y = y;
552 mViewport.width = width;
553 mViewport.height = height;
554}
555
556const Rectangle &State::getViewport() const
557{
558 return mViewport;
559}
560
561void State::setActiveSampler(unsigned int active)
562{
563 mActiveSampler = active;
564}
565
566unsigned int State::getActiveSampler() const
567{
568 return mActiveSampler;
569}
570
Geoff Lang76b10c92014-09-05 16:28:14 -0400571void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400572{
Geoff Lang76b10c92014-09-05 16:28:14 -0400573 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400574}
575
Geoff Lang76b10c92014-09-05 16:28:14 -0400576Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400577{
Jamie Madill5864ac22015-01-12 14:43:07 -0500578 const auto it = mSamplerTextures.find(type);
579 ASSERT(it != mSamplerTextures.end());
580 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400581}
582
Geoff Lang76b10c92014-09-05 16:28:14 -0400583GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400584{
Jamie Madill5864ac22015-01-12 14:43:07 -0500585 const auto it = mSamplerTextures.find(type);
586 ASSERT(it != mSamplerTextures.end());
587 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400588}
589
Jamie Madille6382c32014-11-07 15:05:26 -0500590void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400591{
592 // Textures have a detach method on State rather than a simple
593 // removeBinding, because the zero/null texture objects are managed
594 // separately, and don't have to go through the Context's maps or
595 // the ResourceManager.
596
597 // [OpenGL ES 2.0.24] section 3.8 page 84:
598 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
599 // rebound to texture object zero
600
Geoff Lang76b10c92014-09-05 16:28:14 -0400601 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400602 {
Jamie Madille6382c32014-11-07 15:05:26 -0500603 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400604 TextureBindingVector &textureVector = bindingVec->second;
605 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400606 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400607 BindingPointer<Texture> &binding = textureVector[textureIdx];
608 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400609 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500610 auto it = zeroTextures.find(textureType);
611 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500612 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500613 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400614 }
615 }
616 }
617
618 // [OpenGL ES 2.0.24] section 4.4 page 112:
619 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
620 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
621 // image was attached in the currently bound framebuffer.
622
623 if (mReadFramebuffer)
624 {
625 mReadFramebuffer->detachTexture(texture);
626 }
627
628 if (mDrawFramebuffer)
629 {
630 mDrawFramebuffer->detachTexture(texture);
631 }
632}
633
Jamie Madille6382c32014-11-07 15:05:26 -0500634void State::initializeZeroTextures(const TextureMap &zeroTextures)
635{
636 for (const auto &zeroTexture : zeroTextures)
637 {
638 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
639
640 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
641 {
642 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
643 }
644 }
645}
646
Shannon Woods53a94a82014-06-24 15:20:36 -0400647void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
648{
649 mSamplers[textureUnit].set(sampler);
650}
651
652GLuint State::getSamplerId(GLuint textureUnit) const
653{
Geoff Lang76b10c92014-09-05 16:28:14 -0400654 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400655 return mSamplers[textureUnit].id();
656}
657
658Sampler *State::getSampler(GLuint textureUnit) const
659{
660 return mSamplers[textureUnit].get();
661}
662
663void State::detachSampler(GLuint sampler)
664{
665 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
666 // If a sampler object that is currently bound to one or more texture units is
667 // deleted, it is as though BindSampler is called once for each texture unit to
668 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400669 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400670 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400671 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
672 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400673 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400674 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400675 }
676 }
677}
678
679void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
680{
681 mRenderbuffer.set(renderbuffer);
682}
683
684GLuint State::getRenderbufferId() const
685{
686 return mRenderbuffer.id();
687}
688
689Renderbuffer *State::getCurrentRenderbuffer()
690{
691 return mRenderbuffer.get();
692}
693
694void State::detachRenderbuffer(GLuint renderbuffer)
695{
696 // [OpenGL ES 2.0.24] section 4.4 page 109:
697 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
698 // had been executed with the target RENDERBUFFER and name of zero.
699
700 if (mRenderbuffer.id() == renderbuffer)
701 {
702 mRenderbuffer.set(NULL);
703 }
704
705 // [OpenGL ES 2.0.24] section 4.4 page 111:
706 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
707 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
708 // point to which this image was attached in the currently bound framebuffer.
709
710 Framebuffer *readFramebuffer = mReadFramebuffer;
711 Framebuffer *drawFramebuffer = mDrawFramebuffer;
712
713 if (readFramebuffer)
714 {
715 readFramebuffer->detachRenderbuffer(renderbuffer);
716 }
717
718 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
719 {
720 drawFramebuffer->detachRenderbuffer(renderbuffer);
721 }
722
723}
724
725void State::setReadFramebufferBinding(Framebuffer *framebuffer)
726{
727 mReadFramebuffer = framebuffer;
728}
729
730void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
731{
732 mDrawFramebuffer = framebuffer;
733}
734
735Framebuffer *State::getTargetFramebuffer(GLenum target) const
736{
737 switch (target)
738 {
739 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
740 case GL_DRAW_FRAMEBUFFER_ANGLE:
741 case GL_FRAMEBUFFER: return mDrawFramebuffer;
742 default: UNREACHABLE(); return NULL;
743 }
744}
745
746Framebuffer *State::getReadFramebuffer()
747{
748 return mReadFramebuffer;
749}
750
751Framebuffer *State::getDrawFramebuffer()
752{
753 return mDrawFramebuffer;
754}
755
756const Framebuffer *State::getReadFramebuffer() const
757{
758 return mReadFramebuffer;
759}
760
761const Framebuffer *State::getDrawFramebuffer() const
762{
763 return mDrawFramebuffer;
764}
765
766bool State::removeReadFramebufferBinding(GLuint framebuffer)
767{
Jamie Madill77a72f62015-04-14 11:18:32 -0400768 if (mReadFramebuffer != nullptr &&
769 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400770 {
771 mReadFramebuffer = NULL;
772 return true;
773 }
774
775 return false;
776}
777
778bool State::removeDrawFramebufferBinding(GLuint framebuffer)
779{
Jamie Madill77a72f62015-04-14 11:18:32 -0400780 if (mReadFramebuffer != nullptr &&
781 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400782 {
783 mDrawFramebuffer = NULL;
784 return true;
785 }
786
787 return false;
788}
789
790void State::setVertexArrayBinding(VertexArray *vertexArray)
791{
792 mVertexArray = vertexArray;
793}
794
795GLuint State::getVertexArrayId() const
796{
797 ASSERT(mVertexArray != NULL);
798 return mVertexArray->id();
799}
800
801VertexArray *State::getVertexArray() const
802{
803 ASSERT(mVertexArray != NULL);
804 return mVertexArray;
805}
806
807bool State::removeVertexArrayBinding(GLuint vertexArray)
808{
809 if (mVertexArray->id() == vertexArray)
810 {
811 mVertexArray = NULL;
812 return true;
813 }
814
815 return false;
816}
817
Geoff Lang7dd2e102014-11-10 15:19:26 -0500818void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400819{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500820 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400821 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500822 if (mProgram)
823 {
824 mProgram->release();
825 }
826
827 mProgram = newProgram;
828
829 if (mProgram)
830 {
831 newProgram->addRef();
832 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400833 }
834}
835
Geoff Lang7dd2e102014-11-10 15:19:26 -0500836Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400837{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500838 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400839}
840
841void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
842{
843 mTransformFeedback.set(transformFeedback);
844}
845
846TransformFeedback *State::getCurrentTransformFeedback() const
847{
848 return mTransformFeedback.get();
849}
850
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000851bool State::isTransformFeedbackActiveUnpaused() const
852{
853 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
854 return curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused();
855}
856
Shannon Woods53a94a82014-06-24 15:20:36 -0400857void State::detachTransformFeedback(GLuint transformFeedback)
858{
859 if (mTransformFeedback.id() == transformFeedback)
860 {
861 mTransformFeedback.set(NULL);
862 }
863}
864
865bool State::isQueryActive() const
866{
867 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
868 i != mActiveQueries.end(); i++)
869 {
870 if (i->second.get() != NULL)
871 {
872 return true;
873 }
874 }
875
876 return false;
877}
878
879void State::setActiveQuery(GLenum target, Query *query)
880{
881 mActiveQueries[target].set(query);
882}
883
884GLuint State::getActiveQueryId(GLenum target) const
885{
886 const Query *query = getActiveQuery(target);
887 return (query ? query->id() : 0u);
888}
889
890Query *State::getActiveQuery(GLenum target) const
891{
Jamie Madill5864ac22015-01-12 14:43:07 -0500892 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400893
Jamie Madill5864ac22015-01-12 14:43:07 -0500894 // All query types should already exist in the activeQueries map
895 ASSERT(it != mActiveQueries.end());
896
897 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400898}
899
900void State::setArrayBufferBinding(Buffer *buffer)
901{
902 mArrayBuffer.set(buffer);
903}
904
905GLuint State::getArrayBufferId() const
906{
907 return mArrayBuffer.id();
908}
909
910bool State::removeArrayBufferBinding(GLuint buffer)
911{
912 if (mArrayBuffer.id() == buffer)
913 {
914 mArrayBuffer.set(NULL);
915 return true;
916 }
917
918 return false;
919}
920
921void State::setGenericUniformBufferBinding(Buffer *buffer)
922{
923 mGenericUniformBuffer.set(buffer);
924}
925
926void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
927{
928 mUniformBuffers[index].set(buffer, offset, size);
929}
930
931GLuint State::getIndexedUniformBufferId(GLuint index) const
932{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400933 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400934
935 return mUniformBuffers[index].id();
936}
937
938Buffer *State::getIndexedUniformBuffer(GLuint index) const
939{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400940 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400941
942 return mUniformBuffers[index].get();
943}
944
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +0000945GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
946{
947 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
948
949 return mUniformBuffers[index].getOffset();
950}
951
952GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
953{
954 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
955
956 return mUniformBuffers[index].getSize();
957}
958
Shannon Woods53a94a82014-06-24 15:20:36 -0400959void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
960{
961 mGenericTransformFeedbackBuffer.set(buffer);
962}
963
964void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
965{
966 mTransformFeedbackBuffers[index].set(buffer, offset, size);
967}
968
969GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
970{
Shannon Woods8299bb02014-09-26 18:55:43 -0400971 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400972
973 return mTransformFeedbackBuffers[index].id();
974}
975
976Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
977{
Shannon Woods8299bb02014-09-26 18:55:43 -0400978 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400979
980 return mTransformFeedbackBuffers[index].get();
981}
982
983GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
984{
Shannon Woods8299bb02014-09-26 18:55:43 -0400985 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400986
Minmin Gong794e0002015-04-07 18:31:54 -0700987 return static_cast<unsigned int>(mTransformFeedbackBuffers[index].getOffset());
Shannon Woods53a94a82014-06-24 15:20:36 -0400988}
989
Shannon Woods8299bb02014-09-26 18:55:43 -0400990size_t State::getTransformFeedbackBufferIndexRange() const
991{
992 return mTransformFeedbackBuffers.size();
993}
994
Shannon Woods53a94a82014-06-24 15:20:36 -0400995void State::setCopyReadBufferBinding(Buffer *buffer)
996{
997 mCopyReadBuffer.set(buffer);
998}
999
1000void State::setCopyWriteBufferBinding(Buffer *buffer)
1001{
1002 mCopyWriteBuffer.set(buffer);
1003}
1004
1005void State::setPixelPackBufferBinding(Buffer *buffer)
1006{
1007 mPack.pixelBuffer.set(buffer);
1008}
1009
1010void State::setPixelUnpackBufferBinding(Buffer *buffer)
1011{
1012 mUnpack.pixelBuffer.set(buffer);
1013}
1014
1015Buffer *State::getTargetBuffer(GLenum target) const
1016{
1017 switch (target)
1018 {
1019 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1020 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1021 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1022 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1023 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1024 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1025 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1026 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1027 default: UNREACHABLE(); return NULL;
1028 }
1029}
1030
1031void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1032{
1033 getVertexArray()->enableAttribute(attribNum, enabled);
1034}
1035
1036void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1037{
Shannon Woods23e05002014-09-22 19:07:27 -04001038 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001039 mVertexAttribCurrentValues[index].setFloatValues(values);
1040}
1041
1042void State::setVertexAttribu(GLuint index, const GLuint values[4])
1043{
Shannon Woods23e05002014-09-22 19:07:27 -04001044 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001045 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1046}
1047
1048void State::setVertexAttribi(GLuint index, const GLint values[4])
1049{
Shannon Woods23e05002014-09-22 19:07:27 -04001050 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001051 mVertexAttribCurrentValues[index].setIntValues(values);
1052}
1053
1054void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1055 bool pureInteger, GLsizei stride, const void *pointer)
1056{
1057 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1058}
1059
Shannon Woods53a94a82014-06-24 15:20:36 -04001060const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1061{
Shannon Woods23e05002014-09-22 19:07:27 -04001062 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001063 return mVertexAttribCurrentValues[attribNum];
1064}
1065
Shannon Woods53a94a82014-06-24 15:20:36 -04001066const void *State::getVertexAttribPointer(unsigned int attribNum) const
1067{
1068 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1069}
1070
1071void State::setPackAlignment(GLint alignment)
1072{
1073 mPack.alignment = alignment;
1074}
1075
1076GLint State::getPackAlignment() const
1077{
1078 return mPack.alignment;
1079}
1080
1081void State::setPackReverseRowOrder(bool reverseRowOrder)
1082{
1083 mPack.reverseRowOrder = reverseRowOrder;
1084}
1085
1086bool State::getPackReverseRowOrder() const
1087{
1088 return mPack.reverseRowOrder;
1089}
1090
1091const PixelPackState &State::getPackState() const
1092{
1093 return mPack;
1094}
1095
Jamie Madill87de3622015-03-16 10:41:44 -04001096PixelPackState &State::getPackState()
1097{
1098 return mPack;
1099}
1100
Shannon Woods53a94a82014-06-24 15:20:36 -04001101void State::setUnpackAlignment(GLint alignment)
1102{
1103 mUnpack.alignment = alignment;
1104}
1105
1106GLint State::getUnpackAlignment() const
1107{
1108 return mUnpack.alignment;
1109}
1110
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001111void State::setUnpackRowLength(GLint rowLength)
1112{
1113 mUnpack.rowLength = rowLength;
1114}
1115
1116GLint State::getUnpackRowLength() const
1117{
1118 return mUnpack.rowLength;
1119}
1120
Shannon Woods53a94a82014-06-24 15:20:36 -04001121const PixelUnpackState &State::getUnpackState() const
1122{
1123 return mUnpack;
1124}
1125
Jamie Madill67102f02015-03-16 10:41:42 -04001126PixelUnpackState &State::getUnpackState()
1127{
1128 return mUnpack;
1129}
1130
Shannon Woods53a94a82014-06-24 15:20:36 -04001131void State::getBooleanv(GLenum pname, GLboolean *params)
1132{
1133 switch (pname)
1134 {
1135 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1136 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1137 case GL_COLOR_WRITEMASK:
1138 params[0] = mBlend.colorMaskRed;
1139 params[1] = mBlend.colorMaskGreen;
1140 params[2] = mBlend.colorMaskBlue;
1141 params[3] = mBlend.colorMaskAlpha;
1142 break;
1143 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1144 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1145 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1146 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1147 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1148 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1149 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1150 case GL_BLEND: *params = mBlend.blend; break;
1151 case GL_DITHER: *params = mBlend.dither; break;
1152 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1153 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1154 default:
1155 UNREACHABLE();
1156 break;
1157 }
1158}
1159
1160void State::getFloatv(GLenum pname, GLfloat *params)
1161{
1162 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1163 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1164 // GetIntegerv as its native query function. As it would require conversion in any
1165 // case, this should make no difference to the calling application.
1166 switch (pname)
1167 {
1168 case GL_LINE_WIDTH: *params = mLineWidth; break;
1169 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1170 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1171 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1172 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1173 case GL_DEPTH_RANGE:
1174 params[0] = mNearZ;
1175 params[1] = mFarZ;
1176 break;
1177 case GL_COLOR_CLEAR_VALUE:
1178 params[0] = mColorClearValue.red;
1179 params[1] = mColorClearValue.green;
1180 params[2] = mColorClearValue.blue;
1181 params[3] = mColorClearValue.alpha;
1182 break;
1183 case GL_BLEND_COLOR:
1184 params[0] = mBlendColor.red;
1185 params[1] = mBlendColor.green;
1186 params[2] = mBlendColor.blue;
1187 params[3] = mBlendColor.alpha;
1188 break;
1189 default:
1190 UNREACHABLE();
1191 break;
1192 }
1193}
1194
Jamie Madill48faf802014-11-06 15:27:22 -05001195void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001196{
1197 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1198 {
1199 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001200 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001201 Framebuffer *framebuffer = mDrawFramebuffer;
1202 *params = framebuffer->getDrawBufferState(colorAttachment);
1203 return;
1204 }
1205
1206 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1207 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1208 // GetIntegerv as its native query function. As it would require conversion in any
1209 // case, this should make no difference to the calling application. You may find it in
1210 // State::getFloatv.
1211 switch (pname)
1212 {
1213 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1214 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1215 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1216 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1217 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1218 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1219 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001220 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001221 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1222 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1223 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001224 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001225 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1226 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1227 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1228 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1229 case GL_STENCIL_REF: *params = mStencilRef; break;
1230 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1231 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1232 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1233 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1234 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1235 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1236 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1237 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1238 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1239 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1240 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1241 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1242 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1243 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1244 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1245 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1246 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1247 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1248 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1249 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001250 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1251 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001252 case GL_SAMPLE_BUFFERS:
1253 case GL_SAMPLES:
1254 {
1255 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001256 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001257 {
1258 switch (pname)
1259 {
1260 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001261 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001262 {
1263 *params = 1;
1264 }
1265 else
1266 {
1267 *params = 0;
1268 }
1269 break;
1270 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001271 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001272 break;
1273 }
1274 }
1275 else
1276 {
1277 *params = 0;
1278 }
1279 }
1280 break;
1281 case GL_VIEWPORT:
1282 params[0] = mViewport.x;
1283 params[1] = mViewport.y;
1284 params[2] = mViewport.width;
1285 params[3] = mViewport.height;
1286 break;
1287 case GL_SCISSOR_BOX:
1288 params[0] = mScissor.x;
1289 params[1] = mScissor.y;
1290 params[2] = mScissor.width;
1291 params[3] = mScissor.height;
1292 break;
1293 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1294 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1295 case GL_RED_BITS:
1296 case GL_GREEN_BITS:
1297 case GL_BLUE_BITS:
1298 case GL_ALPHA_BITS:
1299 {
1300 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1301 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1302
1303 if (colorbuffer)
1304 {
1305 switch (pname)
1306 {
1307 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1308 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1309 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1310 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1311 }
1312 }
1313 else
1314 {
1315 *params = 0;
1316 }
1317 }
1318 break;
1319 case GL_DEPTH_BITS:
1320 {
1321 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1322 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1323
1324 if (depthbuffer)
1325 {
1326 *params = depthbuffer->getDepthSize();
1327 }
1328 else
1329 {
1330 *params = 0;
1331 }
1332 }
1333 break;
1334 case GL_STENCIL_BITS:
1335 {
1336 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1337 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1338
1339 if (stencilbuffer)
1340 {
1341 *params = stencilbuffer->getStencilSize();
1342 }
1343 else
1344 {
1345 *params = 0;
1346 }
1347 }
1348 break;
1349 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001350 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001351 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001352 break;
1353 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001354 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001355 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001356 break;
1357 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001358 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001359 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001360 break;
1361 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001362 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001363 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001364 break;
1365 case GL_UNIFORM_BUFFER_BINDING:
1366 *params = mGenericUniformBuffer.id();
1367 break;
1368 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1369 *params = mGenericTransformFeedbackBuffer.id();
1370 break;
1371 case GL_COPY_READ_BUFFER_BINDING:
1372 *params = mCopyReadBuffer.id();
1373 break;
1374 case GL_COPY_WRITE_BUFFER_BINDING:
1375 *params = mCopyWriteBuffer.id();
1376 break;
1377 case GL_PIXEL_PACK_BUFFER_BINDING:
1378 *params = mPack.pixelBuffer.id();
1379 break;
1380 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1381 *params = mUnpack.pixelBuffer.id();
1382 break;
1383 default:
1384 UNREACHABLE();
1385 break;
1386 }
1387}
1388
1389bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1390{
1391 switch (target)
1392 {
1393 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Shannon Woods8299bb02014-09-26 18:55:43 -04001394 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001395 {
1396 *data = mTransformFeedbackBuffers[index].id();
1397 }
1398 break;
1399 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001400 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001401 {
1402 *data = mUniformBuffers[index].id();
1403 }
1404 break;
1405 default:
1406 return false;
1407 }
1408
1409 return true;
1410}
1411
1412bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1413{
1414 switch (target)
1415 {
1416 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Shannon Woods8299bb02014-09-26 18:55:43 -04001417 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001418 {
1419 *data = mTransformFeedbackBuffers[index].getOffset();
1420 }
1421 break;
1422 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Shannon Woods8299bb02014-09-26 18:55:43 -04001423 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001424 {
1425 *data = mTransformFeedbackBuffers[index].getSize();
1426 }
1427 break;
1428 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001429 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001430 {
1431 *data = mUniformBuffers[index].getOffset();
1432 }
1433 break;
1434 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001435 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001436 {
1437 *data = mUniformBuffers[index].getSize();
1438 }
1439 break;
1440 default:
1441 return false;
1442 }
1443
1444 return true;
1445}
1446
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001447bool State::hasMappedBuffer(GLenum target) const
1448{
1449 if (target == GL_ARRAY_BUFFER)
1450 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001451 const VertexArray *vao = getVertexArray();
Shannon Woods23e05002014-09-22 19:07:27 -04001452 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001453 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001454 const gl::VertexAttribute &vertexAttrib = vao->getVertexAttribute(attribIndex);
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001455 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1456 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1457 {
1458 return true;
1459 }
1460 }
1461
1462 return false;
1463 }
1464 else
1465 {
1466 Buffer *buffer = getTargetBuffer(target);
1467 return (buffer && buffer->isMapped());
1468 }
1469}
1470
Shannon Woods53a94a82014-06-24 15:20:36 -04001471}