blob: e727cd5d68243c5e81afeda554c349f99a1f2a3b [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);
123
Geoff Lang76b10c92014-09-05 16:28:14 -0400124 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
125 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
126 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400127 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400128 // TODO: These could also be enabled via extension
129 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
130 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400131 }
132
Geoff Lang76b10c92014-09-05 16:28:14 -0400133 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400134
135 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
136 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
137 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
138
Geoff Lang7dd2e102014-11-10 15:19:26 -0500139 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400140
141 mReadFramebuffer = NULL;
142 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500143
144 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400145}
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 Woods8299bb02014-09-26 18:55:43 -0400179 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400180 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400181 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400182 }
183
Shannon Woods53a94a82014-06-24 15:20:36 -0400184 mCopyReadBuffer.set(NULL);
185 mCopyWriteBuffer.set(NULL);
186
187 mPack.pixelBuffer.set(NULL);
188 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500189
190 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400191}
192
193const RasterizerState &State::getRasterizerState() const
194{
195 return mRasterizer;
196}
197
198const BlendState &State::getBlendState() const
199{
200 return mBlend;
201}
202
203const DepthStencilState &State::getDepthStencilState() const
204{
205 return mDepthStencil;
206}
207
Jamie Madillf75ab352015-03-16 10:46:52 -0400208void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400209{
210 mColorClearValue.red = red;
211 mColorClearValue.green = green;
212 mColorClearValue.blue = blue;
213 mColorClearValue.alpha = alpha;
214}
215
Jamie Madillf75ab352015-03-16 10:46:52 -0400216void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400217{
218 mDepthClearValue = depth;
219}
220
Jamie Madillf75ab352015-03-16 10:46:52 -0400221void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400222{
223 mStencilClearValue = stencil;
224}
225
Shannon Woods53a94a82014-06-24 15:20:36 -0400226void State::setColorMask(bool red, bool green, bool blue, bool alpha)
227{
228 mBlend.colorMaskRed = red;
229 mBlend.colorMaskGreen = green;
230 mBlend.colorMaskBlue = blue;
231 mBlend.colorMaskAlpha = alpha;
232}
233
234void State::setDepthMask(bool mask)
235{
236 mDepthStencil.depthMask = mask;
237}
238
239bool State::isRasterizerDiscardEnabled() const
240{
241 return mRasterizer.rasterizerDiscard;
242}
243
244void State::setRasterizerDiscard(bool enabled)
245{
246 mRasterizer.rasterizerDiscard = enabled;
247}
248
249bool State::isCullFaceEnabled() const
250{
251 return mRasterizer.cullFace;
252}
253
254void State::setCullFace(bool enabled)
255{
256 mRasterizer.cullFace = enabled;
257}
258
259void State::setCullMode(GLenum mode)
260{
261 mRasterizer.cullMode = mode;
262}
263
264void State::setFrontFace(GLenum front)
265{
266 mRasterizer.frontFace = front;
267}
268
269bool State::isDepthTestEnabled() const
270{
271 return mDepthStencil.depthTest;
272}
273
274void State::setDepthTest(bool enabled)
275{
276 mDepthStencil.depthTest = enabled;
277}
278
279void State::setDepthFunc(GLenum depthFunc)
280{
281 mDepthStencil.depthFunc = depthFunc;
282}
283
284void State::setDepthRange(float zNear, float zFar)
285{
286 mNearZ = zNear;
287 mFarZ = zFar;
288}
289
290void State::getDepthRange(float *zNear, float *zFar) const
291{
292 *zNear = mNearZ;
293 *zFar = mFarZ;
294}
295
296bool State::isBlendEnabled() const
297{
298 return mBlend.blend;
299}
300
301void State::setBlend(bool enabled)
302{
303 mBlend.blend = enabled;
304}
305
306void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
307{
308 mBlend.sourceBlendRGB = sourceRGB;
309 mBlend.destBlendRGB = destRGB;
310 mBlend.sourceBlendAlpha = sourceAlpha;
311 mBlend.destBlendAlpha = destAlpha;
312}
313
314void State::setBlendColor(float red, float green, float blue, float alpha)
315{
316 mBlendColor.red = red;
317 mBlendColor.green = green;
318 mBlendColor.blue = blue;
319 mBlendColor.alpha = alpha;
320}
321
322void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
323{
324 mBlend.blendEquationRGB = rgbEquation;
325 mBlend.blendEquationAlpha = alphaEquation;
326}
327
328const ColorF &State::getBlendColor() const
329{
330 return mBlendColor;
331}
332
333bool State::isStencilTestEnabled() const
334{
335 return mDepthStencil.stencilTest;
336}
337
338void State::setStencilTest(bool enabled)
339{
340 mDepthStencil.stencilTest = enabled;
341}
342
343void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
344{
345 mDepthStencil.stencilFunc = stencilFunc;
346 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
347 mDepthStencil.stencilMask = stencilMask;
348}
349
350void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
351{
352 mDepthStencil.stencilBackFunc = stencilBackFunc;
353 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
354 mDepthStencil.stencilBackMask = stencilBackMask;
355}
356
357void State::setStencilWritemask(GLuint stencilWritemask)
358{
359 mDepthStencil.stencilWritemask = stencilWritemask;
360}
361
362void State::setStencilBackWritemask(GLuint stencilBackWritemask)
363{
364 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
365}
366
367void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
368{
369 mDepthStencil.stencilFail = stencilFail;
370 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
371 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
372}
373
374void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
375{
376 mDepthStencil.stencilBackFail = stencilBackFail;
377 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
378 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
379}
380
381GLint State::getStencilRef() const
382{
383 return mStencilRef;
384}
385
386GLint State::getStencilBackRef() const
387{
388 return mStencilBackRef;
389}
390
391bool State::isPolygonOffsetFillEnabled() const
392{
393 return mRasterizer.polygonOffsetFill;
394}
395
396void State::setPolygonOffsetFill(bool enabled)
397{
398 mRasterizer.polygonOffsetFill = enabled;
399}
400
401void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
402{
403 // An application can pass NaN values here, so handle this gracefully
404 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
405 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
406}
407
408bool State::isSampleAlphaToCoverageEnabled() const
409{
410 return mBlend.sampleAlphaToCoverage;
411}
412
413void State::setSampleAlphaToCoverage(bool enabled)
414{
415 mBlend.sampleAlphaToCoverage = enabled;
416}
417
418bool State::isSampleCoverageEnabled() const
419{
420 return mSampleCoverage;
421}
422
423void State::setSampleCoverage(bool enabled)
424{
425 mSampleCoverage = enabled;
426}
427
428void State::setSampleCoverageParams(GLclampf value, bool invert)
429{
430 mSampleCoverageValue = value;
431 mSampleCoverageInvert = invert;
432}
433
Jamie Madilld9e58302014-11-06 15:27:26 -0500434void State::getSampleCoverageParams(GLclampf *value, bool *invert) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400435{
436 ASSERT(value != NULL && invert != NULL);
437
438 *value = mSampleCoverageValue;
439 *invert = mSampleCoverageInvert;
440}
441
442bool State::isScissorTestEnabled() const
443{
444 return mScissorTest;
445}
446
447void State::setScissorTest(bool enabled)
448{
449 mScissorTest = enabled;
450}
451
452void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
453{
454 mScissor.x = x;
455 mScissor.y = y;
456 mScissor.width = width;
457 mScissor.height = height;
458}
459
460const Rectangle &State::getScissor() const
461{
462 return mScissor;
463}
464
465bool State::isDitherEnabled() const
466{
467 return mBlend.dither;
468}
469
470void State::setDither(bool enabled)
471{
472 mBlend.dither = enabled;
473}
474
Jamie Madillb4b53c52015-02-03 15:22:48 -0500475bool State::isPrimitiveRestartEnabled() const
476{
477 return mPrimitiveRestart;
478}
479
480void State::setPrimitiveRestart(bool enabled)
481{
482 mPrimitiveRestart = enabled;
483}
484
Shannon Woods53a94a82014-06-24 15:20:36 -0400485void State::setEnableFeature(GLenum feature, bool enabled)
486{
487 switch (feature)
488 {
489 case GL_CULL_FACE: setCullFace(enabled); break;
490 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
491 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
492 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
493 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
494 case GL_STENCIL_TEST: setStencilTest(enabled); break;
495 case GL_DEPTH_TEST: setDepthTest(enabled); break;
496 case GL_BLEND: setBlend(enabled); break;
497 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500498 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400499 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
500 default: UNREACHABLE();
501 }
502}
503
504bool State::getEnableFeature(GLenum feature)
505{
506 switch (feature)
507 {
508 case GL_CULL_FACE: return isCullFaceEnabled();
509 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
510 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
511 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
512 case GL_SCISSOR_TEST: return isScissorTestEnabled();
513 case GL_STENCIL_TEST: return isStencilTestEnabled();
514 case GL_DEPTH_TEST: return isDepthTestEnabled();
515 case GL_BLEND: return isBlendEnabled();
516 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500517 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400518 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
519 default: UNREACHABLE(); return false;
520 }
521}
522
523void State::setLineWidth(GLfloat width)
524{
525 mLineWidth = width;
526}
527
528void State::setGenerateMipmapHint(GLenum hint)
529{
530 mGenerateMipmapHint = hint;
531}
532
533void State::setFragmentShaderDerivativeHint(GLenum hint)
534{
535 mFragmentShaderDerivativeHint = hint;
536 // TODO: Propagate the hint to shader translator so we can write
537 // ddx, ddx_coarse, or ddx_fine depending on the hint.
538 // Ignore for now. It is valid for implementations to ignore hint.
539}
540
541void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
542{
543 mViewport.x = x;
544 mViewport.y = y;
545 mViewport.width = width;
546 mViewport.height = height;
547}
548
549const Rectangle &State::getViewport() const
550{
551 return mViewport;
552}
553
554void State::setActiveSampler(unsigned int active)
555{
556 mActiveSampler = active;
557}
558
559unsigned int State::getActiveSampler() const
560{
561 return mActiveSampler;
562}
563
Geoff Lang76b10c92014-09-05 16:28:14 -0400564void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400565{
Geoff Lang76b10c92014-09-05 16:28:14 -0400566 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400567}
568
Geoff Lang76b10c92014-09-05 16:28:14 -0400569Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400570{
Jamie Madill5864ac22015-01-12 14:43:07 -0500571 const auto it = mSamplerTextures.find(type);
572 ASSERT(it != mSamplerTextures.end());
573 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400574}
575
Geoff Lang76b10c92014-09-05 16:28:14 -0400576GLuint State::getSamplerTextureId(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].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400581}
582
Jamie Madille6382c32014-11-07 15:05:26 -0500583void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400584{
585 // Textures have a detach method on State rather than a simple
586 // removeBinding, because the zero/null texture objects are managed
587 // separately, and don't have to go through the Context's maps or
588 // the ResourceManager.
589
590 // [OpenGL ES 2.0.24] section 3.8 page 84:
591 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
592 // rebound to texture object zero
593
Geoff Lang76b10c92014-09-05 16:28:14 -0400594 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400595 {
Jamie Madille6382c32014-11-07 15:05:26 -0500596 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400597 TextureBindingVector &textureVector = bindingVec->second;
598 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400599 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400600 BindingPointer<Texture> &binding = textureVector[textureIdx];
601 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400602 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500603 auto it = zeroTextures.find(textureType);
604 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500605 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500606 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400607 }
608 }
609 }
610
611 // [OpenGL ES 2.0.24] section 4.4 page 112:
612 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
613 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
614 // image was attached in the currently bound framebuffer.
615
616 if (mReadFramebuffer)
617 {
618 mReadFramebuffer->detachTexture(texture);
619 }
620
621 if (mDrawFramebuffer)
622 {
623 mDrawFramebuffer->detachTexture(texture);
624 }
625}
626
Jamie Madille6382c32014-11-07 15:05:26 -0500627void State::initializeZeroTextures(const TextureMap &zeroTextures)
628{
629 for (const auto &zeroTexture : zeroTextures)
630 {
631 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
632
633 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
634 {
635 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
636 }
637 }
638}
639
Shannon Woods53a94a82014-06-24 15:20:36 -0400640void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
641{
642 mSamplers[textureUnit].set(sampler);
643}
644
645GLuint State::getSamplerId(GLuint textureUnit) const
646{
Geoff Lang76b10c92014-09-05 16:28:14 -0400647 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400648 return mSamplers[textureUnit].id();
649}
650
651Sampler *State::getSampler(GLuint textureUnit) const
652{
653 return mSamplers[textureUnit].get();
654}
655
656void State::detachSampler(GLuint sampler)
657{
658 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
659 // If a sampler object that is currently bound to one or more texture units is
660 // deleted, it is as though BindSampler is called once for each texture unit to
661 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400662 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400663 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400664 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
665 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400666 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400667 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400668 }
669 }
670}
671
672void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
673{
674 mRenderbuffer.set(renderbuffer);
675}
676
677GLuint State::getRenderbufferId() const
678{
679 return mRenderbuffer.id();
680}
681
682Renderbuffer *State::getCurrentRenderbuffer()
683{
684 return mRenderbuffer.get();
685}
686
687void State::detachRenderbuffer(GLuint renderbuffer)
688{
689 // [OpenGL ES 2.0.24] section 4.4 page 109:
690 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
691 // had been executed with the target RENDERBUFFER and name of zero.
692
693 if (mRenderbuffer.id() == renderbuffer)
694 {
695 mRenderbuffer.set(NULL);
696 }
697
698 // [OpenGL ES 2.0.24] section 4.4 page 111:
699 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
700 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
701 // point to which this image was attached in the currently bound framebuffer.
702
703 Framebuffer *readFramebuffer = mReadFramebuffer;
704 Framebuffer *drawFramebuffer = mDrawFramebuffer;
705
706 if (readFramebuffer)
707 {
708 readFramebuffer->detachRenderbuffer(renderbuffer);
709 }
710
711 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
712 {
713 drawFramebuffer->detachRenderbuffer(renderbuffer);
714 }
715
716}
717
718void State::setReadFramebufferBinding(Framebuffer *framebuffer)
719{
720 mReadFramebuffer = framebuffer;
721}
722
723void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
724{
725 mDrawFramebuffer = framebuffer;
726}
727
728Framebuffer *State::getTargetFramebuffer(GLenum target) const
729{
730 switch (target)
731 {
732 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
733 case GL_DRAW_FRAMEBUFFER_ANGLE:
734 case GL_FRAMEBUFFER: return mDrawFramebuffer;
735 default: UNREACHABLE(); return NULL;
736 }
737}
738
739Framebuffer *State::getReadFramebuffer()
740{
741 return mReadFramebuffer;
742}
743
744Framebuffer *State::getDrawFramebuffer()
745{
746 return mDrawFramebuffer;
747}
748
749const Framebuffer *State::getReadFramebuffer() const
750{
751 return mReadFramebuffer;
752}
753
754const Framebuffer *State::getDrawFramebuffer() const
755{
756 return mDrawFramebuffer;
757}
758
759bool State::removeReadFramebufferBinding(GLuint framebuffer)
760{
Jamie Madill77a72f62015-04-14 11:18:32 -0400761 if (mReadFramebuffer != nullptr &&
762 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400763 {
764 mReadFramebuffer = NULL;
765 return true;
766 }
767
768 return false;
769}
770
771bool State::removeDrawFramebufferBinding(GLuint framebuffer)
772{
Jamie Madill77a72f62015-04-14 11:18:32 -0400773 if (mReadFramebuffer != nullptr &&
774 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400775 {
776 mDrawFramebuffer = NULL;
777 return true;
778 }
779
780 return false;
781}
782
783void State::setVertexArrayBinding(VertexArray *vertexArray)
784{
785 mVertexArray = vertexArray;
786}
787
788GLuint State::getVertexArrayId() const
789{
790 ASSERT(mVertexArray != NULL);
791 return mVertexArray->id();
792}
793
794VertexArray *State::getVertexArray() const
795{
796 ASSERT(mVertexArray != NULL);
797 return mVertexArray;
798}
799
800bool State::removeVertexArrayBinding(GLuint vertexArray)
801{
802 if (mVertexArray->id() == vertexArray)
803 {
804 mVertexArray = NULL;
805 return true;
806 }
807
808 return false;
809}
810
Geoff Lang7dd2e102014-11-10 15:19:26 -0500811void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400812{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500813 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400814 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500815 if (mProgram)
816 {
817 mProgram->release();
818 }
819
820 mProgram = newProgram;
821
822 if (mProgram)
823 {
824 newProgram->addRef();
825 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400826 }
827}
828
Geoff Lang7dd2e102014-11-10 15:19:26 -0500829Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400830{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500831 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400832}
833
834void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
835{
836 mTransformFeedback.set(transformFeedback);
837}
838
839TransformFeedback *State::getCurrentTransformFeedback() const
840{
841 return mTransformFeedback.get();
842}
843
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000844bool State::isTransformFeedbackActiveUnpaused() const
845{
846 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400847 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000848}
849
Shannon Woods53a94a82014-06-24 15:20:36 -0400850void State::detachTransformFeedback(GLuint transformFeedback)
851{
852 if (mTransformFeedback.id() == transformFeedback)
853 {
854 mTransformFeedback.set(NULL);
855 }
856}
857
858bool State::isQueryActive() const
859{
860 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
861 i != mActiveQueries.end(); i++)
862 {
863 if (i->second.get() != NULL)
864 {
865 return true;
866 }
867 }
868
869 return false;
870}
871
872void State::setActiveQuery(GLenum target, Query *query)
873{
874 mActiveQueries[target].set(query);
875}
876
877GLuint State::getActiveQueryId(GLenum target) const
878{
879 const Query *query = getActiveQuery(target);
880 return (query ? query->id() : 0u);
881}
882
883Query *State::getActiveQuery(GLenum target) const
884{
Jamie Madill5864ac22015-01-12 14:43:07 -0500885 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400886
Jamie Madill5864ac22015-01-12 14:43:07 -0500887 // All query types should already exist in the activeQueries map
888 ASSERT(it != mActiveQueries.end());
889
890 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400891}
892
893void State::setArrayBufferBinding(Buffer *buffer)
894{
895 mArrayBuffer.set(buffer);
896}
897
898GLuint State::getArrayBufferId() const
899{
900 return mArrayBuffer.id();
901}
902
903bool State::removeArrayBufferBinding(GLuint buffer)
904{
905 if (mArrayBuffer.id() == buffer)
906 {
907 mArrayBuffer.set(NULL);
908 return true;
909 }
910
911 return false;
912}
913
914void State::setGenericUniformBufferBinding(Buffer *buffer)
915{
916 mGenericUniformBuffer.set(buffer);
917}
918
919void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
920{
921 mUniformBuffers[index].set(buffer, offset, size);
922}
923
924GLuint State::getIndexedUniformBufferId(GLuint index) const
925{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400926 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400927
928 return mUniformBuffers[index].id();
929}
930
931Buffer *State::getIndexedUniformBuffer(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].get();
936}
937
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +0000938GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
939{
940 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
941
942 return mUniformBuffers[index].getOffset();
943}
944
945GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
946{
947 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
948
949 return mUniformBuffers[index].getSize();
950}
951
Shannon Woods53a94a82014-06-24 15:20:36 -0400952void State::setCopyReadBufferBinding(Buffer *buffer)
953{
954 mCopyReadBuffer.set(buffer);
955}
956
957void State::setCopyWriteBufferBinding(Buffer *buffer)
958{
959 mCopyWriteBuffer.set(buffer);
960}
961
962void State::setPixelPackBufferBinding(Buffer *buffer)
963{
964 mPack.pixelBuffer.set(buffer);
965}
966
967void State::setPixelUnpackBufferBinding(Buffer *buffer)
968{
969 mUnpack.pixelBuffer.set(buffer);
970}
971
972Buffer *State::getTargetBuffer(GLenum target) const
973{
974 switch (target)
975 {
976 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
977 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
978 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
979 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
980 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
981 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -0400982 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400983 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
984 default: UNREACHABLE(); return NULL;
985 }
986}
987
988void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
989{
990 getVertexArray()->enableAttribute(attribNum, enabled);
991}
992
993void State::setVertexAttribf(GLuint index, const GLfloat values[4])
994{
Shannon Woods23e05002014-09-22 19:07:27 -0400995 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400996 mVertexAttribCurrentValues[index].setFloatValues(values);
997}
998
999void State::setVertexAttribu(GLuint index, const GLuint values[4])
1000{
Shannon Woods23e05002014-09-22 19:07:27 -04001001 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001002 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1003}
1004
1005void State::setVertexAttribi(GLuint index, const GLint values[4])
1006{
Shannon Woods23e05002014-09-22 19:07:27 -04001007 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001008 mVertexAttribCurrentValues[index].setIntValues(values);
1009}
1010
1011void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1012 bool pureInteger, GLsizei stride, const void *pointer)
1013{
1014 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1015}
1016
Shannon Woods53a94a82014-06-24 15:20:36 -04001017const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1018{
Shannon Woods23e05002014-09-22 19:07:27 -04001019 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001020 return mVertexAttribCurrentValues[attribNum];
1021}
1022
Shannon Woods53a94a82014-06-24 15:20:36 -04001023const void *State::getVertexAttribPointer(unsigned int attribNum) const
1024{
1025 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1026}
1027
1028void State::setPackAlignment(GLint alignment)
1029{
1030 mPack.alignment = alignment;
1031}
1032
1033GLint State::getPackAlignment() const
1034{
1035 return mPack.alignment;
1036}
1037
1038void State::setPackReverseRowOrder(bool reverseRowOrder)
1039{
1040 mPack.reverseRowOrder = reverseRowOrder;
1041}
1042
1043bool State::getPackReverseRowOrder() const
1044{
1045 return mPack.reverseRowOrder;
1046}
1047
1048const PixelPackState &State::getPackState() const
1049{
1050 return mPack;
1051}
1052
Jamie Madill87de3622015-03-16 10:41:44 -04001053PixelPackState &State::getPackState()
1054{
1055 return mPack;
1056}
1057
Shannon Woods53a94a82014-06-24 15:20:36 -04001058void State::setUnpackAlignment(GLint alignment)
1059{
1060 mUnpack.alignment = alignment;
1061}
1062
1063GLint State::getUnpackAlignment() const
1064{
1065 return mUnpack.alignment;
1066}
1067
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001068void State::setUnpackRowLength(GLint rowLength)
1069{
1070 mUnpack.rowLength = rowLength;
1071}
1072
1073GLint State::getUnpackRowLength() const
1074{
1075 return mUnpack.rowLength;
1076}
1077
Shannon Woods53a94a82014-06-24 15:20:36 -04001078const PixelUnpackState &State::getUnpackState() const
1079{
1080 return mUnpack;
1081}
1082
Jamie Madill67102f02015-03-16 10:41:42 -04001083PixelUnpackState &State::getUnpackState()
1084{
1085 return mUnpack;
1086}
1087
Shannon Woods53a94a82014-06-24 15:20:36 -04001088void State::getBooleanv(GLenum pname, GLboolean *params)
1089{
1090 switch (pname)
1091 {
1092 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1093 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1094 case GL_COLOR_WRITEMASK:
1095 params[0] = mBlend.colorMaskRed;
1096 params[1] = mBlend.colorMaskGreen;
1097 params[2] = mBlend.colorMaskBlue;
1098 params[3] = mBlend.colorMaskAlpha;
1099 break;
1100 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1101 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1102 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1103 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1104 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1105 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1106 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1107 case GL_BLEND: *params = mBlend.blend; break;
1108 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001109 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1110 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001111 default:
1112 UNREACHABLE();
1113 break;
1114 }
1115}
1116
1117void State::getFloatv(GLenum pname, GLfloat *params)
1118{
1119 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1120 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1121 // GetIntegerv as its native query function. As it would require conversion in any
1122 // case, this should make no difference to the calling application.
1123 switch (pname)
1124 {
1125 case GL_LINE_WIDTH: *params = mLineWidth; break;
1126 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1127 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1128 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1129 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1130 case GL_DEPTH_RANGE:
1131 params[0] = mNearZ;
1132 params[1] = mFarZ;
1133 break;
1134 case GL_COLOR_CLEAR_VALUE:
1135 params[0] = mColorClearValue.red;
1136 params[1] = mColorClearValue.green;
1137 params[2] = mColorClearValue.blue;
1138 params[3] = mColorClearValue.alpha;
1139 break;
1140 case GL_BLEND_COLOR:
1141 params[0] = mBlendColor.red;
1142 params[1] = mBlendColor.green;
1143 params[2] = mBlendColor.blue;
1144 params[3] = mBlendColor.alpha;
1145 break;
1146 default:
1147 UNREACHABLE();
1148 break;
1149 }
1150}
1151
Jamie Madill48faf802014-11-06 15:27:22 -05001152void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001153{
1154 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1155 {
1156 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001157 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001158 Framebuffer *framebuffer = mDrawFramebuffer;
1159 *params = framebuffer->getDrawBufferState(colorAttachment);
1160 return;
1161 }
1162
1163 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv 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. You may find it in
1167 // State::getFloatv.
1168 switch (pname)
1169 {
1170 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1171 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1172 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1173 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1174 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1175 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1176 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001177 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001178 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1179 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1180 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001181 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001182 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1183 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1184 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1185 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1186 case GL_STENCIL_REF: *params = mStencilRef; break;
1187 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1188 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1189 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1190 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1191 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1192 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1193 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1194 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1195 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1196 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1197 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1198 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1199 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1200 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1201 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1202 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1203 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1204 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1205 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1206 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001207 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1208 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001209 case GL_SAMPLE_BUFFERS:
1210 case GL_SAMPLES:
1211 {
1212 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001213 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001214 {
1215 switch (pname)
1216 {
1217 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001218 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001219 {
1220 *params = 1;
1221 }
1222 else
1223 {
1224 *params = 0;
1225 }
1226 break;
1227 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001228 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001229 break;
1230 }
1231 }
1232 else
1233 {
1234 *params = 0;
1235 }
1236 }
1237 break;
1238 case GL_VIEWPORT:
1239 params[0] = mViewport.x;
1240 params[1] = mViewport.y;
1241 params[2] = mViewport.width;
1242 params[3] = mViewport.height;
1243 break;
1244 case GL_SCISSOR_BOX:
1245 params[0] = mScissor.x;
1246 params[1] = mScissor.y;
1247 params[2] = mScissor.width;
1248 params[3] = mScissor.height;
1249 break;
1250 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1251 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1252 case GL_RED_BITS:
1253 case GL_GREEN_BITS:
1254 case GL_BLUE_BITS:
1255 case GL_ALPHA_BITS:
1256 {
1257 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001258 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001259
1260 if (colorbuffer)
1261 {
1262 switch (pname)
1263 {
1264 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1265 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1266 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1267 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1268 }
1269 }
1270 else
1271 {
1272 *params = 0;
1273 }
1274 }
1275 break;
1276 case GL_DEPTH_BITS:
1277 {
1278 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1279 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1280
1281 if (depthbuffer)
1282 {
1283 *params = depthbuffer->getDepthSize();
1284 }
1285 else
1286 {
1287 *params = 0;
1288 }
1289 }
1290 break;
1291 case GL_STENCIL_BITS:
1292 {
1293 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1294 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1295
1296 if (stencilbuffer)
1297 {
1298 *params = stencilbuffer->getStencilSize();
1299 }
1300 else
1301 {
1302 *params = 0;
1303 }
1304 }
1305 break;
1306 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001307 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001308 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001309 break;
1310 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001311 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001312 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001313 break;
1314 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001315 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001316 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001317 break;
1318 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001319 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001320 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001321 break;
1322 case GL_UNIFORM_BUFFER_BINDING:
1323 *params = mGenericUniformBuffer.id();
1324 break;
1325 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001326 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001327 break;
1328 case GL_COPY_READ_BUFFER_BINDING:
1329 *params = mCopyReadBuffer.id();
1330 break;
1331 case GL_COPY_WRITE_BUFFER_BINDING:
1332 *params = mCopyWriteBuffer.id();
1333 break;
1334 case GL_PIXEL_PACK_BUFFER_BINDING:
1335 *params = mPack.pixelBuffer.id();
1336 break;
1337 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1338 *params = mUnpack.pixelBuffer.id();
1339 break;
1340 default:
1341 UNREACHABLE();
1342 break;
1343 }
1344}
1345
1346bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1347{
1348 switch (target)
1349 {
1350 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001351 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001352 {
Geoff Lang045536b2015-03-27 15:17:18 -04001353 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001354 }
1355 break;
1356 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001357 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001358 {
1359 *data = mUniformBuffers[index].id();
1360 }
1361 break;
1362 default:
1363 return false;
1364 }
1365
1366 return true;
1367}
1368
1369bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1370{
1371 switch (target)
1372 {
1373 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001374 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001375 {
Geoff Lang045536b2015-03-27 15:17:18 -04001376 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001377 }
1378 break;
1379 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001380 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001381 {
Geoff Lang045536b2015-03-27 15:17:18 -04001382 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001383 }
1384 break;
1385 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001386 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001387 {
1388 *data = mUniformBuffers[index].getOffset();
1389 }
1390 break;
1391 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001392 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001393 {
1394 *data = mUniformBuffers[index].getSize();
1395 }
1396 break;
1397 default:
1398 return false;
1399 }
1400
1401 return true;
1402}
1403
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001404bool State::hasMappedBuffer(GLenum target) const
1405{
1406 if (target == GL_ARRAY_BUFFER)
1407 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001408 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001409 const auto &vertexAttribs = vao->getVertexAttributes();
1410 for (size_t attribIndex = 0; attribIndex < vertexAttribs.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001411 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001412 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001413 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1414 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1415 {
1416 return true;
1417 }
1418 }
1419
1420 return false;
1421 }
1422 else
1423 {
1424 Buffer *buffer = getTargetBuffer(target);
1425 return (buffer && buffer->isMapped());
1426 }
1427}
1428
Shannon Woods53a94a82014-06-24 15:20:36 -04001429}