blob: cbe5576a65fcfc7eb1a57a4bae496218195718cb [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"
18#include "libANGLE/renderer/RenderTarget.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040019
20namespace gl
21{
Geoff Lang76b10c92014-09-05 16:28:14 -040022
Shannon Woods53a94a82014-06-24 15:20:36 -040023State::State()
24{
Shannon Woods2df6a602014-09-26 16:12:07 -040025 mMaxDrawBuffers = 0;
26 mMaxCombinedTextureImageUnits = 0;
Geoff Lang76b10c92014-09-05 16:28:14 -040027}
28
29State::~State()
30{
31 reset();
32}
33
34void State::initialize(const Caps& caps, GLuint clientVersion)
35{
Shannon Woods2df6a602014-09-26 16:12:07 -040036 mMaxDrawBuffers = caps.maxDrawBuffers;
37 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040038
39 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
40
41 mDepthClearValue = 1.0f;
42 mStencilClearValue = 0;
43
44 mRasterizer.rasterizerDiscard = false;
45 mRasterizer.cullFace = false;
46 mRasterizer.cullMode = GL_BACK;
47 mRasterizer.frontFace = GL_CCW;
48 mRasterizer.polygonOffsetFill = false;
49 mRasterizer.polygonOffsetFactor = 0.0f;
50 mRasterizer.polygonOffsetUnits = 0.0f;
51 mRasterizer.pointDrawMode = false;
52 mRasterizer.multiSample = false;
53 mScissorTest = false;
54 mScissor.x = 0;
55 mScissor.y = 0;
56 mScissor.width = 0;
57 mScissor.height = 0;
58
59 mBlend.blend = false;
60 mBlend.sourceBlendRGB = GL_ONE;
61 mBlend.sourceBlendAlpha = GL_ONE;
62 mBlend.destBlendRGB = GL_ZERO;
63 mBlend.destBlendAlpha = GL_ZERO;
64 mBlend.blendEquationRGB = GL_FUNC_ADD;
65 mBlend.blendEquationAlpha = GL_FUNC_ADD;
66 mBlend.sampleAlphaToCoverage = false;
67 mBlend.dither = true;
68
69 mBlendColor.red = 0;
70 mBlendColor.green = 0;
71 mBlendColor.blue = 0;
72 mBlendColor.alpha = 0;
73
74 mDepthStencil.depthTest = false;
75 mDepthStencil.depthFunc = GL_LESS;
76 mDepthStencil.depthMask = true;
77 mDepthStencil.stencilTest = false;
78 mDepthStencil.stencilFunc = GL_ALWAYS;
79 mDepthStencil.stencilMask = -1;
80 mDepthStencil.stencilWritemask = -1;
81 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Geoff Lang76b10c92014-09-05 16:28:14 -040082 mDepthStencil.stencilBackMask = -1;
Shannon Woods53a94a82014-06-24 15:20:36 -040083 mDepthStencil.stencilBackWritemask = -1;
84 mDepthStencil.stencilFail = GL_KEEP;
85 mDepthStencil.stencilPassDepthFail = GL_KEEP;
86 mDepthStencil.stencilPassDepthPass = GL_KEEP;
87 mDepthStencil.stencilBackFail = GL_KEEP;
88 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
89 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
90
91 mStencilRef = 0;
92 mStencilBackRef = 0;
93
94 mSampleCoverage = false;
95 mSampleCoverageValue = 1.0f;
96 mSampleCoverageInvert = false;
97 mGenerateMipmapHint = GL_DONT_CARE;
98 mFragmentShaderDerivativeHint = GL_DONT_CARE;
99
100 mLineWidth = 1.0f;
101
102 mViewport.x = 0;
103 mViewport.y = 0;
104 mViewport.width = 0;
105 mViewport.height = 0;
106 mNearZ = 0.0f;
107 mFarZ = 1.0f;
108
109 mBlend.colorMaskRed = true;
110 mBlend.colorMaskGreen = true;
111 mBlend.colorMaskBlue = true;
112 mBlend.colorMaskAlpha = true;
113
Geoff Lang76b10c92014-09-05 16:28:14 -0400114 mActiveSampler = 0;
115
Shannon Woods53a94a82014-06-24 15:20:36 -0400116 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
Shannon Woods23e05002014-09-22 19:07:27 -0400117 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
118 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
Shannon Woods53a94a82014-06-24 15:20:36 -0400119 {
120 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
121 }
122
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400123 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
Shannon Woods8299bb02014-09-26 18:55:43 -0400124 mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400125
Geoff Lang76b10c92014-09-05 16:28:14 -0400126 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
127 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
128 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400129 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400130 // TODO: These could also be enabled via extension
131 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
132 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400133 }
134
Geoff Lang76b10c92014-09-05 16:28:14 -0400135 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400136
137 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
138 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
139 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
140
Geoff Lang7dd2e102014-11-10 15:19:26 -0500141 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400142
143 mReadFramebuffer = NULL;
144 mDrawFramebuffer = NULL;
145}
146
Geoff Lang76b10c92014-09-05 16:28:14 -0400147void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400148{
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400150 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400151 TextureBindingVector &textureVector = bindingVec->second;
152 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400153 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400154 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 }
156 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400157 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
158 {
159 mSamplers[samplerIdx].set(NULL);
160 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400161
Shannon Woods53a94a82014-06-24 15:20:36 -0400162 mArrayBuffer.set(NULL);
163 mRenderbuffer.set(NULL);
164
Geoff Lang7dd2e102014-11-10 15:19:26 -0500165 if (mProgram)
166 {
167 mProgram->release();
168 }
169 mProgram = NULL;
170
Shannon Woods53a94a82014-06-24 15:20:36 -0400171 mTransformFeedback.set(NULL);
172
173 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
174 {
175 i->second.set(NULL);
176 }
177
178 mGenericUniformBuffer.set(NULL);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400179 mGenericTransformFeedbackBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400180 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400181 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400182 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400183 }
184
Shannon Woods8299bb02014-09-26 18:55:43 -0400185 for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400186 {
Shannon Woods8299bb02014-09-26 18:55:43 -0400187 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400188 }
189
190 mCopyReadBuffer.set(NULL);
191 mCopyWriteBuffer.set(NULL);
192
193 mPack.pixelBuffer.set(NULL);
194 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500195
196 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400197}
198
199const RasterizerState &State::getRasterizerState() const
200{
201 return mRasterizer;
202}
203
204const BlendState &State::getBlendState() const
205{
206 return mBlend;
207}
208
209const DepthStencilState &State::getDepthStencilState() const
210{
211 return mDepthStencil;
212}
213
214void State::setClearColor(float red, float green, float blue, float alpha)
215{
216 mColorClearValue.red = red;
217 mColorClearValue.green = green;
218 mColorClearValue.blue = blue;
219 mColorClearValue.alpha = alpha;
220}
221
222void State::setClearDepth(float depth)
223{
224 mDepthClearValue = depth;
225}
226
227void State::setClearStencil(int stencil)
228{
229 mStencilClearValue = stencil;
230}
231
232ClearParameters State::getClearParameters(GLbitfield mask) const
233{
Jamie Madill639db122014-12-03 11:36:43 -0500234 ClearParameters clearParams;
235 memset(&clearParams, 0, sizeof(ClearParameters));
Shannon Woods53a94a82014-06-24 15:20:36 -0400236 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
237 {
238 clearParams.clearColor[i] = false;
239 }
240 clearParams.colorFClearValue = mColorClearValue;
241 clearParams.colorClearType = GL_FLOAT;
242 clearParams.colorMaskRed = mBlend.colorMaskRed;
243 clearParams.colorMaskGreen = mBlend.colorMaskGreen;
244 clearParams.colorMaskBlue = mBlend.colorMaskBlue;
245 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
246 clearParams.clearDepth = false;
247 clearParams.depthClearValue = mDepthClearValue;
248 clearParams.clearStencil = false;
249 clearParams.stencilClearValue = mStencilClearValue;
250 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
251 clearParams.scissorEnabled = mScissorTest;
252 clearParams.scissor = mScissor;
253
254 const Framebuffer *framebufferObject = getDrawFramebuffer();
255 if (mask & GL_COLOR_BUFFER_BIT)
256 {
257 if (framebufferObject->hasEnabledColorAttachment())
258 {
259 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
260 {
261 clearParams.clearColor[i] = true;
262 }
263 }
264 }
265
266 if (mask & GL_DEPTH_BUFFER_BIT)
267 {
268 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
269 {
270 clearParams.clearDepth = true;
271 }
272 }
273
274 if (mask & GL_STENCIL_BUFFER_BIT)
275 {
276 if (framebufferObject->getStencilbuffer() != NULL)
277 {
Jamie Madilldd8488d2014-09-03 15:07:21 -0400278 GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
279 if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
Shannon Woods53a94a82014-06-24 15:20:36 -0400280 {
281 clearParams.clearStencil = true;
282 }
283 }
284 }
285
286 return clearParams;
287}
288
289void State::setColorMask(bool red, bool green, bool blue, bool alpha)
290{
291 mBlend.colorMaskRed = red;
292 mBlend.colorMaskGreen = green;
293 mBlend.colorMaskBlue = blue;
294 mBlend.colorMaskAlpha = alpha;
295}
296
297void State::setDepthMask(bool mask)
298{
299 mDepthStencil.depthMask = mask;
300}
301
302bool State::isRasterizerDiscardEnabled() const
303{
304 return mRasterizer.rasterizerDiscard;
305}
306
307void State::setRasterizerDiscard(bool enabled)
308{
309 mRasterizer.rasterizerDiscard = enabled;
310}
311
312bool State::isCullFaceEnabled() const
313{
314 return mRasterizer.cullFace;
315}
316
317void State::setCullFace(bool enabled)
318{
319 mRasterizer.cullFace = enabled;
320}
321
322void State::setCullMode(GLenum mode)
323{
324 mRasterizer.cullMode = mode;
325}
326
327void State::setFrontFace(GLenum front)
328{
329 mRasterizer.frontFace = front;
330}
331
332bool State::isDepthTestEnabled() const
333{
334 return mDepthStencil.depthTest;
335}
336
337void State::setDepthTest(bool enabled)
338{
339 mDepthStencil.depthTest = enabled;
340}
341
342void State::setDepthFunc(GLenum depthFunc)
343{
344 mDepthStencil.depthFunc = depthFunc;
345}
346
347void State::setDepthRange(float zNear, float zFar)
348{
349 mNearZ = zNear;
350 mFarZ = zFar;
351}
352
353void State::getDepthRange(float *zNear, float *zFar) const
354{
355 *zNear = mNearZ;
356 *zFar = mFarZ;
357}
358
359bool State::isBlendEnabled() const
360{
361 return mBlend.blend;
362}
363
364void State::setBlend(bool enabled)
365{
366 mBlend.blend = enabled;
367}
368
369void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
370{
371 mBlend.sourceBlendRGB = sourceRGB;
372 mBlend.destBlendRGB = destRGB;
373 mBlend.sourceBlendAlpha = sourceAlpha;
374 mBlend.destBlendAlpha = destAlpha;
375}
376
377void State::setBlendColor(float red, float green, float blue, float alpha)
378{
379 mBlendColor.red = red;
380 mBlendColor.green = green;
381 mBlendColor.blue = blue;
382 mBlendColor.alpha = alpha;
383}
384
385void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
386{
387 mBlend.blendEquationRGB = rgbEquation;
388 mBlend.blendEquationAlpha = alphaEquation;
389}
390
391const ColorF &State::getBlendColor() const
392{
393 return mBlendColor;
394}
395
396bool State::isStencilTestEnabled() const
397{
398 return mDepthStencil.stencilTest;
399}
400
401void State::setStencilTest(bool enabled)
402{
403 mDepthStencil.stencilTest = enabled;
404}
405
406void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
407{
408 mDepthStencil.stencilFunc = stencilFunc;
409 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
410 mDepthStencil.stencilMask = stencilMask;
411}
412
413void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
414{
415 mDepthStencil.stencilBackFunc = stencilBackFunc;
416 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
417 mDepthStencil.stencilBackMask = stencilBackMask;
418}
419
420void State::setStencilWritemask(GLuint stencilWritemask)
421{
422 mDepthStencil.stencilWritemask = stencilWritemask;
423}
424
425void State::setStencilBackWritemask(GLuint stencilBackWritemask)
426{
427 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
428}
429
430void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
431{
432 mDepthStencil.stencilFail = stencilFail;
433 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
434 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
435}
436
437void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
438{
439 mDepthStencil.stencilBackFail = stencilBackFail;
440 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
441 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
442}
443
444GLint State::getStencilRef() const
445{
446 return mStencilRef;
447}
448
449GLint State::getStencilBackRef() const
450{
451 return mStencilBackRef;
452}
453
454bool State::isPolygonOffsetFillEnabled() const
455{
456 return mRasterizer.polygonOffsetFill;
457}
458
459void State::setPolygonOffsetFill(bool enabled)
460{
461 mRasterizer.polygonOffsetFill = enabled;
462}
463
464void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
465{
466 // An application can pass NaN values here, so handle this gracefully
467 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
468 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
469}
470
471bool State::isSampleAlphaToCoverageEnabled() const
472{
473 return mBlend.sampleAlphaToCoverage;
474}
475
476void State::setSampleAlphaToCoverage(bool enabled)
477{
478 mBlend.sampleAlphaToCoverage = enabled;
479}
480
481bool State::isSampleCoverageEnabled() const
482{
483 return mSampleCoverage;
484}
485
486void State::setSampleCoverage(bool enabled)
487{
488 mSampleCoverage = enabled;
489}
490
491void State::setSampleCoverageParams(GLclampf value, bool invert)
492{
493 mSampleCoverageValue = value;
494 mSampleCoverageInvert = invert;
495}
496
Jamie Madilld9e58302014-11-06 15:27:26 -0500497void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400498{
499 ASSERT(value != NULL && invert != NULL);
500
501 *value = mSampleCoverageValue;
502 *invert = mSampleCoverageInvert;
503}
504
505bool State::isScissorTestEnabled() const
506{
507 return mScissorTest;
508}
509
510void State::setScissorTest(bool enabled)
511{
512 mScissorTest = enabled;
513}
514
515void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
516{
517 mScissor.x = x;
518 mScissor.y = y;
519 mScissor.width = width;
520 mScissor.height = height;
521}
522
523const Rectangle &State::getScissor() const
524{
525 return mScissor;
526}
527
528bool State::isDitherEnabled() const
529{
530 return mBlend.dither;
531}
532
533void State::setDither(bool enabled)
534{
535 mBlend.dither = enabled;
536}
537
538void State::setEnableFeature(GLenum feature, bool enabled)
539{
540 switch (feature)
541 {
542 case GL_CULL_FACE: setCullFace(enabled); break;
543 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
544 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
545 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
546 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
547 case GL_STENCIL_TEST: setStencilTest(enabled); break;
548 case GL_DEPTH_TEST: setDepthTest(enabled); break;
549 case GL_BLEND: setBlend(enabled); break;
550 case GL_DITHER: setDither(enabled); break;
551 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
552 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
553 default: UNREACHABLE();
554 }
555}
556
557bool State::getEnableFeature(GLenum feature)
558{
559 switch (feature)
560 {
561 case GL_CULL_FACE: return isCullFaceEnabled();
562 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
563 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
564 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
565 case GL_SCISSOR_TEST: return isScissorTestEnabled();
566 case GL_STENCIL_TEST: return isStencilTestEnabled();
567 case GL_DEPTH_TEST: return isDepthTestEnabled();
568 case GL_BLEND: return isBlendEnabled();
569 case GL_DITHER: return isDitherEnabled();
570 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
571 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
572 default: UNREACHABLE(); return false;
573 }
574}
575
576void State::setLineWidth(GLfloat width)
577{
578 mLineWidth = width;
579}
580
581void State::setGenerateMipmapHint(GLenum hint)
582{
583 mGenerateMipmapHint = hint;
584}
585
586void State::setFragmentShaderDerivativeHint(GLenum hint)
587{
588 mFragmentShaderDerivativeHint = hint;
589 // TODO: Propagate the hint to shader translator so we can write
590 // ddx, ddx_coarse, or ddx_fine depending on the hint.
591 // Ignore for now. It is valid for implementations to ignore hint.
592}
593
594void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
595{
596 mViewport.x = x;
597 mViewport.y = y;
598 mViewport.width = width;
599 mViewport.height = height;
600}
601
602const Rectangle &State::getViewport() const
603{
604 return mViewport;
605}
606
607void State::setActiveSampler(unsigned int active)
608{
609 mActiveSampler = active;
610}
611
612unsigned int State::getActiveSampler() const
613{
614 return mActiveSampler;
615}
616
Geoff Lang76b10c92014-09-05 16:28:14 -0400617void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400618{
Geoff Lang76b10c92014-09-05 16:28:14 -0400619 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400620}
621
Geoff Lang76b10c92014-09-05 16:28:14 -0400622Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400623{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500624 return mSamplerTextures.at(type)[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400625}
626
Geoff Lang76b10c92014-09-05 16:28:14 -0400627GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400628{
Geoff Lang76b10c92014-09-05 16:28:14 -0400629 return mSamplerTextures.at(type)[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400630}
631
Jamie Madille6382c32014-11-07 15:05:26 -0500632void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400633{
634 // Textures have a detach method on State rather than a simple
635 // removeBinding, because the zero/null texture objects are managed
636 // separately, and don't have to go through the Context's maps or
637 // the ResourceManager.
638
639 // [OpenGL ES 2.0.24] section 3.8 page 84:
640 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
641 // rebound to texture object zero
642
Geoff Lang76b10c92014-09-05 16:28:14 -0400643 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400644 {
Jamie Madille6382c32014-11-07 15:05:26 -0500645 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400646 TextureBindingVector &textureVector = bindingVec->second;
647 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400648 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400649 BindingPointer<Texture> &binding = textureVector[textureIdx];
650 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400651 {
Jamie Madille6382c32014-11-07 15:05:26 -0500652 // Zero textures are the "default" textures instead of NULL
653 binding.set(zeroTextures.at(textureType).get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400654 }
655 }
656 }
657
658 // [OpenGL ES 2.0.24] section 4.4 page 112:
659 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
660 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
661 // image was attached in the currently bound framebuffer.
662
663 if (mReadFramebuffer)
664 {
665 mReadFramebuffer->detachTexture(texture);
666 }
667
668 if (mDrawFramebuffer)
669 {
670 mDrawFramebuffer->detachTexture(texture);
671 }
672}
673
Jamie Madille6382c32014-11-07 15:05:26 -0500674void State::initializeZeroTextures(const TextureMap &zeroTextures)
675{
676 for (const auto &zeroTexture : zeroTextures)
677 {
678 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
679
680 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
681 {
682 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
683 }
684 }
685}
686
Shannon Woods53a94a82014-06-24 15:20:36 -0400687void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
688{
689 mSamplers[textureUnit].set(sampler);
690}
691
692GLuint State::getSamplerId(GLuint textureUnit) const
693{
Geoff Lang76b10c92014-09-05 16:28:14 -0400694 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400695 return mSamplers[textureUnit].id();
696}
697
698Sampler *State::getSampler(GLuint textureUnit) const
699{
700 return mSamplers[textureUnit].get();
701}
702
703void State::detachSampler(GLuint sampler)
704{
705 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
706 // If a sampler object that is currently bound to one or more texture units is
707 // deleted, it is as though BindSampler is called once for each texture unit to
708 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400709 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400710 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400711 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
712 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400713 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400714 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400715 }
716 }
717}
718
719void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
720{
721 mRenderbuffer.set(renderbuffer);
722}
723
724GLuint State::getRenderbufferId() const
725{
726 return mRenderbuffer.id();
727}
728
729Renderbuffer *State::getCurrentRenderbuffer()
730{
731 return mRenderbuffer.get();
732}
733
734void State::detachRenderbuffer(GLuint renderbuffer)
735{
736 // [OpenGL ES 2.0.24] section 4.4 page 109:
737 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
738 // had been executed with the target RENDERBUFFER and name of zero.
739
740 if (mRenderbuffer.id() == renderbuffer)
741 {
742 mRenderbuffer.set(NULL);
743 }
744
745 // [OpenGL ES 2.0.24] section 4.4 page 111:
746 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
747 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
748 // point to which this image was attached in the currently bound framebuffer.
749
750 Framebuffer *readFramebuffer = mReadFramebuffer;
751 Framebuffer *drawFramebuffer = mDrawFramebuffer;
752
753 if (readFramebuffer)
754 {
755 readFramebuffer->detachRenderbuffer(renderbuffer);
756 }
757
758 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
759 {
760 drawFramebuffer->detachRenderbuffer(renderbuffer);
761 }
762
763}
764
765void State::setReadFramebufferBinding(Framebuffer *framebuffer)
766{
767 mReadFramebuffer = framebuffer;
768}
769
770void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
771{
772 mDrawFramebuffer = framebuffer;
773}
774
775Framebuffer *State::getTargetFramebuffer(GLenum target) const
776{
777 switch (target)
778 {
779 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
780 case GL_DRAW_FRAMEBUFFER_ANGLE:
781 case GL_FRAMEBUFFER: return mDrawFramebuffer;
782 default: UNREACHABLE(); return NULL;
783 }
784}
785
786Framebuffer *State::getReadFramebuffer()
787{
788 return mReadFramebuffer;
789}
790
791Framebuffer *State::getDrawFramebuffer()
792{
793 return mDrawFramebuffer;
794}
795
796const Framebuffer *State::getReadFramebuffer() const
797{
798 return mReadFramebuffer;
799}
800
801const Framebuffer *State::getDrawFramebuffer() const
802{
803 return mDrawFramebuffer;
804}
805
806bool State::removeReadFramebufferBinding(GLuint framebuffer)
807{
808 if (mReadFramebuffer->id() == framebuffer)
809 {
810 mReadFramebuffer = NULL;
811 return true;
812 }
813
814 return false;
815}
816
817bool State::removeDrawFramebufferBinding(GLuint framebuffer)
818{
819 if (mDrawFramebuffer->id() == framebuffer)
820 {
821 mDrawFramebuffer = NULL;
822 return true;
823 }
824
825 return false;
826}
827
828void State::setVertexArrayBinding(VertexArray *vertexArray)
829{
830 mVertexArray = vertexArray;
831}
832
833GLuint State::getVertexArrayId() const
834{
835 ASSERT(mVertexArray != NULL);
836 return mVertexArray->id();
837}
838
839VertexArray *State::getVertexArray() const
840{
841 ASSERT(mVertexArray != NULL);
842 return mVertexArray;
843}
844
845bool State::removeVertexArrayBinding(GLuint vertexArray)
846{
847 if (mVertexArray->id() == vertexArray)
848 {
849 mVertexArray = NULL;
850 return true;
851 }
852
853 return false;
854}
855
Geoff Lang7dd2e102014-11-10 15:19:26 -0500856void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400857{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500858 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400859 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500860 if (mProgram)
861 {
862 mProgram->release();
863 }
864
865 mProgram = newProgram;
866
867 if (mProgram)
868 {
869 newProgram->addRef();
870 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400871 }
872}
873
Geoff Lang7dd2e102014-11-10 15:19:26 -0500874Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400875{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500876 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400877}
878
879void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
880{
881 mTransformFeedback.set(transformFeedback);
882}
883
884TransformFeedback *State::getCurrentTransformFeedback() const
885{
886 return mTransformFeedback.get();
887}
888
889void State::detachTransformFeedback(GLuint transformFeedback)
890{
891 if (mTransformFeedback.id() == transformFeedback)
892 {
893 mTransformFeedback.set(NULL);
894 }
895}
896
897bool State::isQueryActive() const
898{
899 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
900 i != mActiveQueries.end(); i++)
901 {
902 if (i->second.get() != NULL)
903 {
904 return true;
905 }
906 }
907
908 return false;
909}
910
911void State::setActiveQuery(GLenum target, Query *query)
912{
913 mActiveQueries[target].set(query);
914}
915
916GLuint State::getActiveQueryId(GLenum target) const
917{
918 const Query *query = getActiveQuery(target);
919 return (query ? query->id() : 0u);
920}
921
922Query *State::getActiveQuery(GLenum target) const
923{
924 // All query types should already exist in the activeQueries map
925 ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
926
927 return mActiveQueries.at(target).get();
928}
929
930void State::setArrayBufferBinding(Buffer *buffer)
931{
932 mArrayBuffer.set(buffer);
933}
934
935GLuint State::getArrayBufferId() const
936{
937 return mArrayBuffer.id();
938}
939
940bool State::removeArrayBufferBinding(GLuint buffer)
941{
942 if (mArrayBuffer.id() == buffer)
943 {
944 mArrayBuffer.set(NULL);
945 return true;
946 }
947
948 return false;
949}
950
951void State::setGenericUniformBufferBinding(Buffer *buffer)
952{
953 mGenericUniformBuffer.set(buffer);
954}
955
956void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
957{
958 mUniformBuffers[index].set(buffer, offset, size);
959}
960
961GLuint State::getIndexedUniformBufferId(GLuint index) const
962{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400963 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400964
965 return mUniformBuffers[index].id();
966}
967
968Buffer *State::getIndexedUniformBuffer(GLuint index) const
969{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400970 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400971
972 return mUniformBuffers[index].get();
973}
974
975void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
976{
977 mGenericTransformFeedbackBuffer.set(buffer);
978}
979
980void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
981{
982 mTransformFeedbackBuffers[index].set(buffer, offset, size);
983}
984
985GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
986{
Shannon Woods8299bb02014-09-26 18:55:43 -0400987 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400988
989 return mTransformFeedbackBuffers[index].id();
990}
991
992Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
993{
Shannon Woods8299bb02014-09-26 18:55:43 -0400994 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400995
996 return mTransformFeedbackBuffers[index].get();
997}
998
999GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
1000{
Shannon Woods8299bb02014-09-26 18:55:43 -04001001 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001002
1003 return mTransformFeedbackBuffers[index].getOffset();
1004}
1005
Shannon Woods8299bb02014-09-26 18:55:43 -04001006size_t State::getTransformFeedbackBufferIndexRange() const
1007{
1008 return mTransformFeedbackBuffers.size();
1009}
1010
Shannon Woods53a94a82014-06-24 15:20:36 -04001011void State::setCopyReadBufferBinding(Buffer *buffer)
1012{
1013 mCopyReadBuffer.set(buffer);
1014}
1015
1016void State::setCopyWriteBufferBinding(Buffer *buffer)
1017{
1018 mCopyWriteBuffer.set(buffer);
1019}
1020
1021void State::setPixelPackBufferBinding(Buffer *buffer)
1022{
1023 mPack.pixelBuffer.set(buffer);
1024}
1025
1026void State::setPixelUnpackBufferBinding(Buffer *buffer)
1027{
1028 mUnpack.pixelBuffer.set(buffer);
1029}
1030
1031Buffer *State::getTargetBuffer(GLenum target) const
1032{
1033 switch (target)
1034 {
1035 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1036 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1037 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1038 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1039 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1040 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1041 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1042 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1043 default: UNREACHABLE(); return NULL;
1044 }
1045}
1046
1047void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1048{
1049 getVertexArray()->enableAttribute(attribNum, enabled);
1050}
1051
1052void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1053{
Shannon Woods23e05002014-09-22 19:07:27 -04001054 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001055 mVertexAttribCurrentValues[index].setFloatValues(values);
1056}
1057
1058void State::setVertexAttribu(GLuint index, const GLuint values[4])
1059{
Shannon Woods23e05002014-09-22 19:07:27 -04001060 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001061 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1062}
1063
1064void State::setVertexAttribi(GLuint index, const GLint values[4])
1065{
Shannon Woods23e05002014-09-22 19:07:27 -04001066 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001067 mVertexAttribCurrentValues[index].setIntValues(values);
1068}
1069
1070void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1071 bool pureInteger, GLsizei stride, const void *pointer)
1072{
1073 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1074}
1075
1076const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1077{
1078 return getVertexArray()->getVertexAttribute(attribNum);
1079}
1080
1081const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1082{
Shannon Woods23e05002014-09-22 19:07:27 -04001083 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001084 return mVertexAttribCurrentValues[attribNum];
1085}
1086
Shannon Woods53a94a82014-06-24 15:20:36 -04001087const void *State::getVertexAttribPointer(unsigned int attribNum) const
1088{
1089 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1090}
1091
1092void State::setPackAlignment(GLint alignment)
1093{
1094 mPack.alignment = alignment;
1095}
1096
1097GLint State::getPackAlignment() const
1098{
1099 return mPack.alignment;
1100}
1101
1102void State::setPackReverseRowOrder(bool reverseRowOrder)
1103{
1104 mPack.reverseRowOrder = reverseRowOrder;
1105}
1106
1107bool State::getPackReverseRowOrder() const
1108{
1109 return mPack.reverseRowOrder;
1110}
1111
1112const PixelPackState &State::getPackState() const
1113{
1114 return mPack;
1115}
1116
1117void State::setUnpackAlignment(GLint alignment)
1118{
1119 mUnpack.alignment = alignment;
1120}
1121
1122GLint State::getUnpackAlignment() const
1123{
1124 return mUnpack.alignment;
1125}
1126
1127const PixelUnpackState &State::getUnpackState() const
1128{
1129 return mUnpack;
1130}
1131
1132void State::getBooleanv(GLenum pname, GLboolean *params)
1133{
1134 switch (pname)
1135 {
1136 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1137 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1138 case GL_COLOR_WRITEMASK:
1139 params[0] = mBlend.colorMaskRed;
1140 params[1] = mBlend.colorMaskGreen;
1141 params[2] = mBlend.colorMaskBlue;
1142 params[3] = mBlend.colorMaskAlpha;
1143 break;
1144 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1145 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1146 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1147 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1148 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1149 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1150 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1151 case GL_BLEND: *params = mBlend.blend; break;
1152 case GL_DITHER: *params = mBlend.dither; break;
1153 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1154 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1155 default:
1156 UNREACHABLE();
1157 break;
1158 }
1159}
1160
1161void State::getFloatv(GLenum pname, GLfloat *params)
1162{
1163 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1164 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1165 // GetIntegerv as its native query function. As it would require conversion in any
1166 // case, this should make no difference to the calling application.
1167 switch (pname)
1168 {
1169 case GL_LINE_WIDTH: *params = mLineWidth; break;
1170 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1171 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1172 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1173 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1174 case GL_DEPTH_RANGE:
1175 params[0] = mNearZ;
1176 params[1] = mFarZ;
1177 break;
1178 case GL_COLOR_CLEAR_VALUE:
1179 params[0] = mColorClearValue.red;
1180 params[1] = mColorClearValue.green;
1181 params[2] = mColorClearValue.blue;
1182 params[3] = mColorClearValue.alpha;
1183 break;
1184 case GL_BLEND_COLOR:
1185 params[0] = mBlendColor.red;
1186 params[1] = mBlendColor.green;
1187 params[2] = mBlendColor.blue;
1188 params[3] = mBlendColor.alpha;
1189 break;
1190 default:
1191 UNREACHABLE();
1192 break;
1193 }
1194}
1195
Jamie Madill48faf802014-11-06 15:27:22 -05001196void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001197{
1198 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1199 {
1200 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001201 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001202 Framebuffer *framebuffer = mDrawFramebuffer;
1203 *params = framebuffer->getDrawBufferState(colorAttachment);
1204 return;
1205 }
1206
1207 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1208 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1209 // GetIntegerv as its native query function. As it would require conversion in any
1210 // case, this should make no difference to the calling application. You may find it in
1211 // State::getFloatv.
1212 switch (pname)
1213 {
1214 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1215 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1216 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1217 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1218 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1219 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1220 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001221 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001222 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1223 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1224 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
1225 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;
1250 case GL_SAMPLE_BUFFERS:
1251 case GL_SAMPLES:
1252 {
1253 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001254 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001255 {
1256 switch (pname)
1257 {
1258 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001259 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001260 {
1261 *params = 1;
1262 }
1263 else
1264 {
1265 *params = 0;
1266 }
1267 break;
1268 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001269 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001270 break;
1271 }
1272 }
1273 else
1274 {
1275 *params = 0;
1276 }
1277 }
1278 break;
1279 case GL_VIEWPORT:
1280 params[0] = mViewport.x;
1281 params[1] = mViewport.y;
1282 params[2] = mViewport.width;
1283 params[3] = mViewport.height;
1284 break;
1285 case GL_SCISSOR_BOX:
1286 params[0] = mScissor.x;
1287 params[1] = mScissor.y;
1288 params[2] = mScissor.width;
1289 params[3] = mScissor.height;
1290 break;
1291 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1292 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1293 case GL_RED_BITS:
1294 case GL_GREEN_BITS:
1295 case GL_BLUE_BITS:
1296 case GL_ALPHA_BITS:
1297 {
1298 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1299 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1300
1301 if (colorbuffer)
1302 {
1303 switch (pname)
1304 {
1305 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1306 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1307 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1308 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1309 }
1310 }
1311 else
1312 {
1313 *params = 0;
1314 }
1315 }
1316 break;
1317 case GL_DEPTH_BITS:
1318 {
1319 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1320 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1321
1322 if (depthbuffer)
1323 {
1324 *params = depthbuffer->getDepthSize();
1325 }
1326 else
1327 {
1328 *params = 0;
1329 }
1330 }
1331 break;
1332 case GL_STENCIL_BITS:
1333 {
1334 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1335 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1336
1337 if (stencilbuffer)
1338 {
1339 *params = stencilbuffer->getStencilSize();
1340 }
1341 else
1342 {
1343 *params = 0;
1344 }
1345 }
1346 break;
1347 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001348 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001349 *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001350 break;
1351 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001352 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001353 *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001354 break;
1355 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001356 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001357 *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001358 break;
1359 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001360 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001361 *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001362 break;
1363 case GL_UNIFORM_BUFFER_BINDING:
1364 *params = mGenericUniformBuffer.id();
1365 break;
1366 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1367 *params = mGenericTransformFeedbackBuffer.id();
1368 break;
1369 case GL_COPY_READ_BUFFER_BINDING:
1370 *params = mCopyReadBuffer.id();
1371 break;
1372 case GL_COPY_WRITE_BUFFER_BINDING:
1373 *params = mCopyWriteBuffer.id();
1374 break;
1375 case GL_PIXEL_PACK_BUFFER_BINDING:
1376 *params = mPack.pixelBuffer.id();
1377 break;
1378 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1379 *params = mUnpack.pixelBuffer.id();
1380 break;
1381 default:
1382 UNREACHABLE();
1383 break;
1384 }
1385}
1386
1387bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1388{
1389 switch (target)
1390 {
1391 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Shannon Woods8299bb02014-09-26 18:55:43 -04001392 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001393 {
1394 *data = mTransformFeedbackBuffers[index].id();
1395 }
1396 break;
1397 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001398 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001399 {
1400 *data = mUniformBuffers[index].id();
1401 }
1402 break;
1403 default:
1404 return false;
1405 }
1406
1407 return true;
1408}
1409
1410bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1411{
1412 switch (target)
1413 {
1414 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Shannon Woods8299bb02014-09-26 18:55:43 -04001415 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001416 {
1417 *data = mTransformFeedbackBuffers[index].getOffset();
1418 }
1419 break;
1420 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Shannon Woods8299bb02014-09-26 18:55:43 -04001421 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001422 {
1423 *data = mTransformFeedbackBuffers[index].getSize();
1424 }
1425 break;
1426 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001427 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001428 {
1429 *data = mUniformBuffers[index].getOffset();
1430 }
1431 break;
1432 case GL_UNIFORM_BUFFER_SIZE:
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].getSize();
1436 }
1437 break;
1438 default:
1439 return false;
1440 }
1441
1442 return true;
1443}
1444
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001445bool State::hasMappedBuffer(GLenum target) const
1446{
1447 if (target == GL_ARRAY_BUFFER)
1448 {
Shannon Woods23e05002014-09-22 19:07:27 -04001449 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001450 {
Shannon Woods23e05002014-09-22 19:07:27 -04001451 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001452 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1453 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1454 {
1455 return true;
1456 }
1457 }
1458
1459 return false;
1460 }
1461 else
1462 {
1463 Buffer *buffer = getTargetBuffer(target);
1464 return (buffer && buffer->isMapped());
1465 }
1466}
1467
Shannon Woods53a94a82014-06-24 15:20:36 -04001468}