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