blob: c47824c5fee957101b73d2a97e2b31b2f9db1674 [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),
Jamie Madille08a1d32017-03-07 17:24:06 -050065 mFramebufferSRGB(true),
66 mRobustResourceInit(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040067{
Geoff Lang76b10c92014-09-05 16:28:14 -040068}
69
70State::~State()
71{
Geoff Lang76b10c92014-09-05 16:28:14 -040072}
73
Geoff Lang70d0f492015-12-10 17:45:46 -050074void State::initialize(const Caps &caps,
75 const Extensions &extensions,
Geoff Langeb66a6e2016-10-31 13:06:12 -040076 const Version &clientVersion,
Geoff Langf41a7152016-09-19 15:11:17 -040077 bool debug,
Geoff Langfeb8c682017-02-13 16:07:35 -050078 bool bindGeneratesResource,
Jamie Madille08a1d32017-03-07 17:24:06 -050079 bool clientArraysEnabled,
80 bool robustResourceInit)
Geoff Lang76b10c92014-09-05 16:28:14 -040081{
Shannon Woods2df6a602014-09-26 16:12:07 -040082 mMaxDrawBuffers = caps.maxDrawBuffers;
83 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040084
Jamie Madillf75ab352015-03-16 10:46:52 -040085 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040086
87 mDepthClearValue = 1.0f;
88 mStencilClearValue = 0;
89
90 mRasterizer.rasterizerDiscard = false;
91 mRasterizer.cullFace = false;
92 mRasterizer.cullMode = GL_BACK;
93 mRasterizer.frontFace = GL_CCW;
94 mRasterizer.polygonOffsetFill = false;
95 mRasterizer.polygonOffsetFactor = 0.0f;
96 mRasterizer.polygonOffsetUnits = 0.0f;
97 mRasterizer.pointDrawMode = false;
98 mRasterizer.multiSample = false;
99 mScissorTest = false;
100 mScissor.x = 0;
101 mScissor.y = 0;
102 mScissor.width = 0;
103 mScissor.height = 0;
104
105 mBlend.blend = false;
106 mBlend.sourceBlendRGB = GL_ONE;
107 mBlend.sourceBlendAlpha = GL_ONE;
108 mBlend.destBlendRGB = GL_ZERO;
109 mBlend.destBlendAlpha = GL_ZERO;
110 mBlend.blendEquationRGB = GL_FUNC_ADD;
111 mBlend.blendEquationAlpha = GL_FUNC_ADD;
112 mBlend.sampleAlphaToCoverage = false;
113 mBlend.dither = true;
114
115 mBlendColor.red = 0;
116 mBlendColor.green = 0;
117 mBlendColor.blue = 0;
118 mBlendColor.alpha = 0;
119
120 mDepthStencil.depthTest = false;
121 mDepthStencil.depthFunc = GL_LESS;
122 mDepthStencil.depthMask = true;
123 mDepthStencil.stencilTest = false;
124 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700125 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
126 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400127 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700128 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
129 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400130 mDepthStencil.stencilFail = GL_KEEP;
131 mDepthStencil.stencilPassDepthFail = GL_KEEP;
132 mDepthStencil.stencilPassDepthPass = GL_KEEP;
133 mDepthStencil.stencilBackFail = GL_KEEP;
134 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
135 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
136
137 mStencilRef = 0;
138 mStencilBackRef = 0;
139
140 mSampleCoverage = false;
141 mSampleCoverageValue = 1.0f;
142 mSampleCoverageInvert = false;
143 mGenerateMipmapHint = GL_DONT_CARE;
144 mFragmentShaderDerivativeHint = GL_DONT_CARE;
145
Geoff Langf41a7152016-09-19 15:11:17 -0400146 mBindGeneratesResource = bindGeneratesResource;
Geoff Langfeb8c682017-02-13 16:07:35 -0500147 mClientArraysEnabled = clientArraysEnabled;
Geoff Langf41a7152016-09-19 15:11:17 -0400148
Shannon Woods53a94a82014-06-24 15:20:36 -0400149 mLineWidth = 1.0f;
150
151 mViewport.x = 0;
152 mViewport.y = 0;
153 mViewport.width = 0;
154 mViewport.height = 0;
155 mNearZ = 0.0f;
156 mFarZ = 1.0f;
157
158 mBlend.colorMaskRed = true;
159 mBlend.colorMaskGreen = true;
160 mBlend.colorMaskBlue = true;
161 mBlend.colorMaskAlpha = true;
162
Geoff Lang76b10c92014-09-05 16:28:14 -0400163 mActiveSampler = 0;
164
Shannon Woods23e05002014-09-22 19:07:27 -0400165 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400166
Geoff Lang4dc3af02016-11-18 14:09:27 -0500167 mUniformBuffers.resize(caps.maxUniformBufferBindings);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400168
Geoff Lang76b10c92014-09-05 16:28:14 -0400169 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
170 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
Geoff Langeb66a6e2016-10-31 13:06:12 -0400171 if (clientVersion >= Version(3, 0))
Shannon Woods53a94a82014-06-24 15:20:36 -0400172 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400173 // TODO: These could also be enabled via extension
174 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
175 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400176 }
Geoff Lang3b573612016-10-31 14:08:10 -0400177 if (clientVersion >= Version(3, 1))
178 {
179 mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800180
181 mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
Geoff Lang3b573612016-10-31 14:08:10 -0400182 }
Ian Ewellbda75592016-04-18 17:25:54 -0400183 if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
184 {
185 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
186 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400187
Geoff Lang76b10c92014-09-05 16:28:14 -0400188 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400189
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500190 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
191 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
192 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
193 mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
Geoff Lang2b4ce802016-04-28 13:34:50 -0400194 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400195
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500196 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400197
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500198 mReadFramebuffer = nullptr;
199 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500200
201 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500202
203 mDebug.setOutputEnabled(debug);
204 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300205
206 if (extensions.framebufferMultisample)
207 {
208 mMultiSampling = true;
209 mSampleAlphaToOne = false;
210 }
Sami Väisänena797e062016-05-12 15:23:40 +0300211
212 mCoverageModulation = GL_NONE;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300213
214 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
215 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
216 mPathStencilFunc = GL_ALWAYS;
217 mPathStencilRef = 0;
218 mPathStencilMask = std::numeric_limits<GLuint>::max();
Jamie Madille08a1d32017-03-07 17:24:06 -0500219
220 mRobustResourceInit = robustResourceInit;
Shannon Woods53a94a82014-06-24 15:20:36 -0400221}
222
Jamie Madill6c1f6712017-02-14 19:08:04 -0500223void State::reset(const Context *context)
Shannon Woods53a94a82014-06-24 15:20:36 -0400224{
Geoff Lang76b10c92014-09-05 16:28:14 -0400225 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400226 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400227 TextureBindingVector &textureVector = bindingVec->second;
228 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400229 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400230 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400231 }
232 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400233 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
234 {
235 mSamplers[samplerIdx].set(NULL);
236 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400237
Shannon Woods53a94a82014-06-24 15:20:36 -0400238 mArrayBuffer.set(NULL);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +0800239 mDrawIndirectBuffer.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400240 mRenderbuffer.set(NULL);
241
Geoff Lang7dd2e102014-11-10 15:19:26 -0500242 if (mProgram)
243 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500244 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500245 }
246 mProgram = NULL;
247
Shannon Woods53a94a82014-06-24 15:20:36 -0400248 mTransformFeedback.set(NULL);
249
250 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
251 {
252 i->second.set(NULL);
253 }
254
255 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400256 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400257 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400258 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400259 }
260
Shannon Woods53a94a82014-06-24 15:20:36 -0400261 mCopyReadBuffer.set(NULL);
262 mCopyWriteBuffer.set(NULL);
263
264 mPack.pixelBuffer.set(NULL);
265 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500266
Jiajia Qin6eafb042016-12-27 17:04:07 +0800267 mGenericAtomicCounterBuffer.set(nullptr);
268 for (auto &buf : mAtomicCounterBuffers)
269 {
270 buf.set(nullptr);
271 }
272
Geoff Lang7dd2e102014-11-10 15:19:26 -0500273 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400274
Sami Väisänene45e53b2016-05-25 10:36:04 +0300275 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
276 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
277 mPathStencilFunc = GL_ALWAYS;
278 mPathStencilRef = 0;
279 mPathStencilMask = std::numeric_limits<GLuint>::max();
280
Jamie Madill1b94d432015-08-07 13:23:23 -0400281 // TODO(jmadill): Is this necessary?
282 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400283}
284
285const RasterizerState &State::getRasterizerState() const
286{
287 return mRasterizer;
288}
289
290const BlendState &State::getBlendState() const
291{
292 return mBlend;
293}
294
295const DepthStencilState &State::getDepthStencilState() const
296{
297 return mDepthStencil;
298}
299
Jamie Madillf75ab352015-03-16 10:46:52 -0400300void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400301{
302 mColorClearValue.red = red;
303 mColorClearValue.green = green;
304 mColorClearValue.blue = blue;
305 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400306 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400307}
308
Jamie Madillf75ab352015-03-16 10:46:52 -0400309void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400310{
311 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400312 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400313}
314
Jamie Madillf75ab352015-03-16 10:46:52 -0400315void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400316{
317 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400318 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400319}
320
Shannon Woods53a94a82014-06-24 15:20:36 -0400321void State::setColorMask(bool red, bool green, bool blue, bool alpha)
322{
323 mBlend.colorMaskRed = red;
324 mBlend.colorMaskGreen = green;
325 mBlend.colorMaskBlue = blue;
326 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400327 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400328}
329
330void State::setDepthMask(bool mask)
331{
332 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400333 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400334}
335
336bool State::isRasterizerDiscardEnabled() const
337{
338 return mRasterizer.rasterizerDiscard;
339}
340
341void State::setRasterizerDiscard(bool enabled)
342{
343 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400344 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400345}
346
347bool State::isCullFaceEnabled() const
348{
349 return mRasterizer.cullFace;
350}
351
352void State::setCullFace(bool enabled)
353{
354 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400355 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400356}
357
358void State::setCullMode(GLenum mode)
359{
360 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400361 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400362}
363
364void State::setFrontFace(GLenum front)
365{
366 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400367 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400368}
369
370bool State::isDepthTestEnabled() const
371{
372 return mDepthStencil.depthTest;
373}
374
375void State::setDepthTest(bool enabled)
376{
377 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400378 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400379}
380
381void State::setDepthFunc(GLenum depthFunc)
382{
383 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400384 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400385}
386
387void State::setDepthRange(float zNear, float zFar)
388{
389 mNearZ = zNear;
390 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400391 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400392}
393
Geoff Langd42f5b82015-04-16 14:03:29 -0400394float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400395{
Geoff Langd42f5b82015-04-16 14:03:29 -0400396 return mNearZ;
397}
398
399float State::getFarPlane() const
400{
401 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400402}
403
404bool State::isBlendEnabled() const
405{
406 return mBlend.blend;
407}
408
409void State::setBlend(bool enabled)
410{
411 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400412 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400413}
414
415void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
416{
417 mBlend.sourceBlendRGB = sourceRGB;
418 mBlend.destBlendRGB = destRGB;
419 mBlend.sourceBlendAlpha = sourceAlpha;
420 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400421 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400422}
423
424void State::setBlendColor(float red, float green, float blue, float alpha)
425{
426 mBlendColor.red = red;
427 mBlendColor.green = green;
428 mBlendColor.blue = blue;
429 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400430 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400431}
432
433void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
434{
435 mBlend.blendEquationRGB = rgbEquation;
436 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400437 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400438}
439
440const ColorF &State::getBlendColor() const
441{
442 return mBlendColor;
443}
444
445bool State::isStencilTestEnabled() const
446{
447 return mDepthStencil.stencilTest;
448}
449
450void State::setStencilTest(bool enabled)
451{
452 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400454}
455
456void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
457{
458 mDepthStencil.stencilFunc = stencilFunc;
459 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
460 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400461 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400462}
463
464void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
465{
466 mDepthStencil.stencilBackFunc = stencilBackFunc;
467 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
468 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400469 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400470}
471
472void State::setStencilWritemask(GLuint stencilWritemask)
473{
474 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400475 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400476}
477
478void State::setStencilBackWritemask(GLuint stencilBackWritemask)
479{
480 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400481 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400482}
483
484void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
485{
486 mDepthStencil.stencilFail = stencilFail;
487 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
488 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400489 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400490}
491
492void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
493{
494 mDepthStencil.stencilBackFail = stencilBackFail;
495 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
496 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400497 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400498}
499
500GLint State::getStencilRef() const
501{
502 return mStencilRef;
503}
504
505GLint State::getStencilBackRef() const
506{
507 return mStencilBackRef;
508}
509
510bool State::isPolygonOffsetFillEnabled() const
511{
512 return mRasterizer.polygonOffsetFill;
513}
514
515void State::setPolygonOffsetFill(bool enabled)
516{
Jamie Madill1b94d432015-08-07 13:23:23 -0400517 mRasterizer.polygonOffsetFill = enabled;
518 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400519}
520
521void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
522{
523 // An application can pass NaN values here, so handle this gracefully
524 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
525 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400526 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400527}
528
529bool State::isSampleAlphaToCoverageEnabled() const
530{
531 return mBlend.sampleAlphaToCoverage;
532}
533
534void State::setSampleAlphaToCoverage(bool enabled)
535{
536 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400537 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400538}
539
540bool State::isSampleCoverageEnabled() const
541{
542 return mSampleCoverage;
543}
544
545void State::setSampleCoverage(bool enabled)
546{
547 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400548 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400549}
550
551void State::setSampleCoverageParams(GLclampf value, bool invert)
552{
553 mSampleCoverageValue = value;
554 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400555 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400556}
557
Geoff Lang0fbb6002015-04-16 11:11:53 -0400558GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400559{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400560 return mSampleCoverageValue;
561}
Shannon Woods53a94a82014-06-24 15:20:36 -0400562
Geoff Lang0fbb6002015-04-16 11:11:53 -0400563bool State::getSampleCoverageInvert() const
564{
565 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400566}
567
Sami Väisänen74c23472016-05-09 17:30:30 +0300568void State::setSampleAlphaToOne(bool enabled)
569{
570 mSampleAlphaToOne = enabled;
571 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
572}
573
574bool State::isSampleAlphaToOneEnabled() const
575{
576 return mSampleAlphaToOne;
577}
578
579void State::setMultisampling(bool enabled)
580{
581 mMultiSampling = enabled;
582 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
583}
584
585bool State::isMultisamplingEnabled() const
586{
587 return mMultiSampling;
588}
589
Shannon Woods53a94a82014-06-24 15:20:36 -0400590bool State::isScissorTestEnabled() const
591{
592 return mScissorTest;
593}
594
595void State::setScissorTest(bool enabled)
596{
597 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400598 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400599}
600
601void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
602{
603 mScissor.x = x;
604 mScissor.y = y;
605 mScissor.width = width;
606 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400607 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400608}
609
610const Rectangle &State::getScissor() const
611{
612 return mScissor;
613}
614
615bool State::isDitherEnabled() const
616{
617 return mBlend.dither;
618}
619
620void State::setDither(bool enabled)
621{
622 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400623 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400624}
625
Jamie Madillb4b53c52015-02-03 15:22:48 -0500626bool State::isPrimitiveRestartEnabled() const
627{
628 return mPrimitiveRestart;
629}
630
631void State::setPrimitiveRestart(bool enabled)
632{
633 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400634 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500635}
636
Shannon Woods53a94a82014-06-24 15:20:36 -0400637void State::setEnableFeature(GLenum feature, bool enabled)
638{
639 switch (feature)
640 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300641 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
642 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400643 case GL_CULL_FACE: setCullFace(enabled); break;
644 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
645 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
646 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
647 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
648 case GL_STENCIL_TEST: setStencilTest(enabled); break;
649 case GL_DEPTH_TEST: setDepthTest(enabled); break;
650 case GL_BLEND: setBlend(enabled); break;
651 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500652 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400653 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang3b573612016-10-31 14:08:10 -0400654 case GL_SAMPLE_MASK:
Geoff Lang9f090372016-12-02 10:20:43 -0500655 if (enabled)
656 {
657 // Enabling this feature is not implemented yet.
658 UNIMPLEMENTED();
659 }
Geoff Lang3b573612016-10-31 14:08:10 -0400660 break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500661 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
662 mDebug.setOutputSynchronous(enabled);
663 break;
664 case GL_DEBUG_OUTPUT:
665 mDebug.setOutputEnabled(enabled);
666 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700667 case GL_FRAMEBUFFER_SRGB_EXT:
668 setFramebufferSRGB(enabled);
669 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400670 default: UNREACHABLE();
671 }
672}
673
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700674bool State::getEnableFeature(GLenum feature) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400675{
676 switch (feature)
677 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300678 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
679 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400680 case GL_CULL_FACE: return isCullFaceEnabled();
681 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
682 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
683 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
684 case GL_SCISSOR_TEST: return isScissorTestEnabled();
685 case GL_STENCIL_TEST: return isStencilTestEnabled();
686 case GL_DEPTH_TEST: return isDepthTestEnabled();
687 case GL_BLEND: return isBlendEnabled();
688 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500689 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400690 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Langb5e997f2016-12-06 10:55:34 -0500691 case GL_SAMPLE_MASK:
692 UNIMPLEMENTED();
693 return false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500694 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
695 return mDebug.isOutputSynchronous();
696 case GL_DEBUG_OUTPUT:
697 return mDebug.isOutputEnabled();
Geoff Langf41a7152016-09-19 15:11:17 -0400698 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
699 return isBindGeneratesResourceEnabled();
Geoff Langfeb8c682017-02-13 16:07:35 -0500700 case GL_CLIENT_ARRAYS_ANGLE:
701 return areClientArraysEnabled();
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700702 case GL_FRAMEBUFFER_SRGB_EXT:
703 return getFramebufferSRGB();
Jamie Madille08a1d32017-03-07 17:24:06 -0500704 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
705 return mRobustResourceInit;
Shannon Woods53a94a82014-06-24 15:20:36 -0400706 default: UNREACHABLE(); return false;
707 }
708}
709
710void State::setLineWidth(GLfloat width)
711{
712 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400713 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400714}
715
Geoff Lang4b3f4162015-04-16 13:22:05 -0400716float State::getLineWidth() const
717{
718 return mLineWidth;
719}
720
Shannon Woods53a94a82014-06-24 15:20:36 -0400721void State::setGenerateMipmapHint(GLenum hint)
722{
723 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400724 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400725}
726
727void State::setFragmentShaderDerivativeHint(GLenum hint)
728{
729 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400730 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400731 // TODO: Propagate the hint to shader translator so we can write
732 // ddx, ddx_coarse, or ddx_fine depending on the hint.
733 // Ignore for now. It is valid for implementations to ignore hint.
734}
735
Geoff Langf41a7152016-09-19 15:11:17 -0400736bool State::isBindGeneratesResourceEnabled() const
737{
738 return mBindGeneratesResource;
739}
740
Geoff Langfeb8c682017-02-13 16:07:35 -0500741bool State::areClientArraysEnabled() const
742{
743 return mClientArraysEnabled;
744}
745
Shannon Woods53a94a82014-06-24 15:20:36 -0400746void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
747{
748 mViewport.x = x;
749 mViewport.y = y;
750 mViewport.width = width;
751 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400752 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400753}
754
755const Rectangle &State::getViewport() const
756{
757 return mViewport;
758}
759
760void State::setActiveSampler(unsigned int active)
761{
762 mActiveSampler = active;
763}
764
765unsigned int State::getActiveSampler() const
766{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700767 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400768}
769
Geoff Lang76b10c92014-09-05 16:28:14 -0400770void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400771{
Geoff Lang76b10c92014-09-05 16:28:14 -0400772 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400773}
774
Jamie Madillc29968b2016-01-20 11:17:23 -0500775Texture *State::getTargetTexture(GLenum target) const
776{
777 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
778}
779
Geoff Lang76b10c92014-09-05 16:28:14 -0400780Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400781{
Jamie Madill5864ac22015-01-12 14:43:07 -0500782 const auto it = mSamplerTextures.find(type);
783 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400784 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500785 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400786}
787
Geoff Lang76b10c92014-09-05 16:28:14 -0400788GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400789{
Jamie Madill5864ac22015-01-12 14:43:07 -0500790 const auto it = mSamplerTextures.find(type);
791 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400792 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500793 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400794}
795
Jamie Madilla02315b2017-02-23 14:14:47 -0500796void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400797{
798 // Textures have a detach method on State rather than a simple
799 // removeBinding, because the zero/null texture objects are managed
800 // separately, and don't have to go through the Context's maps or
801 // the ResourceManager.
802
803 // [OpenGL ES 2.0.24] section 3.8 page 84:
804 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
805 // rebound to texture object zero
806
Corentin Walleza2257da2016-04-19 16:43:12 -0400807 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400808 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400809 GLenum textureType = bindingVec.first;
810 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400811 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400812 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400813 BindingPointer<Texture> &binding = textureVector[textureIdx];
814 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400815 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500816 auto it = zeroTextures.find(textureType);
817 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500818 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500819 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400820 }
821 }
822 }
823
824 // [OpenGL ES 2.0.24] section 4.4 page 112:
825 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
826 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
827 // image was attached in the currently bound framebuffer.
828
829 if (mReadFramebuffer)
830 {
Jamie Madilla02315b2017-02-23 14:14:47 -0500831 mReadFramebuffer->detachTexture(context, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400832 }
833
834 if (mDrawFramebuffer)
835 {
Jamie Madilla02315b2017-02-23 14:14:47 -0500836 mDrawFramebuffer->detachTexture(context, texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400837 }
838}
839
Jamie Madille6382c32014-11-07 15:05:26 -0500840void State::initializeZeroTextures(const TextureMap &zeroTextures)
841{
842 for (const auto &zeroTexture : zeroTextures)
843 {
844 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
845
846 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
847 {
848 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
849 }
850 }
851}
852
Shannon Woods53a94a82014-06-24 15:20:36 -0400853void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
854{
855 mSamplers[textureUnit].set(sampler);
856}
857
858GLuint State::getSamplerId(GLuint textureUnit) const
859{
Geoff Lang76b10c92014-09-05 16:28:14 -0400860 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400861 return mSamplers[textureUnit].id();
862}
863
864Sampler *State::getSampler(GLuint textureUnit) const
865{
866 return mSamplers[textureUnit].get();
867}
868
869void State::detachSampler(GLuint sampler)
870{
871 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
872 // If a sampler object that is currently bound to one or more texture units is
873 // deleted, it is as though BindSampler is called once for each texture unit to
874 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400875 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400876 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400877 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
878 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400879 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400880 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400881 }
882 }
883}
884
885void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
886{
887 mRenderbuffer.set(renderbuffer);
888}
889
890GLuint State::getRenderbufferId() const
891{
892 return mRenderbuffer.id();
893}
894
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700895Renderbuffer *State::getCurrentRenderbuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400896{
897 return mRenderbuffer.get();
898}
899
Jamie Madilla02315b2017-02-23 14:14:47 -0500900void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400901{
902 // [OpenGL ES 2.0.24] section 4.4 page 109:
903 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
904 // had been executed with the target RENDERBUFFER and name of zero.
905
906 if (mRenderbuffer.id() == renderbuffer)
907 {
908 mRenderbuffer.set(NULL);
909 }
910
911 // [OpenGL ES 2.0.24] section 4.4 page 111:
912 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
913 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
914 // point to which this image was attached in the currently bound framebuffer.
915
916 Framebuffer *readFramebuffer = mReadFramebuffer;
917 Framebuffer *drawFramebuffer = mDrawFramebuffer;
918
919 if (readFramebuffer)
920 {
Jamie Madilla02315b2017-02-23 14:14:47 -0500921 readFramebuffer->detachRenderbuffer(context, renderbuffer);
Shannon Woods53a94a82014-06-24 15:20:36 -0400922 }
923
924 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
925 {
Jamie Madilla02315b2017-02-23 14:14:47 -0500926 drawFramebuffer->detachRenderbuffer(context, renderbuffer);
Shannon Woods53a94a82014-06-24 15:20:36 -0400927 }
928
929}
930
931void State::setReadFramebufferBinding(Framebuffer *framebuffer)
932{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500933 if (mReadFramebuffer == framebuffer)
934 return;
935
Shannon Woods53a94a82014-06-24 15:20:36 -0400936 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500937 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
938
939 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
940 {
941 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
942 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400943}
944
945void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
946{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500947 if (mDrawFramebuffer == framebuffer)
948 return;
949
Shannon Woods53a94a82014-06-24 15:20:36 -0400950 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500951 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
952
953 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
954 {
955 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
956 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400957}
958
959Framebuffer *State::getTargetFramebuffer(GLenum target) const
960{
961 switch (target)
962 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500963 case GL_READ_FRAMEBUFFER_ANGLE:
964 return mReadFramebuffer;
965 case GL_DRAW_FRAMEBUFFER_ANGLE:
966 case GL_FRAMEBUFFER:
967 return mDrawFramebuffer;
968 default:
969 UNREACHABLE();
970 return NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400971 }
972}
973
Jamie Madill51f40ec2016-06-15 14:06:00 -0400974Framebuffer *State::getReadFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400975{
976 return mReadFramebuffer;
977}
978
Jamie Madill51f40ec2016-06-15 14:06:00 -0400979Framebuffer *State::getDrawFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400980{
981 return mDrawFramebuffer;
982}
983
984bool State::removeReadFramebufferBinding(GLuint framebuffer)
985{
Jamie Madill77a72f62015-04-14 11:18:32 -0400986 if (mReadFramebuffer != nullptr &&
987 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400988 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500989 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400990 return true;
991 }
992
993 return false;
994}
995
996bool State::removeDrawFramebufferBinding(GLuint framebuffer)
997{
Jamie Madill77a72f62015-04-14 11:18:32 -0400998 if (mReadFramebuffer != nullptr &&
999 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001000 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001001 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001002 return true;
1003 }
1004
1005 return false;
1006}
1007
1008void State::setVertexArrayBinding(VertexArray *vertexArray)
1009{
1010 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001011 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001012
1013 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1014 {
1015 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1016 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001017}
1018
1019GLuint State::getVertexArrayId() const
1020{
1021 ASSERT(mVertexArray != NULL);
1022 return mVertexArray->id();
1023}
1024
1025VertexArray *State::getVertexArray() const
1026{
1027 ASSERT(mVertexArray != NULL);
1028 return mVertexArray;
1029}
1030
1031bool State::removeVertexArrayBinding(GLuint vertexArray)
1032{
1033 if (mVertexArray->id() == vertexArray)
1034 {
1035 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001036 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001037 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001038 return true;
1039 }
1040
1041 return false;
1042}
1043
Jamie Madill6c1f6712017-02-14 19:08:04 -05001044void State::setProgram(const Context *context, Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001045{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001046 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001047 {
Geoff Lang7dd2e102014-11-10 15:19:26 -05001048 if (mProgram)
1049 {
Jamie Madill6c1f6712017-02-14 19:08:04 -05001050 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001051 }
1052
1053 mProgram = newProgram;
1054
1055 if (mProgram)
1056 {
1057 newProgram->addRef();
1058 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001059 }
1060}
1061
Geoff Lang7dd2e102014-11-10 15:19:26 -05001062Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001063{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001064 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -04001065}
1066
1067void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
1068{
1069 mTransformFeedback.set(transformFeedback);
1070}
1071
1072TransformFeedback *State::getCurrentTransformFeedback() const
1073{
1074 return mTransformFeedback.get();
1075}
1076
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001077bool State::isTransformFeedbackActiveUnpaused() const
1078{
1079 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001080 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001081}
1082
Corentin Walleza2257da2016-04-19 16:43:12 -04001083bool State::removeTransformFeedbackBinding(GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001084{
1085 if (mTransformFeedback.id() == transformFeedback)
1086 {
Corentin Walleza2257da2016-04-19 16:43:12 -04001087 mTransformFeedback.set(nullptr);
1088 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001089 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001090
1091 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001092}
1093
Olli Etuahobbf1c102016-06-28 13:31:33 +03001094bool State::isQueryActive(const GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001095{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001096 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001097 {
Olli Etuahobbf1c102016-06-28 13:31:33 +03001098 const Query *query = iter.second.get();
1099 if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001100 {
1101 return true;
1102 }
1103 }
1104
1105 return false;
1106}
1107
1108bool State::isQueryActive(Query *query) const
1109{
1110 for (auto &iter : mActiveQueries)
1111 {
1112 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001113 {
1114 return true;
1115 }
1116 }
1117
1118 return false;
1119}
1120
1121void State::setActiveQuery(GLenum target, Query *query)
1122{
1123 mActiveQueries[target].set(query);
1124}
1125
1126GLuint State::getActiveQueryId(GLenum target) const
1127{
1128 const Query *query = getActiveQuery(target);
1129 return (query ? query->id() : 0u);
1130}
1131
1132Query *State::getActiveQuery(GLenum target) const
1133{
Jamie Madill5864ac22015-01-12 14:43:07 -05001134 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001135
Jamie Madill5864ac22015-01-12 14:43:07 -05001136 // All query types should already exist in the activeQueries map
1137 ASSERT(it != mActiveQueries.end());
1138
1139 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001140}
1141
1142void State::setArrayBufferBinding(Buffer *buffer)
1143{
1144 mArrayBuffer.set(buffer);
1145}
1146
1147GLuint State::getArrayBufferId() const
1148{
1149 return mArrayBuffer.id();
1150}
1151
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001152void State::setDrawIndirectBufferBinding(Buffer *buffer)
1153{
1154 mDrawIndirectBuffer.set(buffer);
1155 mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
1156}
1157
Shannon Woods53a94a82014-06-24 15:20:36 -04001158void State::setGenericUniformBufferBinding(Buffer *buffer)
1159{
1160 mGenericUniformBuffer.set(buffer);
1161}
1162
1163void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1164{
1165 mUniformBuffers[index].set(buffer, offset, size);
1166}
1167
Geoff Lang5d124a62015-09-15 13:03:27 -04001168const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001169{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001170 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001171 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001172}
1173
Jiajia Qin6eafb042016-12-27 17:04:07 +08001174void State::setGenericAtomicCounterBufferBinding(Buffer *buffer)
1175{
1176 mGenericAtomicCounterBuffer.set(buffer);
1177}
1178
1179void State::setIndexedAtomicCounterBufferBinding(GLuint index,
1180 Buffer *buffer,
1181 GLintptr offset,
1182 GLsizeiptr size)
1183{
1184 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1185 mAtomicCounterBuffers[index].set(buffer, offset, size);
1186}
1187
1188const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
1189{
1190 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1191 return mAtomicCounterBuffers[index];
1192}
1193
Shannon Woods53a94a82014-06-24 15:20:36 -04001194void State::setCopyReadBufferBinding(Buffer *buffer)
1195{
1196 mCopyReadBuffer.set(buffer);
1197}
1198
1199void State::setCopyWriteBufferBinding(Buffer *buffer)
1200{
1201 mCopyWriteBuffer.set(buffer);
1202}
1203
1204void State::setPixelPackBufferBinding(Buffer *buffer)
1205{
1206 mPack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001207 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001208}
1209
1210void State::setPixelUnpackBufferBinding(Buffer *buffer)
1211{
1212 mUnpack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001213 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001214}
1215
1216Buffer *State::getTargetBuffer(GLenum target) const
1217{
1218 switch (target)
1219 {
1220 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1221 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1222 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001223 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001224 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1225 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001226 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001227 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001228 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001229 return mGenericAtomicCounterBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001230 case GL_SHADER_STORAGE_BUFFER:
1231 UNIMPLEMENTED();
1232 return nullptr;
1233 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001234 return mDrawIndirectBuffer.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001235 default: UNREACHABLE(); return NULL;
1236 }
1237}
1238
Yuly Novikov5807a532015-12-03 13:01:22 -05001239void State::detachBuffer(GLuint bufferName)
1240{
Jiajia Qin6eafb042016-12-27 17:04:07 +08001241 BindingPointer<Buffer> *buffers[] = {&mArrayBuffer, &mGenericAtomicCounterBuffer,
1242 &mCopyReadBuffer, &mCopyWriteBuffer,
1243 &mDrawIndirectBuffer, &mPack.pixelBuffer,
1244 &mUnpack.pixelBuffer, &mGenericUniformBuffer};
Yuly Novikov5807a532015-12-03 13:01:22 -05001245 for (auto buffer : buffers)
1246 {
1247 if (buffer->id() == bufferName)
1248 {
1249 buffer->set(nullptr);
1250 }
1251 }
1252
1253 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1254 if (curTransformFeedback)
1255 {
1256 curTransformFeedback->detachBuffer(bufferName);
1257 }
1258
1259 getVertexArray()->detachBuffer(bufferName);
1260}
1261
Shannon Woods53a94a82014-06-24 15:20:36 -04001262void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1263{
1264 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001265 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001266}
1267
1268void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1269{
Shannon Woods23e05002014-09-22 19:07:27 -04001270 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001271 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001272 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001273}
1274
1275void State::setVertexAttribu(GLuint index, const GLuint values[4])
1276{
Shannon Woods23e05002014-09-22 19:07:27 -04001277 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001278 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001279 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001280}
1281
1282void State::setVertexAttribi(GLuint index, const GLint values[4])
1283{
Shannon Woods23e05002014-09-22 19:07:27 -04001284 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001285 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001286 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001287}
1288
Jamie Madill0b9e9032015-08-17 11:51:52 +00001289void State::setVertexAttribState(unsigned int attribNum,
1290 Buffer *boundBuffer,
1291 GLint size,
1292 GLenum type,
1293 bool normalized,
1294 bool pureInteger,
1295 GLsizei stride,
1296 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001297{
1298 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001299 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001300}
1301
1302void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1303{
1304 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001305 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001306}
1307
Shannon Woods53a94a82014-06-24 15:20:36 -04001308const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1309{
Shannon Woods23e05002014-09-22 19:07:27 -04001310 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001311 return mVertexAttribCurrentValues[attribNum];
1312}
1313
Shannon Woods53a94a82014-06-24 15:20:36 -04001314const void *State::getVertexAttribPointer(unsigned int attribNum) const
1315{
1316 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1317}
1318
1319void State::setPackAlignment(GLint alignment)
1320{
1321 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001322 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001323}
1324
1325GLint State::getPackAlignment() const
1326{
1327 return mPack.alignment;
1328}
1329
1330void State::setPackReverseRowOrder(bool reverseRowOrder)
1331{
1332 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001333 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001334}
1335
1336bool State::getPackReverseRowOrder() const
1337{
1338 return mPack.reverseRowOrder;
1339}
1340
Minmin Gongadff67b2015-10-14 10:34:45 -04001341void State::setPackRowLength(GLint rowLength)
1342{
1343 mPack.rowLength = rowLength;
1344 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1345}
1346
1347GLint State::getPackRowLength() const
1348{
1349 return mPack.rowLength;
1350}
1351
1352void State::setPackSkipRows(GLint skipRows)
1353{
1354 mPack.skipRows = skipRows;
1355 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1356}
1357
1358GLint State::getPackSkipRows() const
1359{
1360 return mPack.skipRows;
1361}
1362
1363void State::setPackSkipPixels(GLint skipPixels)
1364{
1365 mPack.skipPixels = skipPixels;
1366 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1367}
1368
1369GLint State::getPackSkipPixels() const
1370{
1371 return mPack.skipPixels;
1372}
1373
Shannon Woods53a94a82014-06-24 15:20:36 -04001374const PixelPackState &State::getPackState() const
1375{
1376 return mPack;
1377}
1378
Jamie Madill87de3622015-03-16 10:41:44 -04001379PixelPackState &State::getPackState()
1380{
1381 return mPack;
1382}
1383
Shannon Woods53a94a82014-06-24 15:20:36 -04001384void State::setUnpackAlignment(GLint alignment)
1385{
1386 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001387 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001388}
1389
1390GLint State::getUnpackAlignment() const
1391{
1392 return mUnpack.alignment;
1393}
1394
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001395void State::setUnpackRowLength(GLint rowLength)
1396{
1397 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001398 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001399}
1400
1401GLint State::getUnpackRowLength() const
1402{
1403 return mUnpack.rowLength;
1404}
1405
Minmin Gongadff67b2015-10-14 10:34:45 -04001406void State::setUnpackImageHeight(GLint imageHeight)
1407{
1408 mUnpack.imageHeight = imageHeight;
1409 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1410}
1411
1412GLint State::getUnpackImageHeight() const
1413{
1414 return mUnpack.imageHeight;
1415}
1416
1417void State::setUnpackSkipImages(GLint skipImages)
1418{
1419 mUnpack.skipImages = skipImages;
1420 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1421}
1422
1423GLint State::getUnpackSkipImages() const
1424{
1425 return mUnpack.skipImages;
1426}
1427
1428void State::setUnpackSkipRows(GLint skipRows)
1429{
1430 mUnpack.skipRows = skipRows;
1431 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1432}
1433
1434GLint State::getUnpackSkipRows() const
1435{
1436 return mUnpack.skipRows;
1437}
1438
1439void State::setUnpackSkipPixels(GLint skipPixels)
1440{
1441 mUnpack.skipPixels = skipPixels;
1442 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1443}
1444
1445GLint State::getUnpackSkipPixels() const
1446{
1447 return mUnpack.skipPixels;
1448}
1449
Shannon Woods53a94a82014-06-24 15:20:36 -04001450const PixelUnpackState &State::getUnpackState() const
1451{
1452 return mUnpack;
1453}
1454
Jamie Madill67102f02015-03-16 10:41:42 -04001455PixelUnpackState &State::getUnpackState()
1456{
1457 return mUnpack;
1458}
1459
Geoff Lang70d0f492015-12-10 17:45:46 -05001460const Debug &State::getDebug() const
1461{
1462 return mDebug;
1463}
1464
1465Debug &State::getDebug()
1466{
1467 return mDebug;
1468}
1469
Sami Väisänena797e062016-05-12 15:23:40 +03001470void State::setCoverageModulation(GLenum components)
1471{
1472 mCoverageModulation = components;
1473 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1474}
1475
1476GLenum State::getCoverageModulation() const
1477{
1478 return mCoverageModulation;
1479}
1480
Sami Väisänene45e53b2016-05-25 10:36:04 +03001481void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1482{
1483 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1484 {
1485 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1486 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1487 }
1488 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1489 {
1490 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1491 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1492 }
1493 else
1494 {
1495 UNREACHABLE();
1496 }
1497}
1498
1499const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1500{
1501 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1502 {
1503 return mPathMatrixMV;
1504 }
1505 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1506 {
1507 return mPathMatrixProj;
1508 }
1509
1510 UNREACHABLE();
1511 return nullptr;
1512}
1513
1514void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1515{
1516 mPathStencilFunc = func;
1517 mPathStencilRef = ref;
1518 mPathStencilMask = mask;
1519 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1520}
1521
1522GLenum State::getPathStencilFunc() const
1523{
1524 return mPathStencilFunc;
1525}
1526
1527GLint State::getPathStencilRef() const
1528{
1529 return mPathStencilRef;
1530}
1531
1532GLuint State::getPathStencilMask() const
1533{
1534 return mPathStencilMask;
1535}
1536
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001537void State::setFramebufferSRGB(bool sRGB)
1538{
1539 mFramebufferSRGB = sRGB;
1540 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1541}
1542
1543bool State::getFramebufferSRGB() const
1544{
1545 return mFramebufferSRGB;
1546}
1547
Shannon Woods53a94a82014-06-24 15:20:36 -04001548void State::getBooleanv(GLenum pname, GLboolean *params)
1549{
1550 switch (pname)
1551 {
1552 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1553 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1554 case GL_COLOR_WRITEMASK:
1555 params[0] = mBlend.colorMaskRed;
1556 params[1] = mBlend.colorMaskGreen;
1557 params[2] = mBlend.colorMaskBlue;
1558 params[3] = mBlend.colorMaskAlpha;
1559 break;
1560 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1561 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1562 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1563 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1564 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1565 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1566 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1567 case GL_BLEND: *params = mBlend.blend; break;
1568 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001569 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1570 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001571 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1572 *params = mPrimitiveRestart;
1573 break;
Geoff Langab831f02015-12-01 09:39:10 -05001574 case GL_RASTERIZER_DISCARD:
1575 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1576 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001577 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1578 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1579 break;
1580 case GL_DEBUG_OUTPUT:
1581 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1582 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001583 case GL_MULTISAMPLE_EXT:
1584 *params = mMultiSampling;
1585 break;
1586 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1587 *params = mSampleAlphaToOne;
1588 break;
Geoff Langf41a7152016-09-19 15:11:17 -04001589 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1590 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1591 break;
Geoff Langfeb8c682017-02-13 16:07:35 -05001592 case GL_CLIENT_ARRAYS_ANGLE:
1593 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1594 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001595 case GL_FRAMEBUFFER_SRGB_EXT:
1596 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1597 break;
Jamie Madille08a1d32017-03-07 17:24:06 -05001598 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1599 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
1600 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001601 default:
1602 UNREACHABLE();
1603 break;
1604 }
1605}
1606
1607void State::getFloatv(GLenum pname, GLfloat *params)
1608{
1609 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1610 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1611 // GetIntegerv as its native query function. As it would require conversion in any
1612 // case, this should make no difference to the calling application.
1613 switch (pname)
1614 {
1615 case GL_LINE_WIDTH: *params = mLineWidth; break;
1616 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1617 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1618 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1619 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1620 case GL_DEPTH_RANGE:
1621 params[0] = mNearZ;
1622 params[1] = mFarZ;
1623 break;
1624 case GL_COLOR_CLEAR_VALUE:
1625 params[0] = mColorClearValue.red;
1626 params[1] = mColorClearValue.green;
1627 params[2] = mColorClearValue.blue;
1628 params[3] = mColorClearValue.alpha;
1629 break;
1630 case GL_BLEND_COLOR:
1631 params[0] = mBlendColor.red;
1632 params[1] = mBlendColor.green;
1633 params[2] = mBlendColor.blue;
1634 params[3] = mBlendColor.alpha;
1635 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001636 case GL_MULTISAMPLE_EXT:
1637 *params = static_cast<GLfloat>(mMultiSampling);
1638 break;
1639 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1640 *params = static_cast<GLfloat>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001641 case GL_COVERAGE_MODULATION_CHROMIUM:
Jamie Madille2e406c2016-06-02 13:04:10 -04001642 params[0] = static_cast<GLfloat>(mCoverageModulation);
1643 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001644 default:
1645 UNREACHABLE();
1646 break;
1647 }
1648}
1649
Jamie Madill9082b982016-04-27 15:21:51 -04001650void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001651{
1652 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1653 {
1654 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001655 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001656 Framebuffer *framebuffer = mDrawFramebuffer;
1657 *params = framebuffer->getDrawBufferState(colorAttachment);
1658 return;
1659 }
1660
1661 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1662 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1663 // GetIntegerv as its native query function. As it would require conversion in any
1664 // case, this should make no difference to the calling application. You may find it in
1665 // State::getFloatv.
1666 switch (pname)
1667 {
1668 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001669 case GL_DRAW_INDIRECT_BUFFER_BINDING:
1670 *params = mDrawIndirectBuffer.id();
1671 break;
Jamie Madill8e344942015-07-09 14:22:07 -04001672 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001673 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1674 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1675 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1676 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1677 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001678 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001679 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1680 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001681 case GL_PACK_ROW_LENGTH:
1682 *params = mPack.rowLength;
1683 break;
1684 case GL_PACK_SKIP_ROWS:
1685 *params = mPack.skipRows;
1686 break;
1687 case GL_PACK_SKIP_PIXELS:
1688 *params = mPack.skipPixels;
1689 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001690 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001691 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001692 case GL_UNPACK_IMAGE_HEIGHT:
1693 *params = mUnpack.imageHeight;
1694 break;
1695 case GL_UNPACK_SKIP_IMAGES:
1696 *params = mUnpack.skipImages;
1697 break;
1698 case GL_UNPACK_SKIP_ROWS:
1699 *params = mUnpack.skipRows;
1700 break;
1701 case GL_UNPACK_SKIP_PIXELS:
1702 *params = mUnpack.skipPixels;
1703 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001704 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1705 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001706 case GL_ACTIVE_TEXTURE:
1707 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1708 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001709 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1710 case GL_STENCIL_REF: *params = mStencilRef; break;
1711 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1712 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1713 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1714 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1715 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1716 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1717 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1718 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1719 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1720 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1721 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1722 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1723 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1724 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1725 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1726 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1727 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1728 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1729 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1730 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001731 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1732 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001733 case GL_SAMPLE_BUFFERS:
1734 case GL_SAMPLES:
1735 {
1736 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001737 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001738 {
1739 switch (pname)
1740 {
1741 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001742 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001743 {
1744 *params = 1;
1745 }
1746 else
1747 {
1748 *params = 0;
1749 }
1750 break;
1751 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001752 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001753 break;
1754 }
1755 }
1756 else
1757 {
1758 *params = 0;
1759 }
1760 }
1761 break;
1762 case GL_VIEWPORT:
1763 params[0] = mViewport.x;
1764 params[1] = mViewport.y;
1765 params[2] = mViewport.width;
1766 params[3] = mViewport.height;
1767 break;
1768 case GL_SCISSOR_BOX:
1769 params[0] = mScissor.x;
1770 params[1] = mScissor.y;
1771 params[2] = mScissor.width;
1772 params[3] = mScissor.height;
1773 break;
1774 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1775 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1776 case GL_RED_BITS:
1777 case GL_GREEN_BITS:
1778 case GL_BLUE_BITS:
1779 case GL_ALPHA_BITS:
1780 {
1781 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001782 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001783
1784 if (colorbuffer)
1785 {
1786 switch (pname)
1787 {
1788 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1789 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1790 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1791 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1792 }
1793 }
1794 else
1795 {
1796 *params = 0;
1797 }
1798 }
1799 break;
1800 case GL_DEPTH_BITS:
1801 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001802 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1803 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001804
1805 if (depthbuffer)
1806 {
1807 *params = depthbuffer->getDepthSize();
1808 }
1809 else
1810 {
1811 *params = 0;
1812 }
1813 }
1814 break;
1815 case GL_STENCIL_BITS:
1816 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001817 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1818 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001819
1820 if (stencilbuffer)
1821 {
1822 *params = stencilbuffer->getStencilSize();
1823 }
1824 else
1825 {
1826 *params = 0;
1827 }
1828 }
1829 break;
1830 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001831 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001832 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001833 break;
1834 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001835 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001836 *params =
1837 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001838 break;
1839 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001840 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001841 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001842 break;
1843 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001844 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001845 *params =
1846 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001847 break;
John Bauman18319182016-09-28 14:22:27 -07001848 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1849 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1850 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1851 GL_TEXTURE_EXTERNAL_OES);
1852 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001853 case GL_UNIFORM_BUFFER_BINDING:
1854 *params = mGenericUniformBuffer.id();
1855 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001856 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001857 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001858 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001859 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001860 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001861 break;
1862 case GL_COPY_READ_BUFFER_BINDING:
1863 *params = mCopyReadBuffer.id();
1864 break;
1865 case GL_COPY_WRITE_BUFFER_BINDING:
1866 *params = mCopyWriteBuffer.id();
1867 break;
1868 case GL_PIXEL_PACK_BUFFER_BINDING:
1869 *params = mPack.pixelBuffer.id();
1870 break;
1871 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1872 *params = mUnpack.pixelBuffer.id();
1873 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02001874 case GL_READ_BUFFER:
1875 *params = mReadFramebuffer->getReadBufferState();
1876 break;
1877 case GL_SAMPLER_BINDING:
1878 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1879 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
1880 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001881 case GL_DEBUG_LOGGED_MESSAGES:
1882 *params = static_cast<GLint>(mDebug.getMessageCount());
1883 break;
1884 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1885 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1886 break;
1887 case GL_DEBUG_GROUP_STACK_DEPTH:
1888 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1889 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001890 case GL_MULTISAMPLE_EXT:
1891 *params = static_cast<GLint>(mMultiSampling);
1892 break;
1893 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1894 *params = static_cast<GLint>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001895 case GL_COVERAGE_MODULATION_CHROMIUM:
1896 *params = static_cast<GLint>(mCoverageModulation);
Sami Väisänen74c23472016-05-09 17:30:30 +03001897 break;
Jiajia Qin6eafb042016-12-27 17:04:07 +08001898 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
1899 *params = mGenericAtomicCounterBuffer.id();
1900 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001901 default:
1902 UNREACHABLE();
1903 break;
1904 }
1905}
1906
Geoff Lang70d0f492015-12-10 17:45:46 -05001907void State::getPointerv(GLenum pname, void **params) const
1908{
1909 switch (pname)
1910 {
1911 case GL_DEBUG_CALLBACK_FUNCTION:
1912 *params = reinterpret_cast<void *>(mDebug.getCallback());
1913 break;
1914 case GL_DEBUG_CALLBACK_USER_PARAM:
1915 *params = const_cast<void *>(mDebug.getUserParam());
1916 break;
1917 default:
1918 UNREACHABLE();
1919 break;
1920 }
1921}
1922
Martin Radev66fb8202016-07-28 11:45:20 +03001923void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04001924{
1925 switch (target)
1926 {
1927 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001928 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
1929 *data = mTransformFeedback->getIndexedBuffer(index).id();
1930 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001931 case GL_UNIFORM_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001932 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1933 *data = mUniformBuffers[index].id();
1934 break;
1935 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
1936 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1937 *data = mAtomicCounterBuffers[index].id();
1938 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001939 default:
Martin Radev66fb8202016-07-28 11:45:20 +03001940 UNREACHABLE();
1941 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001942 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001943}
1944
Martin Radev66fb8202016-07-28 11:45:20 +03001945void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04001946{
1947 switch (target)
1948 {
1949 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001950 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
1951 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
1952 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001953 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001954 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
1955 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
1956 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001957 case GL_UNIFORM_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001958 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1959 *data = mUniformBuffers[index].getOffset();
1960 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001961 case GL_UNIFORM_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001962 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
1963 *data = mUniformBuffers[index].getSize();
1964 break;
1965 case GL_ATOMIC_COUNTER_BUFFER_START:
1966 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1967 *data = mAtomicCounterBuffers[index].getOffset();
1968 break;
1969 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
1970 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1971 *data = mAtomicCounterBuffers[index].getSize();
1972 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001973 default:
Martin Radev66fb8202016-07-28 11:45:20 +03001974 UNREACHABLE();
1975 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001976 }
Martin Radev66fb8202016-07-28 11:45:20 +03001977}
Shannon Woods53a94a82014-06-24 15:20:36 -04001978
Martin Radev66fb8202016-07-28 11:45:20 +03001979void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
1980{
1981 UNREACHABLE();
Shannon Woods53a94a82014-06-24 15:20:36 -04001982}
1983
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001984bool State::hasMappedBuffer(GLenum target) const
1985{
1986 if (target == GL_ARRAY_BUFFER)
1987 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08001988 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001989 const auto &vertexAttribs = vao->getVertexAttributes();
Jiawei-Shao2597fb62016-12-09 16:38:02 +08001990 const auto &vertexBindings = vao->getVertexBindings();
Jamie Madill8e344942015-07-09 14:22:07 -04001991 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001992 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001993 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001994 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jiawei-Shao2597fb62016-12-09 16:38:02 +08001995 auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].buffer.get();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001996 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1997 {
1998 return true;
1999 }
2000 }
2001
2002 return false;
2003 }
2004 else
2005 {
2006 Buffer *buffer = getTargetBuffer(target);
2007 return (buffer && buffer->isMapped());
2008 }
2009}
2010
Jamie Madillc9d442d2016-01-20 11:17:24 -05002011void State::syncDirtyObjects()
2012{
2013 if (!mDirtyObjects.any())
2014 return;
2015
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002016 syncDirtyObjects(mDirtyObjects);
2017}
2018
2019void State::syncDirtyObjects(const DirtyObjects &bitset)
2020{
2021 for (auto dirtyObject : angle::IterateBitSet(bitset))
Jamie Madillc9d442d2016-01-20 11:17:24 -05002022 {
2023 switch (dirtyObject)
2024 {
2025 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002026 ASSERT(mReadFramebuffer);
2027 mReadFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002028 break;
2029 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002030 ASSERT(mDrawFramebuffer);
2031 mDrawFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05002032 break;
2033 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002034 ASSERT(mVertexArray);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002035 mVertexArray->syncImplState();
2036 break;
2037 case DIRTY_OBJECT_PROGRAM:
2038 // TODO(jmadill): implement this
2039 break;
2040 default:
2041 UNREACHABLE();
2042 break;
2043 }
2044 }
2045
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002046 mDirtyObjects &= ~bitset;
2047}
2048
2049void State::syncDirtyObject(GLenum target)
2050{
2051 DirtyObjects localSet;
2052
2053 switch (target)
2054 {
2055 case GL_READ_FRAMEBUFFER:
2056 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2057 break;
2058 case GL_DRAW_FRAMEBUFFER:
2059 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2060 break;
2061 case GL_FRAMEBUFFER:
2062 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2063 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2064 break;
2065 case GL_VERTEX_ARRAY:
2066 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2067 break;
2068 case GL_PROGRAM:
2069 localSet.set(DIRTY_OBJECT_PROGRAM);
2070 break;
2071 }
2072
2073 syncDirtyObjects(localSet);
2074}
2075
2076void State::setObjectDirty(GLenum target)
2077{
2078 switch (target)
2079 {
2080 case GL_READ_FRAMEBUFFER:
2081 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2082 break;
2083 case GL_DRAW_FRAMEBUFFER:
2084 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2085 break;
2086 case GL_FRAMEBUFFER:
2087 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2088 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2089 break;
2090 case GL_VERTEX_ARRAY:
2091 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2092 break;
2093 case GL_PROGRAM:
2094 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
2095 break;
2096 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002097}
Jamie Madillc9d442d2016-01-20 11:17:24 -05002098
2099} // namespace gl