blob: 876b9434a4eb47623017b7d15c6b1cdb69469e70 [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/mathutil.h"
jchen10a99ed552017-09-22 08:10:32 +080016#include "common/matrix_utils.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Caps.h"
jchen10a99ed552017-09-22 08:10:32 +080018#include "libANGLE/Context.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"
jchen10a99ed552017-09-22 08:10:32 +080025#include "libANGLE/queryconversions.h"
Geoff Lang4751aab2017-10-30 15:14:52 -040026#include "libANGLE/renderer/ContextImpl.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040027
Olli Etuahobbf1c102016-06-28 13:31:33 +030028namespace
29{
30
31GLenum ActiveQueryType(const GLenum type)
32{
33 return (type == GL_ANY_SAMPLES_PASSED_CONSERVATIVE) ? GL_ANY_SAMPLES_PASSED : type;
34}
35
36} // anonymous namepace
37
Shannon Woods53a94a82014-06-24 15:20:36 -040038namespace gl
39{
Geoff Lang76b10c92014-09-05 16:28:14 -040040
Shannon Woods53a94a82014-06-24 15:20:36 -040041State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050042 : mMaxDrawBuffers(0),
43 mMaxCombinedTextureImageUnits(0),
44 mDepthClearValue(0),
45 mStencilClearValue(0),
46 mScissorTest(false),
47 mSampleCoverage(false),
48 mSampleCoverageValue(0),
49 mSampleCoverageInvert(false),
Jiawei Shaodb342272017-09-27 10:21:45 +080050 mSampleMask(false),
51 mMaxSampleMaskWords(0),
Jamie Madille79b1e12015-11-04 16:36:37 -050052 mStencilRef(0),
53 mStencilBackRef(0),
54 mLineWidth(0),
55 mGenerateMipmapHint(GL_NONE),
56 mFragmentShaderDerivativeHint(GL_NONE),
Geoff Langf41a7152016-09-19 15:11:17 -040057 mBindGeneratesResource(true),
Geoff Langfeb8c682017-02-13 16:07:35 -050058 mClientArraysEnabled(true),
Jamie Madille79b1e12015-11-04 16:36:37 -050059 mNearZ(0),
60 mFarZ(0),
61 mReadFramebuffer(nullptr),
62 mDrawFramebuffer(nullptr),
63 mProgram(nullptr),
64 mVertexArray(nullptr),
65 mActiveSampler(0),
Sami Väisänen74c23472016-05-09 17:30:30 +030066 mPrimitiveRestart(false),
67 mMultiSampling(false),
Geoff Lang1d2c41d2016-10-19 16:14:46 -070068 mSampleAlphaToOne(false),
Jamie Madille08a1d32017-03-07 17:24:06 -050069 mFramebufferSRGB(true),
Jamie Madillc43be722017-07-13 16:22:14 -040070 mRobustResourceInit(false),
71 mProgramBinaryCacheEnabled(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040072{
Geoff Lang76b10c92014-09-05 16:28:14 -040073}
74
75State::~State()
76{
Geoff Lang76b10c92014-09-05 16:28:14 -040077}
78
Jamie Madill4928b7c2017-06-20 12:57:39 -040079void State::initialize(const Context *context,
Geoff Langf41a7152016-09-19 15:11:17 -040080 bool debug,
Geoff Langfeb8c682017-02-13 16:07:35 -050081 bool bindGeneratesResource,
Jamie Madille08a1d32017-03-07 17:24:06 -050082 bool clientArraysEnabled,
Jamie Madillc43be722017-07-13 16:22:14 -040083 bool robustResourceInit,
84 bool programBinaryCacheEnabled)
Geoff Lang76b10c92014-09-05 16:28:14 -040085{
Jamie Madill4928b7c2017-06-20 12:57:39 -040086 const Caps &caps = context->getCaps();
87 const Extensions &extensions = context->getExtensions();
Geoff Lang4751aab2017-10-30 15:14:52 -040088 const Extensions &nativeExtensions = context->getImplementation()->getNativeExtensions();
Jamie Madill4928b7c2017-06-20 12:57:39 -040089 const Version &clientVersion = context->getClientVersion();
90
Shannon Woods2df6a602014-09-26 16:12:07 -040091 mMaxDrawBuffers = caps.maxDrawBuffers;
92 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040093
Jamie Madillf75ab352015-03-16 10:46:52 -040094 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040095
96 mDepthClearValue = 1.0f;
97 mStencilClearValue = 0;
98
Shannon Woods53a94a82014-06-24 15:20:36 -040099 mScissorTest = false;
100 mScissor.x = 0;
101 mScissor.y = 0;
102 mScissor.width = 0;
103 mScissor.height = 0;
104
Shannon Woods53a94a82014-06-24 15:20:36 -0400105 mBlendColor.red = 0;
106 mBlendColor.green = 0;
107 mBlendColor.blue = 0;
108 mBlendColor.alpha = 0;
109
Shannon Woods53a94a82014-06-24 15:20:36 -0400110 mStencilRef = 0;
111 mStencilBackRef = 0;
112
113 mSampleCoverage = false;
114 mSampleCoverageValue = 1.0f;
115 mSampleCoverageInvert = false;
Jiawei Shaodb342272017-09-27 10:21:45 +0800116
117 mMaxSampleMaskWords = caps.maxSampleMaskWords;
118 mSampleMask = false;
119 mSampleMaskValues.fill(~GLbitfield(0));
120
Shannon Woods53a94a82014-06-24 15:20:36 -0400121 mGenerateMipmapHint = GL_DONT_CARE;
122 mFragmentShaderDerivativeHint = GL_DONT_CARE;
123
Geoff Langf41a7152016-09-19 15:11:17 -0400124 mBindGeneratesResource = bindGeneratesResource;
Geoff Langfeb8c682017-02-13 16:07:35 -0500125 mClientArraysEnabled = clientArraysEnabled;
Geoff Langf41a7152016-09-19 15:11:17 -0400126
Shannon Woods53a94a82014-06-24 15:20:36 -0400127 mLineWidth = 1.0f;
128
129 mViewport.x = 0;
130 mViewport.y = 0;
131 mViewport.width = 0;
132 mViewport.height = 0;
133 mNearZ = 0.0f;
134 mFarZ = 1.0f;
135
136 mBlend.colorMaskRed = true;
137 mBlend.colorMaskGreen = true;
138 mBlend.colorMaskBlue = true;
139 mBlend.colorMaskAlpha = true;
140
Geoff Lang76b10c92014-09-05 16:28:14 -0400141 mActiveSampler = 0;
142
Shannon Woods23e05002014-09-22 19:07:27 -0400143 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400144
Geoff Lang4dc3af02016-11-18 14:09:27 -0500145 mUniformBuffers.resize(caps.maxUniformBufferBindings);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400146
Geoff Lang76b10c92014-09-05 16:28:14 -0400147 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
148 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
Geoff Langeb66a6e2016-10-31 13:06:12 -0400149 if (clientVersion >= Version(3, 0))
Shannon Woods53a94a82014-06-24 15:20:36 -0400150 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400151 // TODO: These could also be enabled via extension
152 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
153 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400154 }
Geoff Lang3b573612016-10-31 14:08:10 -0400155 if (clientVersion >= Version(3, 1))
156 {
157 mSamplerTextures[GL_TEXTURE_2D_MULTISAMPLE].resize(caps.maxCombinedTextureImageUnits);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800158
159 mAtomicCounterBuffers.resize(caps.maxAtomicCounterBufferBindings);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800160 mShaderStorageBuffers.resize(caps.maxShaderStorageBufferBindings);
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800161 mImageUnits.resize(caps.maxImageUnits);
Geoff Lang3b573612016-10-31 14:08:10 -0400162 }
Geoff Lang4751aab2017-10-30 15:14:52 -0400163 if (nativeExtensions.textureRectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400164 {
165 mSamplerTextures[GL_TEXTURE_RECTANGLE_ANGLE].resize(caps.maxCombinedTextureImageUnits);
166 }
Geoff Lang4751aab2017-10-30 15:14:52 -0400167 if (nativeExtensions.eglImageExternal || nativeExtensions.eglStreamConsumerExternal)
Ian Ewellbda75592016-04-18 17:25:54 -0400168 {
169 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
170 }
Jamie Madill81c2e252017-09-09 23:32:46 -0400171 mCompleteTextureCache.resize(caps.maxCombinedTextureImageUnits, nullptr);
172 mCompleteTextureBindings.reserve(caps.maxCombinedTextureImageUnits);
Geoff Lange51ba632017-11-21 11:45:25 -0500173 mCachedTexturesInitState = InitState::MayNeedInit;
Jamie Madill81c2e252017-09-09 23:32:46 -0400174 for (uint32_t textureIndex = 0; textureIndex < caps.maxCombinedTextureImageUnits;
175 ++textureIndex)
176 {
177 mCompleteTextureBindings.emplace_back(OnAttachmentDirtyBinding(this, textureIndex));
178 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400179
Geoff Lang76b10c92014-09-05 16:28:14 -0400180 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400181
Jamie Madill4928b7c2017-06-20 12:57:39 -0400182 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(context, nullptr);
183 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(context, nullptr);
184 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(context, nullptr);
185 mActiveQueries[GL_TIME_ELAPSED_EXT].set(context, nullptr);
186 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400187
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500188 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400189
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500190 mReadFramebuffer = nullptr;
191 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500192
193 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500194
195 mDebug.setOutputEnabled(debug);
196 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300197
Geoff Lang488130e2017-09-27 13:53:11 -0400198 mMultiSampling = true;
199 mSampleAlphaToOne = false;
Sami Väisänena797e062016-05-12 15:23:40 +0300200
201 mCoverageModulation = GL_NONE;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300202
203 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
204 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
205 mPathStencilFunc = GL_ALWAYS;
206 mPathStencilRef = 0;
207 mPathStencilMask = std::numeric_limits<GLuint>::max();
Jamie Madille08a1d32017-03-07 17:24:06 -0500208
209 mRobustResourceInit = robustResourceInit;
Jamie Madillc43be722017-07-13 16:22:14 -0400210 mProgramBinaryCacheEnabled = programBinaryCacheEnabled;
Shannon Woods53a94a82014-06-24 15:20:36 -0400211}
212
Jamie Madill6c1f6712017-02-14 19:08:04 -0500213void State::reset(const Context *context)
Shannon Woods53a94a82014-06-24 15:20:36 -0400214{
Jamie Madill8693bdb2017-09-02 15:32:14 -0400215 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400216 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400217 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400218 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400219 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400220 textureVector[textureIdx].set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400221 }
222 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400223 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
224 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400225 mSamplers[samplerIdx].set(context, nullptr);
Geoff Lang76b10c92014-09-05 16:28:14 -0400226 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400227
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800228 for (auto &imageUnit : mImageUnits)
229 {
230 imageUnit.texture.set(context, nullptr);
231 imageUnit.level = 0;
232 imageUnit.layered = false;
233 imageUnit.layer = 0;
234 imageUnit.access = GL_READ_ONLY;
235 imageUnit.format = GL_R32UI;
236 }
237
Jamie Madill4928b7c2017-06-20 12:57:39 -0400238 mRenderbuffer.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400239
Corentin Wallez336129f2017-10-17 15:55:40 -0400240 for (auto type : angle::AllEnums<BufferBinding>())
241 {
242 mBoundBuffers[type].set(context, nullptr);
243 }
244
Geoff Lang7dd2e102014-11-10 15:19:26 -0500245 if (mProgram)
246 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500247 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500248 }
Yunchao Hed7297bf2017-04-19 15:27:10 +0800249 mProgram = nullptr;
Geoff Lang7dd2e102014-11-10 15:19:26 -0500250
Yunchao Hea336b902017-08-02 16:05:21 +0800251 mProgramPipeline.set(context, nullptr);
252
Jamie Madill4928b7c2017-06-20 12:57:39 -0400253 mTransformFeedback.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400254
255 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
256 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400257 i->second.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400258 }
259
Corentin Wallez336129f2017-10-17 15:55:40 -0400260 for (auto &buf : mUniformBuffers)
Shannon Woods53a94a82014-06-24 15:20:36 -0400261 {
Corentin Wallez336129f2017-10-17 15:55:40 -0400262 buf.set(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400263 }
264
Jiajia Qin6eafb042016-12-27 17:04:07 +0800265 for (auto &buf : mAtomicCounterBuffers)
266 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400267 buf.set(context, nullptr);
Jiajia Qin6eafb042016-12-27 17:04:07 +0800268 }
269
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800270 for (auto &buf : mShaderStorageBuffers)
271 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400272 buf.set(context, nullptr);
Jiajia Qinf546e7d2017-03-27 14:12:59 +0800273 }
274
Sami Väisänene45e53b2016-05-25 10:36:04 +0300275 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
276 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
277 mPathStencilFunc = GL_ALWAYS;
278 mPathStencilRef = 0;
279 mPathStencilMask = std::numeric_limits<GLuint>::max();
280
Jamie Madill1b94d432015-08-07 13:23:23 -0400281 // TODO(jmadill): Is this necessary?
282 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400283}
284
285const RasterizerState &State::getRasterizerState() const
286{
287 return mRasterizer;
288}
289
290const BlendState &State::getBlendState() const
291{
292 return mBlend;
293}
294
295const DepthStencilState &State::getDepthStencilState() const
296{
297 return mDepthStencil;
298}
299
Jamie Madillf75ab352015-03-16 10:46:52 -0400300void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400301{
302 mColorClearValue.red = red;
303 mColorClearValue.green = green;
304 mColorClearValue.blue = blue;
305 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400306 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400307}
308
Jamie Madillf75ab352015-03-16 10:46:52 -0400309void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400310{
311 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400312 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400313}
314
Jamie Madillf75ab352015-03-16 10:46:52 -0400315void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400316{
317 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400318 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400319}
320
Shannon Woods53a94a82014-06-24 15:20:36 -0400321void State::setColorMask(bool red, bool green, bool blue, bool alpha)
322{
323 mBlend.colorMaskRed = red;
324 mBlend.colorMaskGreen = green;
325 mBlend.colorMaskBlue = blue;
326 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400327 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400328}
329
330void State::setDepthMask(bool mask)
331{
332 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400333 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400334}
335
336bool State::isRasterizerDiscardEnabled() const
337{
338 return mRasterizer.rasterizerDiscard;
339}
340
341void State::setRasterizerDiscard(bool enabled)
342{
343 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400344 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400345}
346
347bool State::isCullFaceEnabled() const
348{
349 return mRasterizer.cullFace;
350}
351
352void State::setCullFace(bool enabled)
353{
354 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400355 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400356}
357
Corentin Wallez2e568cf2017-09-18 17:05:22 -0400358void State::setCullMode(CullFaceMode mode)
Shannon Woods53a94a82014-06-24 15:20:36 -0400359{
360 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400361 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400362}
363
364void State::setFrontFace(GLenum front)
365{
366 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400367 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400368}
369
370bool State::isDepthTestEnabled() const
371{
372 return mDepthStencil.depthTest;
373}
374
375void State::setDepthTest(bool enabled)
376{
377 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400378 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400379}
380
381void State::setDepthFunc(GLenum depthFunc)
382{
383 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400384 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400385}
386
387void State::setDepthRange(float zNear, float zFar)
388{
389 mNearZ = zNear;
390 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400391 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400392}
393
Geoff Langd42f5b82015-04-16 14:03:29 -0400394float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400395{
Geoff Langd42f5b82015-04-16 14:03:29 -0400396 return mNearZ;
397}
398
399float State::getFarPlane() const
400{
401 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400402}
403
404bool State::isBlendEnabled() const
405{
406 return mBlend.blend;
407}
408
409void State::setBlend(bool enabled)
410{
411 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400412 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400413}
414
415void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
416{
417 mBlend.sourceBlendRGB = sourceRGB;
418 mBlend.destBlendRGB = destRGB;
419 mBlend.sourceBlendAlpha = sourceAlpha;
420 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400421 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400422}
423
424void State::setBlendColor(float red, float green, float blue, float alpha)
425{
426 mBlendColor.red = red;
427 mBlendColor.green = green;
428 mBlendColor.blue = blue;
429 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400430 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400431}
432
433void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
434{
435 mBlend.blendEquationRGB = rgbEquation;
436 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400437 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400438}
439
440const ColorF &State::getBlendColor() const
441{
442 return mBlendColor;
443}
444
445bool State::isStencilTestEnabled() const
446{
447 return mDepthStencil.stencilTest;
448}
449
450void State::setStencilTest(bool enabled)
451{
452 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400453 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400454}
455
456void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
457{
458 mDepthStencil.stencilFunc = stencilFunc;
459 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
460 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400461 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400462}
463
464void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
465{
466 mDepthStencil.stencilBackFunc = stencilBackFunc;
467 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
468 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400469 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400470}
471
472void State::setStencilWritemask(GLuint stencilWritemask)
473{
474 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400475 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400476}
477
478void State::setStencilBackWritemask(GLuint stencilBackWritemask)
479{
480 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400481 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400482}
483
484void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
485{
486 mDepthStencil.stencilFail = stencilFail;
487 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
488 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400489 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400490}
491
492void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
493{
494 mDepthStencil.stencilBackFail = stencilBackFail;
495 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
496 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400497 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400498}
499
500GLint State::getStencilRef() const
501{
502 return mStencilRef;
503}
504
505GLint State::getStencilBackRef() const
506{
507 return mStencilBackRef;
508}
509
510bool State::isPolygonOffsetFillEnabled() const
511{
512 return mRasterizer.polygonOffsetFill;
513}
514
515void State::setPolygonOffsetFill(bool enabled)
516{
Jamie Madill1b94d432015-08-07 13:23:23 -0400517 mRasterizer.polygonOffsetFill = enabled;
518 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400519}
520
521void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
522{
523 // An application can pass NaN values here, so handle this gracefully
524 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
525 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400526 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400527}
528
529bool State::isSampleAlphaToCoverageEnabled() const
530{
531 return mBlend.sampleAlphaToCoverage;
532}
533
534void State::setSampleAlphaToCoverage(bool enabled)
535{
536 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400537 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400538}
539
540bool State::isSampleCoverageEnabled() const
541{
542 return mSampleCoverage;
543}
544
545void State::setSampleCoverage(bool enabled)
546{
547 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400548 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400549}
550
551void State::setSampleCoverageParams(GLclampf value, bool invert)
552{
553 mSampleCoverageValue = value;
554 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400555 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400556}
557
Geoff Lang0fbb6002015-04-16 11:11:53 -0400558GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400559{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400560 return mSampleCoverageValue;
561}
Shannon Woods53a94a82014-06-24 15:20:36 -0400562
Geoff Lang0fbb6002015-04-16 11:11:53 -0400563bool State::getSampleCoverageInvert() const
564{
565 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400566}
567
Jiawei Shaodb342272017-09-27 10:21:45 +0800568bool State::isSampleMaskEnabled() const
569{
570 return mSampleMask;
571}
572
573void State::setSampleMaskEnabled(bool enabled)
574{
575 mSampleMask = enabled;
576 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK_ENABLED);
577}
578
579void State::setSampleMaskParams(GLuint maskNumber, GLbitfield mask)
580{
581 ASSERT(maskNumber < mMaxSampleMaskWords);
582 mSampleMaskValues[maskNumber] = mask;
Jamie Madillc67323a2017-11-02 23:11:41 -0400583 // TODO(jmadill): Use a child dirty bit if we ever use more than two words.
584 mDirtyBits.set(DIRTY_BIT_SAMPLE_MASK);
Jiawei Shaodb342272017-09-27 10:21:45 +0800585}
586
587GLbitfield State::getSampleMaskWord(GLuint maskNumber) const
588{
589 ASSERT(maskNumber < mMaxSampleMaskWords);
590 return mSampleMaskValues[maskNumber];
591}
592
593GLuint State::getMaxSampleMaskWords() const
594{
595 return mMaxSampleMaskWords;
596}
597
Sami Väisänen74c23472016-05-09 17:30:30 +0300598void State::setSampleAlphaToOne(bool enabled)
599{
600 mSampleAlphaToOne = enabled;
601 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
602}
603
604bool State::isSampleAlphaToOneEnabled() const
605{
606 return mSampleAlphaToOne;
607}
608
609void State::setMultisampling(bool enabled)
610{
611 mMultiSampling = enabled;
612 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
613}
614
615bool State::isMultisamplingEnabled() const
616{
617 return mMultiSampling;
618}
619
Shannon Woods53a94a82014-06-24 15:20:36 -0400620bool State::isScissorTestEnabled() const
621{
622 return mScissorTest;
623}
624
625void State::setScissorTest(bool enabled)
626{
627 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400628 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400629}
630
631void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
632{
633 mScissor.x = x;
634 mScissor.y = y;
635 mScissor.width = width;
636 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400637 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400638}
639
640const Rectangle &State::getScissor() const
641{
642 return mScissor;
643}
644
645bool State::isDitherEnabled() const
646{
647 return mBlend.dither;
648}
649
650void State::setDither(bool enabled)
651{
652 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400653 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400654}
655
Jamie Madillb4b53c52015-02-03 15:22:48 -0500656bool State::isPrimitiveRestartEnabled() const
657{
658 return mPrimitiveRestart;
659}
660
661void State::setPrimitiveRestart(bool enabled)
662{
663 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400664 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500665}
666
Shannon Woods53a94a82014-06-24 15:20:36 -0400667void State::setEnableFeature(GLenum feature, bool enabled)
668{
669 switch (feature)
670 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300671 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
672 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400673 case GL_CULL_FACE: setCullFace(enabled); break;
674 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
675 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
676 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
677 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
678 case GL_STENCIL_TEST: setStencilTest(enabled); break;
679 case GL_DEPTH_TEST: setDepthTest(enabled); break;
680 case GL_BLEND: setBlend(enabled); break;
681 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500682 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400683 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang3b573612016-10-31 14:08:10 -0400684 case GL_SAMPLE_MASK:
Jiawei Shaodb342272017-09-27 10:21:45 +0800685 setSampleMaskEnabled(enabled);
Geoff Lang3b573612016-10-31 14:08:10 -0400686 break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500687 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
688 mDebug.setOutputSynchronous(enabled);
689 break;
690 case GL_DEBUG_OUTPUT:
691 mDebug.setOutputEnabled(enabled);
692 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700693 case GL_FRAMEBUFFER_SRGB_EXT:
694 setFramebufferSRGB(enabled);
695 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400696 default: UNREACHABLE();
697 }
698}
699
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700700bool State::getEnableFeature(GLenum feature) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400701{
702 switch (feature)
703 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300704 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
705 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400706 case GL_CULL_FACE: return isCullFaceEnabled();
707 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
708 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
709 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
710 case GL_SCISSOR_TEST: return isScissorTestEnabled();
711 case GL_STENCIL_TEST: return isStencilTestEnabled();
712 case GL_DEPTH_TEST: return isDepthTestEnabled();
713 case GL_BLEND: return isBlendEnabled();
714 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500715 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400716 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Langb5e997f2016-12-06 10:55:34 -0500717 case GL_SAMPLE_MASK:
Jiawei Shaodb342272017-09-27 10:21:45 +0800718 return isSampleMaskEnabled();
Geoff Lang70d0f492015-12-10 17:45:46 -0500719 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
720 return mDebug.isOutputSynchronous();
721 case GL_DEBUG_OUTPUT:
722 return mDebug.isOutputEnabled();
Geoff Langf41a7152016-09-19 15:11:17 -0400723 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
724 return isBindGeneratesResourceEnabled();
Geoff Langfeb8c682017-02-13 16:07:35 -0500725 case GL_CLIENT_ARRAYS_ANGLE:
726 return areClientArraysEnabled();
Geoff Lang1d2c41d2016-10-19 16:14:46 -0700727 case GL_FRAMEBUFFER_SRGB_EXT:
728 return getFramebufferSRGB();
Geoff Langb433e872017-10-05 14:01:47 -0400729 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madille08a1d32017-03-07 17:24:06 -0500730 return mRobustResourceInit;
Jamie Madillc43be722017-07-13 16:22:14 -0400731 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
732 return mProgramBinaryCacheEnabled;
733
734 default:
735 UNREACHABLE();
736 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400737 }
738}
739
740void State::setLineWidth(GLfloat width)
741{
742 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400743 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400744}
745
Geoff Lang4b3f4162015-04-16 13:22:05 -0400746float State::getLineWidth() const
747{
748 return mLineWidth;
749}
750
Shannon Woods53a94a82014-06-24 15:20:36 -0400751void State::setGenerateMipmapHint(GLenum hint)
752{
753 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400754 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400755}
756
757void State::setFragmentShaderDerivativeHint(GLenum hint)
758{
759 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400760 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400761 // TODO: Propagate the hint to shader translator so we can write
762 // ddx, ddx_coarse, or ddx_fine depending on the hint.
763 // Ignore for now. It is valid for implementations to ignore hint.
764}
765
Geoff Langf41a7152016-09-19 15:11:17 -0400766bool State::isBindGeneratesResourceEnabled() const
767{
768 return mBindGeneratesResource;
769}
770
Geoff Langfeb8c682017-02-13 16:07:35 -0500771bool State::areClientArraysEnabled() const
772{
773 return mClientArraysEnabled;
774}
775
Shannon Woods53a94a82014-06-24 15:20:36 -0400776void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
777{
778 mViewport.x = x;
779 mViewport.y = y;
780 mViewport.width = width;
781 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400782 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400783}
784
785const Rectangle &State::getViewport() const
786{
787 return mViewport;
788}
789
790void State::setActiveSampler(unsigned int active)
791{
792 mActiveSampler = active;
793}
794
795unsigned int State::getActiveSampler() const
796{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700797 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400798}
799
Jamie Madill4928b7c2017-06-20 12:57:39 -0400800void State::setSamplerTexture(const Context *context, GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400801{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400802 mSamplerTextures[type][mActiveSampler].set(context, texture);
Jamie Madill81c2e252017-09-09 23:32:46 -0400803 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
804 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Shannon Woods53a94a82014-06-24 15:20:36 -0400805}
806
Jamie Madillc29968b2016-01-20 11:17:23 -0500807Texture *State::getTargetTexture(GLenum target) const
808{
809 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
810}
811
Geoff Lang76b10c92014-09-05 16:28:14 -0400812Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400813{
Jamie Madill5864ac22015-01-12 14:43:07 -0500814 const auto it = mSamplerTextures.find(type);
815 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400816 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500817 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400818}
819
Geoff Lang76b10c92014-09-05 16:28:14 -0400820GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400821{
Jamie Madill5864ac22015-01-12 14:43:07 -0500822 const auto it = mSamplerTextures.find(type);
823 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400824 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500825 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400826}
827
Jamie Madilla02315b2017-02-23 14:14:47 -0500828void State::detachTexture(const Context *context, const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400829{
830 // Textures have a detach method on State rather than a simple
831 // removeBinding, because the zero/null texture objects are managed
832 // separately, and don't have to go through the Context's maps or
833 // the ResourceManager.
834
835 // [OpenGL ES 2.0.24] section 3.8 page 84:
836 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
837 // rebound to texture object zero
838
Corentin Walleza2257da2016-04-19 16:43:12 -0400839 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400840 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400841 GLenum textureType = bindingVec.first;
842 TextureBindingVector &textureVector = bindingVec.second;
Jamie Madill81c2e252017-09-09 23:32:46 -0400843 for (BindingPointer<Texture> &binding : textureVector)
Shannon Woods53a94a82014-06-24 15:20:36 -0400844 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400845 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400846 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500847 auto it = zeroTextures.find(textureType);
848 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500849 // Zero textures are the "default" textures instead of NULL
Jamie Madill4928b7c2017-06-20 12:57:39 -0400850 binding.set(context, it->second.get());
Jamie Madill81c2e252017-09-09 23:32:46 -0400851 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400852 }
853 }
854 }
855
Xinghua Cao65ec0b22017-03-28 16:10:52 +0800856 for (auto &bindingImageUnit : mImageUnits)
857 {
858 if (bindingImageUnit.texture.id() == texture)
859 {
860 bindingImageUnit.texture.set(context, nullptr);
861 bindingImageUnit.level = 0;
862 bindingImageUnit.layered = false;
863 bindingImageUnit.layer = 0;
864 bindingImageUnit.access = GL_READ_ONLY;
865 bindingImageUnit.format = GL_R32UI;
866 break;
867 }
868 }
869
Shannon Woods53a94a82014-06-24 15:20:36 -0400870 // [OpenGL ES 2.0.24] section 4.4 page 112:
871 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
872 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
873 // image was attached in the currently bound framebuffer.
874
Jamie Madill8693bdb2017-09-02 15:32:14 -0400875 if (mReadFramebuffer && mReadFramebuffer->detachTexture(context, texture))
Shannon Woods53a94a82014-06-24 15:20:36 -0400876 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400877 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400878 }
879
Jamie Madill8693bdb2017-09-02 15:32:14 -0400880 if (mDrawFramebuffer && mDrawFramebuffer->detachTexture(context, texture))
Shannon Woods53a94a82014-06-24 15:20:36 -0400881 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400882 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400883 }
884}
885
Jamie Madill4928b7c2017-06-20 12:57:39 -0400886void State::initializeZeroTextures(const Context *context, const TextureMap &zeroTextures)
Jamie Madille6382c32014-11-07 15:05:26 -0500887{
888 for (const auto &zeroTexture : zeroTextures)
889 {
890 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
891
892 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
893 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400894 samplerTextureArray[textureUnit].set(context, zeroTexture.second.get());
Jamie Madille6382c32014-11-07 15:05:26 -0500895 }
896 }
897}
898
Jamie Madill4928b7c2017-06-20 12:57:39 -0400899void State::setSamplerBinding(const Context *context, GLuint textureUnit, Sampler *sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400900{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400901 mSamplers[textureUnit].set(context, sampler);
Jamie Madill81c2e252017-09-09 23:32:46 -0400902 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
903 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Shannon Woods53a94a82014-06-24 15:20:36 -0400904}
905
906GLuint State::getSamplerId(GLuint textureUnit) const
907{
Geoff Lang76b10c92014-09-05 16:28:14 -0400908 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400909 return mSamplers[textureUnit].id();
910}
911
912Sampler *State::getSampler(GLuint textureUnit) const
913{
914 return mSamplers[textureUnit].get();
915}
916
Jamie Madill4928b7c2017-06-20 12:57:39 -0400917void State::detachSampler(const Context *context, GLuint sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400918{
919 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
920 // If a sampler object that is currently bound to one or more texture units is
921 // deleted, it is as though BindSampler is called once for each texture unit to
922 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Jamie Madill81c2e252017-09-09 23:32:46 -0400923 for (BindingPointer<Sampler> &samplerBinding : mSamplers)
Shannon Woods53a94a82014-06-24 15:20:36 -0400924 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400925 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400926 {
Jamie Madill4928b7c2017-06-20 12:57:39 -0400927 samplerBinding.set(context, nullptr);
Jamie Madill81c2e252017-09-09 23:32:46 -0400928 mDirtyBits.set(DIRTY_BIT_SAMPLER_BINDINGS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400929 }
930 }
931}
932
Jamie Madill4928b7c2017-06-20 12:57:39 -0400933void State::setRenderbufferBinding(const Context *context, Renderbuffer *renderbuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400934{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400935 mRenderbuffer.set(context, renderbuffer);
Jamie Madill8693bdb2017-09-02 15:32:14 -0400936 mDirtyBits.set(DIRTY_BIT_RENDERBUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -0400937}
938
939GLuint State::getRenderbufferId() const
940{
941 return mRenderbuffer.id();
942}
943
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700944Renderbuffer *State::getCurrentRenderbuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400945{
946 return mRenderbuffer.get();
947}
948
Jamie Madilla02315b2017-02-23 14:14:47 -0500949void State::detachRenderbuffer(const Context *context, GLuint renderbuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400950{
951 // [OpenGL ES 2.0.24] section 4.4 page 109:
952 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
953 // had been executed with the target RENDERBUFFER and name of zero.
954
955 if (mRenderbuffer.id() == renderbuffer)
956 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400957 setRenderbufferBinding(context, nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400958 }
959
960 // [OpenGL ES 2.0.24] section 4.4 page 111:
961 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
962 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
963 // point to which this image was attached in the currently bound framebuffer.
964
965 Framebuffer *readFramebuffer = mReadFramebuffer;
966 Framebuffer *drawFramebuffer = mDrawFramebuffer;
967
Jamie Madill8693bdb2017-09-02 15:32:14 -0400968 if (readFramebuffer && readFramebuffer->detachRenderbuffer(context, renderbuffer))
Shannon Woods53a94a82014-06-24 15:20:36 -0400969 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400970 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
Shannon Woods53a94a82014-06-24 15:20:36 -0400971 }
972
973 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
974 {
Jamie Madill8693bdb2017-09-02 15:32:14 -0400975 if (drawFramebuffer->detachRenderbuffer(context, renderbuffer))
976 {
977 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
978 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400979 }
980
981}
982
983void State::setReadFramebufferBinding(Framebuffer *framebuffer)
984{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500985 if (mReadFramebuffer == framebuffer)
986 return;
987
Shannon Woods53a94a82014-06-24 15:20:36 -0400988 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500989 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
990
991 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
992 {
993 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
994 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400995}
996
997void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
998{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500999 if (mDrawFramebuffer == framebuffer)
1000 return;
1001
Shannon Woods53a94a82014-06-24 15:20:36 -04001002 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001003 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
1004
1005 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
1006 {
1007 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1008 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001009}
1010
1011Framebuffer *State::getTargetFramebuffer(GLenum target) const
1012{
1013 switch (target)
1014 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001015 case GL_READ_FRAMEBUFFER_ANGLE:
1016 return mReadFramebuffer;
1017 case GL_DRAW_FRAMEBUFFER_ANGLE:
1018 case GL_FRAMEBUFFER:
1019 return mDrawFramebuffer;
1020 default:
1021 UNREACHABLE();
Yunchao Hef81ce4a2017-04-24 10:49:17 +08001022 return nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -04001023 }
1024}
1025
Jamie Madill51f40ec2016-06-15 14:06:00 -04001026Framebuffer *State::getReadFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001027{
1028 return mReadFramebuffer;
1029}
1030
Jamie Madill51f40ec2016-06-15 14:06:00 -04001031Framebuffer *State::getDrawFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001032{
1033 return mDrawFramebuffer;
1034}
1035
1036bool State::removeReadFramebufferBinding(GLuint framebuffer)
1037{
Jamie Madill77a72f62015-04-14 11:18:32 -04001038 if (mReadFramebuffer != nullptr &&
1039 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001040 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001041 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001042 return true;
1043 }
1044
1045 return false;
1046}
1047
1048bool State::removeDrawFramebufferBinding(GLuint framebuffer)
1049{
Jamie Madill77a72f62015-04-14 11:18:32 -04001050 if (mReadFramebuffer != nullptr &&
1051 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001052 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001053 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001054 return true;
1055 }
1056
1057 return false;
1058}
1059
1060void State::setVertexArrayBinding(VertexArray *vertexArray)
1061{
1062 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001063 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001064
1065 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
1066 {
1067 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1068 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001069}
1070
1071GLuint State::getVertexArrayId() const
1072{
Yunchao He4f285442017-04-21 12:15:49 +08001073 ASSERT(mVertexArray != nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001074 return mVertexArray->id();
1075}
1076
1077VertexArray *State::getVertexArray() const
1078{
Yunchao He4f285442017-04-21 12:15:49 +08001079 ASSERT(mVertexArray != nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -04001080 return mVertexArray;
1081}
1082
1083bool State::removeVertexArrayBinding(GLuint vertexArray)
1084{
1085 if (mVertexArray->id() == vertexArray)
1086 {
Yunchao Hed7297bf2017-04-19 15:27:10 +08001087 mVertexArray = nullptr;
Jamie Madill0b9e9032015-08-17 11:51:52 +00001088 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001089 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001090 return true;
1091 }
1092
1093 return false;
1094}
1095
Jamie Madill4928b7c2017-06-20 12:57:39 -04001096void State::bindVertexBuffer(const Context *context,
1097 GLuint bindingIndex,
Shao80957d92017-02-20 21:25:59 +08001098 Buffer *boundBuffer,
1099 GLintptr offset,
1100 GLsizei stride)
1101{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001102 getVertexArray()->bindVertexBuffer(context, bindingIndex, boundBuffer, offset, stride);
Shao80957d92017-02-20 21:25:59 +08001103 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1104}
1105
Shaodde78e82017-05-22 14:13:27 +08001106void State::setVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
Shao80957d92017-02-20 21:25:59 +08001107{
Shaodde78e82017-05-22 14:13:27 +08001108 getVertexArray()->setVertexAttribBinding(context, attribIndex, bindingIndex);
Shao80957d92017-02-20 21:25:59 +08001109 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1110}
1111
1112void State::setVertexAttribFormat(GLuint attribIndex,
1113 GLint size,
1114 GLenum type,
1115 bool normalized,
1116 bool pureInteger,
1117 GLuint relativeOffset)
1118{
1119 getVertexArray()->setVertexAttribFormat(attribIndex, size, type, normalized, pureInteger,
1120 relativeOffset);
1121 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1122}
1123
1124void State::setVertexBindingDivisor(GLuint bindingIndex, GLuint divisor)
1125{
1126 getVertexArray()->setVertexBindingDivisor(bindingIndex, divisor);
1127 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1128}
1129
Jamie Madill6c1f6712017-02-14 19:08:04 -05001130void State::setProgram(const Context *context, Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001131{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001132 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -04001133 {
Geoff Lang7dd2e102014-11-10 15:19:26 -05001134 if (mProgram)
1135 {
Jamie Madill6c1f6712017-02-14 19:08:04 -05001136 mProgram->release(context);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001137 }
1138
1139 mProgram = newProgram;
1140
1141 if (mProgram)
1142 {
1143 newProgram->addRef();
Jamie Madill81c2e252017-09-09 23:32:46 -04001144 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Geoff Lang7dd2e102014-11-10 15:19:26 -05001145 }
Jamie Madilla779b612017-07-24 11:46:05 -04001146 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
1147 mDirtyBits.set(DIRTY_BIT_PROGRAM_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001148 }
1149}
1150
Geoff Lang7dd2e102014-11-10 15:19:26 -05001151Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -04001152{
Geoff Lang7dd2e102014-11-10 15:19:26 -05001153 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -04001154}
1155
Jamie Madill4928b7c2017-06-20 12:57:39 -04001156void State::setTransformFeedbackBinding(const Context *context,
1157 TransformFeedback *transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001158{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001159 mTransformFeedback.set(context, transformFeedback);
Geoff Langded79232017-11-28 15:21:11 -05001160 mDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001161}
1162
1163TransformFeedback *State::getCurrentTransformFeedback() const
1164{
1165 return mTransformFeedback.get();
1166}
1167
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001168bool State::isTransformFeedbackActiveUnpaused() const
1169{
Jamie Madill81c2e252017-09-09 23:32:46 -04001170 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001171 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001172}
1173
Jamie Madill4928b7c2017-06-20 12:57:39 -04001174bool State::removeTransformFeedbackBinding(const Context *context, GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001175{
1176 if (mTransformFeedback.id() == transformFeedback)
1177 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001178 mTransformFeedback.set(context, nullptr);
Corentin Walleza2257da2016-04-19 16:43:12 -04001179 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001180 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001181
1182 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001183}
1184
Yunchao Hea336b902017-08-02 16:05:21 +08001185void State::setProgramPipelineBinding(const Context *context, ProgramPipeline *pipeline)
1186{
1187 mProgramPipeline.set(context, pipeline);
1188}
1189
1190void State::detachProgramPipeline(const Context *context, GLuint pipeline)
1191{
1192 mProgramPipeline.set(context, nullptr);
1193}
1194
Olli Etuahobbf1c102016-06-28 13:31:33 +03001195bool State::isQueryActive(const GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001196{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001197 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001198 {
Olli Etuahobbf1c102016-06-28 13:31:33 +03001199 const Query *query = iter.second.get();
1200 if (query != nullptr && ActiveQueryType(query->getType()) == ActiveQueryType(type))
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001201 {
1202 return true;
1203 }
1204 }
1205
1206 return false;
1207}
1208
1209bool State::isQueryActive(Query *query) const
1210{
1211 for (auto &iter : mActiveQueries)
1212 {
1213 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001214 {
1215 return true;
1216 }
1217 }
1218
1219 return false;
1220}
1221
Jamie Madill4928b7c2017-06-20 12:57:39 -04001222void State::setActiveQuery(const Context *context, GLenum target, Query *query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001223{
Jamie Madill4928b7c2017-06-20 12:57:39 -04001224 mActiveQueries[target].set(context, query);
Shannon Woods53a94a82014-06-24 15:20:36 -04001225}
1226
1227GLuint State::getActiveQueryId(GLenum target) const
1228{
1229 const Query *query = getActiveQuery(target);
1230 return (query ? query->id() : 0u);
1231}
1232
1233Query *State::getActiveQuery(GLenum target) const
1234{
Jamie Madill5864ac22015-01-12 14:43:07 -05001235 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001236
Jamie Madill5864ac22015-01-12 14:43:07 -05001237 // All query types should already exist in the activeQueries map
1238 ASSERT(it != mActiveQueries.end());
1239
1240 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001241}
1242
Corentin Wallez336129f2017-10-17 15:55:40 -04001243void State::setBufferBinding(const Context *context, BufferBinding target, Buffer *buffer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001244{
Corentin Wallez336129f2017-10-17 15:55:40 -04001245 switch (target)
1246 {
1247 case BufferBinding::PixelPack:
Corentin Wallezd5d30992017-11-13 10:21:52 -08001248 mBoundBuffers[target].set(context, buffer);
Corentin Wallez336129f2017-10-17 15:55:40 -04001249 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
1250 break;
1251 case BufferBinding::PixelUnpack:
Corentin Wallezd5d30992017-11-13 10:21:52 -08001252 mBoundBuffers[target].set(context, buffer);
Corentin Wallez336129f2017-10-17 15:55:40 -04001253 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
1254 break;
1255 case BufferBinding::DrawIndirect:
Corentin Wallezd5d30992017-11-13 10:21:52 -08001256 mBoundBuffers[target].set(context, buffer);
Corentin Wallez336129f2017-10-17 15:55:40 -04001257 mDirtyBits.set(DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING);
1258 break;
Qin Jiajiaa98a2812017-11-30 18:12:06 +08001259 case BufferBinding::DispatchIndirect:
1260 mBoundBuffers[target].set(context, buffer);
1261 mDirtyBits.set(DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING);
1262 break;
Corentin Wallez336129f2017-10-17 15:55:40 -04001263 case BufferBinding::TransformFeedback:
1264 if (mTransformFeedback.get() != nullptr)
1265 {
1266 mTransformFeedback->bindGenericBuffer(context, buffer);
1267 }
1268 break;
1269 case BufferBinding::ElementArray:
1270 getVertexArray()->setElementArrayBuffer(context, buffer);
1271 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1272 break;
Xinghua Cao10a4d432017-11-28 14:46:26 +08001273 case BufferBinding::ShaderStorage:
1274 mBoundBuffers[target].set(context, buffer);
1275 mDirtyBits.set(DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
1276 break;
Corentin Wallez336129f2017-10-17 15:55:40 -04001277 default:
Corentin Wallezd5d30992017-11-13 10:21:52 -08001278 mBoundBuffers[target].set(context, buffer);
Corentin Wallez336129f2017-10-17 15:55:40 -04001279 break;
1280 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001281}
Corentin Wallez336129f2017-10-17 15:55:40 -04001282void State::setIndexedBufferBinding(const Context *context,
1283 BufferBinding target,
1284 GLuint index,
1285 Buffer *buffer,
1286 GLintptr offset,
1287 GLsizeiptr size)
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001288{
Corentin Wallez336129f2017-10-17 15:55:40 -04001289 setBufferBinding(context, target, buffer);
Jiajia Qin9d7d0b12016-11-29 16:30:31 +08001290
Corentin Wallez336129f2017-10-17 15:55:40 -04001291 switch (target)
1292 {
1293 case BufferBinding::TransformFeedback:
1294 mTransformFeedback->bindIndexedBuffer(context, index, buffer, offset, size);
1295 break;
1296 case BufferBinding::Uniform:
1297 mUniformBuffers[index].set(context, buffer, offset, size);
Jamie Madillf4141212017-12-12 15:08:07 -05001298 mDirtyBits.set(DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
Corentin Wallez336129f2017-10-17 15:55:40 -04001299 break;
1300 case BufferBinding::AtomicCounter:
1301 mAtomicCounterBuffers[index].set(context, buffer, offset, size);
1302 break;
1303 case BufferBinding::ShaderStorage:
1304 mShaderStorageBuffers[index].set(context, buffer, offset, size);
1305 break;
1306 default:
1307 UNREACHABLE();
1308 break;
1309 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001310}
1311
Geoff Lang5d124a62015-09-15 13:03:27 -04001312const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001313{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001314 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001315 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001316}
1317
Jiajia Qin6eafb042016-12-27 17:04:07 +08001318const OffsetBindingPointer<Buffer> &State::getIndexedAtomicCounterBuffer(size_t index) const
1319{
1320 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
1321 return mAtomicCounterBuffers[index];
1322}
1323
Jiajia Qinf546e7d2017-03-27 14:12:59 +08001324const OffsetBindingPointer<Buffer> &State::getIndexedShaderStorageBuffer(size_t index) const
1325{
1326 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
1327 return mShaderStorageBuffers[index];
1328}
1329
Corentin Wallez336129f2017-10-17 15:55:40 -04001330Buffer *State::getTargetBuffer(BufferBinding target) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001331{
1332 switch (target)
1333 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001334 case BufferBinding::ElementArray:
1335 return getVertexArray()->getElementArrayBuffer().get();
1336 case BufferBinding::TransformFeedback:
1337 return mTransformFeedback->getGenericBuffer().get();
1338 default:
1339 return mBoundBuffers[target].get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001340 }
1341}
1342
Jamie Madill4928b7c2017-06-20 12:57:39 -04001343void State::detachBuffer(const Context *context, GLuint bufferName)
Yuly Novikov5807a532015-12-03 13:01:22 -05001344{
Corentin Wallez336129f2017-10-17 15:55:40 -04001345 for (auto &buffer : mBoundBuffers)
Yuly Novikov5807a532015-12-03 13:01:22 -05001346 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001347 if (buffer.id() == bufferName)
Yuly Novikov5807a532015-12-03 13:01:22 -05001348 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001349 buffer.set(context, nullptr);
Yuly Novikov5807a532015-12-03 13:01:22 -05001350 }
1351 }
1352
1353 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1354 if (curTransformFeedback)
1355 {
Jamie Madill4928b7c2017-06-20 12:57:39 -04001356 curTransformFeedback->detachBuffer(context, bufferName);
Yuly Novikov5807a532015-12-03 13:01:22 -05001357 }
1358
Jamie Madill4928b7c2017-06-20 12:57:39 -04001359 getVertexArray()->detachBuffer(context, bufferName);
Yuly Novikov5807a532015-12-03 13:01:22 -05001360}
1361
Shannon Woods53a94a82014-06-24 15:20:36 -04001362void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1363{
1364 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001365 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001366}
1367
1368void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1369{
Shannon Woods23e05002014-09-22 19:07:27 -04001370 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001371 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madillc67323a2017-11-02 23:11:41 -04001372 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1373 mDirtyCurrentValues.set(index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001374}
1375
1376void State::setVertexAttribu(GLuint index, const GLuint values[4])
1377{
Shannon Woods23e05002014-09-22 19:07:27 -04001378 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001379 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madillc67323a2017-11-02 23:11:41 -04001380 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1381 mDirtyCurrentValues.set(index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001382}
1383
1384void State::setVertexAttribi(GLuint index, const GLint values[4])
1385{
Shannon Woods23e05002014-09-22 19:07:27 -04001386 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001387 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madillc67323a2017-11-02 23:11:41 -04001388 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUES);
1389 mDirtyCurrentValues.set(index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001390}
1391
Shaodde78e82017-05-22 14:13:27 +08001392void State::setVertexAttribPointer(const Context *context,
1393 unsigned int attribNum,
1394 Buffer *boundBuffer,
1395 GLint size,
1396 GLenum type,
1397 bool normalized,
1398 bool pureInteger,
1399 GLsizei stride,
1400 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001401{
Shaodde78e82017-05-22 14:13:27 +08001402 getVertexArray()->setVertexAttribPointer(context, attribNum, boundBuffer, size, type,
1403 normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001404 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001405}
1406
Shaodde78e82017-05-22 14:13:27 +08001407void State::setVertexAttribDivisor(const Context *context, GLuint index, GLuint divisor)
Jamie Madill0b9e9032015-08-17 11:51:52 +00001408{
Shaodde78e82017-05-22 14:13:27 +08001409 getVertexArray()->setVertexAttribDivisor(context, index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001410 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001411}
1412
Jamie Madill6de51852017-04-12 09:53:01 -04001413const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(size_t attribNum) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001414{
Jamie Madill6de51852017-04-12 09:53:01 -04001415 ASSERT(attribNum < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001416 return mVertexAttribCurrentValues[attribNum];
1417}
1418
Jamie Madillcac94a92017-11-10 10:09:32 -05001419const std::vector<VertexAttribCurrentValueData> &State::getVertexAttribCurrentValues() const
1420{
1421 return mVertexAttribCurrentValues;
1422}
1423
Shannon Woods53a94a82014-06-24 15:20:36 -04001424const void *State::getVertexAttribPointer(unsigned int attribNum) const
1425{
1426 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1427}
1428
1429void State::setPackAlignment(GLint alignment)
1430{
1431 mPack.alignment = alignment;
Jamie Madillc67323a2017-11-02 23:11:41 -04001432 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
Shannon Woods53a94a82014-06-24 15:20:36 -04001433}
1434
1435GLint State::getPackAlignment() const
1436{
1437 return mPack.alignment;
1438}
1439
1440void State::setPackReverseRowOrder(bool reverseRowOrder)
1441{
1442 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madillc67323a2017-11-02 23:11:41 -04001443 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
Shannon Woods53a94a82014-06-24 15:20:36 -04001444}
1445
1446bool State::getPackReverseRowOrder() const
1447{
1448 return mPack.reverseRowOrder;
1449}
1450
Minmin Gongadff67b2015-10-14 10:34:45 -04001451void State::setPackRowLength(GLint rowLength)
1452{
1453 mPack.rowLength = rowLength;
Jamie Madillc67323a2017-11-02 23:11:41 -04001454 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001455}
1456
1457GLint State::getPackRowLength() const
1458{
1459 return mPack.rowLength;
1460}
1461
1462void State::setPackSkipRows(GLint skipRows)
1463{
1464 mPack.skipRows = skipRows;
Jamie Madillc67323a2017-11-02 23:11:41 -04001465 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001466}
1467
1468GLint State::getPackSkipRows() const
1469{
1470 return mPack.skipRows;
1471}
1472
1473void State::setPackSkipPixels(GLint skipPixels)
1474{
1475 mPack.skipPixels = skipPixels;
Jamie Madillc67323a2017-11-02 23:11:41 -04001476 mDirtyBits.set(DIRTY_BIT_PACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001477}
1478
1479GLint State::getPackSkipPixels() const
1480{
1481 return mPack.skipPixels;
1482}
1483
Shannon Woods53a94a82014-06-24 15:20:36 -04001484const PixelPackState &State::getPackState() const
1485{
1486 return mPack;
1487}
1488
Jamie Madill87de3622015-03-16 10:41:44 -04001489PixelPackState &State::getPackState()
1490{
1491 return mPack;
1492}
1493
Shannon Woods53a94a82014-06-24 15:20:36 -04001494void State::setUnpackAlignment(GLint alignment)
1495{
1496 mUnpack.alignment = alignment;
Jamie Madillc67323a2017-11-02 23:11:41 -04001497 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Shannon Woods53a94a82014-06-24 15:20:36 -04001498}
1499
1500GLint State::getUnpackAlignment() const
1501{
1502 return mUnpack.alignment;
1503}
1504
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001505void State::setUnpackRowLength(GLint rowLength)
1506{
1507 mUnpack.rowLength = rowLength;
Jamie Madillc67323a2017-11-02 23:11:41 -04001508 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001509}
1510
1511GLint State::getUnpackRowLength() const
1512{
1513 return mUnpack.rowLength;
1514}
1515
Minmin Gongadff67b2015-10-14 10:34:45 -04001516void State::setUnpackImageHeight(GLint imageHeight)
1517{
1518 mUnpack.imageHeight = imageHeight;
Jamie Madillc67323a2017-11-02 23:11:41 -04001519 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001520}
1521
1522GLint State::getUnpackImageHeight() const
1523{
1524 return mUnpack.imageHeight;
1525}
1526
1527void State::setUnpackSkipImages(GLint skipImages)
1528{
1529 mUnpack.skipImages = skipImages;
Jamie Madillc67323a2017-11-02 23:11:41 -04001530 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001531}
1532
1533GLint State::getUnpackSkipImages() const
1534{
1535 return mUnpack.skipImages;
1536}
1537
1538void State::setUnpackSkipRows(GLint skipRows)
1539{
1540 mUnpack.skipRows = skipRows;
Jamie Madillc67323a2017-11-02 23:11:41 -04001541 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001542}
1543
1544GLint State::getUnpackSkipRows() const
1545{
1546 return mUnpack.skipRows;
1547}
1548
1549void State::setUnpackSkipPixels(GLint skipPixels)
1550{
1551 mUnpack.skipPixels = skipPixels;
Jamie Madillc67323a2017-11-02 23:11:41 -04001552 mDirtyBits.set(DIRTY_BIT_UNPACK_STATE);
Minmin Gongadff67b2015-10-14 10:34:45 -04001553}
1554
1555GLint State::getUnpackSkipPixels() const
1556{
1557 return mUnpack.skipPixels;
1558}
1559
Shannon Woods53a94a82014-06-24 15:20:36 -04001560const PixelUnpackState &State::getUnpackState() const
1561{
1562 return mUnpack;
1563}
1564
Jamie Madill67102f02015-03-16 10:41:42 -04001565PixelUnpackState &State::getUnpackState()
1566{
1567 return mUnpack;
1568}
1569
Geoff Lang70d0f492015-12-10 17:45:46 -05001570const Debug &State::getDebug() const
1571{
1572 return mDebug;
1573}
1574
1575Debug &State::getDebug()
1576{
1577 return mDebug;
1578}
1579
Sami Väisänena797e062016-05-12 15:23:40 +03001580void State::setCoverageModulation(GLenum components)
1581{
1582 mCoverageModulation = components;
1583 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1584}
1585
1586GLenum State::getCoverageModulation() const
1587{
1588 return mCoverageModulation;
1589}
1590
Sami Väisänene45e53b2016-05-25 10:36:04 +03001591void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1592{
1593 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1594 {
1595 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1596 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1597 }
1598 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1599 {
1600 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1601 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1602 }
1603 else
1604 {
1605 UNREACHABLE();
1606 }
1607}
1608
1609const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1610{
1611 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1612 {
1613 return mPathMatrixMV;
1614 }
1615 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1616 {
1617 return mPathMatrixProj;
1618 }
1619
1620 UNREACHABLE();
1621 return nullptr;
1622}
1623
1624void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1625{
1626 mPathStencilFunc = func;
1627 mPathStencilRef = ref;
1628 mPathStencilMask = mask;
1629 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1630}
1631
1632GLenum State::getPathStencilFunc() const
1633{
1634 return mPathStencilFunc;
1635}
1636
1637GLint State::getPathStencilRef() const
1638{
1639 return mPathStencilRef;
1640}
1641
1642GLuint State::getPathStencilMask() const
1643{
1644 return mPathStencilMask;
1645}
1646
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001647void State::setFramebufferSRGB(bool sRGB)
1648{
1649 mFramebufferSRGB = sRGB;
1650 mDirtyBits.set(DIRTY_BIT_FRAMEBUFFER_SRGB);
1651}
1652
1653bool State::getFramebufferSRGB() const
1654{
1655 return mFramebufferSRGB;
1656}
1657
Shannon Woods53a94a82014-06-24 15:20:36 -04001658void State::getBooleanv(GLenum pname, GLboolean *params)
1659{
1660 switch (pname)
1661 {
1662 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1663 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1664 case GL_COLOR_WRITEMASK:
1665 params[0] = mBlend.colorMaskRed;
1666 params[1] = mBlend.colorMaskGreen;
1667 params[2] = mBlend.colorMaskBlue;
1668 params[3] = mBlend.colorMaskAlpha;
1669 break;
Corentin Wallez2e568cf2017-09-18 17:05:22 -04001670 case GL_CULL_FACE:
1671 *params = mRasterizer.cullFace;
1672 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001673 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1674 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1675 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
Jiawei Shaodb342272017-09-27 10:21:45 +08001676 case GL_SAMPLE_MASK:
1677 *params = mSampleMask;
1678 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001679 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1680 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1681 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1682 case GL_BLEND: *params = mBlend.blend; break;
1683 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001684 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1685 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001686 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1687 *params = mPrimitiveRestart;
1688 break;
Geoff Langab831f02015-12-01 09:39:10 -05001689 case GL_RASTERIZER_DISCARD:
1690 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1691 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001692 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1693 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1694 break;
1695 case GL_DEBUG_OUTPUT:
1696 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1697 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001698 case GL_MULTISAMPLE_EXT:
1699 *params = mMultiSampling;
1700 break;
1701 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1702 *params = mSampleAlphaToOne;
1703 break;
Geoff Langf41a7152016-09-19 15:11:17 -04001704 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
1705 *params = isBindGeneratesResourceEnabled() ? GL_TRUE : GL_FALSE;
1706 break;
Geoff Langfeb8c682017-02-13 16:07:35 -05001707 case GL_CLIENT_ARRAYS_ANGLE:
1708 *params = areClientArraysEnabled() ? GL_TRUE : GL_FALSE;
1709 break;
Geoff Lang1d2c41d2016-10-19 16:14:46 -07001710 case GL_FRAMEBUFFER_SRGB_EXT:
1711 *params = getFramebufferSRGB() ? GL_TRUE : GL_FALSE;
1712 break;
Geoff Langb433e872017-10-05 14:01:47 -04001713 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madille08a1d32017-03-07 17:24:06 -05001714 *params = mRobustResourceInit ? GL_TRUE : GL_FALSE;
1715 break;
Jamie Madillc43be722017-07-13 16:22:14 -04001716 case GL_PROGRAM_CACHE_ENABLED_ANGLE:
1717 *params = mProgramBinaryCacheEnabled ? GL_TRUE : GL_FALSE;
1718 break;
1719
Shannon Woods53a94a82014-06-24 15:20:36 -04001720 default:
1721 UNREACHABLE();
1722 break;
1723 }
1724}
1725
1726void State::getFloatv(GLenum pname, GLfloat *params)
1727{
1728 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1729 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1730 // GetIntegerv as its native query function. As it would require conversion in any
1731 // case, this should make no difference to the calling application.
1732 switch (pname)
1733 {
1734 case GL_LINE_WIDTH: *params = mLineWidth; break;
1735 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1736 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1737 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1738 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1739 case GL_DEPTH_RANGE:
1740 params[0] = mNearZ;
1741 params[1] = mFarZ;
1742 break;
1743 case GL_COLOR_CLEAR_VALUE:
1744 params[0] = mColorClearValue.red;
1745 params[1] = mColorClearValue.green;
1746 params[2] = mColorClearValue.blue;
1747 params[3] = mColorClearValue.alpha;
1748 break;
1749 case GL_BLEND_COLOR:
1750 params[0] = mBlendColor.red;
1751 params[1] = mBlendColor.green;
1752 params[2] = mBlendColor.blue;
1753 params[3] = mBlendColor.alpha;
1754 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001755 case GL_MULTISAMPLE_EXT:
1756 *params = static_cast<GLfloat>(mMultiSampling);
1757 break;
1758 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1759 *params = static_cast<GLfloat>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001760 case GL_COVERAGE_MODULATION_CHROMIUM:
Jamie Madille2e406c2016-06-02 13:04:10 -04001761 params[0] = static_cast<GLfloat>(mCoverageModulation);
1762 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001763 default:
1764 UNREACHABLE();
1765 break;
1766 }
1767}
1768
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001769void State::getIntegerv(const Context *context, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001770{
1771 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1772 {
1773 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001774 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001775 Framebuffer *framebuffer = mDrawFramebuffer;
1776 *params = framebuffer->getDrawBufferState(colorAttachment);
1777 return;
1778 }
1779
1780 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1781 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1782 // GetIntegerv as its native query function. As it would require conversion in any
1783 // case, this should make no difference to the calling application. You may find it in
1784 // State::getFloatv.
1785 switch (pname)
1786 {
Corentin Wallez336129f2017-10-17 15:55:40 -04001787 case GL_ARRAY_BUFFER_BINDING:
1788 *params = mBoundBuffers[BufferBinding::Array].id();
1789 break;
1790 case GL_DRAW_INDIRECT_BUFFER_BINDING:
1791 *params = mBoundBuffers[BufferBinding::DrawIndirect].id();
1792 break;
1793 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1794 *params = getVertexArray()->getElementArrayBuffer().id();
1795 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001796 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1797 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1798 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1799 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1800 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001801 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001802 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1803 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001804 case GL_PACK_ROW_LENGTH:
1805 *params = mPack.rowLength;
1806 break;
1807 case GL_PACK_SKIP_ROWS:
1808 *params = mPack.skipRows;
1809 break;
1810 case GL_PACK_SKIP_PIXELS:
1811 *params = mPack.skipPixels;
1812 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001813 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001814 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001815 case GL_UNPACK_IMAGE_HEIGHT:
1816 *params = mUnpack.imageHeight;
1817 break;
1818 case GL_UNPACK_SKIP_IMAGES:
1819 *params = mUnpack.skipImages;
1820 break;
1821 case GL_UNPACK_SKIP_ROWS:
1822 *params = mUnpack.skipRows;
1823 break;
1824 case GL_UNPACK_SKIP_PIXELS:
1825 *params = mUnpack.skipPixels;
1826 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001827 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1828 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001829 case GL_ACTIVE_TEXTURE:
1830 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1831 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001832 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1833 case GL_STENCIL_REF: *params = mStencilRef; break;
jchen10a99ed552017-09-22 08:10:32 +08001834 case GL_STENCIL_VALUE_MASK:
1835 *params = CastMaskValue(context, mDepthStencil.stencilMask);
1836 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001837 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1838 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
jchen10a99ed552017-09-22 08:10:32 +08001839 case GL_STENCIL_BACK_VALUE_MASK:
1840 *params = CastMaskValue(context, mDepthStencil.stencilBackMask);
1841 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001842 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1843 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1844 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1845 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1846 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1847 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1848 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1849 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1850 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1851 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1852 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1853 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1854 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
jchen10a99ed552017-09-22 08:10:32 +08001855 case GL_STENCIL_WRITEMASK:
1856 *params = CastMaskValue(context, mDepthStencil.stencilWritemask);
1857 break;
1858 case GL_STENCIL_BACK_WRITEMASK:
1859 *params = CastMaskValue(context, mDepthStencil.stencilBackWritemask);
1860 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001861 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Jamie Madill4928b7c2017-06-20 12:57:39 -04001862 case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1863 *params = mReadFramebuffer->getImplementationColorReadType(context);
1864 break;
1865 case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1866 *params = mReadFramebuffer->getImplementationColorReadFormat(context);
1867 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001868 case GL_SAMPLE_BUFFERS:
1869 case GL_SAMPLES:
1870 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001871 Framebuffer *framebuffer = mDrawFramebuffer;
Jamie Madilldd43e6c2017-03-24 14:18:49 -04001872 if (framebuffer->checkStatus(context) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001873 {
1874 switch (pname)
1875 {
Jamie Madilla0016b72017-07-14 14:30:46 -04001876 case GL_SAMPLE_BUFFERS:
1877 if (framebuffer->getSamples(context) != 0)
1878 {
1879 *params = 1;
1880 }
1881 else
1882 {
1883 *params = 0;
1884 }
1885 break;
1886 case GL_SAMPLES:
1887 *params = framebuffer->getSamples(context);
1888 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001889 }
1890 }
1891 else
1892 {
1893 *params = 0;
1894 }
1895 }
1896 break;
1897 case GL_VIEWPORT:
1898 params[0] = mViewport.x;
1899 params[1] = mViewport.y;
1900 params[2] = mViewport.width;
1901 params[3] = mViewport.height;
1902 break;
1903 case GL_SCISSOR_BOX:
1904 params[0] = mScissor.x;
1905 params[1] = mScissor.y;
1906 params[2] = mScissor.width;
1907 params[3] = mScissor.height;
1908 break;
Corentin Wallez2e568cf2017-09-18 17:05:22 -04001909 case GL_CULL_FACE_MODE:
1910 *params = ToGLenum(mRasterizer.cullMode);
1911 break;
1912 case GL_FRONT_FACE:
1913 *params = mRasterizer.frontFace;
1914 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001915 case GL_RED_BITS:
1916 case GL_GREEN_BITS:
1917 case GL_BLUE_BITS:
1918 case GL_ALPHA_BITS:
1919 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001920 Framebuffer *framebuffer = getDrawFramebuffer();
1921 const FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001922
1923 if (colorbuffer)
1924 {
1925 switch (pname)
1926 {
1927 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1928 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1929 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1930 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1931 }
1932 }
1933 else
1934 {
1935 *params = 0;
1936 }
1937 }
1938 break;
1939 case GL_DEPTH_BITS:
1940 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001941 const Framebuffer *framebuffer = getDrawFramebuffer();
1942 const FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001943
1944 if (depthbuffer)
1945 {
1946 *params = depthbuffer->getDepthSize();
1947 }
1948 else
1949 {
1950 *params = 0;
1951 }
1952 }
1953 break;
1954 case GL_STENCIL_BITS:
1955 {
Jamie Madill81c2e252017-09-09 23:32:46 -04001956 const Framebuffer *framebuffer = getDrawFramebuffer();
1957 const FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001958
1959 if (stencilbuffer)
1960 {
1961 *params = stencilbuffer->getStencilSize();
1962 }
1963 else
1964 {
1965 *params = 0;
1966 }
1967 }
1968 break;
1969 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001970 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001971 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001972 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001973 case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
1974 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1975 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1976 GL_TEXTURE_RECTANGLE_ANGLE);
1977 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001978 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001979 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001980 *params =
1981 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001982 break;
1983 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001984 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001985 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001986 break;
1987 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001988 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001989 *params =
1990 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001991 break;
JiangYizhou24fe74c2017-07-06 16:56:50 +08001992 case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
1993 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1994 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
1995 GL_TEXTURE_2D_MULTISAMPLE);
1996 break;
John Bauman18319182016-09-28 14:22:27 -07001997 case GL_TEXTURE_BINDING_EXTERNAL_OES:
1998 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1999 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler),
2000 GL_TEXTURE_EXTERNAL_OES);
2001 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002002 case GL_UNIFORM_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002003 *params = mBoundBuffers[BufferBinding::Uniform].id();
2004 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05002005 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05002006 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05002007 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002008 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002009 ASSERT(mTransformFeedback.get() != nullptr);
2010 *params = mTransformFeedback->getGenericBuffer().id();
2011 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002012 case GL_COPY_READ_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002013 *params = mBoundBuffers[BufferBinding::CopyRead].id();
2014 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002015 case GL_COPY_WRITE_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002016 *params = mBoundBuffers[BufferBinding::CopyWrite].id();
2017 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002018 case GL_PIXEL_PACK_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002019 *params = mBoundBuffers[BufferBinding::PixelPack].id();
Corentin Wallezcda6af12017-10-30 19:20:37 -04002020 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002021 case GL_PIXEL_UNPACK_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002022 *params = mBoundBuffers[BufferBinding::PixelUnpack].id();
Corentin Wallezcda6af12017-10-30 19:20:37 -04002023 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02002024 case GL_READ_BUFFER:
2025 *params = mReadFramebuffer->getReadBufferState();
2026 break;
2027 case GL_SAMPLER_BINDING:
2028 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
2029 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
2030 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05002031 case GL_DEBUG_LOGGED_MESSAGES:
2032 *params = static_cast<GLint>(mDebug.getMessageCount());
2033 break;
2034 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
2035 *params = static_cast<GLint>(mDebug.getNextMessageLength());
2036 break;
2037 case GL_DEBUG_GROUP_STACK_DEPTH:
2038 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
2039 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03002040 case GL_MULTISAMPLE_EXT:
2041 *params = static_cast<GLint>(mMultiSampling);
2042 break;
2043 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
2044 *params = static_cast<GLint>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03002045 case GL_COVERAGE_MODULATION_CHROMIUM:
2046 *params = static_cast<GLint>(mCoverageModulation);
Sami Väisänen74c23472016-05-09 17:30:30 +03002047 break;
Jiajia Qin6eafb042016-12-27 17:04:07 +08002048 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002049 *params = mBoundBuffers[BufferBinding::AtomicCounter].id();
Jiajia Qin6eafb042016-12-27 17:04:07 +08002050 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002051 case GL_SHADER_STORAGE_BUFFER_BINDING:
Corentin Wallez336129f2017-10-17 15:55:40 -04002052 *params = mBoundBuffers[BufferBinding::ShaderStorage].id();
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002053 break;
Qin Jiajiaa98a2812017-11-30 18:12:06 +08002054 case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
2055 *params = mBoundBuffers[BufferBinding::DispatchIndirect].id();
2056 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002057 default:
2058 UNREACHABLE();
2059 break;
2060 }
2061}
2062
Geoff Lang70d0f492015-12-10 17:45:46 -05002063void State::getPointerv(GLenum pname, void **params) const
2064{
2065 switch (pname)
2066 {
2067 case GL_DEBUG_CALLBACK_FUNCTION:
2068 *params = reinterpret_cast<void *>(mDebug.getCallback());
2069 break;
2070 case GL_DEBUG_CALLBACK_USER_PARAM:
2071 *params = const_cast<void *>(mDebug.getUserParam());
2072 break;
2073 default:
2074 UNREACHABLE();
2075 break;
2076 }
2077}
2078
Martin Radev66fb8202016-07-28 11:45:20 +03002079void State::getIntegeri_v(GLenum target, GLuint index, GLint *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04002080{
2081 switch (target)
2082 {
2083 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002084 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2085 *data = mTransformFeedback->getIndexedBuffer(index).id();
2086 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002087 case GL_UNIFORM_BUFFER_BINDING:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002088 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2089 *data = mUniformBuffers[index].id();
2090 break;
2091 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
2092 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2093 *data = mAtomicCounterBuffers[index].id();
2094 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002095 case GL_SHADER_STORAGE_BUFFER_BINDING:
2096 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2097 *data = mShaderStorageBuffers[index].id();
2098 break;
Shao80957d92017-02-20 21:25:59 +08002099 case GL_VERTEX_BINDING_BUFFER:
2100 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002101 *data = mVertexArray->getVertexBinding(index).getBuffer().id();
Shao80957d92017-02-20 21:25:59 +08002102 break;
2103 case GL_VERTEX_BINDING_DIVISOR:
2104 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002105 *data = mVertexArray->getVertexBinding(index).getDivisor();
Shao80957d92017-02-20 21:25:59 +08002106 break;
2107 case GL_VERTEX_BINDING_OFFSET:
2108 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002109 *data = static_cast<GLuint>(mVertexArray->getVertexBinding(index).getOffset());
Shao80957d92017-02-20 21:25:59 +08002110 break;
2111 case GL_VERTEX_BINDING_STRIDE:
2112 ASSERT(static_cast<size_t>(index) < mVertexArray->getMaxBindings());
Martin Radevdd5f27e2017-06-07 10:17:09 +03002113 *data = mVertexArray->getVertexBinding(index).getStride();
Shao80957d92017-02-20 21:25:59 +08002114 break;
Jiawei Shaodb342272017-09-27 10:21:45 +08002115 case GL_SAMPLE_MASK_VALUE:
2116 ASSERT(static_cast<size_t>(index) < mSampleMaskValues.size());
2117 *data = mSampleMaskValues[index];
2118 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002119 default:
Martin Radev66fb8202016-07-28 11:45:20 +03002120 UNREACHABLE();
2121 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002122 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002123}
2124
Martin Radev66fb8202016-07-28 11:45:20 +03002125void State::getInteger64i_v(GLenum target, GLuint index, GLint64 *data)
Shannon Woods53a94a82014-06-24 15:20:36 -04002126{
2127 switch (target)
2128 {
2129 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002130 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2131 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
2132 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002133 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002134 ASSERT(static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount());
2135 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
2136 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002137 case GL_UNIFORM_BUFFER_START:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002138 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2139 *data = mUniformBuffers[index].getOffset();
2140 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002141 case GL_UNIFORM_BUFFER_SIZE:
Jiajia Qin6eafb042016-12-27 17:04:07 +08002142 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
2143 *data = mUniformBuffers[index].getSize();
2144 break;
2145 case GL_ATOMIC_COUNTER_BUFFER_START:
2146 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2147 *data = mAtomicCounterBuffers[index].getOffset();
2148 break;
2149 case GL_ATOMIC_COUNTER_BUFFER_SIZE:
2150 ASSERT(static_cast<size_t>(index) < mAtomicCounterBuffers.size());
2151 *data = mAtomicCounterBuffers[index].getSize();
2152 break;
Jiajia Qinf546e7d2017-03-27 14:12:59 +08002153 case GL_SHADER_STORAGE_BUFFER_START:
2154 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2155 *data = mShaderStorageBuffers[index].getOffset();
2156 break;
2157 case GL_SHADER_STORAGE_BUFFER_SIZE:
2158 ASSERT(static_cast<size_t>(index) < mShaderStorageBuffers.size());
2159 *data = mShaderStorageBuffers[index].getSize();
2160 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002161 default:
Martin Radev66fb8202016-07-28 11:45:20 +03002162 UNREACHABLE();
2163 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04002164 }
Martin Radev66fb8202016-07-28 11:45:20 +03002165}
Shannon Woods53a94a82014-06-24 15:20:36 -04002166
Martin Radev66fb8202016-07-28 11:45:20 +03002167void State::getBooleani_v(GLenum target, GLuint index, GLboolean *data)
2168{
2169 UNREACHABLE();
Shannon Woods53a94a82014-06-24 15:20:36 -04002170}
2171
Corentin Wallez336129f2017-10-17 15:55:40 -04002172bool State::hasMappedBuffer(BufferBinding target) const
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002173{
Corentin Wallez336129f2017-10-17 15:55:40 -04002174 if (target == BufferBinding::Array)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002175 {
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002176 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04002177 const auto &vertexAttribs = vao->getVertexAttributes();
Jiawei-Shao2597fb62016-12-09 16:38:02 +08002178 const auto &vertexBindings = vao->getVertexBindings();
Jamie Madill8e344942015-07-09 14:22:07 -04002179 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04002180 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002181 {
Jamie Madill81c2e252017-09-09 23:32:46 -04002182 const VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Martin Radevdd5f27e2017-06-07 10:17:09 +03002183 auto *boundBuffer = vertexBindings[vertexAttrib.bindingIndex].getBuffer().get();
Jamie Madilld9ba4f72014-08-04 10:47:59 -04002184 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
2185 {
2186 return true;
2187 }
2188 }
2189
2190 return false;
2191 }
2192 else
2193 {
2194 Buffer *buffer = getTargetBuffer(target);
2195 return (buffer && buffer->isMapped());
2196 }
2197}
2198
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002199void State::syncDirtyObjects(const Context *context)
Jamie Madillc9d442d2016-01-20 11:17:24 -05002200{
2201 if (!mDirtyObjects.any())
2202 return;
2203
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002204 syncDirtyObjects(context, mDirtyObjects);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002205}
2206
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002207void State::syncDirtyObjects(const Context *context, const DirtyObjects &bitset)
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002208{
Jamie Madill6de51852017-04-12 09:53:01 -04002209 for (auto dirtyObject : bitset)
Jamie Madillc9d442d2016-01-20 11:17:24 -05002210 {
2211 switch (dirtyObject)
2212 {
2213 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002214 ASSERT(mReadFramebuffer);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002215 mReadFramebuffer->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002216 break;
2217 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002218 ASSERT(mDrawFramebuffer);
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002219 mDrawFramebuffer->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002220 break;
2221 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002222 ASSERT(mVertexArray);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002223 mVertexArray->syncState(context);
Jamie Madillc9d442d2016-01-20 11:17:24 -05002224 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002225 case DIRTY_OBJECT_PROGRAM_TEXTURES:
2226 syncProgramTextures(context);
2227 break;
2228
Jamie Madillc9d442d2016-01-20 11:17:24 -05002229 default:
2230 UNREACHABLE();
2231 break;
2232 }
2233 }
2234
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002235 mDirtyObjects &= ~bitset;
2236}
2237
Jamie Madill81c2e252017-09-09 23:32:46 -04002238void State::syncProgramTextures(const Context *context)
2239{
Jamie Madill81c2e252017-09-09 23:32:46 -04002240 // TODO(jmadill): Fine-grained updates.
2241 if (!mProgram)
2242 {
2243 return;
2244 }
2245
2246 ASSERT(mDirtyObjects[DIRTY_OBJECT_PROGRAM_TEXTURES]);
2247 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2248
Jamie Madill0f80ed82017-09-19 00:24:56 -04002249 ActiveTextureMask newActiveTextures;
2250
Geoff Lange51ba632017-11-21 11:45:25 -05002251 // Initialize to the 'Initialized' state and set to 'MayNeedInit' if any texture is not
2252 // initialized.
2253 mCachedTexturesInitState = InitState::Initialized;
2254
Jamie Madill81c2e252017-09-09 23:32:46 -04002255 for (const SamplerBinding &samplerBinding : mProgram->getSamplerBindings())
2256 {
2257 if (samplerBinding.unreferenced)
2258 continue;
2259
2260 GLenum textureType = samplerBinding.textureType;
2261 for (GLuint textureUnitIndex : samplerBinding.boundTextureUnits)
2262 {
2263 Texture *texture = getSamplerTexture(textureUnitIndex, textureType);
Jamie Madill06ef36b2017-09-09 23:32:46 -04002264 Sampler *sampler = getSampler(textureUnitIndex);
Jamie Madill0f80ed82017-09-19 00:24:56 -04002265 ASSERT(static_cast<size_t>(textureUnitIndex) < mCompleteTextureCache.size());
2266 ASSERT(static_cast<size_t>(textureUnitIndex) < newActiveTextures.size());
Jamie Madill81c2e252017-09-09 23:32:46 -04002267
Jamie Madill42975642017-10-12 12:31:51 -04002268 ASSERT(texture);
Jamie Madill81c2e252017-09-09 23:32:46 -04002269
Jamie Madill42975642017-10-12 12:31:51 -04002270 // Mark the texture binding bit as dirty if the texture completeness changes.
2271 // TODO(jmadill): Use specific dirty bit for completeness change.
2272 if (texture->isSamplerComplete(context, sampler) &&
2273 !mDrawFramebuffer->hasTextureAttachment(texture))
2274 {
2275 texture->syncState();
2276 mCompleteTextureCache[textureUnitIndex] = texture;
Jamie Madill81c2e252017-09-09 23:32:46 -04002277 }
Jamie Madill42975642017-10-12 12:31:51 -04002278 else
2279 {
2280 mCompleteTextureCache[textureUnitIndex] = nullptr;
2281 }
2282
2283 // Bind the texture unconditionally, to recieve completeness change notifications.
2284 mCompleteTextureBindings[textureUnitIndex].bind(texture->getDirtyChannel());
Jamie Madilla59fc192017-11-02 12:57:58 -04002285 mActiveTexturesMask.set(textureUnitIndex);
Jamie Madill42975642017-10-12 12:31:51 -04002286 newActiveTextures.set(textureUnitIndex);
Jamie Madill81c2e252017-09-09 23:32:46 -04002287
Jamie Madill06ef36b2017-09-09 23:32:46 -04002288 if (sampler != nullptr)
2289 {
2290 sampler->syncState(context);
2291 }
Geoff Lange51ba632017-11-21 11:45:25 -05002292
2293 if (texture->initState() == InitState::MayNeedInit)
2294 {
2295 mCachedTexturesInitState = InitState::MayNeedInit;
2296 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002297 }
2298 }
Jamie Madill0f80ed82017-09-19 00:24:56 -04002299
2300 // Unset now missing textures.
Jamie Madilla59fc192017-11-02 12:57:58 -04002301 ActiveTextureMask negativeMask = mActiveTexturesMask & ~newActiveTextures;
Jamie Madill0f80ed82017-09-19 00:24:56 -04002302 if (negativeMask.any())
2303 {
2304 for (auto textureIndex : negativeMask)
2305 {
2306 mCompleteTextureBindings[textureIndex].reset();
2307 mCompleteTextureCache[textureIndex] = nullptr;
Jamie Madilla59fc192017-11-02 12:57:58 -04002308 mActiveTexturesMask.reset(textureIndex);
Jamie Madill0f80ed82017-09-19 00:24:56 -04002309 }
2310 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002311}
2312
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002313void State::syncDirtyObject(const Context *context, GLenum target)
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002314{
2315 DirtyObjects localSet;
2316
2317 switch (target)
2318 {
2319 case GL_READ_FRAMEBUFFER:
2320 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2321 break;
2322 case GL_DRAW_FRAMEBUFFER:
2323 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2324 break;
2325 case GL_FRAMEBUFFER:
2326 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2327 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2328 break;
2329 case GL_VERTEX_ARRAY:
2330 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
2331 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002332 case GL_TEXTURE:
2333 case GL_SAMPLER:
2334 case GL_PROGRAM:
2335 localSet.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2336 break;
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002337 }
2338
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002339 syncDirtyObjects(context, localSet);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002340}
2341
2342void State::setObjectDirty(GLenum target)
2343{
2344 switch (target)
2345 {
2346 case GL_READ_FRAMEBUFFER:
2347 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2348 break;
2349 case GL_DRAW_FRAMEBUFFER:
2350 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2351 break;
2352 case GL_FRAMEBUFFER:
2353 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
2354 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
2355 break;
2356 case GL_VERTEX_ARRAY:
2357 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
2358 break;
Jamie Madill81c2e252017-09-09 23:32:46 -04002359 case GL_TEXTURE:
2360 case GL_SAMPLER:
Jamie Madill81c2e252017-09-09 23:32:46 -04002361 case GL_PROGRAM:
2362 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
2363 mDirtyBits.set(DIRTY_BIT_TEXTURE_BINDINGS);
2364 break;
Jamie Madilla779b612017-07-24 11:46:05 -04002365 }
2366}
2367
2368void State::onProgramExecutableChange(Program *program)
2369{
2370 // OpenGL Spec:
2371 // "If LinkProgram or ProgramBinary successfully re-links a program object
2372 // that was already in use as a result of a previous call to UseProgram, then the
2373 // generated executable code will be installed as part of the current rendering state."
2374 if (program->isLinked() && mProgram == program)
2375 {
2376 mDirtyBits.set(DIRTY_BIT_PROGRAM_EXECUTABLE);
Jamie Madill81c2e252017-09-09 23:32:46 -04002377 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Jamie Madill60ec6ea2016-01-22 15:27:19 -05002378 }
Shannon Woods53a94a82014-06-24 15:20:36 -04002379}
Jamie Madillc9d442d2016-01-20 11:17:24 -05002380
Xinghua Cao65ec0b22017-03-28 16:10:52 +08002381void State::setImageUnit(const Context *context,
2382 GLuint unit,
2383 Texture *texture,
2384 GLint level,
2385 GLboolean layered,
2386 GLint layer,
2387 GLenum access,
2388 GLenum format)
2389{
2390 mImageUnits[unit].texture.set(context, texture);
2391 mImageUnits[unit].level = level;
2392 mImageUnits[unit].layered = layered;
2393 mImageUnits[unit].layer = layer;
2394 mImageUnits[unit].access = access;
2395 mImageUnits[unit].format = format;
2396}
2397
2398const ImageUnit &State::getImageUnit(GLuint unit) const
2399{
2400 return mImageUnits[unit];
2401}
2402
Jamie Madill81c2e252017-09-09 23:32:46 -04002403// Handle a dirty texture event.
Jamie Madill05b35b22017-10-03 09:01:44 -04002404void State::signal(size_t textureIndex, InitState initState)
Jamie Madill81c2e252017-09-09 23:32:46 -04002405{
2406 // Conservatively assume all textures are dirty.
2407 // TODO(jmadill): More fine-grained update.
2408 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM_TEXTURES);
Geoff Lange51ba632017-11-21 11:45:25 -05002409
2410 if (initState == InitState::MayNeedInit)
2411 {
2412 mCachedTexturesInitState = InitState::MayNeedInit;
2413 }
Jamie Madill81c2e252017-09-09 23:32:46 -04002414}
2415
Jamie Madill05b35b22017-10-03 09:01:44 -04002416Error State::clearUnclearedActiveTextures(const Context *context)
2417{
Jamie Madilla59fc192017-11-02 12:57:58 -04002418 ASSERT(mRobustResourceInit);
Jamie Madill05b35b22017-10-03 09:01:44 -04002419
Geoff Lange51ba632017-11-21 11:45:25 -05002420 if (mCachedTexturesInitState == InitState::Initialized)
2421 {
2422 return NoError();
2423 }
2424
Jamie Madilla59fc192017-11-02 12:57:58 -04002425 for (auto textureIndex : mActiveTexturesMask)
Jamie Madill05b35b22017-10-03 09:01:44 -04002426 {
Jamie Madilla59fc192017-11-02 12:57:58 -04002427 Texture *texture = mCompleteTextureCache[textureIndex];
Jamie Madill05b35b22017-10-03 09:01:44 -04002428 if (texture)
2429 {
2430 ANGLE_TRY(texture->ensureInitialized(context));
2431 }
2432 }
Jamie Madilla59fc192017-11-02 12:57:58 -04002433
Geoff Lange51ba632017-11-21 11:45:25 -05002434 mCachedTexturesInitState = InitState::Initialized;
2435
Jamie Madill05b35b22017-10-03 09:01:44 -04002436 return NoError();
2437}
2438
Jamie Madillc67323a2017-11-02 23:11:41 -04002439AttributesMask State::getAndResetDirtyCurrentValues() const
2440{
2441 AttributesMask retVal = mDirtyCurrentValues;
2442 mDirtyCurrentValues.reset();
2443 return retVal;
2444}
2445
Jamie Madillc9d442d2016-01-20 11:17:24 -05002446} // namespace gl