blob: fa3bbd6e174db3c8b3e05b2d90fd2d4e3799c671 [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
9#include "libGLESv2/State.h"
10
11#include "libGLESv2/Context.h"
Geoff Lang76b10c92014-09-05 16:28:14 -040012#include "libGLESv2/Caps.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040013#include "libGLESv2/Framebuffer.h"
14#include "libGLESv2/FramebufferAttachment.h"
Jamie Madill1e9ae072014-11-06 15:27:21 -050015#include "libGLESv2/Query.h"
16#include "libGLESv2/VertexArray.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040017#include "libGLESv2/formatutils.h"
Jamie Madill1e9ae072014-11-06 15:27:21 -050018#include "libGLESv2/renderer/RenderTarget.h"
Shannon Woods53a94a82014-06-24 15:20:36 -040019
20namespace gl
21{
Geoff Lang76b10c92014-09-05 16:28:14 -040022
Shannon Woods53a94a82014-06-24 15:20:36 -040023State::State()
24{
Shannon Woods2df6a602014-09-26 16:12:07 -040025 mMaxDrawBuffers = 0;
26 mMaxCombinedTextureImageUnits = 0;
Geoff Lang76b10c92014-09-05 16:28:14 -040027}
28
29State::~State()
30{
31 reset();
32}
33
34void State::initialize(const Caps& caps, GLuint clientVersion)
35{
Shannon Woods2df6a602014-09-26 16:12:07 -040036 mMaxDrawBuffers = caps.maxDrawBuffers;
37 mMaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits;
Shannon Woods53a94a82014-06-24 15:20:36 -040038
39 setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
40
41 mDepthClearValue = 1.0f;
42 mStencilClearValue = 0;
43
44 mRasterizer.rasterizerDiscard = false;
45 mRasterizer.cullFace = false;
46 mRasterizer.cullMode = GL_BACK;
47 mRasterizer.frontFace = GL_CCW;
48 mRasterizer.polygonOffsetFill = false;
49 mRasterizer.polygonOffsetFactor = 0.0f;
50 mRasterizer.polygonOffsetUnits = 0.0f;
51 mRasterizer.pointDrawMode = false;
52 mRasterizer.multiSample = false;
53 mScissorTest = false;
54 mScissor.x = 0;
55 mScissor.y = 0;
56 mScissor.width = 0;
57 mScissor.height = 0;
58
59 mBlend.blend = false;
60 mBlend.sourceBlendRGB = GL_ONE;
61 mBlend.sourceBlendAlpha = GL_ONE;
62 mBlend.destBlendRGB = GL_ZERO;
63 mBlend.destBlendAlpha = GL_ZERO;
64 mBlend.blendEquationRGB = GL_FUNC_ADD;
65 mBlend.blendEquationAlpha = GL_FUNC_ADD;
66 mBlend.sampleAlphaToCoverage = false;
67 mBlend.dither = true;
68
69 mBlendColor.red = 0;
70 mBlendColor.green = 0;
71 mBlendColor.blue = 0;
72 mBlendColor.alpha = 0;
73
74 mDepthStencil.depthTest = false;
75 mDepthStencil.depthFunc = GL_LESS;
76 mDepthStencil.depthMask = true;
77 mDepthStencil.stencilTest = false;
78 mDepthStencil.stencilFunc = GL_ALWAYS;
79 mDepthStencil.stencilMask = -1;
80 mDepthStencil.stencilWritemask = -1;
81 mDepthStencil.stencilBackFunc = GL_ALWAYS;
Geoff Lang76b10c92014-09-05 16:28:14 -040082 mDepthStencil.stencilBackMask = -1;
Shannon Woods53a94a82014-06-24 15:20:36 -040083 mDepthStencil.stencilBackWritemask = -1;
84 mDepthStencil.stencilFail = GL_KEEP;
85 mDepthStencil.stencilPassDepthFail = GL_KEEP;
86 mDepthStencil.stencilPassDepthPass = GL_KEEP;
87 mDepthStencil.stencilBackFail = GL_KEEP;
88 mDepthStencil.stencilBackPassDepthFail = GL_KEEP;
89 mDepthStencil.stencilBackPassDepthPass = GL_KEEP;
90
91 mStencilRef = 0;
92 mStencilBackRef = 0;
93
94 mSampleCoverage = false;
95 mSampleCoverageValue = 1.0f;
96 mSampleCoverageInvert = false;
97 mGenerateMipmapHint = GL_DONT_CARE;
98 mFragmentShaderDerivativeHint = GL_DONT_CARE;
99
100 mLineWidth = 1.0f;
101
102 mViewport.x = 0;
103 mViewport.y = 0;
104 mViewport.width = 0;
105 mViewport.height = 0;
106 mNearZ = 0.0f;
107 mFarZ = 1.0f;
108
109 mBlend.colorMaskRed = true;
110 mBlend.colorMaskGreen = true;
111 mBlend.colorMaskBlue = true;
112 mBlend.colorMaskAlpha = true;
113
Geoff Lang76b10c92014-09-05 16:28:14 -0400114 mActiveSampler = 0;
115
Shannon Woods53a94a82014-06-24 15:20:36 -0400116 const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
Shannon Woods23e05002014-09-22 19:07:27 -0400117 mVertexAttribCurrentValues.resize(caps.maxVertexAttributes);
118 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); ++attribIndex)
Shannon Woods53a94a82014-06-24 15:20:36 -0400119 {
120 mVertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
121 }
122
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400123 mUniformBuffers.resize(caps.maxCombinedUniformBlocks);
Shannon Woods8299bb02014-09-26 18:55:43 -0400124 mTransformFeedbackBuffers.resize(caps.maxTransformFeedbackSeparateAttributes);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400125
Geoff Lang76b10c92014-09-05 16:28:14 -0400126 mSamplerTextures[GL_TEXTURE_2D].resize(caps.maxCombinedTextureImageUnits);
127 mSamplerTextures[GL_TEXTURE_CUBE_MAP].resize(caps.maxCombinedTextureImageUnits);
128 if (clientVersion >= 3)
Shannon Woods53a94a82014-06-24 15:20:36 -0400129 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400130 // TODO: These could also be enabled via extension
131 mSamplerTextures[GL_TEXTURE_2D_ARRAY].resize(caps.maxCombinedTextureImageUnits);
132 mSamplerTextures[GL_TEXTURE_3D].resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400133 }
134
Geoff Lang76b10c92014-09-05 16:28:14 -0400135 mSamplers.resize(caps.maxCombinedTextureImageUnits);
Shannon Woods53a94a82014-06-24 15:20:36 -0400136
137 mActiveQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
138 mActiveQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
139 mActiveQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
140
141 mCurrentProgramId = 0;
142 mCurrentProgramBinary.set(NULL);
143
144 mReadFramebuffer = NULL;
145 mDrawFramebuffer = NULL;
146}
147
Geoff Lang76b10c92014-09-05 16:28:14 -0400148void State::reset()
Shannon Woods53a94a82014-06-24 15:20:36 -0400149{
Geoff Lang76b10c92014-09-05 16:28:14 -0400150 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400151 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400152 TextureBindingVector &textureVector = bindingVec->second;
153 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400154 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400155 textureVector[textureIdx].set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400156 }
157 }
Geoff Lang76b10c92014-09-05 16:28:14 -0400158 for (size_t samplerIdx = 0; samplerIdx < mSamplers.size(); samplerIdx++)
159 {
160 mSamplers[samplerIdx].set(NULL);
161 }
Shannon Woods53a94a82014-06-24 15:20:36 -0400162
Shannon Woods53a94a82014-06-24 15:20:36 -0400163 mArrayBuffer.set(NULL);
164 mRenderbuffer.set(NULL);
165
166 mTransformFeedback.set(NULL);
167
168 for (State::ActiveQueryMap::iterator i = mActiveQueries.begin(); i != mActiveQueries.end(); i++)
169 {
170 i->second.set(NULL);
171 }
172
173 mGenericUniformBuffer.set(NULL);
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400174 mGenericTransformFeedbackBuffer.set(NULL);
Shannon Woods8299bb02014-09-26 18:55:43 -0400175 for (BufferVector::iterator bufItr = mUniformBuffers.begin(); bufItr != mUniformBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400176 {
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400177 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400178 }
179
Shannon Woods8299bb02014-09-26 18:55:43 -0400180 for (BufferVector::iterator bufItr = mTransformFeedbackBuffers.begin(); bufItr != mTransformFeedbackBuffers.end(); ++bufItr)
Shannon Woods53a94a82014-06-24 15:20:36 -0400181 {
Shannon Woods8299bb02014-09-26 18:55:43 -0400182 bufItr->set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400183 }
184
185 mCopyReadBuffer.set(NULL);
186 mCopyWriteBuffer.set(NULL);
187
188 mPack.pixelBuffer.set(NULL);
189 mUnpack.pixelBuffer.set(NULL);
190}
191
192const RasterizerState &State::getRasterizerState() const
193{
194 return mRasterizer;
195}
196
197const BlendState &State::getBlendState() const
198{
199 return mBlend;
200}
201
202const DepthStencilState &State::getDepthStencilState() const
203{
204 return mDepthStencil;
205}
206
207void State::setClearColor(float red, float green, float blue, float alpha)
208{
209 mColorClearValue.red = red;
210 mColorClearValue.green = green;
211 mColorClearValue.blue = blue;
212 mColorClearValue.alpha = alpha;
213}
214
215void State::setClearDepth(float depth)
216{
217 mDepthClearValue = depth;
218}
219
220void State::setClearStencil(int stencil)
221{
222 mStencilClearValue = stencil;
223}
224
225ClearParameters State::getClearParameters(GLbitfield mask) const
226{
227 ClearParameters clearParams = { 0 };
228 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
229 {
230 clearParams.clearColor[i] = false;
231 }
232 clearParams.colorFClearValue = mColorClearValue;
233 clearParams.colorClearType = GL_FLOAT;
234 clearParams.colorMaskRed = mBlend.colorMaskRed;
235 clearParams.colorMaskGreen = mBlend.colorMaskGreen;
236 clearParams.colorMaskBlue = mBlend.colorMaskBlue;
237 clearParams.colorMaskAlpha = mBlend.colorMaskAlpha;
238 clearParams.clearDepth = false;
239 clearParams.depthClearValue = mDepthClearValue;
240 clearParams.clearStencil = false;
241 clearParams.stencilClearValue = mStencilClearValue;
242 clearParams.stencilWriteMask = mDepthStencil.stencilWritemask;
243 clearParams.scissorEnabled = mScissorTest;
244 clearParams.scissor = mScissor;
245
246 const Framebuffer *framebufferObject = getDrawFramebuffer();
247 if (mask & GL_COLOR_BUFFER_BIT)
248 {
249 if (framebufferObject->hasEnabledColorAttachment())
250 {
251 for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
252 {
253 clearParams.clearColor[i] = true;
254 }
255 }
256 }
257
258 if (mask & GL_DEPTH_BUFFER_BIT)
259 {
260 if (mDepthStencil.depthMask && framebufferObject->getDepthbuffer() != NULL)
261 {
262 clearParams.clearDepth = true;
263 }
264 }
265
266 if (mask & GL_STENCIL_BUFFER_BIT)
267 {
268 if (framebufferObject->getStencilbuffer() != NULL)
269 {
Jamie Madilldd8488d2014-09-03 15:07:21 -0400270 GLenum stencilActualFormat = framebufferObject->getStencilbuffer()->getActualFormat();
271 if (GetInternalFormatInfo(stencilActualFormat).stencilBits > 0)
Shannon Woods53a94a82014-06-24 15:20:36 -0400272 {
273 clearParams.clearStencil = true;
274 }
275 }
276 }
277
278 return clearParams;
279}
280
281void State::setColorMask(bool red, bool green, bool blue, bool alpha)
282{
283 mBlend.colorMaskRed = red;
284 mBlend.colorMaskGreen = green;
285 mBlend.colorMaskBlue = blue;
286 mBlend.colorMaskAlpha = alpha;
287}
288
289void State::setDepthMask(bool mask)
290{
291 mDepthStencil.depthMask = mask;
292}
293
294bool State::isRasterizerDiscardEnabled() const
295{
296 return mRasterizer.rasterizerDiscard;
297}
298
299void State::setRasterizerDiscard(bool enabled)
300{
301 mRasterizer.rasterizerDiscard = enabled;
302}
303
304bool State::isCullFaceEnabled() const
305{
306 return mRasterizer.cullFace;
307}
308
309void State::setCullFace(bool enabled)
310{
311 mRasterizer.cullFace = enabled;
312}
313
314void State::setCullMode(GLenum mode)
315{
316 mRasterizer.cullMode = mode;
317}
318
319void State::setFrontFace(GLenum front)
320{
321 mRasterizer.frontFace = front;
322}
323
324bool State::isDepthTestEnabled() const
325{
326 return mDepthStencil.depthTest;
327}
328
329void State::setDepthTest(bool enabled)
330{
331 mDepthStencil.depthTest = enabled;
332}
333
334void State::setDepthFunc(GLenum depthFunc)
335{
336 mDepthStencil.depthFunc = depthFunc;
337}
338
339void State::setDepthRange(float zNear, float zFar)
340{
341 mNearZ = zNear;
342 mFarZ = zFar;
343}
344
345void State::getDepthRange(float *zNear, float *zFar) const
346{
347 *zNear = mNearZ;
348 *zFar = mFarZ;
349}
350
351bool State::isBlendEnabled() const
352{
353 return mBlend.blend;
354}
355
356void State::setBlend(bool enabled)
357{
358 mBlend.blend = enabled;
359}
360
361void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
362{
363 mBlend.sourceBlendRGB = sourceRGB;
364 mBlend.destBlendRGB = destRGB;
365 mBlend.sourceBlendAlpha = sourceAlpha;
366 mBlend.destBlendAlpha = destAlpha;
367}
368
369void State::setBlendColor(float red, float green, float blue, float alpha)
370{
371 mBlendColor.red = red;
372 mBlendColor.green = green;
373 mBlendColor.blue = blue;
374 mBlendColor.alpha = alpha;
375}
376
377void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
378{
379 mBlend.blendEquationRGB = rgbEquation;
380 mBlend.blendEquationAlpha = alphaEquation;
381}
382
383const ColorF &State::getBlendColor() const
384{
385 return mBlendColor;
386}
387
388bool State::isStencilTestEnabled() const
389{
390 return mDepthStencil.stencilTest;
391}
392
393void State::setStencilTest(bool enabled)
394{
395 mDepthStencil.stencilTest = enabled;
396}
397
398void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
399{
400 mDepthStencil.stencilFunc = stencilFunc;
401 mStencilRef = (stencilRef > 0) ? stencilRef : 0;
402 mDepthStencil.stencilMask = stencilMask;
403}
404
405void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
406{
407 mDepthStencil.stencilBackFunc = stencilBackFunc;
408 mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
409 mDepthStencil.stencilBackMask = stencilBackMask;
410}
411
412void State::setStencilWritemask(GLuint stencilWritemask)
413{
414 mDepthStencil.stencilWritemask = stencilWritemask;
415}
416
417void State::setStencilBackWritemask(GLuint stencilBackWritemask)
418{
419 mDepthStencil.stencilBackWritemask = stencilBackWritemask;
420}
421
422void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
423{
424 mDepthStencil.stencilFail = stencilFail;
425 mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
426 mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
427}
428
429void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
430{
431 mDepthStencil.stencilBackFail = stencilBackFail;
432 mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
433 mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
434}
435
436GLint State::getStencilRef() const
437{
438 return mStencilRef;
439}
440
441GLint State::getStencilBackRef() const
442{
443 return mStencilBackRef;
444}
445
446bool State::isPolygonOffsetFillEnabled() const
447{
448 return mRasterizer.polygonOffsetFill;
449}
450
451void State::setPolygonOffsetFill(bool enabled)
452{
453 mRasterizer.polygonOffsetFill = enabled;
454}
455
456void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
457{
458 // An application can pass NaN values here, so handle this gracefully
459 mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
460 mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
461}
462
463bool State::isSampleAlphaToCoverageEnabled() const
464{
465 return mBlend.sampleAlphaToCoverage;
466}
467
468void State::setSampleAlphaToCoverage(bool enabled)
469{
470 mBlend.sampleAlphaToCoverage = enabled;
471}
472
473bool State::isSampleCoverageEnabled() const
474{
475 return mSampleCoverage;
476}
477
478void State::setSampleCoverage(bool enabled)
479{
480 mSampleCoverage = enabled;
481}
482
483void State::setSampleCoverageParams(GLclampf value, bool invert)
484{
485 mSampleCoverageValue = value;
486 mSampleCoverageInvert = invert;
487}
488
489void State::getSampleCoverageParams(GLclampf *value, bool *invert)
490{
491 ASSERT(value != NULL && invert != NULL);
492
493 *value = mSampleCoverageValue;
494 *invert = mSampleCoverageInvert;
495}
496
497bool State::isScissorTestEnabled() const
498{
499 return mScissorTest;
500}
501
502void State::setScissorTest(bool enabled)
503{
504 mScissorTest = enabled;
505}
506
507void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
508{
509 mScissor.x = x;
510 mScissor.y = y;
511 mScissor.width = width;
512 mScissor.height = height;
513}
514
515const Rectangle &State::getScissor() const
516{
517 return mScissor;
518}
519
520bool State::isDitherEnabled() const
521{
522 return mBlend.dither;
523}
524
525void State::setDither(bool enabled)
526{
527 mBlend.dither = enabled;
528}
529
530void State::setEnableFeature(GLenum feature, bool enabled)
531{
532 switch (feature)
533 {
534 case GL_CULL_FACE: setCullFace(enabled); break;
535 case GL_POLYGON_OFFSET_FILL: setPolygonOffsetFill(enabled); break;
536 case GL_SAMPLE_ALPHA_TO_COVERAGE: setSampleAlphaToCoverage(enabled); break;
537 case GL_SAMPLE_COVERAGE: setSampleCoverage(enabled); break;
538 case GL_SCISSOR_TEST: setScissorTest(enabled); break;
539 case GL_STENCIL_TEST: setStencilTest(enabled); break;
540 case GL_DEPTH_TEST: setDepthTest(enabled); break;
541 case GL_BLEND: setBlend(enabled); break;
542 case GL_DITHER: setDither(enabled); break;
543 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); break;
544 case GL_RASTERIZER_DISCARD: setRasterizerDiscard(enabled); break;
545 default: UNREACHABLE();
546 }
547}
548
549bool State::getEnableFeature(GLenum feature)
550{
551 switch (feature)
552 {
553 case GL_CULL_FACE: return isCullFaceEnabled();
554 case GL_POLYGON_OFFSET_FILL: return isPolygonOffsetFillEnabled();
555 case GL_SAMPLE_ALPHA_TO_COVERAGE: return isSampleAlphaToCoverageEnabled();
556 case GL_SAMPLE_COVERAGE: return isSampleCoverageEnabled();
557 case GL_SCISSOR_TEST: return isScissorTestEnabled();
558 case GL_STENCIL_TEST: return isStencilTestEnabled();
559 case GL_DEPTH_TEST: return isDepthTestEnabled();
560 case GL_BLEND: return isBlendEnabled();
561 case GL_DITHER: return isDitherEnabled();
562 case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
563 case GL_RASTERIZER_DISCARD: return isRasterizerDiscardEnabled();
564 default: UNREACHABLE(); return false;
565 }
566}
567
568void State::setLineWidth(GLfloat width)
569{
570 mLineWidth = width;
571}
572
573void State::setGenerateMipmapHint(GLenum hint)
574{
575 mGenerateMipmapHint = hint;
576}
577
578void State::setFragmentShaderDerivativeHint(GLenum hint)
579{
580 mFragmentShaderDerivativeHint = hint;
581 // TODO: Propagate the hint to shader translator so we can write
582 // ddx, ddx_coarse, or ddx_fine depending on the hint.
583 // Ignore for now. It is valid for implementations to ignore hint.
584}
585
586void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
587{
588 mViewport.x = x;
589 mViewport.y = y;
590 mViewport.width = width;
591 mViewport.height = height;
592}
593
594const Rectangle &State::getViewport() const
595{
596 return mViewport;
597}
598
599void State::setActiveSampler(unsigned int active)
600{
601 mActiveSampler = active;
602}
603
604unsigned int State::getActiveSampler() const
605{
606 return mActiveSampler;
607}
608
Geoff Lang76b10c92014-09-05 16:28:14 -0400609void State::setSamplerTexture(GLenum type, Texture *texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400610{
Geoff Lang76b10c92014-09-05 16:28:14 -0400611 mSamplerTextures[type][mActiveSampler].set(texture);
Shannon Woods53a94a82014-06-24 15:20:36 -0400612}
613
Geoff Lang76b10c92014-09-05 16:28:14 -0400614Texture *State::getSamplerTexture(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400615{
Jamie Madilldedd7b92014-11-05 16:30:36 -0500616 return mSamplerTextures.at(type)[sampler].get();
Shannon Woods53a94a82014-06-24 15:20:36 -0400617}
618
Geoff Lang76b10c92014-09-05 16:28:14 -0400619GLuint State::getSamplerTextureId(unsigned int sampler, GLenum type) const
Shannon Woods53a94a82014-06-24 15:20:36 -0400620{
Geoff Lang76b10c92014-09-05 16:28:14 -0400621 return mSamplerTextures.at(type)[sampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -0400622}
623
Jamie Madille6382c32014-11-07 15:05:26 -0500624void State::detachTexture(const TextureMap &zeroTextures, GLuint texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400625{
626 // Textures have a detach method on State rather than a simple
627 // removeBinding, because the zero/null texture objects are managed
628 // separately, and don't have to go through the Context's maps or
629 // the ResourceManager.
630
631 // [OpenGL ES 2.0.24] section 3.8 page 84:
632 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
633 // rebound to texture object zero
634
Geoff Lang76b10c92014-09-05 16:28:14 -0400635 for (TextureBindingMap::iterator bindingVec = mSamplerTextures.begin(); bindingVec != mSamplerTextures.end(); bindingVec++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400636 {
Jamie Madille6382c32014-11-07 15:05:26 -0500637 GLenum textureType = bindingVec->first;
Geoff Lang76b10c92014-09-05 16:28:14 -0400638 TextureBindingVector &textureVector = bindingVec->second;
639 for (size_t textureIdx = 0; textureIdx < textureVector.size(); textureIdx++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400640 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400641 BindingPointer<Texture> &binding = textureVector[textureIdx];
642 if (binding.id() == texture)
Shannon Woods53a94a82014-06-24 15:20:36 -0400643 {
Jamie Madille6382c32014-11-07 15:05:26 -0500644 // Zero textures are the "default" textures instead of NULL
645 binding.set(zeroTextures.at(textureType).get());
Shannon Woods53a94a82014-06-24 15:20:36 -0400646 }
647 }
648 }
649
650 // [OpenGL ES 2.0.24] section 4.4 page 112:
651 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
652 // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
653 // image was attached in the currently bound framebuffer.
654
655 if (mReadFramebuffer)
656 {
657 mReadFramebuffer->detachTexture(texture);
658 }
659
660 if (mDrawFramebuffer)
661 {
662 mDrawFramebuffer->detachTexture(texture);
663 }
664}
665
Jamie Madille6382c32014-11-07 15:05:26 -0500666void State::initializeZeroTextures(const TextureMap &zeroTextures)
667{
668 for (const auto &zeroTexture : zeroTextures)
669 {
670 auto &samplerTextureArray = mSamplerTextures[zeroTexture.first];
671
672 for (size_t textureUnit = 0; textureUnit < samplerTextureArray.size(); ++textureUnit)
673 {
674 samplerTextureArray[textureUnit].set(zeroTexture.second.get());
675 }
676 }
677}
678
Shannon Woods53a94a82014-06-24 15:20:36 -0400679void State::setSamplerBinding(GLuint textureUnit, Sampler *sampler)
680{
681 mSamplers[textureUnit].set(sampler);
682}
683
684GLuint State::getSamplerId(GLuint textureUnit) const
685{
Geoff Lang76b10c92014-09-05 16:28:14 -0400686 ASSERT(textureUnit < mSamplers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400687 return mSamplers[textureUnit].id();
688}
689
690Sampler *State::getSampler(GLuint textureUnit) const
691{
692 return mSamplers[textureUnit].get();
693}
694
695void State::detachSampler(GLuint sampler)
696{
697 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
698 // If a sampler object that is currently bound to one or more texture units is
699 // deleted, it is as though BindSampler is called once for each texture unit to
700 // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
Geoff Lang76b10c92014-09-05 16:28:14 -0400701 for (size_t textureUnit = 0; textureUnit < mSamplers.size(); textureUnit++)
Shannon Woods53a94a82014-06-24 15:20:36 -0400702 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400703 BindingPointer<Sampler> &samplerBinding = mSamplers[textureUnit];
704 if (samplerBinding.id() == sampler)
Shannon Woods53a94a82014-06-24 15:20:36 -0400705 {
Geoff Lang76b10c92014-09-05 16:28:14 -0400706 samplerBinding.set(NULL);
Shannon Woods53a94a82014-06-24 15:20:36 -0400707 }
708 }
709}
710
711void State::setRenderbufferBinding(Renderbuffer *renderbuffer)
712{
713 mRenderbuffer.set(renderbuffer);
714}
715
716GLuint State::getRenderbufferId() const
717{
718 return mRenderbuffer.id();
719}
720
721Renderbuffer *State::getCurrentRenderbuffer()
722{
723 return mRenderbuffer.get();
724}
725
726void State::detachRenderbuffer(GLuint renderbuffer)
727{
728 // [OpenGL ES 2.0.24] section 4.4 page 109:
729 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
730 // had been executed with the target RENDERBUFFER and name of zero.
731
732 if (mRenderbuffer.id() == renderbuffer)
733 {
734 mRenderbuffer.set(NULL);
735 }
736
737 // [OpenGL ES 2.0.24] section 4.4 page 111:
738 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
739 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
740 // point to which this image was attached in the currently bound framebuffer.
741
742 Framebuffer *readFramebuffer = mReadFramebuffer;
743 Framebuffer *drawFramebuffer = mDrawFramebuffer;
744
745 if (readFramebuffer)
746 {
747 readFramebuffer->detachRenderbuffer(renderbuffer);
748 }
749
750 if (drawFramebuffer && drawFramebuffer != readFramebuffer)
751 {
752 drawFramebuffer->detachRenderbuffer(renderbuffer);
753 }
754
755}
756
757void State::setReadFramebufferBinding(Framebuffer *framebuffer)
758{
759 mReadFramebuffer = framebuffer;
760}
761
762void State::setDrawFramebufferBinding(Framebuffer *framebuffer)
763{
764 mDrawFramebuffer = framebuffer;
765}
766
767Framebuffer *State::getTargetFramebuffer(GLenum target) const
768{
769 switch (target)
770 {
771 case GL_READ_FRAMEBUFFER_ANGLE: return mReadFramebuffer;
772 case GL_DRAW_FRAMEBUFFER_ANGLE:
773 case GL_FRAMEBUFFER: return mDrawFramebuffer;
774 default: UNREACHABLE(); return NULL;
775 }
776}
777
778Framebuffer *State::getReadFramebuffer()
779{
780 return mReadFramebuffer;
781}
782
783Framebuffer *State::getDrawFramebuffer()
784{
785 return mDrawFramebuffer;
786}
787
788const Framebuffer *State::getReadFramebuffer() const
789{
790 return mReadFramebuffer;
791}
792
793const Framebuffer *State::getDrawFramebuffer() const
794{
795 return mDrawFramebuffer;
796}
797
798bool State::removeReadFramebufferBinding(GLuint framebuffer)
799{
800 if (mReadFramebuffer->id() == framebuffer)
801 {
802 mReadFramebuffer = NULL;
803 return true;
804 }
805
806 return false;
807}
808
809bool State::removeDrawFramebufferBinding(GLuint framebuffer)
810{
811 if (mDrawFramebuffer->id() == framebuffer)
812 {
813 mDrawFramebuffer = NULL;
814 return true;
815 }
816
817 return false;
818}
819
820void State::setVertexArrayBinding(VertexArray *vertexArray)
821{
822 mVertexArray = vertexArray;
823}
824
825GLuint State::getVertexArrayId() const
826{
827 ASSERT(mVertexArray != NULL);
828 return mVertexArray->id();
829}
830
831VertexArray *State::getVertexArray() const
832{
833 ASSERT(mVertexArray != NULL);
834 return mVertexArray;
835}
836
837bool State::removeVertexArrayBinding(GLuint vertexArray)
838{
839 if (mVertexArray->id() == vertexArray)
840 {
841 mVertexArray = NULL;
842 return true;
843 }
844
845 return false;
846}
847
848void State::setCurrentProgram(GLuint programId, Program *newProgram)
849{
850 mCurrentProgramId = programId; // set new ID before trying to delete program binary; otherwise it will only be flagged for deletion
851 mCurrentProgramBinary.set(NULL);
852
853 if (newProgram)
854 {
855 newProgram->addRef();
856 mCurrentProgramBinary.set(newProgram->getProgramBinary());
857 }
858}
859
860void State::setCurrentProgramBinary(ProgramBinary *binary)
861{
862 mCurrentProgramBinary.set(binary);
863}
864
865GLuint State::getCurrentProgramId() const
866{
867 return mCurrentProgramId;
868}
869
870ProgramBinary *State::getCurrentProgramBinary() const
871{
872 return mCurrentProgramBinary.get();
873}
874
875void State::setTransformFeedbackBinding(TransformFeedback *transformFeedback)
876{
877 mTransformFeedback.set(transformFeedback);
878}
879
880TransformFeedback *State::getCurrentTransformFeedback() const
881{
882 return mTransformFeedback.get();
883}
884
885void State::detachTransformFeedback(GLuint transformFeedback)
886{
887 if (mTransformFeedback.id() == transformFeedback)
888 {
889 mTransformFeedback.set(NULL);
890 }
891}
892
893bool State::isQueryActive() const
894{
895 for (State::ActiveQueryMap::const_iterator i = mActiveQueries.begin();
896 i != mActiveQueries.end(); i++)
897 {
898 if (i->second.get() != NULL)
899 {
900 return true;
901 }
902 }
903
904 return false;
905}
906
907void State::setActiveQuery(GLenum target, Query *query)
908{
909 mActiveQueries[target].set(query);
910}
911
912GLuint State::getActiveQueryId(GLenum target) const
913{
914 const Query *query = getActiveQuery(target);
915 return (query ? query->id() : 0u);
916}
917
918Query *State::getActiveQuery(GLenum target) const
919{
920 // All query types should already exist in the activeQueries map
921 ASSERT(mActiveQueries.find(target) != mActiveQueries.end());
922
923 return mActiveQueries.at(target).get();
924}
925
926void State::setArrayBufferBinding(Buffer *buffer)
927{
928 mArrayBuffer.set(buffer);
929}
930
931GLuint State::getArrayBufferId() const
932{
933 return mArrayBuffer.id();
934}
935
936bool State::removeArrayBufferBinding(GLuint buffer)
937{
938 if (mArrayBuffer.id() == buffer)
939 {
940 mArrayBuffer.set(NULL);
941 return true;
942 }
943
944 return false;
945}
946
947void State::setGenericUniformBufferBinding(Buffer *buffer)
948{
949 mGenericUniformBuffer.set(buffer);
950}
951
952void State::setIndexedUniformBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
953{
954 mUniformBuffers[index].set(buffer, offset, size);
955}
956
957GLuint State::getIndexedUniformBufferId(GLuint index) const
958{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400959 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400960
961 return mUniformBuffers[index].id();
962}
963
964Buffer *State::getIndexedUniformBuffer(GLuint index) const
965{
Shannon Woodsf3acaf92014-09-23 18:07:11 -0400966 ASSERT(static_cast<size_t>(index) < mUniformBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400967
968 return mUniformBuffers[index].get();
969}
970
971void State::setGenericTransformFeedbackBufferBinding(Buffer *buffer)
972{
973 mGenericTransformFeedbackBuffer.set(buffer);
974}
975
976void State::setIndexedTransformFeedbackBufferBinding(GLuint index, Buffer *buffer, GLintptr offset, GLsizeiptr size)
977{
978 mTransformFeedbackBuffers[index].set(buffer, offset, size);
979}
980
981GLuint State::getIndexedTransformFeedbackBufferId(GLuint index) const
982{
Shannon Woods8299bb02014-09-26 18:55:43 -0400983 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400984
985 return mTransformFeedbackBuffers[index].id();
986}
987
988Buffer *State::getIndexedTransformFeedbackBuffer(GLuint index) const
989{
Shannon Woods8299bb02014-09-26 18:55:43 -0400990 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400991
992 return mTransformFeedbackBuffers[index].get();
993}
994
995GLuint State::getIndexedTransformFeedbackBufferOffset(GLuint index) const
996{
Shannon Woods8299bb02014-09-26 18:55:43 -0400997 ASSERT(static_cast<size_t>(index) < mTransformFeedbackBuffers.size());
Shannon Woods53a94a82014-06-24 15:20:36 -0400998
999 return mTransformFeedbackBuffers[index].getOffset();
1000}
1001
Shannon Woods8299bb02014-09-26 18:55:43 -04001002size_t State::getTransformFeedbackBufferIndexRange() const
1003{
1004 return mTransformFeedbackBuffers.size();
1005}
1006
Shannon Woods53a94a82014-06-24 15:20:36 -04001007void State::setCopyReadBufferBinding(Buffer *buffer)
1008{
1009 mCopyReadBuffer.set(buffer);
1010}
1011
1012void State::setCopyWriteBufferBinding(Buffer *buffer)
1013{
1014 mCopyWriteBuffer.set(buffer);
1015}
1016
1017void State::setPixelPackBufferBinding(Buffer *buffer)
1018{
1019 mPack.pixelBuffer.set(buffer);
1020}
1021
1022void State::setPixelUnpackBufferBinding(Buffer *buffer)
1023{
1024 mUnpack.pixelBuffer.set(buffer);
1025}
1026
1027Buffer *State::getTargetBuffer(GLenum target) const
1028{
1029 switch (target)
1030 {
1031 case GL_ARRAY_BUFFER: return mArrayBuffer.get();
1032 case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
1033 case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
1034 case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
1035 case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
1036 case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
1037 case GL_TRANSFORM_FEEDBACK_BUFFER: return mGenericTransformFeedbackBuffer.get();
1038 case GL_UNIFORM_BUFFER: return mGenericUniformBuffer.get();
1039 default: UNREACHABLE(); return NULL;
1040 }
1041}
1042
1043void State::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
1044{
1045 getVertexArray()->enableAttribute(attribNum, enabled);
1046}
1047
1048void State::setVertexAttribf(GLuint index, const GLfloat values[4])
1049{
Shannon Woods23e05002014-09-22 19:07:27 -04001050 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001051 mVertexAttribCurrentValues[index].setFloatValues(values);
1052}
1053
1054void State::setVertexAttribu(GLuint index, const GLuint values[4])
1055{
Shannon Woods23e05002014-09-22 19:07:27 -04001056 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001057 mVertexAttribCurrentValues[index].setUnsignedIntValues(values);
1058}
1059
1060void State::setVertexAttribi(GLuint index, const GLint values[4])
1061{
Shannon Woods23e05002014-09-22 19:07:27 -04001062 ASSERT(static_cast<size_t>(index) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001063 mVertexAttribCurrentValues[index].setIntValues(values);
1064}
1065
1066void State::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
1067 bool pureInteger, GLsizei stride, const void *pointer)
1068{
1069 getVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
1070}
1071
1072const VertexAttribute &State::getVertexAttribState(unsigned int attribNum) const
1073{
1074 return getVertexArray()->getVertexAttribute(attribNum);
1075}
1076
1077const VertexAttribCurrentValueData &State::getVertexAttribCurrentValue(unsigned int attribNum) const
1078{
Shannon Woods23e05002014-09-22 19:07:27 -04001079 ASSERT(static_cast<size_t>(attribNum) < mVertexAttribCurrentValues.size());
Shannon Woods53a94a82014-06-24 15:20:36 -04001080 return mVertexAttribCurrentValues[attribNum];
1081}
1082
Shannon Woods53a94a82014-06-24 15:20:36 -04001083const void *State::getVertexAttribPointer(unsigned int attribNum) const
1084{
1085 return getVertexArray()->getVertexAttribute(attribNum).pointer;
1086}
1087
1088void State::setPackAlignment(GLint alignment)
1089{
1090 mPack.alignment = alignment;
1091}
1092
1093GLint State::getPackAlignment() const
1094{
1095 return mPack.alignment;
1096}
1097
1098void State::setPackReverseRowOrder(bool reverseRowOrder)
1099{
1100 mPack.reverseRowOrder = reverseRowOrder;
1101}
1102
1103bool State::getPackReverseRowOrder() const
1104{
1105 return mPack.reverseRowOrder;
1106}
1107
1108const PixelPackState &State::getPackState() const
1109{
1110 return mPack;
1111}
1112
1113void State::setUnpackAlignment(GLint alignment)
1114{
1115 mUnpack.alignment = alignment;
1116}
1117
1118GLint State::getUnpackAlignment() const
1119{
1120 return mUnpack.alignment;
1121}
1122
1123const PixelUnpackState &State::getUnpackState() const
1124{
1125 return mUnpack;
1126}
1127
1128void State::getBooleanv(GLenum pname, GLboolean *params)
1129{
1130 switch (pname)
1131 {
1132 case GL_SAMPLE_COVERAGE_INVERT: *params = mSampleCoverageInvert; break;
1133 case GL_DEPTH_WRITEMASK: *params = mDepthStencil.depthMask; break;
1134 case GL_COLOR_WRITEMASK:
1135 params[0] = mBlend.colorMaskRed;
1136 params[1] = mBlend.colorMaskGreen;
1137 params[2] = mBlend.colorMaskBlue;
1138 params[3] = mBlend.colorMaskAlpha;
1139 break;
1140 case GL_CULL_FACE: *params = mRasterizer.cullFace; break;
1141 case GL_POLYGON_OFFSET_FILL: *params = mRasterizer.polygonOffsetFill; break;
1142 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mBlend.sampleAlphaToCoverage; break;
1143 case GL_SAMPLE_COVERAGE: *params = mSampleCoverage; break;
1144 case GL_SCISSOR_TEST: *params = mScissorTest; break;
1145 case GL_STENCIL_TEST: *params = mDepthStencil.stencilTest; break;
1146 case GL_DEPTH_TEST: *params = mDepthStencil.depthTest; break;
1147 case GL_BLEND: *params = mBlend.blend; break;
1148 case GL_DITHER: *params = mBlend.dither; break;
1149 case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1150 case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused(); break;
1151 default:
1152 UNREACHABLE();
1153 break;
1154 }
1155}
1156
1157void State::getFloatv(GLenum pname, GLfloat *params)
1158{
1159 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1160 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1161 // GetIntegerv as its native query function. As it would require conversion in any
1162 // case, this should make no difference to the calling application.
1163 switch (pname)
1164 {
1165 case GL_LINE_WIDTH: *params = mLineWidth; break;
1166 case GL_SAMPLE_COVERAGE_VALUE: *params = mSampleCoverageValue; break;
1167 case GL_DEPTH_CLEAR_VALUE: *params = mDepthClearValue; break;
1168 case GL_POLYGON_OFFSET_FACTOR: *params = mRasterizer.polygonOffsetFactor; break;
1169 case GL_POLYGON_OFFSET_UNITS: *params = mRasterizer.polygonOffsetUnits; break;
1170 case GL_DEPTH_RANGE:
1171 params[0] = mNearZ;
1172 params[1] = mFarZ;
1173 break;
1174 case GL_COLOR_CLEAR_VALUE:
1175 params[0] = mColorClearValue.red;
1176 params[1] = mColorClearValue.green;
1177 params[2] = mColorClearValue.blue;
1178 params[3] = mColorClearValue.alpha;
1179 break;
1180 case GL_BLEND_COLOR:
1181 params[0] = mBlendColor.red;
1182 params[1] = mBlendColor.green;
1183 params[2] = mBlendColor.blue;
1184 params[3] = mBlendColor.alpha;
1185 break;
1186 default:
1187 UNREACHABLE();
1188 break;
1189 }
1190}
1191
Jamie Madill48faf802014-11-06 15:27:22 -05001192void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
Shannon Woods53a94a82014-06-24 15:20:36 -04001193{
1194 if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1195 {
1196 unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
Shannon Woods2df6a602014-09-26 16:12:07 -04001197 ASSERT(colorAttachment < mMaxDrawBuffers);
Shannon Woods53a94a82014-06-24 15:20:36 -04001198 Framebuffer *framebuffer = mDrawFramebuffer;
1199 *params = framebuffer->getDrawBufferState(colorAttachment);
1200 return;
1201 }
1202
1203 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1204 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1205 // GetIntegerv as its native query function. As it would require conversion in any
1206 // case, this should make no difference to the calling application. You may find it in
1207 // State::getFloatv.
1208 switch (pname)
1209 {
1210 case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
1211 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
1212 //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1213 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
1214 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
1215 case GL_RENDERBUFFER_BINDING: *params = mRenderbuffer.id(); break;
1216 case GL_VERTEX_ARRAY_BINDING: *params = mVertexArray->id(); break;
1217 case GL_CURRENT_PROGRAM: *params = mCurrentProgramId; break;
1218 case GL_PACK_ALIGNMENT: *params = mPack.alignment; break;
1219 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: *params = mPack.reverseRowOrder; break;
1220 case GL_UNPACK_ALIGNMENT: *params = mUnpack.alignment; break;
1221 case GL_GENERATE_MIPMAP_HINT: *params = mGenerateMipmapHint; break;
1222 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mFragmentShaderDerivativeHint; break;
1223 case GL_ACTIVE_TEXTURE: *params = (mActiveSampler + GL_TEXTURE0); break;
1224 case GL_STENCIL_FUNC: *params = mDepthStencil.stencilFunc; break;
1225 case GL_STENCIL_REF: *params = mStencilRef; break;
1226 case GL_STENCIL_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilMask); break;
1227 case GL_STENCIL_BACK_FUNC: *params = mDepthStencil.stencilBackFunc; break;
1228 case GL_STENCIL_BACK_REF: *params = mStencilBackRef; break;
1229 case GL_STENCIL_BACK_VALUE_MASK: *params = clampToInt(mDepthStencil.stencilBackMask); break;
1230 case GL_STENCIL_FAIL: *params = mDepthStencil.stencilFail; break;
1231 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilPassDepthFail; break;
1232 case GL_STENCIL_PASS_DEPTH_PASS: *params = mDepthStencil.stencilPassDepthPass; break;
1233 case GL_STENCIL_BACK_FAIL: *params = mDepthStencil.stencilBackFail; break;
1234 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mDepthStencil.stencilBackPassDepthFail; break;
1235 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mDepthStencil.stencilBackPassDepthPass; break;
1236 case GL_DEPTH_FUNC: *params = mDepthStencil.depthFunc; break;
1237 case GL_BLEND_SRC_RGB: *params = mBlend.sourceBlendRGB; break;
1238 case GL_BLEND_SRC_ALPHA: *params = mBlend.sourceBlendAlpha; break;
1239 case GL_BLEND_DST_RGB: *params = mBlend.destBlendRGB; break;
1240 case GL_BLEND_DST_ALPHA: *params = mBlend.destBlendAlpha; break;
1241 case GL_BLEND_EQUATION_RGB: *params = mBlend.blendEquationRGB; break;
1242 case GL_BLEND_EQUATION_ALPHA: *params = mBlend.blendEquationAlpha; break;
1243 case GL_STENCIL_WRITEMASK: *params = clampToInt(mDepthStencil.stencilWritemask); break;
1244 case GL_STENCIL_BACK_WRITEMASK: *params = clampToInt(mDepthStencil.stencilBackWritemask); break;
1245 case GL_STENCIL_CLEAR_VALUE: *params = mStencilClearValue; break;
1246 case GL_SAMPLE_BUFFERS:
1247 case GL_SAMPLES:
1248 {
1249 gl::Framebuffer *framebuffer = mDrawFramebuffer;
Jamie Madill48faf802014-11-06 15:27:22 -05001250 if (framebuffer->completeness(data) == GL_FRAMEBUFFER_COMPLETE)
Shannon Woods53a94a82014-06-24 15:20:36 -04001251 {
1252 switch (pname)
1253 {
1254 case GL_SAMPLE_BUFFERS:
Jamie Madill48faf802014-11-06 15:27:22 -05001255 if (framebuffer->getSamples(data) != 0)
Shannon Woods53a94a82014-06-24 15:20:36 -04001256 {
1257 *params = 1;
1258 }
1259 else
1260 {
1261 *params = 0;
1262 }
1263 break;
1264 case GL_SAMPLES:
Jamie Madill48faf802014-11-06 15:27:22 -05001265 *params = framebuffer->getSamples(data);
Shannon Woods53a94a82014-06-24 15:20:36 -04001266 break;
1267 }
1268 }
1269 else
1270 {
1271 *params = 0;
1272 }
1273 }
1274 break;
1275 case GL_VIEWPORT:
1276 params[0] = mViewport.x;
1277 params[1] = mViewport.y;
1278 params[2] = mViewport.width;
1279 params[3] = mViewport.height;
1280 break;
1281 case GL_SCISSOR_BOX:
1282 params[0] = mScissor.x;
1283 params[1] = mScissor.y;
1284 params[2] = mScissor.width;
1285 params[3] = mScissor.height;
1286 break;
1287 case GL_CULL_FACE_MODE: *params = mRasterizer.cullMode; break;
1288 case GL_FRONT_FACE: *params = mRasterizer.frontFace; break;
1289 case GL_RED_BITS:
1290 case GL_GREEN_BITS:
1291 case GL_BLUE_BITS:
1292 case GL_ALPHA_BITS:
1293 {
1294 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1295 gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1296
1297 if (colorbuffer)
1298 {
1299 switch (pname)
1300 {
1301 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break;
1302 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1303 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break;
1304 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1305 }
1306 }
1307 else
1308 {
1309 *params = 0;
1310 }
1311 }
1312 break;
1313 case GL_DEPTH_BITS:
1314 {
1315 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1316 gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1317
1318 if (depthbuffer)
1319 {
1320 *params = depthbuffer->getDepthSize();
1321 }
1322 else
1323 {
1324 *params = 0;
1325 }
1326 }
1327 break;
1328 case GL_STENCIL_BITS:
1329 {
1330 gl::Framebuffer *framebuffer = getDrawFramebuffer();
1331 gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1332
1333 if (stencilbuffer)
1334 {
1335 *params = stencilbuffer->getStencilSize();
1336 }
1337 else
1338 {
1339 *params = 0;
1340 }
1341 }
1342 break;
1343 case GL_TEXTURE_BINDING_2D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001344 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001345 *params = mSamplerTextures.at(GL_TEXTURE_2D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001346 break;
1347 case GL_TEXTURE_BINDING_CUBE_MAP:
Shannon Woods2df6a602014-09-26 16:12:07 -04001348 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001349 *params = mSamplerTextures.at(GL_TEXTURE_CUBE_MAP)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001350 break;
1351 case GL_TEXTURE_BINDING_3D:
Shannon Woods2df6a602014-09-26 16:12:07 -04001352 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001353 *params = mSamplerTextures.at(GL_TEXTURE_3D)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001354 break;
1355 case GL_TEXTURE_BINDING_2D_ARRAY:
Shannon Woods2df6a602014-09-26 16:12:07 -04001356 ASSERT(mActiveSampler < mMaxCombinedTextureImageUnits);
Geoff Lang76b10c92014-09-05 16:28:14 -04001357 *params = mSamplerTextures.at(GL_TEXTURE_2D_ARRAY)[mActiveSampler].id();
Shannon Woods53a94a82014-06-24 15:20:36 -04001358 break;
1359 case GL_UNIFORM_BUFFER_BINDING:
1360 *params = mGenericUniformBuffer.id();
1361 break;
1362 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1363 *params = mGenericTransformFeedbackBuffer.id();
1364 break;
1365 case GL_COPY_READ_BUFFER_BINDING:
1366 *params = mCopyReadBuffer.id();
1367 break;
1368 case GL_COPY_WRITE_BUFFER_BINDING:
1369 *params = mCopyWriteBuffer.id();
1370 break;
1371 case GL_PIXEL_PACK_BUFFER_BINDING:
1372 *params = mPack.pixelBuffer.id();
1373 break;
1374 case GL_PIXEL_UNPACK_BUFFER_BINDING:
1375 *params = mUnpack.pixelBuffer.id();
1376 break;
1377 default:
1378 UNREACHABLE();
1379 break;
1380 }
1381}
1382
1383bool State::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
1384{
1385 switch (target)
1386 {
1387 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
Shannon Woods8299bb02014-09-26 18:55:43 -04001388 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001389 {
1390 *data = mTransformFeedbackBuffers[index].id();
1391 }
1392 break;
1393 case GL_UNIFORM_BUFFER_BINDING:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001394 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001395 {
1396 *data = mUniformBuffers[index].id();
1397 }
1398 break;
1399 default:
1400 return false;
1401 }
1402
1403 return true;
1404}
1405
1406bool State::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
1407{
1408 switch (target)
1409 {
1410 case GL_TRANSFORM_FEEDBACK_BUFFER_START:
Shannon Woods8299bb02014-09-26 18:55:43 -04001411 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001412 {
1413 *data = mTransformFeedbackBuffers[index].getOffset();
1414 }
1415 break;
1416 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
Shannon Woods8299bb02014-09-26 18:55:43 -04001417 if (static_cast<size_t>(index) < mTransformFeedbackBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001418 {
1419 *data = mTransformFeedbackBuffers[index].getSize();
1420 }
1421 break;
1422 case GL_UNIFORM_BUFFER_START:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001423 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001424 {
1425 *data = mUniformBuffers[index].getOffset();
1426 }
1427 break;
1428 case GL_UNIFORM_BUFFER_SIZE:
Shannon Woodsf3acaf92014-09-23 18:07:11 -04001429 if (static_cast<size_t>(index) < mUniformBuffers.size())
Shannon Woods53a94a82014-06-24 15:20:36 -04001430 {
1431 *data = mUniformBuffers[index].getSize();
1432 }
1433 break;
1434 default:
1435 return false;
1436 }
1437
1438 return true;
1439}
1440
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001441bool State::hasMappedBuffer(GLenum target) const
1442{
1443 if (target == GL_ARRAY_BUFFER)
1444 {
Shannon Woods23e05002014-09-22 19:07:27 -04001445 for (size_t attribIndex = 0; attribIndex < mVertexAttribCurrentValues.size(); attribIndex++)
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001446 {
Shannon Woods23e05002014-09-22 19:07:27 -04001447 const gl::VertexAttribute &vertexAttrib = getVertexAttribState(static_cast<unsigned int>(attribIndex));
Jamie Madilld9ba4f72014-08-04 10:47:59 -04001448 gl::Buffer *boundBuffer = vertexAttrib.buffer.get();
1449 if (vertexAttrib.enabled && boundBuffer && boundBuffer->isMapped())
1450 {
1451 return true;
1452 }
1453 }
1454
1455 return false;
1456 }
1457 else
1458 {
1459 Buffer *buffer = getTargetBuffer(target);
1460 return (buffer && buffer->isMapped());
1461 }
1462}
1463
Shannon Woods53a94a82014-06-24 15:20:36 -04001464}