blob: 7302a51822e0b858f16b6ce8f0414b7a244b94a3 [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
Jamie Madillc9d442d2016-01-20 11:17:24 -050011#include "common/BitSetIterator.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050012#include "libANGLE/Context.h"
13#include "libANGLE/Caps.h"
Geoff Lang70d0f492015-12-10 17:45:46 -050014#include "libANGLE/Debug.h"
Geoff Lang2b5420c2014-11-19 14:20:15 -050015#include "libANGLE/Framebuffer.h"
16#include "libANGLE/FramebufferAttachment.h"
17#include "libANGLE/Query.h"
18#include "libANGLE/VertexArray.h"
19#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040020
21namespace gl
22{
Geoff Lang76b10c92014-09-05 16:28:14 -040023
Shannon Woods53a94a82014-06-24 15:20:36 -040024State::State()
Jamie Madille79b1e12015-11-04 16:36:37 -050025 : mMaxDrawBuffers(0),
26 mMaxCombinedTextureImageUnits(0),
27 mDepthClearValue(0),
28 mStencilClearValue(0),
29 mScissorTest(false),
30 mSampleCoverage(false),
31 mSampleCoverageValue(0),
32 mSampleCoverageInvert(false),
33 mStencilRef(0),
34 mStencilBackRef(0),
35 mLineWidth(0),
36 mGenerateMipmapHint(GL_NONE),
37 mFragmentShaderDerivativeHint(GL_NONE),
38 mNearZ(0),
39 mFarZ(0),
40 mReadFramebuffer(nullptr),
41 mDrawFramebuffer(nullptr),
42 mProgram(nullptr),
43 mVertexArray(nullptr),
44 mActiveSampler(0),
45 mPrimitiveRestart(false)
Shannon Woods53a94a82014-06-24 15:20:36 -040046{
Jamie Madill1b94d432015-08-07 13:23:23 -040047 // Initialize dirty bit masks
48 // TODO(jmadill): additional ES3 state
49 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
50 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongadff67b2015-10-14 10:34:45 -040051 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
52 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
53 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
54 mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040055
Jamie Madill1b94d432015-08-07 13:23:23 -040056 mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
57 mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Minmin Gongadff67b2015-10-14 10:34:45 -040058 mPackStateBitMask.set(DIRTY_BIT_PACK_ROW_LENGTH);
59 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_ROWS);
60 mPackStateBitMask.set(DIRTY_BIT_PACK_SKIP_PIXELS);
Geoff Lang242468f2015-09-24 14:15:41 -040061
Jamie Madill1b94d432015-08-07 13:23:23 -040062 mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
63 mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
64 mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
65 mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
66 mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
67 mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
68 mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
69 mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
70 mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
71 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
72 mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Geoff Lang242468f2015-09-24 14:15:41 -040073
74 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
75 mBlitStateBitMask.set(DIRTY_BIT_SCISSOR);
Geoff Lang76b10c92014-09-05 16:28:14 -040076}
77
78State::~State()
79{
80 reset();
81}
82
Geoff Lang70d0f492015-12-10 17:45:46 -050083void State::initialize(const Caps &caps,
84 const Extensions &extensions,
85 GLuint clientVersion,
86 bool debug)
Geoff Lang76b10c92014-09-05 16:28:14 -040087{
Shannon Woods2df6a602014-09-26 16:12:07 -040088 mMaxDrawBuffers = caps.maxDrawBuffers;
89 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040090
Jamie Madillf75ab352015-03-16 10:46:52 -040091 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040092
93 mDepthClearValue = 1.0f;
94 mStencilClearValue = 0;
95
96 mRasterizer.rasterizerDiscard = false;
97 mRasterizer.cullFace = false;
98 mRasterizer.cullMode = GL_BACK;
99 mRasterizer.frontFace = GL_CCW;
100 mRasterizer.polygonOffsetFill = false;
101 mRasterizer.polygonOffsetFactor = 0.0f;
102 mRasterizer.polygonOffsetUnits = 0.0f;
103 mRasterizer.pointDrawMode = false;
104 mRasterizer.multiSample = false;
105 mScissorTest = false;
106 mScissor.x = 0;
107 mScissor.y = 0;
108 mScissor.width = 0;
109 mScissor.height = 0;
110
111 mBlend.blend = false;
112 mBlend.sourceBlendRGB = GL_ONE;
113 mBlend.sourceBlendAlpha = GL_ONE;
114 mBlend.destBlendRGB = GL_ZERO;
115 mBlend.destBlendAlpha = GL_ZERO;
116 mBlend.blendEquationRGB = GL_FUNC_ADD;
117 mBlend.blendEquationAlpha = GL_FUNC_ADD;
118 mBlend.sampleAlphaToCoverage = false;
119 mBlend.dither = true;
120
121 mBlendColor.red = 0;
122 mBlendColor.green = 0;
123 mBlendColor.blue = 0;
124 mBlendColor.alpha = 0;
125
126 mDepthStencil.depthTest = false;
127 mDepthStencil.depthFunc = GL_LESS;
128 mDepthStencil.depthMask = true;
129 mDepthStencil.stencilTest = false;
130 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700131 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
132 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400133 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -0700134 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
135 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -0400136 mDepthStencil.stencilFail = GL_KEEP;
137 mDepthStencil.stencilPassDepthFail = GL_KEEP;
138 mDepthStencil.stencilPassDepthPass = GL_KEEP;
139 mDepthStencil.stencilBackFail = GL_KEEP;
140 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
141 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
142
143 mStencilRef = 0;
144 mStencilBackRef = 0;
145
146 mSampleCoverage = false;
147 mSampleCoverageValue = 1.0f;
148 mSampleCoverageInvert = false;
149 mGenerateMipmapHint = GL_DONT_CARE;
150 mFragmentShaderDerivativeHint = GL_DONT_CARE;
151
152 mLineWidth = 1.0f;
153
154 mViewport.x = 0;
155 mViewport.y = 0;
156 mViewport.width = 0;
157 mViewport.height = 0;
158 mNearZ = 0.0f;
159 mFarZ = 1.0f;
160
161 mBlend.colorMaskRed = true;
162 mBlend.colorMaskGreen = true;
163 mBlend.colorMaskBlue = true;
164 mBlend.colorMaskAlpha = true;
165
Geoff Lang76b10c92014-09-05 16:28:14 -0400166 mActiveSampler = 0;
167
Shannon Woods23e05002014-09-22 19:07:27 -0400168 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
Shannon Woods53a94a82014-06-24 15:20:36 -0400169
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400170 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
171
Geoff Lang76b10c92014-09-05 16:28:14 -0400172 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
173 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
174 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400175 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400176 // TODO: These could also be enabled via extension
177 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
178 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400179 }
180
Geoff Lang76b10c92014-09-05 16:28:14 -0400181 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400182
183 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
184 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
185 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
186
Geoff Lang7dd2e102014-11-10 15:19:26 -0500187 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400188
189 mReadFramebuffer = NULL;
190 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500191
192 mPrimitiveRestart = false;
Geoff Lang70d0f492015-12-10 17:45:46 -0500193
194 mDebug.setOutputEnabled(debug);
195 mDebug.setMaxLoggedMessages(extensions.maxDebugLoggedMessages);
Shannon Woods53a94a82014-06-24 15:20:36 -0400196}
197
Geoff Lang76b10c92014-09-05 16:28:14 -0400198void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400199{
Geoff Lang76b10c92014-09-05 16:28:14 -0400200 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400201 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400202 TextureBindingVector &textureVector = bindingVec->second;
203 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400204 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400205 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400206 }
207 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400208 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
209 {
210 mSamplers[samplerIdx].set(NULL);
211 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400212
Shannon Woods53a94a82014-06-24 15:20:36 -0400213 mArrayBuffer.set(NULL);
214 mRenderbuffer.set(NULL);
215
Geoff Lang7dd2e102014-11-10 15:19:26 -0500216 if (mProgram)
217 {
218 mProgram->release();
219 }
220 mProgram = NULL;
221
Shannon Woods53a94a82014-06-24 15:20:36 -0400222 mTransformFeedback.set(NULL);
223
224 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
225 {
226 i->second.set(NULL);
227 }
228
229 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400230 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400231 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400232 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400233 }
234
Shannon Woods53a94a82014-06-24 15:20:36 -0400235 mCopyReadBuffer.set(NULL);
236 mCopyWriteBuffer.set(NULL);
237
238 mPack.pixelBuffer.set(NULL);
239 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500240
241 mProgram = NULL;
Jamie Madill1b94d432015-08-07 13:23:23 -0400242
243 // TODO(jmadill): Is this necessary?
244 setAllDirtyBits();
Shannon Woods53a94a82014-06-24 15:20:36 -0400245}
246
247const RasterizerState &State::getRasterizerState() const
248{
249 return mRasterizer;
250}
251
252const BlendState &State::getBlendState() const
253{
254 return mBlend;
255}
256
257const DepthStencilState &State::getDepthStencilState() const
258{
259 return mDepthStencil;
260}
261
Jamie Madillf75ab352015-03-16 10:46:52 -0400262void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400263{
264 mColorClearValue.red = red;
265 mColorClearValue.green = green;
266 mColorClearValue.blue = blue;
267 mColorClearValue.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400268 mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400269}
270
Jamie Madillf75ab352015-03-16 10:46:52 -0400271void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400272{
273 mDepthClearValue = depth;
Jamie Madill1b94d432015-08-07 13:23:23 -0400274 mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400275}
276
Jamie Madillf75ab352015-03-16 10:46:52 -0400277void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400278{
279 mStencilClearValue = stencil;
Jamie Madill1b94d432015-08-07 13:23:23 -0400280 mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400281}
282
Shannon Woods53a94a82014-06-24 15:20:36 -0400283void State::setColorMask(bool red, bool green, bool blue, bool alpha)
284{
285 mBlend.colorMaskRed = red;
286 mBlend.colorMaskGreen = green;
287 mBlend.colorMaskBlue = blue;
288 mBlend.colorMaskAlpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400289 mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400290}
291
292void State::setDepthMask(bool mask)
293{
294 mDepthStencil.depthMask = mask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400295 mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400296}
297
298bool State::isRasterizerDiscardEnabled() const
299{
300 return mRasterizer.rasterizerDiscard;
301}
302
303void State::setRasterizerDiscard(bool enabled)
304{
305 mRasterizer.rasterizerDiscard = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400306 mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400307}
308
309bool State::isCullFaceEnabled() const
310{
311 return mRasterizer.cullFace;
312}
313
314void State::setCullFace(bool enabled)
315{
316 mRasterizer.cullFace = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400317 mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400318}
319
320void State::setCullMode(GLenum mode)
321{
322 mRasterizer.cullMode = mode;
Jamie Madill1b94d432015-08-07 13:23:23 -0400323 mDirtyBits.set(DIRTY_BIT_CULL_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400324}
325
326void State::setFrontFace(GLenum front)
327{
328 mRasterizer.frontFace = front;
Jamie Madill1b94d432015-08-07 13:23:23 -0400329 mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400330}
331
332bool State::isDepthTestEnabled() const
333{
334 return mDepthStencil.depthTest;
335}
336
337void State::setDepthTest(bool enabled)
338{
339 mDepthStencil.depthTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400340 mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400341}
342
343void State::setDepthFunc(GLenum depthFunc)
344{
345 mDepthStencil.depthFunc = depthFunc;
Jamie Madill1b94d432015-08-07 13:23:23 -0400346 mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
Shannon Woods53a94a82014-06-24 15:20:36 -0400347}
348
349void State::setDepthRange(float zNear, float zFar)
350{
351 mNearZ = zNear;
352 mFarZ = zFar;
Jamie Madill1b94d432015-08-07 13:23:23 -0400353 mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400354}
355
Geoff Langd42f5b82015-04-16 14:03:29 -0400356float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400357{
Geoff Langd42f5b82015-04-16 14:03:29 -0400358 return mNearZ;
359}
360
361float State::getFarPlane() const
362{
363 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400364}
365
366bool State::isBlendEnabled() const
367{
368 return mBlend.blend;
369}
370
371void State::setBlend(bool enabled)
372{
373 mBlend.blend = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400374 mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400375}
376
377void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
378{
379 mBlend.sourceBlendRGB = sourceRGB;
380 mBlend.destBlendRGB = destRGB;
381 mBlend.sourceBlendAlpha = sourceAlpha;
382 mBlend.destBlendAlpha = destAlpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400383 mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400384}
385
386void State::setBlendColor(float red, float green, float blue, float alpha)
387{
388 mBlendColor.red = red;
389 mBlendColor.green = green;
390 mBlendColor.blue = blue;
391 mBlendColor.alpha = alpha;
Jamie Madill1b94d432015-08-07 13:23:23 -0400392 mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400393}
394
395void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
396{
397 mBlend.blendEquationRGB = rgbEquation;
398 mBlend.blendEquationAlpha = alphaEquation;
Jamie Madill1b94d432015-08-07 13:23:23 -0400399 mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
Shannon Woods53a94a82014-06-24 15:20:36 -0400400}
401
402const ColorF &State::getBlendColor() const
403{
404 return mBlendColor;
405}
406
407bool State::isStencilTestEnabled() const
408{
409 return mDepthStencil.stencilTest;
410}
411
412void State::setStencilTest(bool enabled)
413{
414 mDepthStencil.stencilTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400415 mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400416}
417
418void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
419{
420 mDepthStencil.stencilFunc = stencilFunc;
421 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
422 mDepthStencil.stencilMask = stencilMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400423 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400424}
425
426void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
427{
428 mDepthStencil.stencilBackFunc = stencilBackFunc;
429 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
430 mDepthStencil.stencilBackMask = stencilBackMask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400431 mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400432}
433
434void State::setStencilWritemask(GLuint stencilWritemask)
435{
436 mDepthStencil.stencilWritemask = stencilWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400437 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400438}
439
440void State::setStencilBackWritemask(GLuint stencilBackWritemask)
441{
442 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
Jamie Madill1b94d432015-08-07 13:23:23 -0400443 mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400444}
445
446void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
447{
448 mDepthStencil.stencilFail = stencilFail;
449 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
450 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400451 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400452}
453
454void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
455{
456 mDepthStencil.stencilBackFail = stencilBackFail;
457 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
458 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
Jamie Madill1b94d432015-08-07 13:23:23 -0400459 mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
Shannon Woods53a94a82014-06-24 15:20:36 -0400460}
461
462GLint State::getStencilRef() const
463{
464 return mStencilRef;
465}
466
467GLint State::getStencilBackRef() const
468{
469 return mStencilBackRef;
470}
471
472bool State::isPolygonOffsetFillEnabled() const
473{
474 return mRasterizer.polygonOffsetFill;
475}
476
477void State::setPolygonOffsetFill(bool enabled)
478{
Jamie Madill1b94d432015-08-07 13:23:23 -0400479 mRasterizer.polygonOffsetFill = enabled;
480 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400481}
482
483void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
484{
485 // An application can pass NaN values here, so handle this gracefully
486 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
487 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
Jamie Madill1b94d432015-08-07 13:23:23 -0400488 mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
Shannon Woods53a94a82014-06-24 15:20:36 -0400489}
490
491bool State::isSampleAlphaToCoverageEnabled() const
492{
493 return mBlend.sampleAlphaToCoverage;
494}
495
496void State::setSampleAlphaToCoverage(bool enabled)
497{
498 mBlend.sampleAlphaToCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400499 mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400500}
501
502bool State::isSampleCoverageEnabled() const
503{
504 return mSampleCoverage;
505}
506
507void State::setSampleCoverage(bool enabled)
508{
509 mSampleCoverage = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400510 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400511}
512
513void State::setSampleCoverageParams(GLclampf value, bool invert)
514{
515 mSampleCoverageValue = value;
516 mSampleCoverageInvert = invert;
Jamie Madill1b94d432015-08-07 13:23:23 -0400517 mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
Shannon Woods53a94a82014-06-24 15:20:36 -0400518}
519
Geoff Lang0fbb6002015-04-16 11:11:53 -0400520GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400521{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400522 return mSampleCoverageValue;
523}
Shannon Woods53a94a82014-06-24 15:20:36 -0400524
Geoff Lang0fbb6002015-04-16 11:11:53 -0400525bool State::getSampleCoverageInvert() const
526{
527 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400528}
529
530bool State::isScissorTestEnabled() const
531{
532 return mScissorTest;
533}
534
535void State::setScissorTest(bool enabled)
536{
537 mScissorTest = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400538 mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400539}
540
541void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
542{
543 mScissor.x = x;
544 mScissor.y = y;
545 mScissor.width = width;
546 mScissor.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400547 mDirtyBits.set(DIRTY_BIT_SCISSOR);
Shannon Woods53a94a82014-06-24 15:20:36 -0400548}
549
550const Rectangle &State::getScissor() const
551{
552 return mScissor;
553}
554
555bool State::isDitherEnabled() const
556{
557 return mBlend.dither;
558}
559
560void State::setDither(bool enabled)
561{
562 mBlend.dither = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400563 mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
Shannon Woods53a94a82014-06-24 15:20:36 -0400564}
565
Jamie Madillb4b53c52015-02-03 15:22:48 -0500566bool State::isPrimitiveRestartEnabled() const
567{
568 return mPrimitiveRestart;
569}
570
571void State::setPrimitiveRestart(bool enabled)
572{
573 mPrimitiveRestart = enabled;
Jamie Madill1b94d432015-08-07 13:23:23 -0400574 mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
Jamie Madillb4b53c52015-02-03 15:22:48 -0500575}
576
Shannon Woods53a94a82014-06-24 15:20:36 -0400577void State::setEnableFeature(GLenum feature, bool enabled)
578{
579 switch (feature)
580 {
581 case GL_CULL_FACE: setCullFace(enabled); break;
582 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
583 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
584 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
585 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
586 case GL_STENCIL_TEST: setStencilTest(enabled); break;
587 case GL_DEPTH_TEST: setDepthTest(enabled); break;
588 case GL_BLEND: setBlend(enabled); break;
589 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500590 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400591 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
Geoff Lang70d0f492015-12-10 17:45:46 -0500592 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
593 mDebug.setOutputSynchronous(enabled);
594 break;
595 case GL_DEBUG_OUTPUT:
596 mDebug.setOutputEnabled(enabled);
597 break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400598 default: UNREACHABLE();
599 }
600}
601
602bool State::getEnableFeature(GLenum feature)
603{
604 switch (feature)
605 {
606 case GL_CULL_FACE: return isCullFaceEnabled();
607 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
608 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
609 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
610 case GL_SCISSOR_TEST: return isScissorTestEnabled();
611 case GL_STENCIL_TEST: return isStencilTestEnabled();
612 case GL_DEPTH_TEST: return isDepthTestEnabled();
613 case GL_BLEND: return isBlendEnabled();
614 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500615 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400616 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
Geoff Lang70d0f492015-12-10 17:45:46 -0500617 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
618 return mDebug.isOutputSynchronous();
619 case GL_DEBUG_OUTPUT:
620 return mDebug.isOutputEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400621 default: UNREACHABLE(); return false;
622 }
623}
624
625void State::setLineWidth(GLfloat width)
626{
627 mLineWidth = width;
Jamie Madill1b94d432015-08-07 13:23:23 -0400628 mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
Shannon Woods53a94a82014-06-24 15:20:36 -0400629}
630
Geoff Lang4b3f4162015-04-16 13:22:05 -0400631float State::getLineWidth() const
632{
633 return mLineWidth;
634}
635
Shannon Woods53a94a82014-06-24 15:20:36 -0400636void State::setGenerateMipmapHint(GLenum hint)
637{
638 mGenerateMipmapHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400639 mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400640}
641
642void State::setFragmentShaderDerivativeHint(GLenum hint)
643{
644 mFragmentShaderDerivativeHint = hint;
Jamie Madill1b94d432015-08-07 13:23:23 -0400645 mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400646 // TODO: Propagate the hint to shader translator so we can write
647 // ddx, ddx_coarse, or ddx_fine depending on the hint.
648 // Ignore for now. It is valid for implementations to ignore hint.
649}
650
651void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
652{
653 mViewport.x = x;
654 mViewport.y = y;
655 mViewport.width = width;
656 mViewport.height = height;
Jamie Madill1b94d432015-08-07 13:23:23 -0400657 mDirtyBits.set(DIRTY_BIT_VIEWPORT);
Shannon Woods53a94a82014-06-24 15:20:36 -0400658}
659
660const Rectangle &State::getViewport() const
661{
662 return mViewport;
663}
664
665void State::setActiveSampler(unsigned int active)
666{
667 mActiveSampler = active;
668}
669
670unsigned int State::getActiveSampler() const
671{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700672 return static_cast<unsigned int>(mActiveSampler);
Shannon Woods53a94a82014-06-24 15:20:36 -0400673}
674
Geoff Lang76b10c92014-09-05 16:28:14 -0400675void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400676{
Geoff Lang76b10c92014-09-05 16:28:14 -0400677 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400678}
679
Jamie Madillc29968b2016-01-20 11:17:23 -0500680Texture *State::getTargetTexture(GLenum target) const
681{
682 return getSamplerTexture(static_cast<unsigned int>(mActiveSampler), target);
683}
684
Geoff Lang76b10c92014-09-05 16:28:14 -0400685Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400686{
Jamie Madill5864ac22015-01-12 14:43:07 -0500687 const auto it = mSamplerTextures.find(type);
688 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400689 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500690 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400691}
692
Geoff Lang76b10c92014-09-05 16:28:14 -0400693GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400694{
Jamie Madill5864ac22015-01-12 14:43:07 -0500695 const auto it = mSamplerTextures.find(type);
696 ASSERT(it != mSamplerTextures.end());
Jamie Madill3d3d2f22015-09-23 16:47:51 -0400697 ASSERT(sampler < it->second.size());
Jamie Madill5864ac22015-01-12 14:43:07 -0500698 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400699}
700
Jamie Madille6382c32014-11-07 15:05:26 -0500701void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400702{
703 // Textures have a detach method on State rather than a simple
704 // removeBinding, because the zero/null texture objects are managed
705 // separately, and don't have to go through the Context's maps or
706 // the ResourceManager.
707
708 // [OpenGL ES 2.0.24] section 3.8 page 84:
709 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
710 // rebound to texture object zero
711
Geoff Lang76b10c92014-09-05 16:28:14 -0400712 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400713 {
Jamie Madille6382c32014-11-07 15:05:26 -0500714 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400715 TextureBindingVector &textureVector = bindingVec->second;
716 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400717 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400718 BindingPointer<Texture> &binding = textureVector[textureIdx];
719 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400720 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500721 auto it = zeroTextures.find(textureType);
722 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500723 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500724 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400725 }
726 }
727 }
728
729 // [OpenGL ES 2.0.24] section 4.4 page 112:
730 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
731 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
732 // image was attached in the currently bound framebuffer.
733
734 if (mReadFramebuffer)
735 {
736 mReadFramebuffer->detachTexture(texture);
737 }
738
739 if (mDrawFramebuffer)
740 {
741 mDrawFramebuffer->detachTexture(texture);
742 }
743}
744
Jamie Madille6382c32014-11-07 15:05:26 -0500745void State::initializeZeroTextures(const TextureMap &zeroTextures)
746{
747 for (const auto &zeroTexture : zeroTextures)
748 {
749 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
750
751 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
752 {
753 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
754 }
755 }
756}
757
Shannon Woods53a94a82014-06-24 15:20:36 -0400758void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
759{
760 mSamplers[textureUnit].set(sampler);
761}
762
763GLuint State::getSamplerId(GLuint textureUnit) const
764{
Geoff Lang76b10c92014-09-05 16:28:14 -0400765 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400766 return mSamplers[textureUnit].id();
767}
768
769Sampler *State::getSampler(GLuint textureUnit) const
770{
771 return mSamplers[textureUnit].get();
772}
773
774void State::detachSampler(GLuint sampler)
775{
776 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
777 // If a sampler object that is currently bound to one or more texture units is
778 // deleted, it is as though BindSampler is called once for each texture unit to
779 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400780 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400781 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400782 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
783 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400784 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400785 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400786 }
787 }
788}
789
790void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
791{
792 mRenderbuffer.set(renderbuffer);
793}
794
795GLuint State::getRenderbufferId() const
796{
797 return mRenderbuffer.id();
798}
799
800Renderbuffer *State::getCurrentRenderbuffer()
801{
802 return mRenderbuffer.get();
803}
804
805void State::detachRenderbuffer(GLuint renderbuffer)
806{
807 // [OpenGL ES 2.0.24] section 4.4 page 109:
808 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
809 // had been executed with the target RENDERBUFFER and name of zero.
810
811 if (mRenderbuffer.id() == renderbuffer)
812 {
813 mRenderbuffer.set(NULL);
814 }
815
816 // [OpenGL ES 2.0.24] section 4.4 page 111:
817 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
818 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
819 // point to which this image was attached in the currently bound framebuffer.
820
821 Framebuffer *readFramebuffer = mReadFramebuffer;
822 Framebuffer *drawFramebuffer = mDrawFramebuffer;
823
824 if (readFramebuffer)
825 {
826 readFramebuffer->detachRenderbuffer(renderbuffer);
827 }
828
829 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
830 {
831 drawFramebuffer->detachRenderbuffer(renderbuffer);
832 }
833
834}
835
836void State::setReadFramebufferBinding(Framebuffer *framebuffer)
837{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500838 if (mReadFramebuffer == framebuffer)
839 return;
840
Shannon Woods53a94a82014-06-24 15:20:36 -0400841 mReadFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500842 mDirtyBits.set(DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
843
844 if (mReadFramebuffer && mReadFramebuffer->hasAnyDirtyBit())
845 {
846 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
847 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400848}
849
850void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
851{
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500852 if (mDrawFramebuffer == framebuffer)
853 return;
854
Shannon Woods53a94a82014-06-24 15:20:36 -0400855 mDrawFramebuffer = framebuffer;
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500856 mDirtyBits.set(DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
857
858 if (mDrawFramebuffer && mDrawFramebuffer->hasAnyDirtyBit())
859 {
860 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
861 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400862}
863
864Framebuffer *State::getTargetFramebuffer(GLenum target) const
865{
866 switch (target)
867 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500868 case GL_READ_FRAMEBUFFER_ANGLE:
869 return mReadFramebuffer;
870 case GL_DRAW_FRAMEBUFFER_ANGLE:
871 case GL_FRAMEBUFFER:
872 return mDrawFramebuffer;
873 default:
874 UNREACHABLE();
875 return NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400876 }
877}
878
879Framebuffer *State::getReadFramebuffer()
880{
881 return mReadFramebuffer;
882}
883
884Framebuffer *State::getDrawFramebuffer()
885{
886 return mDrawFramebuffer;
887}
888
889const Framebuffer *State::getReadFramebuffer() const
890{
891 return mReadFramebuffer;
892}
893
894const Framebuffer *State::getDrawFramebuffer() const
895{
896 return mDrawFramebuffer;
897}
898
899bool State::removeReadFramebufferBinding(GLuint framebuffer)
900{
Jamie Madill77a72f62015-04-14 11:18:32 -0400901 if (mReadFramebuffer != nullptr &&
902 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400903 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500904 setReadFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400905 return true;
906 }
907
908 return false;
909}
910
911bool State::removeDrawFramebufferBinding(GLuint framebuffer)
912{
Jamie Madill77a72f62015-04-14 11:18:32 -0400913 if (mReadFramebuffer != nullptr &&
914 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400915 {
Jamie Madill60ec6ea2016-01-22 15:27:19 -0500916 setDrawFramebufferBinding(nullptr);
Shannon Woods53a94a82014-06-24 15:20:36 -0400917 return true;
918 }
919
920 return false;
921}
922
923void State::setVertexArrayBinding(VertexArray *vertexArray)
924{
925 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000926 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500927
928 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
929 {
930 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
931 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400932}
933
934GLuint State::getVertexArrayId() const
935{
936 ASSERT(mVertexArray != NULL);
937 return mVertexArray->id();
938}
939
940VertexArray *State::getVertexArray() const
941{
942 ASSERT(mVertexArray != NULL);
943 return mVertexArray;
944}
945
946bool State::removeVertexArrayBinding(GLuint vertexArray)
947{
948 if (mVertexArray->id() == vertexArray)
949 {
950 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000951 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500952 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -0400953 return true;
954 }
955
956 return false;
957}
958
Geoff Lang7dd2e102014-11-10 15:19:26 -0500959void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400960{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500961 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400962 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500963 if (mProgram)
964 {
965 mProgram->release();
966 }
967
968 mProgram = newProgram;
969
970 if (mProgram)
971 {
972 newProgram->addRef();
973 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400974 }
975}
976
Geoff Lang7dd2e102014-11-10 15:19:26 -0500977Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400978{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500979 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400980}
981
982void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
983{
984 mTransformFeedback.set(transformFeedback);
985}
986
987TransformFeedback *State::getCurrentTransformFeedback() const
988{
989 return mTransformFeedback.get();
990}
991
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000992bool State::isTransformFeedbackActiveUnpaused() const
993{
994 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400995 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000996}
997
Shannon Woods53a94a82014-06-24 15:20:36 -0400998void State::detachTransformFeedback(GLuint transformFeedback)
999{
1000 if (mTransformFeedback.id() == transformFeedback)
1001 {
1002 mTransformFeedback.set(NULL);
1003 }
1004}
1005
1006bool State::isQueryActive() const
1007{
1008 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
1009 i != mActiveQueries.end(); i++)
1010 {
1011 if (i->second.get() != NULL)
1012 {
1013 return true;
1014 }
1015 }
1016
1017 return false;
1018}
1019
1020void State::setActiveQuery(GLenum target, Query *query)
1021{
1022 mActiveQueries[target].set(query);
1023}
1024
1025GLuint State::getActiveQueryId(GLenum target) const
1026{
1027 const Query *query = getActiveQuery(target);
1028 return (query ? query->id() : 0u);
1029}
1030
1031Query *State::getActiveQuery(GLenum target) const
1032{
Jamie Madill5864ac22015-01-12 14:43:07 -05001033 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001034
Jamie Madill5864ac22015-01-12 14:43:07 -05001035 // All query types should already exist in the activeQueries map
1036 ASSERT(it != mActiveQueries.end());
1037
1038 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001039}
1040
1041void State::setArrayBufferBinding(Buffer *buffer)
1042{
1043 mArrayBuffer.set(buffer);
1044}
1045
1046GLuint State::getArrayBufferId() const
1047{
1048 return mArrayBuffer.id();
1049}
1050
Shannon Woods53a94a82014-06-24 15:20:36 -04001051void State::setGenericUniformBufferBinding(Buffer *buffer)
1052{
1053 mGenericUniformBuffer.set(buffer);
1054}
1055
1056void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1057{
1058 mUniformBuffers[index].set(buffer, offset, size);
1059}
1060
Geoff Lang5d124a62015-09-15 13:03:27 -04001061const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001062{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001063 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001064 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001065}
1066
Shannon Woods53a94a82014-06-24 15:20:36 -04001067void State::setCopyReadBufferBinding(Buffer *buffer)
1068{
1069 mCopyReadBuffer.set(buffer);
1070}
1071
1072void State::setCopyWriteBufferBinding(Buffer *buffer)
1073{
1074 mCopyWriteBuffer.set(buffer);
1075}
1076
1077void State::setPixelPackBufferBinding(Buffer *buffer)
1078{
1079 mPack.pixelBuffer.set(buffer);
1080}
1081
1082void State::setPixelUnpackBufferBinding(Buffer *buffer)
1083{
1084 mUnpack.pixelBuffer.set(buffer);
1085}
1086
1087Buffer *State::getTargetBuffer(GLenum target) const
1088{
1089 switch (target)
1090 {
1091 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1092 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1093 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001094 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001095 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1096 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001097 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001098 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1099 default: UNREACHABLE(); return NULL;
1100 }
1101}
1102
Yuly Novikov5807a532015-12-03 13:01:22 -05001103void State::detachBuffer(GLuint bufferName)
1104{
1105 BindingPointer<Buffer> *buffers[] = {&mArrayBuffer, &mCopyReadBuffer,
1106 &mCopyWriteBuffer, &mPack.pixelBuffer,
1107 &mUnpack.pixelBuffer, &mGenericUniformBuffer};
1108 for (auto buffer : buffers)
1109 {
1110 if (buffer->id() == bufferName)
1111 {
1112 buffer->set(nullptr);
1113 }
1114 }
1115
1116 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1117 if (curTransformFeedback)
1118 {
1119 curTransformFeedback->detachBuffer(bufferName);
1120 }
1121
1122 getVertexArray()->detachBuffer(bufferName);
1123}
1124
Shannon Woods53a94a82014-06-24 15:20:36 -04001125void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1126{
1127 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001128 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001129}
1130
1131void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1132{
Shannon Woods23e05002014-09-22 19:07:27 -04001133 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001134 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001135 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001136}
1137
1138void State::setVertexAttribu(GLuint index, const GLuint values[4])
1139{
Shannon Woods23e05002014-09-22 19:07:27 -04001140 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001141 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001142 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001143}
1144
1145void State::setVertexAttribi(GLuint index, const GLint values[4])
1146{
Shannon Woods23e05002014-09-22 19:07:27 -04001147 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001148 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001149 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001150}
1151
Jamie Madill0b9e9032015-08-17 11:51:52 +00001152void State::setVertexAttribState(unsigned int attribNum,
1153 Buffer *boundBuffer,
1154 GLint size,
1155 GLenum type,
1156 bool normalized,
1157 bool pureInteger,
1158 GLsizei stride,
1159 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001160{
1161 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001162 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001163}
1164
1165void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1166{
1167 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001168 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001169}
1170
Shannon Woods53a94a82014-06-24 15:20:36 -04001171const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1172{
Shannon Woods23e05002014-09-22 19:07:27 -04001173 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001174 return mVertexAttribCurrentValues[attribNum];
1175}
1176
Shannon Woods53a94a82014-06-24 15:20:36 -04001177const void *State::getVertexAttribPointer(unsigned int attribNum) const
1178{
1179 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1180}
1181
1182void State::setPackAlignment(GLint alignment)
1183{
1184 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001185 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001186}
1187
1188GLint State::getPackAlignment() const
1189{
1190 return mPack.alignment;
1191}
1192
1193void State::setPackReverseRowOrder(bool reverseRowOrder)
1194{
1195 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001196 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001197}
1198
1199bool State::getPackReverseRowOrder() const
1200{
1201 return mPack.reverseRowOrder;
1202}
1203
Minmin Gongadff67b2015-10-14 10:34:45 -04001204void State::setPackRowLength(GLint rowLength)
1205{
1206 mPack.rowLength = rowLength;
1207 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1208}
1209
1210GLint State::getPackRowLength() const
1211{
1212 return mPack.rowLength;
1213}
1214
1215void State::setPackSkipRows(GLint skipRows)
1216{
1217 mPack.skipRows = skipRows;
1218 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1219}
1220
1221GLint State::getPackSkipRows() const
1222{
1223 return mPack.skipRows;
1224}
1225
1226void State::setPackSkipPixels(GLint skipPixels)
1227{
1228 mPack.skipPixels = skipPixels;
1229 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1230}
1231
1232GLint State::getPackSkipPixels() const
1233{
1234 return mPack.skipPixels;
1235}
1236
Shannon Woods53a94a82014-06-24 15:20:36 -04001237const PixelPackState &State::getPackState() const
1238{
1239 return mPack;
1240}
1241
Jamie Madill87de3622015-03-16 10:41:44 -04001242PixelPackState &State::getPackState()
1243{
1244 return mPack;
1245}
1246
Shannon Woods53a94a82014-06-24 15:20:36 -04001247void State::setUnpackAlignment(GLint alignment)
1248{
1249 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001250 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001251}
1252
1253GLint State::getUnpackAlignment() const
1254{
1255 return mUnpack.alignment;
1256}
1257
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001258void State::setUnpackRowLength(GLint rowLength)
1259{
1260 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001261 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001262}
1263
1264GLint State::getUnpackRowLength() const
1265{
1266 return mUnpack.rowLength;
1267}
1268
Minmin Gongadff67b2015-10-14 10:34:45 -04001269void State::setUnpackImageHeight(GLint imageHeight)
1270{
1271 mUnpack.imageHeight = imageHeight;
1272 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1273}
1274
1275GLint State::getUnpackImageHeight() const
1276{
1277 return mUnpack.imageHeight;
1278}
1279
1280void State::setUnpackSkipImages(GLint skipImages)
1281{
1282 mUnpack.skipImages = skipImages;
1283 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1284}
1285
1286GLint State::getUnpackSkipImages() const
1287{
1288 return mUnpack.skipImages;
1289}
1290
1291void State::setUnpackSkipRows(GLint skipRows)
1292{
1293 mUnpack.skipRows = skipRows;
1294 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1295}
1296
1297GLint State::getUnpackSkipRows() const
1298{
1299 return mUnpack.skipRows;
1300}
1301
1302void State::setUnpackSkipPixels(GLint skipPixels)
1303{
1304 mUnpack.skipPixels = skipPixels;
1305 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1306}
1307
1308GLint State::getUnpackSkipPixels() const
1309{
1310 return mUnpack.skipPixels;
1311}
1312
Shannon Woods53a94a82014-06-24 15:20:36 -04001313const PixelUnpackState &State::getUnpackState() const
1314{
1315 return mUnpack;
1316}
1317
Jamie Madill67102f02015-03-16 10:41:42 -04001318PixelUnpackState &State::getUnpackState()
1319{
1320 return mUnpack;
1321}
1322
Geoff Lang70d0f492015-12-10 17:45:46 -05001323const Debug &State::getDebug() const
1324{
1325 return mDebug;
1326}
1327
1328Debug &State::getDebug()
1329{
1330 return mDebug;
1331}
1332
Shannon Woods53a94a82014-06-24 15:20:36 -04001333void State::getBooleanv(GLenum pname, GLboolean *params)
1334{
1335 switch (pname)
1336 {
1337 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1338 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1339 case GL_COLOR_WRITEMASK:
1340 params[0] = mBlend.colorMaskRed;
1341 params[1] = mBlend.colorMaskGreen;
1342 params[2] = mBlend.colorMaskBlue;
1343 params[3] = mBlend.colorMaskAlpha;
1344 break;
1345 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1346 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1347 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1348 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1349 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1350 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1351 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1352 case GL_BLEND: *params = mBlend.blend; break;
1353 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001354 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1355 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001356 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1357 *params = mPrimitiveRestart;
1358 break;
Geoff Langab831f02015-12-01 09:39:10 -05001359 case GL_RASTERIZER_DISCARD:
1360 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1361 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001362 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1363 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1364 break;
1365 case GL_DEBUG_OUTPUT:
1366 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1367 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001368 default:
1369 UNREACHABLE();
1370 break;
1371 }
1372}
1373
1374void State::getFloatv(GLenum pname, GLfloat *params)
1375{
1376 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1377 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1378 // GetIntegerv as its native query function. As it would require conversion in any
1379 // case, this should make no difference to the calling application.
1380 switch (pname)
1381 {
1382 case GL_LINE_WIDTH: *params = mLineWidth; break;
1383 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1384 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1385 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1386 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1387 case GL_DEPTH_RANGE:
1388 params[0] = mNearZ;
1389 params[1] = mFarZ;
1390 break;
1391 case GL_COLOR_CLEAR_VALUE:
1392 params[0] = mColorClearValue.red;
1393 params[1] = mColorClearValue.green;
1394 params[2] = mColorClearValue.blue;
1395 params[3] = mColorClearValue.alpha;
1396 break;
1397 case GL_BLEND_COLOR:
1398 params[0] = mBlendColor.red;
1399 params[1] = mBlendColor.green;
1400 params[2] = mBlendColor.blue;
1401 params[3] = mBlendColor.alpha;
1402 break;
1403 default:
1404 UNREACHABLE();
1405 break;
1406 }
1407}
1408
Jamie Madill48faf802014-11-06 15:27:22 -05001409void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001410{
1411 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1412 {
1413 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001414 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001415 Framebuffer *framebuffer = mDrawFramebuffer;
1416 *params = framebuffer->getDrawBufferState(colorAttachment);
1417 return;
1418 }
1419
1420 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1421 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1422 // GetIntegerv as its native query function. As it would require conversion in any
1423 // case, this should make no difference to the calling application. You may find it in
1424 // State::getFloatv.
1425 switch (pname)
1426 {
1427 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001428 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001429 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1430 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1431 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1432 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1433 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001434 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001435 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1436 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001437 case GL_PACK_ROW_LENGTH:
1438 *params = mPack.rowLength;
1439 break;
1440 case GL_PACK_SKIP_ROWS:
1441 *params = mPack.skipRows;
1442 break;
1443 case GL_PACK_SKIP_PIXELS:
1444 *params = mPack.skipPixels;
1445 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001446 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001447 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001448 case GL_UNPACK_IMAGE_HEIGHT:
1449 *params = mUnpack.imageHeight;
1450 break;
1451 case GL_UNPACK_SKIP_IMAGES:
1452 *params = mUnpack.skipImages;
1453 break;
1454 case GL_UNPACK_SKIP_ROWS:
1455 *params = mUnpack.skipRows;
1456 break;
1457 case GL_UNPACK_SKIP_PIXELS:
1458 *params = mUnpack.skipPixels;
1459 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001460 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1461 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001462 case GL_ACTIVE_TEXTURE:
1463 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1464 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001465 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1466 case GL_STENCIL_REF: *params = mStencilRef; break;
1467 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1468 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1469 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1470 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1471 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1472 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1473 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1474 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1475 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1476 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1477 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1478 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1479 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1480 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1481 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1482 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1483 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1484 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1485 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1486 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001487 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1488 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001489 case GL_SAMPLE_BUFFERS:
1490 case GL_SAMPLES:
1491 {
1492 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001493 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001494 {
1495 switch (pname)
1496 {
1497 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001498 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001499 {
1500 *params = 1;
1501 }
1502 else
1503 {
1504 *params = 0;
1505 }
1506 break;
1507 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001508 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001509 break;
1510 }
1511 }
1512 else
1513 {
1514 *params = 0;
1515 }
1516 }
1517 break;
1518 case GL_VIEWPORT:
1519 params[0] = mViewport.x;
1520 params[1] = mViewport.y;
1521 params[2] = mViewport.width;
1522 params[3] = mViewport.height;
1523 break;
1524 case GL_SCISSOR_BOX:
1525 params[0] = mScissor.x;
1526 params[1] = mScissor.y;
1527 params[2] = mScissor.width;
1528 params[3] = mScissor.height;
1529 break;
1530 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1531 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1532 case GL_RED_BITS:
1533 case GL_GREEN_BITS:
1534 case GL_BLUE_BITS:
1535 case GL_ALPHA_BITS:
1536 {
1537 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001538 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001539
1540 if (colorbuffer)
1541 {
1542 switch (pname)
1543 {
1544 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1545 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1546 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1547 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1548 }
1549 }
1550 else
1551 {
1552 *params = 0;
1553 }
1554 }
1555 break;
1556 case GL_DEPTH_BITS:
1557 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001558 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1559 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001560
1561 if (depthbuffer)
1562 {
1563 *params = depthbuffer->getDepthSize();
1564 }
1565 else
1566 {
1567 *params = 0;
1568 }
1569 }
1570 break;
1571 case GL_STENCIL_BITS:
1572 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001573 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1574 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001575
1576 if (stencilbuffer)
1577 {
1578 *params = stencilbuffer->getStencilSize();
1579 }
1580 else
1581 {
1582 *params = 0;
1583 }
1584 }
1585 break;
1586 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001587 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001588 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001589 break;
1590 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001591 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001592 *params =
1593 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001594 break;
1595 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001596 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001597 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001598 break;
1599 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001600 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001601 *params =
1602 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001603 break;
1604 case GL_UNIFORM_BUFFER_BINDING:
1605 *params = mGenericUniformBuffer.id();
1606 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001607 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001608 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001609 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001610 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001611 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001612 break;
1613 case GL_COPY_READ_BUFFER_BINDING:
1614 *params = mCopyReadBuffer.id();
1615 break;
1616 case GL_COPY_WRITE_BUFFER_BINDING:
1617 *params = mCopyWriteBuffer.id();
1618 break;
1619 case GL_PIXEL_PACK_BUFFER_BINDING:
1620 *params = mPack.pixelBuffer.id();
1621 break;
1622 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1623 *params = mUnpack.pixelBuffer.id();
1624 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001625 case GL_DEBUG_LOGGED_MESSAGES:
1626 *params = static_cast<GLint>(mDebug.getMessageCount());
1627 break;
1628 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1629 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1630 break;
1631 case GL_DEBUG_GROUP_STACK_DEPTH:
1632 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1633 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001634 default:
1635 UNREACHABLE();
1636 break;
1637 }
1638}
1639
Geoff Lang70d0f492015-12-10 17:45:46 -05001640void State::getPointerv(GLenum pname, void **params) const
1641{
1642 switch (pname)
1643 {
1644 case GL_DEBUG_CALLBACK_FUNCTION:
1645 *params = reinterpret_cast<void *>(mDebug.getCallback());
1646 break;
1647 case GL_DEBUG_CALLBACK_USER_PARAM:
1648 *params = const_cast<void *>(mDebug.getUserParam());
1649 break;
1650 default:
1651 UNREACHABLE();
1652 break;
1653 }
1654}
1655
Shannon Woods53a94a82014-06-24 15:20:36 -04001656bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1657{
1658 switch (target)
1659 {
1660 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001661 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001662 {
Geoff Lang045536b2015-03-27 15:17:18 -04001663 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001664 }
1665 break;
1666 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001667 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001668 {
1669 *data = mUniformBuffers[index].id();
1670 }
1671 break;
1672 default:
1673 return false;
1674 }
1675
1676 return true;
1677}
1678
1679bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1680{
1681 switch (target)
1682 {
1683 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001684 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001685 {
Geoff Lang045536b2015-03-27 15:17:18 -04001686 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001687 }
1688 break;
1689 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001690 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001691 {
Geoff Lang045536b2015-03-27 15:17:18 -04001692 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001693 }
1694 break;
1695 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001696 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001697 {
1698 *data = mUniformBuffers[index].getOffset();
1699 }
1700 break;
1701 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001702 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001703 {
1704 *data = mUniformBuffers[index].getSize();
1705 }
1706 break;
1707 default:
1708 return false;
1709 }
1710
1711 return true;
1712}
1713
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001714bool State::hasMappedBuffer(GLenum target) const
1715{
1716 if (target == GL_ARRAY_BUFFER)
1717 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001718 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001719 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001720 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001721 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001722 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001723 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001724 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1725 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1726 {
1727 return true;
1728 }
1729 }
1730
1731 return false;
1732 }
1733 else
1734 {
1735 Buffer *buffer = getTargetBuffer(target);
1736 return (buffer && buffer->isMapped());
1737 }
1738}
1739
Jamie Madillc9d442d2016-01-20 11:17:24 -05001740void State::syncDirtyObjects()
1741{
1742 if (!mDirtyObjects.any())
1743 return;
1744
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001745 syncDirtyObjects(mDirtyObjects);
1746}
1747
1748void State::syncDirtyObjects(const DirtyObjects &bitset)
1749{
1750 for (auto dirtyObject : angle::IterateBitSet(bitset))
Jamie Madillc9d442d2016-01-20 11:17:24 -05001751 {
1752 switch (dirtyObject)
1753 {
1754 case DIRTY_OBJECT_READ_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001755 ASSERT(mReadFramebuffer);
1756 mReadFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001757 break;
1758 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001759 ASSERT(mDrawFramebuffer);
1760 mDrawFramebuffer->syncState();
Jamie Madillc9d442d2016-01-20 11:17:24 -05001761 break;
1762 case DIRTY_OBJECT_VERTEX_ARRAY:
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001763 ASSERT(mVertexArray);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001764 mVertexArray->syncImplState();
1765 break;
1766 case DIRTY_OBJECT_PROGRAM:
1767 // TODO(jmadill): implement this
1768 break;
1769 default:
1770 UNREACHABLE();
1771 break;
1772 }
1773 }
1774
Jamie Madill60ec6ea2016-01-22 15:27:19 -05001775 mDirtyObjects &= ~bitset;
1776}
1777
1778void State::syncDirtyObject(GLenum target)
1779{
1780 DirtyObjects localSet;
1781
1782 switch (target)
1783 {
1784 case GL_READ_FRAMEBUFFER:
1785 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1786 break;
1787 case GL_DRAW_FRAMEBUFFER:
1788 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1789 break;
1790 case GL_FRAMEBUFFER:
1791 localSet.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1792 localSet.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1793 break;
1794 case GL_VERTEX_ARRAY:
1795 localSet.set(DIRTY_OBJECT_VERTEX_ARRAY);
1796 break;
1797 case GL_PROGRAM:
1798 localSet.set(DIRTY_OBJECT_PROGRAM);
1799 break;
1800 }
1801
1802 syncDirtyObjects(localSet);
1803}
1804
1805void State::setObjectDirty(GLenum target)
1806{
1807 switch (target)
1808 {
1809 case GL_READ_FRAMEBUFFER:
1810 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1811 break;
1812 case GL_DRAW_FRAMEBUFFER:
1813 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1814 break;
1815 case GL_FRAMEBUFFER:
1816 mDirtyObjects.set(DIRTY_OBJECT_READ_FRAMEBUFFER);
1817 mDirtyObjects.set(DIRTY_OBJECT_DRAW_FRAMEBUFFER);
1818 break;
1819 case GL_VERTEX_ARRAY:
1820 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
1821 break;
1822 case GL_PROGRAM:
1823 mDirtyObjects.set(DIRTY_OBJECT_PROGRAM);
1824 break;
1825 }
Shannon Woods53a94a82014-06-24 15:20:36 -04001826}
Jamie Madillc9d442d2016-01-20 11:17:24 -05001827
1828} // namespace gl