blob: b9c9f4b799c228e79287890db0a794d943143e8b [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{
838 mReadFramebuffer = framebuffer;
839}
840
841void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
842{
843 mDrawFramebuffer = framebuffer;
844}
845
846Framebuffer *State::getTargetFramebuffer(GLenum target) const
847{
848 switch (target)
849 {
850 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
851 case GL_DRAW_FRAMEBUFFER_ANGLE:
852 case GL_FRAMEBUFFER: return mDrawFramebuffer;
853 default: UNREACHABLE(); return NULL;
854 }
855}
856
857Framebuffer *State::getReadFramebuffer()
858{
859 return mReadFramebuffer;
860}
861
862Framebuffer *State::getDrawFramebuffer()
863{
864 return mDrawFramebuffer;
865}
866
867const Framebuffer *State::getReadFramebuffer() const
868{
869 return mReadFramebuffer;
870}
871
872const Framebuffer *State::getDrawFramebuffer() const
873{
874 return mDrawFramebuffer;
875}
876
877bool State::removeReadFramebufferBinding(GLuint framebuffer)
878{
Jamie Madill77a72f62015-04-14 11:18:32 -0400879 if (mReadFramebuffer != nullptr &&
880 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400881 {
882 mReadFramebuffer = NULL;
883 return true;
884 }
885
886 return false;
887}
888
889bool State::removeDrawFramebufferBinding(GLuint framebuffer)
890{
Jamie Madill77a72f62015-04-14 11:18:32 -0400891 if (mReadFramebuffer != nullptr &&
892 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400893 {
894 mDrawFramebuffer = NULL;
895 return true;
896 }
897
898 return false;
899}
900
901void State::setVertexArrayBinding(VertexArray *vertexArray)
902{
903 mVertexArray = vertexArray;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000904 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500905
906 if (mVertexArray && mVertexArray->hasAnyDirtyBit())
907 {
908 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
909 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400910}
911
912GLuint State::getVertexArrayId() const
913{
914 ASSERT(mVertexArray != NULL);
915 return mVertexArray->id();
916}
917
918VertexArray *State::getVertexArray() const
919{
920 ASSERT(mVertexArray != NULL);
921 return mVertexArray;
922}
923
924bool State::removeVertexArrayBinding(GLuint vertexArray)
925{
926 if (mVertexArray->id() == vertexArray)
927 {
928 mVertexArray = NULL;
Jamie Madill0b9e9032015-08-17 11:51:52 +0000929 mDirtyBits.set(DIRTY_BIT_VERTEX_ARRAY_BINDING);
Jamie Madillc9d442d2016-01-20 11:17:24 -0500930 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -0400931 return true;
932 }
933
934 return false;
935}
936
Geoff Lang7dd2e102014-11-10 15:19:26 -0500937void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400938{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500939 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400940 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500941 if (mProgram)
942 {
943 mProgram->release();
944 }
945
946 mProgram = newProgram;
947
948 if (mProgram)
949 {
950 newProgram->addRef();
951 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400952 }
953}
954
Geoff Lang7dd2e102014-11-10 15:19:26 -0500955Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400956{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500957 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400958}
959
960void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
961{
962 mTransformFeedback.set(transformFeedback);
963}
964
965TransformFeedback *State::getCurrentTransformFeedback() const
966{
967 return mTransformFeedback.get();
968}
969
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000970bool State::isTransformFeedbackActiveUnpaused() const
971{
972 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400973 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000974}
975
Shannon Woods53a94a82014-06-24 15:20:36 -0400976void State::detachTransformFeedback(GLuint transformFeedback)
977{
978 if (mTransformFeedback.id() == transformFeedback)
979 {
980 mTransformFeedback.set(NULL);
981 }
982}
983
984bool State::isQueryActive() const
985{
986 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
987 i != mActiveQueries.end(); i++)
988 {
989 if (i->second.get() != NULL)
990 {
991 return true;
992 }
993 }
994
995 return false;
996}
997
998void State::setActiveQuery(GLenum target, Query *query)
999{
1000 mActiveQueries[target].set(query);
1001}
1002
1003GLuint State::getActiveQueryId(GLenum target) const
1004{
1005 const Query *query = getActiveQuery(target);
1006 return (query ? query->id() : 0u);
1007}
1008
1009Query *State::getActiveQuery(GLenum target) const
1010{
Jamie Madill5864ac22015-01-12 14:43:07 -05001011 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -04001012
Jamie Madill5864ac22015-01-12 14:43:07 -05001013 // All query types should already exist in the activeQueries map
1014 ASSERT(it != mActiveQueries.end());
1015
1016 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001017}
1018
1019void State::setArrayBufferBinding(Buffer *buffer)
1020{
1021 mArrayBuffer.set(buffer);
1022}
1023
1024GLuint State::getArrayBufferId() const
1025{
1026 return mArrayBuffer.id();
1027}
1028
Shannon Woods53a94a82014-06-24 15:20:36 -04001029void State::setGenericUniformBufferBinding(Buffer *buffer)
1030{
1031 mGenericUniformBuffer.set(buffer);
1032}
1033
1034void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
1035{
1036 mUniformBuffers[index].set(buffer, offset, size);
1037}
1038
Geoff Lang5d124a62015-09-15 13:03:27 -04001039const OffsetBindingPointer<Buffer> &State::getIndexedUniformBuffer(size_t index) const
Shannon Woods53a94a82014-06-24 15:20:36 -04001040{
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001041 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Geoff Lang5d124a62015-09-15 13:03:27 -04001042 return mUniformBuffers[index];
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +00001043}
1044
Shannon Woods53a94a82014-06-24 15:20:36 -04001045void State::setCopyReadBufferBinding(Buffer *buffer)
1046{
1047 mCopyReadBuffer.set(buffer);
1048}
1049
1050void State::setCopyWriteBufferBinding(Buffer *buffer)
1051{
1052 mCopyWriteBuffer.set(buffer);
1053}
1054
1055void State::setPixelPackBufferBinding(Buffer *buffer)
1056{
1057 mPack.pixelBuffer.set(buffer);
1058}
1059
1060void State::setPixelUnpackBufferBinding(Buffer *buffer)
1061{
1062 mUnpack.pixelBuffer.set(buffer);
1063}
1064
1065Buffer *State::getTargetBuffer(GLenum target) const
1066{
1067 switch (target)
1068 {
1069 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1070 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1071 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
Jamie Madill8e344942015-07-09 14:22:07 -04001072 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001073 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1074 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -04001075 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -04001076 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1077 default: UNREACHABLE(); return NULL;
1078 }
1079}
1080
Yuly Novikov5807a532015-12-03 13:01:22 -05001081void State::detachBuffer(GLuint bufferName)
1082{
1083 BindingPointer<Buffer> *buffers[] = {&mArrayBuffer, &mCopyReadBuffer,
1084 &mCopyWriteBuffer, &mPack.pixelBuffer,
1085 &mUnpack.pixelBuffer, &mGenericUniformBuffer};
1086 for (auto buffer : buffers)
1087 {
1088 if (buffer->id() == bufferName)
1089 {
1090 buffer->set(nullptr);
1091 }
1092 }
1093
1094 TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
1095 if (curTransformFeedback)
1096 {
1097 curTransformFeedback->detachBuffer(bufferName);
1098 }
1099
1100 getVertexArray()->detachBuffer(bufferName);
1101}
1102
Shannon Woods53a94a82014-06-24 15:20:36 -04001103void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1104{
1105 getVertexArray()->enableAttribute(attribNum, enabled);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001106 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001107}
1108
1109void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1110{
Shannon Woods23e05002014-09-22 19:07:27 -04001111 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001112 mVertexAttribCurrentValues[index].setFloatValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001113 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001114}
1115
1116void State::setVertexAttribu(GLuint index, const GLuint values[4])
1117{
Shannon Woods23e05002014-09-22 19:07:27 -04001118 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001119 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001120 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001121}
1122
1123void State::setVertexAttribi(GLuint index, const GLint values[4])
1124{
Shannon Woods23e05002014-09-22 19:07:27 -04001125 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001126 mVertexAttribCurrentValues[index].setIntValues(values);
Jamie Madill1e0bc3a2015-08-11 08:12:21 -04001127 mDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_0 + index);
Shannon Woods53a94a82014-06-24 15:20:36 -04001128}
1129
Jamie Madill0b9e9032015-08-17 11:51:52 +00001130void State::setVertexAttribState(unsigned int attribNum,
1131 Buffer *boundBuffer,
1132 GLint size,
1133 GLenum type,
1134 bool normalized,
1135 bool pureInteger,
1136 GLsizei stride,
1137 const void *pointer)
Shannon Woods53a94a82014-06-24 15:20:36 -04001138{
1139 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001140 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Jamie Madill0b9e9032015-08-17 11:51:52 +00001141}
1142
1143void State::setVertexAttribDivisor(GLuint index, GLuint divisor)
1144{
1145 getVertexArray()->setVertexAttribDivisor(index, divisor);
Jamie Madillc9d442d2016-01-20 11:17:24 -05001146 mDirtyObjects.set(DIRTY_OBJECT_VERTEX_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001147}
1148
Shannon Woods53a94a82014-06-24 15:20:36 -04001149const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1150{
Shannon Woods23e05002014-09-22 19:07:27 -04001151 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001152 return mVertexAttribCurrentValues[attribNum];
1153}
1154
Shannon Woods53a94a82014-06-24 15:20:36 -04001155const void *State::getVertexAttribPointer(unsigned int attribNum) const
1156{
1157 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1158}
1159
1160void State::setPackAlignment(GLint alignment)
1161{
1162 mPack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001163 mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001164}
1165
1166GLint State::getPackAlignment() const
1167{
1168 return mPack.alignment;
1169}
1170
1171void State::setPackReverseRowOrder(bool reverseRowOrder)
1172{
1173 mPack.reverseRowOrder = reverseRowOrder;
Jamie Madill1b94d432015-08-07 13:23:23 -04001174 mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
Shannon Woods53a94a82014-06-24 15:20:36 -04001175}
1176
1177bool State::getPackReverseRowOrder() const
1178{
1179 return mPack.reverseRowOrder;
1180}
1181
Minmin Gongadff67b2015-10-14 10:34:45 -04001182void State::setPackRowLength(GLint rowLength)
1183{
1184 mPack.rowLength = rowLength;
1185 mDirtyBits.set(DIRTY_BIT_PACK_ROW_LENGTH);
1186}
1187
1188GLint State::getPackRowLength() const
1189{
1190 return mPack.rowLength;
1191}
1192
1193void State::setPackSkipRows(GLint skipRows)
1194{
1195 mPack.skipRows = skipRows;
1196 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_ROWS);
1197}
1198
1199GLint State::getPackSkipRows() const
1200{
1201 return mPack.skipRows;
1202}
1203
1204void State::setPackSkipPixels(GLint skipPixels)
1205{
1206 mPack.skipPixels = skipPixels;
1207 mDirtyBits.set(DIRTY_BIT_PACK_SKIP_PIXELS);
1208}
1209
1210GLint State::getPackSkipPixels() const
1211{
1212 return mPack.skipPixels;
1213}
1214
Shannon Woods53a94a82014-06-24 15:20:36 -04001215const PixelPackState &State::getPackState() const
1216{
1217 return mPack;
1218}
1219
Jamie Madill87de3622015-03-16 10:41:44 -04001220PixelPackState &State::getPackState()
1221{
1222 return mPack;
1223}
1224
Shannon Woods53a94a82014-06-24 15:20:36 -04001225void State::setUnpackAlignment(GLint alignment)
1226{
1227 mUnpack.alignment = alignment;
Jamie Madill1b94d432015-08-07 13:23:23 -04001228 mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
Shannon Woods53a94a82014-06-24 15:20:36 -04001229}
1230
1231GLint State::getUnpackAlignment() const
1232{
1233 return mUnpack.alignment;
1234}
1235
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001236void State::setUnpackRowLength(GLint rowLength)
1237{
1238 mUnpack.rowLength = rowLength;
Jamie Madill1b94d432015-08-07 13:23:23 -04001239 mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001240}
1241
1242GLint State::getUnpackRowLength() const
1243{
1244 return mUnpack.rowLength;
1245}
1246
Minmin Gongadff67b2015-10-14 10:34:45 -04001247void State::setUnpackImageHeight(GLint imageHeight)
1248{
1249 mUnpack.imageHeight = imageHeight;
1250 mDirtyBits.set(DIRTY_BIT_UNPACK_IMAGE_HEIGHT);
1251}
1252
1253GLint State::getUnpackImageHeight() const
1254{
1255 return mUnpack.imageHeight;
1256}
1257
1258void State::setUnpackSkipImages(GLint skipImages)
1259{
1260 mUnpack.skipImages = skipImages;
1261 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_IMAGES);
1262}
1263
1264GLint State::getUnpackSkipImages() const
1265{
1266 return mUnpack.skipImages;
1267}
1268
1269void State::setUnpackSkipRows(GLint skipRows)
1270{
1271 mUnpack.skipRows = skipRows;
1272 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_ROWS);
1273}
1274
1275GLint State::getUnpackSkipRows() const
1276{
1277 return mUnpack.skipRows;
1278}
1279
1280void State::setUnpackSkipPixels(GLint skipPixels)
1281{
1282 mUnpack.skipPixels = skipPixels;
1283 mDirtyBits.set(DIRTY_BIT_UNPACK_SKIP_PIXELS);
1284}
1285
1286GLint State::getUnpackSkipPixels() const
1287{
1288 return mUnpack.skipPixels;
1289}
1290
Shannon Woods53a94a82014-06-24 15:20:36 -04001291const PixelUnpackState &State::getUnpackState() const
1292{
1293 return mUnpack;
1294}
1295
Jamie Madill67102f02015-03-16 10:41:42 -04001296PixelUnpackState &State::getUnpackState()
1297{
1298 return mUnpack;
1299}
1300
Geoff Lang70d0f492015-12-10 17:45:46 -05001301const Debug &State::getDebug() const
1302{
1303 return mDebug;
1304}
1305
1306Debug &State::getDebug()
1307{
1308 return mDebug;
1309}
1310
Shannon Woods53a94a82014-06-24 15:20:36 -04001311void State::getBooleanv(GLenum pname, GLboolean *params)
1312{
1313 switch (pname)
1314 {
1315 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1316 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1317 case GL_COLOR_WRITEMASK:
1318 params[0] = mBlend.colorMaskRed;
1319 params[1] = mBlend.colorMaskGreen;
1320 params[2] = mBlend.colorMaskBlue;
1321 params[3] = mBlend.colorMaskAlpha;
1322 break;
1323 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1324 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1325 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1326 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1327 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1328 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1329 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1330 case GL_BLEND: *params = mBlend.blend; break;
1331 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001332 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1333 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Jamie Madille2cd53d2015-10-27 11:15:46 -04001334 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1335 *params = mPrimitiveRestart;
1336 break;
Geoff Langab831f02015-12-01 09:39:10 -05001337 case GL_RASTERIZER_DISCARD:
1338 *params = isRasterizerDiscardEnabled() ? GL_TRUE : GL_FALSE;
1339 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001340 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
1341 *params = mDebug.isOutputSynchronous() ? GL_TRUE : GL_FALSE;
1342 break;
1343 case GL_DEBUG_OUTPUT:
1344 *params = mDebug.isOutputEnabled() ? GL_TRUE : GL_FALSE;
1345 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001346 default:
1347 UNREACHABLE();
1348 break;
1349 }
1350}
1351
1352void State::getFloatv(GLenum pname, GLfloat *params)
1353{
1354 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1355 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1356 // GetIntegerv as its native query function. As it would require conversion in any
1357 // case, this should make no difference to the calling application.
1358 switch (pname)
1359 {
1360 case GL_LINE_WIDTH: *params = mLineWidth; break;
1361 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1362 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1363 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1364 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1365 case GL_DEPTH_RANGE:
1366 params[0] = mNearZ;
1367 params[1] = mFarZ;
1368 break;
1369 case GL_COLOR_CLEAR_VALUE:
1370 params[0] = mColorClearValue.red;
1371 params[1] = mColorClearValue.green;
1372 params[2] = mColorClearValue.blue;
1373 params[3] = mColorClearValue.alpha;
1374 break;
1375 case GL_BLEND_COLOR:
1376 params[0] = mBlendColor.red;
1377 params[1] = mBlendColor.green;
1378 params[2] = mBlendColor.blue;
1379 params[3] = mBlendColor.alpha;
1380 break;
1381 default:
1382 UNREACHABLE();
1383 break;
1384 }
1385}
1386
Jamie Madill48faf802014-11-06 15:27:22 -05001387void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001388{
1389 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1390 {
1391 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001392 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001393 Framebuffer *framebuffer = mDrawFramebuffer;
1394 *params = framebuffer->getDrawBufferState(colorAttachment);
1395 return;
1396 }
1397
1398 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1399 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1400 // GetIntegerv as its native query function. As it would require conversion in any
1401 // case, this should make no difference to the calling application. You may find it in
1402 // State::getFloatv.
1403 switch (pname)
1404 {
1405 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
Jamie Madill8e344942015-07-09 14:22:07 -04001406 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001407 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1408 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1409 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1410 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1411 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001412 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001413 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1414 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001415 case GL_PACK_ROW_LENGTH:
1416 *params = mPack.rowLength;
1417 break;
1418 case GL_PACK_SKIP_ROWS:
1419 *params = mPack.skipRows;
1420 break;
1421 case GL_PACK_SKIP_PIXELS:
1422 *params = mPack.skipPixels;
1423 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001424 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001425 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Minmin Gongadff67b2015-10-14 10:34:45 -04001426 case GL_UNPACK_IMAGE_HEIGHT:
1427 *params = mUnpack.imageHeight;
1428 break;
1429 case GL_UNPACK_SKIP_IMAGES:
1430 *params = mUnpack.skipImages;
1431 break;
1432 case GL_UNPACK_SKIP_ROWS:
1433 *params = mUnpack.skipRows;
1434 break;
1435 case GL_UNPACK_SKIP_PIXELS:
1436 *params = mUnpack.skipPixels;
1437 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001438 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1439 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001440 case GL_ACTIVE_TEXTURE:
1441 *params = (static_cast<GLint>(mActiveSampler) + GL_TEXTURE0);
1442 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001443 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1444 case GL_STENCIL_REF: *params = mStencilRef; break;
1445 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1446 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1447 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1448 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1449 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1450 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1451 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1452 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1453 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1454 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1455 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1456 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1457 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1458 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1459 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1460 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1461 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1462 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1463 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1464 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001465 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1466 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001467 case GL_SAMPLE_BUFFERS:
1468 case GL_SAMPLES:
1469 {
1470 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001471 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001472 {
1473 switch (pname)
1474 {
1475 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001476 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001477 {
1478 *params = 1;
1479 }
1480 else
1481 {
1482 *params = 0;
1483 }
1484 break;
1485 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001486 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001487 break;
1488 }
1489 }
1490 else
1491 {
1492 *params = 0;
1493 }
1494 }
1495 break;
1496 case GL_VIEWPORT:
1497 params[0] = mViewport.x;
1498 params[1] = mViewport.y;
1499 params[2] = mViewport.width;
1500 params[3] = mViewport.height;
1501 break;
1502 case GL_SCISSOR_BOX:
1503 params[0] = mScissor.x;
1504 params[1] = mScissor.y;
1505 params[2] = mScissor.width;
1506 params[3] = mScissor.height;
1507 break;
1508 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1509 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1510 case GL_RED_BITS:
1511 case GL_GREEN_BITS:
1512 case GL_BLUE_BITS:
1513 case GL_ALPHA_BITS:
1514 {
1515 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001516 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001517
1518 if (colorbuffer)
1519 {
1520 switch (pname)
1521 {
1522 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1523 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1524 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1525 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1526 }
1527 }
1528 else
1529 {
1530 *params = 0;
1531 }
1532 }
1533 break;
1534 case GL_DEPTH_BITS:
1535 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001536 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1537 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001538
1539 if (depthbuffer)
1540 {
1541 *params = depthbuffer->getDepthSize();
1542 }
1543 else
1544 {
1545 *params = 0;
1546 }
1547 }
1548 break;
1549 case GL_STENCIL_BITS:
1550 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001551 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1552 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001553
1554 if (stencilbuffer)
1555 {
1556 *params = stencilbuffer->getStencilSize();
1557 }
1558 else
1559 {
1560 *params = 0;
1561 }
1562 }
1563 break;
1564 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001565 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001566 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001567 break;
1568 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001569 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001570 *params =
1571 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001572 break;
1573 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001574 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001575 *params = getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001576 break;
1577 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001578 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Cooper Partin4d61f7e2015-08-12 10:56:50 -07001579 *params =
1580 getSamplerTextureId(static_cast<unsigned int>(mActiveSampler), GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001581 break;
1582 case GL_UNIFORM_BUFFER_BINDING:
1583 *params = mGenericUniformBuffer.id();
1584 break;
Frank Henigman22581ff2015-11-06 14:25:54 -05001585 case GL_TRANSFORM_FEEDBACK_BINDING:
Frank Henigmanb0f0b812015-11-21 17:49:29 -05001586 *params = mTransformFeedback.id();
Frank Henigman22581ff2015-11-06 14:25:54 -05001587 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001588 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001589 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001590 break;
1591 case GL_COPY_READ_BUFFER_BINDING:
1592 *params = mCopyReadBuffer.id();
1593 break;
1594 case GL_COPY_WRITE_BUFFER_BINDING:
1595 *params = mCopyWriteBuffer.id();
1596 break;
1597 case GL_PIXEL_PACK_BUFFER_BINDING:
1598 *params = mPack.pixelBuffer.id();
1599 break;
1600 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1601 *params = mUnpack.pixelBuffer.id();
1602 break;
Geoff Lang70d0f492015-12-10 17:45:46 -05001603 case GL_DEBUG_LOGGED_MESSAGES:
1604 *params = static_cast<GLint>(mDebug.getMessageCount());
1605 break;
1606 case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
1607 *params = static_cast<GLint>(mDebug.getNextMessageLength());
1608 break;
1609 case GL_DEBUG_GROUP_STACK_DEPTH:
1610 *params = static_cast<GLint>(mDebug.getGroupStackDepth());
1611 break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001612 default:
1613 UNREACHABLE();
1614 break;
1615 }
1616}
1617
Geoff Lang70d0f492015-12-10 17:45:46 -05001618void State::getPointerv(GLenum pname, void **params) const
1619{
1620 switch (pname)
1621 {
1622 case GL_DEBUG_CALLBACK_FUNCTION:
1623 *params = reinterpret_cast<void *>(mDebug.getCallback());
1624 break;
1625 case GL_DEBUG_CALLBACK_USER_PARAM:
1626 *params = const_cast<void *>(mDebug.getUserParam());
1627 break;
1628 default:
1629 UNREACHABLE();
1630 break;
1631 }
1632}
1633
Shannon Woods53a94a82014-06-24 15:20:36 -04001634bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1635{
1636 switch (target)
1637 {
1638 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001639 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001640 {
Geoff Lang045536b2015-03-27 15:17:18 -04001641 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001642 }
1643 break;
1644 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001645 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001646 {
1647 *data = mUniformBuffers[index].id();
1648 }
1649 break;
1650 default:
1651 return false;
1652 }
1653
1654 return true;
1655}
1656
1657bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1658{
1659 switch (target)
1660 {
1661 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001662 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001663 {
Geoff Lang045536b2015-03-27 15:17:18 -04001664 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001665 }
1666 break;
1667 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001668 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001669 {
Geoff Lang045536b2015-03-27 15:17:18 -04001670 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001671 }
1672 break;
1673 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001674 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001675 {
1676 *data = mUniformBuffers[index].getOffset();
1677 }
1678 break;
1679 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001680 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001681 {
1682 *data = mUniformBuffers[index].getSize();
1683 }
1684 break;
1685 default:
1686 return false;
1687 }
1688
1689 return true;
1690}
1691
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001692bool State::hasMappedBuffer(GLenum target) const
1693{
1694 if (target == GL_ARRAY_BUFFER)
1695 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001696 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001697 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madill8e344942015-07-09 14:22:07 -04001698 size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001699 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001700 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001701 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001702 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1703 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1704 {
1705 return true;
1706 }
1707 }
1708
1709 return false;
1710 }
1711 else
1712 {
1713 Buffer *buffer = getTargetBuffer(target);
1714 return (buffer && buffer->isMapped());
1715 }
1716}
1717
Jamie Madillc9d442d2016-01-20 11:17:24 -05001718void State::syncDirtyObjects()
1719{
1720 if (!mDirtyObjects.any())
1721 return;
1722
1723 for (auto dirtyObject : angle::IterateBitSet(mDirtyObjects))
1724 {
1725 switch (dirtyObject)
1726 {
1727 case DIRTY_OBJECT_READ_FRAMEBUFFER:
1728 // TODO(jmadill): implement this
1729 break;
1730 case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
1731 // TODO(jmadill): implement this
1732 break;
1733 case DIRTY_OBJECT_VERTEX_ARRAY:
1734 mVertexArray->syncImplState();
1735 break;
1736 case DIRTY_OBJECT_PROGRAM:
1737 // TODO(jmadill): implement this
1738 break;
1739 default:
1740 UNREACHABLE();
1741 break;
1742 }
1743 }
1744
1745 mDirtyObjects.reset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001746}
Jamie Madillc9d442d2016-01-20 11:17:24 -05001747
1748} // namespace gl