blob: be03719f9d197e3ef768e16a2901a4048beed2de [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
Sami Väisänene45e53b2016-05-25 10:36:04 +030011#include <limits>
12#include <string.h>
13
Jamie Madillc9d442d2016-01-20 11:17:24 -050014#include "common/BitSetIterator.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030015#include "common/matrix_utils.h"
16#include "common/mathutil.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Context.h"
18#include "libANGLE/Caps.h"
Geoff Lang70d0f492015-12-10 17:45:46 -050019#include "libANGLE/Debug.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Framebuffer.h"
21#include "libANGLE/FramebufferAttachment.h"
22#include "libANGLE/Query.h"
23#include "libANGLE/VertexArray.h"
24#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040025
Olli Etuahobbf1c102016-06-28 13:31:33 +030026namespace
27{
28
29GLenum ActiveQueryType(const GLenum type)
30{
31 return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
32}
33
34} // anonymous namepace
35
Shannon Woods53a94a82014-06-24 15:20:36 -040036namespace gl
37{
Geoff Lang76b10c92014-09-05 16:28:14 -040038
Shannon Woods53a94a82014-06-24 15:20:36 -040039State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050040 : mMaxDrawBuffers(0),
41 mMaxCombinedTextureImageUnits(0),
42 mDepthClearValue(0),
43 mStencilClearValue(0),
44 mScissorTest(false),
45 mSampleCoverage(false),
46 mSampleCoverageValue(0),
47 mSampleCoverageInvert(false),
48 mStencilRef(0),
49 mStencilBackRef(0),
50 mLineWidth(0),
51 mGenerateMipmapHint(GL_NONE),
52 mFragmentShaderDerivativeHint(GL_NONE),
Geoff Langf41a7152016-09-19 15:11:17 -040053 mBindGeneratesResource(true),
Geoff Langfeb8c682017-02-13 16:07:35 -050054 mClientArraysEnabled(true),
Jamie Madille79b1e12015-11-04 16:36:37 -050055 mNearZ(0),
56 mFarZ(0),
57 mReadFramebuffer(nullptr),
58 mDrawFramebuffer(nullptr),
59 mProgram(nullptr),
60 mVertexArray(nullptr),
61 mActiveSampler(0),
Sami Väisänen74c23472016-05-09 17:30:30 +030062 mPrimitiveRestart(false),
63 mMultiSampling(false),
Geoff Lang1d2c41d2016-10-19 16:14:46 -070064 mSampleAlphaToOne(false),
65 mFramebufferSRGB(true)
Shannon Woods53a94a82014-06-24 15:20:36 -040066{
Geoff Lang76b10c92014-09-05 16:28:14 -040067}
68
69State::~State()
70{
Geoff Lang76b10c92014-09-05 16:28:14 -040071}
72
Geoff Lang70d0f492015-12-10 17:45:46 -050073void State::initialize(const Caps &caps,
74 const Extensions &extensions,
Geoff Langeb66a6e2016-10-31 13:06:12 -040075 const Version &clientVersion,
Geoff Langf41a7152016-09-19 15:11:17 -040076 bool debug,
Geoff Langfeb8c682017-02-13 16:07:35 -050077 bool bindGeneratesResource,
78 bool clientArraysEnabled)
Geoff Lang76b10c92014-09-05 16:28:14 -040079{
Shannon Woods2df6a602014-09-26 16:12:07 -040080 mMaxDrawBuffers = caps.maxDrawBuffers;
81 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040082
Jamie Madillf75ab352015-03-16 10:46:52 -040083 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040084
85 mDepthClearValue = 1.0f;
86 mStencilClearValue = 0;
87
88 mRasterizer.rasterizerDiscard = false;
89 mRasterizer.cullFace = false;
90 mRasterizer.cullMode = GL_BACK;
91 mRasterizer.frontFace = GL_CCW;
92 mRasterizer.polygonOffsetFill = false;
93 mRasterizer.polygonOffsetFactor = 0.0f;
94 mRasterizer.polygonOffsetUnits = 0.0f;
95 mRasterizer.pointDrawMode = false;
96 mRasterizer.multiSample = false;
97 mScissorTest = false;
98 mScissor.x = 0;
99 mScissor.y = 0;
100 mScissor.width = 0;
101 mScissor.height = 0;
102
103 mBlend.blend = false;
104 mBlend.sourceBlendRGB = GL_ONE;
105 mBlend.sourceBlendAlpha = GL_ONE;
106 mBlend.destBlendRGB = GL_ZERO;
107 mBlend.destBlendAlpha = GL_ZERO;
108 mBlend.blendEquationRGB = GL_FUNC_ADD;
109 mBlend.blendEquationAlpha = GL_FUNC_ADD;
110 mBlend.sampleAlphaToCoverage = false;
111 mBlend.dither = true;
112
113 mBlendColor.red = 0;
114 mBlendColor.green = 0;
115 mBlendColor.blue = 0;
116 mBlendColor.alpha = 0;
117
118 mDepthStencil.depthTest = false;
119 mDepthStencil.depthFunc = GL_LESS;
120 mDepthStencil.depthMask = true;
121 mDepthStencil.stencilTest = false;
122 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700123 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
124 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400125 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700126 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
127 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400128 mDepthStencil.stencilFail = GL_KEEP;
129 mDepthStencil.stencilPassDepthFail = GL_KEEP;
130 mDepthStencil.stencilPassDepthPass = GL_KEEP;
131 mDepthStencil.stencilBackFail = GL_KEEP;
132 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
133 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
134
135 mStencilRef = 0;
136 mStencilBackRef = 0;
137
138 mSampleCoverage = false;
139 mSampleCoverageValue = 1.0f;
140 mSampleCoverageInvert = false;
141 mGenerateMipmapHint = GL_DONT_CARE;
142 mFragmentShaderDerivativeHint = GL_DONT_CARE;
143
Geoff Langf41a7152016-09-19 15:11:17 -0400144 mBindGeneratesResource = bindGeneratesResource;
Geoff Langfeb8c682017-02-13 16:07:35 -0500145 mClientArraysEnabled = clientArraysEnabled;
Geoff Langf41a7152016-09-19 15:11:17 -0400146
Shannon Woods53a94a82014-06-24 15:20:36 -0400147 mLineWidth = 1.0f;
148
149 mViewport.x = 0;
150 mViewport.y = 0;
151 mViewport.width = 0;
152 mViewport.height = 0;
153 mNearZ = 0.0f;
154 mFarZ = 1.0f;
155
156 mBlend.colorMaskRed = true;
157 mBlend.colorMaskGreen = true;
158 mBlend.colorMaskBlue = true;
159 mBlend.colorMaskAlpha = true;
160
Geoff Lang76b10c92014-09-05 16:28:14 -0400161 mActiveSampler = 0;
162
Shannon Woods23e05002014-09-22 19:07:27 -0400163 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400164
Geoff Lang4dc3af02016-11-18 14:09:27 -0500165 mUniformBuffers.resize(caps.maxUniformBufferBindings);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400166
Geoff Lang76b10c92014-09-05 16:28:14 -0400167 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
168 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
Geoff Langeb66a6e2016-10-31 13:06:12 -0400169 if (clientVersion >= Version(3, 0))
Shannon Woods53a94a82014-06-24 15:20:36 -0400170 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400171 // TODO: These could also be enabled via extension
172 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
173 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400174 }
Geoff Lang3b573612016-10-31 14:08:10 -0400175 if (clientVersion >= Version(3, 1))
176 {
177 mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
178 }
Ian Ewellbda75592016-04-18 17:25:54 -0400179 if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
180 {
181 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
182 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400183
Geoff Lang76b10c92014-09-05 16:28:14 -0400184 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400185
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500186 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
187 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
188 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
189 mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
Geoff Lang2b4ce802016-04-28 13:34:50 -0400190 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400191
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500192 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400193
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500194 mReadFramebuffer = nullptr;
195 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500196
197 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500198
199 mDebug.setOutputEnabled(debug);
200 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300201
202 if (extensions.framebufferMultisample)
203 {
204 mMultiSampling = true;
205 mSampleAlphaToOne = false;
206 }
Sami Väisänena797e062016-05-12 15:23:40 +0300207
208 mCoverageModulation = GL_NONE;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300209
210 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
211 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
212 mPathStencilFunc = GL_ALWAYS;
213 mPathStencilRef = 0;
214 mPathStencilMask = std::numeric_limits<GLuint>::max();
Shannon Woods53a94a82014-06-24 15:20:36 -0400215}
216
Jamie Madill6c1f6712017-02-14 19:08:04 -0500217void State::reset(const Context *context)
Shannon Woods53a94a82014-06-24 15:20:36 -0400218{
Geoff Lang76b10c92014-09-05 16:28:14 -0400219 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400220 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400221 TextureBindingVector &textureVector = bindingVec->second;
222 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400223 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400224 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400225 }
226 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400227 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
228 {
229 mSamplers[samplerIdx].set(NULL);
230 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400231
Shannon Woods53a94a82014-06-24 15:20:36 -0400232 mArrayBuffer.set(NULL);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800233 mDrawIndirectBuffer.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400234 mRenderbuffer.set(NULL);
235
Geoff Lang7dd2e102014-11-10 15:19:26 -0500236 if (mProgram)
237 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500238 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500239 }
240 mProgram = NULL;
241
Shannon Woods53a94a82014-06-24 15:20:36 -0400242 mTransformFeedback.set(NULL);
243
244 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
245 {
246 i->second.set(NULL);
247 }
248
249 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400250 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400251 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400252 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400253 }
254
Shannon Woods53a94a82014-06-24 15:20:36 -0400255 mCopyReadBuffer.set(NULL);
256 mCopyWriteBuffer.set(NULL);
257
258 mPack.pixelBuffer.set(NULL);
259 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500260
261 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400262
Sami Väisänene45e53b2016-05-25 10:36:04 +0300263 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
264 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
265 mPathStencilFunc = GL_ALWAYS;
266 mPathStencilRef = 0;
267 mPathStencilMask = std::numeric_limits<GLuint>::max();
268
Jamie Madill1b94d432015-08-07 13:23:23 -0400269 // TODO(jmadill): Is this necessary?
270 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400271}
272
273const RasterizerState &State::getRasterizerState() const
274{
275 return mRasterizer;
276}
277
278const BlendState &State::getBlendState() const
279{
280 return mBlend;
281}
282
283const DepthStencilState &State::getDepthStencilState() const
284{
285 return mDepthStencil;
286}
287
Jamie Madillf75ab352015-03-16 10:46:52 -0400288void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400289{
290 mColorClearValue.red = red;
291 mColorClearValue.green = green;
292 mColorClearValue.blue = blue;
293 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400294 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400295}
296
Jamie Madillf75ab352015-03-16 10:46:52 -0400297void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400298{
299 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400300 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400301}
302
Jamie Madillf75ab352015-03-16 10:46:52 -0400303void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400304{
305 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400306 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400307}
308
Shannon Woods53a94a82014-06-24 15:20:36 -0400309void State::setColorMask(bool red, bool green, bool blue, bool alpha)
310{
311 mBlend.colorMaskRed = red;
312 mBlend.colorMaskGreen = green;
313 mBlend.colorMaskBlue = blue;
314 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400315 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400316}
317
318void State::setDepthMask(bool mask)
319{
320 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400321 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400322}
323
324bool State::isRasterizerDiscardEnabled() const
325{
326 return mRasterizer.rasterizerDiscard;
327}
328
329void State::setRasterizerDiscard(bool enabled)
330{
331 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400332 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400333}
334
335bool State::isCullFaceEnabled() const
336{
337 return mRasterizer.cullFace;
338}
339
340void State::setCullFace(bool enabled)
341{
342 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400343 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400344}
345
346void State::setCullMode(GLenum mode)
347{
348 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400349 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400350}
351
352void State::setFrontFace(GLenum front)
353{
354 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400355 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400356}
357
358bool State::isDepthTestEnabled() const
359{
360 return mDepthStencil.depthTest;
361}
362
363void State::setDepthTest(bool enabled)
364{
365 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400366 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400367}
368
369void State::setDepthFunc(GLenum depthFunc)
370{
371 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400372 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400373}
374
375void State::setDepthRange(float zNear, float zFar)
376{
377 mNearZ = zNear;
378 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400379 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400380}
381
Geoff Langd42f5b82015-04-16 14:03:29 -0400382float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400383{
Geoff Langd42f5b82015-04-16 14:03:29 -0400384 return mNearZ;
385}
386
387float State::getFarPlane() const
388{
389 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400390}
391
392bool State::isBlendEnabled() const
393{
394 return mBlend.blend;
395}
396
397void State::setBlend(bool enabled)
398{
399 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400400 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400401}
402
403void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
404{
405 mBlend.sourceBlendRGB = sourceRGB;
406 mBlend.destBlendRGB = destRGB;
407 mBlend.sourceBlendAlpha = sourceAlpha;
408 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400409 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400410}
411
412void State::setBlendColor(float red, float green, float blue, float alpha)
413{
414 mBlendColor.red = red;
415 mBlendColor.green = green;
416 mBlendColor.blue = blue;
417 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400418 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400419}
420
421void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
422{
423 mBlend.blendEquationRGB = rgbEquation;
424 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400425 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400426}
427
428const ColorF &State::getBlendColor() const
429{
430 return mBlendColor;
431}
432
433bool State::isStencilTestEnabled() const
434{
435 return mDepthStencil.stencilTest;
436}
437
438void State::setStencilTest(bool enabled)
439{
440 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400441 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400442}
443
444void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
445{
446 mDepthStencil.stencilFunc = stencilFunc;
447 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
448 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400449 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400450}
451
452void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
453{
454 mDepthStencil.stencilBackFunc = stencilBackFunc;
455 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
456 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400457 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400458}
459
460void State::setStencilWritemask(GLuint stencilWritemask)
461{
462 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400463 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400464}
465
466void State::setStencilBackWritemask(GLuint stencilBackWritemask)
467{
468 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400469 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400470}
471
472void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
473{
474 mDepthStencil.stencilFail = stencilFail;
475 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
476 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400477 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400478}
479
480void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
481{
482 mDepthStencil.stencilBackFail = stencilBackFail;
483 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
484 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400485 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400486}
487
488GLint State::getStencilRef() const
489{
490 return mStencilRef;
491}
492
493GLint State::getStencilBackRef() const
494{
495 return mStencilBackRef;
496}
497
498bool State::isPolygonOffsetFillEnabled() const
499{
500 return mRasterizer.polygonOffsetFill;
501}
502
503void State::setPolygonOffsetFill(bool enabled)
504{
Jamie Madill1b94d432015-08-07 13:23:23 -0400505 mRasterizer.polygonOffsetFill = enabled;
506 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400507}
508
509void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
510{
511 // An application can pass NaN values here, so handle this gracefully
512 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
513 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400514 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400515}
516
517bool State::isSampleAlphaToCoverageEnabled() const
518{
519 return mBlend.sampleAlphaToCoverage;
520}
521
522void State::setSampleAlphaToCoverage(bool enabled)
523{
524 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400525 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400526}
527
528bool State::isSampleCoverageEnabled() const
529{
530 return mSampleCoverage;
531}
532
533void State::setSampleCoverage(bool enabled)
534{
535 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400536 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400537}
538
539void State::setSampleCoverageParams(GLclampf value, bool invert)
540{
541 mSampleCoverageValue = value;
542 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400543 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400544}
545
Geoff Lang0fbb6002015-04-16 11:11:53 -0400546GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400547{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400548 return mSampleCoverageValue;
549}
Shannon Woods53a94a82014-06-24 15:20:36 -0400550
Geoff Lang0fbb6002015-04-16 11:11:53 -0400551bool State::getSampleCoverageInvert() const
552{
553 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400554}
555
Sami Väisänen74c23472016-05-09 17:30:30 +0300556void State::setSampleAlphaToOne(bool enabled)
557{
558 mSampleAlphaToOne = enabled;
559 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
560}
561
562bool State::isSampleAlphaToOneEnabled() const
563{
564 return mSampleAlphaToOne;
565}
566
567void State::setMultisampling(bool enabled)
568{
569 mMultiSampling = enabled;
570 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
571}
572
573bool State::isMultisamplingEnabled() const
574{
575 return mMultiSampling;
576}
577
Shannon Woods53a94a82014-06-24 15:20:36 -0400578bool State::isScissorTestEnabled() const
579{
580 return mScissorTest;
581}
582
583void State::setScissorTest(bool enabled)
584{
585 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400586 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400587}
588
589void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
590{
591 mScissor.x = x;
592 mScissor.y = y;
593 mScissor.width = width;
594 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400595 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400596}
597
598const Rectangle &State::getScissor() const
599{
600 return mScissor;
601}
602
603bool State::isDitherEnabled() const
604{
605 return mBlend.dither;
606}
607
608void State::setDither(bool enabled)
609{
610 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400611 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400612}
613
Jamie Madillb4b53c52015-02-03 15:22:48 -0500614bool State::isPrimitiveRestartEnabled() const
615{
616 return mPrimitiveRestart;
617}
618
619void State::setPrimitiveRestart(bool enabled)
620{
621 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400622 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500623}
624
Shannon Woods53a94a82014-06-24 15:20:36 -0400625void State::setEnableFeature(GLenum feature, bool enabled)
626{
627 switch (feature)
628 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300629 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
630 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400631 case GL_CULL_FACE: setCullFace(enabled); break;
632 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
633 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
634 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
635 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
636 case GL_STENCIL_TEST: setStencilTest(enabled); break;
637 case GL_DEPTH_TEST: setDepthTest(enabled); break;
638 case GL_BLEND: setBlend(enabled); break;
639 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500640 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400641 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang3b573612016-10-31 14:08:10 -0400642 case GL_SAMPLE_MASK:
Geoff Lang9f090372016-12-02 10:20:43 -0500643 if (enabled)
644 {
645 // Enabling this feature is not implemented yet.
646 UNIMPLEMENTED();
647 }
Geoff Lang3b573612016-10-31 14:08:10 -0400648 break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500649 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
650 mDebug.setOutputSynchronous(enabled);
651 break;
652 case GL_DEBUG_OUTPUT:
653 mDebug.setOutputEnabled(enabled);
654 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700655 case GL_FRAMEBUFFER_SRGB_EXT:
656 setFramebufferSRGB(enabled);
657 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400658 default: UNREACHABLE();
659 }
660}
661
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700662bool State::getEnableFeature(GLenum feature) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400663{
664 switch (feature)
665 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300666 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
667 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400668 case GL_CULL_FACE: return isCullFaceEnabled();
669 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
670 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
671 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
672 case GL_SCISSOR_TEST: return isScissorTestEnabled();
673 case GL_STENCIL_TEST: return isStencilTestEnabled();
674 case GL_DEPTH_TEST: return isDepthTestEnabled();
675 case GL_BLEND: return isBlendEnabled();
676 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500677 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400678 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Langb5e997f2016-12-06 10:55:34 -0500679 case GL_SAMPLE_MASK:
680 UNIMPLEMENTED();
681 return false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500682 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
683 return mDebug.isOutputSynchronous();
684 case GL_DEBUG_OUTPUT:
685 return mDebug.isOutputEnabled();
Geoff Langf41a7152016-09-19 15:11:17 -0400686 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
687 return isBindGeneratesResourceEnabled();
Geoff Langfeb8c682017-02-13 16:07:35 -0500688 case GL_CLIENT_ARRAYS_ANGLE:
689 return areClientArraysEnabled();
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700690 case GL_FRAMEBUFFER_SRGB_EXT:
691 return getFramebufferSRGB();
Shannon Woods53a94a82014-06-24 15:20:36 -0400692 default: UNREACHABLE(); return false;
693 }
694}
695
696void State::setLineWidth(GLfloat width)
697{
698 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400699 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400700}
701
Geoff Lang4b3f4162015-04-16 13:22:05 -0400702float State::getLineWidth() const
703{
704 return mLineWidth;
705}
706
Shannon Woods53a94a82014-06-24 15:20:36 -0400707void State::setGenerateMipmapHint(GLenum hint)
708{
709 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400710 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400711}
712
713void State::setFragmentShaderDerivativeHint(GLenum hint)
714{
715 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400716 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400717 // TODO: Propagate the hint to shader translator so we can write
718 // ddx, ddx_coarse, or ddx_fine depending on the hint.
719 // Ignore for now. It is valid for implementations to ignore hint.
720}
721
Geoff Langf41a7152016-09-19 15:11:17 -0400722bool State::isBindGeneratesResourceEnabled() const
723{
724 return mBindGeneratesResource;
725}
726
Geoff Langfeb8c682017-02-13 16:07:35 -0500727bool State::areClientArraysEnabled() const
728{
729 return mClientArraysEnabled;
730}
731
Shannon Woods53a94a82014-06-24 15:20:36 -0400732void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
733{
734 mViewport.x = x;
735 mViewport.y = y;
736 mViewport.width = width;
737 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400738 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400739}
740
741const Rectangle &State::getViewport() const
742{
743 return mViewport;
744}
745
746void State::setActiveSampler(unsigned int active)
747{
748 mActiveSampler = active;
749}
750
751unsigned int State::getActiveSampler() const
752{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700753 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400754}
755
Geoff Lang76b10c92014-09-05 16:28:14 -0400756void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400757{
Geoff Lang76b10c92014-09-05 16:28:14 -0400758 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400759}
760
Jamie Madillc29968b2016-01-20 11:17:23 -0500761Texture *State::getTargetTexture(GLenum target) const
762{
763 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
764}
765
Geoff Lang76b10c92014-09-05 16:28:14 -0400766Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400767{
Jamie Madill5864ac22015-01-12 14:43:07 -0500768 const auto it = mSamplerTextures.find(type);
769 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400770 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500771 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400772}
773
Geoff Lang76b10c92014-09-05 16:28:14 -0400774GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400775{
Jamie Madill5864ac22015-01-12 14:43:07 -0500776 const auto it = mSamplerTextures.find(type);
777 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400778 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500779 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400780}
781
Jamie Madille6382c32014-11-07 15:05:26 -0500782void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400783{
784 // Textures have a detach method on State rather than a simple
785 // removeBinding, because the zero/null texture objects are managed
786 // separately, and don't have to go through the Context's maps or
787 // the ResourceManager.
788
789 // [OpenGL ES 2.0.24] section 3.8 page 84:
790 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
791 // rebound to texture object zero
792
Corentin Walleza2257da2016-04-19 16:43:12 -0400793 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400794 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400795 GLenum textureType = bindingVec.first;
796 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400797 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400798 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400799 BindingPointer<Texture> &binding = textureVector[textureIdx];
800 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400801 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500802 auto it = zeroTextures.find(textureType);
803 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500804 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500805 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400806 }
807 }
808 }
809
810 // [OpenGL ES 2.0.24] section 4.4 page 112:
811 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
812 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
813 // image was attached in the currently bound framebuffer.
814
815 if (mReadFramebuffer)
816 {
817 mReadFramebuffer->detachTexture(texture);
818 }
819
820 if (mDrawFramebuffer)
821 {
822 mDrawFramebuffer->detachTexture(texture);
823 }
824}
825
Jamie Madille6382c32014-11-07 15:05:26 -0500826void State::initializeZeroTextures(const TextureMap &zeroTextures)
827{
828 for (const auto &zeroTexture : zeroTextures)
829 {
830 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
831
832 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
833 {
834 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
835 }
836 }
837}
838
Shannon Woods53a94a82014-06-24 15:20:36 -0400839void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
840{
841 mSamplers[textureUnit].set(sampler);
842}
843
844GLuint State::getSamplerId(GLuint textureUnit) const
845{
Geoff Lang76b10c92014-09-05 16:28:14 -0400846 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400847 return mSamplers[textureUnit].id();
848}
849
850Sampler *State::getSampler(GLuint textureUnit) const
851{
852 return mSamplers[textureUnit].get();
853}
854
855void State::detachSampler(GLuint sampler)
856{
857 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
858 // If a sampler object that is currently bound to one or more texture units is
859 // deleted, it is as though BindSampler is called once for each texture unit to
860 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400861 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400862 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400863 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
864 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400865 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400866 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400867 }
868 }
869}
870
871void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
872{
873 mRenderbuffer.set(renderbuffer);
874}
875
876GLuint State::getRenderbufferId() const
877{
878 return mRenderbuffer.id();
879}
880
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700881Renderbuffer *State::getCurrentRenderbuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400882{
883 return mRenderbuffer.get();
884}
885
886void State::detachRenderbuffer(GLuint renderbuffer)
887{
888 // [OpenGL ES 2.0.24] section 4.4 page 109:
889 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
890 // had been executed with the target RENDERBUFFER and name of zero.
891
892 if (mRenderbuffer.id() == renderbuffer)
893 {
894 mRenderbuffer.set(NULL);
895 }
896
897 // [OpenGL ES 2.0.24] section 4.4 page 111:
898 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
899 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
900 // point to which this image was attached in the currently bound framebuffer.
901
902 Framebuffer *readFramebuffer = mReadFramebuffer;
903 Framebuffer *drawFramebuffer = mDrawFramebuffer;
904
905 if (readFramebuffer)
906 {
907 readFramebuffer->detachRenderbuffer(renderbuffer);
908 }
909
910 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
911 {
912 drawFramebuffer->detachRenderbuffer(renderbuffer);
913 }
914
915}
916
917void State::setReadFramebufferBinding(Framebuffer *framebuffer)
918{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500919 if (mReadFramebuffer == framebuffer)
920 return;
921
Shannon Woods53a94a82014-06-24 15:20:36 -0400922 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500923 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
924
925 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
926 {
927 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
928 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400929}
930
931void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
932{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500933 if (mDrawFramebuffer == framebuffer)
934 return;
935
Shannon Woods53a94a82014-06-24 15:20:36 -0400936 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500937 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
938
939 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
940 {
941 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
942 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400943}
944
945Framebuffer *State::getTargetFramebuffer(GLenum target) const
946{
947 switch (target)
948 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500949 case GL_READ_FRAMEBUFFER_ANGLE:
950 return mReadFramebuffer;
951 case GL_DRAW_FRAMEBUFFER_ANGLE:
952 case GL_FRAMEBUFFER:
953 return mDrawFramebuffer;
954 default:
955 UNREACHABLE();
956 return NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400957 }
958}
959
Jamie Madill51f40ec2016-06-15 14:06:00 -0400960Framebuffer *State::getReadFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400961{
962 return mReadFramebuffer;
963}
964
Jamie Madill51f40ec2016-06-15 14:06:00 -0400965Framebuffer *State::getDrawFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400966{
967 return mDrawFramebuffer;
968}
969
970bool State::removeReadFramebufferBinding(GLuint framebuffer)
971{
Jamie Madill77a72f62015-04-14 11:18:32 -0400972 if (mReadFramebuffer != nullptr &&
973 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400974 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500975 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400976 return true;
977 }
978
979 return false;
980}
981
982bool State::removeDrawFramebufferBinding(GLuint framebuffer)
983{
Jamie Madill77a72f62015-04-14 11:18:32 -0400984 if (mReadFramebuffer != nullptr &&
985 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400986 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500987 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400988 return true;
989 }
990
991 return false;
992}
993
994void State::setVertexArrayBinding(VertexArray *vertexArray)
995{
996 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000997 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500998
999 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1000 {
1001 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1002 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001003}
1004
1005GLuint State::getVertexArrayId() const
1006{
1007 ASSERT(mVertexArray != NULL);
1008 return mVertexArray->id();
1009}
1010
1011VertexArray *State::getVertexArray() const
1012{
1013 ASSERT(mVertexArray != NULL);
1014 return mVertexArray;
1015}
1016
1017bool State::removeVertexArrayBinding(GLuint vertexArray)
1018{
1019 if (mVertexArray->id() == vertexArray)
1020 {
1021 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001022 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001023 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 return true;
1025 }
1026
1027 return false;
1028}
1029
Jamie Madill6c1f6712017-02-14 19:08:04 -05001030void State::setProgram(const Context *context, Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001031{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001032 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001033 {
Geoff Lang7dd2e102014-11-10 15:19:26 -05001034 if (mProgram)
1035 {
Jamie Madill6c1f6712017-02-14 19:08:04 -05001036 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001037 }
1038
1039 mProgram = newProgram;
1040
1041 if (mProgram)
1042 {
1043 newProgram->addRef();
1044 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001045 }
1046}
1047
Geoff Lang7dd2e102014-11-10 15:19:26 -05001048Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001049{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001050 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -04001051}
1052
1053void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
1054{
1055 mTransformFeedback.set(transformFeedback);
1056}
1057
1058TransformFeedback *State::getCurrentTransformFeedback() const
1059{
1060 return mTransformFeedback.get();
1061}
1062
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001063bool State::isTransformFeedbackActiveUnpaused() const
1064{
1065 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001066 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001067}
1068
Corentin Walleza2257da2016-04-19 16:43:12 -04001069bool State::removeTransformFeedbackBinding(GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001070{
1071 if (mTransformFeedback.id() == transformFeedback)
1072 {
Corentin Walleza2257da2016-04-19 16:43:12 -04001073 mTransformFeedback.set(nullptr);
1074 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001075 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001076
1077 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001078}
1079
Olli Etuahobbf1c102016-06-28 13:31:33 +03001080bool State::isQueryActive(const GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001081{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001082 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001083 {
Olli Etuahobbf1c102016-06-28 13:31:33 +03001084 const Query *query = iter.second.get();
1085 if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001086 {
1087 return true;
1088 }
1089 }
1090
1091 return false;
1092}
1093
1094bool State::isQueryActive(Query *query) const
1095{
1096 for (auto &iter : mActiveQueries)
1097 {
1098 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001099 {
1100 return true;
1101 }
1102 }
1103
1104 return false;
1105}
1106
1107void State::setActiveQuery(GLenum target, Query *query)
1108{
1109 mActiveQueries[target].set(query);
1110}
1111
1112GLuint State::getActiveQueryId(GLenum target) const
1113{
1114 const Query *query = getActiveQuery(target);
1115 return (query ? query->id() : 0u);
1116}
1117
1118Query *State::getActiveQuery(GLenum target) const
1119{
Jamie Madill5864ac22015-01-12 14:43:07 -05001120 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001121
Jamie Madill5864ac22015-01-12 14:43:07 -05001122 // All query types should already exist in the activeQueries map
1123 ASSERT(it != mActiveQueries.end());
1124
1125 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001126}
1127
1128void State::setArrayBufferBinding(Buffer *buffer)
1129{
1130 mArrayBuffer.set(buffer);
1131}
1132
1133GLuint State::getArrayBufferId() const
1134{
1135 return mArrayBuffer.id();
1136}
1137
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001138void State::setDrawIndirectBufferBinding(Buffer *buffer)
1139{
1140 mDrawIndirectBuffer.set(buffer);
1141 mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
1142}
1143
Shannon Woods53a94a82014-06-24 15:20:36 -04001144void State::setGenericUniformBufferBinding(Buffer *buffer)
1145{
1146 mGenericUniformBuffer.set(buffer);
1147}
1148
1149void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1150{
1151 mUniformBuffers[index].set(buffer, offset, size);
1152}
1153
Geoff Lang5d124a62015-09-15 13:03:27 -04001154const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001155{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001156 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001157 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001158}
1159
Shannon Woods53a94a82014-06-24 15:20:36 -04001160void State::setCopyReadBufferBinding(Buffer *buffer)
1161{
1162 mCopyReadBuffer.set(buffer);
1163}
1164
1165void State::setCopyWriteBufferBinding(Buffer *buffer)
1166{
1167 mCopyWriteBuffer.set(buffer);
1168}
1169
1170void State::setPixelPackBufferBinding(Buffer *buffer)
1171{
1172 mPack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001173 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001174}
1175
1176void State::setPixelUnpackBufferBinding(Buffer *buffer)
1177{
1178 mUnpack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001179 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001180}
1181
1182Buffer *State::getTargetBuffer(GLenum target) const
1183{
1184 switch (target)
1185 {
1186 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1187 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1188 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001189 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001190 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1191 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001192 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001193 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001194 case GL_ATOMIC_COUNTER_BUFFER:
1195 UNIMPLEMENTED();
1196 return nullptr;
1197 case GL_SHADER_STORAGE_BUFFER:
1198 UNIMPLEMENTED();
1199 return nullptr;
1200 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001201 return mDrawIndirectBuffer.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001202 default: UNREACHABLE(); return NULL;
1203 }
1204}
1205
Yuly Novikov5807a532015-12-03 13:01:22 -05001206void State::detachBuffer(GLuint bufferName)
1207{
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001208 BindingPointer<Buffer> *buffers[] = {
1209 &mArrayBuffer, &mCopyReadBuffer, &mCopyWriteBuffer, &mDrawIndirectBuffer,
1210 &mPack.pixelBuffer, &mUnpack.pixelBuffer, &mGenericUniformBuffer};
Yuly Novikov5807a532015-12-03 13:01:22 -05001211 for (auto buffer : buffers)
1212 {
1213 if (buffer->id() == bufferName)
1214 {
1215 buffer->set(nullptr);
1216 }
1217 }
1218
1219 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1220 if (curTransformFeedback)
1221 {
1222 curTransformFeedback->detachBuffer(bufferName);
1223 }
1224
1225 getVertexArray()->detachBuffer(bufferName);
1226}
1227
Shannon Woods53a94a82014-06-24 15:20:36 -04001228void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1229{
1230 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001231 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001232}
1233
1234void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1235{
Shannon Woods23e05002014-09-22 19:07:27 -04001236 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001237 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001238 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001239}
1240
1241void State::setVertexAttribu(GLuint index, const GLuint values[4])
1242{
Shannon Woods23e05002014-09-22 19:07:27 -04001243 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001244 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001245 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001246}
1247
1248void State::setVertexAttribi(GLuint index, const GLint values[4])
1249{
Shannon Woods23e05002014-09-22 19:07:27 -04001250 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001251 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001252 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001253}
1254
Jamie Madill0b9e9032015-08-17 11:51:52 +00001255void State::setVertexAttribState(unsigned int attribNum,
1256 Buffer *boundBuffer,
1257 GLint size,
1258 GLenum type,
1259 bool normalized,
1260 bool pureInteger,
1261 GLsizei stride,
1262 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001263{
1264 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001265 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001266}
1267
1268void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1269{
1270 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001271 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001272}
1273
Shannon Woods53a94a82014-06-24 15:20:36 -04001274const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1275{
Shannon Woods23e05002014-09-22 19:07:27 -04001276 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001277 return mVertexAttribCurrentValues[attribNum];
1278}
1279
Shannon Woods53a94a82014-06-24 15:20:36 -04001280const void *State::getVertexAttribPointer(unsigned int attribNum) const
1281{
1282 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1283}
1284
1285void State::setPackAlignment(GLint alignment)
1286{
1287 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001288 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001289}
1290
1291GLint State::getPackAlignment() const
1292{
1293 return mPack.alignment;
1294}
1295
1296void State::setPackReverseRowOrder(bool reverseRowOrder)
1297{
1298 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001299 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001300}
1301
1302bool State::getPackReverseRowOrder() const
1303{
1304 return mPack.reverseRowOrder;
1305}
1306
Minmin Gongadff67b2015-10-14 10:34:45 -04001307void State::setPackRowLength(GLint rowLength)
1308{
1309 mPack.rowLength = rowLength;
1310 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1311}
1312
1313GLint State::getPackRowLength() const
1314{
1315 return mPack.rowLength;
1316}
1317
1318void State::setPackSkipRows(GLint skipRows)
1319{
1320 mPack.skipRows = skipRows;
1321 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1322}
1323
1324GLint State::getPackSkipRows() const
1325{
1326 return mPack.skipRows;
1327}
1328
1329void State::setPackSkipPixels(GLint skipPixels)
1330{
1331 mPack.skipPixels = skipPixels;
1332 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1333}
1334
1335GLint State::getPackSkipPixels() const
1336{
1337 return mPack.skipPixels;
1338}
1339
Shannon Woods53a94a82014-06-24 15:20:36 -04001340const PixelPackState &State::getPackState() const
1341{
1342 return mPack;
1343}
1344
Jamie Madill87de3622015-03-16 10:41:44 -04001345PixelPackState &State::getPackState()
1346{
1347 return mPack;
1348}
1349
Shannon Woods53a94a82014-06-24 15:20:36 -04001350void State::setUnpackAlignment(GLint alignment)
1351{
1352 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001353 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001354}
1355
1356GLint State::getUnpackAlignment() const
1357{
1358 return mUnpack.alignment;
1359}
1360
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001361void State::setUnpackRowLength(GLint rowLength)
1362{
1363 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001364 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001365}
1366
1367GLint State::getUnpackRowLength() const
1368{
1369 return mUnpack.rowLength;
1370}
1371
Minmin Gongadff67b2015-10-14 10:34:45 -04001372void State::setUnpackImageHeight(GLint imageHeight)
1373{
1374 mUnpack.imageHeight = imageHeight;
1375 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1376}
1377
1378GLint State::getUnpackImageHeight() const
1379{
1380 return mUnpack.imageHeight;
1381}
1382
1383void State::setUnpackSkipImages(GLint skipImages)
1384{
1385 mUnpack.skipImages = skipImages;
1386 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1387}
1388
1389GLint State::getUnpackSkipImages() const
1390{
1391 return mUnpack.skipImages;
1392}
1393
1394void State::setUnpackSkipRows(GLint skipRows)
1395{
1396 mUnpack.skipRows = skipRows;
1397 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1398}
1399
1400GLint State::getUnpackSkipRows() const
1401{
1402 return mUnpack.skipRows;
1403}
1404
1405void State::setUnpackSkipPixels(GLint skipPixels)
1406{
1407 mUnpack.skipPixels = skipPixels;
1408 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1409}
1410
1411GLint State::getUnpackSkipPixels() const
1412{
1413 return mUnpack.skipPixels;
1414}
1415
Shannon Woods53a94a82014-06-24 15:20:36 -04001416const PixelUnpackState &State::getUnpackState() const
1417{
1418 return mUnpack;
1419}
1420
Jamie Madill67102f02015-03-16 10:41:42 -04001421PixelUnpackState &State::getUnpackState()
1422{
1423 return mUnpack;
1424}
1425
Geoff Lang70d0f492015-12-10 17:45:46 -05001426const Debug &State::getDebug() const
1427{
1428 return mDebug;
1429}
1430
1431Debug &State::getDebug()
1432{
1433 return mDebug;
1434}
1435
Sami Väisänena797e062016-05-12 15:23:40 +03001436void State::setCoverageModulation(GLenum components)
1437{
1438 mCoverageModulation = components;
1439 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1440}
1441
1442GLenum State::getCoverageModulation() const
1443{
1444 return mCoverageModulation;
1445}
1446
Sami Väisänene45e53b2016-05-25 10:36:04 +03001447void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1448{
1449 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1450 {
1451 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1452 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1453 }
1454 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1455 {
1456 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1457 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1458 }
1459 else
1460 {
1461 UNREACHABLE();
1462 }
1463}
1464
1465const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1466{
1467 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1468 {
1469 return mPathMatrixMV;
1470 }
1471 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1472 {
1473 return mPathMatrixProj;
1474 }
1475
1476 UNREACHABLE();
1477 return nullptr;
1478}
1479
1480void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1481{
1482 mPathStencilFunc = func;
1483 mPathStencilRef = ref;
1484 mPathStencilMask = mask;
1485 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1486}
1487
1488GLenum State::getPathStencilFunc() const
1489{
1490 return mPathStencilFunc;
1491}
1492
1493GLint State::getPathStencilRef() const
1494{
1495 return mPathStencilRef;
1496}
1497
1498GLuint State::getPathStencilMask() const
1499{
1500 return mPathStencilMask;
1501}
1502
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001503void State::setFramebufferSRGB(bool sRGB)
1504{
1505 mFramebufferSRGB = sRGB;
1506 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1507}
1508
1509bool State::getFramebufferSRGB() const
1510{
1511 return mFramebufferSRGB;
1512}
1513
Shannon Woods53a94a82014-06-24 15:20:36 -04001514void State::getBooleanv(GLenum pname, GLboolean *params)
1515{
1516 switch (pname)
1517 {
1518 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1519 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1520 case GL_COLOR_WRITEMASK:
1521 params[0] = mBlend.colorMaskRed;
1522 params[1] = mBlend.colorMaskGreen;
1523 params[2] = mBlend.colorMaskBlue;
1524 params[3] = mBlend.colorMaskAlpha;
1525 break;
1526 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1527 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1528 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1529 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1530 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1531 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1532 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1533 case GL_BLEND: *params = mBlend.blend; break;
1534 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001535 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1536 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001537 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1538 *params = mPrimitiveRestart;
1539 break;
Geoff Langab831f02015-12-01 09:39:10 -05001540 case GL_RASTERIZER_DISCARD:
1541 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1542 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001543 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1544 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1545 break;
1546 case GL_DEBUG_OUTPUT:
1547 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1548 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001549 case GL_MULTISAMPLE_EXT:
1550 *params = mMultiSampling;
1551 break;
1552 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1553 *params = mSampleAlphaToOne;
1554 break;
Geoff Langf41a7152016-09-19 15:11:17 -04001555 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1556 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1557 break;
Geoff Langfeb8c682017-02-13 16:07:35 -05001558 case GL_CLIENT_ARRAYS_ANGLE:
1559 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1560 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001561 case GL_FRAMEBUFFER_SRGB_EXT:
1562 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1563 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001564 default:
1565 UNREACHABLE();
1566 break;
1567 }
1568}
1569
1570void State::getFloatv(GLenum pname, GLfloat *params)
1571{
1572 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1573 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1574 // GetIntegerv as its native query function. As it would require conversion in any
1575 // case, this should make no difference to the calling application.
1576 switch (pname)
1577 {
1578 case GL_LINE_WIDTH: *params = mLineWidth; break;
1579 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1580 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1581 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1582 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1583 case GL_DEPTH_RANGE:
1584 params[0] = mNearZ;
1585 params[1] = mFarZ;
1586 break;
1587 case GL_COLOR_CLEAR_VALUE:
1588 params[0] = mColorClearValue.red;
1589 params[1] = mColorClearValue.green;
1590 params[2] = mColorClearValue.blue;
1591 params[3] = mColorClearValue.alpha;
1592 break;
1593 case GL_BLEND_COLOR:
1594 params[0] = mBlendColor.red;
1595 params[1] = mBlendColor.green;
1596 params[2] = mBlendColor.blue;
1597 params[3] = mBlendColor.alpha;
1598 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001599 case GL_MULTISAMPLE_EXT:
1600 *params = static_cast<GLfloat>(mMultiSampling);
1601 break;
1602 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1603 *params = static_cast<GLfloat>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001604 case GL_COVERAGE_MODULATION_CHROMIUM:
Jamie Madille2e406c2016-06-02 13:04:10 -04001605 params[0] = static_cast<GLfloat>(mCoverageModulation);
1606 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001607 default:
1608 UNREACHABLE();
1609 break;
1610 }
1611}
1612
Jamie Madill9082b982016-04-27 15:21:51 -04001613void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001614{
1615 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1616 {
1617 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001618 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001619 Framebuffer *framebuffer = mDrawFramebuffer;
1620 *params = framebuffer->getDrawBufferState(colorAttachment);
1621 return;
1622 }
1623
1624 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1625 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1626 // GetIntegerv as its native query function. As it would require conversion in any
1627 // case, this should make no difference to the calling application. You may find it in
1628 // State::getFloatv.
1629 switch (pname)
1630 {
1631 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001632 case GL_DRAW_INDIRECT_BUFFER_BINDING:
1633 *params = mDrawIndirectBuffer.id();
1634 break;
Jamie Madill8e344942015-07-09 14:22:07 -04001635 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001636 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1637 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1638 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1639 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1640 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001641 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001642 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1643 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001644 case GL_PACK_ROW_LENGTH:
1645 *params = mPack.rowLength;
1646 break;
1647 case GL_PACK_SKIP_ROWS:
1648 *params = mPack.skipRows;
1649 break;
1650 case GL_PACK_SKIP_PIXELS:
1651 *params = mPack.skipPixels;
1652 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001653 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001654 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001655 case GL_UNPACK_IMAGE_HEIGHT:
1656 *params = mUnpack.imageHeight;
1657 break;
1658 case GL_UNPACK_SKIP_IMAGES:
1659 *params = mUnpack.skipImages;
1660 break;
1661 case GL_UNPACK_SKIP_ROWS:
1662 *params = mUnpack.skipRows;
1663 break;
1664 case GL_UNPACK_SKIP_PIXELS:
1665 *params = mUnpack.skipPixels;
1666 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001667 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1668 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001669 case GL_ACTIVE_TEXTURE:
1670 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1671 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001672 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1673 case GL_STENCIL_REF: *params = mStencilRef; break;
1674 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1675 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1676 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1677 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1678 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1679 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1680 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1681 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1682 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1683 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1684 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1685 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1686 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1687 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1688 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1689 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1690 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1691 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1692 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1693 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001694 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1695 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001696 case GL_SAMPLE_BUFFERS:
1697 case GL_SAMPLES:
1698 {
1699 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001700 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001701 {
1702 switch (pname)
1703 {
1704 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001705 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001706 {
1707 *params = 1;
1708 }
1709 else
1710 {
1711 *params = 0;
1712 }
1713 break;
1714 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001715 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001716 break;
1717 }
1718 }
1719 else
1720 {
1721 *params = 0;
1722 }
1723 }
1724 break;
1725 case GL_VIEWPORT:
1726 params[0] = mViewport.x;
1727 params[1] = mViewport.y;
1728 params[2] = mViewport.width;
1729 params[3] = mViewport.height;
1730 break;
1731 case GL_SCISSOR_BOX:
1732 params[0] = mScissor.x;
1733 params[1] = mScissor.y;
1734 params[2] = mScissor.width;
1735 params[3] = mScissor.height;
1736 break;
1737 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1738 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1739 case GL_RED_BITS:
1740 case GL_GREEN_BITS:
1741 case GL_BLUE_BITS:
1742 case GL_ALPHA_BITS:
1743 {
1744 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001745 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001746
1747 if (colorbuffer)
1748 {
1749 switch (pname)
1750 {
1751 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1752 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1753 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1754 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1755 }
1756 }
1757 else
1758 {
1759 *params = 0;
1760 }
1761 }
1762 break;
1763 case GL_DEPTH_BITS:
1764 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001765 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1766 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001767
1768 if (depthbuffer)
1769 {
1770 *params = depthbuffer->getDepthSize();
1771 }
1772 else
1773 {
1774 *params = 0;
1775 }
1776 }
1777 break;
1778 case GL_STENCIL_BITS:
1779 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001780 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1781 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001782
1783 if (stencilbuffer)
1784 {
1785 *params = stencilbuffer->getStencilSize();
1786 }
1787 else
1788 {
1789 *params = 0;
1790 }
1791 }
1792 break;
1793 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001794 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001795 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001796 break;
1797 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001798 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001799 *params =
1800 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001801 break;
1802 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001803 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001804 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001805 break;
1806 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001807 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001808 *params =
1809 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001810 break;
John Bauman18319182016-09-28 14:22:27 -07001811 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1812 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1813 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1814 GL_TEXTURE_EXTERNAL_OES);
1815 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001816 case GL_UNIFORM_BUFFER_BINDING:
1817 *params = mGenericUniformBuffer.id();
1818 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001819 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001820 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001821 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001822 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001823 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001824 break;
1825 case GL_COPY_READ_BUFFER_BINDING:
1826 *params = mCopyReadBuffer.id();
1827 break;
1828 case GL_COPY_WRITE_BUFFER_BINDING:
1829 *params = mCopyWriteBuffer.id();
1830 break;
1831 case GL_PIXEL_PACK_BUFFER_BINDING:
1832 *params = mPack.pixelBuffer.id();
1833 break;
1834 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1835 *params = mUnpack.pixelBuffer.id();
1836 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02001837 case GL_READ_BUFFER:
1838 *params = mReadFramebuffer->getReadBufferState();
1839 break;
1840 case GL_SAMPLER_BINDING:
1841 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1842 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
1843 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001844 case GL_DEBUG_LOGGED_MESSAGES:
1845 *params = static_cast<GLint>(mDebug.getMessageCount());
1846 break;
1847 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1848 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1849 break;
1850 case GL_DEBUG_GROUP_STACK_DEPTH:
1851 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1852 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001853 case GL_MULTISAMPLE_EXT:
1854 *params = static_cast<GLint>(mMultiSampling);
1855 break;
1856 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1857 *params = static_cast<GLint>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001858 case GL_COVERAGE_MODULATION_CHROMIUM:
1859 *params = static_cast<GLint>(mCoverageModulation);
Sami Väisänen74c23472016-05-09 17:30:30 +03001860 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001861 default:
1862 UNREACHABLE();
1863 break;
1864 }
1865}
1866
Geoff Lang70d0f492015-12-10 17:45:46 -05001867void State::getPointerv(GLenum pname, void **params) const
1868{
1869 switch (pname)
1870 {
1871 case GL_DEBUG_CALLBACK_FUNCTION:
1872 *params = reinterpret_cast<void *>(mDebug.getCallback());
1873 break;
1874 case GL_DEBUG_CALLBACK_USER_PARAM:
1875 *params = const_cast<void *>(mDebug.getUserParam());
1876 break;
1877 default:
1878 UNREACHABLE();
1879 break;
1880 }
1881}
1882
Martin Radev66fb8202016-07-28 11:45:20 +03001883void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04001884{
1885 switch (target)
1886 {
1887 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001888 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001889 {
Geoff Lang045536b2015-03-27 15:17:18 -04001890 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001891 }
1892 break;
1893 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001894 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001895 {
1896 *data = mUniformBuffers[index].id();
1897 }
1898 break;
1899 default:
Martin Radev66fb8202016-07-28 11:45:20 +03001900 UNREACHABLE();
1901 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001902 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001903}
1904
Martin Radev66fb8202016-07-28 11:45:20 +03001905void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04001906{
1907 switch (target)
1908 {
1909 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001910 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001911 {
Geoff Lang045536b2015-03-27 15:17:18 -04001912 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001913 }
1914 break;
1915 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001916 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001917 {
Geoff Lang045536b2015-03-27 15:17:18 -04001918 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001919 }
1920 break;
1921 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001922 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001923 {
1924 *data = mUniformBuffers[index].getOffset();
1925 }
1926 break;
1927 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001928 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001929 {
1930 *data = mUniformBuffers[index].getSize();
1931 }
1932 break;
1933 default:
Martin Radev66fb8202016-07-28 11:45:20 +03001934 UNREACHABLE();
1935 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001936 }
Martin Radev66fb8202016-07-28 11:45:20 +03001937}
Shannon Woods53a94a82014-06-24 15:20:36 -04001938
Martin Radev66fb8202016-07-28 11:45:20 +03001939void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1940{
1941 UNREACHABLE();
Shannon Woods53a94a82014-06-24 15:20:36 -04001942}
1943
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001944bool State::hasMappedBuffer(GLenum target) const
1945{
1946 if (target == GL_ARRAY_BUFFER)
1947 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001948 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001949 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001950 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001951 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001952 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001953 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001954 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1955 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1956 {
1957 return true;
1958 }
1959 }
1960
1961 return false;
1962 }
1963 else
1964 {
1965 Buffer *buffer = getTargetBuffer(target);
1966 return (buffer && buffer->isMapped());
1967 }
1968}
1969
Jamie Madillc9d442d2016-01-20 11:17:24 -05001970void State::syncDirtyObjects()
1971{
1972 if (!mDirtyObjects.any())
1973 return;
1974
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001975 syncDirtyObjects(mDirtyObjects);
1976}
1977
1978void State::syncDirtyObjects(const DirtyObjects &bitset)
1979{
1980 for (auto dirtyObject : angle::IterateBitSet(bitset))
Jamie Madillc9d442d2016-01-20 11:17:24 -05001981 {
1982 switch (dirtyObject)
1983 {
1984 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001985 ASSERT(mReadFramebuffer);
1986 mReadFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001987 break;
1988 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001989 ASSERT(mDrawFramebuffer);
1990 mDrawFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001991 break;
1992 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001993 ASSERT(mVertexArray);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001994 mVertexArray->syncImplState();
1995 break;
1996 case DIRTY_OBJECT_PROGRAM:
1997 // TODO(jmadill): implement this
1998 break;
1999 default:
2000 UNREACHABLE();
2001 break;
2002 }
2003 }
2004
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002005 mDirtyObjects &= ~bitset;
2006}
2007
2008void State::syncDirtyObject(GLenum target)
2009{
2010 DirtyObjects localSet;
2011
2012 switch (target)
2013 {
2014 case GL_READ_FRAMEBUFFER:
2015 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2016 break;
2017 case GL_DRAW_FRAMEBUFFER:
2018 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2019 break;
2020 case GL_FRAMEBUFFER:
2021 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2022 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2023 break;
2024 case GL_VERTEX_ARRAY:
2025 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2026 break;
2027 case GL_PROGRAM:
2028 localSet.set(DIRTY_OBJECT_PROGRAM);
2029 break;
2030 }
2031
2032 syncDirtyObjects(localSet);
2033}
2034
2035void State::setObjectDirty(GLenum target)
2036{
2037 switch (target)
2038 {
2039 case GL_READ_FRAMEBUFFER:
2040 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2041 break;
2042 case GL_DRAW_FRAMEBUFFER:
2043 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2044 break;
2045 case GL_FRAMEBUFFER:
2046 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2047 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2048 break;
2049 case GL_VERTEX_ARRAY:
2050 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2051 break;
2052 case GL_PROGRAM:
2053 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
2054 break;
2055 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002056}
Jamie Madillc9d442d2016-01-20 11:17:24 -05002057
2058} // namespace gl