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