blob: f731774e43c784596f1a4edb2f6ae7c34c03d041 [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
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Context.h"
12#include "libANGLE/Caps.h"
13#include "libANGLE/Framebuffer.h"
14#include "libANGLE/FramebufferAttachment.h"
15#include "libANGLE/Query.h"
16#include "libANGLE/VertexArray.h"
17#include "libANGLE/formatutils.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040018
19namespace gl
20{
Geoff Lang76b10c92014-09-05 16:28:14 -040021
Shannon Woods53a94a82014-06-24 15:20:36 -040022State::State()
23{
Shannon Woods2df6a602014-09-26 16:12:07 -040024 mMaxDrawBuffers = 0;
25 mMaxCombinedTextureImageUnits = 0;
Geoff Lang76b10c92014-09-05 16:28:14 -040026}
27
28State::~State()
29{
30 reset();
31}
32
Jamie Madillc185cb82015-04-28 12:39:08 -040033void State::initialize(const Caps &caps, GLuint clientVersion)
Geoff Lang76b10c92014-09-05 16:28:14 -040034{
Shannon Woods2df6a602014-09-26 16:12:07 -040035 mMaxDrawBuffers = caps.maxDrawBuffers;
36 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040037
Jamie Madillf75ab352015-03-16 10:46:52 -040038 setColorClearValue(0.0f, 0.0f, 0.0f, 0.0f);
Shannon Woods53a94a82014-06-24 15:20:36 -040039
40 mDepthClearValue = 1.0f;
41 mStencilClearValue = 0;
42
43 mRasterizer.rasterizerDiscard = false;
44 mRasterizer.cullFace = false;
45 mRasterizer.cullMode = GL_BACK;
46 mRasterizer.frontFace = GL_CCW;
47 mRasterizer.polygonOffsetFill = false;
48 mRasterizer.polygonOffsetFactor = 0.0f;
49 mRasterizer.polygonOffsetUnits = 0.0f;
50 mRasterizer.pointDrawMode = false;
51 mRasterizer.multiSample = false;
52 mScissorTest = false;
53 mScissor.x = 0;
54 mScissor.y = 0;
55 mScissor.width = 0;
56 mScissor.height = 0;
57
58 mBlend.blend = false;
59 mBlend.sourceBlendRGB = GL_ONE;
60 mBlend.sourceBlendAlpha = GL_ONE;
61 mBlend.destBlendRGB = GL_ZERO;
62 mBlend.destBlendAlpha = GL_ZERO;
63 mBlend.blendEquationRGB = GL_FUNC_ADD;
64 mBlend.blendEquationAlpha = GL_FUNC_ADD;
65 mBlend.sampleAlphaToCoverage = false;
66 mBlend.dither = true;
67
68 mBlendColor.red = 0;
69 mBlendColor.green = 0;
70 mBlendColor.blue = 0;
71 mBlendColor.alpha = 0;
72
73 mDepthStencil.depthTest = false;
74 mDepthStencil.depthFunc = GL_LESS;
75 mDepthStencil.depthMask = true;
76 mDepthStencil.stencilTest = false;
77 mDepthStencil.stencilFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070078 mDepthStencil.stencilMask = static_cast<GLuint>(-1);
79 mDepthStencil.stencilWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040080 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Austin Kinrossb8af7232015-03-16 22:33:25 -070081 mDepthStencil.stencilBackMask = static_cast<GLuint>(-1);
82 mDepthStencil.stencilBackWritemask = static_cast<GLuint>(-1);
Shannon Woods53a94a82014-06-24 15:20:36 -040083 mDepthStencil.stencilFail = GL_KEEP;
84 mDepthStencil.stencilPassDepthFail = GL_KEEP;
85 mDepthStencil.stencilPassDepthPass = GL_KEEP;
86 mDepthStencil.stencilBackFail = GL_KEEP;
87 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
88 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
89
90 mStencilRef = 0;
91 mStencilBackRef = 0;
92
93 mSampleCoverage = false;
94 mSampleCoverageValue = 1.0f;
95 mSampleCoverageInvert = false;
96 mGenerateMipmapHint = GL_DONT_CARE;
97 mFragmentShaderDerivativeHint = GL_DONT_CARE;
98
99 mLineWidth = 1.0f;
100
101 mViewport.x = 0;
102 mViewport.y = 0;
103 mViewport.width = 0;
104 mViewport.height = 0;
105 mNearZ = 0.0f;
106 mFarZ = 1.0f;
107
108 mBlend.colorMaskRed = true;
109 mBlend.colorMaskGreen = true;
110 mBlend.colorMaskBlue = true;
111 mBlend.colorMaskAlpha = true;
112
Geoff Lang76b10c92014-09-05 16:28:14 -0400113 mActiveSampler = 0;
114
Shannon Woods53a94a82014-06-24 15:20:36 -0400115 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
Shannon Woods23e05002014-09-22 19:07:27 -0400116 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
117 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
Shannon Woods53a94a82014-06-24 15:20:36 -0400118 {
119 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
120 }
121
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400122 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
123
Geoff Lang76b10c92014-09-05 16:28:14 -0400124 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
125 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
126 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400127 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400128 // TODO: These could also be enabled via extension
129 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
130 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400131 }
132
Geoff Lang76b10c92014-09-05 16:28:14 -0400133 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400134
135 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
136 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
137 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
138
Geoff Lang7dd2e102014-11-10 15:19:26 -0500139 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400140
141 mReadFramebuffer = NULL;
142 mDrawFramebuffer = NULL;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500143
144 mPrimitiveRestart = false;
Shannon Woods53a94a82014-06-24 15:20:36 -0400145}
146
Geoff Lang76b10c92014-09-05 16:28:14 -0400147void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400148{
Geoff Lang76b10c92014-09-05 16:28:14 -0400149 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400150 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400151 TextureBindingVector &textureVector = bindingVec->second;
152 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400153 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400154 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400155 }
156 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400157 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
158 {
159 mSamplers[samplerIdx].set(NULL);
160 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400161
Shannon Woods53a94a82014-06-24 15:20:36 -0400162 mArrayBuffer.set(NULL);
163 mRenderbuffer.set(NULL);
164
Geoff Lang7dd2e102014-11-10 15:19:26 -0500165 if (mProgram)
166 {
167 mProgram->release();
168 }
169 mProgram = NULL;
170
Shannon Woods53a94a82014-06-24 15:20:36 -0400171 mTransformFeedback.set(NULL);
172
173 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
174 {
175 i->second.set(NULL);
176 }
177
178 mGenericUniformBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400179 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400180 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400181 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400182 }
183
Shannon Woods53a94a82014-06-24 15:20:36 -0400184 mCopyReadBuffer.set(NULL);
185 mCopyWriteBuffer.set(NULL);
186
187 mPack.pixelBuffer.set(NULL);
188 mUnpack.pixelBuffer.set(NULL);
Geoff Lang7dd2e102014-11-10 15:19:26 -0500189
190 mProgram = NULL;
Shannon Woods53a94a82014-06-24 15:20:36 -0400191}
192
193const RasterizerState &State::getRasterizerState() const
194{
195 return mRasterizer;
196}
197
198const BlendState &State::getBlendState() const
199{
200 return mBlend;
201}
202
203const DepthStencilState &State::getDepthStencilState() const
204{
205 return mDepthStencil;
206}
207
Jamie Madillf75ab352015-03-16 10:46:52 -0400208void State::setColorClearValue(float red, float green, float blue, float alpha)
Shannon Woods53a94a82014-06-24 15:20:36 -0400209{
210 mColorClearValue.red = red;
211 mColorClearValue.green = green;
212 mColorClearValue.blue = blue;
213 mColorClearValue.alpha = alpha;
214}
215
Jamie Madillf75ab352015-03-16 10:46:52 -0400216void State::setDepthClearValue(float depth)
Shannon Woods53a94a82014-06-24 15:20:36 -0400217{
218 mDepthClearValue = depth;
219}
220
Jamie Madillf75ab352015-03-16 10:46:52 -0400221void State::setStencilClearValue(int stencil)
Shannon Woods53a94a82014-06-24 15:20:36 -0400222{
223 mStencilClearValue = stencil;
224}
225
Shannon Woods53a94a82014-06-24 15:20:36 -0400226void State::setColorMask(bool red, bool green, bool blue, bool alpha)
227{
228 mBlend.colorMaskRed = red;
229 mBlend.colorMaskGreen = green;
230 mBlend.colorMaskBlue = blue;
231 mBlend.colorMaskAlpha = alpha;
232}
233
234void State::setDepthMask(bool mask)
235{
236 mDepthStencil.depthMask = mask;
237}
238
239bool State::isRasterizerDiscardEnabled() const
240{
241 return mRasterizer.rasterizerDiscard;
242}
243
244void State::setRasterizerDiscard(bool enabled)
245{
246 mRasterizer.rasterizerDiscard = enabled;
247}
248
249bool State::isCullFaceEnabled() const
250{
251 return mRasterizer.cullFace;
252}
253
254void State::setCullFace(bool enabled)
255{
256 mRasterizer.cullFace = enabled;
257}
258
259void State::setCullMode(GLenum mode)
260{
261 mRasterizer.cullMode = mode;
262}
263
264void State::setFrontFace(GLenum front)
265{
266 mRasterizer.frontFace = front;
267}
268
269bool State::isDepthTestEnabled() const
270{
271 return mDepthStencil.depthTest;
272}
273
274void State::setDepthTest(bool enabled)
275{
276 mDepthStencil.depthTest = enabled;
277}
278
279void State::setDepthFunc(GLenum depthFunc)
280{
281 mDepthStencil.depthFunc = depthFunc;
282}
283
284void State::setDepthRange(float zNear, float zFar)
285{
286 mNearZ = zNear;
287 mFarZ = zFar;
288}
289
Geoff Langd42f5b82015-04-16 14:03:29 -0400290float State::getNearPlane() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400291{
Geoff Langd42f5b82015-04-16 14:03:29 -0400292 return mNearZ;
293}
294
295float State::getFarPlane() const
296{
297 return mFarZ;
Shannon Woods53a94a82014-06-24 15:20:36 -0400298}
299
300bool State::isBlendEnabled() const
301{
302 return mBlend.blend;
303}
304
305void State::setBlend(bool enabled)
306{
307 mBlend.blend = enabled;
308}
309
310void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
311{
312 mBlend.sourceBlendRGB = sourceRGB;
313 mBlend.destBlendRGB = destRGB;
314 mBlend.sourceBlendAlpha = sourceAlpha;
315 mBlend.destBlendAlpha = destAlpha;
316}
317
318void State::setBlendColor(float red, float green, float blue, float alpha)
319{
320 mBlendColor.red = red;
321 mBlendColor.green = green;
322 mBlendColor.blue = blue;
323 mBlendColor.alpha = alpha;
324}
325
326void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
327{
328 mBlend.blendEquationRGB = rgbEquation;
329 mBlend.blendEquationAlpha = alphaEquation;
330}
331
332const ColorF &State::getBlendColor() const
333{
334 return mBlendColor;
335}
336
337bool State::isStencilTestEnabled() const
338{
339 return mDepthStencil.stencilTest;
340}
341
342void State::setStencilTest(bool enabled)
343{
344 mDepthStencil.stencilTest = enabled;
345}
346
347void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
348{
349 mDepthStencil.stencilFunc = stencilFunc;
350 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
351 mDepthStencil.stencilMask = stencilMask;
352}
353
354void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
355{
356 mDepthStencil.stencilBackFunc = stencilBackFunc;
357 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
358 mDepthStencil.stencilBackMask = stencilBackMask;
359}
360
361void State::setStencilWritemask(GLuint stencilWritemask)
362{
363 mDepthStencil.stencilWritemask = stencilWritemask;
364}
365
366void State::setStencilBackWritemask(GLuint stencilBackWritemask)
367{
368 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
369}
370
371void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
372{
373 mDepthStencil.stencilFail = stencilFail;
374 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
375 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
376}
377
378void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
379{
380 mDepthStencil.stencilBackFail = stencilBackFail;
381 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
382 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
383}
384
385GLint State::getStencilRef() const
386{
387 return mStencilRef;
388}
389
390GLint State::getStencilBackRef() const
391{
392 return mStencilBackRef;
393}
394
395bool State::isPolygonOffsetFillEnabled() const
396{
397 return mRasterizer.polygonOffsetFill;
398}
399
400void State::setPolygonOffsetFill(bool enabled)
401{
402 mRasterizer.polygonOffsetFill = enabled;
403}
404
405void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
406{
407 // An application can pass NaN values here, so handle this gracefully
408 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
409 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
410}
411
412bool State::isSampleAlphaToCoverageEnabled() const
413{
414 return mBlend.sampleAlphaToCoverage;
415}
416
417void State::setSampleAlphaToCoverage(bool enabled)
418{
419 mBlend.sampleAlphaToCoverage = enabled;
420}
421
422bool State::isSampleCoverageEnabled() const
423{
424 return mSampleCoverage;
425}
426
427void State::setSampleCoverage(bool enabled)
428{
429 mSampleCoverage = enabled;
430}
431
432void State::setSampleCoverageParams(GLclampf value, bool invert)
433{
434 mSampleCoverageValue = value;
435 mSampleCoverageInvert = invert;
436}
437
Geoff Lang0fbb6002015-04-16 11:11:53 -0400438GLclampf State::getSampleCoverageValue() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400439{
Geoff Lang0fbb6002015-04-16 11:11:53 -0400440 return mSampleCoverageValue;
441}
Shannon Woods53a94a82014-06-24 15:20:36 -0400442
Geoff Lang0fbb6002015-04-16 11:11:53 -0400443bool State::getSampleCoverageInvert() const
444{
445 return mSampleCoverageInvert;
Shannon Woods53a94a82014-06-24 15:20:36 -0400446}
447
448bool State::isScissorTestEnabled() const
449{
450 return mScissorTest;
451}
452
453void State::setScissorTest(bool enabled)
454{
455 mScissorTest = enabled;
456}
457
458void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
459{
460 mScissor.x = x;
461 mScissor.y = y;
462 mScissor.width = width;
463 mScissor.height = height;
464}
465
466const Rectangle &State::getScissor() const
467{
468 return mScissor;
469}
470
471bool State::isDitherEnabled() const
472{
473 return mBlend.dither;
474}
475
476void State::setDither(bool enabled)
477{
478 mBlend.dither = enabled;
479}
480
Jamie Madillb4b53c52015-02-03 15:22:48 -0500481bool State::isPrimitiveRestartEnabled() const
482{
483 return mPrimitiveRestart;
484}
485
486void State::setPrimitiveRestart(bool enabled)
487{
488 mPrimitiveRestart = enabled;
489}
490
Shannon Woods53a94a82014-06-24 15:20:36 -0400491void State::setEnableFeature(GLenum feature, bool enabled)
492{
493 switch (feature)
494 {
495 case GL_CULL_FACE: setCullFace(enabled); break;
496 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
497 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
498 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
499 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
500 case GL_STENCIL_TEST: setStencilTest(enabled); break;
501 case GL_DEPTH_TEST: setDepthTest(enabled); break;
502 case GL_BLEND: setBlend(enabled); break;
503 case GL_DITHER: setDither(enabled); break;
Jamie Madillb4b53c52015-02-03 15:22:48 -0500504 case GL_PRIMITIVE_RESTART_FIXED_INDEX: setPrimitiveRestart(enabled); break;
Shannon Woods53a94a82014-06-24 15:20:36 -0400505 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
506 default: UNREACHABLE();
507 }
508}
509
510bool State::getEnableFeature(GLenum feature)
511{
512 switch (feature)
513 {
514 case GL_CULL_FACE: return isCullFaceEnabled();
515 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
516 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
517 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
518 case GL_SCISSOR_TEST: return isScissorTestEnabled();
519 case GL_STENCIL_TEST: return isStencilTestEnabled();
520 case GL_DEPTH_TEST: return isDepthTestEnabled();
521 case GL_BLEND: return isBlendEnabled();
522 case GL_DITHER: return isDitherEnabled();
Jamie Madillb4b53c52015-02-03 15:22:48 -0500523 case GL_PRIMITIVE_RESTART_FIXED_INDEX: return isPrimitiveRestartEnabled();
Shannon Woods53a94a82014-06-24 15:20:36 -0400524 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
525 default: UNREACHABLE(); return false;
526 }
527}
528
529void State::setLineWidth(GLfloat width)
530{
531 mLineWidth = width;
532}
533
Geoff Lang4b3f4162015-04-16 13:22:05 -0400534float State::getLineWidth() const
535{
536 return mLineWidth;
537}
538
Shannon Woods53a94a82014-06-24 15:20:36 -0400539void State::setGenerateMipmapHint(GLenum hint)
540{
541 mGenerateMipmapHint = hint;
542}
543
544void State::setFragmentShaderDerivativeHint(GLenum hint)
545{
546 mFragmentShaderDerivativeHint = hint;
547 // TODO: Propagate the hint to shader translator so we can write
548 // ddx, ddx_coarse, or ddx_fine depending on the hint.
549 // Ignore for now. It is valid for implementations to ignore hint.
550}
551
552void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
553{
554 mViewport.x = x;
555 mViewport.y = y;
556 mViewport.width = width;
557 mViewport.height = height;
558}
559
560const Rectangle &State::getViewport() const
561{
562 return mViewport;
563}
564
565void State::setActiveSampler(unsigned int active)
566{
567 mActiveSampler = active;
568}
569
570unsigned int State::getActiveSampler() const
571{
572 return mActiveSampler;
573}
574
Geoff Lang76b10c92014-09-05 16:28:14 -0400575void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400576{
Geoff Lang76b10c92014-09-05 16:28:14 -0400577 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400578}
579
Geoff Lang76b10c92014-09-05 16:28:14 -0400580Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400581{
Jamie Madill5864ac22015-01-12 14:43:07 -0500582 const auto it = mSamplerTextures.find(type);
583 ASSERT(it != mSamplerTextures.end());
584 return it->second[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400585}
586
Geoff Lang76b10c92014-09-05 16:28:14 -0400587GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400588{
Jamie Madill5864ac22015-01-12 14:43:07 -0500589 const auto it = mSamplerTextures.find(type);
590 ASSERT(it != mSamplerTextures.end());
591 return it->second[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400592}
593
Jamie Madille6382c32014-11-07 15:05:26 -0500594void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400595{
596 // Textures have a detach method on State rather than a simple
597 // removeBinding, because the zero/null texture objects are managed
598 // separately, and don't have to go through the Context's maps or
599 // the ResourceManager.
600
601 // [OpenGL ES 2.0.24] section 3.8 page 84:
602 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
603 // rebound to texture object zero
604
Geoff Lang76b10c92014-09-05 16:28:14 -0400605 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400606 {
Jamie Madille6382c32014-11-07 15:05:26 -0500607 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400608 TextureBindingVector &textureVector = bindingVec->second;
609 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400610 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400611 BindingPointer<Texture> &binding = textureVector[textureIdx];
612 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400613 {
Jamie Madill5864ac22015-01-12 14:43:07 -0500614 auto it = zeroTextures.find(textureType);
615 ASSERT(it != zeroTextures.end());
Jamie Madille6382c32014-11-07 15:05:26 -0500616 // Zero textures are the "default" textures instead of NULL
Jamie Madill5864ac22015-01-12 14:43:07 -0500617 binding.set(it->second.get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400618 }
619 }
620 }
621
622 // [OpenGL ES 2.0.24] section 4.4 page 112:
623 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
624 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
625 // image was attached in the currently bound framebuffer.
626
627 if (mReadFramebuffer)
628 {
629 mReadFramebuffer->detachTexture(texture);
630 }
631
632 if (mDrawFramebuffer)
633 {
634 mDrawFramebuffer->detachTexture(texture);
635 }
636}
637
Jamie Madille6382c32014-11-07 15:05:26 -0500638void State::initializeZeroTextures(const TextureMap &zeroTextures)
639{
640 for (const auto &zeroTexture : zeroTextures)
641 {
642 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
643
644 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
645 {
646 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
647 }
648 }
649}
650
Shannon Woods53a94a82014-06-24 15:20:36 -0400651void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
652{
653 mSamplers[textureUnit].set(sampler);
654}
655
656GLuint State::getSamplerId(GLuint textureUnit) const
657{
Geoff Lang76b10c92014-09-05 16:28:14 -0400658 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400659 return mSamplers[textureUnit].id();
660}
661
662Sampler *State::getSampler(GLuint textureUnit) const
663{
664 return mSamplers[textureUnit].get();
665}
666
667void State::detachSampler(GLuint sampler)
668{
669 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
670 // If a sampler object that is currently bound to one or more texture units is
671 // deleted, it is as though BindSampler is called once for each texture unit to
672 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400673 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400674 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400675 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
676 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400677 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400678 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400679 }
680 }
681}
682
683void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
684{
685 mRenderbuffer.set(renderbuffer);
686}
687
688GLuint State::getRenderbufferId() const
689{
690 return mRenderbuffer.id();
691}
692
693Renderbuffer *State::getCurrentRenderbuffer()
694{
695 return mRenderbuffer.get();
696}
697
698void State::detachRenderbuffer(GLuint renderbuffer)
699{
700 // [OpenGL ES 2.0.24] section 4.4 page 109:
701 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
702 // had been executed with the target RENDERBUFFER and name of zero.
703
704 if (mRenderbuffer.id() == renderbuffer)
705 {
706 mRenderbuffer.set(NULL);
707 }
708
709 // [OpenGL ES 2.0.24] section 4.4 page 111:
710 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
711 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
712 // point to which this image was attached in the currently bound framebuffer.
713
714 Framebuffer *readFramebuffer = mReadFramebuffer;
715 Framebuffer *drawFramebuffer = mDrawFramebuffer;
716
717 if (readFramebuffer)
718 {
719 readFramebuffer->detachRenderbuffer(renderbuffer);
720 }
721
722 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
723 {
724 drawFramebuffer->detachRenderbuffer(renderbuffer);
725 }
726
727}
728
729void State::setReadFramebufferBinding(Framebuffer *framebuffer)
730{
731 mReadFramebuffer = framebuffer;
732}
733
734void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
735{
736 mDrawFramebuffer = framebuffer;
737}
738
739Framebuffer *State::getTargetFramebuffer(GLenum target) const
740{
741 switch (target)
742 {
743 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
744 case GL_DRAW_FRAMEBUFFER_ANGLE:
745 case GL_FRAMEBUFFER: return mDrawFramebuffer;
746 default: UNREACHABLE(); return NULL;
747 }
748}
749
750Framebuffer *State::getReadFramebuffer()
751{
752 return mReadFramebuffer;
753}
754
755Framebuffer *State::getDrawFramebuffer()
756{
757 return mDrawFramebuffer;
758}
759
760const Framebuffer *State::getReadFramebuffer() const
761{
762 return mReadFramebuffer;
763}
764
765const Framebuffer *State::getDrawFramebuffer() const
766{
767 return mDrawFramebuffer;
768}
769
770bool State::removeReadFramebufferBinding(GLuint framebuffer)
771{
Jamie Madill77a72f62015-04-14 11:18:32 -0400772 if (mReadFramebuffer != nullptr &&
773 mReadFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400774 {
775 mReadFramebuffer = NULL;
776 return true;
777 }
778
779 return false;
780}
781
782bool State::removeDrawFramebufferBinding(GLuint framebuffer)
783{
Jamie Madill77a72f62015-04-14 11:18:32 -0400784 if (mReadFramebuffer != nullptr &&
785 mDrawFramebuffer->id() == framebuffer)
Shannon Woods53a94a82014-06-24 15:20:36 -0400786 {
787 mDrawFramebuffer = NULL;
788 return true;
789 }
790
791 return false;
792}
793
794void State::setVertexArrayBinding(VertexArray *vertexArray)
795{
796 mVertexArray = vertexArray;
797}
798
799GLuint State::getVertexArrayId() const
800{
801 ASSERT(mVertexArray != NULL);
802 return mVertexArray->id();
803}
804
805VertexArray *State::getVertexArray() const
806{
807 ASSERT(mVertexArray != NULL);
808 return mVertexArray;
809}
810
811bool State::removeVertexArrayBinding(GLuint vertexArray)
812{
813 if (mVertexArray->id() == vertexArray)
814 {
815 mVertexArray = NULL;
816 return true;
817 }
818
819 return false;
820}
821
Geoff Lang7dd2e102014-11-10 15:19:26 -0500822void State::setProgram(Program *newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400823{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500824 if (mProgram != newProgram)
Shannon Woods53a94a82014-06-24 15:20:36 -0400825 {
Geoff Lang7dd2e102014-11-10 15:19:26 -0500826 if (mProgram)
827 {
828 mProgram->release();
829 }
830
831 mProgram = newProgram;
832
833 if (mProgram)
834 {
835 newProgram->addRef();
836 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400837 }
838}
839
Geoff Lang7dd2e102014-11-10 15:19:26 -0500840Program *State::getProgram() const
Shannon Woods53a94a82014-06-24 15:20:36 -0400841{
Geoff Lang7dd2e102014-11-10 15:19:26 -0500842 return mProgram;
Shannon Woods53a94a82014-06-24 15:20:36 -0400843}
844
845void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
846{
847 mTransformFeedback.set(transformFeedback);
848}
849
850TransformFeedback *State::getCurrentTransformFeedback() const
851{
852 return mTransformFeedback.get();
853}
854
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000855bool State::isTransformFeedbackActiveUnpaused() const
856{
857 gl::TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
Geoff Langbb0a0bb2015-03-27 12:16:57 -0400858 return curTransformFeedback && curTransformFeedback->isActive() && !curTransformFeedback->isPaused();
Gregoire Payen de La Garanderie52742022015-02-04 14:55:39 +0000859}
860
Shannon Woods53a94a82014-06-24 15:20:36 -0400861void State::detachTransformFeedback(GLuint transformFeedback)
862{
863 if (mTransformFeedback.id() == transformFeedback)
864 {
865 mTransformFeedback.set(NULL);
866 }
867}
868
869bool State::isQueryActive() const
870{
871 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
872 i != mActiveQueries.end(); i++)
873 {
874 if (i->second.get() != NULL)
875 {
876 return true;
877 }
878 }
879
880 return false;
881}
882
883void State::setActiveQuery(GLenum target, Query *query)
884{
885 mActiveQueries[target].set(query);
886}
887
888GLuint State::getActiveQueryId(GLenum target) const
889{
890 const Query *query = getActiveQuery(target);
891 return (query ? query->id() : 0u);
892}
893
894Query *State::getActiveQuery(GLenum target) const
895{
Jamie Madill5864ac22015-01-12 14:43:07 -0500896 const auto it = mActiveQueries.find(target);
Shannon Woods53a94a82014-06-24 15:20:36 -0400897
Jamie Madill5864ac22015-01-12 14:43:07 -0500898 // All query types should already exist in the activeQueries map
899 ASSERT(it != mActiveQueries.end());
900
901 return it->second.get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400902}
903
904void State::setArrayBufferBinding(Buffer *buffer)
905{
906 mArrayBuffer.set(buffer);
907}
908
909GLuint State::getArrayBufferId() const
910{
911 return mArrayBuffer.id();
912}
913
914bool State::removeArrayBufferBinding(GLuint buffer)
915{
916 if (mArrayBuffer.id() == buffer)
917 {
918 mArrayBuffer.set(NULL);
919 return true;
920 }
921
922 return false;
923}
924
925void State::setGenericUniformBufferBinding(Buffer *buffer)
926{
927 mGenericUniformBuffer.set(buffer);
928}
929
930void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
931{
932 mUniformBuffers[index].set(buffer, offset, size);
933}
934
935GLuint State::getIndexedUniformBufferId(GLuint index) const
936{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400937 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400938
939 return mUniformBuffers[index].id();
940}
941
942Buffer *State::getIndexedUniformBuffer(GLuint index) const
943{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400944 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400945
946 return mUniformBuffers[index].get();
947}
948
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +0000949GLintptr State::getIndexedUniformBufferOffset(GLuint index) const
950{
951 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
952
953 return mUniformBuffers[index].getOffset();
954}
955
956GLsizeiptr State::getIndexedUniformBufferSize(GLuint index) const
957{
958 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
959
960 return mUniformBuffers[index].getSize();
961}
962
Shannon Woods53a94a82014-06-24 15:20:36 -0400963void State::setCopyReadBufferBinding(Buffer *buffer)
964{
965 mCopyReadBuffer.set(buffer);
966}
967
968void State::setCopyWriteBufferBinding(Buffer *buffer)
969{
970 mCopyWriteBuffer.set(buffer);
971}
972
973void State::setPixelPackBufferBinding(Buffer *buffer)
974{
975 mPack.pixelBuffer.set(buffer);
976}
977
978void State::setPixelUnpackBufferBinding(Buffer *buffer)
979{
980 mUnpack.pixelBuffer.set(buffer);
981}
982
983Buffer *State::getTargetBuffer(GLenum target) const
984{
985 switch (target)
986 {
987 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
988 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
989 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
990 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
991 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
992 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
Geoff Lang045536b2015-03-27 15:17:18 -0400993 case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400994 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
995 default: UNREACHABLE(); return NULL;
996 }
997}
998
999void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1000{
1001 getVertexArray()->enableAttribute(attribNum, enabled);
1002}
1003
1004void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1005{
Shannon Woods23e05002014-09-22 19:07:27 -04001006 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001007 mVertexAttribCurrentValues[index].setFloatValues(values);
1008}
1009
1010void State::setVertexAttribu(GLuint index, const GLuint values[4])
1011{
Shannon Woods23e05002014-09-22 19:07:27 -04001012 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001013 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1014}
1015
1016void State::setVertexAttribi(GLuint index, const GLint values[4])
1017{
Shannon Woods23e05002014-09-22 19:07:27 -04001018 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001019 mVertexAttribCurrentValues[index].setIntValues(values);
1020}
1021
1022void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1023 bool pureInteger, GLsizei stride, const void *pointer)
1024{
1025 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1026}
1027
Shannon Woods53a94a82014-06-24 15:20:36 -04001028const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1029{
Shannon Woods23e05002014-09-22 19:07:27 -04001030 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001031 return mVertexAttribCurrentValues[attribNum];
1032}
1033
Shannon Woods53a94a82014-06-24 15:20:36 -04001034const void *State::getVertexAttribPointer(unsigned int attribNum) const
1035{
1036 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1037}
1038
1039void State::setPackAlignment(GLint alignment)
1040{
1041 mPack.alignment = alignment;
1042}
1043
1044GLint State::getPackAlignment() const
1045{
1046 return mPack.alignment;
1047}
1048
1049void State::setPackReverseRowOrder(bool reverseRowOrder)
1050{
1051 mPack.reverseRowOrder = reverseRowOrder;
1052}
1053
1054bool State::getPackReverseRowOrder() const
1055{
1056 return mPack.reverseRowOrder;
1057}
1058
1059const PixelPackState &State::getPackState() const
1060{
1061 return mPack;
1062}
1063
Jamie Madill87de3622015-03-16 10:41:44 -04001064PixelPackState &State::getPackState()
1065{
1066 return mPack;
1067}
1068
Shannon Woods53a94a82014-06-24 15:20:36 -04001069void State::setUnpackAlignment(GLint alignment)
1070{
1071 mUnpack.alignment = alignment;
1072}
1073
1074GLint State::getUnpackAlignment() const
1075{
1076 return mUnpack.alignment;
1077}
1078
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001079void State::setUnpackRowLength(GLint rowLength)
1080{
1081 mUnpack.rowLength = rowLength;
1082}
1083
1084GLint State::getUnpackRowLength() const
1085{
1086 return mUnpack.rowLength;
1087}
1088
Shannon Woods53a94a82014-06-24 15:20:36 -04001089const PixelUnpackState &State::getUnpackState() const
1090{
1091 return mUnpack;
1092}
1093
Jamie Madill67102f02015-03-16 10:41:42 -04001094PixelUnpackState &State::getUnpackState()
1095{
1096 return mUnpack;
1097}
1098
Shannon Woods53a94a82014-06-24 15:20:36 -04001099void State::getBooleanv(GLenum pname, GLboolean *params)
1100{
1101 switch (pname)
1102 {
1103 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1104 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1105 case GL_COLOR_WRITEMASK:
1106 params[0] = mBlend.colorMaskRed;
1107 params[1] = mBlend.colorMaskGreen;
1108 params[2] = mBlend.colorMaskBlue;
1109 params[3] = mBlend.colorMaskAlpha;
1110 break;
1111 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1112 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1113 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1114 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1115 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1116 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1117 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1118 case GL_BLEND: *params = mBlend.blend; break;
1119 case GL_DITHER: *params = mBlend.dither; break;
Geoff Langbb0a0bb2015-03-27 12:16:57 -04001120 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isActive() ? GL_TRUE : GL_FALSE; break;
1121 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused() ? GL_TRUE : GL_FALSE; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001122 default:
1123 UNREACHABLE();
1124 break;
1125 }
1126}
1127
1128void State::getFloatv(GLenum pname, GLfloat *params)
1129{
1130 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1131 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1132 // GetIntegerv as its native query function. As it would require conversion in any
1133 // case, this should make no difference to the calling application.
1134 switch (pname)
1135 {
1136 case GL_LINE_WIDTH: *params = mLineWidth; break;
1137 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1138 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1139 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1140 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1141 case GL_DEPTH_RANGE:
1142 params[0] = mNearZ;
1143 params[1] = mFarZ;
1144 break;
1145 case GL_COLOR_CLEAR_VALUE:
1146 params[0] = mColorClearValue.red;
1147 params[1] = mColorClearValue.green;
1148 params[2] = mColorClearValue.blue;
1149 params[3] = mColorClearValue.alpha;
1150 break;
1151 case GL_BLEND_COLOR:
1152 params[0] = mBlendColor.red;
1153 params[1] = mBlendColor.green;
1154 params[2] = mBlendColor.blue;
1155 params[3] = mBlendColor.alpha;
1156 break;
1157 default:
1158 UNREACHABLE();
1159 break;
1160 }
1161}
1162
Jamie Madill48faf802014-11-06 15:27:22 -05001163void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001164{
1165 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1166 {
1167 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001168 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001169 Framebuffer *framebuffer = mDrawFramebuffer;
1170 *params = framebuffer->getDrawBufferState(colorAttachment);
1171 return;
1172 }
1173
1174 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1175 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1176 // GetIntegerv as its native query function. As it would require conversion in any
1177 // case, this should make no difference to the calling application. You may find it in
1178 // State::getFloatv.
1179 switch (pname)
1180 {
1181 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1182 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1183 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1184 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1185 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1186 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1187 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
Geoff Lang7dd2e102014-11-10 15:19:26 -05001188 case GL_CURRENT_PROGRAM: *params = mProgram ? mProgram->id() : 0; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001189 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1190 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1191 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
Minmin Gongb8aee3b2015-01-27 14:42:36 -08001192 case GL_UNPACK_ROW_LENGTH: *params = mUnpack.rowLength; break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001193 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1194 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1195 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1196 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1197 case GL_STENCIL_REF: *params = mStencilRef; break;
1198 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1199 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1200 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1201 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1202 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1203 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1204 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1205 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1206 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1207 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1208 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1209 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1210 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1211 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1212 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1213 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1214 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1215 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1216 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1217 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
Geoff Langbce529e2014-12-01 12:48:41 -05001218 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = mReadFramebuffer->getImplementationColorReadType(); break;
1219 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = mReadFramebuffer->getImplementationColorReadFormat(); break;
Shannon Woods53a94a82014-06-24 15:20:36 -04001220 case GL_SAMPLE_BUFFERS:
1221 case GL_SAMPLES:
1222 {
1223 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Geoff Lang748f74e2014-12-01 11:25:34 -05001224 if (framebuffer->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001225 {
1226 switch (pname)
1227 {
1228 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001229 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001230 {
1231 *params = 1;
1232 }
1233 else
1234 {
1235 *params = 0;
1236 }
1237 break;
1238 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001239 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001240 break;
1241 }
1242 }
1243 else
1244 {
1245 *params = 0;
1246 }
1247 }
1248 break;
1249 case GL_VIEWPORT:
1250 params[0] = mViewport.x;
1251 params[1] = mViewport.y;
1252 params[2] = mViewport.width;
1253 params[3] = mViewport.height;
1254 break;
1255 case GL_SCISSOR_BOX:
1256 params[0] = mScissor.x;
1257 params[1] = mScissor.y;
1258 params[2] = mScissor.width;
1259 params[3] = mScissor.height;
1260 break;
1261 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1262 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1263 case GL_RED_BITS:
1264 case GL_GREEN_BITS:
1265 case GL_BLUE_BITS:
1266 case GL_ALPHA_BITS:
1267 {
1268 gl::Framebuffer *framebuffer = getDrawFramebuffer();
Jamie Madillb6bda4a2015-04-20 12:53:26 -04001269 const gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001270
1271 if (colorbuffer)
1272 {
1273 switch (pname)
1274 {
1275 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1276 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1277 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1278 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1279 }
1280 }
1281 else
1282 {
1283 *params = 0;
1284 }
1285 }
1286 break;
1287 case GL_DEPTH_BITS:
1288 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001289 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1290 const gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001291
1292 if (depthbuffer)
1293 {
1294 *params = depthbuffer->getDepthSize();
1295 }
1296 else
1297 {
1298 *params = 0;
1299 }
1300 }
1301 break;
1302 case GL_STENCIL_BITS:
1303 {
Jamie Madille3ef7152015-04-28 16:55:17 +00001304 const gl::Framebuffer *framebuffer = getDrawFramebuffer();
1305 const gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
Shannon Woods53a94a82014-06-24 15:20:36 -04001306
1307 if (stencilbuffer)
1308 {
1309 *params = stencilbuffer->getStencilSize();
1310 }
1311 else
1312 {
1313 *params = 0;
1314 }
1315 }
1316 break;
1317 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001318 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001319 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D) ;
Shannon Woods53a94a82014-06-24 15:20:36 -04001320 break;
1321 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001322 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001323 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_CUBE_MAP);
Shannon Woods53a94a82014-06-24 15:20:36 -04001324 break;
1325 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001326 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001327 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_3D);
Shannon Woods53a94a82014-06-24 15:20:36 -04001328 break;
1329 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001330 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Jamie Madill5864ac22015-01-12 14:43:07 -05001331 *params = getSamplerTextureId(mActiveSampler, GL_TEXTURE_2D_ARRAY);
Shannon Woods53a94a82014-06-24 15:20:36 -04001332 break;
1333 case GL_UNIFORM_BUFFER_BINDING:
1334 *params = mGenericUniformBuffer.id();
1335 break;
1336 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001337 *params = mTransformFeedback->getGenericBuffer().id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001338 break;
1339 case GL_COPY_READ_BUFFER_BINDING:
1340 *params = mCopyReadBuffer.id();
1341 break;
1342 case GL_COPY_WRITE_BUFFER_BINDING:
1343 *params = mCopyWriteBuffer.id();
1344 break;
1345 case GL_PIXEL_PACK_BUFFER_BINDING:
1346 *params = mPack.pixelBuffer.id();
1347 break;
1348 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1349 *params = mUnpack.pixelBuffer.id();
1350 break;
1351 default:
1352 UNREACHABLE();
1353 break;
1354 }
1355}
1356
1357bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1358{
1359 switch (target)
1360 {
1361 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Geoff Lang045536b2015-03-27 15:17:18 -04001362 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001363 {
Geoff Lang045536b2015-03-27 15:17:18 -04001364 *data = mTransformFeedback->getIndexedBuffer(index).id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001365 }
1366 break;
1367 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001368 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001369 {
1370 *data = mUniformBuffers[index].id();
1371 }
1372 break;
1373 default:
1374 return false;
1375 }
1376
1377 return true;
1378}
1379
1380bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1381{
1382 switch (target)
1383 {
1384 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Geoff Lang045536b2015-03-27 15:17:18 -04001385 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001386 {
Geoff Lang045536b2015-03-27 15:17:18 -04001387 *data = mTransformFeedback->getIndexedBuffer(index).getOffset();
Shannon Woods53a94a82014-06-24 15:20:36 -04001388 }
1389 break;
1390 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Geoff Lang045536b2015-03-27 15:17:18 -04001391 if (static_cast<size_t>(index) < mTransformFeedback->getIndexedBufferCount())
Shannon Woods53a94a82014-06-24 15:20:36 -04001392 {
Geoff Lang045536b2015-03-27 15:17:18 -04001393 *data = mTransformFeedback->getIndexedBuffer(index).getSize();
Shannon Woods53a94a82014-06-24 15:20:36 -04001394 }
1395 break;
1396 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001397 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001398 {
1399 *data = mUniformBuffers[index].getOffset();
1400 }
1401 break;
1402 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001403 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001404 {
1405 *data = mUniformBuffers[index].getSize();
1406 }
1407 break;
1408 default:
1409 return false;
1410 }
1411
1412 return true;
1413}
1414
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001415bool State::hasMappedBuffer(GLenum target) const
1416{
1417 if (target == GL_ARRAY_BUFFER)
1418 {
Geoff Lang5ead9272015-03-25 12:27:43 -04001419 const VertexArray *vao = getVertexArray();
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001420 const auto &vertexAttribs = vao->getVertexAttributes();
Jamie Madillaebf9dd2015-04-28 12:39:07 -04001421 unsigned int maxEnabledAttrib = vao->getMaxEnabledAttribute();
1422 for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001423 {
Jamie Madilleea3a6e2015-04-15 10:02:48 -04001424 const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001425 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1426 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1427 {
1428 return true;
1429 }
1430 }
1431
1432 return false;
1433 }
1434 else
1435 {
1436 Buffer *buffer = getTargetBuffer(target);
1437 return (buffer && buffer->isMapped());
1438 }
1439}
1440
Shannon Woods53a94a82014-06-24 15:20:36 -04001441}