blob: a5ae996144ce82f1e983117eb4d3eada01e48b3b [file] [log] [blame]
Shannon Woods53a94a82014-06-24 15:20:36 -04001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// State.cpp: Implements the State class, encapsulating raw GL state.
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/State.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040010
Sami Väisänene45e53b2016-05-25 10:36:04 +030011#include <limits>
12#include <string.h>
13
Jamie Madillc9d442d2016-01-20 11:17:24 -050014#include "common/BitSetIterator.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030015#include "common/matrix_utils.h"
16#include "common/mathutil.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050017#include "libANGLE/Context.h"
18#include "libANGLE/Caps.h"
Geoff Lang70d0f492015-12-10 17:45:46 -050019#include "libANGLE/Debug.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050020#include "libANGLE/Framebuffer.h"
21#include "libANGLE/FramebufferAttachment.h"
22#include "libANGLE/Query.h"
23#include "libANGLE/VertexArray.h"
24#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040025
26namespace gl
27{
Geoff Lang76b10c92014-09-05 16:28:14 -040028
Shannon Woods53a94a82014-06-24 15:20:36 -040029State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050030 : mMaxDrawBuffers(0),
31 mMaxCombinedTextureImageUnits(0),
32 mDepthClearValue(0),
33 mStencilClearValue(0),
34 mScissorTest(false),
35 mSampleCoverage(false),
36 mSampleCoverageValue(0),
37 mSampleCoverageInvert(false),
38 mStencilRef(0),
39 mStencilBackRef(0),
40 mLineWidth(0),
41 mGenerateMipmapHint(GL_NONE),
42 mFragmentShaderDerivativeHint(GL_NONE),
43 mNearZ(0),
44 mFarZ(0),
45 mReadFramebuffer(nullptr),
46 mDrawFramebuffer(nullptr),
47 mProgram(nullptr),
48 mVertexArray(nullptr),
49 mActiveSampler(0),
Sami Väisänen74c23472016-05-09 17:30:30 +030050 mPrimitiveRestart(false),
51 mMultiSampling(false),
52 mSampleAlphaToOne(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040053{
Geoff Lang76b10c92014-09-05 16:28:14 -040054}
55
56State::~State()
57{
58 reset();
59}
60
Geoff Lang70d0f492015-12-10 17:45:46 -050061void State::initialize(const Caps &caps,
62 const Extensions &extensions,
63 GLuint clientVersion,
64 bool debug)
Geoff Lang76b10c92014-09-05 16:28:14 -040065{
Shannon Woods2df6a602014-09-26 16:12:07 -040066 mMaxDrawBuffers = caps.maxDrawBuffers;
67 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040068
Jamie Madillf75ab352015-03-16 10:46:52 -040069 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040070
71 mDepthClearValue = 1.0f;
72 mStencilClearValue = 0;
73
74 mRasterizer.rasterizerDiscard = false;
75 mRasterizer.cullFace = false;
76 mRasterizer.cullMode = GL_BACK;
77 mRasterizer.frontFace = GL_CCW;
78 mRasterizer.polygonOffsetFill = false;
79 mRasterizer.polygonOffsetFactor = 0.0f;
80 mRasterizer.polygonOffsetUnits = 0.0f;
81 mRasterizer.pointDrawMode = false;
82 mRasterizer.multiSample = false;
83 mScissorTest = false;
84 mScissor.x = 0;
85 mScissor.y = 0;
86 mScissor.width = 0;
87 mScissor.height = 0;
88
89 mBlend.blend = false;
90 mBlend.sourceBlendRGB = GL_ONE;
91 mBlend.sourceBlendAlpha = GL_ONE;
92 mBlend.destBlendRGB = GL_ZERO;
93 mBlend.destBlendAlpha = GL_ZERO;
94 mBlend.blendEquationRGB = GL_FUNC_ADD;
95 mBlend.blendEquationAlpha = GL_FUNC_ADD;
96 mBlend.sampleAlphaToCoverage = false;
97 mBlend.dither = true;
98
99 mBlendColor.red = 0;
100 mBlendColor.green = 0;
101 mBlendColor.blue = 0;
102 mBlendColor.alpha = 0;
103
104 mDepthStencil.depthTest = false;
105 mDepthStencil.depthFunc = GL_LESS;
106 mDepthStencil.depthMask = true;
107 mDepthStencil.stencilTest = false;
108 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700109 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
110 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400111 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700112 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
113 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400114 mDepthStencil.stencilFail = GL_KEEP;
115 mDepthStencil.stencilPassDepthFail = GL_KEEP;
116 mDepthStencil.stencilPassDepthPass = GL_KEEP;
117 mDepthStencil.stencilBackFail = GL_KEEP;
118 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
119 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
120
121 mStencilRef = 0;
122 mStencilBackRef = 0;
123
124 mSampleCoverage = false;
125 mSampleCoverageValue = 1.0f;
126 mSampleCoverageInvert = false;
127 mGenerateMipmapHint = GL_DONT_CARE;
128 mFragmentShaderDerivativeHint = GL_DONT_CARE;
129
130 mLineWidth = 1.0f;
131
132 mViewport.x = 0;
133 mViewport.y = 0;
134 mViewport.width = 0;
135 mViewport.height = 0;
136 mNearZ = 0.0f;
137 mFarZ = 1.0f;
138
139 mBlend.colorMaskRed = true;
140 mBlend.colorMaskGreen = true;
141 mBlend.colorMaskBlue = true;
142 mBlend.colorMaskAlpha = true;
143
Geoff Lang76b10c92014-09-05 16:28:14 -0400144 mActiveSampler = 0;
145
Shannon Woods23e05002014-09-22 19:07:27 -0400146 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400147
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400148 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
149
Geoff Lang76b10c92014-09-05 16:28:14 -0400150 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
151 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
152 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400153 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400154 // TODO: These could also be enabled via extension
155 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
156 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400157 }
Ian Ewellbda75592016-04-18 17:25:54 -0400158 if (extensions.eglImageExternal || extensions.eglStreamConsumerExternal)
159 {
160 mSamplerTextures[GL_TEXTURE_EXTERNAL_OES].resize(caps.maxCombinedTextureImageUnits);
161 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400162
Geoff Lang76b10c92014-09-05 16:28:14 -0400163 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400164
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500165 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(nullptr);
166 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(nullptr);
167 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(nullptr);
168 mActiveQueries[GL_TIME_ELAPSED_EXT].set(nullptr);
Geoff Lang2b4ce802016-04-28 13:34:50 -0400169 mActiveQueries[GL_COMMANDS_COMPLETED_CHROMIUM].set(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400170
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500171 mProgram = nullptr;
Shannon Woods53a94a82014-06-24 15:20:36 -0400172
Ian Ewell3ffd78b2016-01-22 16:09:42 -0500173 mReadFramebuffer = nullptr;
174 mDrawFramebuffer = nullptr;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500175
176 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500177
178 mDebug.setOutputEnabled(debug);
179 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Sami Väisänen74c23472016-05-09 17:30:30 +0300180
181 if (extensions.framebufferMultisample)
182 {
183 mMultiSampling = true;
184 mSampleAlphaToOne = false;
185 }
Sami Väisänena797e062016-05-12 15:23:40 +0300186
187 mCoverageModulation = GL_NONE;
Sami Väisänene45e53b2016-05-25 10:36:04 +0300188
189 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
190 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
191 mPathStencilFunc = GL_ALWAYS;
192 mPathStencilRef = 0;
193 mPathStencilMask = std::numeric_limits<GLuint>::max();
Shannon Woods53a94a82014-06-24 15:20:36 -0400194}
195
Geoff Lang76b10c92014-09-05 16:28:14 -0400196void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400197{
Geoff Lang76b10c92014-09-05 16:28:14 -0400198 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400199 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400200 TextureBindingVector &textureVector = bindingVec->second;
201 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400202 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400203 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400204 }
205 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400206 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
207 {
208 mSamplers[samplerIdx].set(NULL);
209 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400210
Shannon Woods53a94a82014-06-24 15:20:36 -0400211 mArrayBuffer.set(NULL);
212 mRenderbuffer.set(NULL);
213
Geoff Lang7dd2e102014-11-10 15:19:26 -0500214 if (mProgram)
215 {
216 mProgram->release();
217 }
218 mProgram = NULL;
219
Shannon Woods53a94a82014-06-24 15:20:36 -0400220 mTransformFeedback.set(NULL);
221
222 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
223 {
224 i->second.set(NULL);
225 }
226
227 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400228 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400229 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400230 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400231 }
232
Shannon Woods53a94a82014-06-24 15:20:36 -0400233 mCopyReadBuffer.set(NULL);
234 mCopyWriteBuffer.set(NULL);
235
236 mPack.pixelBuffer.set(NULL);
237 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500238
239 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400240
Sami Väisänene45e53b2016-05-25 10:36:04 +0300241 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixProj);
242 angle::Matrix<GLfloat>::setToIdentity(mPathMatrixMV);
243 mPathStencilFunc = GL_ALWAYS;
244 mPathStencilRef = 0;
245 mPathStencilMask = std::numeric_limits<GLuint>::max();
246
Jamie Madill1b94d432015-08-07 13:23:23 -0400247 // TODO(jmadill): Is this necessary?
248 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400249}
250
251const RasterizerState &State::getRasterizerState() const
252{
253 return mRasterizer;
254}
255
256const BlendState &State::getBlendState() const
257{
258 return mBlend;
259}
260
261const DepthStencilState &State::getDepthStencilState() const
262{
263 return mDepthStencil;
264}
265
Jamie Madillf75ab352015-03-16 10:46:52 -0400266void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400267{
268 mColorClearValue.red = red;
269 mColorClearValue.green = green;
270 mColorClearValue.blue = blue;
271 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400272 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400273}
274
Jamie Madillf75ab352015-03-16 10:46:52 -0400275void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400276{
277 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400278 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400279}
280
Jamie Madillf75ab352015-03-16 10:46:52 -0400281void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400282{
283 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400284 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400285}
286
Shannon Woods53a94a82014-06-24 15:20:36 -0400287void State::setColorMask(bool red, bool green, bool blue, bool alpha)
288{
289 mBlend.colorMaskRed = red;
290 mBlend.colorMaskGreen = green;
291 mBlend.colorMaskBlue = blue;
292 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400293 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400294}
295
296void State::setDepthMask(bool mask)
297{
298 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400299 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400300}
301
302bool State::isRasterizerDiscardEnabled() const
303{
304 return mRasterizer.rasterizerDiscard;
305}
306
307void State::setRasterizerDiscard(bool enabled)
308{
309 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400310 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400311}
312
313bool State::isCullFaceEnabled() const
314{
315 return mRasterizer.cullFace;
316}
317
318void State::setCullFace(bool enabled)
319{
320 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400321 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400322}
323
324void State::setCullMode(GLenum mode)
325{
326 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400327 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400328}
329
330void State::setFrontFace(GLenum front)
331{
332 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400333 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400334}
335
336bool State::isDepthTestEnabled() const
337{
338 return mDepthStencil.depthTest;
339}
340
341void State::setDepthTest(bool enabled)
342{
343 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400344 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400345}
346
347void State::setDepthFunc(GLenum depthFunc)
348{
349 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400350 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400351}
352
353void State::setDepthRange(float zNear, float zFar)
354{
355 mNearZ = zNear;
356 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400357 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400358}
359
Geoff Langd42f5b82015-04-16 14:03:29 -0400360float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400361{
Geoff Langd42f5b82015-04-16 14:03:29 -0400362 return mNearZ;
363}
364
365float State::getFarPlane() const
366{
367 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400368}
369
370bool State::isBlendEnabled() const
371{
372 return mBlend.blend;
373}
374
375void State::setBlend(bool enabled)
376{
377 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400378 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400379}
380
381void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
382{
383 mBlend.sourceBlendRGB = sourceRGB;
384 mBlend.destBlendRGB = destRGB;
385 mBlend.sourceBlendAlpha = sourceAlpha;
386 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400387 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400388}
389
390void State::setBlendColor(float red, float green, float blue, float alpha)
391{
392 mBlendColor.red = red;
393 mBlendColor.green = green;
394 mBlendColor.blue = blue;
395 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400396 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400397}
398
399void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
400{
401 mBlend.blendEquationRGB = rgbEquation;
402 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400403 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400404}
405
406const ColorF &State::getBlendColor() const
407{
408 return mBlendColor;
409}
410
411bool State::isStencilTestEnabled() const
412{
413 return mDepthStencil.stencilTest;
414}
415
416void State::setStencilTest(bool enabled)
417{
418 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400419 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400420}
421
422void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
423{
424 mDepthStencil.stencilFunc = stencilFunc;
425 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
426 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400427 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400428}
429
430void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
431{
432 mDepthStencil.stencilBackFunc = stencilBackFunc;
433 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
434 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400435 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400436}
437
438void State::setStencilWritemask(GLuint stencilWritemask)
439{
440 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400441 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400442}
443
444void State::setStencilBackWritemask(GLuint stencilBackWritemask)
445{
446 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400447 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400448}
449
450void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
451{
452 mDepthStencil.stencilFail = stencilFail;
453 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
454 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400455 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400456}
457
458void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
459{
460 mDepthStencil.stencilBackFail = stencilBackFail;
461 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
462 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400463 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400464}
465
466GLint State::getStencilRef() const
467{
468 return mStencilRef;
469}
470
471GLint State::getStencilBackRef() const
472{
473 return mStencilBackRef;
474}
475
476bool State::isPolygonOffsetFillEnabled() const
477{
478 return mRasterizer.polygonOffsetFill;
479}
480
481void State::setPolygonOffsetFill(bool enabled)
482{
Jamie Madill1b94d432015-08-07 13:23:23 -0400483 mRasterizer.polygonOffsetFill = enabled;
484 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400485}
486
487void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
488{
489 // An application can pass NaN values here, so handle this gracefully
490 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
491 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400492 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400493}
494
495bool State::isSampleAlphaToCoverageEnabled() const
496{
497 return mBlend.sampleAlphaToCoverage;
498}
499
500void State::setSampleAlphaToCoverage(bool enabled)
501{
502 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400503 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400504}
505
506bool State::isSampleCoverageEnabled() const
507{
508 return mSampleCoverage;
509}
510
511void State::setSampleCoverage(bool enabled)
512{
513 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400514 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400515}
516
517void State::setSampleCoverageParams(GLclampf value, bool invert)
518{
519 mSampleCoverageValue = value;
520 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400521 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400522}
523
Geoff Lang0fbb6002015-04-16 11:11:53 -0400524GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400525{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400526 return mSampleCoverageValue;
527}
Shannon Woods53a94a82014-06-24 15:20:36 -0400528
Geoff Lang0fbb6002015-04-16 11:11:53 -0400529bool State::getSampleCoverageInvert() const
530{
531 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400532}
533
Sami Väisänen74c23472016-05-09 17:30:30 +0300534void State::setSampleAlphaToOne(bool enabled)
535{
536 mSampleAlphaToOne = enabled;
537 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
538}
539
540bool State::isSampleAlphaToOneEnabled() const
541{
542 return mSampleAlphaToOne;
543}
544
545void State::setMultisampling(bool enabled)
546{
547 mMultiSampling = enabled;
548 mDirtyBits.set(DIRTY_BIT_MULTISAMPLING);
549}
550
551bool State::isMultisamplingEnabled() const
552{
553 return mMultiSampling;
554}
555
Shannon Woods53a94a82014-06-24 15:20:36 -0400556bool State::isScissorTestEnabled() const
557{
558 return mScissorTest;
559}
560
561void State::setScissorTest(bool enabled)
562{
563 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400564 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400565}
566
567void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
568{
569 mScissor.x = x;
570 mScissor.y = y;
571 mScissor.width = width;
572 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400573 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400574}
575
576const Rectangle &State::getScissor() const
577{
578 return mScissor;
579}
580
581bool State::isDitherEnabled() const
582{
583 return mBlend.dither;
584}
585
586void State::setDither(bool enabled)
587{
588 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400589 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400590}
591
Jamie Madillb4b53c52015-02-03 15:22:48 -0500592bool State::isPrimitiveRestartEnabled() const
593{
594 return mPrimitiveRestart;
595}
596
597void State::setPrimitiveRestart(bool enabled)
598{
599 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400600 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500601}
602
Shannon Woods53a94a82014-06-24 15:20:36 -0400603void State::setEnableFeature(GLenum feature, bool enabled)
604{
605 switch (feature)
606 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300607 case GL_MULTISAMPLE_EXT: setMultisampling(enabled); break;
608 case GL_SAMPLE_ALPHA_TO_ONE_EXT: setSampleAlphaToOne(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400609 case GL_CULL_FACE: setCullFace(enabled); break;
610 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
611 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
612 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
613 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
614 case GL_STENCIL_TEST: setStencilTest(enabled); break;
615 case GL_DEPTH_TEST: setDepthTest(enabled); break;
616 case GL_BLEND: setBlend(enabled); break;
617 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500618 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400619 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500620 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
621 mDebug.setOutputSynchronous(enabled);
622 break;
623 case GL_DEBUG_OUTPUT:
624 mDebug.setOutputEnabled(enabled);
625 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400626 default: UNREACHABLE();
627 }
628}
629
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700630bool State::getEnableFeature(GLenum feature) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400631{
632 switch (feature)
633 {
Sami Väisänen74c23472016-05-09 17:30:30 +0300634 case GL_MULTISAMPLE_EXT: return isMultisamplingEnabled();
635 case GL_SAMPLE_ALPHA_TO_ONE_EXT: return isSampleAlphaToOneEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400636 case GL_CULL_FACE: return isCullFaceEnabled();
637 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
638 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
639 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
640 case GL_SCISSOR_TEST: return isScissorTestEnabled();
641 case GL_STENCIL_TEST: return isStencilTestEnabled();
642 case GL_DEPTH_TEST: return isDepthTestEnabled();
643 case GL_BLEND: return isBlendEnabled();
644 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500645 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400646 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Lang70d0f492015-12-10 17:45:46 -0500647 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
648 return mDebug.isOutputSynchronous();
649 case GL_DEBUG_OUTPUT:
650 return mDebug.isOutputEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400651 default: UNREACHABLE(); return false;
652 }
653}
654
655void State::setLineWidth(GLfloat width)
656{
657 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400658 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400659}
660
Geoff Lang4b3f4162015-04-16 13:22:05 -0400661float State::getLineWidth() const
662{
663 return mLineWidth;
664}
665
Shannon Woods53a94a82014-06-24 15:20:36 -0400666void State::setGenerateMipmapHint(GLenum hint)
667{
668 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400669 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400670}
671
672void State::setFragmentShaderDerivativeHint(GLenum hint)
673{
674 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400675 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400676 // TODO: Propagate the hint to shader translator so we can write
677 // ddx, ddx_coarse, or ddx_fine depending on the hint.
678 // Ignore for now. It is valid for implementations to ignore hint.
679}
680
681void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
682{
683 mViewport.x = x;
684 mViewport.y = y;
685 mViewport.width = width;
686 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400687 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400688}
689
690const Rectangle &State::getViewport() const
691{
692 return mViewport;
693}
694
695void State::setActiveSampler(unsigned int active)
696{
697 mActiveSampler = active;
698}
699
700unsigned int State::getActiveSampler() const
701{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700702 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400703}
704
Geoff Lang76b10c92014-09-05 16:28:14 -0400705void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400706{
Geoff Lang76b10c92014-09-05 16:28:14 -0400707 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400708}
709
Jamie Madillc29968b2016-01-20 11:17:23 -0500710Texture *State::getTargetTexture(GLenum target) const
711{
712 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
713}
714
Geoff Lang76b10c92014-09-05 16:28:14 -0400715Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400716{
Jamie Madill5864ac22015-01-12 14:43:07 -0500717 const auto it = mSamplerTextures.find(type);
718 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400719 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500720 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400721}
722
Geoff Lang76b10c92014-09-05 16:28:14 -0400723GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400724{
Jamie Madill5864ac22015-01-12 14:43:07 -0500725 const auto it = mSamplerTextures.find(type);
726 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400727 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500728 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400729}
730
Jamie Madille6382c32014-11-07 15:05:26 -0500731void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400732{
733 // Textures have a detach method on State rather than a simple
734 // removeBinding, because the zero/null texture objects are managed
735 // separately, and don't have to go through the Context's maps or
736 // the ResourceManager.
737
738 // [OpenGL ES 2.0.24] section 3.8 page 84:
739 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
740 // rebound to texture object zero
741
Corentin Walleza2257da2016-04-19 16:43:12 -0400742 for (auto &bindingVec : mSamplerTextures)
Shannon Woods53a94a82014-06-24 15:20:36 -0400743 {
Corentin Walleza2257da2016-04-19 16:43:12 -0400744 GLenum textureType = bindingVec.first;
745 TextureBindingVector &textureVector = bindingVec.second;
Geoff Lang76b10c92014-09-05 16:28:14 -0400746 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400747 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400748 BindingPointer<Texture> &binding = textureVector[textureIdx];
749 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400750 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500751 auto it = zeroTextures.find(textureType);
752 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500753 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500754 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400755 }
756 }
757 }
758
759 // [OpenGL ES 2.0.24] section 4.4 page 112:
760 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
761 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
762 // image was attached in the currently bound framebuffer.
763
764 if (mReadFramebuffer)
765 {
766 mReadFramebuffer->detachTexture(texture);
767 }
768
769 if (mDrawFramebuffer)
770 {
771 mDrawFramebuffer->detachTexture(texture);
772 }
773}
774
Jamie Madille6382c32014-11-07 15:05:26 -0500775void State::initializeZeroTextures(const TextureMap &zeroTextures)
776{
777 for (const auto &zeroTexture : zeroTextures)
778 {
779 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
780
781 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
782 {
783 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
784 }
785 }
786}
787
Shannon Woods53a94a82014-06-24 15:20:36 -0400788void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
789{
790 mSamplers[textureUnit].set(sampler);
791}
792
793GLuint State::getSamplerId(GLuint textureUnit) const
794{
Geoff Lang76b10c92014-09-05 16:28:14 -0400795 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400796 return mSamplers[textureUnit].id();
797}
798
799Sampler *State::getSampler(GLuint textureUnit) const
800{
801 return mSamplers[textureUnit].get();
802}
803
804void State::detachSampler(GLuint sampler)
805{
806 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
807 // If a sampler object that is currently bound to one or more texture units is
808 // deleted, it is as though BindSampler is called once for each texture unit to
809 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400810 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400811 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400812 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
813 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400814 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400815 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400816 }
817 }
818}
819
820void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
821{
822 mRenderbuffer.set(renderbuffer);
823}
824
825GLuint State::getRenderbufferId() const
826{
827 return mRenderbuffer.id();
828}
829
Jamie Madilldfde6ab2016-06-09 07:07:18 -0700830Renderbuffer *State::getCurrentRenderbuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400831{
832 return mRenderbuffer.get();
833}
834
835void State::detachRenderbuffer(GLuint renderbuffer)
836{
837 // [OpenGL ES 2.0.24] section 4.4 page 109:
838 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
839 // had been executed with the target RENDERBUFFER and name of zero.
840
841 if (mRenderbuffer.id() == renderbuffer)
842 {
843 mRenderbuffer.set(NULL);
844 }
845
846 // [OpenGL ES 2.0.24] section 4.4 page 111:
847 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
848 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
849 // point to which this image was attached in the currently bound framebuffer.
850
851 Framebuffer *readFramebuffer = mReadFramebuffer;
852 Framebuffer *drawFramebuffer = mDrawFramebuffer;
853
854 if (readFramebuffer)
855 {
856 readFramebuffer->detachRenderbuffer(renderbuffer);
857 }
858
859 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
860 {
861 drawFramebuffer->detachRenderbuffer(renderbuffer);
862 }
863
864}
865
866void State::setReadFramebufferBinding(Framebuffer *framebuffer)
867{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500868 if (mReadFramebuffer == framebuffer)
869 return;
870
Shannon Woods53a94a82014-06-24 15:20:36 -0400871 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500872 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
873
874 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
875 {
876 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
877 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400878}
879
880void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
881{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500882 if (mDrawFramebuffer == framebuffer)
883 return;
884
Shannon Woods53a94a82014-06-24 15:20:36 -0400885 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500886 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
887
888 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
889 {
890 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
891 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400892}
893
894Framebuffer *State::getTargetFramebuffer(GLenum target) const
895{
896 switch (target)
897 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500898 case GL_READ_FRAMEBUFFER_ANGLE:
899 return mReadFramebuffer;
900 case GL_DRAW_FRAMEBUFFER_ANGLE:
901 case GL_FRAMEBUFFER:
902 return mDrawFramebuffer;
903 default:
904 UNREACHABLE();
905 return NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400906 }
907}
908
Jamie Madill51f40ec2016-06-15 14:06:00 -0400909Framebuffer *State::getReadFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400910{
911 return mReadFramebuffer;
912}
913
Jamie Madill51f40ec2016-06-15 14:06:00 -0400914Framebuffer *State::getDrawFramebuffer() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400915{
916 return mDrawFramebuffer;
917}
918
919bool State::removeReadFramebufferBinding(GLuint framebuffer)
920{
Jamie Madill77a72f62015-04-14 11:18:32 -0400921 if (mReadFramebuffer != nullptr &&
922 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400923 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500924 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400925 return true;
926 }
927
928 return false;
929}
930
931bool State::removeDrawFramebufferBinding(GLuint framebuffer)
932{
Jamie Madill77a72f62015-04-14 11:18:32 -0400933 if (mReadFramebuffer != nullptr &&
934 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400935 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500936 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400937 return true;
938 }
939
940 return false;
941}
942
943void State::setVertexArrayBinding(VertexArray *vertexArray)
944{
945 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000946 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500947
948 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
949 {
950 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
951 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400952}
953
954GLuint State::getVertexArrayId() const
955{
956 ASSERT(mVertexArray != NULL);
957 return mVertexArray->id();
958}
959
960VertexArray *State::getVertexArray() const
961{
962 ASSERT(mVertexArray != NULL);
963 return mVertexArray;
964}
965
966bool State::removeVertexArrayBinding(GLuint vertexArray)
967{
968 if (mVertexArray->id() == vertexArray)
969 {
970 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000971 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500972 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -0400973 return true;
974 }
975
976 return false;
977}
978
Geoff Lang7dd2e102014-11-10 15:19:26 -0500979void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400980{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500981 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400982 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500983 if (mProgram)
984 {
985 mProgram->release();
986 }
987
988 mProgram = newProgram;
989
990 if (mProgram)
991 {
992 newProgram->addRef();
993 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400994 }
995}
996
Geoff Lang7dd2e102014-11-10 15:19:26 -0500997Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400998{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500999 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -04001000}
1001
1002void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
1003{
1004 mTransformFeedback.set(transformFeedback);
1005}
1006
1007TransformFeedback *State::getCurrentTransformFeedback() const
1008{
1009 return mTransformFeedback.get();
1010}
1011
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001012bool State::isTransformFeedbackActiveUnpaused() const
1013{
1014 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001015 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +00001016}
1017
Corentin Walleza2257da2016-04-19 16:43:12 -04001018bool State::removeTransformFeedbackBinding(GLuint transformFeedback)
Shannon Woods53a94a82014-06-24 15:20:36 -04001019{
1020 if (mTransformFeedback.id() == transformFeedback)
1021 {
Corentin Walleza2257da2016-04-19 16:43:12 -04001022 mTransformFeedback.set(nullptr);
1023 return true;
Shannon Woods53a94a82014-06-24 15:20:36 -04001024 }
Corentin Walleza2257da2016-04-19 16:43:12 -04001025
1026 return false;
Shannon Woods53a94a82014-06-24 15:20:36 -04001027}
1028
Corentin Walleze71ea192016-04-19 13:16:37 -04001029bool State::isQueryActive(GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001030{
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001031 for (auto &iter : mActiveQueries)
Shannon Woods53a94a82014-06-24 15:20:36 -04001032 {
Corentin Walleze71ea192016-04-19 13:16:37 -04001033 Query *query = iter.second.get();
1034 if (query != nullptr && query->getType() == type)
Ian Ewell3ffd78b2016-01-22 16:09:42 -05001035 {
1036 return true;
1037 }
1038 }
1039
1040 return false;
1041}
1042
1043bool State::isQueryActive(Query *query) const
1044{
1045 for (auto &iter : mActiveQueries)
1046 {
1047 if (iter.second.get() == query)
Shannon Woods53a94a82014-06-24 15:20:36 -04001048 {
1049 return true;
1050 }
1051 }
1052
1053 return false;
1054}
1055
1056void State::setActiveQuery(GLenum target, Query *query)
1057{
1058 mActiveQueries[target].set(query);
1059}
1060
1061GLuint State::getActiveQueryId(GLenum target) const
1062{
1063 const Query *query = getActiveQuery(target);
1064 return (query ? query->id() : 0u);
1065}
1066
1067Query *State::getActiveQuery(GLenum target) const
1068{
Jamie Madill5864ac22015-01-12 14:43:07 -05001069 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001070
Jamie Madill5864ac22015-01-12 14:43:07 -05001071 // All query types should already exist in the activeQueries map
1072 ASSERT(it != mActiveQueries.end());
1073
1074 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001075}
1076
1077void State::setArrayBufferBinding(Buffer *buffer)
1078{
1079 mArrayBuffer.set(buffer);
1080}
1081
1082GLuint State::getArrayBufferId() const
1083{
1084 return mArrayBuffer.id();
1085}
1086
Shannon Woods53a94a82014-06-24 15:20:36 -04001087void State::setGenericUniformBufferBinding(Buffer *buffer)
1088{
1089 mGenericUniformBuffer.set(buffer);
1090}
1091
1092void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1093{
1094 mUniformBuffers[index].set(buffer, offset, size);
1095}
1096
Geoff Lang5d124a62015-09-15 13:03:27 -04001097const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001098{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001099 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001100 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001101}
1102
Shannon Woods53a94a82014-06-24 15:20:36 -04001103void State::setCopyReadBufferBinding(Buffer *buffer)
1104{
1105 mCopyReadBuffer.set(buffer);
1106}
1107
1108void State::setCopyWriteBufferBinding(Buffer *buffer)
1109{
1110 mCopyWriteBuffer.set(buffer);
1111}
1112
1113void State::setPixelPackBufferBinding(Buffer *buffer)
1114{
1115 mPack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001116 mDirtyBits.set(DIRTY_BIT_PACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001117}
1118
1119void State::setPixelUnpackBufferBinding(Buffer *buffer)
1120{
1121 mUnpack.pixelBuffer.set(buffer);
Corentin Wallezbbd663a2016-04-20 17:49:17 -04001122 mDirtyBits.set(DIRTY_BIT_UNPACK_BUFFER_BINDING);
Shannon Woods53a94a82014-06-24 15:20:36 -04001123}
1124
1125Buffer *State::getTargetBuffer(GLenum target) const
1126{
1127 switch (target)
1128 {
1129 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1130 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1131 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001132 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001133 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1134 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001135 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001136 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1137 default: UNREACHABLE(); return NULL;
1138 }
1139}
1140
Yuly Novikov5807a532015-12-03 13:01:22 -05001141void State::detachBuffer(GLuint bufferName)
1142{
1143 BindingPointer<Buffer> *buffers[] = {&mArrayBuffer, &mCopyReadBuffer,
1144 &mCopyWriteBuffer, &mPack.pixelBuffer,
1145 &mUnpack.pixelBuffer, &mGenericUniformBuffer};
1146 for (auto buffer : buffers)
1147 {
1148 if (buffer->id() == bufferName)
1149 {
1150 buffer->set(nullptr);
1151 }
1152 }
1153
1154 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1155 if (curTransformFeedback)
1156 {
1157 curTransformFeedback->detachBuffer(bufferName);
1158 }
1159
1160 getVertexArray()->detachBuffer(bufferName);
1161}
1162
Shannon Woods53a94a82014-06-24 15:20:36 -04001163void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1164{
1165 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001166 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001167}
1168
1169void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1170{
Shannon Woods23e05002014-09-22 19:07:27 -04001171 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001172 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001173 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001174}
1175
1176void State::setVertexAttribu(GLuint index, const GLuint values[4])
1177{
Shannon Woods23e05002014-09-22 19:07:27 -04001178 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001179 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001180 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001181}
1182
1183void State::setVertexAttribi(GLuint index, const GLint values[4])
1184{
Shannon Woods23e05002014-09-22 19:07:27 -04001185 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001186 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001187 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001188}
1189
Jamie Madill0b9e9032015-08-17 11:51:52 +00001190void State::setVertexAttribState(unsigned int attribNum,
1191 Buffer *boundBuffer,
1192 GLint size,
1193 GLenum type,
1194 bool normalized,
1195 bool pureInteger,
1196 GLsizei stride,
1197 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001198{
1199 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001200 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001201}
1202
1203void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1204{
1205 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001206 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001207}
1208
Shannon Woods53a94a82014-06-24 15:20:36 -04001209const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1210{
Shannon Woods23e05002014-09-22 19:07:27 -04001211 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001212 return mVertexAttribCurrentValues[attribNum];
1213}
1214
Shannon Woods53a94a82014-06-24 15:20:36 -04001215const void *State::getVertexAttribPointer(unsigned int attribNum) const
1216{
1217 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1218}
1219
1220void State::setPackAlignment(GLint alignment)
1221{
1222 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001223 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001224}
1225
1226GLint State::getPackAlignment() const
1227{
1228 return mPack.alignment;
1229}
1230
1231void State::setPackReverseRowOrder(bool reverseRowOrder)
1232{
1233 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001234 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001235}
1236
1237bool State::getPackReverseRowOrder() const
1238{
1239 return mPack.reverseRowOrder;
1240}
1241
Minmin Gongadff67b2015-10-14 10:34:45 -04001242void State::setPackRowLength(GLint rowLength)
1243{
1244 mPack.rowLength = rowLength;
1245 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1246}
1247
1248GLint State::getPackRowLength() const
1249{
1250 return mPack.rowLength;
1251}
1252
1253void State::setPackSkipRows(GLint skipRows)
1254{
1255 mPack.skipRows = skipRows;
1256 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1257}
1258
1259GLint State::getPackSkipRows() const
1260{
1261 return mPack.skipRows;
1262}
1263
1264void State::setPackSkipPixels(GLint skipPixels)
1265{
1266 mPack.skipPixels = skipPixels;
1267 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1268}
1269
1270GLint State::getPackSkipPixels() const
1271{
1272 return mPack.skipPixels;
1273}
1274
Shannon Woods53a94a82014-06-24 15:20:36 -04001275const PixelPackState &State::getPackState() const
1276{
1277 return mPack;
1278}
1279
Jamie Madill87de3622015-03-16 10:41:44 -04001280PixelPackState &State::getPackState()
1281{
1282 return mPack;
1283}
1284
Shannon Woods53a94a82014-06-24 15:20:36 -04001285void State::setUnpackAlignment(GLint alignment)
1286{
1287 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001288 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001289}
1290
1291GLint State::getUnpackAlignment() const
1292{
1293 return mUnpack.alignment;
1294}
1295
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001296void State::setUnpackRowLength(GLint rowLength)
1297{
1298 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001299 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001300}
1301
1302GLint State::getUnpackRowLength() const
1303{
1304 return mUnpack.rowLength;
1305}
1306
Minmin Gongadff67b2015-10-14 10:34:45 -04001307void State::setUnpackImageHeight(GLint imageHeight)
1308{
1309 mUnpack.imageHeight = imageHeight;
1310 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1311}
1312
1313GLint State::getUnpackImageHeight() const
1314{
1315 return mUnpack.imageHeight;
1316}
1317
1318void State::setUnpackSkipImages(GLint skipImages)
1319{
1320 mUnpack.skipImages = skipImages;
1321 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1322}
1323
1324GLint State::getUnpackSkipImages() const
1325{
1326 return mUnpack.skipImages;
1327}
1328
1329void State::setUnpackSkipRows(GLint skipRows)
1330{
1331 mUnpack.skipRows = skipRows;
1332 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1333}
1334
1335GLint State::getUnpackSkipRows() const
1336{
1337 return mUnpack.skipRows;
1338}
1339
1340void State::setUnpackSkipPixels(GLint skipPixels)
1341{
1342 mUnpack.skipPixels = skipPixels;
1343 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1344}
1345
1346GLint State::getUnpackSkipPixels() const
1347{
1348 return mUnpack.skipPixels;
1349}
1350
Shannon Woods53a94a82014-06-24 15:20:36 -04001351const PixelUnpackState &State::getUnpackState() const
1352{
1353 return mUnpack;
1354}
1355
Jamie Madill67102f02015-03-16 10:41:42 -04001356PixelUnpackState &State::getUnpackState()
1357{
1358 return mUnpack;
1359}
1360
Geoff Lang70d0f492015-12-10 17:45:46 -05001361const Debug &State::getDebug() const
1362{
1363 return mDebug;
1364}
1365
1366Debug &State::getDebug()
1367{
1368 return mDebug;
1369}
1370
Sami Väisänena797e062016-05-12 15:23:40 +03001371void State::setCoverageModulation(GLenum components)
1372{
1373 mCoverageModulation = components;
1374 mDirtyBits.set(DIRTY_BIT_COVERAGE_MODULATION);
1375}
1376
1377GLenum State::getCoverageModulation() const
1378{
1379 return mCoverageModulation;
1380}
1381
Sami Väisänene45e53b2016-05-25 10:36:04 +03001382void State::loadPathRenderingMatrix(GLenum matrixMode, const GLfloat *matrix)
1383{
1384 if (matrixMode == GL_PATH_MODELVIEW_CHROMIUM)
1385 {
1386 memcpy(mPathMatrixMV, matrix, 16 * sizeof(GLfloat));
1387 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_MV);
1388 }
1389 else if (matrixMode == GL_PATH_PROJECTION_CHROMIUM)
1390 {
1391 memcpy(mPathMatrixProj, matrix, 16 * sizeof(GLfloat));
1392 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_MATRIX_PROJ);
1393 }
1394 else
1395 {
1396 UNREACHABLE();
1397 }
1398}
1399
1400const GLfloat *State::getPathRenderingMatrix(GLenum which) const
1401{
1402 if (which == GL_PATH_MODELVIEW_MATRIX_CHROMIUM)
1403 {
1404 return mPathMatrixMV;
1405 }
1406 else if (which == GL_PATH_PROJECTION_MATRIX_CHROMIUM)
1407 {
1408 return mPathMatrixProj;
1409 }
1410
1411 UNREACHABLE();
1412 return nullptr;
1413}
1414
1415void State::setPathStencilFunc(GLenum func, GLint ref, GLuint mask)
1416{
1417 mPathStencilFunc = func;
1418 mPathStencilRef = ref;
1419 mPathStencilMask = mask;
1420 mDirtyBits.set(DIRTY_BIT_PATH_RENDERING_STENCIL_STATE);
1421}
1422
1423GLenum State::getPathStencilFunc() const
1424{
1425 return mPathStencilFunc;
1426}
1427
1428GLint State::getPathStencilRef() const
1429{
1430 return mPathStencilRef;
1431}
1432
1433GLuint State::getPathStencilMask() const
1434{
1435 return mPathStencilMask;
1436}
1437
Shannon Woods53a94a82014-06-24 15:20:36 -04001438void State::getBooleanv(GLenum pname, GLboolean *params)
1439{
1440 switch (pname)
1441 {
1442 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1443 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1444 case GL_COLOR_WRITEMASK:
1445 params[0] = mBlend.colorMaskRed;
1446 params[1] = mBlend.colorMaskGreen;
1447 params[2] = mBlend.colorMaskBlue;
1448 params[3] = mBlend.colorMaskAlpha;
1449 break;
1450 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1451 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1452 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1453 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1454 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1455 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1456 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1457 case GL_BLEND: *params = mBlend.blend; break;
1458 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001459 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1460 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001461 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1462 *params = mPrimitiveRestart;
1463 break;
Geoff Langab831f02015-12-01 09:39:10 -05001464 case GL_RASTERIZER_DISCARD:
1465 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1466 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001467 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1468 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1469 break;
1470 case GL_DEBUG_OUTPUT:
1471 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1472 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001473 case GL_MULTISAMPLE_EXT:
1474 *params = mMultiSampling;
1475 break;
1476 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1477 *params = mSampleAlphaToOne;
1478 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001479 default:
1480 UNREACHABLE();
1481 break;
1482 }
1483}
1484
1485void State::getFloatv(GLenum pname, GLfloat *params)
1486{
1487 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1488 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1489 // GetIntegerv as its native query function. As it would require conversion in any
1490 // case, this should make no difference to the calling application.
1491 switch (pname)
1492 {
1493 case GL_LINE_WIDTH: *params = mLineWidth; break;
1494 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1495 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1496 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1497 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1498 case GL_DEPTH_RANGE:
1499 params[0] = mNearZ;
1500 params[1] = mFarZ;
1501 break;
1502 case GL_COLOR_CLEAR_VALUE:
1503 params[0] = mColorClearValue.red;
1504 params[1] = mColorClearValue.green;
1505 params[2] = mColorClearValue.blue;
1506 params[3] = mColorClearValue.alpha;
1507 break;
1508 case GL_BLEND_COLOR:
1509 params[0] = mBlendColor.red;
1510 params[1] = mBlendColor.green;
1511 params[2] = mBlendColor.blue;
1512 params[3] = mBlendColor.alpha;
1513 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001514 case GL_MULTISAMPLE_EXT:
1515 *params = static_cast<GLfloat>(mMultiSampling);
1516 break;
1517 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1518 *params = static_cast<GLfloat>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001519 case GL_COVERAGE_MODULATION_CHROMIUM:
Jamie Madille2e406c2016-06-02 13:04:10 -04001520 params[0] = static_cast<GLfloat>(mCoverageModulation);
1521 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001522 default:
1523 UNREACHABLE();
1524 break;
1525 }
1526}
1527
Jamie Madill9082b982016-04-27 15:21:51 -04001528void State::getIntegerv(const ContextState &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001529{
1530 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1531 {
1532 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001533 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001534 Framebuffer *framebuffer = mDrawFramebuffer;
1535 *params = framebuffer->getDrawBufferState(colorAttachment);
1536 return;
1537 }
1538
1539 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1540 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1541 // GetIntegerv as its native query function. As it would require conversion in any
1542 // case, this should make no difference to the calling application. You may find it in
1543 // State::getFloatv.
1544 switch (pname)
1545 {
1546 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001547 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001548 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1549 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1550 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1551 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1552 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001553 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001554 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1555 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001556 case GL_PACK_ROW_LENGTH:
1557 *params = mPack.rowLength;
1558 break;
1559 case GL_PACK_SKIP_ROWS:
1560 *params = mPack.skipRows;
1561 break;
1562 case GL_PACK_SKIP_PIXELS:
1563 *params = mPack.skipPixels;
1564 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001565 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001566 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001567 case GL_UNPACK_IMAGE_HEIGHT:
1568 *params = mUnpack.imageHeight;
1569 break;
1570 case GL_UNPACK_SKIP_IMAGES:
1571 *params = mUnpack.skipImages;
1572 break;
1573 case GL_UNPACK_SKIP_ROWS:
1574 *params = mUnpack.skipRows;
1575 break;
1576 case GL_UNPACK_SKIP_PIXELS:
1577 *params = mUnpack.skipPixels;
1578 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001579 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1580 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001581 case GL_ACTIVE_TEXTURE:
1582 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1583 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001584 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1585 case GL_STENCIL_REF: *params = mStencilRef; break;
1586 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1587 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1588 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1589 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1590 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1591 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1592 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1593 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1594 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1595 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1596 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1597 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1598 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1599 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1600 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1601 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1602 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1603 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1604 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1605 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001606 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1607 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001608 case GL_SAMPLE_BUFFERS:
1609 case GL_SAMPLES:
1610 {
1611 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001612 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001613 {
1614 switch (pname)
1615 {
1616 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001617 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001618 {
1619 *params = 1;
1620 }
1621 else
1622 {
1623 *params = 0;
1624 }
1625 break;
1626 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001627 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001628 break;
1629 }
1630 }
1631 else
1632 {
1633 *params = 0;
1634 }
1635 }
1636 break;
1637 case GL_VIEWPORT:
1638 params[0] = mViewport.x;
1639 params[1] = mViewport.y;
1640 params[2] = mViewport.width;
1641 params[3] = mViewport.height;
1642 break;
1643 case GL_SCISSOR_BOX:
1644 params[0] = mScissor.x;
1645 params[1] = mScissor.y;
1646 params[2] = mScissor.width;
1647 params[3] = mScissor.height;
1648 break;
1649 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1650 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1651 case GL_RED_BITS:
1652 case GL_GREEN_BITS:
1653 case GL_BLUE_BITS:
1654 case GL_ALPHA_BITS:
1655 {
1656 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001657 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001658
1659 if (colorbuffer)
1660 {
1661 switch (pname)
1662 {
1663 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1664 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1665 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1666 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1667 }
1668 }
1669 else
1670 {
1671 *params = 0;
1672 }
1673 }
1674 break;
1675 case GL_DEPTH_BITS:
1676 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001677 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1678 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001679
1680 if (depthbuffer)
1681 {
1682 *params = depthbuffer->getDepthSize();
1683 }
1684 else
1685 {
1686 *params = 0;
1687 }
1688 }
1689 break;
1690 case GL_STENCIL_BITS:
1691 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001692 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1693 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001694
1695 if (stencilbuffer)
1696 {
1697 *params = stencilbuffer->getStencilSize();
1698 }
1699 else
1700 {
1701 *params = 0;
1702 }
1703 }
1704 break;
1705 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001706 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001707 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001708 break;
1709 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001710 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001711 *params =
1712 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001713 break;
1714 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001715 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001716 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001717 break;
1718 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001719 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001720 *params =
1721 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001722 break;
1723 case GL_UNIFORM_BUFFER_BINDING:
1724 *params = mGenericUniformBuffer.id();
1725 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001726 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001727 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001728 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001729 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001730 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001731 break;
1732 case GL_COPY_READ_BUFFER_BINDING:
1733 *params = mCopyReadBuffer.id();
1734 break;
1735 case GL_COPY_WRITE_BUFFER_BINDING:
1736 *params = mCopyWriteBuffer.id();
1737 break;
1738 case GL_PIXEL_PACK_BUFFER_BINDING:
1739 *params = mPack.pixelBuffer.id();
1740 break;
1741 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1742 *params = mUnpack.pixelBuffer.id();
1743 break;
Olli Etuaho86821db2016-03-04 12:05:47 +02001744 case GL_READ_BUFFER:
1745 *params = mReadFramebuffer->getReadBufferState();
1746 break;
1747 case GL_SAMPLER_BINDING:
1748 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
1749 *params = getSamplerId(static_cast<GLuint>(mActiveSampler));
1750 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001751 case GL_DEBUG_LOGGED_MESSAGES:
1752 *params = static_cast<GLint>(mDebug.getMessageCount());
1753 break;
1754 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1755 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1756 break;
1757 case GL_DEBUG_GROUP_STACK_DEPTH:
1758 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1759 break;
Sami Väisänen74c23472016-05-09 17:30:30 +03001760 case GL_MULTISAMPLE_EXT:
1761 *params = static_cast<GLint>(mMultiSampling);
1762 break;
1763 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
1764 *params = static_cast<GLint>(mSampleAlphaToOne);
Sami Väisänena797e062016-05-12 15:23:40 +03001765 case GL_COVERAGE_MODULATION_CHROMIUM:
1766 *params = static_cast<GLint>(mCoverageModulation);
Sami Väisänen74c23472016-05-09 17:30:30 +03001767 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001768 default:
1769 UNREACHABLE();
1770 break;
1771 }
1772}
1773
Geoff Lang70d0f492015-12-10 17:45:46 -05001774void State::getPointerv(GLenum pname, void **params) const
1775{
1776 switch (pname)
1777 {
1778 case GL_DEBUG_CALLBACK_FUNCTION:
1779 *params = reinterpret_cast<void *>(mDebug.getCallback());
1780 break;
1781 case GL_DEBUG_CALLBACK_USER_PARAM:
1782 *params = const_cast<void *>(mDebug.getUserParam());
1783 break;
1784 default:
1785 UNREACHABLE();
1786 break;
1787 }
1788}
1789
Shannon Woods53a94a82014-06-24 15:20:36 -04001790bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1791{
1792 switch (target)
1793 {
1794 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001795 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001796 {
Geoff Lang045536b2015-03-27 15:17:18 -04001797 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001798 }
1799 break;
1800 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001801 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001802 {
1803 *data = mUniformBuffers[index].id();
1804 }
1805 break;
1806 default:
1807 return false;
1808 }
1809
1810 return true;
1811}
1812
1813bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1814{
1815 switch (target)
1816 {
1817 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001818 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001819 {
Geoff Lang045536b2015-03-27 15:17:18 -04001820 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001821 }
1822 break;
1823 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001824 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001825 {
Geoff Lang045536b2015-03-27 15:17:18 -04001826 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001827 }
1828 break;
1829 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001830 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001831 {
1832 *data = mUniformBuffers[index].getOffset();
1833 }
1834 break;
1835 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001836 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001837 {
1838 *data = mUniformBuffers[index].getSize();
1839 }
1840 break;
1841 default:
1842 return false;
1843 }
1844
1845 return true;
1846}
1847
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001848bool State::hasMappedBuffer(GLenum target) const
1849{
1850 if (target == GL_ARRAY_BUFFER)
1851 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001852 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001853 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001854 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001855 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001856 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001857 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001858 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1859 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1860 {
1861 return true;
1862 }
1863 }
1864
1865 return false;
1866 }
1867 else
1868 {
1869 Buffer *buffer = getTargetBuffer(target);
1870 return (buffer && buffer->isMapped());
1871 }
1872}
1873
Jamie Madillc9d442d2016-01-20 11:17:24 -05001874void State::syncDirtyObjects()
1875{
1876 if (!mDirtyObjects.any())
1877 return;
1878
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001879 syncDirtyObjects(mDirtyObjects);
1880}
1881
1882void State::syncDirtyObjects(const DirtyObjects &bitset)
1883{
1884 for (auto dirtyObject : angle::IterateBitSet(bitset))
Jamie Madillc9d442d2016-01-20 11:17:24 -05001885 {
1886 switch (dirtyObject)
1887 {
1888 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001889 ASSERT(mReadFramebuffer);
1890 mReadFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001891 break;
1892 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001893 ASSERT(mDrawFramebuffer);
1894 mDrawFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001895 break;
1896 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001897 ASSERT(mVertexArray);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001898 mVertexArray->syncImplState();
1899 break;
1900 case DIRTY_OBJECT_PROGRAM:
1901 // TODO(jmadill): implement this
1902 break;
1903 default:
1904 UNREACHABLE();
1905 break;
1906 }
1907 }
1908
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001909 mDirtyObjects &= ~bitset;
1910}
1911
1912void State::syncDirtyObject(GLenum target)
1913{
1914 DirtyObjects localSet;
1915
1916 switch (target)
1917 {
1918 case GL_READ_FRAMEBUFFER:
1919 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1920 break;
1921 case GL_DRAW_FRAMEBUFFER:
1922 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1923 break;
1924 case GL_FRAMEBUFFER:
1925 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1926 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1927 break;
1928 case GL_VERTEX_ARRAY:
1929 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
1930 break;
1931 case GL_PROGRAM:
1932 localSet.set(DIRTY_OBJECT_PROGRAM);
1933 break;
1934 }
1935
1936 syncDirtyObjects(localSet);
1937}
1938
1939void State::setObjectDirty(GLenum target)
1940{
1941 switch (target)
1942 {
1943 case GL_READ_FRAMEBUFFER:
1944 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1945 break;
1946 case GL_DRAW_FRAMEBUFFER:
1947 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1948 break;
1949 case GL_FRAMEBUFFER:
1950 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1951 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1952 break;
1953 case GL_VERTEX_ARRAY:
1954 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1955 break;
1956 case GL_PROGRAM:
1957 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
1958 break;
1959 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001960}
Jamie Madillc9d442d2016-01-20 11:17:24 -05001961
1962} // namespace gl