blob: 4c923e7d608f0eb12743e65fb40d3b585d90aa18 [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
Jamie Madillc9d442d2016-01-20 11:17:24 -050011#include "common/BitSetIterator.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/Context.h"
13#include "libANGLE/Caps.h"
Geoff Lang70d0f492015-12-10 17:45:46 -050014#include "libANGLE/Debug.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/Framebuffer.h"
16#include "libANGLE/FramebufferAttachment.h"
17#include "libANGLE/Query.h"
18#include "libANGLE/VertexArray.h"
19#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040020
21namespace gl
22{
Geoff Lang76b10c92014-09-05 16:28:14 -040023
Shannon Woods53a94a82014-06-24 15:20:36 -040024State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050025 : mMaxDrawBuffers(0),
26 mMaxCombinedTextureImageUnits(0),
27 mDepthClearValue(0),
28 mStencilClearValue(0),
29 mScissorTest(false),
30 mSampleCoverage(false),
31 mSampleCoverageValue(0),
32 mSampleCoverageInvert(false),
33 mStencilRef(0),
34 mStencilBackRef(0),
35 mLineWidth(0),
36 mGenerateMipmapHint(GL_NONE),
37 mFragmentShaderDerivativeHint(GL_NONE),
38 mNearZ(0),
39 mFarZ(0),
40 mReadFramebuffer(nullptr),
41 mDrawFramebuffer(nullptr),
42 mProgram(nullptr),
43 mVertexArray(nullptr),
44 mActiveSampler(0),
Sami Väisänen74c23472016-05-09 17:30:30 +030045 mPrimitiveRestart(false),
46 mMultiSampling(false),
47 mSampleAlphaToOne(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040048{
Geoff Lang76b10c92014-09-05 16:28:14 -040049}
50
51State::~State()
52{
53 reset();
54}
55
Geoff Lang70d0f492015-12-10 17:45:46 -050056void State::initialize(const Caps &caps,
57 const Extensions &extensions,
58 GLuint clientVersion,
59 bool debug)
Geoff Lang76b10c92014-09-05 16:28:14 -040060{
Shannon Woods2df6a602014-09-26 16:12:07 -040061 mMaxDrawBuffers = caps.maxDrawBuffers;
62 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040063
Jamie Madillf75ab352015-03-16 10:46:52 -040064 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040065
66 mDepthClearValue = 1.0f;
67 mStencilClearValue = 0;
68
69 mRasterizer.rasterizerDiscard = false;
70 mRasterizer.cullFace = false;
71 mRasterizer.cullMode = GL_BACK;
72 mRasterizer.frontFace = GL_CCW;
73 mRasterizer.polygonOffsetFill = false;
74 mRasterizer.polygonOffsetFactor = 0.0f;
75 mRasterizer.polygonOffsetUnits = 0.0f;
76 mRasterizer.pointDrawMode = false;
77 mRasterizer.multiSample = false;
78 mScissorTest = false;
79 mScissor.x = 0;
80 mScissor.y = 0;
81 mScissor.width = 0;
82 mScissor.height = 0;
83
84 mBlend.blend = false;
85 mBlend.sourceBlendRGB = GL_ONE;
86 mBlend.sourceBlendAlpha = GL_ONE;
87 mBlend.destBlendRGB = GL_ZERO;
88 mBlend.destBlendAlpha = GL_ZERO;
89 mBlend.blendEquationRGB = GL_FUNC_ADD;
90 mBlend.blendEquationAlpha = GL_FUNC_ADD;
91 mBlend.sampleAlphaToCoverage = false;
92 mBlend.dither = true;
93
94 mBlendColor.red = 0;
95 mBlendColor.green = 0;
96 mBlendColor.blue = 0;
97 mBlendColor.alpha = 0;
98
99 mDepthStencil.depthTest = false;
100 mDepthStencil.depthFunc = GL_LESS;
101 mDepthStencil.depthMask = true;
102 mDepthStencil.stencilTest = false;
103 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700104 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
105 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400106 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700107 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
108 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400109 mDepthStencil.stencilFail = GL_KEEP;
110 mDepthStencil.stencilPassDepthFail = GL_KEEP;
111 mDepthStencil.stencilPassDepthPass = GL_KEEP;
112 mDepthStencil.stencilBackFail = GL_KEEP;
113 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
114 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
115
116 mStencilRef = 0;
117 mStencilBackRef = 0;
118
119 mSampleCoverage = false;
120 mSampleCoverageValue = 1.0f;
121 mSampleCoverageInvert = false;
122 mGenerateMipmapHint = GL_DONT_CARE;
123 mFragmentShaderDerivativeHint = GL_DONT_CARE;
124
125 mLineWidth = 1.0f;
126
127 mViewport.x = 0;
128 mViewport.y = 0;
129 mViewport.width = 0;
130 mViewport.height = 0;
131 mNearZ = 0.0f;
132 mFarZ = 1.0f;
133
134 mBlend.colorMaskRed = true;
135 mBlend.colorMaskGreen = true;
136 mBlend.colorMaskBlue = true;
137 mBlend.colorMaskAlpha = true;
138
Geoff Lang76b10c92014-09-05 16:28:14 -0400139 mActiveSampler = 0;
140
Shannon Woods23e05002014-09-22 19:07:27 -0400141 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400142
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400143 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
144
Geoff Lang76b10c92014-09-05 16:28:14 -0400145 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
146 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
147 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400148 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 // TODO: These could also be enabled via extension
150 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
151 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400152 }
Ian Ewellbda75592016-04-18 17:25:54 -0400153 if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
154 {
155 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
156 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400157
Geoff Lang76b10c92014-09-05 16:28:14 -0400158 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400159
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500160 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
161 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
162 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
163 mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
Geoff Lang2b4ce802016-04-28 13:34:50 -0400164 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400165
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500166 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400167
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500168 mReadFramebuffer = nullptr;
169 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500170
171 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500172
173 mDebug.setOutputEnabled(debug);
174 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300175
176 if (extensions.framebufferMultisample)
177 {
178 mMultiSampling = true;
179 mSampleAlphaToOne = false;
180 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400181}
182
Geoff Lang76b10c92014-09-05 16:28:14 -0400183void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400184{
Geoff Lang76b10c92014-09-05 16:28:14 -0400185 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400186 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400187 TextureBindingVector &textureVector = bindingVec->second;
188 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400189 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400190 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400191 }
192 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400193 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
194 {
195 mSamplers[samplerIdx].set(NULL);
196 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400197
Shannon Woods53a94a82014-06-24 15:20:36 -0400198 mArrayBuffer.set(NULL);
199 mRenderbuffer.set(NULL);
200
Geoff Lang7dd2e102014-11-10 15:19:26 -0500201 if (mProgram)
202 {
203 mProgram->release();
204 }
205 mProgram = NULL;
206
Shannon Woods53a94a82014-06-24 15:20:36 -0400207 mTransformFeedback.set(NULL);
208
209 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
210 {
211 i->second.set(NULL);
212 }
213
214 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400215 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400216 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400217 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400218 }
219
Shannon Woods53a94a82014-06-24 15:20:36 -0400220 mCopyReadBuffer.set(NULL);
221 mCopyWriteBuffer.set(NULL);
222
223 mPack.pixelBuffer.set(NULL);
224 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500225
226 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400227
228 // TODO(jmadill): Is this necessary?
229 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400230}
231
232const RasterizerState &State::getRasterizerState() const
233{
234 return mRasterizer;
235}
236
237const BlendState &State::getBlendState() const
238{
239 return mBlend;
240}
241
242const DepthStencilState &State::getDepthStencilState() const
243{
244 return mDepthStencil;
245}
246
Jamie Madillf75ab352015-03-16 10:46:52 -0400247void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400248{
249 mColorClearValue.red = red;
250 mColorClearValue.green = green;
251 mColorClearValue.blue = blue;
252 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400253 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400254}
255
Jamie Madillf75ab352015-03-16 10:46:52 -0400256void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400257{
258 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400259 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400260}
261
Jamie Madillf75ab352015-03-16 10:46:52 -0400262void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400263{
264 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400265 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400266}
267
Shannon Woods53a94a82014-06-24 15:20:36 -0400268void State::setColorMask(bool red, bool green, bool blue, bool alpha)
269{
270 mBlend.colorMaskRed = red;
271 mBlend.colorMaskGreen = green;
272 mBlend.colorMaskBlue = blue;
273 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400274 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400275}
276
277void State::setDepthMask(bool mask)
278{
279 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400280 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400281}
282
283bool State::isRasterizerDiscardEnabled() const
284{
285 return mRasterizer.rasterizerDiscard;
286}
287
288void State::setRasterizerDiscard(bool enabled)
289{
290 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400291 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400292}
293
294bool State::isCullFaceEnabled() const
295{
296 return mRasterizer.cullFace;
297}
298
299void State::setCullFace(bool enabled)
300{
301 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400302 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400303}
304
305void State::setCullMode(GLenum mode)
306{
307 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400308 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400309}
310
311void State::setFrontFace(GLenum front)
312{
313 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400314 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400315}
316
317bool State::isDepthTestEnabled() const
318{
319 return mDepthStencil.depthTest;
320}
321
322void State::setDepthTest(bool enabled)
323{
324 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400325 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400326}
327
328void State::setDepthFunc(GLenum depthFunc)
329{
330 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400331 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400332}
333
334void State::setDepthRange(float zNear, float zFar)
335{
336 mNearZ = zNear;
337 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400338 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400339}
340
Geoff Langd42f5b82015-04-16 14:03:29 -0400341float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400342{
Geoff Langd42f5b82015-04-16 14:03:29 -0400343 return mNearZ;
344}
345
346float State::getFarPlane() const
347{
348 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400349}
350
351bool State::isBlendEnabled() const
352{
353 return mBlend.blend;
354}
355
356void State::setBlend(bool enabled)
357{
358 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400359 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400360}
361
362void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
363{
364 mBlend.sourceBlendRGB = sourceRGB;
365 mBlend.destBlendRGB = destRGB;
366 mBlend.sourceBlendAlpha = sourceAlpha;
367 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400368 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400369}
370
371void State::setBlendColor(float red, float green, float blue, float alpha)
372{
373 mBlendColor.red = red;
374 mBlendColor.green = green;
375 mBlendColor.blue = blue;
376 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400377 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400378}
379
380void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
381{
382 mBlend.blendEquationRGB = rgbEquation;
383 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400384 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400385}
386
387const ColorF &State::getBlendColor() const
388{
389 return mBlendColor;
390}
391
392bool State::isStencilTestEnabled() const
393{
394 return mDepthStencil.stencilTest;
395}
396
397void State::setStencilTest(bool enabled)
398{
399 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400400 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400401}
402
403void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
404{
405 mDepthStencil.stencilFunc = stencilFunc;
406 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
407 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400408 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400409}
410
411void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
412{
413 mDepthStencil.stencilBackFunc = stencilBackFunc;
414 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
415 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400416 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400417}
418
419void State::setStencilWritemask(GLuint stencilWritemask)
420{
421 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400422 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400423}
424
425void State::setStencilBackWritemask(GLuint stencilBackWritemask)
426{
427 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400428 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400429}
430
431void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
432{
433 mDepthStencil.stencilFail = stencilFail;
434 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
435 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400436 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400437}
438
439void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
440{
441 mDepthStencil.stencilBackFail = stencilBackFail;
442 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
443 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400444 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400445}
446
447GLint State::getStencilRef() const
448{
449 return mStencilRef;
450}
451
452GLint State::getStencilBackRef() const
453{
454 return mStencilBackRef;
455}
456
457bool State::isPolygonOffsetFillEnabled() const
458{
459 return mRasterizer.polygonOffsetFill;
460}
461
462void State::setPolygonOffsetFill(bool enabled)
463{
Jamie Madill1b94d432015-08-07 13:23:23 -0400464 mRasterizer.polygonOffsetFill = enabled;
465 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400466}
467
468void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
469{
470 // An application can pass NaN values here, so handle this gracefully
471 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
472 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400473 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400474}
475
476bool State::isSampleAlphaToCoverageEnabled() const
477{
478 return mBlend.sampleAlphaToCoverage;
479}
480
481void State::setSampleAlphaToCoverage(bool enabled)
482{
483 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400484 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400485}
486
487bool State::isSampleCoverageEnabled() const
488{
489 return mSampleCoverage;
490}
491
492void State::setSampleCoverage(bool enabled)
493{
494 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400495 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400496}
497
498void State::setSampleCoverageParams(GLclampf value, bool invert)
499{
500 mSampleCoverageValue = value;
501 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400502 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400503}
504
Geoff Lang0fbb6002015-04-16 11:11:53 -0400505GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400506{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400507 return mSampleCoverageValue;
508}
Shannon Woods53a94a82014-06-24 15:20:36 -0400509
Geoff Lang0fbb6002015-04-16 11:11:53 -0400510bool State::getSampleCoverageInvert() const
511{
512 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400513}
514
Sami Väisänen74c23472016-05-09 17:30:30 +0300515void State::setSampleAlphaToOne(bool enabled)
516{
517 mSampleAlphaToOne = enabled;
518 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
519}
520
521bool State::isSampleAlphaToOneEnabled() const
522{
523 return mSampleAlphaToOne;
524}
525
526void State::setMultisampling(bool enabled)
527{
528 mMultiSampling = enabled;
529 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
530}
531
532bool State::isMultisamplingEnabled() const
533{
534 return mMultiSampling;
535}
536
Shannon Woods53a94a82014-06-24 15:20:36 -0400537bool State::isScissorTestEnabled() const
538{
539 return mScissorTest;
540}
541
542void State::setScissorTest(bool enabled)
543{
544 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400545 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400546}
547
548void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
549{
550 mScissor.x = x;
551 mScissor.y = y;
552 mScissor.width = width;
553 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400554 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400555}
556
557const Rectangle &State::getScissor() const
558{
559 return mScissor;
560}
561
562bool State::isDitherEnabled() const
563{
564 return mBlend.dither;
565}
566
567void State::setDither(bool enabled)
568{
569 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400570 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400571}
572
Jamie Madillb4b53c52015-02-03 15:22:48 -0500573bool State::isPrimitiveRestartEnabled() const
574{
575 return mPrimitiveRestart;
576}
577
578void State::setPrimitiveRestart(bool enabled)
579{
580 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400581 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500582}
583
Shannon Woods53a94a82014-06-24 15:20:36 -0400584void State::setEnableFeature(GLenum feature, bool enabled)
585{
586 switch (feature)
587 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300588 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
589 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400590 case GL_CULL_FACE: setCullFace(enabled); break;
591 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
592 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
593 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
594 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
595 case GL_STENCIL_TEST: setStencilTest(enabled); break;
596 case GL_DEPTH_TEST: setDepthTest(enabled); break;
597 case GL_BLEND: setBlend(enabled); break;
598 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500599 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400600 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500601 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
602 mDebug.setOutputSynchronous(enabled);
603 break;
604 case GL_DEBUG_OUTPUT:
605 mDebug.setOutputEnabled(enabled);
606 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400607 default: UNREACHABLE();
608 }
609}
610
611bool State::getEnableFeature(GLenum feature)
612{
613 switch (feature)
614 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300615 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
616 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400617 case GL_CULL_FACE: return isCullFaceEnabled();
618 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
619 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
620 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
621 case GL_SCISSOR_TEST: return isScissorTestEnabled();
622 case GL_STENCIL_TEST: return isStencilTestEnabled();
623 case GL_DEPTH_TEST: return isDepthTestEnabled();
624 case GL_BLEND: return isBlendEnabled();
625 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500626 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400627 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Lang70d0f492015-12-10 17:45:46 -0500628 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
629 return mDebug.isOutputSynchronous();
630 case GL_DEBUG_OUTPUT:
631 return mDebug.isOutputEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400632 default: UNREACHABLE(); return false;
633 }
634}
635
636void State::setLineWidth(GLfloat width)
637{
638 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400639 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400640}
641
Geoff Lang4b3f4162015-04-16 13:22:05 -0400642float State::getLineWidth() const
643{
644 return mLineWidth;
645}
646
Shannon Woods53a94a82014-06-24 15:20:36 -0400647void State::setGenerateMipmapHint(GLenum hint)
648{
649 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400650 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400651}
652
653void State::setFragmentShaderDerivativeHint(GLenum hint)
654{
655 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400656 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400657 // TODO: Propagate the hint to shader translator so we can write
658 // ddx, ddx_coarse, or ddx_fine depending on the hint.
659 // Ignore for now. It is valid for implementations to ignore hint.
660}
661
662void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
663{
664 mViewport.x = x;
665 mViewport.y = y;
666 mViewport.width = width;
667 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400668 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400669}
670
671const Rectangle &State::getViewport() const
672{
673 return mViewport;
674}
675
676void State::setActiveSampler(unsigned int active)
677{
678 mActiveSampler = active;
679}
680
681unsigned int State::getActiveSampler() const
682{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700683 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400684}
685
Geoff Lang76b10c92014-09-05 16:28:14 -0400686void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400687{
Geoff Lang76b10c92014-09-05 16:28:14 -0400688 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400689}
690
Jamie Madillc29968b2016-01-20 11:17:23 -0500691Texture *State::getTargetTexture(GLenum target) const
692{
693 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
694}
695
Geoff Lang76b10c92014-09-05 16:28:14 -0400696Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400697{
Jamie Madill5864ac22015-01-12 14:43:07 -0500698 const auto it = mSamplerTextures.find(type);
699 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400700 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500701 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400702}
703
Geoff Lang76b10c92014-09-05 16:28:14 -0400704GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400705{
Jamie Madill5864ac22015-01-12 14:43:07 -0500706 const auto it = mSamplerTextures.find(type);
707 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400708 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500709 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400710}
711
Jamie Madille6382c32014-11-07 15:05:26 -0500712void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400713{
714 // Textures have a detach method on State rather than a simple
715 // removeBinding, because the zero/null texture objects are managed
716 // separately, and don't have to go through the Context's maps or
717 // the ResourceManager.
718
719 // [OpenGL ES 2.0.24] section 3.8 page 84:
720 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
721 // rebound to texture object zero
722
Corentin Walleza2257da2016-04-19 16:43:12 -0400723 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400724 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400725 GLenum textureType = bindingVec.first;
726 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400727 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400728 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400729 BindingPointer<Texture> &binding = textureVector[textureIdx];
730 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400731 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500732 auto it = zeroTextures.find(textureType);
733 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500734 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500735 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400736 }
737 }
738 }
739
740 // [OpenGL ES 2.0.24] section 4.4 page 112:
741 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
742 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
743 // image was attached in the currently bound framebuffer.
744
745 if (mReadFramebuffer)
746 {
747 mReadFramebuffer->detachTexture(texture);
748 }
749
750 if (mDrawFramebuffer)
751 {
752 mDrawFramebuffer->detachTexture(texture);
753 }
754}
755
Jamie Madille6382c32014-11-07 15:05:26 -0500756void State::initializeZeroTextures(const TextureMap &zeroTextures)
757{
758 for (const auto &zeroTexture : zeroTextures)
759 {
760 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
761
762 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
763 {
764 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
765 }
766 }
767}
768
Shannon Woods53a94a82014-06-24 15:20:36 -0400769void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
770{
771 mSamplers[textureUnit].set(sampler);
772}
773
774GLuint State::getSamplerId(GLuint textureUnit) const
775{
Geoff Lang76b10c92014-09-05 16:28:14 -0400776 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400777 return mSamplers[textureUnit].id();
778}
779
780Sampler *State::getSampler(GLuint textureUnit) const
781{
782 return mSamplers[textureUnit].get();
783}
784
785void State::detachSampler(GLuint sampler)
786{
787 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
788 // If a sampler object that is currently bound to one or more texture units is
789 // deleted, it is as though BindSampler is called once for each texture unit to
790 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400791 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400792 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400793 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
794 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400795 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400796 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400797 }
798 }
799}
800
801void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
802{
803 mRenderbuffer.set(renderbuffer);
804}
805
806GLuint State::getRenderbufferId() const
807{
808 return mRenderbuffer.id();
809}
810
811Renderbuffer *State::getCurrentRenderbuffer()
812{
813 return mRenderbuffer.get();
814}
815
816void State::detachRenderbuffer(GLuint renderbuffer)
817{
818 // [OpenGL ES 2.0.24] section 4.4 page 109:
819 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
820 // had been executed with the target RENDERBUFFER and name of zero.
821
822 if (mRenderbuffer.id() == renderbuffer)
823 {
824 mRenderbuffer.set(NULL);
825 }
826
827 // [OpenGL ES 2.0.24] section 4.4 page 111:
828 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
829 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
830 // point to which this image was attached in the currently bound framebuffer.
831
832 Framebuffer *readFramebuffer = mReadFramebuffer;
833 Framebuffer *drawFramebuffer = mDrawFramebuffer;
834
835 if (readFramebuffer)
836 {
837 readFramebuffer->detachRenderbuffer(renderbuffer);
838 }
839
840 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
841 {
842 drawFramebuffer->detachRenderbuffer(renderbuffer);
843 }
844
845}
846
847void State::setReadFramebufferBinding(Framebuffer *framebuffer)
848{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500849 if (mReadFramebuffer == framebuffer)
850 return;
851
Shannon Woods53a94a82014-06-24 15:20:36 -0400852 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500853 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
854
855 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
856 {
857 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
858 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400859}
860
861void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
862{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500863 if (mDrawFramebuffer == framebuffer)
864 return;
865
Shannon Woods53a94a82014-06-24 15:20:36 -0400866 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500867 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
868
869 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
870 {
871 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
872 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400873}
874
875Framebuffer *State::getTargetFramebuffer(GLenum target) const
876{
877 switch (target)
878 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500879 case GL_READ_FRAMEBUFFER_ANGLE:
880 return mReadFramebuffer;
881 case GL_DRAW_FRAMEBUFFER_ANGLE:
882 case GL_FRAMEBUFFER:
883 return mDrawFramebuffer;
884 default:
885 UNREACHABLE();
886 return NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400887 }
888}
889
890Framebuffer *State::getReadFramebuffer()
891{
892 return mReadFramebuffer;
893}
894
895Framebuffer *State::getDrawFramebuffer()
896{
897 return mDrawFramebuffer;
898}
899
900const Framebuffer *State::getReadFramebuffer() const
901{
902 return mReadFramebuffer;
903}
904
905const Framebuffer *State::getDrawFramebuffer() const
906{
907 return mDrawFramebuffer;
908}
909
910bool State::removeReadFramebufferBinding(GLuint framebuffer)
911{
Jamie Madill77a72f62015-04-14 11:18:32 -0400912 if (mReadFramebuffer != nullptr &&
913 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400914 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500915 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400916 return true;
917 }
918
919 return false;
920}
921
922bool State::removeDrawFramebufferBinding(GLuint framebuffer)
923{
Jamie Madill77a72f62015-04-14 11:18:32 -0400924 if (mReadFramebuffer != nullptr &&
925 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400926 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500927 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400928 return true;
929 }
930
931 return false;
932}
933
934void State::setVertexArrayBinding(VertexArray *vertexArray)
935{
936 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000937 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500938
939 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
940 {
941 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
942 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400943}
944
945GLuint State::getVertexArrayId() const
946{
947 ASSERT(mVertexArray != NULL);
948 return mVertexArray->id();
949}
950
951VertexArray *State::getVertexArray() const
952{
953 ASSERT(mVertexArray != NULL);
954 return mVertexArray;
955}
956
957bool State::removeVertexArrayBinding(GLuint vertexArray)
958{
959 if (mVertexArray->id() == vertexArray)
960 {
961 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000962 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500963 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -0400964 return true;
965 }
966
967 return false;
968}
969
Geoff Lang7dd2e102014-11-10 15:19:26 -0500970void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400971{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500972 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400973 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500974 if (mProgram)
975 {
976 mProgram->release();
977 }
978
979 mProgram = newProgram;
980
981 if (mProgram)
982 {
983 newProgram->addRef();
984 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400985 }
986}
987
Geoff Lang7dd2e102014-11-10 15:19:26 -0500988Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400989{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500990 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400991}
992
993void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
994{
995 mTransformFeedback.set(transformFeedback);
996}
997
998TransformFeedback *State::getCurrentTransformFeedback() const
999{
1000 return mTransformFeedback.get();
1001}
1002
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001003bool State::isTransformFeedbackActiveUnpaused() const
1004{
1005 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001006 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001007}
1008
Corentin Walleza2257da2016-04-19 16:43:12 -04001009bool State::removeTransformFeedbackBinding(GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001010{
1011 if (mTransformFeedback.id() == transformFeedback)
1012 {
Corentin Walleza2257da2016-04-19 16:43:12 -04001013 mTransformFeedback.set(nullptr);
1014 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001015 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001016
1017 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001018}
1019
Corentin Walleze71ea192016-04-19 13:16:37 -04001020bool State::isQueryActive(GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001021{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001022 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001023 {
Corentin Walleze71ea192016-04-19 13:16:37 -04001024 Query *query = iter.second.get();
1025 if (query != nullptr && query->getType() == type)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001026 {
1027 return true;
1028 }
1029 }
1030
1031 return false;
1032}
1033
1034bool State::isQueryActive(Query *query) const
1035{
1036 for (auto &iter : mActiveQueries)
1037 {
1038 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001039 {
1040 return true;
1041 }
1042 }
1043
1044 return false;
1045}
1046
1047void State::setActiveQuery(GLenum target, Query *query)
1048{
1049 mActiveQueries[target].set(query);
1050}
1051
1052GLuint State::getActiveQueryId(GLenum target) const
1053{
1054 const Query *query = getActiveQuery(target);
1055 return (query ? query->id() : 0u);
1056}
1057
1058Query *State::getActiveQuery(GLenum target) const
1059{
Jamie Madill5864ac22015-01-12 14:43:07 -05001060 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001061
Jamie Madill5864ac22015-01-12 14:43:07 -05001062 // All query types should already exist in the activeQueries map
1063 ASSERT(it != mActiveQueries.end());
1064
1065 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001066}
1067
1068void State::setArrayBufferBinding(Buffer *buffer)
1069{
1070 mArrayBuffer.set(buffer);
1071}
1072
1073GLuint State::getArrayBufferId() const
1074{
1075 return mArrayBuffer.id();
1076}
1077
Shannon Woods53a94a82014-06-24 15:20:36 -04001078void State::setGenericUniformBufferBinding(Buffer *buffer)
1079{
1080 mGenericUniformBuffer.set(buffer);
1081}
1082
1083void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1084{
1085 mUniformBuffers[index].set(buffer, offset, size);
1086}
1087
Geoff Lang5d124a62015-09-15 13:03:27 -04001088const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001089{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001090 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001091 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001092}
1093
Shannon Woods53a94a82014-06-24 15:20:36 -04001094void State::setCopyReadBufferBinding(Buffer *buffer)
1095{
1096 mCopyReadBuffer.set(buffer);
1097}
1098
1099void State::setCopyWriteBufferBinding(Buffer *buffer)
1100{
1101 mCopyWriteBuffer.set(buffer);
1102}
1103
1104void State::setPixelPackBufferBinding(Buffer *buffer)
1105{
1106 mPack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001107 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001108}
1109
1110void State::setPixelUnpackBufferBinding(Buffer *buffer)
1111{
1112 mUnpack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001113 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001114}
1115
1116Buffer *State::getTargetBuffer(GLenum target) const
1117{
1118 switch (target)
1119 {
1120 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1121 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1122 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001123 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001124 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1125 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001126 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001127 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1128 default: UNREACHABLE(); return NULL;
1129 }
1130}
1131
Yuly Novikov5807a532015-12-03 13:01:22 -05001132void State::detachBuffer(GLuint bufferName)
1133{
1134 BindingPointer<Buffer> *buffers[] = {&mArrayBuffer, &mCopyReadBuffer,
1135 &mCopyWriteBuffer, &mPack.pixelBuffer,
1136 &mUnpack.pixelBuffer, &mGenericUniformBuffer};
1137 for (auto buffer : buffers)
1138 {
1139 if (buffer->id() == bufferName)
1140 {
1141 buffer->set(nullptr);
1142 }
1143 }
1144
1145 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1146 if (curTransformFeedback)
1147 {
1148 curTransformFeedback->detachBuffer(bufferName);
1149 }
1150
1151 getVertexArray()->detachBuffer(bufferName);
1152}
1153
Shannon Woods53a94a82014-06-24 15:20:36 -04001154void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1155{
1156 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001157 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001158}
1159
1160void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1161{
Shannon Woods23e05002014-09-22 19:07:27 -04001162 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001163 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001164 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001165}
1166
1167void State::setVertexAttribu(GLuint index, const GLuint values[4])
1168{
Shannon Woods23e05002014-09-22 19:07:27 -04001169 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001170 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001171 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001172}
1173
1174void State::setVertexAttribi(GLuint index, const GLint values[4])
1175{
Shannon Woods23e05002014-09-22 19:07:27 -04001176 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001177 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001178 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001179}
1180
Jamie Madill0b9e9032015-08-17 11:51:52 +00001181void State::setVertexAttribState(unsigned int attribNum,
1182 Buffer *boundBuffer,
1183 GLint size,
1184 GLenum type,
1185 bool normalized,
1186 bool pureInteger,
1187 GLsizei stride,
1188 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001189{
1190 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001191 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001192}
1193
1194void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1195{
1196 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001197 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001198}
1199
Shannon Woods53a94a82014-06-24 15:20:36 -04001200const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1201{
Shannon Woods23e05002014-09-22 19:07:27 -04001202 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001203 return mVertexAttribCurrentValues[attribNum];
1204}
1205
Shannon Woods53a94a82014-06-24 15:20:36 -04001206const void *State::getVertexAttribPointer(unsigned int attribNum) const
1207{
1208 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1209}
1210
1211void State::setPackAlignment(GLint alignment)
1212{
1213 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001214 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001215}
1216
1217GLint State::getPackAlignment() const
1218{
1219 return mPack.alignment;
1220}
1221
1222void State::setPackReverseRowOrder(bool reverseRowOrder)
1223{
1224 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001225 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001226}
1227
1228bool State::getPackReverseRowOrder() const
1229{
1230 return mPack.reverseRowOrder;
1231}
1232
Minmin Gongadff67b2015-10-14 10:34:45 -04001233void State::setPackRowLength(GLint rowLength)
1234{
1235 mPack.rowLength = rowLength;
1236 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1237}
1238
1239GLint State::getPackRowLength() const
1240{
1241 return mPack.rowLength;
1242}
1243
1244void State::setPackSkipRows(GLint skipRows)
1245{
1246 mPack.skipRows = skipRows;
1247 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1248}
1249
1250GLint State::getPackSkipRows() const
1251{
1252 return mPack.skipRows;
1253}
1254
1255void State::setPackSkipPixels(GLint skipPixels)
1256{
1257 mPack.skipPixels = skipPixels;
1258 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1259}
1260
1261GLint State::getPackSkipPixels() const
1262{
1263 return mPack.skipPixels;
1264}
1265
Shannon Woods53a94a82014-06-24 15:20:36 -04001266const PixelPackState &State::getPackState() const
1267{
1268 return mPack;
1269}
1270
Jamie Madill87de3622015-03-16 10:41:44 -04001271PixelPackState &State::getPackState()
1272{
1273 return mPack;
1274}
1275
Shannon Woods53a94a82014-06-24 15:20:36 -04001276void State::setUnpackAlignment(GLint alignment)
1277{
1278 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001279 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001280}
1281
1282GLint State::getUnpackAlignment() const
1283{
1284 return mUnpack.alignment;
1285}
1286
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001287void State::setUnpackRowLength(GLint rowLength)
1288{
1289 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001290 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001291}
1292
1293GLint State::getUnpackRowLength() const
1294{
1295 return mUnpack.rowLength;
1296}
1297
Minmin Gongadff67b2015-10-14 10:34:45 -04001298void State::setUnpackImageHeight(GLint imageHeight)
1299{
1300 mUnpack.imageHeight = imageHeight;
1301 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1302}
1303
1304GLint State::getUnpackImageHeight() const
1305{
1306 return mUnpack.imageHeight;
1307}
1308
1309void State::setUnpackSkipImages(GLint skipImages)
1310{
1311 mUnpack.skipImages = skipImages;
1312 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1313}
1314
1315GLint State::getUnpackSkipImages() const
1316{
1317 return mUnpack.skipImages;
1318}
1319
1320void State::setUnpackSkipRows(GLint skipRows)
1321{
1322 mUnpack.skipRows = skipRows;
1323 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1324}
1325
1326GLint State::getUnpackSkipRows() const
1327{
1328 return mUnpack.skipRows;
1329}
1330
1331void State::setUnpackSkipPixels(GLint skipPixels)
1332{
1333 mUnpack.skipPixels = skipPixels;
1334 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1335}
1336
1337GLint State::getUnpackSkipPixels() const
1338{
1339 return mUnpack.skipPixels;
1340}
1341
Shannon Woods53a94a82014-06-24 15:20:36 -04001342const PixelUnpackState &State::getUnpackState() const
1343{
1344 return mUnpack;
1345}
1346
Jamie Madill67102f02015-03-16 10:41:42 -04001347PixelUnpackState &State::getUnpackState()
1348{
1349 return mUnpack;
1350}
1351
Geoff Lang70d0f492015-12-10 17:45:46 -05001352const Debug &State::getDebug() const
1353{
1354 return mDebug;
1355}
1356
1357Debug &State::getDebug()
1358{
1359 return mDebug;
1360}
1361
Shannon Woods53a94a82014-06-24 15:20:36 -04001362void State::getBooleanv(GLenum pname, GLboolean *params)
1363{
1364 switch (pname)
1365 {
1366 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1367 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1368 case GL_COLOR_WRITEMASK:
1369 params[0] = mBlend.colorMaskRed;
1370 params[1] = mBlend.colorMaskGreen;
1371 params[2] = mBlend.colorMaskBlue;
1372 params[3] = mBlend.colorMaskAlpha;
1373 break;
1374 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1375 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1376 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1377 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1378 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1379 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1380 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1381 case GL_BLEND: *params = mBlend.blend; break;
1382 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001383 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1384 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001385 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1386 *params = mPrimitiveRestart;
1387 break;
Geoff Langab831f02015-12-01 09:39:10 -05001388 case GL_RASTERIZER_DISCARD:
1389 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1390 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001391 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1392 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1393 break;
1394 case GL_DEBUG_OUTPUT:
1395 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1396 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001397 case GL_MULTISAMPLE_EXT:
1398 *params = mMultiSampling;
1399 break;
1400 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1401 *params = mSampleAlphaToOne;
1402 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001403 default:
1404 UNREACHABLE();
1405 break;
1406 }
1407}
1408
1409void State::getFloatv(GLenum pname, GLfloat *params)
1410{
1411 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1412 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1413 // GetIntegerv as its native query function. As it would require conversion in any
1414 // case, this should make no difference to the calling application.
1415 switch (pname)
1416 {
1417 case GL_LINE_WIDTH: *params = mLineWidth; break;
1418 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1419 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1420 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1421 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1422 case GL_DEPTH_RANGE:
1423 params[0] = mNearZ;
1424 params[1] = mFarZ;
1425 break;
1426 case GL_COLOR_CLEAR_VALUE:
1427 params[0] = mColorClearValue.red;
1428 params[1] = mColorClearValue.green;
1429 params[2] = mColorClearValue.blue;
1430 params[3] = mColorClearValue.alpha;
1431 break;
1432 case GL_BLEND_COLOR:
1433 params[0] = mBlendColor.red;
1434 params[1] = mBlendColor.green;
1435 params[2] = mBlendColor.blue;
1436 params[3] = mBlendColor.alpha;
1437 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001438 case GL_MULTISAMPLE_EXT:
1439 *params = static_cast<GLfloat>(mMultiSampling);
1440 break;
1441 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1442 *params = static_cast<GLfloat>(mSampleAlphaToOne);
1443 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001444 default:
1445 UNREACHABLE();
1446 break;
1447 }
1448}
1449
Jamie Madill9082b982016-04-27 15:21:51 -04001450void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001451{
1452 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1453 {
1454 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001455 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001456 Framebuffer *framebuffer = mDrawFramebuffer;
1457 *params = framebuffer->getDrawBufferState(colorAttachment);
1458 return;
1459 }
1460
1461 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1462 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1463 // GetIntegerv as its native query function. As it would require conversion in any
1464 // case, this should make no difference to the calling application. You may find it in
1465 // State::getFloatv.
1466 switch (pname)
1467 {
1468 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001469 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001470 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1471 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1472 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1473 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1474 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001475 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001476 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1477 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001478 case GL_PACK_ROW_LENGTH:
1479 *params = mPack.rowLength;
1480 break;
1481 case GL_PACK_SKIP_ROWS:
1482 *params = mPack.skipRows;
1483 break;
1484 case GL_PACK_SKIP_PIXELS:
1485 *params = mPack.skipPixels;
1486 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001487 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001488 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001489 case GL_UNPACK_IMAGE_HEIGHT:
1490 *params = mUnpack.imageHeight;
1491 break;
1492 case GL_UNPACK_SKIP_IMAGES:
1493 *params = mUnpack.skipImages;
1494 break;
1495 case GL_UNPACK_SKIP_ROWS:
1496 *params = mUnpack.skipRows;
1497 break;
1498 case GL_UNPACK_SKIP_PIXELS:
1499 *params = mUnpack.skipPixels;
1500 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001501 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1502 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001503 case GL_ACTIVE_TEXTURE:
1504 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1505 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001506 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1507 case GL_STENCIL_REF: *params = mStencilRef; break;
1508 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1509 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1510 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1511 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1512 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1513 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1514 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1515 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1516 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1517 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1518 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1519 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1520 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1521 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1522 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1523 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1524 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1525 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1526 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1527 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001528 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1529 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001530 case GL_SAMPLE_BUFFERS:
1531 case GL_SAMPLES:
1532 {
1533 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001534 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001535 {
1536 switch (pname)
1537 {
1538 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001539 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001540 {
1541 *params = 1;
1542 }
1543 else
1544 {
1545 *params = 0;
1546 }
1547 break;
1548 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001549 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001550 break;
1551 }
1552 }
1553 else
1554 {
1555 *params = 0;
1556 }
1557 }
1558 break;
1559 case GL_VIEWPORT:
1560 params[0] = mViewport.x;
1561 params[1] = mViewport.y;
1562 params[2] = mViewport.width;
1563 params[3] = mViewport.height;
1564 break;
1565 case GL_SCISSOR_BOX:
1566 params[0] = mScissor.x;
1567 params[1] = mScissor.y;
1568 params[2] = mScissor.width;
1569 params[3] = mScissor.height;
1570 break;
1571 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1572 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1573 case GL_RED_BITS:
1574 case GL_GREEN_BITS:
1575 case GL_BLUE_BITS:
1576 case GL_ALPHA_BITS:
1577 {
1578 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001579 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001580
1581 if (colorbuffer)
1582 {
1583 switch (pname)
1584 {
1585 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1586 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1587 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1588 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1589 }
1590 }
1591 else
1592 {
1593 *params = 0;
1594 }
1595 }
1596 break;
1597 case GL_DEPTH_BITS:
1598 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001599 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1600 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001601
1602 if (depthbuffer)
1603 {
1604 *params = depthbuffer->getDepthSize();
1605 }
1606 else
1607 {
1608 *params = 0;
1609 }
1610 }
1611 break;
1612 case GL_STENCIL_BITS:
1613 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001614 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1615 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001616
1617 if (stencilbuffer)
1618 {
1619 *params = stencilbuffer->getStencilSize();
1620 }
1621 else
1622 {
1623 *params = 0;
1624 }
1625 }
1626 break;
1627 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001628 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001629 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001630 break;
1631 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001632 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001633 *params =
1634 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001635 break;
1636 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001637 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001638 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001639 break;
1640 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001641 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001642 *params =
1643 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001644 break;
1645 case GL_UNIFORM_BUFFER_BINDING:
1646 *params = mGenericUniformBuffer.id();
1647 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001648 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001649 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001650 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001651 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001652 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001653 break;
1654 case GL_COPY_READ_BUFFER_BINDING:
1655 *params = mCopyReadBuffer.id();
1656 break;
1657 case GL_COPY_WRITE_BUFFER_BINDING:
1658 *params = mCopyWriteBuffer.id();
1659 break;
1660 case GL_PIXEL_PACK_BUFFER_BINDING:
1661 *params = mPack.pixelBuffer.id();
1662 break;
1663 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1664 *params = mUnpack.pixelBuffer.id();
1665 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02001666 case GL_READ_BUFFER:
1667 *params = mReadFramebuffer->getReadBufferState();
1668 break;
1669 case GL_SAMPLER_BINDING:
1670 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1671 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
1672 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001673 case GL_DEBUG_LOGGED_MESSAGES:
1674 *params = static_cast<GLint>(mDebug.getMessageCount());
1675 break;
1676 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1677 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1678 break;
1679 case GL_DEBUG_GROUP_STACK_DEPTH:
1680 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1681 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001682 case GL_MULTISAMPLE_EXT:
1683 *params = static_cast<GLint>(mMultiSampling);
1684 break;
1685 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1686 *params = static_cast<GLint>(mSampleAlphaToOne);
1687 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001688 default:
1689 UNREACHABLE();
1690 break;
1691 }
1692}
1693
Geoff Lang70d0f492015-12-10 17:45:46 -05001694void State::getPointerv(GLenum pname, void **params) const
1695{
1696 switch (pname)
1697 {
1698 case GL_DEBUG_CALLBACK_FUNCTION:
1699 *params = reinterpret_cast<void *>(mDebug.getCallback());
1700 break;
1701 case GL_DEBUG_CALLBACK_USER_PARAM:
1702 *params = const_cast<void *>(mDebug.getUserParam());
1703 break;
1704 default:
1705 UNREACHABLE();
1706 break;
1707 }
1708}
1709
Shannon Woods53a94a82014-06-24 15:20:36 -04001710bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1711{
1712 switch (target)
1713 {
1714 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001715 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001716 {
Geoff Lang045536b2015-03-27 15:17:18 -04001717 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001718 }
1719 break;
1720 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001721 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001722 {
1723 *data = mUniformBuffers[index].id();
1724 }
1725 break;
1726 default:
1727 return false;
1728 }
1729
1730 return true;
1731}
1732
1733bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1734{
1735 switch (target)
1736 {
1737 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001738 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001739 {
Geoff Lang045536b2015-03-27 15:17:18 -04001740 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001741 }
1742 break;
1743 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001744 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001745 {
Geoff Lang045536b2015-03-27 15:17:18 -04001746 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001747 }
1748 break;
1749 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001750 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001751 {
1752 *data = mUniformBuffers[index].getOffset();
1753 }
1754 break;
1755 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001756 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001757 {
1758 *data = mUniformBuffers[index].getSize();
1759 }
1760 break;
1761 default:
1762 return false;
1763 }
1764
1765 return true;
1766}
1767
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001768bool State::hasMappedBuffer(GLenum target) const
1769{
1770 if (target == GL_ARRAY_BUFFER)
1771 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001772 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001773 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001774 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001775 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001776 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001777 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001778 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1779 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1780 {
1781 return true;
1782 }
1783 }
1784
1785 return false;
1786 }
1787 else
1788 {
1789 Buffer *buffer = getTargetBuffer(target);
1790 return (buffer && buffer->isMapped());
1791 }
1792}
1793
Jamie Madillc9d442d2016-01-20 11:17:24 -05001794void State::syncDirtyObjects()
1795{
1796 if (!mDirtyObjects.any())
1797 return;
1798
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001799 syncDirtyObjects(mDirtyObjects);
1800}
1801
1802void State::syncDirtyObjects(const DirtyObjects &bitset)
1803{
1804 for (auto dirtyObject : angle::IterateBitSet(bitset))
Jamie Madillc9d442d2016-01-20 11:17:24 -05001805 {
1806 switch (dirtyObject)
1807 {
1808 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001809 ASSERT(mReadFramebuffer);
1810 mReadFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001811 break;
1812 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001813 ASSERT(mDrawFramebuffer);
1814 mDrawFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001815 break;
1816 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001817 ASSERT(mVertexArray);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001818 mVertexArray->syncImplState();
1819 break;
1820 case DIRTY_OBJECT_PROGRAM:
1821 // TODO(jmadill): implement this
1822 break;
1823 default:
1824 UNREACHABLE();
1825 break;
1826 }
1827 }
1828
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001829 mDirtyObjects &= ~bitset;
1830}
1831
1832void State::syncDirtyObject(GLenum target)
1833{
1834 DirtyObjects localSet;
1835
1836 switch (target)
1837 {
1838 case GL_READ_FRAMEBUFFER:
1839 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1840 break;
1841 case GL_DRAW_FRAMEBUFFER:
1842 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1843 break;
1844 case GL_FRAMEBUFFER:
1845 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1846 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1847 break;
1848 case GL_VERTEX_ARRAY:
1849 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
1850 break;
1851 case GL_PROGRAM:
1852 localSet.set(DIRTY_OBJECT_PROGRAM);
1853 break;
1854 }
1855
1856 syncDirtyObjects(localSet);
1857}
1858
1859void State::setObjectDirty(GLenum target)
1860{
1861 switch (target)
1862 {
1863 case GL_READ_FRAMEBUFFER:
1864 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1865 break;
1866 case GL_DRAW_FRAMEBUFFER:
1867 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1868 break;
1869 case GL_FRAMEBUFFER:
1870 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1871 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1872 break;
1873 case GL_VERTEX_ARRAY:
1874 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1875 break;
1876 case GL_PROGRAM:
1877 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
1878 break;
1879 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001880}
Jamie Madillc9d442d2016-01-20 11:17:24 -05001881
1882} // namespace gl