blob: 5791cb934e5d8845c2c893ff5fa8b3d6bcac5e31 [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;
Jamie Madill1b94d432015-08-07 13:23:23 -040026
27 // Initialize dirty bit masks
28 // TODO(jmadill): additional ES3 state
29 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
30 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
31 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
32 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
33 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
34 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
35 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
36 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
37 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
38 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
39 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
40 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
41 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
42 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
43 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang76b10c92014-09-05 16:28:14 -040044}
45
46State::~State()
47{
48 reset();
49}
50
Jamie Madillc185cb82015-04-28 12:39:08 -040051void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040052{
Shannon Woods2df6a602014-09-26 16:12:07 -040053 mMaxDrawBuffers = caps.maxDrawBuffers;
54 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040055
Jamie Madillf75ab352015-03-16 10:46:52 -040056 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040057
58 mDepthClearValue = 1.0f;
59 mStencilClearValue = 0;
60
61 mRasterizer.rasterizerDiscard = false;
62 mRasterizer.cullFace = false;
63 mRasterizer.cullMode = GL_BACK;
64 mRasterizer.frontFace = GL_CCW;
65 mRasterizer.polygonOffsetFill = false;
66 mRasterizer.polygonOffsetFactor = 0.0f;
67 mRasterizer.polygonOffsetUnits = 0.0f;
68 mRasterizer.pointDrawMode = false;
69 mRasterizer.multiSample = false;
70 mScissorTest = false;
71 mScissor.x = 0;
72 mScissor.y = 0;
73 mScissor.width = 0;
74 mScissor.height = 0;
75
76 mBlend.blend = false;
77 mBlend.sourceBlendRGB = GL_ONE;
78 mBlend.sourceBlendAlpha = GL_ONE;
79 mBlend.destBlendRGB = GL_ZERO;
80 mBlend.destBlendAlpha = GL_ZERO;
81 mBlend.blendEquationRGB = GL_FUNC_ADD;
82 mBlend.blendEquationAlpha = GL_FUNC_ADD;
83 mBlend.sampleAlphaToCoverage = false;
84 mBlend.dither = true;
85
86 mBlendColor.red = 0;
87 mBlendColor.green = 0;
88 mBlendColor.blue = 0;
89 mBlendColor.alpha = 0;
90
91 mDepthStencil.depthTest = false;
92 mDepthStencil.depthFunc = GL_LESS;
93 mDepthStencil.depthMask = true;
94 mDepthStencil.stencilTest = false;
95 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070096 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
97 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040098 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070099 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
100 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400101 mDepthStencil.stencilFail = GL_KEEP;
102 mDepthStencil.stencilPassDepthFail = GL_KEEP;
103 mDepthStencil.stencilPassDepthPass = GL_KEEP;
104 mDepthStencil.stencilBackFail = GL_KEEP;
105 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
106 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
107
108 mStencilRef = 0;
109 mStencilBackRef = 0;
110
111 mSampleCoverage = false;
112 mSampleCoverageValue = 1.0f;
113 mSampleCoverageInvert = false;
114 mGenerateMipmapHint = GL_DONT_CARE;
115 mFragmentShaderDerivativeHint = GL_DONT_CARE;
116
117 mLineWidth = 1.0f;
118
119 mViewport.x = 0;
120 mViewport.y = 0;
121 mViewport.width = 0;
122 mViewport.height = 0;
123 mNearZ = 0.0f;
124 mFarZ = 1.0f;
125
126 mBlend.colorMaskRed = true;
127 mBlend.colorMaskGreen = true;
128 mBlend.colorMaskBlue = true;
129 mBlend.colorMaskAlpha = true;
130
Geoff Lang76b10c92014-09-05 16:28:14 -0400131 mActiveSampler = 0;
132
Shannon Woods23e05002014-09-22 19:07:27 -0400133 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400134
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400135 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
136
Geoff Lang76b10c92014-09-05 16:28:14 -0400137 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
138 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
139 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400140 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400141 // TODO: These could also be enabled via extension
142 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
143 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400144 }
145
Geoff Lang76b10c92014-09-05 16:28:14 -0400146 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400147
148 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
149 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
150 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
151
Geoff Lang7dd2e102014-11-10 15:19:26 -0500152 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400153
154 mReadFramebuffer = NULL;
155 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500156
157 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400158}
159
Geoff Lang76b10c92014-09-05 16:28:14 -0400160void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400161{
Geoff Lang76b10c92014-09-05 16:28:14 -0400162 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400163 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400164 TextureBindingVector &textureVector = bindingVec->second;
165 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400166 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400167 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400168 }
169 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400170 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
171 {
172 mSamplers[samplerIdx].set(NULL);
173 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400174
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 mArrayBuffer.set(NULL);
176 mRenderbuffer.set(NULL);
177
Geoff Lang7dd2e102014-11-10 15:19:26 -0500178 if (mProgram)
179 {
180 mProgram->release();
181 }
182 mProgram = NULL;
183
Shannon Woods53a94a82014-06-24 15:20:36 -0400184 mTransformFeedback.set(NULL);
185
186 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
187 {
188 i->second.set(NULL);
189 }
190
191 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400192 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400193 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400194 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400195 }
196
Shannon Woods53a94a82014-06-24 15:20:36 -0400197 mCopyReadBuffer.set(NULL);
198 mCopyWriteBuffer.set(NULL);
199
200 mPack.pixelBuffer.set(NULL);
201 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500202
203 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400204
205 // TODO(jmadill): Is this necessary?
206 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400207}
208
209const RasterizerState &State::getRasterizerState() const
210{
211 return mRasterizer;
212}
213
214const BlendState &State::getBlendState() const
215{
216 return mBlend;
217}
218
219const DepthStencilState &State::getDepthStencilState() const
220{
221 return mDepthStencil;
222}
223
Jamie Madillf75ab352015-03-16 10:46:52 -0400224void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400225{
226 mColorClearValue.red = red;
227 mColorClearValue.green = green;
228 mColorClearValue.blue = blue;
229 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400230 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400231}
232
Jamie Madillf75ab352015-03-16 10:46:52 -0400233void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400234{
235 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400236 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400237}
238
Jamie Madillf75ab352015-03-16 10:46:52 -0400239void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400240{
241 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400242 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400243}
244
Shannon Woods53a94a82014-06-24 15:20:36 -0400245void State::setColorMask(bool red, bool green, bool blue, bool alpha)
246{
247 mBlend.colorMaskRed = red;
248 mBlend.colorMaskGreen = green;
249 mBlend.colorMaskBlue = blue;
250 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400251 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400252}
253
254void State::setDepthMask(bool mask)
255{
256 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400257 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400258}
259
260bool State::isRasterizerDiscardEnabled() const
261{
262 return mRasterizer.rasterizerDiscard;
263}
264
265void State::setRasterizerDiscard(bool enabled)
266{
267 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400268 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400269}
270
271bool State::isCullFaceEnabled() const
272{
273 return mRasterizer.cullFace;
274}
275
276void State::setCullFace(bool enabled)
277{
278 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400279 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400280}
281
282void State::setCullMode(GLenum mode)
283{
284 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400285 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400286}
287
288void State::setFrontFace(GLenum front)
289{
290 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400291 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400292}
293
294bool State::isDepthTestEnabled() const
295{
296 return mDepthStencil.depthTest;
297}
298
299void State::setDepthTest(bool enabled)
300{
301 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400302 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400303}
304
305void State::setDepthFunc(GLenum depthFunc)
306{
307 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400308 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400309}
310
311void State::setDepthRange(float zNear, float zFar)
312{
313 mNearZ = zNear;
314 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400315 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400316}
317
Geoff Langd42f5b82015-04-16 14:03:29 -0400318float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400319{
Geoff Langd42f5b82015-04-16 14:03:29 -0400320 return mNearZ;
321}
322
323float State::getFarPlane() const
324{
325 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400326}
327
328bool State::isBlendEnabled() const
329{
330 return mBlend.blend;
331}
332
333void State::setBlend(bool enabled)
334{
335 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400336 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400337}
338
339void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
340{
341 mBlend.sourceBlendRGB = sourceRGB;
342 mBlend.destBlendRGB = destRGB;
343 mBlend.sourceBlendAlpha = sourceAlpha;
344 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400345 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400346}
347
348void State::setBlendColor(float red, float green, float blue, float alpha)
349{
350 mBlendColor.red = red;
351 mBlendColor.green = green;
352 mBlendColor.blue = blue;
353 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400354 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400355}
356
357void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
358{
359 mBlend.blendEquationRGB = rgbEquation;
360 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400361 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400362}
363
364const ColorF &State::getBlendColor() const
365{
366 return mBlendColor;
367}
368
369bool State::isStencilTestEnabled() const
370{
371 return mDepthStencil.stencilTest;
372}
373
374void State::setStencilTest(bool enabled)
375{
376 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400377 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400378}
379
380void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
381{
382 mDepthStencil.stencilFunc = stencilFunc;
383 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
384 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400385 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400386}
387
388void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
389{
390 mDepthStencil.stencilBackFunc = stencilBackFunc;
391 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
392 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400393 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400394}
395
396void State::setStencilWritemask(GLuint stencilWritemask)
397{
398 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400399 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400400}
401
402void State::setStencilBackWritemask(GLuint stencilBackWritemask)
403{
404 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400405 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400406}
407
408void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
409{
410 mDepthStencil.stencilFail = stencilFail;
411 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
412 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400413 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400414}
415
416void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
417{
418 mDepthStencil.stencilBackFail = stencilBackFail;
419 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
420 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400421 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400422}
423
424GLint State::getStencilRef() const
425{
426 return mStencilRef;
427}
428
429GLint State::getStencilBackRef() const
430{
431 return mStencilBackRef;
432}
433
434bool State::isPolygonOffsetFillEnabled() const
435{
436 return mRasterizer.polygonOffsetFill;
437}
438
439void State::setPolygonOffsetFill(bool enabled)
440{
Jamie Madill1b94d432015-08-07 13:23:23 -0400441 mRasterizer.polygonOffsetFill = enabled;
442 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400443}
444
445void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
446{
447 // An application can pass NaN values here, so handle this gracefully
448 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
449 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400450 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400451}
452
453bool State::isSampleAlphaToCoverageEnabled() const
454{
455 return mBlend.sampleAlphaToCoverage;
456}
457
458void State::setSampleAlphaToCoverage(bool enabled)
459{
460 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400461 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400462}
463
464bool State::isSampleCoverageEnabled() const
465{
466 return mSampleCoverage;
467}
468
469void State::setSampleCoverage(bool enabled)
470{
471 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400472 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400473}
474
475void State::setSampleCoverageParams(GLclampf value, bool invert)
476{
477 mSampleCoverageValue = value;
478 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400479 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400480}
481
Geoff Lang0fbb6002015-04-16 11:11:53 -0400482GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400483{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400484 return mSampleCoverageValue;
485}
Shannon Woods53a94a82014-06-24 15:20:36 -0400486
Geoff Lang0fbb6002015-04-16 11:11:53 -0400487bool State::getSampleCoverageInvert() const
488{
489 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400490}
491
492bool State::isScissorTestEnabled() const
493{
494 return mScissorTest;
495}
496
497void State::setScissorTest(bool enabled)
498{
499 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400500 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400501}
502
503void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
504{
505 mScissor.x = x;
506 mScissor.y = y;
507 mScissor.width = width;
508 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400509 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400510}
511
512const Rectangle &State::getScissor() const
513{
514 return mScissor;
515}
516
517bool State::isDitherEnabled() const
518{
519 return mBlend.dither;
520}
521
522void State::setDither(bool enabled)
523{
524 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400525 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400526}
527
Jamie Madillb4b53c52015-02-03 15:22:48 -0500528bool State::isPrimitiveRestartEnabled() const
529{
530 return mPrimitiveRestart;
531}
532
533void State::setPrimitiveRestart(bool enabled)
534{
535 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400536 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500537}
538
Shannon Woods53a94a82014-06-24 15:20:36 -0400539void State::setEnableFeature(GLenum feature, bool enabled)
540{
541 switch (feature)
542 {
543 case GL_CULL_FACE: setCullFace(enabled); break;
544 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
545 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
546 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
547 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
548 case GL_STENCIL_TEST: setStencilTest(enabled); break;
549 case GL_DEPTH_TEST: setDepthTest(enabled); break;
550 case GL_BLEND: setBlend(enabled); break;
551 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500552 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400553 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
554 default: UNREACHABLE();
555 }
556}
557
558bool State::getEnableFeature(GLenum feature)
559{
560 switch (feature)
561 {
562 case GL_CULL_FACE: return isCullFaceEnabled();
563 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
564 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
565 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
566 case GL_SCISSOR_TEST: return isScissorTestEnabled();
567 case GL_STENCIL_TEST: return isStencilTestEnabled();
568 case GL_DEPTH_TEST: return isDepthTestEnabled();
569 case GL_BLEND: return isBlendEnabled();
570 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500571 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400572 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
573 default: UNREACHABLE(); return false;
574 }
575}
576
577void State::setLineWidth(GLfloat width)
578{
579 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400580 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400581}
582
Geoff Lang4b3f4162015-04-16 13:22:05 -0400583float State::getLineWidth() const
584{
585 return mLineWidth;
586}
587
Shannon Woods53a94a82014-06-24 15:20:36 -0400588void State::setGenerateMipmapHint(GLenum hint)
589{
590 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400591 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400592}
593
594void State::setFragmentShaderDerivativeHint(GLenum hint)
595{
596 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400597 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400598 // TODO: Propagate the hint to shader translator so we can write
599 // ddx, ddx_coarse, or ddx_fine depending on the hint.
600 // Ignore for now. It is valid for implementations to ignore hint.
601}
602
603void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
604{
605 mViewport.x = x;
606 mViewport.y = y;
607 mViewport.width = width;
608 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400609 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400610}
611
612const Rectangle &State::getViewport() const
613{
614 return mViewport;
615}
616
617void State::setActiveSampler(unsigned int active)
618{
619 mActiveSampler = active;
620}
621
622unsigned int State::getActiveSampler() const
623{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700624 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400625}
626
Geoff Lang76b10c92014-09-05 16:28:14 -0400627void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400628{
Geoff Lang76b10c92014-09-05 16:28:14 -0400629 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400630}
631
Geoff Lang76b10c92014-09-05 16:28:14 -0400632Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400633{
Jamie Madill5864ac22015-01-12 14:43:07 -0500634 const auto it = mSamplerTextures.find(type);
635 ASSERT(it != mSamplerTextures.end());
636 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400637}
638
Geoff Lang76b10c92014-09-05 16:28:14 -0400639GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400640{
Jamie Madill5864ac22015-01-12 14:43:07 -0500641 const auto it = mSamplerTextures.find(type);
642 ASSERT(it != mSamplerTextures.end());
643 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400644}
645
Jamie Madille6382c32014-11-07 15:05:26 -0500646void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400647{
648 // Textures have a detach method on State rather than a simple
649 // removeBinding, because the zero/null texture objects are managed
650 // separately, and don't have to go through the Context's maps or
651 // the ResourceManager.
652
653 // [OpenGL ES 2.0.24] section 3.8 page 84:
654 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
655 // rebound to texture object zero
656
Geoff Lang76b10c92014-09-05 16:28:14 -0400657 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400658 {
Jamie Madille6382c32014-11-07 15:05:26 -0500659 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400660 TextureBindingVector &textureVector = bindingVec->second;
661 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400662 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400663 BindingPointer<Texture> &binding = textureVector[textureIdx];
664 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400665 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500666 auto it = zeroTextures.find(textureType);
667 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500668 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500669 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400670 }
671 }
672 }
673
674 // [OpenGL ES 2.0.24] section 4.4 page 112:
675 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
676 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
677 // image was attached in the currently bound framebuffer.
678
679 if (mReadFramebuffer)
680 {
681 mReadFramebuffer->detachTexture(texture);
682 }
683
684 if (mDrawFramebuffer)
685 {
686 mDrawFramebuffer->detachTexture(texture);
687 }
688}
689
Jamie Madille6382c32014-11-07 15:05:26 -0500690void State::initializeZeroTextures(const TextureMap &zeroTextures)
691{
692 for (const auto &zeroTexture : zeroTextures)
693 {
694 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
695
696 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
697 {
698 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
699 }
700 }
701}
702
Shannon Woods53a94a82014-06-24 15:20:36 -0400703void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
704{
705 mSamplers[textureUnit].set(sampler);
706}
707
708GLuint State::getSamplerId(GLuint textureUnit) const
709{
Geoff Lang76b10c92014-09-05 16:28:14 -0400710 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400711 return mSamplers[textureUnit].id();
712}
713
714Sampler *State::getSampler(GLuint textureUnit) const
715{
716 return mSamplers[textureUnit].get();
717}
718
719void State::detachSampler(GLuint sampler)
720{
721 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
722 // If a sampler object that is currently bound to one or more texture units is
723 // deleted, it is as though BindSampler is called once for each texture unit to
724 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400725 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400726 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400727 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
728 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400729 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400730 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400731 }
732 }
733}
734
735void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
736{
737 mRenderbuffer.set(renderbuffer);
738}
739
740GLuint State::getRenderbufferId() const
741{
742 return mRenderbuffer.id();
743}
744
745Renderbuffer *State::getCurrentRenderbuffer()
746{
747 return mRenderbuffer.get();
748}
749
750void State::detachRenderbuffer(GLuint renderbuffer)
751{
752 // [OpenGL ES 2.0.24] section 4.4 page 109:
753 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
754 // had been executed with the target RENDERBUFFER and name of zero.
755
756 if (mRenderbuffer.id() == renderbuffer)
757 {
758 mRenderbuffer.set(NULL);
759 }
760
761 // [OpenGL ES 2.0.24] section 4.4 page 111:
762 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
763 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
764 // point to which this image was attached in the currently bound framebuffer.
765
766 Framebuffer *readFramebuffer = mReadFramebuffer;
767 Framebuffer *drawFramebuffer = mDrawFramebuffer;
768
769 if (readFramebuffer)
770 {
771 readFramebuffer->detachRenderbuffer(renderbuffer);
772 }
773
774 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
775 {
776 drawFramebuffer->detachRenderbuffer(renderbuffer);
777 }
778
779}
780
781void State::setReadFramebufferBinding(Framebuffer *framebuffer)
782{
783 mReadFramebuffer = framebuffer;
784}
785
786void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
787{
788 mDrawFramebuffer = framebuffer;
789}
790
791Framebuffer *State::getTargetFramebuffer(GLenum target) const
792{
793 switch (target)
794 {
795 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
796 case GL_DRAW_FRAMEBUFFER_ANGLE:
797 case GL_FRAMEBUFFER: return mDrawFramebuffer;
798 default: UNREACHABLE(); return NULL;
799 }
800}
801
802Framebuffer *State::getReadFramebuffer()
803{
804 return mReadFramebuffer;
805}
806
807Framebuffer *State::getDrawFramebuffer()
808{
809 return mDrawFramebuffer;
810}
811
812const Framebuffer *State::getReadFramebuffer() const
813{
814 return mReadFramebuffer;
815}
816
817const Framebuffer *State::getDrawFramebuffer() const
818{
819 return mDrawFramebuffer;
820}
821
822bool State::removeReadFramebufferBinding(GLuint framebuffer)
823{
Jamie Madill77a72f62015-04-14 11:18:32 -0400824 if (mReadFramebuffer != nullptr &&
825 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400826 {
827 mReadFramebuffer = NULL;
828 return true;
829 }
830
831 return false;
832}
833
834bool State::removeDrawFramebufferBinding(GLuint framebuffer)
835{
Jamie Madill77a72f62015-04-14 11:18:32 -0400836 if (mReadFramebuffer != nullptr &&
837 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400838 {
839 mDrawFramebuffer = NULL;
840 return true;
841 }
842
843 return false;
844}
845
846void State::setVertexArrayBinding(VertexArray *vertexArray)
847{
848 mVertexArray = vertexArray;
849}
850
851GLuint State::getVertexArrayId() const
852{
853 ASSERT(mVertexArray != NULL);
854 return mVertexArray->id();
855}
856
857VertexArray *State::getVertexArray() const
858{
859 ASSERT(mVertexArray != NULL);
860 return mVertexArray;
861}
862
863bool State::removeVertexArrayBinding(GLuint vertexArray)
864{
865 if (mVertexArray->id() == vertexArray)
866 {
867 mVertexArray = NULL;
868 return true;
869 }
870
871 return false;
872}
873
Geoff Lang7dd2e102014-11-10 15:19:26 -0500874void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400875{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500876 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400877 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500878 if (mProgram)
879 {
880 mProgram->release();
881 }
882
883 mProgram = newProgram;
884
885 if (mProgram)
886 {
887 newProgram->addRef();
888 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400889 }
890}
891
Geoff Lang7dd2e102014-11-10 15:19:26 -0500892Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400893{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500894 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400895}
896
897void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
898{
899 mTransformFeedback.set(transformFeedback);
900}
901
902TransformFeedback *State::getCurrentTransformFeedback() const
903{
904 return mTransformFeedback.get();
905}
906
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000907bool State::isTransformFeedbackActiveUnpaused() const
908{
909 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400910 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000911}
912
Shannon Woods53a94a82014-06-24 15:20:36 -0400913void State::detachTransformFeedback(GLuint transformFeedback)
914{
915 if (mTransformFeedback.id() == transformFeedback)
916 {
917 mTransformFeedback.set(NULL);
918 }
919}
920
921bool State::isQueryActive() const
922{
923 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
924 i != mActiveQueries.end(); i++)
925 {
926 if (i->second.get() != NULL)
927 {
928 return true;
929 }
930 }
931
932 return false;
933}
934
935void State::setActiveQuery(GLenum target, Query *query)
936{
937 mActiveQueries[target].set(query);
938}
939
940GLuint State::getActiveQueryId(GLenum target) const
941{
942 const Query *query = getActiveQuery(target);
943 return (query ? query->id() : 0u);
944}
945
946Query *State::getActiveQuery(GLenum target) const
947{
Jamie Madill5864ac22015-01-12 14:43:07 -0500948 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400949
Jamie Madill5864ac22015-01-12 14:43:07 -0500950 // All query types should already exist in the activeQueries map
951 ASSERT(it != mActiveQueries.end());
952
953 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400954}
955
956void State::setArrayBufferBinding(Buffer *buffer)
957{
958 mArrayBuffer.set(buffer);
959}
960
961GLuint State::getArrayBufferId() const
962{
963 return mArrayBuffer.id();
964}
965
966bool State::removeArrayBufferBinding(GLuint buffer)
967{
968 if (mArrayBuffer.id() == buffer)
969 {
970 mArrayBuffer.set(NULL);
971 return true;
972 }
973
974 return false;
975}
976
977void State::setGenericUniformBufferBinding(Buffer *buffer)
978{
979 mGenericUniformBuffer.set(buffer);
980}
981
982void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
983{
984 mUniformBuffers[index].set(buffer, offset, size);
985}
986
987GLuint State::getIndexedUniformBufferId(GLuint index) const
988{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400989 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400990
991 return mUniformBuffers[index].id();
992}
993
994Buffer *State::getIndexedUniformBuffer(GLuint index) const
995{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400996 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400997
998 return mUniformBuffers[index].get();
999}
1000
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001001GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
1002{
1003 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1004
1005 return mUniformBuffers[index].getOffset();
1006}
1007
1008GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
1009{
1010 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1011
1012 return mUniformBuffers[index].getSize();
1013}
1014
Shannon Woods53a94a82014-06-24 15:20:36 -04001015void State::setCopyReadBufferBinding(Buffer *buffer)
1016{
1017 mCopyReadBuffer.set(buffer);
1018}
1019
1020void State::setCopyWriteBufferBinding(Buffer *buffer)
1021{
1022 mCopyWriteBuffer.set(buffer);
1023}
1024
1025void State::setPixelPackBufferBinding(Buffer *buffer)
1026{
1027 mPack.pixelBuffer.set(buffer);
1028}
1029
1030void State::setPixelUnpackBufferBinding(Buffer *buffer)
1031{
1032 mUnpack.pixelBuffer.set(buffer);
1033}
1034
1035Buffer *State::getTargetBuffer(GLenum target) const
1036{
1037 switch (target)
1038 {
1039 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1040 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1041 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001042 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001043 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1044 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001045 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001046 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1047 default: UNREACHABLE(); return NULL;
1048 }
1049}
1050
1051void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1052{
1053 getVertexArray()->enableAttribute(attribNum, enabled);
1054}
1055
1056void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1057{
Shannon Woods23e05002014-09-22 19:07:27 -04001058 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001059 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001060 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001061}
1062
1063void State::setVertexAttribu(GLuint index, const GLuint values[4])
1064{
Shannon Woods23e05002014-09-22 19:07:27 -04001065 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001066 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001067 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001068}
1069
1070void State::setVertexAttribi(GLuint index, const GLint values[4])
1071{
Shannon Woods23e05002014-09-22 19:07:27 -04001072 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001073 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001074 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001075}
1076
1077void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1078 bool pureInteger, GLsizei stride, const void *pointer)
1079{
1080 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1081}
1082
Shannon Woods53a94a82014-06-24 15:20:36 -04001083const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1084{
Shannon Woods23e05002014-09-22 19:07:27 -04001085 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001086 return mVertexAttribCurrentValues[attribNum];
1087}
1088
Shannon Woods53a94a82014-06-24 15:20:36 -04001089const void *State::getVertexAttribPointer(unsigned int attribNum) const
1090{
1091 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1092}
1093
1094void State::setPackAlignment(GLint alignment)
1095{
1096 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001097 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001098}
1099
1100GLint State::getPackAlignment() const
1101{
1102 return mPack.alignment;
1103}
1104
1105void State::setPackReverseRowOrder(bool reverseRowOrder)
1106{
1107 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001108 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001109}
1110
1111bool State::getPackReverseRowOrder() const
1112{
1113 return mPack.reverseRowOrder;
1114}
1115
1116const PixelPackState &State::getPackState() const
1117{
1118 return mPack;
1119}
1120
Jamie Madill87de3622015-03-16 10:41:44 -04001121PixelPackState &State::getPackState()
1122{
1123 return mPack;
1124}
1125
Shannon Woods53a94a82014-06-24 15:20:36 -04001126void State::setUnpackAlignment(GLint alignment)
1127{
1128 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001129 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001130}
1131
1132GLint State::getUnpackAlignment() const
1133{
1134 return mUnpack.alignment;
1135}
1136
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001137void State::setUnpackRowLength(GLint rowLength)
1138{
1139 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001140 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001141}
1142
1143GLint State::getUnpackRowLength() const
1144{
1145 return mUnpack.rowLength;
1146}
1147
Shannon Woods53a94a82014-06-24 15:20:36 -04001148const PixelUnpackState &State::getUnpackState() const
1149{
1150 return mUnpack;
1151}
1152
Jamie Madill67102f02015-03-16 10:41:42 -04001153PixelUnpackState &State::getUnpackState()
1154{
1155 return mUnpack;
1156}
1157
Shannon Woods53a94a82014-06-24 15:20:36 -04001158void State::getBooleanv(GLenum pname, GLboolean *params)
1159{
1160 switch (pname)
1161 {
1162 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1163 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1164 case GL_COLOR_WRITEMASK:
1165 params[0] = mBlend.colorMaskRed;
1166 params[1] = mBlend.colorMaskGreen;
1167 params[2] = mBlend.colorMaskBlue;
1168 params[3] = mBlend.colorMaskAlpha;
1169 break;
1170 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1171 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1172 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1173 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1174 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1175 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1176 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1177 case GL_BLEND: *params = mBlend.blend; break;
1178 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001179 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1180 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001181 default:
1182 UNREACHABLE();
1183 break;
1184 }
1185}
1186
1187void State::getFloatv(GLenum pname, GLfloat *params)
1188{
1189 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1190 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1191 // GetIntegerv as its native query function. As it would require conversion in any
1192 // case, this should make no difference to the calling application.
1193 switch (pname)
1194 {
1195 case GL_LINE_WIDTH: *params = mLineWidth; break;
1196 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1197 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1198 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1199 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1200 case GL_DEPTH_RANGE:
1201 params[0] = mNearZ;
1202 params[1] = mFarZ;
1203 break;
1204 case GL_COLOR_CLEAR_VALUE:
1205 params[0] = mColorClearValue.red;
1206 params[1] = mColorClearValue.green;
1207 params[2] = mColorClearValue.blue;
1208 params[3] = mColorClearValue.alpha;
1209 break;
1210 case GL_BLEND_COLOR:
1211 params[0] = mBlendColor.red;
1212 params[1] = mBlendColor.green;
1213 params[2] = mBlendColor.blue;
1214 params[3] = mBlendColor.alpha;
1215 break;
1216 default:
1217 UNREACHABLE();
1218 break;
1219 }
1220}
1221
Jamie Madill48faf802014-11-06 15:27:22 -05001222void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001223{
1224 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1225 {
1226 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001227 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001228 Framebuffer *framebuffer = mDrawFramebuffer;
1229 *params = framebuffer->getDrawBufferState(colorAttachment);
1230 return;
1231 }
1232
1233 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1234 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1235 // GetIntegerv as its native query function. As it would require conversion in any
1236 // case, this should make no difference to the calling application. You may find it in
1237 // State::getFloatv.
1238 switch (pname)
1239 {
1240 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001241 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001242 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1243 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1244 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1245 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1246 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001247 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001248 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1249 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1250 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001251 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001252 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1253 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001254 case GL_ACTIVE_TEXTURE:
1255 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1256 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001257 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1258 case GL_STENCIL_REF: *params = mStencilRef; break;
1259 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1260 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1261 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1262 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1263 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1264 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1265 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1266 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1267 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1268 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1269 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1270 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1271 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1272 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1273 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1274 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1275 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1276 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1277 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1278 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001279 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1280 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001281 case GL_SAMPLE_BUFFERS:
1282 case GL_SAMPLES:
1283 {
1284 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001285 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001286 {
1287 switch (pname)
1288 {
1289 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001290 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001291 {
1292 *params = 1;
1293 }
1294 else
1295 {
1296 *params = 0;
1297 }
1298 break;
1299 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001300 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001301 break;
1302 }
1303 }
1304 else
1305 {
1306 *params = 0;
1307 }
1308 }
1309 break;
1310 case GL_VIEWPORT:
1311 params[0] = mViewport.x;
1312 params[1] = mViewport.y;
1313 params[2] = mViewport.width;
1314 params[3] = mViewport.height;
1315 break;
1316 case GL_SCISSOR_BOX:
1317 params[0] = mScissor.x;
1318 params[1] = mScissor.y;
1319 params[2] = mScissor.width;
1320 params[3] = mScissor.height;
1321 break;
1322 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1323 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1324 case GL_RED_BITS:
1325 case GL_GREEN_BITS:
1326 case GL_BLUE_BITS:
1327 case GL_ALPHA_BITS:
1328 {
1329 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001330 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001331
1332 if (colorbuffer)
1333 {
1334 switch (pname)
1335 {
1336 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1337 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1338 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1339 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1340 }
1341 }
1342 else
1343 {
1344 *params = 0;
1345 }
1346 }
1347 break;
1348 case GL_DEPTH_BITS:
1349 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001350 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1351 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001352
1353 if (depthbuffer)
1354 {
1355 *params = depthbuffer->getDepthSize();
1356 }
1357 else
1358 {
1359 *params = 0;
1360 }
1361 }
1362 break;
1363 case GL_STENCIL_BITS:
1364 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001365 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1366 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001367
1368 if (stencilbuffer)
1369 {
1370 *params = stencilbuffer->getStencilSize();
1371 }
1372 else
1373 {
1374 *params = 0;
1375 }
1376 }
1377 break;
1378 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001379 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001380 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001381 break;
1382 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001383 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001384 *params =
1385 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001386 break;
1387 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001388 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001389 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001390 break;
1391 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001392 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001393 *params =
1394 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001395 break;
1396 case GL_UNIFORM_BUFFER_BINDING:
1397 *params = mGenericUniformBuffer.id();
1398 break;
1399 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001400 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001401 break;
1402 case GL_COPY_READ_BUFFER_BINDING:
1403 *params = mCopyReadBuffer.id();
1404 break;
1405 case GL_COPY_WRITE_BUFFER_BINDING:
1406 *params = mCopyWriteBuffer.id();
1407 break;
1408 case GL_PIXEL_PACK_BUFFER_BINDING:
1409 *params = mPack.pixelBuffer.id();
1410 break;
1411 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1412 *params = mUnpack.pixelBuffer.id();
1413 break;
1414 default:
1415 UNREACHABLE();
1416 break;
1417 }
1418}
1419
1420bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1421{
1422 switch (target)
1423 {
1424 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001425 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001426 {
Geoff Lang045536b2015-03-27 15:17:18 -04001427 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001428 }
1429 break;
1430 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001431 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001432 {
1433 *data = mUniformBuffers[index].id();
1434 }
1435 break;
1436 default:
1437 return false;
1438 }
1439
1440 return true;
1441}
1442
1443bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1444{
1445 switch (target)
1446 {
1447 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001448 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001449 {
Geoff Lang045536b2015-03-27 15:17:18 -04001450 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001451 }
1452 break;
1453 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001454 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001455 {
Geoff Lang045536b2015-03-27 15:17:18 -04001456 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001457 }
1458 break;
1459 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001460 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001461 {
1462 *data = mUniformBuffers[index].getOffset();
1463 }
1464 break;
1465 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001466 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001467 {
1468 *data = mUniformBuffers[index].getSize();
1469 }
1470 break;
1471 default:
1472 return false;
1473 }
1474
1475 return true;
1476}
1477
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001478bool State::hasMappedBuffer(GLenum target) const
1479{
1480 if (target == GL_ARRAY_BUFFER)
1481 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001482 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001483 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001484 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001485 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001486 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001487 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001488 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1489 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1490 {
1491 return true;
1492 }
1493 }
1494
1495 return false;
1496 }
1497 else
1498 {
1499 Buffer *buffer = getTargetBuffer(target);
1500 return (buffer && buffer->isMapped());
1501 }
1502}
1503
Shannon Woods53a94a82014-06-24 15:20:36 -04001504}