blob: dcf65c3f23523464ec454194c87bfeb5b17e130f [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 Madill20e005b2017-04-07 14:19:22 -040014#include "common/bitset_utils.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),
Jamie Madillc43be722017-07-13 16:22:14 -040066 mRobustResourceInit(false),
67 mProgramBinaryCacheEnabled(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040068{
Geoff Lang76b10c92014-09-05 16:28:14 -040069}
70
71State::~State()
72{
Geoff Lang76b10c92014-09-05 16:28:14 -040073}
74
Jamie Madill4928b7c2017-06-20 12:57:39 -040075void State::initialize(const Context *context,
Geoff Langf41a7152016-09-19 15:11:17 -040076 bool debug,
Geoff Langfeb8c682017-02-13 16:07:35 -050077 bool bindGeneratesResource,
Jamie Madille08a1d32017-03-07 17:24:06 -050078 bool clientArraysEnabled,
Jamie Madillc43be722017-07-13 16:22:14 -040079 bool robustResourceInit,
80 bool programBinaryCacheEnabled)
Geoff Lang76b10c92014-09-05 16:28:14 -040081{
Jamie Madill4928b7c2017-06-20 12:57:39 -040082 const Caps &caps = context->getCaps();
83 const Extensions &extensions = context->getExtensions();
84 const Version &clientVersion = context->getClientVersion();
85
Shannon Woods2df6a602014-09-26 16:12:07 -040086 mMaxDrawBuffers = caps.maxDrawBuffers;
87 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040088
Jamie Madillf75ab352015-03-16 10:46:52 -040089 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040090
91 mDepthClearValue = 1.0f;
92 mStencilClearValue = 0;
93
Shannon Woods53a94a82014-06-24 15:20:36 -040094 mScissorTest = false;
95 mScissor.x = 0;
96 mScissor.y = 0;
97 mScissor.width = 0;
98 mScissor.height = 0;
99
Shannon Woods53a94a82014-06-24 15:20:36 -0400100 mBlendColor.red = 0;
101 mBlendColor.green = 0;
102 mBlendColor.blue = 0;
103 mBlendColor.alpha = 0;
104
Shannon Woods53a94a82014-06-24 15:20:36 -0400105 mStencilRef = 0;
106 mStencilBackRef = 0;
107
108 mSampleCoverage = false;
109 mSampleCoverageValue = 1.0f;
110 mSampleCoverageInvert = false;
111 mGenerateMipmapHint = GL_DONT_CARE;
112 mFragmentShaderDerivativeHint = GL_DONT_CARE;
113
Geoff Langf41a7152016-09-19 15:11:17 -0400114 mBindGeneratesResource = bindGeneratesResource;
Geoff Langfeb8c682017-02-13 16:07:35 -0500115 mClientArraysEnabled = clientArraysEnabled;
Geoff Langf41a7152016-09-19 15:11:17 -0400116
Shannon Woods53a94a82014-06-24 15:20:36 -0400117 mLineWidth = 1.0f;
118
119 mViewport.x = 0;
120 mViewport.y = 0;
121 mViewport.width = 0;
122 mViewport.height = 0;
123 mNearZ = 0.0f;
124 mFarZ = 1.0f;
125
126 mBlend.colorMaskRed = true;
127 mBlend.colorMaskGreen = true;
128 mBlend.colorMaskBlue = true;
129 mBlend.colorMaskAlpha = true;
130
Geoff Lang76b10c92014-09-05 16:28:14 -0400131 mActiveSampler = 0;
132
Shannon Woods23e05002014-09-22 19:07:27 -0400133 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400134
Geoff Lang4dc3af02016-11-18 14:09:27 -0500135 mUniformBuffers.resize(caps.maxUniformBufferBindings);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400136
Geoff Lang76b10c92014-09-05 16:28:14 -0400137 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
138 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
Geoff Langeb66a6e2016-10-31 13:06:12 -0400139 if (clientVersion >= Version(3, 0))
Shannon Woods53a94a82014-06-24 15:20:36 -0400140 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400141 // TODO: These could also be enabled via extension
142 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
143 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400144 }
Geoff Lang3b573612016-10-31 14:08:10 -0400145 if (clientVersion >= Version(3, 1))
146 {
147 mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800148
149 mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800150 mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800151 mImageUnits.resize(caps.maxImageUnits);
Geoff Lang3b573612016-10-31 14:08:10 -0400152 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400153 if (extensions.textureRectangle)
154 {
155 mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
156 }
Ian Ewellbda75592016-04-18 17:25:54 -0400157 if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
158 {
159 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
160 }
Jamie Madill81c2e252017-09-09 23:32:46 -0400161 mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
162 mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
163 for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
164 ++textureIndex)
165 {
166 mCompleteTextureBindings.emplace_back(OnAttachmentDirtyBinding(this, textureIndex));
167 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400168
Geoff Lang76b10c92014-09-05 16:28:14 -0400169 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400170
Jamie Madill4928b7c2017-06-20 12:57:39 -0400171 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(context, nullptr);
172 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(context, nullptr);
173 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(context, nullptr);
174 mActiveQueries[GL_TIME_ELAPSED_EXT].set(context, nullptr);
175 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400176
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500177 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400178
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500179 mReadFramebuffer = nullptr;
180 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500181
182 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500183
184 mDebug.setOutputEnabled(debug);
185 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300186
187 if (extensions.framebufferMultisample)
188 {
189 mMultiSampling = true;
190 mSampleAlphaToOne = false;
191 }
Sami Väisänena797e062016-05-12 15:23:40 +0300192
193 mCoverageModulation = GL_NONE;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300194
195 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
196 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
197 mPathStencilFunc = GL_ALWAYS;
198 mPathStencilRef = 0;
199 mPathStencilMask = std::numeric_limits<GLuint>::max();
Jamie Madille08a1d32017-03-07 17:24:06 -0500200
201 mRobustResourceInit = robustResourceInit;
Jamie Madillc43be722017-07-13 16:22:14 -0400202 mProgramBinaryCacheEnabled = programBinaryCacheEnabled;
Shannon Woods53a94a82014-06-24 15:20:36 -0400203}
204
Jamie Madill6c1f6712017-02-14 19:08:04 -0500205void State::reset(const Context *context)
Shannon Woods53a94a82014-06-24 15:20:36 -0400206{
Jamie Madill8693bdb2017-09-02 15:32:14 -0400207 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400208 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400209 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400210 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400211 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400212 textureVector[textureIdx].set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400213 }
214 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400215 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
216 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400217 mSamplers[samplerIdx].set(context, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400218 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400219
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800220 for (auto &imageUnit : mImageUnits)
221 {
222 imageUnit.texture.set(context, nullptr);
223 imageUnit.level = 0;
224 imageUnit.layered = false;
225 imageUnit.layer = 0;
226 imageUnit.access = GL_READ_ONLY;
227 imageUnit.format = GL_R32UI;
228 }
229
Jamie Madill4928b7c2017-06-20 12:57:39 -0400230 mArrayBuffer.set(context, nullptr);
231 mDrawIndirectBuffer.set(context, nullptr);
232 mRenderbuffer.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400233
Geoff Lang7dd2e102014-11-10 15:19:26 -0500234 if (mProgram)
235 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500236 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500237 }
Yunchao Hed7297bf2017-04-19 15:27:10 +0800238 mProgram = nullptr;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500239
Yunchao Hea336b902017-08-02 16:05:21 +0800240 mProgramPipeline.set(context, nullptr);
241
Jamie Madill4928b7c2017-06-20 12:57:39 -0400242 mTransformFeedback.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400243
244 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
245 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400246 i->second.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400247 }
248
Jamie Madill4928b7c2017-06-20 12:57:39 -0400249 mGenericUniformBuffer.set(context, nullptr);
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 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400252 bufItr->set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400253 }
254
Jamie Madill4928b7c2017-06-20 12:57:39 -0400255 mCopyReadBuffer.set(context, nullptr);
256 mCopyWriteBuffer.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400257
Jamie Madill4928b7c2017-06-20 12:57:39 -0400258 mPack.pixelBuffer.set(context, nullptr);
259 mUnpack.pixelBuffer.set(context, nullptr);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500260
Jamie Madill4928b7c2017-06-20 12:57:39 -0400261 mGenericAtomicCounterBuffer.set(context, nullptr);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800262 for (auto &buf : mAtomicCounterBuffers)
263 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400264 buf.set(context, nullptr);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800265 }
266
Jamie Madill4928b7c2017-06-20 12:57:39 -0400267 mGenericShaderStorageBuffer.set(context, nullptr);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800268 for (auto &buf : mShaderStorageBuffers)
269 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400270 buf.set(context, nullptr);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800271 }
272
Sami Väisänene45e53b2016-05-25 10:36:04 +0300273 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
274 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
275 mPathStencilFunc = GL_ALWAYS;
276 mPathStencilRef = 0;
277 mPathStencilMask = std::numeric_limits<GLuint>::max();
278
Jamie Madill1b94d432015-08-07 13:23:23 -0400279 // TODO(jmadill): Is this necessary?
280 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400281}
282
283const RasterizerState &State::getRasterizerState() const
284{
285 return mRasterizer;
286}
287
288const BlendState &State::getBlendState() const
289{
290 return mBlend;
291}
292
293const DepthStencilState &State::getDepthStencilState() const
294{
295 return mDepthStencil;
296}
297
Jamie Madillf75ab352015-03-16 10:46:52 -0400298void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400299{
300 mColorClearValue.red = red;
301 mColorClearValue.green = green;
302 mColorClearValue.blue = blue;
303 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400304 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400305}
306
Jamie Madillf75ab352015-03-16 10:46:52 -0400307void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400308{
309 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400310 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400311}
312
Jamie Madillf75ab352015-03-16 10:46:52 -0400313void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400314{
315 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400316 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400317}
318
Shannon Woods53a94a82014-06-24 15:20:36 -0400319void State::setColorMask(bool red, bool green, bool blue, bool alpha)
320{
321 mBlend.colorMaskRed = red;
322 mBlend.colorMaskGreen = green;
323 mBlend.colorMaskBlue = blue;
324 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400325 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400326}
327
328void State::setDepthMask(bool mask)
329{
330 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400331 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400332}
333
334bool State::isRasterizerDiscardEnabled() const
335{
336 return mRasterizer.rasterizerDiscard;
337}
338
339void State::setRasterizerDiscard(bool enabled)
340{
341 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400342 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400343}
344
345bool State::isCullFaceEnabled() const
346{
347 return mRasterizer.cullFace;
348}
349
350void State::setCullFace(bool enabled)
351{
352 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400353 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400354}
355
356void State::setCullMode(GLenum mode)
357{
358 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400359 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400360}
361
362void State::setFrontFace(GLenum front)
363{
364 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400365 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400366}
367
368bool State::isDepthTestEnabled() const
369{
370 return mDepthStencil.depthTest;
371}
372
373void State::setDepthTest(bool enabled)
374{
375 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400376 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400377}
378
379void State::setDepthFunc(GLenum depthFunc)
380{
381 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400382 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400383}
384
385void State::setDepthRange(float zNear, float zFar)
386{
387 mNearZ = zNear;
388 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400389 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400390}
391
Geoff Langd42f5b82015-04-16 14:03:29 -0400392float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400393{
Geoff Langd42f5b82015-04-16 14:03:29 -0400394 return mNearZ;
395}
396
397float State::getFarPlane() const
398{
399 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400400}
401
402bool State::isBlendEnabled() const
403{
404 return mBlend.blend;
405}
406
407void State::setBlend(bool enabled)
408{
409 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400410 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400411}
412
413void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
414{
415 mBlend.sourceBlendRGB = sourceRGB;
416 mBlend.destBlendRGB = destRGB;
417 mBlend.sourceBlendAlpha = sourceAlpha;
418 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400419 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400420}
421
422void State::setBlendColor(float red, float green, float blue, float alpha)
423{
424 mBlendColor.red = red;
425 mBlendColor.green = green;
426 mBlendColor.blue = blue;
427 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400428 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400429}
430
431void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
432{
433 mBlend.blendEquationRGB = rgbEquation;
434 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400435 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400436}
437
438const ColorF &State::getBlendColor() const
439{
440 return mBlendColor;
441}
442
443bool State::isStencilTestEnabled() const
444{
445 return mDepthStencil.stencilTest;
446}
447
448void State::setStencilTest(bool enabled)
449{
450 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400451 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400452}
453
454void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
455{
456 mDepthStencil.stencilFunc = stencilFunc;
457 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
458 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400459 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400460}
461
462void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
463{
464 mDepthStencil.stencilBackFunc = stencilBackFunc;
465 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
466 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400467 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400468}
469
470void State::setStencilWritemask(GLuint stencilWritemask)
471{
472 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400473 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400474}
475
476void State::setStencilBackWritemask(GLuint stencilBackWritemask)
477{
478 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400479 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400480}
481
482void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
483{
484 mDepthStencil.stencilFail = stencilFail;
485 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
486 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400487 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400488}
489
490void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
491{
492 mDepthStencil.stencilBackFail = stencilBackFail;
493 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
494 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400495 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400496}
497
498GLint State::getStencilRef() const
499{
500 return mStencilRef;
501}
502
503GLint State::getStencilBackRef() const
504{
505 return mStencilBackRef;
506}
507
508bool State::isPolygonOffsetFillEnabled() const
509{
510 return mRasterizer.polygonOffsetFill;
511}
512
513void State::setPolygonOffsetFill(bool enabled)
514{
Jamie Madill1b94d432015-08-07 13:23:23 -0400515 mRasterizer.polygonOffsetFill = enabled;
516 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400517}
518
519void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
520{
521 // An application can pass NaN values here, so handle this gracefully
522 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
523 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400524 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400525}
526
527bool State::isSampleAlphaToCoverageEnabled() const
528{
529 return mBlend.sampleAlphaToCoverage;
530}
531
532void State::setSampleAlphaToCoverage(bool enabled)
533{
534 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400535 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400536}
537
538bool State::isSampleCoverageEnabled() const
539{
540 return mSampleCoverage;
541}
542
543void State::setSampleCoverage(bool enabled)
544{
545 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400546 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400547}
548
549void State::setSampleCoverageParams(GLclampf value, bool invert)
550{
551 mSampleCoverageValue = value;
552 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400553 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400554}
555
Geoff Lang0fbb6002015-04-16 11:11:53 -0400556GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400557{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400558 return mSampleCoverageValue;
559}
Shannon Woods53a94a82014-06-24 15:20:36 -0400560
Geoff Lang0fbb6002015-04-16 11:11:53 -0400561bool State::getSampleCoverageInvert() const
562{
563 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400564}
565
Sami Väisänen74c23472016-05-09 17:30:30 +0300566void State::setSampleAlphaToOne(bool enabled)
567{
568 mSampleAlphaToOne = enabled;
569 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
570}
571
572bool State::isSampleAlphaToOneEnabled() const
573{
574 return mSampleAlphaToOne;
575}
576
577void State::setMultisampling(bool enabled)
578{
579 mMultiSampling = enabled;
580 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
581}
582
583bool State::isMultisamplingEnabled() const
584{
585 return mMultiSampling;
586}
587
Shannon Woods53a94a82014-06-24 15:20:36 -0400588bool State::isScissorTestEnabled() const
589{
590 return mScissorTest;
591}
592
593void State::setScissorTest(bool enabled)
594{
595 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400596 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400597}
598
599void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
600{
601 mScissor.x = x;
602 mScissor.y = y;
603 mScissor.width = width;
604 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400605 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400606}
607
608const Rectangle &State::getScissor() const
609{
610 return mScissor;
611}
612
613bool State::isDitherEnabled() const
614{
615 return mBlend.dither;
616}
617
618void State::setDither(bool enabled)
619{
620 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400621 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400622}
623
Jamie Madillb4b53c52015-02-03 15:22:48 -0500624bool State::isPrimitiveRestartEnabled() const
625{
626 return mPrimitiveRestart;
627}
628
629void State::setPrimitiveRestart(bool enabled)
630{
631 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400632 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500633}
634
Shannon Woods53a94a82014-06-24 15:20:36 -0400635void State::setEnableFeature(GLenum feature, bool enabled)
636{
637 switch (feature)
638 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300639 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
640 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400641 case GL_CULL_FACE: setCullFace(enabled); break;
642 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
643 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
644 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
645 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
646 case GL_STENCIL_TEST: setStencilTest(enabled); break;
647 case GL_DEPTH_TEST: setDepthTest(enabled); break;
648 case GL_BLEND: setBlend(enabled); break;
649 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500650 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400651 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang3b573612016-10-31 14:08:10 -0400652 case GL_SAMPLE_MASK:
Geoff Lang9f090372016-12-02 10:20:43 -0500653 if (enabled)
654 {
655 // Enabling this feature is not implemented yet.
656 UNIMPLEMENTED();
657 }
Geoff Lang3b573612016-10-31 14:08:10 -0400658 break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500659 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
660 mDebug.setOutputSynchronous(enabled);
661 break;
662 case GL_DEBUG_OUTPUT:
663 mDebug.setOutputEnabled(enabled);
664 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700665 case GL_FRAMEBUFFER_SRGB_EXT:
666 setFramebufferSRGB(enabled);
667 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400668 default: UNREACHABLE();
669 }
670}
671
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700672bool State::getEnableFeature(GLenum feature) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400673{
674 switch (feature)
675 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300676 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
677 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400678 case GL_CULL_FACE: return isCullFaceEnabled();
679 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
680 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
681 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
682 case GL_SCISSOR_TEST: return isScissorTestEnabled();
683 case GL_STENCIL_TEST: return isStencilTestEnabled();
684 case GL_DEPTH_TEST: return isDepthTestEnabled();
685 case GL_BLEND: return isBlendEnabled();
686 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500687 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400688 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Langb5e997f2016-12-06 10:55:34 -0500689 case GL_SAMPLE_MASK:
690 UNIMPLEMENTED();
691 return false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500692 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
693 return mDebug.isOutputSynchronous();
694 case GL_DEBUG_OUTPUT:
695 return mDebug.isOutputEnabled();
Geoff Langf41a7152016-09-19 15:11:17 -0400696 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
697 return isBindGeneratesResourceEnabled();
Geoff Langfeb8c682017-02-13 16:07:35 -0500698 case GL_CLIENT_ARRAYS_ANGLE:
699 return areClientArraysEnabled();
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700700 case GL_FRAMEBUFFER_SRGB_EXT:
701 return getFramebufferSRGB();
Jamie Madille08a1d32017-03-07 17:24:06 -0500702 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
703 return mRobustResourceInit;
Jamie Madillc43be722017-07-13 16:22:14 -0400704 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
705 return mProgramBinaryCacheEnabled;
706
707 default:
708 UNREACHABLE();
709 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400710 }
711}
712
713void State::setLineWidth(GLfloat width)
714{
715 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400716 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400717}
718
Geoff Lang4b3f4162015-04-16 13:22:05 -0400719float State::getLineWidth() const
720{
721 return mLineWidth;
722}
723
Shannon Woods53a94a82014-06-24 15:20:36 -0400724void State::setGenerateMipmapHint(GLenum hint)
725{
726 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400727 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400728}
729
730void State::setFragmentShaderDerivativeHint(GLenum hint)
731{
732 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400733 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400734 // TODO: Propagate the hint to shader translator so we can write
735 // ddx, ddx_coarse, or ddx_fine depending on the hint.
736 // Ignore for now. It is valid for implementations to ignore hint.
737}
738
Geoff Langf41a7152016-09-19 15:11:17 -0400739bool State::isBindGeneratesResourceEnabled() const
740{
741 return mBindGeneratesResource;
742}
743
Geoff Langfeb8c682017-02-13 16:07:35 -0500744bool State::areClientArraysEnabled() const
745{
746 return mClientArraysEnabled;
747}
748
Shannon Woods53a94a82014-06-24 15:20:36 -0400749void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
750{
751 mViewport.x = x;
752 mViewport.y = y;
753 mViewport.width = width;
754 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400755 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400756}
757
758const Rectangle &State::getViewport() const
759{
760 return mViewport;
761}
762
763void State::setActiveSampler(unsigned int active)
764{
765 mActiveSampler = active;
766}
767
768unsigned int State::getActiveSampler() const
769{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700770 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400771}
772
Jamie Madill4928b7c2017-06-20 12:57:39 -0400773void State::setSamplerTexture(const Context *context, GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400774{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400775 mSamplerTextures[type][mActiveSampler].set(context, texture);
Jamie Madill81c2e252017-09-09 23:32:46 -0400776 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
777 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Shannon Woods53a94a82014-06-24 15:20:36 -0400778}
779
Jamie Madillc29968b2016-01-20 11:17:23 -0500780Texture *State::getTargetTexture(GLenum target) const
781{
782 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
783}
784
Geoff Lang76b10c92014-09-05 16:28:14 -0400785Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400786{
Jamie Madill5864ac22015-01-12 14:43:07 -0500787 const auto it = mSamplerTextures.find(type);
788 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400789 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500790 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400791}
792
Geoff Lang76b10c92014-09-05 16:28:14 -0400793GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400794{
Jamie Madill5864ac22015-01-12 14:43:07 -0500795 const auto it = mSamplerTextures.find(type);
796 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400797 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500798 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400799}
800
Jamie Madilla02315b2017-02-23 14:14:47 -0500801void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400802{
803 // Textures have a detach method on State rather than a simple
804 // removeBinding, because the zero/null texture objects are managed
805 // separately, and don't have to go through the Context's maps or
806 // the ResourceManager.
807
808 // [OpenGL ES 2.0.24] section 3.8 page 84:
809 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
810 // rebound to texture object zero
811
Corentin Walleza2257da2016-04-19 16:43:12 -0400812 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400813 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400814 GLenum textureType = bindingVec.first;
815 TextureBindingVector &textureVector = bindingVec.second;
Jamie Madill81c2e252017-09-09 23:32:46 -0400816 for (BindingPointer<Texture> &binding : textureVector)
Shannon Woods53a94a82014-06-24 15:20:36 -0400817 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400818 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400819 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500820 auto it = zeroTextures.find(textureType);
821 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500822 // Zero textures are the "default" textures instead of NULL
Jamie Madill4928b7c2017-06-20 12:57:39 -0400823 binding.set(context, it->second.get());
Jamie Madill81c2e252017-09-09 23:32:46 -0400824 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400825 }
826 }
827 }
828
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800829 for (auto &bindingImageUnit : mImageUnits)
830 {
831 if (bindingImageUnit.texture.id() == texture)
832 {
833 bindingImageUnit.texture.set(context, nullptr);
834 bindingImageUnit.level = 0;
835 bindingImageUnit.layered = false;
836 bindingImageUnit.layer = 0;
837 bindingImageUnit.access = GL_READ_ONLY;
838 bindingImageUnit.format = GL_R32UI;
839 break;
840 }
841 }
842
Shannon Woods53a94a82014-06-24 15:20:36 -0400843 // [OpenGL ES 2.0.24] section 4.4 page 112:
844 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
845 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
846 // image was attached in the currently bound framebuffer.
847
Jamie Madill8693bdb2017-09-02 15:32:14 -0400848 if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
Shannon Woods53a94a82014-06-24 15:20:36 -0400849 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400850 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400851 }
852
Jamie Madill8693bdb2017-09-02 15:32:14 -0400853 if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
Shannon Woods53a94a82014-06-24 15:20:36 -0400854 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400855 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400856 }
857}
858
Jamie Madill4928b7c2017-06-20 12:57:39 -0400859void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
Jamie Madille6382c32014-11-07 15:05:26 -0500860{
861 for (const auto &zeroTexture : zeroTextures)
862 {
863 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
864
865 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
866 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400867 samplerTextureArray[textureUnit].set(context, zeroTexture.second.get());
Jamie Madille6382c32014-11-07 15:05:26 -0500868 }
869 }
870}
871
Jamie Madill4928b7c2017-06-20 12:57:39 -0400872void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400873{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400874 mSamplers[textureUnit].set(context, sampler);
Jamie Madill81c2e252017-09-09 23:32:46 -0400875 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
876 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Shannon Woods53a94a82014-06-24 15:20:36 -0400877}
878
879GLuint State::getSamplerId(GLuint textureUnit) const
880{
Geoff Lang76b10c92014-09-05 16:28:14 -0400881 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400882 return mSamplers[textureUnit].id();
883}
884
885Sampler *State::getSampler(GLuint textureUnit) const
886{
887 return mSamplers[textureUnit].get();
888}
889
Jamie Madill4928b7c2017-06-20 12:57:39 -0400890void State::detachSampler(const Context *context, GLuint sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400891{
892 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
893 // If a sampler object that is currently bound to one or more texture units is
894 // deleted, it is as though BindSampler is called once for each texture unit to
895 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Jamie Madill81c2e252017-09-09 23:32:46 -0400896 for (BindingPointer<Sampler> &samplerBinding : mSamplers)
Shannon Woods53a94a82014-06-24 15:20:36 -0400897 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400898 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400899 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400900 samplerBinding.set(context, nullptr);
Jamie Madill81c2e252017-09-09 23:32:46 -0400901 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400902 }
903 }
904}
905
Jamie Madill4928b7c2017-06-20 12:57:39 -0400906void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400907{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400908 mRenderbuffer.set(context, renderbuffer);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400909 mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -0400910}
911
912GLuint State::getRenderbufferId() const
913{
914 return mRenderbuffer.id();
915}
916
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700917Renderbuffer *State::getCurrentRenderbuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400918{
919 return mRenderbuffer.get();
920}
921
Jamie Madilla02315b2017-02-23 14:14:47 -0500922void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400923{
924 // [OpenGL ES 2.0.24] section 4.4 page 109:
925 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
926 // had been executed with the target RENDERBUFFER and name of zero.
927
928 if (mRenderbuffer.id() == renderbuffer)
929 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400930 setRenderbufferBinding(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400931 }
932
933 // [OpenGL ES 2.0.24] section 4.4 page 111:
934 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
935 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
936 // point to which this image was attached in the currently bound framebuffer.
937
938 Framebuffer *readFramebuffer = mReadFramebuffer;
939 Framebuffer *drawFramebuffer = mDrawFramebuffer;
940
Jamie Madill8693bdb2017-09-02 15:32:14 -0400941 if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
Shannon Woods53a94a82014-06-24 15:20:36 -0400942 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400943 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400944 }
945
946 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
947 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400948 if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
949 {
950 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
951 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400952 }
953
954}
955
956void State::setReadFramebufferBinding(Framebuffer *framebuffer)
957{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500958 if (mReadFramebuffer == framebuffer)
959 return;
960
Shannon Woods53a94a82014-06-24 15:20:36 -0400961 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500962 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
963
964 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
965 {
966 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
967 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400968}
969
970void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
971{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500972 if (mDrawFramebuffer == framebuffer)
973 return;
974
Shannon Woods53a94a82014-06-24 15:20:36 -0400975 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500976 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
977
978 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
979 {
980 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
981 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400982}
983
984Framebuffer *State::getTargetFramebuffer(GLenum target) const
985{
986 switch (target)
987 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500988 case GL_READ_FRAMEBUFFER_ANGLE:
989 return mReadFramebuffer;
990 case GL_DRAW_FRAMEBUFFER_ANGLE:
991 case GL_FRAMEBUFFER:
992 return mDrawFramebuffer;
993 default:
994 UNREACHABLE();
Yunchao Hef81ce4a2017-04-24 10:49:17 +0800995 return nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400996 }
997}
998
Jamie Madill51f40ec2016-06-15 14:06:00 -0400999Framebuffer *State::getReadFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001000{
1001 return mReadFramebuffer;
1002}
1003
Jamie Madill51f40ec2016-06-15 14:06:00 -04001004Framebuffer *State::getDrawFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001005{
1006 return mDrawFramebuffer;
1007}
1008
1009bool State::removeReadFramebufferBinding(GLuint framebuffer)
1010{
Jamie Madill77a72f62015-04-14 11:18:32 -04001011 if (mReadFramebuffer != nullptr &&
1012 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001013 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001014 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001015 return true;
1016 }
1017
1018 return false;
1019}
1020
1021bool State::removeDrawFramebufferBinding(GLuint framebuffer)
1022{
Jamie Madill77a72f62015-04-14 11:18:32 -04001023 if (mReadFramebuffer != nullptr &&
1024 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001025 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001026 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001027 return true;
1028 }
1029
1030 return false;
1031}
1032
1033void State::setVertexArrayBinding(VertexArray *vertexArray)
1034{
1035 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001036 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001037
1038 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1039 {
1040 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1041 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001042}
1043
1044GLuint State::getVertexArrayId() const
1045{
Yunchao He4f285442017-04-21 12:15:49 +08001046 ASSERT(mVertexArray != nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001047 return mVertexArray->id();
1048}
1049
1050VertexArray *State::getVertexArray() const
1051{
Yunchao He4f285442017-04-21 12:15:49 +08001052 ASSERT(mVertexArray != nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001053 return mVertexArray;
1054}
1055
1056bool State::removeVertexArrayBinding(GLuint vertexArray)
1057{
1058 if (mVertexArray->id() == vertexArray)
1059 {
Yunchao Hed7297bf2017-04-19 15:27:10 +08001060 mVertexArray = nullptr;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001061 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001062 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001063 return true;
1064 }
1065
1066 return false;
1067}
1068
Jamie Madill4928b7c2017-06-20 12:57:39 -04001069void State::setElementArrayBuffer(const Context *context, Buffer *buffer)
Shao80957d92017-02-20 21:25:59 +08001070{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001071 getVertexArray()->setElementArrayBuffer(context, buffer);
Shao80957d92017-02-20 21:25:59 +08001072 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1073}
1074
Jamie Madill4928b7c2017-06-20 12:57:39 -04001075void State::bindVertexBuffer(const Context *context,
1076 GLuint bindingIndex,
Shao80957d92017-02-20 21:25:59 +08001077 Buffer *boundBuffer,
1078 GLintptr offset,
1079 GLsizei stride)
1080{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001081 getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001082 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1083}
1084
Shaodde78e82017-05-22 14:13:27 +08001085void State::setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001086{
Shaodde78e82017-05-22 14:13:27 +08001087 getVertexArray()->setVertexAttribBinding(context, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08001088 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1089}
1090
1091void State::setVertexAttribFormat(GLuint attribIndex,
1092 GLint size,
1093 GLenum type,
1094 bool normalized,
1095 bool pureInteger,
1096 GLuint relativeOffset)
1097{
1098 getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1099 relativeOffset);
1100 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1101}
1102
1103void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1104{
1105 getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
1106 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1107}
1108
Jamie Madill6c1f6712017-02-14 19:08:04 -05001109void State::setProgram(const Context *context, Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001110{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001111 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001112 {
Geoff Lang7dd2e102014-11-10 15:19:26 -05001113 if (mProgram)
1114 {
Jamie Madill6c1f6712017-02-14 19:08:04 -05001115 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001116 }
1117
1118 mProgram = newProgram;
1119
1120 if (mProgram)
1121 {
1122 newProgram->addRef();
Jamie Madill81c2e252017-09-09 23:32:46 -04001123 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001124 }
Jamie Madilla779b612017-07-24 11:46:05 -04001125 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
1126 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001127 }
1128}
1129
Geoff Lang7dd2e102014-11-10 15:19:26 -05001130Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001131{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001132 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -04001133}
1134
Jamie Madill4928b7c2017-06-20 12:57:39 -04001135void State::setTransformFeedbackBinding(const Context *context,
1136 TransformFeedback *transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001137{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001138 mTransformFeedback.set(context, transformFeedback);
Shannon Woods53a94a82014-06-24 15:20:36 -04001139}
1140
1141TransformFeedback *State::getCurrentTransformFeedback() const
1142{
1143 return mTransformFeedback.get();
1144}
1145
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001146bool State::isTransformFeedbackActiveUnpaused() const
1147{
Jamie Madill81c2e252017-09-09 23:32:46 -04001148 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001149 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001150}
1151
Jamie Madill4928b7c2017-06-20 12:57:39 -04001152bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001153{
1154 if (mTransformFeedback.id() == transformFeedback)
1155 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001156 mTransformFeedback.set(context, nullptr);
Corentin Walleza2257da2016-04-19 16:43:12 -04001157 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001158 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001159
1160 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001161}
1162
Yunchao Hea336b902017-08-02 16:05:21 +08001163void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
1164{
1165 mProgramPipeline.set(context, pipeline);
1166}
1167
1168void State::detachProgramPipeline(const Context *context, GLuint pipeline)
1169{
1170 mProgramPipeline.set(context, nullptr);
1171}
1172
Olli Etuahobbf1c102016-06-28 13:31:33 +03001173bool State::isQueryActive(const GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001174{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001175 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001176 {
Olli Etuahobbf1c102016-06-28 13:31:33 +03001177 const Query *query = iter.second.get();
1178 if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001179 {
1180 return true;
1181 }
1182 }
1183
1184 return false;
1185}
1186
1187bool State::isQueryActive(Query *query) const
1188{
1189 for (auto &iter : mActiveQueries)
1190 {
1191 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001192 {
1193 return true;
1194 }
1195 }
1196
1197 return false;
1198}
1199
Jamie Madill4928b7c2017-06-20 12:57:39 -04001200void State::setActiveQuery(const Context *context, GLenum target, Query *query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001201{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001202 mActiveQueries[target].set(context, query);
Shannon Woods53a94a82014-06-24 15:20:36 -04001203}
1204
1205GLuint State::getActiveQueryId(GLenum target) const
1206{
1207 const Query *query = getActiveQuery(target);
1208 return (query ? query->id() : 0u);
1209}
1210
1211Query *State::getActiveQuery(GLenum target) const
1212{
Jamie Madill5864ac22015-01-12 14:43:07 -05001213 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001214
Jamie Madill5864ac22015-01-12 14:43:07 -05001215 // All query types should already exist in the activeQueries map
1216 ASSERT(it != mActiveQueries.end());
1217
1218 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001219}
1220
Jamie Madill4928b7c2017-06-20 12:57:39 -04001221void State::setArrayBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001222{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001223 mArrayBuffer.set(context, buffer);
Shannon Woods53a94a82014-06-24 15:20:36 -04001224}
1225
1226GLuint State::getArrayBufferId() const
1227{
1228 return mArrayBuffer.id();
1229}
1230
Jamie Madill4928b7c2017-06-20 12:57:39 -04001231void State::setDrawIndirectBufferBinding(const Context *context, Buffer *buffer)
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001232{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001233 mDrawIndirectBuffer.set(context, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001234 mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
1235}
1236
Jamie Madill4928b7c2017-06-20 12:57:39 -04001237void State::setGenericUniformBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001238{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001239 mGenericUniformBuffer.set(context, buffer);
Shannon Woods53a94a82014-06-24 15:20:36 -04001240}
1241
Jamie Madill4928b7c2017-06-20 12:57:39 -04001242void State::setIndexedUniformBufferBinding(const Context *context,
1243 GLuint index,
1244 Buffer *buffer,
1245 GLintptr offset,
1246 GLsizeiptr size)
Shannon Woods53a94a82014-06-24 15:20:36 -04001247{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001248 mUniformBuffers[index].set(context, buffer, offset, size);
Shannon Woods53a94a82014-06-24 15:20:36 -04001249}
1250
Geoff Lang5d124a62015-09-15 13:03:27 -04001251const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001252{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001253 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001254 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001255}
1256
Jamie Madill4928b7c2017-06-20 12:57:39 -04001257void State::setGenericAtomicCounterBufferBinding(const Context *context, Buffer *buffer)
Jiajia Qin6eafb042016-12-27 17:04:07 +08001258{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001259 mGenericAtomicCounterBuffer.set(context, buffer);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001260}
1261
Jamie Madill4928b7c2017-06-20 12:57:39 -04001262void State::setIndexedAtomicCounterBufferBinding(const Context *context,
1263 GLuint index,
Jiajia Qin6eafb042016-12-27 17:04:07 +08001264 Buffer *buffer,
1265 GLintptr offset,
1266 GLsizeiptr size)
1267{
1268 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
Jamie Madill4928b7c2017-06-20 12:57:39 -04001269 mAtomicCounterBuffers[index].set(context, buffer, offset, size);
Jiajia Qin6eafb042016-12-27 17:04:07 +08001270}
1271
1272const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
1273{
1274 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1275 return mAtomicCounterBuffers[index];
1276}
1277
Jamie Madill4928b7c2017-06-20 12:57:39 -04001278void State::setGenericShaderStorageBufferBinding(const Context *context, Buffer *buffer)
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001279{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001280 mGenericShaderStorageBuffer.set(context, buffer);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001281}
1282
Jamie Madill4928b7c2017-06-20 12:57:39 -04001283void State::setIndexedShaderStorageBufferBinding(const Context *context,
1284 GLuint index,
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001285 Buffer *buffer,
1286 GLintptr offset,
1287 GLsizeiptr size)
1288{
1289 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
Jamie Madill4928b7c2017-06-20 12:57:39 -04001290 mShaderStorageBuffers[index].set(context, buffer, offset, size);
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001291}
1292
1293const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
1294{
1295 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
1296 return mShaderStorageBuffers[index];
1297}
1298
Jamie Madill4928b7c2017-06-20 12:57:39 -04001299void State::setCopyReadBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001300{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001301 mCopyReadBuffer.set(context, buffer);
Shannon Woods53a94a82014-06-24 15:20:36 -04001302}
1303
Jamie Madill4928b7c2017-06-20 12:57:39 -04001304void State::setCopyWriteBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001305{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001306 mCopyWriteBuffer.set(context, buffer);
Shannon Woods53a94a82014-06-24 15:20:36 -04001307}
1308
Jamie Madill4928b7c2017-06-20 12:57:39 -04001309void State::setPixelPackBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001310{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001311 mPack.pixelBuffer.set(context, buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001312 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001313}
1314
Jamie Madill4928b7c2017-06-20 12:57:39 -04001315void State::setPixelUnpackBufferBinding(const Context *context, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001316{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001317 mUnpack.pixelBuffer.set(context, buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001318 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001319}
1320
1321Buffer *State::getTargetBuffer(GLenum target) const
1322{
1323 switch (target)
1324 {
1325 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1326 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1327 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001328 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001329 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1330 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001331 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001332 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001333 case GL_ATOMIC_COUNTER_BUFFER:
Jiajia Qin6eafb042016-12-27 17:04:07 +08001334 return mGenericAtomicCounterBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001335 case GL_SHADER_STORAGE_BUFFER:
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001336 return mGenericShaderStorageBuffer.get();
Geoff Langb5e997f2016-12-06 10:55:34 -05001337 case GL_DRAW_INDIRECT_BUFFER:
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001338 return mDrawIndirectBuffer.get();
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001339 default:
1340 UNREACHABLE();
1341 return nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -04001342 }
1343}
1344
Jamie Madill4928b7c2017-06-20 12:57:39 -04001345void State::detachBuffer(const Context *context, GLuint bufferName)
Yuly Novikov5807a532015-12-03 13:01:22 -05001346{
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001347 BindingPointer<Buffer> *buffers[] = {
1348 &mArrayBuffer, &mGenericAtomicCounterBuffer, &mCopyReadBuffer,
1349 &mCopyWriteBuffer, &mDrawIndirectBuffer, &mPack.pixelBuffer,
1350 &mUnpack.pixelBuffer, &mGenericUniformBuffer, &mGenericShaderStorageBuffer};
Yuly Novikov5807a532015-12-03 13:01:22 -05001351 for (auto buffer : buffers)
1352 {
1353 if (buffer->id() == bufferName)
1354 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001355 buffer->set(context, nullptr);
Yuly Novikov5807a532015-12-03 13:01:22 -05001356 }
1357 }
1358
1359 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1360 if (curTransformFeedback)
1361 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001362 curTransformFeedback->detachBuffer(context, bufferName);
Yuly Novikov5807a532015-12-03 13:01:22 -05001363 }
1364
Jamie Madill4928b7c2017-06-20 12:57:39 -04001365 getVertexArray()->detachBuffer(context, bufferName);
Yuly Novikov5807a532015-12-03 13:01:22 -05001366}
1367
Shannon Woods53a94a82014-06-24 15:20:36 -04001368void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1369{
1370 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001371 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001372}
1373
1374void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1375{
Shannon Woods23e05002014-09-22 19:07:27 -04001376 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001377 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001378 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001379}
1380
1381void State::setVertexAttribu(GLuint index, const GLuint values[4])
1382{
Shannon Woods23e05002014-09-22 19:07:27 -04001383 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001384 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001385 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001386}
1387
1388void State::setVertexAttribi(GLuint index, const GLint values[4])
1389{
Shannon Woods23e05002014-09-22 19:07:27 -04001390 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001391 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001392 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001393}
1394
Shaodde78e82017-05-22 14:13:27 +08001395void State::setVertexAttribPointer(const Context *context,
1396 unsigned int attribNum,
1397 Buffer *boundBuffer,
1398 GLint size,
1399 GLenum type,
1400 bool normalized,
1401 bool pureInteger,
1402 GLsizei stride,
1403 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001404{
Shaodde78e82017-05-22 14:13:27 +08001405 getVertexArray()->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
1406 normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001407 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001408}
1409
Shaodde78e82017-05-22 14:13:27 +08001410void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
Jamie Madill0b9e9032015-08-17 11:51:52 +00001411{
Shaodde78e82017-05-22 14:13:27 +08001412 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001413 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001414}
1415
Jamie Madill6de51852017-04-12 09:53:01 -04001416const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001417{
Jamie Madill6de51852017-04-12 09:53:01 -04001418 ASSERT(attribNum < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001419 return mVertexAttribCurrentValues[attribNum];
1420}
1421
Shannon Woods53a94a82014-06-24 15:20:36 -04001422const void *State::getVertexAttribPointer(unsigned int attribNum) const
1423{
1424 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1425}
1426
1427void State::setPackAlignment(GLint alignment)
1428{
1429 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001430 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001431}
1432
1433GLint State::getPackAlignment() const
1434{
1435 return mPack.alignment;
1436}
1437
1438void State::setPackReverseRowOrder(bool reverseRowOrder)
1439{
1440 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001441 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001442}
1443
1444bool State::getPackReverseRowOrder() const
1445{
1446 return mPack.reverseRowOrder;
1447}
1448
Minmin Gongadff67b2015-10-14 10:34:45 -04001449void State::setPackRowLength(GLint rowLength)
1450{
1451 mPack.rowLength = rowLength;
1452 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1453}
1454
1455GLint State::getPackRowLength() const
1456{
1457 return mPack.rowLength;
1458}
1459
1460void State::setPackSkipRows(GLint skipRows)
1461{
1462 mPack.skipRows = skipRows;
1463 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1464}
1465
1466GLint State::getPackSkipRows() const
1467{
1468 return mPack.skipRows;
1469}
1470
1471void State::setPackSkipPixels(GLint skipPixels)
1472{
1473 mPack.skipPixels = skipPixels;
1474 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1475}
1476
1477GLint State::getPackSkipPixels() const
1478{
1479 return mPack.skipPixels;
1480}
1481
Shannon Woods53a94a82014-06-24 15:20:36 -04001482const PixelPackState &State::getPackState() const
1483{
1484 return mPack;
1485}
1486
Jamie Madill87de3622015-03-16 10:41:44 -04001487PixelPackState &State::getPackState()
1488{
1489 return mPack;
1490}
1491
Shannon Woods53a94a82014-06-24 15:20:36 -04001492void State::setUnpackAlignment(GLint alignment)
1493{
1494 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001495 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001496}
1497
1498GLint State::getUnpackAlignment() const
1499{
1500 return mUnpack.alignment;
1501}
1502
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001503void State::setUnpackRowLength(GLint rowLength)
1504{
1505 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001506 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001507}
1508
1509GLint State::getUnpackRowLength() const
1510{
1511 return mUnpack.rowLength;
1512}
1513
Minmin Gongadff67b2015-10-14 10:34:45 -04001514void State::setUnpackImageHeight(GLint imageHeight)
1515{
1516 mUnpack.imageHeight = imageHeight;
1517 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1518}
1519
1520GLint State::getUnpackImageHeight() const
1521{
1522 return mUnpack.imageHeight;
1523}
1524
1525void State::setUnpackSkipImages(GLint skipImages)
1526{
1527 mUnpack.skipImages = skipImages;
1528 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1529}
1530
1531GLint State::getUnpackSkipImages() const
1532{
1533 return mUnpack.skipImages;
1534}
1535
1536void State::setUnpackSkipRows(GLint skipRows)
1537{
1538 mUnpack.skipRows = skipRows;
1539 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1540}
1541
1542GLint State::getUnpackSkipRows() const
1543{
1544 return mUnpack.skipRows;
1545}
1546
1547void State::setUnpackSkipPixels(GLint skipPixels)
1548{
1549 mUnpack.skipPixels = skipPixels;
1550 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1551}
1552
1553GLint State::getUnpackSkipPixels() const
1554{
1555 return mUnpack.skipPixels;
1556}
1557
Shannon Woods53a94a82014-06-24 15:20:36 -04001558const PixelUnpackState &State::getUnpackState() const
1559{
1560 return mUnpack;
1561}
1562
Jamie Madill67102f02015-03-16 10:41:42 -04001563PixelUnpackState &State::getUnpackState()
1564{
1565 return mUnpack;
1566}
1567
Geoff Lang70d0f492015-12-10 17:45:46 -05001568const Debug &State::getDebug() const
1569{
1570 return mDebug;
1571}
1572
1573Debug &State::getDebug()
1574{
1575 return mDebug;
1576}
1577
Sami Väisänena797e062016-05-12 15:23:40 +03001578void State::setCoverageModulation(GLenum components)
1579{
1580 mCoverageModulation = components;
1581 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1582}
1583
1584GLenum State::getCoverageModulation() const
1585{
1586 return mCoverageModulation;
1587}
1588
Sami Väisänene45e53b2016-05-25 10:36:04 +03001589void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1590{
1591 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1592 {
1593 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1594 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1595 }
1596 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1597 {
1598 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1599 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1600 }
1601 else
1602 {
1603 UNREACHABLE();
1604 }
1605}
1606
1607const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1608{
1609 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1610 {
1611 return mPathMatrixMV;
1612 }
1613 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1614 {
1615 return mPathMatrixProj;
1616 }
1617
1618 UNREACHABLE();
1619 return nullptr;
1620}
1621
1622void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1623{
1624 mPathStencilFunc = func;
1625 mPathStencilRef = ref;
1626 mPathStencilMask = mask;
1627 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1628}
1629
1630GLenum State::getPathStencilFunc() const
1631{
1632 return mPathStencilFunc;
1633}
1634
1635GLint State::getPathStencilRef() const
1636{
1637 return mPathStencilRef;
1638}
1639
1640GLuint State::getPathStencilMask() const
1641{
1642 return mPathStencilMask;
1643}
1644
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001645void State::setFramebufferSRGB(bool sRGB)
1646{
1647 mFramebufferSRGB = sRGB;
1648 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1649}
1650
1651bool State::getFramebufferSRGB() const
1652{
1653 return mFramebufferSRGB;
1654}
1655
Shannon Woods53a94a82014-06-24 15:20:36 -04001656void State::getBooleanv(GLenum pname, GLboolean *params)
1657{
1658 switch (pname)
1659 {
1660 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1661 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1662 case GL_COLOR_WRITEMASK:
1663 params[0] = mBlend.colorMaskRed;
1664 params[1] = mBlend.colorMaskGreen;
1665 params[2] = mBlend.colorMaskBlue;
1666 params[3] = mBlend.colorMaskAlpha;
1667 break;
1668 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1669 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1670 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1671 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1672 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1673 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1674 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1675 case GL_BLEND: *params = mBlend.blend; break;
1676 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001677 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1678 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001679 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1680 *params = mPrimitiveRestart;
1681 break;
Geoff Langab831f02015-12-01 09:39:10 -05001682 case GL_RASTERIZER_DISCARD:
1683 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1684 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001685 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1686 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1687 break;
1688 case GL_DEBUG_OUTPUT:
1689 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1690 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001691 case GL_MULTISAMPLE_EXT:
1692 *params = mMultiSampling;
1693 break;
1694 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1695 *params = mSampleAlphaToOne;
1696 break;
Geoff Langf41a7152016-09-19 15:11:17 -04001697 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1698 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1699 break;
Geoff Langfeb8c682017-02-13 16:07:35 -05001700 case GL_CLIENT_ARRAYS_ANGLE:
1701 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1702 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001703 case GL_FRAMEBUFFER_SRGB_EXT:
1704 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1705 break;
Jamie Madille08a1d32017-03-07 17:24:06 -05001706 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
1707 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
1708 break;
Jamie Madillc43be722017-07-13 16:22:14 -04001709 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1710 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
1711 break;
1712
Shannon Woods53a94a82014-06-24 15:20:36 -04001713 default:
1714 UNREACHABLE();
1715 break;
1716 }
1717}
1718
1719void State::getFloatv(GLenum pname, GLfloat *params)
1720{
1721 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1722 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1723 // GetIntegerv as its native query function. As it would require conversion in any
1724 // case, this should make no difference to the calling application.
1725 switch (pname)
1726 {
1727 case GL_LINE_WIDTH: *params = mLineWidth; break;
1728 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1729 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1730 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1731 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1732 case GL_DEPTH_RANGE:
1733 params[0] = mNearZ;
1734 params[1] = mFarZ;
1735 break;
1736 case GL_COLOR_CLEAR_VALUE:
1737 params[0] = mColorClearValue.red;
1738 params[1] = mColorClearValue.green;
1739 params[2] = mColorClearValue.blue;
1740 params[3] = mColorClearValue.alpha;
1741 break;
1742 case GL_BLEND_COLOR:
1743 params[0] = mBlendColor.red;
1744 params[1] = mBlendColor.green;
1745 params[2] = mBlendColor.blue;
1746 params[3] = mBlendColor.alpha;
1747 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001748 case GL_MULTISAMPLE_EXT:
1749 *params = static_cast<GLfloat>(mMultiSampling);
1750 break;
1751 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1752 *params = static_cast<GLfloat>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001753 case GL_COVERAGE_MODULATION_CHROMIUM:
Jamie Madille2e406c2016-06-02 13:04:10 -04001754 params[0] = static_cast<GLfloat>(mCoverageModulation);
1755 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001756 default:
1757 UNREACHABLE();
1758 break;
1759 }
1760}
1761
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001762void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001763{
1764 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1765 {
1766 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001767 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001768 Framebuffer *framebuffer = mDrawFramebuffer;
1769 *params = framebuffer->getDrawBufferState(colorAttachment);
1770 return;
1771 }
1772
1773 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1774 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1775 // GetIntegerv as its native query function. As it would require conversion in any
1776 // case, this should make no difference to the calling application. You may find it in
1777 // State::getFloatv.
1778 switch (pname)
1779 {
1780 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001781 case GL_DRAW_INDIRECT_BUFFER_BINDING:
1782 *params = mDrawIndirectBuffer.id();
1783 break;
Jamie Madill8e344942015-07-09 14:22:07 -04001784 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001785 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1786 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1787 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1788 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1789 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001790 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001791 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1792 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001793 case GL_PACK_ROW_LENGTH:
1794 *params = mPack.rowLength;
1795 break;
1796 case GL_PACK_SKIP_ROWS:
1797 *params = mPack.skipRows;
1798 break;
1799 case GL_PACK_SKIP_PIXELS:
1800 *params = mPack.skipPixels;
1801 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001802 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001803 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001804 case GL_UNPACK_IMAGE_HEIGHT:
1805 *params = mUnpack.imageHeight;
1806 break;
1807 case GL_UNPACK_SKIP_IMAGES:
1808 *params = mUnpack.skipImages;
1809 break;
1810 case GL_UNPACK_SKIP_ROWS:
1811 *params = mUnpack.skipRows;
1812 break;
1813 case GL_UNPACK_SKIP_PIXELS:
1814 *params = mUnpack.skipPixels;
1815 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001816 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1817 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001818 case GL_ACTIVE_TEXTURE:
1819 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1820 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001821 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1822 case GL_STENCIL_REF: *params = mStencilRef; break;
1823 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1824 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1825 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1826 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1827 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1828 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1829 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1830 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1831 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1832 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1833 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1834 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1835 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1836 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1837 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1838 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1839 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1840 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1841 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1842 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Jamie Madill4928b7c2017-06-20 12:57:39 -04001843 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1844 *params = mReadFramebuffer->getImplementationColorReadType(context);
1845 break;
1846 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1847 *params = mReadFramebuffer->getImplementationColorReadFormat(context);
1848 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001849 case GL_SAMPLE_BUFFERS:
1850 case GL_SAMPLES:
1851 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001852 Framebuffer *framebuffer = mDrawFramebuffer;
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001853 if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001854 {
1855 switch (pname)
1856 {
Jamie Madilla0016b72017-07-14 14:30:46 -04001857 case GL_SAMPLE_BUFFERS:
1858 if (framebuffer->getSamples(context) != 0)
1859 {
1860 *params = 1;
1861 }
1862 else
1863 {
1864 *params = 0;
1865 }
1866 break;
1867 case GL_SAMPLES:
1868 *params = framebuffer->getSamples(context);
1869 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001870 }
1871 }
1872 else
1873 {
1874 *params = 0;
1875 }
1876 }
1877 break;
1878 case GL_VIEWPORT:
1879 params[0] = mViewport.x;
1880 params[1] = mViewport.y;
1881 params[2] = mViewport.width;
1882 params[3] = mViewport.height;
1883 break;
1884 case GL_SCISSOR_BOX:
1885 params[0] = mScissor.x;
1886 params[1] = mScissor.y;
1887 params[2] = mScissor.width;
1888 params[3] = mScissor.height;
1889 break;
1890 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1891 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1892 case GL_RED_BITS:
1893 case GL_GREEN_BITS:
1894 case GL_BLUE_BITS:
1895 case GL_ALPHA_BITS:
1896 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001897 Framebuffer *framebuffer = getDrawFramebuffer();
1898 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001899
1900 if (colorbuffer)
1901 {
1902 switch (pname)
1903 {
1904 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1905 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1906 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1907 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1908 }
1909 }
1910 else
1911 {
1912 *params = 0;
1913 }
1914 }
1915 break;
1916 case GL_DEPTH_BITS:
1917 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001918 const Framebuffer *framebuffer = getDrawFramebuffer();
1919 const FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001920
1921 if (depthbuffer)
1922 {
1923 *params = depthbuffer->getDepthSize();
1924 }
1925 else
1926 {
1927 *params = 0;
1928 }
1929 }
1930 break;
1931 case GL_STENCIL_BITS:
1932 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001933 const Framebuffer *framebuffer = getDrawFramebuffer();
1934 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001935
1936 if (stencilbuffer)
1937 {
1938 *params = stencilbuffer->getStencilSize();
1939 }
1940 else
1941 {
1942 *params = 0;
1943 }
1944 }
1945 break;
1946 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001947 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001948 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001949 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001950 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
1951 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1952 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1953 GL_TEXTURE_RECTANGLE_ANGLE);
1954 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001955 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001956 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001957 *params =
1958 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001959 break;
1960 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001961 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001962 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001963 break;
1964 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001965 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001966 *params =
1967 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001968 break;
JiangYizhou24fe74c2017-07-06 16:56:50 +08001969 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
1970 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1971 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1972 GL_TEXTURE_2D_MULTISAMPLE);
1973 break;
John Bauman18319182016-09-28 14:22:27 -07001974 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1975 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1976 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1977 GL_TEXTURE_EXTERNAL_OES);
1978 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001979 case GL_UNIFORM_BUFFER_BINDING:
1980 *params = mGenericUniformBuffer.id();
1981 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001982 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001983 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001984 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001985 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001986 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001987 break;
1988 case GL_COPY_READ_BUFFER_BINDING:
1989 *params = mCopyReadBuffer.id();
1990 break;
1991 case GL_COPY_WRITE_BUFFER_BINDING:
1992 *params = mCopyWriteBuffer.id();
1993 break;
1994 case GL_PIXEL_PACK_BUFFER_BINDING:
1995 *params = mPack.pixelBuffer.id();
1996 break;
1997 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1998 *params = mUnpack.pixelBuffer.id();
1999 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02002000 case GL_READ_BUFFER:
2001 *params = mReadFramebuffer->getReadBufferState();
2002 break;
2003 case GL_SAMPLER_BINDING:
2004 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2005 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
2006 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05002007 case GL_DEBUG_LOGGED_MESSAGES:
2008 *params = static_cast<GLint>(mDebug.getMessageCount());
2009 break;
2010 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2011 *params = static_cast<GLint>(mDebug.getNextMessageLength());
2012 break;
2013 case GL_DEBUG_GROUP_STACK_DEPTH:
2014 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2015 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03002016 case GL_MULTISAMPLE_EXT:
2017 *params = static_cast<GLint>(mMultiSampling);
2018 break;
2019 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2020 *params = static_cast<GLint>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03002021 case GL_COVERAGE_MODULATION_CHROMIUM:
2022 *params = static_cast<GLint>(mCoverageModulation);
Sami Väisänen74c23472016-05-09 17:30:30 +03002023 break;
Jiajia Qin6eafb042016-12-27 17:04:07 +08002024 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2025 *params = mGenericAtomicCounterBuffer.id();
2026 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002027 case GL_SHADER_STORAGE_BUFFER_BINDING:
2028 *params = mGenericShaderStorageBuffer.id();
2029 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002030 default:
2031 UNREACHABLE();
2032 break;
2033 }
2034}
2035
Geoff Lang70d0f492015-12-10 17:45:46 -05002036void State::getPointerv(GLenum pname, void **params) const
2037{
2038 switch (pname)
2039 {
2040 case GL_DEBUG_CALLBACK_FUNCTION:
2041 *params = reinterpret_cast<void *>(mDebug.getCallback());
2042 break;
2043 case GL_DEBUG_CALLBACK_USER_PARAM:
2044 *params = const_cast<void *>(mDebug.getUserParam());
2045 break;
2046 default:
2047 UNREACHABLE();
2048 break;
2049 }
2050}
2051
Martin Radev66fb8202016-07-28 11:45:20 +03002052void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04002053{
2054 switch (target)
2055 {
2056 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002057 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2058 *data = mTransformFeedback->getIndexedBuffer(index).id();
2059 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002060 case GL_UNIFORM_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002061 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2062 *data = mUniformBuffers[index].id();
2063 break;
2064 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2065 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2066 *data = mAtomicCounterBuffers[index].id();
2067 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002068 case GL_SHADER_STORAGE_BUFFER_BINDING:
2069 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2070 *data = mShaderStorageBuffers[index].id();
2071 break;
Shao80957d92017-02-20 21:25:59 +08002072 case GL_VERTEX_BINDING_BUFFER:
2073 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002074 *data = mVertexArray->getVertexBinding(index).getBuffer().id();
Shao80957d92017-02-20 21:25:59 +08002075 break;
2076 case GL_VERTEX_BINDING_DIVISOR:
2077 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002078 *data = mVertexArray->getVertexBinding(index).getDivisor();
Shao80957d92017-02-20 21:25:59 +08002079 break;
2080 case GL_VERTEX_BINDING_OFFSET:
2081 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002082 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
Shao80957d92017-02-20 21:25:59 +08002083 break;
2084 case GL_VERTEX_BINDING_STRIDE:
2085 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002086 *data = mVertexArray->getVertexBinding(index).getStride();
Shao80957d92017-02-20 21:25:59 +08002087 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002088 default:
Martin Radev66fb8202016-07-28 11:45:20 +03002089 UNREACHABLE();
2090 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002091 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002092}
2093
Martin Radev66fb8202016-07-28 11:45:20 +03002094void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04002095{
2096 switch (target)
2097 {
2098 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002099 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2100 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
2101 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002102 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002103 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2104 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
2105 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002106 case GL_UNIFORM_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002107 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2108 *data = mUniformBuffers[index].getOffset();
2109 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002110 case GL_UNIFORM_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002111 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2112 *data = mUniformBuffers[index].getSize();
2113 break;
2114 case GL_ATOMIC_COUNTER_BUFFER_START:
2115 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2116 *data = mAtomicCounterBuffers[index].getOffset();
2117 break;
2118 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2119 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2120 *data = mAtomicCounterBuffers[index].getSize();
2121 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002122 case GL_SHADER_STORAGE_BUFFER_START:
2123 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2124 *data = mShaderStorageBuffers[index].getOffset();
2125 break;
2126 case GL_SHADER_STORAGE_BUFFER_SIZE:
2127 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2128 *data = mShaderStorageBuffers[index].getSize();
2129 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002130 default:
Martin Radev66fb8202016-07-28 11:45:20 +03002131 UNREACHABLE();
2132 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002133 }
Martin Radev66fb8202016-07-28 11:45:20 +03002134}
Shannon Woods53a94a82014-06-24 15:20:36 -04002135
Martin Radev66fb8202016-07-28 11:45:20 +03002136void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
2137{
2138 UNREACHABLE();
Shannon Woods53a94a82014-06-24 15:20:36 -04002139}
2140
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002141bool State::hasMappedBuffer(GLenum target) const
2142{
2143 if (target == GL_ARRAY_BUFFER)
2144 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002145 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04002146 const auto &vertexAttribs = vao->getVertexAttributes();
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002147 const auto &vertexBindings = vao->getVertexBindings();
Jamie Madill8e344942015-07-09 14:22:07 -04002148 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04002149 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002150 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002151 const VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +03002152 auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].getBuffer().get();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002153 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
2154 {
2155 return true;
2156 }
2157 }
2158
2159 return false;
2160 }
2161 else
2162 {
2163 Buffer *buffer = getTargetBuffer(target);
2164 return (buffer && buffer->isMapped());
2165 }
2166}
2167
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002168void State::syncDirtyObjects(const Context *context)
Jamie Madillc9d442d2016-01-20 11:17:24 -05002169{
2170 if (!mDirtyObjects.any())
2171 return;
2172
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002173 syncDirtyObjects(context, mDirtyObjects);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002174}
2175
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002176void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002177{
Jamie Madill6de51852017-04-12 09:53:01 -04002178 for (auto dirtyObject : bitset)
Jamie Madillc9d442d2016-01-20 11:17:24 -05002179 {
2180 switch (dirtyObject)
2181 {
2182 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002183 ASSERT(mReadFramebuffer);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002184 mReadFramebuffer->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002185 break;
2186 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002187 ASSERT(mDrawFramebuffer);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002188 mDrawFramebuffer->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002189 break;
2190 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002191 ASSERT(mVertexArray);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002192 mVertexArray->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002193 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002194 case DIRTY_OBJECT_PROGRAM_TEXTURES:
2195 syncProgramTextures(context);
2196 break;
2197
Jamie Madillc9d442d2016-01-20 11:17:24 -05002198 default:
2199 UNREACHABLE();
2200 break;
2201 }
2202 }
2203
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002204 mDirtyObjects &= ~bitset;
2205}
2206
Jamie Madill81c2e252017-09-09 23:32:46 -04002207void State::syncProgramTextures(const Context *context)
2208{
Jamie Madill81c2e252017-09-09 23:32:46 -04002209 // TODO(jmadill): Fine-grained updates.
2210 if (!mProgram)
2211 {
2212 return;
2213 }
2214
2215 ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
2216 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2217
Jamie Madill0f80ed82017-09-19 00:24:56 -04002218 ActiveTextureMask newActiveTextures;
2219
Jamie Madill81c2e252017-09-09 23:32:46 -04002220 for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
2221 {
2222 if (samplerBinding.unreferenced)
2223 continue;
2224
2225 GLenum textureType = samplerBinding.textureType;
2226 for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
2227 {
2228 Texture *texture = getSamplerTexture(textureUnitIndex, textureType);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002229 Sampler *sampler = getSampler(textureUnitIndex);
Jamie Madill0f80ed82017-09-19 00:24:56 -04002230 ASSERT(static_cast<size_t>(textureUnitIndex) < mCompleteTextureCache.size());
2231 ASSERT(static_cast<size_t>(textureUnitIndex) < newActiveTextures.size());
Jamie Madill81c2e252017-09-09 23:32:46 -04002232
2233 if (texture != nullptr)
2234 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002235 // Mark the texture binding bit as dirty if the texture completeness changes.
2236 // TODO(jmadill): Use specific dirty bit for completeness change.
2237 if (texture->isSamplerComplete(context, sampler))
2238 {
Jamie Madill06ef36b2017-09-09 23:32:46 -04002239 texture->syncState();
Jamie Madill81c2e252017-09-09 23:32:46 -04002240 mCompleteTextureCache[textureUnitIndex] = texture;
2241 }
Jamie Madill0f80ed82017-09-19 00:24:56 -04002242 else
2243 {
2244 mCompleteTextureCache[textureUnitIndex] = nullptr;
2245 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002246
2247 // Bind the texture unconditionally, to recieve completeness change notifications.
2248 mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
Jamie Madill0f80ed82017-09-19 00:24:56 -04002249 newActiveTextures.set(textureUnitIndex);
2250 mCompleteTexturesMask.set(textureUnitIndex);
Jamie Madill81c2e252017-09-09 23:32:46 -04002251 }
2252
Jamie Madill06ef36b2017-09-09 23:32:46 -04002253 if (sampler != nullptr)
2254 {
2255 sampler->syncState(context);
2256 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002257 }
2258 }
Jamie Madill0f80ed82017-09-19 00:24:56 -04002259
2260 // Unset now missing textures.
2261 ActiveTextureMask negativeMask = mCompleteTexturesMask & ~newActiveTextures;
2262 if (negativeMask.any())
2263 {
2264 for (auto textureIndex : negativeMask)
2265 {
2266 mCompleteTextureBindings[textureIndex].reset();
2267 mCompleteTextureCache[textureIndex] = nullptr;
2268 mCompleteTexturesMask.reset(textureIndex);
2269 }
2270 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002271}
2272
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002273void State::syncDirtyObject(const Context *context, GLenum target)
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002274{
2275 DirtyObjects localSet;
2276
2277 switch (target)
2278 {
2279 case GL_READ_FRAMEBUFFER:
2280 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2281 break;
2282 case GL_DRAW_FRAMEBUFFER:
2283 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2284 break;
2285 case GL_FRAMEBUFFER:
2286 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2287 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2288 break;
2289 case GL_VERTEX_ARRAY:
2290 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2291 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002292 case GL_TEXTURE:
2293 case GL_SAMPLER:
2294 case GL_PROGRAM:
2295 localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2296 break;
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002297 }
2298
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002299 syncDirtyObjects(context, localSet);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002300}
2301
2302void State::setObjectDirty(GLenum target)
2303{
2304 switch (target)
2305 {
2306 case GL_READ_FRAMEBUFFER:
2307 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2308 break;
2309 case GL_DRAW_FRAMEBUFFER:
2310 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2311 break;
2312 case GL_FRAMEBUFFER:
2313 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2314 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2315 break;
2316 case GL_VERTEX_ARRAY:
2317 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2318 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002319 case GL_TEXTURE:
2320 case GL_SAMPLER:
Jamie Madill81c2e252017-09-09 23:32:46 -04002321 case GL_PROGRAM:
2322 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2323 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2324 break;
Jamie Madilla779b612017-07-24 11:46:05 -04002325 }
2326}
2327
2328void State::onProgramExecutableChange(Program *program)
2329{
2330 // OpenGL Spec:
2331 // "If LinkProgram or ProgramBinary successfully re-links a program object
2332 // that was already in use as a result of a previous call to UseProgram, then the
2333 // generated executable code will be installed as part of the current rendering state."
2334 if (program->isLinked() && mProgram == program)
2335 {
2336 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
Jamie Madill81c2e252017-09-09 23:32:46 -04002337 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002338 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002339}
Jamie Madillc9d442d2016-01-20 11:17:24 -05002340
Xinghua Cao65ec0b22017-03-28 16:10:52 +08002341void State::setImageUnit(const Context *context,
2342 GLuint unit,
2343 Texture *texture,
2344 GLint level,
2345 GLboolean layered,
2346 GLint layer,
2347 GLenum access,
2348 GLenum format)
2349{
2350 mImageUnits[unit].texture.set(context, texture);
2351 mImageUnits[unit].level = level;
2352 mImageUnits[unit].layered = layered;
2353 mImageUnits[unit].layer = layer;
2354 mImageUnits[unit].access = access;
2355 mImageUnits[unit].format = format;
2356}
2357
2358const ImageUnit &State::getImageUnit(GLuint unit) const
2359{
2360 return mImageUnits[unit];
2361}
2362
Jamie Madill81c2e252017-09-09 23:32:46 -04002363// Handle a dirty texture event.
2364void State::signal(uint32_t textureIndex)
2365{
2366 // Conservatively assume all textures are dirty.
2367 // TODO(jmadill): More fine-grained update.
2368 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2369}
2370
Jamie Madillc9d442d2016-01-20 11:17:24 -05002371} // namespace gl