blob: 6790356bff77bdd5e7401a4cef1247e7951ad358 [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
Jamie Madillc185cb82015-04-28 12:39:08 -040033void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040034{
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 Woods23e05002014-09-22 19:07:27 -0400115 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400116
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400117 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
118
Geoff Lang76b10c92014-09-05 16:28:14 -0400119 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
120 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
121 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400122 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400123 // TODO: These could also be enabled via extension
124 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
125 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400126 }
127
Geoff Lang76b10c92014-09-05 16:28:14 -0400128 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400129
130 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
131 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
132 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
133
Geoff Lang7dd2e102014-11-10 15:19:26 -0500134 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400135
136 mReadFramebuffer = NULL;
137 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500138
139 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400140}
141
Geoff Lang76b10c92014-09-05 16:28:14 -0400142void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400143{
Geoff Lang76b10c92014-09-05 16:28:14 -0400144 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400145 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400146 TextureBindingVector &textureVector = bindingVec->second;
147 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400148 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400150 }
151 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400152 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
153 {
154 mSamplers[samplerIdx].set(NULL);
155 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400156
Shannon Woods53a94a82014-06-24 15:20:36 -0400157 mArrayBuffer.set(NULL);
158 mRenderbuffer.set(NULL);
159
Geoff Lang7dd2e102014-11-10 15:19:26 -0500160 if (mProgram)
161 {
162 mProgram->release();
163 }
164 mProgram = NULL;
165
Shannon Woods53a94a82014-06-24 15:20:36 -0400166 mTransformFeedback.set(NULL);
167
168 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
169 {
170 i->second.set(NULL);
171 }
172
173 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400174 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400176 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400177 }
178
Shannon Woods53a94a82014-06-24 15:20:36 -0400179 mCopyReadBuffer.set(NULL);
180 mCopyWriteBuffer.set(NULL);
181
182 mPack.pixelBuffer.set(NULL);
183 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500184
185 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400186}
187
188const RasterizerState &State::getRasterizerState() const
189{
190 return mRasterizer;
191}
192
193const BlendState &State::getBlendState() const
194{
195 return mBlend;
196}
197
198const DepthStencilState &State::getDepthStencilState() const
199{
200 return mDepthStencil;
201}
202
Jamie Madillf75ab352015-03-16 10:46:52 -0400203void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400204{
205 mColorClearValue.red = red;
206 mColorClearValue.green = green;
207 mColorClearValue.blue = blue;
208 mColorClearValue.alpha = alpha;
209}
210
Jamie Madillf75ab352015-03-16 10:46:52 -0400211void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400212{
213 mDepthClearValue = depth;
214}
215
Jamie Madillf75ab352015-03-16 10:46:52 -0400216void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400217{
218 mStencilClearValue = stencil;
219}
220
Shannon Woods53a94a82014-06-24 15:20:36 -0400221void State::setColorMask(bool red, bool green, bool blue, bool alpha)
222{
223 mBlend.colorMaskRed = red;
224 mBlend.colorMaskGreen = green;
225 mBlend.colorMaskBlue = blue;
226 mBlend.colorMaskAlpha = alpha;
227}
228
229void State::setDepthMask(bool mask)
230{
231 mDepthStencil.depthMask = mask;
232}
233
234bool State::isRasterizerDiscardEnabled() const
235{
236 return mRasterizer.rasterizerDiscard;
237}
238
239void State::setRasterizerDiscard(bool enabled)
240{
241 mRasterizer.rasterizerDiscard = enabled;
242}
243
244bool State::isCullFaceEnabled() const
245{
246 return mRasterizer.cullFace;
247}
248
249void State::setCullFace(bool enabled)
250{
251 mRasterizer.cullFace = enabled;
252}
253
254void State::setCullMode(GLenum mode)
255{
256 mRasterizer.cullMode = mode;
257}
258
259void State::setFrontFace(GLenum front)
260{
261 mRasterizer.frontFace = front;
262}
263
264bool State::isDepthTestEnabled() const
265{
266 return mDepthStencil.depthTest;
267}
268
269void State::setDepthTest(bool enabled)
270{
271 mDepthStencil.depthTest = enabled;
272}
273
274void State::setDepthFunc(GLenum depthFunc)
275{
276 mDepthStencil.depthFunc = depthFunc;
277}
278
279void State::setDepthRange(float zNear, float zFar)
280{
281 mNearZ = zNear;
282 mFarZ = zFar;
283}
284
Geoff Langd42f5b82015-04-16 14:03:29 -0400285float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400286{
Geoff Langd42f5b82015-04-16 14:03:29 -0400287 return mNearZ;
288}
289
290float State::getFarPlane() const
291{
292 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400293}
294
295bool State::isBlendEnabled() const
296{
297 return mBlend.blend;
298}
299
300void State::setBlend(bool enabled)
301{
302 mBlend.blend = enabled;
303}
304
305void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
306{
307 mBlend.sourceBlendRGB = sourceRGB;
308 mBlend.destBlendRGB = destRGB;
309 mBlend.sourceBlendAlpha = sourceAlpha;
310 mBlend.destBlendAlpha = destAlpha;
311}
312
313void State::setBlendColor(float red, float green, float blue, float alpha)
314{
315 mBlendColor.red = red;
316 mBlendColor.green = green;
317 mBlendColor.blue = blue;
318 mBlendColor.alpha = alpha;
319}
320
321void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
322{
323 mBlend.blendEquationRGB = rgbEquation;
324 mBlend.blendEquationAlpha = alphaEquation;
325}
326
327const ColorF &State::getBlendColor() const
328{
329 return mBlendColor;
330}
331
332bool State::isStencilTestEnabled() const
333{
334 return mDepthStencil.stencilTest;
335}
336
337void State::setStencilTest(bool enabled)
338{
339 mDepthStencil.stencilTest = enabled;
340}
341
342void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
343{
344 mDepthStencil.stencilFunc = stencilFunc;
345 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
346 mDepthStencil.stencilMask = stencilMask;
347}
348
349void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
350{
351 mDepthStencil.stencilBackFunc = stencilBackFunc;
352 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
353 mDepthStencil.stencilBackMask = stencilBackMask;
354}
355
356void State::setStencilWritemask(GLuint stencilWritemask)
357{
358 mDepthStencil.stencilWritemask = stencilWritemask;
359}
360
361void State::setStencilBackWritemask(GLuint stencilBackWritemask)
362{
363 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
364}
365
366void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
367{
368 mDepthStencil.stencilFail = stencilFail;
369 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
370 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
371}
372
373void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
374{
375 mDepthStencil.stencilBackFail = stencilBackFail;
376 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
377 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
378}
379
380GLint State::getStencilRef() const
381{
382 return mStencilRef;
383}
384
385GLint State::getStencilBackRef() const
386{
387 return mStencilBackRef;
388}
389
390bool State::isPolygonOffsetFillEnabled() const
391{
392 return mRasterizer.polygonOffsetFill;
393}
394
395void State::setPolygonOffsetFill(bool enabled)
396{
397 mRasterizer.polygonOffsetFill = enabled;
398}
399
400void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
401{
402 // An application can pass NaN values here, so handle this gracefully
403 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
404 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
405}
406
407bool State::isSampleAlphaToCoverageEnabled() const
408{
409 return mBlend.sampleAlphaToCoverage;
410}
411
412void State::setSampleAlphaToCoverage(bool enabled)
413{
414 mBlend.sampleAlphaToCoverage = enabled;
415}
416
417bool State::isSampleCoverageEnabled() const
418{
419 return mSampleCoverage;
420}
421
422void State::setSampleCoverage(bool enabled)
423{
424 mSampleCoverage = enabled;
425}
426
427void State::setSampleCoverageParams(GLclampf value, bool invert)
428{
429 mSampleCoverageValue = value;
430 mSampleCoverageInvert = invert;
431}
432
Geoff Lang0fbb6002015-04-16 11:11:53 -0400433GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400434{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400435 return mSampleCoverageValue;
436}
Shannon Woods53a94a82014-06-24 15:20:36 -0400437
Geoff Lang0fbb6002015-04-16 11:11:53 -0400438bool State::getSampleCoverageInvert() const
439{
440 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400441}
442
443bool State::isScissorTestEnabled() const
444{
445 return mScissorTest;
446}
447
448void State::setScissorTest(bool enabled)
449{
450 mScissorTest = enabled;
451}
452
453void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
454{
455 mScissor.x = x;
456 mScissor.y = y;
457 mScissor.width = width;
458 mScissor.height = height;
459}
460
461const Rectangle &State::getScissor() const
462{
463 return mScissor;
464}
465
466bool State::isDitherEnabled() const
467{
468 return mBlend.dither;
469}
470
471void State::setDither(bool enabled)
472{
473 mBlend.dither = enabled;
474}
475
Jamie Madillb4b53c52015-02-03 15:22:48 -0500476bool State::isPrimitiveRestartEnabled() const
477{
478 return mPrimitiveRestart;
479}
480
481void State::setPrimitiveRestart(bool enabled)
482{
483 mPrimitiveRestart = enabled;
484}
485
Shannon Woods53a94a82014-06-24 15:20:36 -0400486void State::setEnableFeature(GLenum feature, bool enabled)
487{
488 switch (feature)
489 {
490 case GL_CULL_FACE: setCullFace(enabled); break;
491 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
492 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
493 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
494 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
495 case GL_STENCIL_TEST: setStencilTest(enabled); break;
496 case GL_DEPTH_TEST: setDepthTest(enabled); break;
497 case GL_BLEND: setBlend(enabled); break;
498 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500499 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400500 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
501 default: UNREACHABLE();
502 }
503}
504
505bool State::getEnableFeature(GLenum feature)
506{
507 switch (feature)
508 {
509 case GL_CULL_FACE: return isCullFaceEnabled();
510 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
511 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
512 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
513 case GL_SCISSOR_TEST: return isScissorTestEnabled();
514 case GL_STENCIL_TEST: return isStencilTestEnabled();
515 case GL_DEPTH_TEST: return isDepthTestEnabled();
516 case GL_BLEND: return isBlendEnabled();
517 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500518 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400519 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
520 default: UNREACHABLE(); return false;
521 }
522}
523
524void State::setLineWidth(GLfloat width)
525{
526 mLineWidth = width;
527}
528
Geoff Lang4b3f4162015-04-16 13:22:05 -0400529float State::getLineWidth() const
530{
531 return mLineWidth;
532}
533
Shannon Woods53a94a82014-06-24 15:20:36 -0400534void State::setGenerateMipmapHint(GLenum hint)
535{
536 mGenerateMipmapHint = hint;
537}
538
539void State::setFragmentShaderDerivativeHint(GLenum hint)
540{
541 mFragmentShaderDerivativeHint = hint;
542 // TODO: Propagate the hint to shader translator so we can write
543 // ddx, ddx_coarse, or ddx_fine depending on the hint.
544 // Ignore for now. It is valid for implementations to ignore hint.
545}
546
547void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
548{
549 mViewport.x = x;
550 mViewport.y = y;
551 mViewport.width = width;
552 mViewport.height = height;
553}
554
555const Rectangle &State::getViewport() const
556{
557 return mViewport;
558}
559
560void State::setActiveSampler(unsigned int active)
561{
562 mActiveSampler = active;
563}
564
565unsigned int State::getActiveSampler() const
566{
567 return mActiveSampler;
568}
569
Geoff Lang76b10c92014-09-05 16:28:14 -0400570void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400571{
Geoff Lang76b10c92014-09-05 16:28:14 -0400572 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400573}
574
Geoff Lang76b10c92014-09-05 16:28:14 -0400575Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400576{
Jamie Madill5864ac22015-01-12 14:43:07 -0500577 const auto it = mSamplerTextures.find(type);
578 ASSERT(it != mSamplerTextures.end());
579 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400580}
581
Geoff Lang76b10c92014-09-05 16:28:14 -0400582GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400583{
Jamie Madill5864ac22015-01-12 14:43:07 -0500584 const auto it = mSamplerTextures.find(type);
585 ASSERT(it != mSamplerTextures.end());
586 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400587}
588
Jamie Madille6382c32014-11-07 15:05:26 -0500589void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400590{
591 // Textures have a detach method on State rather than a simple
592 // removeBinding, because the zero/null texture objects are managed
593 // separately, and don't have to go through the Context's maps or
594 // the ResourceManager.
595
596 // [OpenGL ES 2.0.24] section 3.8 page 84:
597 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
598 // rebound to texture object zero
599
Geoff Lang76b10c92014-09-05 16:28:14 -0400600 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400601 {
Jamie Madille6382c32014-11-07 15:05:26 -0500602 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400603 TextureBindingVector &textureVector = bindingVec->second;
604 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400605 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400606 BindingPointer<Texture> &binding = textureVector[textureIdx];
607 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400608 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500609 auto it = zeroTextures.find(textureType);
610 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500611 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500612 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400613 }
614 }
615 }
616
617 // [OpenGL ES 2.0.24] section 4.4 page 112:
618 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
619 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
620 // image was attached in the currently bound framebuffer.
621
622 if (mReadFramebuffer)
623 {
624 mReadFramebuffer->detachTexture(texture);
625 }
626
627 if (mDrawFramebuffer)
628 {
629 mDrawFramebuffer->detachTexture(texture);
630 }
631}
632
Jamie Madille6382c32014-11-07 15:05:26 -0500633void State::initializeZeroTextures(const TextureMap &zeroTextures)
634{
635 for (const auto &zeroTexture : zeroTextures)
636 {
637 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
638
639 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
640 {
641 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
642 }
643 }
644}
645
Shannon Woods53a94a82014-06-24 15:20:36 -0400646void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
647{
648 mSamplers[textureUnit].set(sampler);
649}
650
651GLuint State::getSamplerId(GLuint textureUnit) const
652{
Geoff Lang76b10c92014-09-05 16:28:14 -0400653 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400654 return mSamplers[textureUnit].id();
655}
656
657Sampler *State::getSampler(GLuint textureUnit) const
658{
659 return mSamplers[textureUnit].get();
660}
661
662void State::detachSampler(GLuint sampler)
663{
664 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
665 // If a sampler object that is currently bound to one or more texture units is
666 // deleted, it is as though BindSampler is called once for each texture unit to
667 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400668 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400669 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400670 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
671 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400672 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400673 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400674 }
675 }
676}
677
678void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
679{
680 mRenderbuffer.set(renderbuffer);
681}
682
683GLuint State::getRenderbufferId() const
684{
685 return mRenderbuffer.id();
686}
687
688Renderbuffer *State::getCurrentRenderbuffer()
689{
690 return mRenderbuffer.get();
691}
692
693void State::detachRenderbuffer(GLuint renderbuffer)
694{
695 // [OpenGL ES 2.0.24] section 4.4 page 109:
696 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
697 // had been executed with the target RENDERBUFFER and name of zero.
698
699 if (mRenderbuffer.id() == renderbuffer)
700 {
701 mRenderbuffer.set(NULL);
702 }
703
704 // [OpenGL ES 2.0.24] section 4.4 page 111:
705 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
706 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
707 // point to which this image was attached in the currently bound framebuffer.
708
709 Framebuffer *readFramebuffer = mReadFramebuffer;
710 Framebuffer *drawFramebuffer = mDrawFramebuffer;
711
712 if (readFramebuffer)
713 {
714 readFramebuffer->detachRenderbuffer(renderbuffer);
715 }
716
717 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
718 {
719 drawFramebuffer->detachRenderbuffer(renderbuffer);
720 }
721
722}
723
724void State::setReadFramebufferBinding(Framebuffer *framebuffer)
725{
726 mReadFramebuffer = framebuffer;
727}
728
729void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
730{
731 mDrawFramebuffer = framebuffer;
732}
733
734Framebuffer *State::getTargetFramebuffer(GLenum target) const
735{
736 switch (target)
737 {
738 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
739 case GL_DRAW_FRAMEBUFFER_ANGLE:
740 case GL_FRAMEBUFFER: return mDrawFramebuffer;
741 default: UNREACHABLE(); return NULL;
742 }
743}
744
745Framebuffer *State::getReadFramebuffer()
746{
747 return mReadFramebuffer;
748}
749
750Framebuffer *State::getDrawFramebuffer()
751{
752 return mDrawFramebuffer;
753}
754
755const Framebuffer *State::getReadFramebuffer() const
756{
757 return mReadFramebuffer;
758}
759
760const Framebuffer *State::getDrawFramebuffer() const
761{
762 return mDrawFramebuffer;
763}
764
765bool State::removeReadFramebufferBinding(GLuint framebuffer)
766{
Jamie Madill77a72f62015-04-14 11:18:32 -0400767 if (mReadFramebuffer != nullptr &&
768 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400769 {
770 mReadFramebuffer = NULL;
771 return true;
772 }
773
774 return false;
775}
776
777bool State::removeDrawFramebufferBinding(GLuint framebuffer)
778{
Jamie Madill77a72f62015-04-14 11:18:32 -0400779 if (mReadFramebuffer != nullptr &&
780 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400781 {
782 mDrawFramebuffer = NULL;
783 return true;
784 }
785
786 return false;
787}
788
789void State::setVertexArrayBinding(VertexArray *vertexArray)
790{
791 mVertexArray = vertexArray;
792}
793
794GLuint State::getVertexArrayId() const
795{
796 ASSERT(mVertexArray != NULL);
797 return mVertexArray->id();
798}
799
800VertexArray *State::getVertexArray() const
801{
802 ASSERT(mVertexArray != NULL);
803 return mVertexArray;
804}
805
806bool State::removeVertexArrayBinding(GLuint vertexArray)
807{
808 if (mVertexArray->id() == vertexArray)
809 {
810 mVertexArray = NULL;
811 return true;
812 }
813
814 return false;
815}
816
Geoff Lang7dd2e102014-11-10 15:19:26 -0500817void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400818{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500819 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400820 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500821 if (mProgram)
822 {
823 mProgram->release();
824 }
825
826 mProgram = newProgram;
827
828 if (mProgram)
829 {
830 newProgram->addRef();
831 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400832 }
833}
834
Geoff Lang7dd2e102014-11-10 15:19:26 -0500835Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400836{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500837 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400838}
839
840void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
841{
842 mTransformFeedback.set(transformFeedback);
843}
844
845TransformFeedback *State::getCurrentTransformFeedback() const
846{
847 return mTransformFeedback.get();
848}
849
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000850bool State::isTransformFeedbackActiveUnpaused() const
851{
852 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400853 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000854}
855
Shannon Woods53a94a82014-06-24 15:20:36 -0400856void State::detachTransformFeedback(GLuint transformFeedback)
857{
858 if (mTransformFeedback.id() == transformFeedback)
859 {
860 mTransformFeedback.set(NULL);
861 }
862}
863
864bool State::isQueryActive() const
865{
866 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
867 i != mActiveQueries.end(); i++)
868 {
869 if (i->second.get() != NULL)
870 {
871 return true;
872 }
873 }
874
875 return false;
876}
877
878void State::setActiveQuery(GLenum target, Query *query)
879{
880 mActiveQueries[target].set(query);
881}
882
883GLuint State::getActiveQueryId(GLenum target) const
884{
885 const Query *query = getActiveQuery(target);
886 return (query ? query->id() : 0u);
887}
888
889Query *State::getActiveQuery(GLenum target) const
890{
Jamie Madill5864ac22015-01-12 14:43:07 -0500891 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400892
Jamie Madill5864ac22015-01-12 14:43:07 -0500893 // All query types should already exist in the activeQueries map
894 ASSERT(it != mActiveQueries.end());
895
896 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400897}
898
899void State::setArrayBufferBinding(Buffer *buffer)
900{
901 mArrayBuffer.set(buffer);
902}
903
904GLuint State::getArrayBufferId() const
905{
906 return mArrayBuffer.id();
907}
908
909bool State::removeArrayBufferBinding(GLuint buffer)
910{
911 if (mArrayBuffer.id() == buffer)
912 {
913 mArrayBuffer.set(NULL);
914 return true;
915 }
916
917 return false;
918}
919
920void State::setGenericUniformBufferBinding(Buffer *buffer)
921{
922 mGenericUniformBuffer.set(buffer);
923}
924
925void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
926{
927 mUniformBuffers[index].set(buffer, offset, size);
928}
929
930GLuint State::getIndexedUniformBufferId(GLuint index) const
931{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400932 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400933
934 return mUniformBuffers[index].id();
935}
936
937Buffer *State::getIndexedUniformBuffer(GLuint index) const
938{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400939 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400940
941 return mUniformBuffers[index].get();
942}
943
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +0000944GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
945{
946 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
947
948 return mUniformBuffers[index].getOffset();
949}
950
951GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
952{
953 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
954
955 return mUniformBuffers[index].getSize();
956}
957
Shannon Woods53a94a82014-06-24 15:20:36 -0400958void State::setCopyReadBufferBinding(Buffer *buffer)
959{
960 mCopyReadBuffer.set(buffer);
961}
962
963void State::setCopyWriteBufferBinding(Buffer *buffer)
964{
965 mCopyWriteBuffer.set(buffer);
966}
967
968void State::setPixelPackBufferBinding(Buffer *buffer)
969{
970 mPack.pixelBuffer.set(buffer);
971}
972
973void State::setPixelUnpackBufferBinding(Buffer *buffer)
974{
975 mUnpack.pixelBuffer.set(buffer);
976}
977
978Buffer *State::getTargetBuffer(GLenum target) const
979{
980 switch (target)
981 {
982 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
983 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
984 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -0400985 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400986 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
987 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -0400988 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400989 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
990 default: UNREACHABLE(); return NULL;
991 }
992}
993
994void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
995{
996 getVertexArray()->enableAttribute(attribNum, enabled);
997}
998
999void State::setVertexAttribf(GLuint index, const GLfloat 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].setFloatValues(values);
1003}
1004
1005void State::setVertexAttribu(GLuint index, const GLuint 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].setUnsignedIntValues(values);
1009}
1010
1011void State::setVertexAttribi(GLuint index, const GLint values[4])
1012{
Shannon Woods23e05002014-09-22 19:07:27 -04001013 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001014 mVertexAttribCurrentValues[index].setIntValues(values);
1015}
1016
1017void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1018 bool pureInteger, GLsizei stride, const void *pointer)
1019{
1020 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1021}
1022
Shannon Woods53a94a82014-06-24 15:20:36 -04001023const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1024{
Shannon Woods23e05002014-09-22 19:07:27 -04001025 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001026 return mVertexAttribCurrentValues[attribNum];
1027}
1028
Shannon Woods53a94a82014-06-24 15:20:36 -04001029const void *State::getVertexAttribPointer(unsigned int attribNum) const
1030{
1031 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1032}
1033
1034void State::setPackAlignment(GLint alignment)
1035{
1036 mPack.alignment = alignment;
1037}
1038
1039GLint State::getPackAlignment() const
1040{
1041 return mPack.alignment;
1042}
1043
1044void State::setPackReverseRowOrder(bool reverseRowOrder)
1045{
1046 mPack.reverseRowOrder = reverseRowOrder;
1047}
1048
1049bool State::getPackReverseRowOrder() const
1050{
1051 return mPack.reverseRowOrder;
1052}
1053
1054const PixelPackState &State::getPackState() const
1055{
1056 return mPack;
1057}
1058
Jamie Madill87de3622015-03-16 10:41:44 -04001059PixelPackState &State::getPackState()
1060{
1061 return mPack;
1062}
1063
Shannon Woods53a94a82014-06-24 15:20:36 -04001064void State::setUnpackAlignment(GLint alignment)
1065{
1066 mUnpack.alignment = alignment;
1067}
1068
1069GLint State::getUnpackAlignment() const
1070{
1071 return mUnpack.alignment;
1072}
1073
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001074void State::setUnpackRowLength(GLint rowLength)
1075{
1076 mUnpack.rowLength = rowLength;
1077}
1078
1079GLint State::getUnpackRowLength() const
1080{
1081 return mUnpack.rowLength;
1082}
1083
Shannon Woods53a94a82014-06-24 15:20:36 -04001084const PixelUnpackState &State::getUnpackState() const
1085{
1086 return mUnpack;
1087}
1088
Jamie Madill67102f02015-03-16 10:41:42 -04001089PixelUnpackState &State::getUnpackState()
1090{
1091 return mUnpack;
1092}
1093
Shannon Woods53a94a82014-06-24 15:20:36 -04001094void State::getBooleanv(GLenum pname, GLboolean *params)
1095{
1096 switch (pname)
1097 {
1098 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1099 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1100 case GL_COLOR_WRITEMASK:
1101 params[0] = mBlend.colorMaskRed;
1102 params[1] = mBlend.colorMaskGreen;
1103 params[2] = mBlend.colorMaskBlue;
1104 params[3] = mBlend.colorMaskAlpha;
1105 break;
1106 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1107 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1108 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1109 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1110 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1111 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1112 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1113 case GL_BLEND: *params = mBlend.blend; break;
1114 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001115 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1116 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001117 default:
1118 UNREACHABLE();
1119 break;
1120 }
1121}
1122
1123void State::getFloatv(GLenum pname, GLfloat *params)
1124{
1125 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1126 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1127 // GetIntegerv as its native query function. As it would require conversion in any
1128 // case, this should make no difference to the calling application.
1129 switch (pname)
1130 {
1131 case GL_LINE_WIDTH: *params = mLineWidth; break;
1132 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1133 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1134 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1135 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1136 case GL_DEPTH_RANGE:
1137 params[0] = mNearZ;
1138 params[1] = mFarZ;
1139 break;
1140 case GL_COLOR_CLEAR_VALUE:
1141 params[0] = mColorClearValue.red;
1142 params[1] = mColorClearValue.green;
1143 params[2] = mColorClearValue.blue;
1144 params[3] = mColorClearValue.alpha;
1145 break;
1146 case GL_BLEND_COLOR:
1147 params[0] = mBlendColor.red;
1148 params[1] = mBlendColor.green;
1149 params[2] = mBlendColor.blue;
1150 params[3] = mBlendColor.alpha;
1151 break;
1152 default:
1153 UNREACHABLE();
1154 break;
1155 }
1156}
1157
Jamie Madill48faf802014-11-06 15:27:22 -05001158void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001159{
1160 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1161 {
1162 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001163 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001164 Framebuffer *framebuffer = mDrawFramebuffer;
1165 *params = framebuffer->getDrawBufferState(colorAttachment);
1166 return;
1167 }
1168
1169 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1170 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1171 // GetIntegerv as its native query function. As it would require conversion in any
1172 // case, this should make no difference to the calling application. You may find it in
1173 // State::getFloatv.
1174 switch (pname)
1175 {
1176 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001177 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001178 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1179 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1180 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1181 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1182 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001183 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001184 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1185 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1186 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001187 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001188 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1189 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1190 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1191 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1192 case GL_STENCIL_REF: *params = mStencilRef; break;
1193 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1194 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1195 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1196 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1197 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1198 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1199 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1200 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1201 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1202 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1203 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1204 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1205 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1206 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1207 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1208 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1209 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1210 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1211 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1212 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001213 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1214 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001215 case GL_SAMPLE_BUFFERS:
1216 case GL_SAMPLES:
1217 {
1218 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001219 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001220 {
1221 switch (pname)
1222 {
1223 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001224 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001225 {
1226 *params = 1;
1227 }
1228 else
1229 {
1230 *params = 0;
1231 }
1232 break;
1233 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001234 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001235 break;
1236 }
1237 }
1238 else
1239 {
1240 *params = 0;
1241 }
1242 }
1243 break;
1244 case GL_VIEWPORT:
1245 params[0] = mViewport.x;
1246 params[1] = mViewport.y;
1247 params[2] = mViewport.width;
1248 params[3] = mViewport.height;
1249 break;
1250 case GL_SCISSOR_BOX:
1251 params[0] = mScissor.x;
1252 params[1] = mScissor.y;
1253 params[2] = mScissor.width;
1254 params[3] = mScissor.height;
1255 break;
1256 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1257 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1258 case GL_RED_BITS:
1259 case GL_GREEN_BITS:
1260 case GL_BLUE_BITS:
1261 case GL_ALPHA_BITS:
1262 {
1263 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001264 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001265
1266 if (colorbuffer)
1267 {
1268 switch (pname)
1269 {
1270 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1271 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1272 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1273 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1274 }
1275 }
1276 else
1277 {
1278 *params = 0;
1279 }
1280 }
1281 break;
1282 case GL_DEPTH_BITS:
1283 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001284 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1285 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001286
1287 if (depthbuffer)
1288 {
1289 *params = depthbuffer->getDepthSize();
1290 }
1291 else
1292 {
1293 *params = 0;
1294 }
1295 }
1296 break;
1297 case GL_STENCIL_BITS:
1298 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001299 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1300 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001301
1302 if (stencilbuffer)
1303 {
1304 *params = stencilbuffer->getStencilSize();
1305 }
1306 else
1307 {
1308 *params = 0;
1309 }
1310 }
1311 break;
1312 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001313 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001314 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001315 break;
1316 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001317 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001318 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001319 break;
1320 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001321 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001322 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001323 break;
1324 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001325 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001326 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001327 break;
1328 case GL_UNIFORM_BUFFER_BINDING:
1329 *params = mGenericUniformBuffer.id();
1330 break;
1331 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001332 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001333 break;
1334 case GL_COPY_READ_BUFFER_BINDING:
1335 *params = mCopyReadBuffer.id();
1336 break;
1337 case GL_COPY_WRITE_BUFFER_BINDING:
1338 *params = mCopyWriteBuffer.id();
1339 break;
1340 case GL_PIXEL_PACK_BUFFER_BINDING:
1341 *params = mPack.pixelBuffer.id();
1342 break;
1343 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1344 *params = mUnpack.pixelBuffer.id();
1345 break;
1346 default:
1347 UNREACHABLE();
1348 break;
1349 }
1350}
1351
1352bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1353{
1354 switch (target)
1355 {
1356 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001357 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001358 {
Geoff Lang045536b2015-03-27 15:17:18 -04001359 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001360 }
1361 break;
1362 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001363 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001364 {
1365 *data = mUniformBuffers[index].id();
1366 }
1367 break;
1368 default:
1369 return false;
1370 }
1371
1372 return true;
1373}
1374
1375bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1376{
1377 switch (target)
1378 {
1379 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
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).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001383 }
1384 break;
1385 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001386 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001387 {
Geoff Lang045536b2015-03-27 15:17:18 -04001388 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001389 }
1390 break;
1391 case GL_UNIFORM_BUFFER_START:
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].getOffset();
1395 }
1396 break;
1397 case GL_UNIFORM_BUFFER_SIZE:
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].getSize();
1401 }
1402 break;
1403 default:
1404 return false;
1405 }
1406
1407 return true;
1408}
1409
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001410bool State::hasMappedBuffer(GLenum target) const
1411{
1412 if (target == GL_ARRAY_BUFFER)
1413 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001414 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001415 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001416 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001417 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001418 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001419 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001420 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1421 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1422 {
1423 return true;
1424 }
1425 }
1426
1427 return false;
1428 }
1429 else
1430 {
1431 Buffer *buffer = getTargetBuffer(target);
1432 return (buffer && buffer->isMapped());
1433 }
1434}
1435
Shannon Woods53a94a82014-06-24 15:20:36 -04001436}