1#include "precompiled.h"
2//
3// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style license that can be
5// found in the LICENSE file.
6//
7
8// Context.cpp: Implements the gl::Context class, managing all GL state and performing
9// rendering operations. It is the GLES2 specific implementation of EGLContext.
10
11#include "libGLESv2/Context.h"
12
13#include "libGLESv2/main.h"
14#include "common/utilities.h"
15#include "libGLESv2/formatutils.h"
16#include "libGLESv2/Buffer.h"
17#include "libGLESv2/Fence.h"
18#include "libGLESv2/Framebuffer.h"
19#include "libGLESv2/Renderbuffer.h"
20#include "libGLESv2/Program.h"
21#include "libGLESv2/ProgramBinary.h"
22#include "libGLESv2/Query.h"
23#include "libGLESv2/Texture.h"
24#include "libGLESv2/ResourceManager.h"
25#include "libGLESv2/renderer/IndexDataManager.h"
26#include "libGLESv2/renderer/RenderTarget.h"
27#include "libGLESv2/renderer/Renderer.h"
28#include "libGLESv2/VertexArray.h"
29#include "libGLESv2/Sampler.h"
30#include "libGLESv2/validationES.h"
31#include "libGLESv2/TransformFeedback.h"
32
33#include "libEGL/Surface.h"
34
35#undef near
36#undef far
37
38namespace gl
39{
40static const char* makeStaticString(const std::string& str)
41{
42    static std::set<std::string> strings;
43    std::set<std::string>::iterator it = strings.find(str);
44    if (it != strings.end())
45      return it->c_str();
46
47    return strings.insert(str).first->c_str();
48}
49
50Context::Context(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess) : mRenderer(renderer)
51{
52    ASSERT(robustAccess == false);   // Unimplemented
53
54    mFenceNVHandleAllocator.setBaseHandle(0);
55
56    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
57
58    mClientVersion = clientVersion;
59
60    mState.depthClearValue = 1.0f;
61    mState.stencilClearValue = 0;
62
63    mState.rasterizer.rasterizerDiscard = false;
64    mState.rasterizer.cullFace = false;
65    mState.rasterizer.cullMode = GL_BACK;
66    mState.rasterizer.frontFace = GL_CCW;
67    mState.rasterizer.polygonOffsetFill = false;
68    mState.rasterizer.polygonOffsetFactor = 0.0f;
69    mState.rasterizer.polygonOffsetUnits = 0.0f;
70    mState.rasterizer.pointDrawMode = false;
71    mState.rasterizer.multiSample = false;
72    mState.scissorTest = false;
73    mState.scissor.x = 0;
74    mState.scissor.y = 0;
75    mState.scissor.width = 0;
76    mState.scissor.height = 0;
77
78    mState.blend.blend = false;
79    mState.blend.sourceBlendRGB = GL_ONE;
80    mState.blend.sourceBlendAlpha = GL_ONE;
81    mState.blend.destBlendRGB = GL_ZERO;
82    mState.blend.destBlendAlpha = GL_ZERO;
83    mState.blend.blendEquationRGB = GL_FUNC_ADD;
84    mState.blend.blendEquationAlpha = GL_FUNC_ADD;
85    mState.blend.sampleAlphaToCoverage = false;
86    mState.blend.dither = true;
87
88    mState.blendColor.red = 0;
89    mState.blendColor.green = 0;
90    mState.blendColor.blue = 0;
91    mState.blendColor.alpha = 0;
92
93    mState.depthStencil.depthTest = false;
94    mState.depthStencil.depthFunc = GL_LESS;
95    mState.depthStencil.depthMask = true;
96    mState.depthStencil.stencilTest = false;
97    mState.depthStencil.stencilFunc = GL_ALWAYS;
98    mState.depthStencil.stencilMask = -1;
99    mState.depthStencil.stencilWritemask = -1;
100    mState.depthStencil.stencilBackFunc = GL_ALWAYS;
101    mState.depthStencil.stencilBackMask = - 1;
102    mState.depthStencil.stencilBackWritemask = -1;
103    mState.depthStencil.stencilFail = GL_KEEP;
104    mState.depthStencil.stencilPassDepthFail = GL_KEEP;
105    mState.depthStencil.stencilPassDepthPass = GL_KEEP;
106    mState.depthStencil.stencilBackFail = GL_KEEP;
107    mState.depthStencil.stencilBackPassDepthFail = GL_KEEP;
108    mState.depthStencil.stencilBackPassDepthPass = GL_KEEP;
109
110    mState.stencilRef = 0;
111    mState.stencilBackRef = 0;
112
113    mState.sampleCoverage = false;
114    mState.sampleCoverageValue = 1.0f;
115    mState.sampleCoverageInvert = false;
116    mState.generateMipmapHint = GL_DONT_CARE;
117    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
118
119    mState.lineWidth = 1.0f;
120
121    mState.viewport.x = 0;
122    mState.viewport.y = 0;
123    mState.viewport.width = 0;
124    mState.viewport.height = 0;
125    mState.zNear = 0.0f;
126    mState.zFar = 1.0f;
127
128    mState.blend.colorMaskRed = true;
129    mState.blend.colorMaskGreen = true;
130    mState.blend.colorMaskBlue = true;
131    mState.blend.colorMaskAlpha = true;
132
133    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
134    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
135    {
136        mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
137    }
138
139    if (shareContext != NULL)
140    {
141        mResourceManager = shareContext->mResourceManager;
142        mResourceManager->addRef();
143    }
144    else
145    {
146        mResourceManager = new ResourceManager(mRenderer);
147    }
148
149    // [OpenGL ES 2.0.24] section 3.7 page 83:
150    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
151    // and cube map texture state vectors respectively associated with them.
152    // In order that access to these initial textures not be lost, they are treated as texture
153    // objects all of whose names are 0.
154
155    mTexture2DZero.set(new Texture2D(mRenderer, 0));
156    mTextureCubeMapZero.set(new TextureCubeMap(mRenderer, 0));
157    mTexture3DZero.set(new Texture3D(mRenderer, 0));
158    mTexture2DArrayZero.set(new Texture2DArray(mRenderer, 0));
159
160    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
161    {
162        mState.samplers[textureUnit] = 0;
163    }
164
165    mState.activeSampler = 0;
166    bindVertexArray(0);
167    bindArrayBuffer(0);
168    bindElementArrayBuffer(0);
169    bindTextureCubeMap(0);
170    bindTexture2D(0);
171    bindReadFramebuffer(0);
172    bindDrawFramebuffer(0);
173    bindRenderbuffer(0);
174
175    mState.activeQueries[GL_ANY_SAMPLES_PASSED].set(NULL);
176    mState.activeQueries[GL_ANY_SAMPLES_PASSED_CONSERVATIVE].set(NULL);
177    mState.activeQueries[GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN].set(NULL);
178
179    bindGenericUniformBuffer(0);
180    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
181    {
182        bindIndexedUniformBuffer(0, i, 0, -1);
183    }
184
185    bindGenericTransformFeedbackBuffer(0);
186    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
187    {
188        bindIndexedTransformFeedbackBuffer(0, i, 0, -1);
189    }
190
191    bindCopyReadBuffer(0);
192    bindCopyWriteBuffer(0);
193    bindPixelPackBuffer(0);
194    bindPixelUnpackBuffer(0);
195
196    // [OpenGL ES 3.0.2] section 2.14.1 pg 85:
197    // In the initial state, a default transform feedback object is bound and treated as
198    // a transform feedback object with a name of zero. That object is bound any time
199    // BindTransformFeedback is called with id of zero
200    mTransformFeedbackZero.set(new TransformFeedback(0));
201    bindTransformFeedback(0);
202
203    mState.currentProgram = 0;
204    mCurrentProgramBinary.set(NULL);
205
206    mCombinedExtensionsString = NULL;
207    mRendererString = NULL;
208
209    mInvalidEnum = false;
210    mInvalidValue = false;
211    mInvalidOperation = false;
212    mOutOfMemory = false;
213    mInvalidFramebufferOperation = false;
214
215    mHasBeenCurrent = false;
216    mContextLost = false;
217    mResetStatus = GL_NO_ERROR;
218    mResetStrategy = (notifyResets ? GL_LOSE_CONTEXT_ON_RESET_EXT : GL_NO_RESET_NOTIFICATION_EXT);
219    mRobustAccess = robustAccess;
220
221    mSupportsBGRATextures = false;
222    mSupportsDXT1Textures = false;
223    mSupportsDXT3Textures = false;
224    mSupportsDXT5Textures = false;
225    mSupportsEventQueries = false;
226    mSupportsOcclusionQueries = false;
227    mNumCompressedTextureFormats = 0;
228}
229
230Context::~Context()
231{
232    if (mState.currentProgram != 0)
233    {
234        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
235        if (programObject)
236        {
237            programObject->release();
238        }
239        mState.currentProgram = 0;
240    }
241    mCurrentProgramBinary.set(NULL);
242
243    while (!mFramebufferMap.empty())
244    {
245        deleteFramebuffer(mFramebufferMap.begin()->first);
246    }
247
248    while (!mFenceNVMap.empty())
249    {
250        deleteFenceNV(mFenceNVMap.begin()->first);
251    }
252
253    while (!mQueryMap.empty())
254    {
255        deleteQuery(mQueryMap.begin()->first);
256    }
257
258    while (!mVertexArrayMap.empty())
259    {
260        deleteVertexArray(mVertexArrayMap.begin()->first);
261    }
262
263    mTransformFeedbackZero.set(NULL);
264    while (!mTransformFeedbackMap.empty())
265    {
266        deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
267    }
268
269    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
270    {
271        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
272        {
273            mState.samplerTexture[type][sampler].set(NULL);
274        }
275    }
276
277    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
278    {
279        mIncompleteTextures[type].set(NULL);
280    }
281
282    const GLfloat defaultFloatValues[] = { 0.0f, 0.0f, 0.0f, 1.0f };
283    for (int attribIndex = 0; attribIndex < MAX_VERTEX_ATTRIBS; attribIndex++)
284    {
285        mState.vertexAttribCurrentValues[attribIndex].setFloatValues(defaultFloatValues);
286    }
287
288    mState.arrayBuffer.set(NULL);
289    mState.renderbuffer.set(NULL);
290
291    mState.transformFeedback.set(NULL);
292
293    mTexture2DZero.set(NULL);
294    mTextureCubeMapZero.set(NULL);
295    mTexture3DZero.set(NULL);
296    mTexture2DArrayZero.set(NULL);
297
298    for (State::ActiveQueryMap::iterator i = mState.activeQueries.begin(); i != mState.activeQueries.end(); i++)
299    {
300        i->second.set(NULL);
301    }
302
303    mState.genericUniformBuffer.set(NULL);
304    for (int i = 0; i < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; i++)
305    {
306        mState.uniformBuffers[i].set(NULL);
307    }
308
309    mState.genericTransformFeedbackBuffer.set(NULL);
310    for (int i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
311    {
312        mState.transformFeedbackBuffers[i].set(NULL);
313    }
314
315    mState.copyReadBuffer.set(NULL);
316    mState.copyWriteBuffer.set(NULL);
317
318    mState.pack.pixelBuffer.set(NULL);
319    mState.unpack.pixelBuffer.set(NULL);
320
321    mResourceManager->release();
322}
323
324void Context::makeCurrent(egl::Surface *surface)
325{
326    if (!mHasBeenCurrent)
327    {
328        mMajorShaderModel = mRenderer->getMajorShaderModel();
329        mMaximumPointSize = mRenderer->getMaxPointSize();
330        mSupportsVertexTexture = mRenderer->getVertexTextureSupport();
331        mSupportsNonPower2Texture = mRenderer->getNonPower2TextureSupport();
332        mSupportsInstancing = mRenderer->getInstancingSupport();
333
334        mMaxViewportDimension = mRenderer->getMaxViewportDimension();
335        mMax2DTextureDimension = std::min(std::min(mRenderer->getMaxTextureWidth(), mRenderer->getMaxTextureHeight()),
336                                          (int)gl::IMPLEMENTATION_MAX_2D_TEXTURE_SIZE);
337        mMaxCubeTextureDimension = std::min(mMax2DTextureDimension, (int)gl::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE);
338        mMax3DTextureDimension = std::min(std::min(mMax2DTextureDimension, mRenderer->getMaxTextureDepth()),
339                                          (int)gl::IMPLEMENTATION_MAX_3D_TEXTURE_SIZE);
340        mMax2DArrayTextureLayers = mRenderer->getMaxTextureArrayLayers();
341        mMaxRenderbufferDimension = mMax2DTextureDimension;
342        mMax2DTextureLevel = log2(mMax2DTextureDimension) + 1;
343        mMaxCubeTextureLevel = log2(mMaxCubeTextureDimension) + 1;
344        mMax3DTextureLevel = log2(mMax3DTextureDimension) + 1;
345        mMax2DArrayTextureLevel = log2(mMax2DTextureDimension) + 1;
346        mMaxTextureAnisotropy = mRenderer->getTextureMaxAnisotropy();
347        TRACE("Max2DTextureDimension=%d, MaxCubeTextureDimension=%d, Max3DTextureDimension=%d, Max2DArrayTextureLayers = %d, "
348              "Max2DTextureLevel=%d, MaxCubeTextureLevel=%d, Max3DTextureLevel=%d, Max2DArrayTextureLevel=%d, "
349              "MaxRenderbufferDimension=%d, MaxTextureAnisotropy=%f",
350              mMax2DTextureDimension, mMaxCubeTextureDimension, mMax3DTextureDimension, mMax2DArrayTextureLayers,
351              mMax2DTextureLevel, mMaxCubeTextureLevel, mMax3DTextureLevel, mMax2DArrayTextureLevel,
352              mMaxRenderbufferDimension, mMaxTextureAnisotropy);
353
354        mSupportsEventQueries = mRenderer->getEventQuerySupport();
355        mSupportsOcclusionQueries = mRenderer->getOcclusionQuerySupport();
356        mSupportsBGRATextures = mRenderer->getBGRATextureSupport();
357        mSupportsDXT1Textures = mRenderer->getDXT1TextureSupport();
358        mSupportsDXT3Textures = mRenderer->getDXT3TextureSupport();
359        mSupportsDXT5Textures = mRenderer->getDXT5TextureSupport();
360        mSupportsFloat32Textures = mRenderer->getFloat32TextureSupport();
361        mSupportsFloat32LinearFilter = mRenderer->getFloat32TextureFilteringSupport();
362        mSupportsFloat32RenderableTextures = mRenderer->getFloat32TextureRenderingSupport();
363        mSupportsFloat16Textures = mRenderer->getFloat16TextureSupport();
364        mSupportsFloat16LinearFilter = mRenderer->getFloat16TextureFilteringSupport();
365        mSupportsFloat16RenderableTextures = mRenderer->getFloat16TextureRenderingSupport();
366        mSupportsLuminanceTextures = mRenderer->getLuminanceTextureSupport();
367        mSupportsLuminanceAlphaTextures = mRenderer->getLuminanceAlphaTextureSupport();
368        mSupportsRGTextures = mRenderer->getRGTextureSupport();
369        mSupportsDepthTextures = mRenderer->getDepthTextureSupport();
370        mSupportsTextureFilterAnisotropy = mRenderer->getTextureFilterAnisotropySupport();
371        mSupports32bitIndices = mRenderer->get32BitIndexSupport();
372        mSupportsPBOs = mRenderer->getPBOSupport();
373
374        mNumCompressedTextureFormats = 0;
375        if (supportsDXT1Textures())
376        {
377            mNumCompressedTextureFormats += 2;
378        }
379        if (supportsDXT3Textures())
380        {
381            mNumCompressedTextureFormats += 1;
382        }
383        if (supportsDXT5Textures())
384        {
385            mNumCompressedTextureFormats += 1;
386        }
387
388        initExtensionString();
389        initRendererString();
390
391        mState.viewport.x = 0;
392        mState.viewport.y = 0;
393        mState.viewport.width = surface->getWidth();
394        mState.viewport.height = surface->getHeight();
395
396        mState.scissor.x = 0;
397        mState.scissor.y = 0;
398        mState.scissor.width = surface->getWidth();
399        mState.scissor.height = surface->getHeight();
400
401        mHasBeenCurrent = true;
402    }
403
404    // Wrap the existing swapchain resources into GL objects and assign them to the '0' names
405    rx::SwapChain *swapchain = surface->getSwapChain();
406
407    Colorbuffer *colorbufferZero = new Colorbuffer(mRenderer, swapchain);
408    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(mRenderer, swapchain);
409    Framebuffer *framebufferZero = new DefaultFramebuffer(mRenderer, colorbufferZero, depthStencilbufferZero);
410
411    setFramebufferZero(framebufferZero);
412
413    // Store the current client version in the renderer
414    mRenderer->setCurrentClientVersion(mClientVersion);
415}
416
417// NOTE: this function should not assume that this context is current!
418void Context::markContextLost()
419{
420    if (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT)
421        mResetStatus = GL_UNKNOWN_CONTEXT_RESET_EXT;
422    mContextLost = true;
423}
424
425bool Context::isContextLost()
426{
427    return mContextLost;
428}
429
430void Context::setCap(GLenum cap, bool enabled)
431{
432    switch (cap)
433    {
434      case GL_CULL_FACE:                     setCullFace(enabled);              break;
435      case GL_POLYGON_OFFSET_FILL:           setPolygonOffsetFill(enabled);     break;
436      case GL_SAMPLE_ALPHA_TO_COVERAGE:      setSampleAlphaToCoverage(enabled); break;
437      case GL_SAMPLE_COVERAGE:               setSampleCoverage(enabled);        break;
438      case GL_SCISSOR_TEST:                  setScissorTest(enabled);           break;
439      case GL_STENCIL_TEST:                  setStencilTest(enabled);           break;
440      case GL_DEPTH_TEST:                    setDepthTest(enabled);             break;
441      case GL_BLEND:                         setBlend(enabled);                 break;
442      case GL_DITHER:                        setDither(enabled);                break;
443      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED();                   break;
444      case GL_RASTERIZER_DISCARD:            setRasterizerDiscard(enabled);     break;
445      default:                               UNREACHABLE();
446    }
447}
448
449bool Context::getCap(GLenum cap)
450{
451    switch (cap)
452    {
453      case GL_CULL_FACE:                     return isCullFaceEnabled();
454      case GL_POLYGON_OFFSET_FILL:           return isPolygonOffsetFillEnabled();
455      case GL_SAMPLE_ALPHA_TO_COVERAGE:      return isSampleAlphaToCoverageEnabled();
456      case GL_SAMPLE_COVERAGE:               return isSampleCoverageEnabled();
457      case GL_SCISSOR_TEST:                  return isScissorTestEnabled();
458      case GL_STENCIL_TEST:                  return isStencilTestEnabled();
459      case GL_DEPTH_TEST:                    return isDepthTestEnabled();
460      case GL_BLEND:                         return isBlendEnabled();
461      case GL_DITHER:                        return isDitherEnabled();
462      case GL_PRIMITIVE_RESTART_FIXED_INDEX: UNIMPLEMENTED(); return false;
463      case GL_RASTERIZER_DISCARD:            return isRasterizerDiscardEnabled();
464      default:                               UNREACHABLE(); return false;
465    }
466}
467
468void Context::setClearColor(float red, float green, float blue, float alpha)
469{
470    mState.colorClearValue.red = red;
471    mState.colorClearValue.green = green;
472    mState.colorClearValue.blue = blue;
473    mState.colorClearValue.alpha = alpha;
474}
475
476void Context::setClearDepth(float depth)
477{
478    mState.depthClearValue = depth;
479}
480
481void Context::setClearStencil(int stencil)
482{
483    mState.stencilClearValue = stencil;
484}
485
486void Context::setRasterizerDiscard(bool enabled)
487{
488    mState.rasterizer.rasterizerDiscard = enabled;
489}
490
491bool Context::isRasterizerDiscardEnabled() const
492{
493    return mState.rasterizer.rasterizerDiscard;
494}
495
496void Context::setCullFace(bool enabled)
497{
498    mState.rasterizer.cullFace = enabled;
499}
500
501bool Context::isCullFaceEnabled() const
502{
503    return mState.rasterizer.cullFace;
504}
505
506void Context::setCullMode(GLenum mode)
507{
508    mState.rasterizer.cullMode = mode;
509}
510
511void Context::setFrontFace(GLenum front)
512{
513    mState.rasterizer.frontFace = front;
514}
515
516void Context::setDepthTest(bool enabled)
517{
518    mState.depthStencil.depthTest = enabled;
519}
520
521bool Context::isDepthTestEnabled() const
522{
523    return mState.depthStencil.depthTest;
524}
525
526void Context::setDepthFunc(GLenum depthFunc)
527{
528     mState.depthStencil.depthFunc = depthFunc;
529}
530
531void Context::setDepthRange(float zNear, float zFar)
532{
533    mState.zNear = zNear;
534    mState.zFar = zFar;
535}
536
537void Context::setBlend(bool enabled)
538{
539    mState.blend.blend = enabled;
540}
541
542bool Context::isBlendEnabled() const
543{
544    return mState.blend.blend;
545}
546
547void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
548{
549    mState.blend.sourceBlendRGB = sourceRGB;
550    mState.blend.destBlendRGB = destRGB;
551    mState.blend.sourceBlendAlpha = sourceAlpha;
552    mState.blend.destBlendAlpha = destAlpha;
553}
554
555void Context::setBlendColor(float red, float green, float blue, float alpha)
556{
557    mState.blendColor.red = red;
558    mState.blendColor.green = green;
559    mState.blendColor.blue = blue;
560    mState.blendColor.alpha = alpha;
561}
562
563void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
564{
565    mState.blend.blendEquationRGB = rgbEquation;
566    mState.blend.blendEquationAlpha = alphaEquation;
567}
568
569void Context::setStencilTest(bool enabled)
570{
571    mState.depthStencil.stencilTest = enabled;
572}
573
574bool Context::isStencilTestEnabled() const
575{
576    return mState.depthStencil.stencilTest;
577}
578
579void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
580{
581    mState.depthStencil.stencilFunc = stencilFunc;
582    mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
583    mState.depthStencil.stencilMask = stencilMask;
584}
585
586void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
587{
588    mState.depthStencil.stencilBackFunc = stencilBackFunc;
589    mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
590    mState.depthStencil.stencilBackMask = stencilBackMask;
591}
592
593void Context::setStencilWritemask(GLuint stencilWritemask)
594{
595    mState.depthStencil.stencilWritemask = stencilWritemask;
596}
597
598void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
599{
600    mState.depthStencil.stencilBackWritemask = stencilBackWritemask;
601}
602
603void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
604{
605    mState.depthStencil.stencilFail = stencilFail;
606    mState.depthStencil.stencilPassDepthFail = stencilPassDepthFail;
607    mState.depthStencil.stencilPassDepthPass = stencilPassDepthPass;
608}
609
610void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
611{
612    mState.depthStencil.stencilBackFail = stencilBackFail;
613    mState.depthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
614    mState.depthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
615}
616
617void Context::setPolygonOffsetFill(bool enabled)
618{
619     mState.rasterizer.polygonOffsetFill = enabled;
620}
621
622bool Context::isPolygonOffsetFillEnabled() const
623{
624    return mState.rasterizer.polygonOffsetFill;
625}
626
627void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
628{
629    // An application can pass NaN values here, so handle this gracefully
630    mState.rasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
631    mState.rasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
632}
633
634void Context::setSampleAlphaToCoverage(bool enabled)
635{
636    mState.blend.sampleAlphaToCoverage = enabled;
637}
638
639bool Context::isSampleAlphaToCoverageEnabled() const
640{
641    return mState.blend.sampleAlphaToCoverage;
642}
643
644void Context::setSampleCoverage(bool enabled)
645{
646    mState.sampleCoverage = enabled;
647}
648
649bool Context::isSampleCoverageEnabled() const
650{
651    return mState.sampleCoverage;
652}
653
654void Context::setSampleCoverageParams(GLclampf value, bool invert)
655{
656    mState.sampleCoverageValue = value;
657    mState.sampleCoverageInvert = invert;
658}
659
660void Context::setScissorTest(bool enabled)
661{
662    mState.scissorTest = enabled;
663}
664
665bool Context::isScissorTestEnabled() const
666{
667    return mState.scissorTest;
668}
669
670void Context::setDither(bool enabled)
671{
672    mState.blend.dither = enabled;
673}
674
675bool Context::isDitherEnabled() const
676{
677    return mState.blend.dither;
678}
679
680void Context::setLineWidth(GLfloat width)
681{
682    mState.lineWidth = width;
683}
684
685void Context::setGenerateMipmapHint(GLenum hint)
686{
687    mState.generateMipmapHint = hint;
688}
689
690void Context::setFragmentShaderDerivativeHint(GLenum hint)
691{
692    mState.fragmentShaderDerivativeHint = hint;
693    // TODO: Propagate the hint to shader translator so we can write
694    // ddx, ddx_coarse, or ddx_fine depending on the hint.
695    // Ignore for now. It is valid for implementations to ignore hint.
696}
697
698void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
699{
700    mState.viewport.x = x;
701    mState.viewport.y = y;
702    mState.viewport.width = width;
703    mState.viewport.height = height;
704}
705
706void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
707{
708    mState.scissor.x = x;
709    mState.scissor.y = y;
710    mState.scissor.width = width;
711    mState.scissor.height = height;
712}
713
714void Context::getScissorParams(GLint *x, GLint *y, GLsizei *width, GLsizei *height)
715{
716    *x = mState.scissor.x;
717    *y = mState.scissor.y;
718    *width = mState.scissor.width;
719    *height = mState.scissor.height;
720}
721
722void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
723{
724    mState.blend.colorMaskRed = red;
725    mState.blend.colorMaskGreen = green;
726    mState.blend.colorMaskBlue = blue;
727    mState.blend.colorMaskAlpha = alpha;
728}
729
730void Context::setDepthMask(bool mask)
731{
732    mState.depthStencil.depthMask = mask;
733}
734
735void Context::setActiveSampler(unsigned int active)
736{
737    mState.activeSampler = active;
738}
739
740GLuint Context::getReadFramebufferHandle() const
741{
742    return mState.readFramebuffer;
743}
744
745GLuint Context::getDrawFramebufferHandle() const
746{
747    return mState.drawFramebuffer;
748}
749
750GLuint Context::getRenderbufferHandle() const
751{
752    return mState.renderbuffer.id();
753}
754
755GLuint Context::getVertexArrayHandle() const
756{
757    return mState.vertexArray;
758}
759
760GLuint Context::getSamplerHandle(GLuint textureUnit) const
761{
762    ASSERT(textureUnit < ArraySize(mState.samplers));
763    return mState.samplers[textureUnit];
764}
765
766unsigned int Context::getActiveSampler() const
767{
768    return mState.activeSampler;
769}
770
771GLuint Context::getArrayBufferHandle() const
772{
773    return mState.arrayBuffer.id();
774}
775
776bool Context::isQueryActive() const
777{
778    for (State::ActiveQueryMap::const_iterator i = mState.activeQueries.begin();
779         i != mState.activeQueries.end(); i++)
780    {
781        if (i->second.get() != NULL)
782        {
783            return true;
784        }
785    }
786
787    return false;
788}
789
790const Query *Context::getActiveQuery(GLenum target) const
791{
792    // All query types should already exist in the activeQueries map
793    ASSERT(mState.activeQueries.find(target) != mState.activeQueries.end());
794
795    return mState.activeQueries.at(target).get();
796}
797
798GLuint Context::getActiveQueryId(GLenum target) const
799{
800    const Query *query = getActiveQuery(target);
801    return (query ? query->id() : 0u);
802}
803
804void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
805{
806    getCurrentVertexArray()->enableAttribute(attribNum, enabled);
807}
808
809const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
810{
811    return getCurrentVertexArray()->getVertexAttribute(attribNum);
812}
813
814const VertexAttribCurrentValueData &Context::getVertexAttribCurrentValue(unsigned int attribNum) const
815{
816    ASSERT(attribNum < MAX_VERTEX_ATTRIBS);
817    return mState.vertexAttribCurrentValues[attribNum];
818}
819
820void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
821                                   bool pureInteger, GLsizei stride, const void *pointer)
822{
823    getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, pureInteger, stride, pointer);
824}
825
826const void *Context::getVertexAttribPointer(unsigned int attribNum) const
827{
828    return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
829}
830
831void Context::setPackAlignment(GLint alignment)
832{
833    mState.pack.alignment = alignment;
834}
835
836GLint Context::getPackAlignment() const
837{
838    return mState.pack.alignment;
839}
840
841void Context::setUnpackAlignment(GLint alignment)
842{
843    mState.unpack.alignment = alignment;
844}
845
846GLint Context::getUnpackAlignment() const
847{
848    return mState.unpack.alignment;
849}
850
851void Context::setPackReverseRowOrder(bool reverseRowOrder)
852{
853    mState.pack.reverseRowOrder = reverseRowOrder;
854}
855
856bool Context::getPackReverseRowOrder() const
857{
858    return mState.pack.reverseRowOrder;
859}
860
861const PixelUnpackState &Context::getUnpackState() const
862{
863    return mState.unpack;
864}
865
866const PixelPackState &Context::getPackState() const
867{
868    return mState.pack;
869}
870
871GLuint Context::createBuffer()
872{
873    return mResourceManager->createBuffer();
874}
875
876GLuint Context::createProgram()
877{
878    return mResourceManager->createProgram();
879}
880
881GLuint Context::createShader(GLenum type)
882{
883    return mResourceManager->createShader(type);
884}
885
886GLuint Context::createTexture()
887{
888    return mResourceManager->createTexture();
889}
890
891GLuint Context::createRenderbuffer()
892{
893    return mResourceManager->createRenderbuffer();
894}
895
896GLsync Context::createFenceSync(GLenum condition)
897{
898    GLuint handle = mResourceManager->createFenceSync();
899
900    gl::FenceSync *fenceSync = mResourceManager->getFenceSync(handle);
901    ASSERT(fenceSync);
902
903    fenceSync->set(condition);
904
905    return reinterpret_cast<GLsync>(handle);
906}
907
908GLuint Context::createVertexArray()
909{
910    GLuint handle = mVertexArrayHandleAllocator.allocate();
911
912    // Although the spec states VAO state is not initialized until the object is bound,
913    // we create it immediately. The resulting behaviour is transparent to the application,
914    // since it's not currently possible to access the state until the object is bound.
915    mVertexArrayMap[handle] = new VertexArray(mRenderer, handle);
916
917    return handle;
918}
919
920GLuint Context::createSampler()
921{
922    return mResourceManager->createSampler();
923}
924
925GLuint Context::createTransformFeedback()
926{
927    GLuint handle = mTransformFeedbackAllocator.allocate();
928    TransformFeedback *transformFeedback = new TransformFeedback(handle);
929    transformFeedback->addRef();
930    mTransformFeedbackMap[handle] = transformFeedback;
931    return handle;
932}
933
934// Returns an unused framebuffer name
935GLuint Context::createFramebuffer()
936{
937    GLuint handle = mFramebufferHandleAllocator.allocate();
938
939    mFramebufferMap[handle] = NULL;
940
941    return handle;
942}
943
944GLuint Context::createFenceNV()
945{
946    GLuint handle = mFenceNVHandleAllocator.allocate();
947
948    mFenceNVMap[handle] = new FenceNV(mRenderer);
949
950    return handle;
951}
952
953// Returns an unused query name
954GLuint Context::createQuery()
955{
956    GLuint handle = mQueryHandleAllocator.allocate();
957
958    mQueryMap[handle] = NULL;
959
960    return handle;
961}
962
963void Context::deleteBuffer(GLuint buffer)
964{
965    if (mResourceManager->getBuffer(buffer))
966    {
967        detachBuffer(buffer);
968    }
969
970    mResourceManager->deleteBuffer(buffer);
971}
972
973void Context::deleteShader(GLuint shader)
974{
975    mResourceManager->deleteShader(shader);
976}
977
978void Context::deleteProgram(GLuint program)
979{
980    mResourceManager->deleteProgram(program);
981}
982
983void Context::deleteTexture(GLuint texture)
984{
985    if (mResourceManager->getTexture(texture))
986    {
987        detachTexture(texture);
988    }
989
990    mResourceManager->deleteTexture(texture);
991}
992
993void Context::deleteRenderbuffer(GLuint renderbuffer)
994{
995    if (mResourceManager->getRenderbuffer(renderbuffer))
996    {
997        detachRenderbuffer(renderbuffer);
998    }
999
1000    mResourceManager->deleteRenderbuffer(renderbuffer);
1001}
1002
1003void Context::deleteFenceSync(GLsync fenceSync)
1004{
1005    // The spec specifies the underlying Fence object is not deleted until all current
1006    // wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1007    // and since our API is currently designed for being called from a single thread, we can delete
1008    // the fence immediately.
1009    mResourceManager->deleteFenceSync(reinterpret_cast<GLuint>(fenceSync));
1010}
1011
1012void Context::deleteVertexArray(GLuint vertexArray)
1013{
1014    auto vertexArrayObject = mVertexArrayMap.find(vertexArray);
1015
1016    if (vertexArrayObject != mVertexArrayMap.end())
1017    {
1018        detachVertexArray(vertexArray);
1019
1020        mVertexArrayHandleAllocator.release(vertexArrayObject->first);
1021        delete vertexArrayObject->second;
1022        mVertexArrayMap.erase(vertexArrayObject);
1023    }
1024}
1025
1026void Context::deleteSampler(GLuint sampler)
1027{
1028    if (mResourceManager->getSampler(sampler))
1029    {
1030        detachSampler(sampler);
1031    }
1032
1033    mResourceManager->deleteSampler(sampler);
1034}
1035
1036void Context::deleteTransformFeedback(GLuint transformFeedback)
1037{
1038    TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(transformFeedback);
1039    if (iter != mTransformFeedbackMap.end())
1040    {
1041        detachTransformFeedback(transformFeedback);
1042        mTransformFeedbackAllocator.release(transformFeedback);
1043        iter->second->release();
1044        mTransformFeedbackMap.erase(iter);
1045    }
1046}
1047
1048void Context::deleteFramebuffer(GLuint framebuffer)
1049{
1050    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
1051
1052    if (framebufferObject != mFramebufferMap.end())
1053    {
1054        detachFramebuffer(framebuffer);
1055
1056        mFramebufferHandleAllocator.release(framebufferObject->first);
1057        delete framebufferObject->second;
1058        mFramebufferMap.erase(framebufferObject);
1059    }
1060}
1061
1062void Context::deleteFenceNV(GLuint fence)
1063{
1064    FenceNVMap::iterator fenceObject = mFenceNVMap.find(fence);
1065
1066    if (fenceObject != mFenceNVMap.end())
1067    {
1068        mFenceNVHandleAllocator.release(fenceObject->first);
1069        delete fenceObject->second;
1070        mFenceNVMap.erase(fenceObject);
1071    }
1072}
1073
1074void Context::deleteQuery(GLuint query)
1075{
1076    QueryMap::iterator queryObject = mQueryMap.find(query);
1077    if (queryObject != mQueryMap.end())
1078    {
1079        mQueryHandleAllocator.release(queryObject->first);
1080        if (queryObject->second)
1081        {
1082            queryObject->second->release();
1083        }
1084        mQueryMap.erase(queryObject);
1085    }
1086}
1087
1088Buffer *Context::getBuffer(GLuint handle)
1089{
1090    return mResourceManager->getBuffer(handle);
1091}
1092
1093Shader *Context::getShader(GLuint handle) const
1094{
1095    return mResourceManager->getShader(handle);
1096}
1097
1098Program *Context::getProgram(GLuint handle) const
1099{
1100    return mResourceManager->getProgram(handle);
1101}
1102
1103Texture *Context::getTexture(GLuint handle)
1104{
1105    return mResourceManager->getTexture(handle);
1106}
1107
1108FramebufferAttachment *Context::getRenderbuffer(GLuint handle)
1109{
1110    return mResourceManager->getRenderbuffer(handle);
1111}
1112
1113FenceSync *Context::getFenceSync(GLsync handle) const
1114{
1115    return mResourceManager->getFenceSync(reinterpret_cast<GLuint>(handle));
1116}
1117
1118VertexArray *Context::getVertexArray(GLuint handle) const
1119{
1120    auto vertexArray = mVertexArrayMap.find(handle);
1121
1122    if (vertexArray == mVertexArrayMap.end())
1123    {
1124        return NULL;
1125    }
1126    else
1127    {
1128        return vertexArray->second;
1129    }
1130}
1131
1132Sampler *Context::getSampler(GLuint handle) const
1133{
1134    return mResourceManager->getSampler(handle);
1135}
1136
1137TransformFeedback *Context::getTransformFeedback(GLuint handle) const
1138{
1139    if (handle == 0)
1140    {
1141        return mTransformFeedbackZero.get();
1142    }
1143    else
1144    {
1145        TransformFeedbackMap::const_iterator iter = mTransformFeedbackMap.find(handle);
1146        return (iter != mTransformFeedbackMap.end()) ? iter->second : NULL;
1147    }
1148}
1149
1150Framebuffer *Context::getReadFramebuffer()
1151{
1152    return getFramebuffer(mState.readFramebuffer);
1153}
1154
1155Framebuffer *Context::getDrawFramebuffer()
1156{
1157    return mBoundDrawFramebuffer;
1158}
1159
1160VertexArray *Context::getCurrentVertexArray() const
1161{
1162    VertexArray *vao = getVertexArray(mState.vertexArray);
1163    ASSERT(vao != NULL);
1164    return vao;
1165}
1166
1167TransformFeedback *Context::getCurrentTransformFeedback() const
1168{
1169    return mState.transformFeedback.get();
1170}
1171
1172bool Context::isSampler(GLuint samplerName) const
1173{
1174    return mResourceManager->isSampler(samplerName);
1175}
1176
1177void Context::bindArrayBuffer(unsigned int buffer)
1178{
1179    mResourceManager->checkBufferAllocation(buffer);
1180
1181    mState.arrayBuffer.set(getBuffer(buffer));
1182}
1183
1184void Context::bindElementArrayBuffer(unsigned int buffer)
1185{
1186    mResourceManager->checkBufferAllocation(buffer);
1187
1188    getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1189}
1190
1191void Context::bindTexture2D(GLuint texture)
1192{
1193    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
1194
1195    mState.samplerTexture[TEXTURE_2D][mState.activeSampler].set(getTexture(texture));
1196}
1197
1198void Context::bindTextureCubeMap(GLuint texture)
1199{
1200    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
1201
1202    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].set(getTexture(texture));
1203}
1204
1205void Context::bindTexture3D(GLuint texture)
1206{
1207    mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
1208
1209    mState.samplerTexture[TEXTURE_3D][mState.activeSampler].set(getTexture(texture));
1210}
1211
1212void Context::bindTexture2DArray(GLuint texture)
1213{
1214    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
1215
1216    mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].set(getTexture(texture));
1217}
1218
1219void Context::bindReadFramebuffer(GLuint framebuffer)
1220{
1221    if (!getFramebuffer(framebuffer))
1222    {
1223        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
1224    }
1225
1226    mState.readFramebuffer = framebuffer;
1227}
1228
1229void Context::bindDrawFramebuffer(GLuint framebuffer)
1230{
1231    if (!getFramebuffer(framebuffer))
1232    {
1233        mFramebufferMap[framebuffer] = new Framebuffer(mRenderer);
1234    }
1235
1236    mState.drawFramebuffer = framebuffer;
1237
1238    mBoundDrawFramebuffer = getFramebuffer(framebuffer);
1239}
1240
1241void Context::bindRenderbuffer(GLuint renderbuffer)
1242{
1243    mResourceManager->checkRenderbufferAllocation(renderbuffer);
1244
1245    mState.renderbuffer.set(getRenderbuffer(renderbuffer));
1246}
1247
1248void Context::bindVertexArray(GLuint vertexArray)
1249{
1250    if (!getVertexArray(vertexArray))
1251    {
1252        mVertexArrayMap[vertexArray] = new VertexArray(mRenderer, vertexArray);
1253    }
1254
1255    mState.vertexArray = vertexArray;
1256}
1257
1258void Context::bindSampler(GLuint textureUnit, GLuint sampler)
1259{
1260    ASSERT(textureUnit < ArraySize(mState.samplers));
1261    mResourceManager->checkSamplerAllocation(sampler);
1262
1263    mState.samplers[textureUnit] = sampler;
1264}
1265
1266void Context::bindGenericUniformBuffer(GLuint buffer)
1267{
1268    mResourceManager->checkBufferAllocation(buffer);
1269
1270    mState.genericUniformBuffer.set(getBuffer(buffer));
1271}
1272
1273void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1274{
1275    mResourceManager->checkBufferAllocation(buffer);
1276
1277    mState.uniformBuffers[index].set(getBuffer(buffer), offset, size);
1278}
1279
1280void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1281{
1282    mResourceManager->checkBufferAllocation(buffer);
1283
1284    mState.genericTransformFeedbackBuffer.set(getBuffer(buffer));
1285}
1286
1287void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1288{
1289    mResourceManager->checkBufferAllocation(buffer);
1290
1291    mState.transformFeedbackBuffers[index].set(getBuffer(buffer), offset, size);
1292}
1293
1294void Context::bindCopyReadBuffer(GLuint buffer)
1295{
1296    mResourceManager->checkBufferAllocation(buffer);
1297
1298    mState.copyReadBuffer.set(getBuffer(buffer));
1299}
1300
1301void Context::bindCopyWriteBuffer(GLuint buffer)
1302{
1303    mResourceManager->checkBufferAllocation(buffer);
1304
1305    mState.copyWriteBuffer.set(getBuffer(buffer));
1306}
1307
1308void Context::bindPixelPackBuffer(GLuint buffer)
1309{
1310    mResourceManager->checkBufferAllocation(buffer);
1311
1312    mState.pack.pixelBuffer.set(getBuffer(buffer));
1313}
1314
1315void Context::bindPixelUnpackBuffer(GLuint buffer)
1316{
1317    mResourceManager->checkBufferAllocation(buffer);
1318
1319    mState.unpack.pixelBuffer.set(getBuffer(buffer));
1320}
1321
1322void Context::useProgram(GLuint program)
1323{
1324    GLuint priorProgram = mState.currentProgram;
1325    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
1326
1327    if (priorProgram != program)
1328    {
1329        Program *newProgram = mResourceManager->getProgram(program);
1330        Program *oldProgram = mResourceManager->getProgram(priorProgram);
1331        mCurrentProgramBinary.set(NULL);
1332
1333        if (newProgram)
1334        {
1335            newProgram->addRef();
1336            mCurrentProgramBinary.set(newProgram->getProgramBinary());
1337        }
1338
1339        if (oldProgram)
1340        {
1341            oldProgram->release();
1342        }
1343    }
1344}
1345
1346void Context::linkProgram(GLuint program)
1347{
1348    Program *programObject = mResourceManager->getProgram(program);
1349
1350    bool linked = programObject->link();
1351
1352    // if the current program was relinked successfully we
1353    // need to install the new executables
1354    if (linked && program == mState.currentProgram)
1355    {
1356        mCurrentProgramBinary.set(programObject->getProgramBinary());
1357    }
1358}
1359
1360void Context::setProgramBinary(GLuint program, const void *binary, GLint length)
1361{
1362    Program *programObject = mResourceManager->getProgram(program);
1363
1364    bool loaded = programObject->setProgramBinary(binary, length);
1365
1366    // if the current program was reloaded successfully we
1367    // need to install the new executables
1368    if (loaded && program == mState.currentProgram)
1369    {
1370        mCurrentProgramBinary.set(programObject->getProgramBinary());
1371    }
1372
1373}
1374
1375void Context::bindTransformFeedback(GLuint transformFeedback)
1376{
1377    TransformFeedback *transformFeedbackObject = getTransformFeedback(transformFeedback);
1378    mState.transformFeedback.set(transformFeedbackObject);
1379}
1380
1381void Context::beginQuery(GLenum target, GLuint query)
1382{
1383    Query *queryObject = getQuery(query, true, target);
1384    ASSERT(queryObject);
1385
1386    // set query as active for specified target
1387    mState.activeQueries[target].set(queryObject);
1388
1389    // begin query
1390    queryObject->begin();
1391}
1392
1393void Context::endQuery(GLenum target)
1394{
1395    Query *queryObject = mState.activeQueries[target].get();
1396    ASSERT(queryObject);
1397
1398    queryObject->end();
1399
1400    mState.activeQueries[target].set(NULL);
1401}
1402
1403void Context::setFramebufferZero(Framebuffer *buffer)
1404{
1405    delete mFramebufferMap[0];
1406    mFramebufferMap[0] = buffer;
1407    if (mState.drawFramebuffer == 0)
1408    {
1409        mBoundDrawFramebuffer = buffer;
1410    }
1411}
1412
1413void Context::setRenderbufferStorage(GLsizei width, GLsizei height, GLenum internalformat, GLsizei samples)
1414{
1415    const bool color = gl::IsColorRenderingSupported(internalformat, this);
1416    const bool depth = gl::IsDepthRenderingSupported(internalformat, this);
1417    const bool stencil = gl::IsStencilRenderingSupported(internalformat, this);
1418
1419    RenderbufferStorage *renderbuffer = NULL;
1420
1421    if (color)
1422    {
1423        renderbuffer = new gl::Colorbuffer(mRenderer,width, height, internalformat, samples);
1424    }
1425    else if (depth && stencil)
1426    {
1427        renderbuffer = new gl::DepthStencilbuffer(mRenderer, width, height, samples);
1428    }
1429    else if (depth)
1430    {
1431        renderbuffer = new gl::Depthbuffer(mRenderer, width, height, samples);
1432    }
1433    else if (stencil)
1434    {
1435        renderbuffer = new gl::Stencilbuffer(mRenderer, width, height, samples);
1436    }
1437    else
1438    {
1439        UNREACHABLE();
1440        return;
1441    }
1442
1443    FramebufferAttachment *renderbufferObject = mState.renderbuffer.get();
1444    renderbufferObject->setStorage(renderbuffer);
1445}
1446
1447Framebuffer *Context::getFramebuffer(unsigned int handle) const
1448{
1449    FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
1450
1451    if (framebuffer == mFramebufferMap.end())
1452    {
1453        return NULL;
1454    }
1455    else
1456    {
1457        return framebuffer->second;
1458    }
1459}
1460
1461FenceNV *Context::getFenceNV(unsigned int handle)
1462{
1463    FenceNVMap::iterator fence = mFenceNVMap.find(handle);
1464
1465    if (fence == mFenceNVMap.end())
1466    {
1467        return NULL;
1468    }
1469    else
1470    {
1471        return fence->second;
1472    }
1473}
1474
1475Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1476{
1477    QueryMap::iterator query = mQueryMap.find(handle);
1478
1479    if (query == mQueryMap.end())
1480    {
1481        return NULL;
1482    }
1483    else
1484    {
1485        if (!query->second && create)
1486        {
1487            query->second = new Query(mRenderer, type, handle);
1488            query->second->addRef();
1489        }
1490        return query->second;
1491    }
1492}
1493
1494Buffer *Context::getTargetBuffer(GLenum target) const
1495{
1496    switch (target)
1497    {
1498      case GL_ARRAY_BUFFER:              return mState.arrayBuffer.get();
1499      case GL_COPY_READ_BUFFER:          return mState.copyReadBuffer.get();
1500      case GL_COPY_WRITE_BUFFER:         return mState.copyWriteBuffer.get();
1501      case GL_ELEMENT_ARRAY_BUFFER:      return getCurrentVertexArray()->getElementArrayBuffer();
1502      case GL_PIXEL_PACK_BUFFER:         return mState.pack.pixelBuffer.get();
1503      case GL_PIXEL_UNPACK_BUFFER:       return mState.unpack.pixelBuffer.get();
1504      case GL_TRANSFORM_FEEDBACK_BUFFER: return mState.genericTransformFeedbackBuffer.get();
1505      case GL_UNIFORM_BUFFER:            return mState.genericUniformBuffer.get();
1506      default: UNREACHABLE();            return NULL;
1507    }
1508}
1509
1510Buffer *Context::getArrayBuffer()
1511{
1512    return mState.arrayBuffer.get();
1513}
1514
1515Buffer *Context::getElementArrayBuffer() const
1516{
1517    return getCurrentVertexArray()->getElementArrayBuffer();
1518}
1519
1520ProgramBinary *Context::getCurrentProgramBinary()
1521{
1522    return mCurrentProgramBinary.get();
1523}
1524
1525Texture *Context::getTargetTexture(GLenum target) const
1526{
1527    if (!ValidTextureTarget(this, target))
1528    {
1529        return NULL;
1530    }
1531
1532    switch (target)
1533    {
1534      case GL_TEXTURE_2D:       return getTexture2D();
1535      case GL_TEXTURE_CUBE_MAP: return getTextureCubeMap();
1536      case GL_TEXTURE_3D:       return getTexture3D();
1537      case GL_TEXTURE_2D_ARRAY: return getTexture2DArray();
1538      default:                  return NULL;
1539    }
1540}
1541
1542GLuint Context::getTargetFramebufferHandle(GLenum target) const
1543{
1544    if (!ValidFramebufferTarget(target))
1545    {
1546        return GL_INVALID_INDEX;
1547    }
1548
1549    if (target == GL_READ_FRAMEBUFFER_ANGLE)
1550    {
1551        return mState.readFramebuffer;
1552    }
1553    else
1554    {
1555        return mState.drawFramebuffer;
1556    }
1557}
1558
1559Framebuffer *Context::getTargetFramebuffer(GLenum target) const
1560{
1561    GLuint framebufferHandle = getTargetFramebufferHandle(target);
1562    return (framebufferHandle == GL_INVALID_INDEX ? NULL : getFramebuffer(framebufferHandle));
1563}
1564
1565Texture2D *Context::getTexture2D() const
1566{
1567    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1568}
1569
1570TextureCubeMap *Context::getTextureCubeMap() const
1571{
1572    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1573}
1574
1575Texture3D *Context::getTexture3D() const
1576{
1577    return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1578}
1579
1580Texture2DArray *Context::getTexture2DArray() const
1581{
1582    return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1583}
1584
1585Buffer *Context::getGenericUniformBuffer()
1586{
1587    return mState.genericUniformBuffer.get();
1588}
1589
1590Buffer *Context::getGenericTransformFeedbackBuffer()
1591{
1592    return mState.genericTransformFeedbackBuffer.get();
1593}
1594
1595Buffer *Context::getCopyReadBuffer()
1596{
1597    return mState.copyReadBuffer.get();
1598}
1599
1600Buffer *Context::getCopyWriteBuffer()
1601{
1602    return mState.copyWriteBuffer.get();
1603}
1604
1605Buffer *Context::getPixelPackBuffer()
1606{
1607    return mState.pack.pixelBuffer.get();
1608}
1609
1610Buffer *Context::getPixelUnpackBuffer()
1611{
1612    return mState.unpack.pixelBuffer.get();
1613}
1614
1615Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1616{
1617    GLuint texid = mState.samplerTexture[type][sampler].id();
1618
1619    if (texid == 0)   // Special case: 0 refers to different initial textures based on the target
1620    {
1621        switch (type)
1622        {
1623          default: UNREACHABLE();
1624          case TEXTURE_2D:       return mTexture2DZero.get();
1625          case TEXTURE_CUBE:     return mTextureCubeMapZero.get();
1626          case TEXTURE_3D:       return mTexture3DZero.get();
1627          case TEXTURE_2D_ARRAY: return mTexture2DArrayZero.get();
1628        }
1629    }
1630
1631    return mState.samplerTexture[type][sampler].get();
1632}
1633
1634void Context::getBooleanv(GLenum pname, GLboolean *params)
1635{
1636    switch (pname)
1637    {
1638      case GL_SHADER_COMPILER:           *params = GL_TRUE;                             break;
1639      case GL_SAMPLE_COVERAGE_INVERT:    *params = mState.sampleCoverageInvert;         break;
1640      case GL_DEPTH_WRITEMASK:           *params = mState.depthStencil.depthMask;       break;
1641      case GL_COLOR_WRITEMASK:
1642        params[0] = mState.blend.colorMaskRed;
1643        params[1] = mState.blend.colorMaskGreen;
1644        params[2] = mState.blend.colorMaskBlue;
1645        params[3] = mState.blend.colorMaskAlpha;
1646        break;
1647      case GL_CULL_FACE:                 *params = mState.rasterizer.cullFace;          break;
1648      case GL_POLYGON_OFFSET_FILL:       *params = mState.rasterizer.polygonOffsetFill; break;
1649      case GL_SAMPLE_ALPHA_TO_COVERAGE:  *params = mState.blend.sampleAlphaToCoverage;  break;
1650      case GL_SAMPLE_COVERAGE:           *params = mState.sampleCoverage;               break;
1651      case GL_SCISSOR_TEST:              *params = mState.scissorTest;                  break;
1652      case GL_STENCIL_TEST:              *params = mState.depthStencil.stencilTest;     break;
1653      case GL_DEPTH_TEST:                *params = mState.depthStencil.depthTest;       break;
1654      case GL_BLEND:                     *params = mState.blend.blend;                  break;
1655      case GL_DITHER:                    *params = mState.blend.dither;                 break;
1656      case GL_CONTEXT_ROBUST_ACCESS_EXT: *params = mRobustAccess ? GL_TRUE : GL_FALSE;  break;
1657      case GL_TRANSFORM_FEEDBACK_ACTIVE: *params = getCurrentTransformFeedback()->isStarted(); break;
1658      case GL_TRANSFORM_FEEDBACK_PAUSED: *params = getCurrentTransformFeedback()->isPaused();  break;
1659      default:
1660        UNREACHABLE();
1661        break;
1662    }
1663}
1664
1665void Context::getFloatv(GLenum pname, GLfloat *params)
1666{
1667    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1668    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1669    // GetIntegerv as its native query function. As it would require conversion in any
1670    // case, this should make no difference to the calling application.
1671    switch (pname)
1672    {
1673      case GL_LINE_WIDTH:               *params = mState.lineWidth;                         break;
1674      case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;               break;
1675      case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;                   break;
1676      case GL_POLYGON_OFFSET_FACTOR:    *params = mState.rasterizer.polygonOffsetFactor;    break;
1677      case GL_POLYGON_OFFSET_UNITS:     *params = mState.rasterizer.polygonOffsetUnits;     break;
1678      case GL_ALIASED_LINE_WIDTH_RANGE:
1679        params[0] = gl::ALIASED_LINE_WIDTH_RANGE_MIN;
1680        params[1] = gl::ALIASED_LINE_WIDTH_RANGE_MAX;
1681        break;
1682      case GL_ALIASED_POINT_SIZE_RANGE:
1683        params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
1684        params[1] = getMaximumPointSize();
1685        break;
1686      case GL_DEPTH_RANGE:
1687        params[0] = mState.zNear;
1688        params[1] = mState.zFar;
1689        break;
1690      case GL_COLOR_CLEAR_VALUE:
1691        params[0] = mState.colorClearValue.red;
1692        params[1] = mState.colorClearValue.green;
1693        params[2] = mState.colorClearValue.blue;
1694        params[3] = mState.colorClearValue.alpha;
1695        break;
1696      case GL_BLEND_COLOR:
1697        params[0] = mState.blendColor.red;
1698        params[1] = mState.blendColor.green;
1699        params[2] = mState.blendColor.blue;
1700        params[3] = mState.blendColor.alpha;
1701        break;
1702      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1703        ASSERT(supportsTextureFilterAnisotropy());
1704        *params = mMaxTextureAnisotropy;
1705        break;
1706      default:
1707        UNREACHABLE();
1708        break;
1709    }
1710}
1711
1712void Context::getIntegerv(GLenum pname, GLint *params)
1713{
1714    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
1715    {
1716        unsigned int colorAttachment = (pname - GL_DRAW_BUFFER0_EXT);
1717        ASSERT(colorAttachment < mRenderer->getMaxRenderTargets());
1718        Framebuffer *framebuffer = getDrawFramebuffer();
1719        *params = framebuffer->getDrawBufferState(colorAttachment);
1720        return;
1721    }
1722
1723    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1724    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1725    // GetIntegerv as its native query function. As it would require conversion in any
1726    // case, this should make no difference to the calling application. You may find it in
1727    // Context::getFloatv.
1728    switch (pname)
1729    {
1730      case GL_MAX_VERTEX_ATTRIBS:                       *params = gl::MAX_VERTEX_ATTRIBS;                               break;
1731      case GL_MAX_VERTEX_UNIFORM_VECTORS:               *params = mRenderer->getMaxVertexUniformVectors();              break;
1732      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:            *params = mRenderer->getMaxVertexUniformVectors() * 4;          break;
1733      case GL_MAX_VARYING_VECTORS:                      *params = mRenderer->getMaxVaryingVectors();                    break;
1734      case GL_MAX_VARYING_COMPONENTS:                   *params = mRenderer->getMaxVaryingVectors() * 4;                break;
1735      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:         *params = mRenderer->getMaxCombinedTextureImageUnits();         break;
1736      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:           *params = mRenderer->getMaxVertexTextureImageUnits();           break;
1737      case GL_MAX_TEXTURE_IMAGE_UNITS:                  *params = gl::MAX_TEXTURE_IMAGE_UNITS;                          break;
1738      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:             *params = mRenderer->getMaxFragmentUniformVectors();            break;
1739      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:          *params = mRenderer->getMaxFragmentUniformVectors() * 4;        break;
1740      case GL_MAX_RENDERBUFFER_SIZE:                    *params = getMaximumRenderbufferDimension();                    break;
1741      case GL_MAX_COLOR_ATTACHMENTS_EXT:                *params = mRenderer->getMaxRenderTargets();                     break;
1742      case GL_MAX_DRAW_BUFFERS_EXT:                     *params = mRenderer->getMaxRenderTargets();                     break;
1743      case GL_NUM_SHADER_BINARY_FORMATS:                *params = 0;                                                    break;
1744      case GL_SHADER_BINARY_FORMATS:                    /* no shader binary formats are supported */                    break;
1745      case GL_ARRAY_BUFFER_BINDING:                     *params = mState.arrayBuffer.id();                              break;
1746      case GL_ELEMENT_ARRAY_BUFFER_BINDING:             *params = getCurrentVertexArray()->getElementArrayBufferId();   break;
1747      //case GL_FRAMEBUFFER_BINDING:                    // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1748      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.drawFramebuffer;                               break;
1749      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:           *params = mState.readFramebuffer;                               break;
1750      case GL_RENDERBUFFER_BINDING:                     *params = mState.renderbuffer.id();                             break;
1751      case GL_VERTEX_ARRAY_BINDING:                     *params = mState.vertexArray;                                   break;
1752      case GL_CURRENT_PROGRAM:                          *params = mState.currentProgram;                                break;
1753      case GL_PACK_ALIGNMENT:                           *params = mState.pack.alignment;                                break;
1754      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:             *params = mState.pack.reverseRowOrder;                          break;
1755      case GL_UNPACK_ALIGNMENT:                         *params = mState.unpack.alignment;                              break;
1756      case GL_GENERATE_MIPMAP_HINT:                     *params = mState.generateMipmapHint;                            break;
1757      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:      *params = mState.fragmentShaderDerivativeHint;                  break;
1758      case GL_ACTIVE_TEXTURE:                           *params = (mState.activeSampler + GL_TEXTURE0);                 break;
1759      case GL_STENCIL_FUNC:                             *params = mState.depthStencil.stencilFunc;                      break;
1760      case GL_STENCIL_REF:                              *params = mState.stencilRef;                                    break;
1761      case GL_STENCIL_VALUE_MASK:                       *params = clampToInt(mState.depthStencil.stencilMask);          break;
1762      case GL_STENCIL_BACK_FUNC:                        *params = mState.depthStencil.stencilBackFunc;                  break;
1763      case GL_STENCIL_BACK_REF:                         *params = mState.stencilBackRef;                                break;
1764      case GL_STENCIL_BACK_VALUE_MASK:                  *params = clampToInt(mState.depthStencil.stencilBackMask);      break;
1765      case GL_STENCIL_FAIL:                             *params = mState.depthStencil.stencilFail;                      break;
1766      case GL_STENCIL_PASS_DEPTH_FAIL:                  *params = mState.depthStencil.stencilPassDepthFail;             break;
1767      case GL_STENCIL_PASS_DEPTH_PASS:                  *params = mState.depthStencil.stencilPassDepthPass;             break;
1768      case GL_STENCIL_BACK_FAIL:                        *params = mState.depthStencil.stencilBackFail;                  break;
1769      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:             *params = mState.depthStencil.stencilBackPassDepthFail;         break;
1770      case GL_STENCIL_BACK_PASS_DEPTH_PASS:             *params = mState.depthStencil.stencilBackPassDepthPass;         break;
1771      case GL_DEPTH_FUNC:                               *params = mState.depthStencil.depthFunc;                        break;
1772      case GL_BLEND_SRC_RGB:                            *params = mState.blend.sourceBlendRGB;                          break;
1773      case GL_BLEND_SRC_ALPHA:                          *params = mState.blend.sourceBlendAlpha;                        break;
1774      case GL_BLEND_DST_RGB:                            *params = mState.blend.destBlendRGB;                            break;
1775      case GL_BLEND_DST_ALPHA:                          *params = mState.blend.destBlendAlpha;                          break;
1776      case GL_BLEND_EQUATION_RGB:                       *params = mState.blend.blendEquationRGB;                        break;
1777      case GL_BLEND_EQUATION_ALPHA:                     *params = mState.blend.blendEquationAlpha;                      break;
1778      case GL_STENCIL_WRITEMASK:                        *params = clampToInt(mState.depthStencil.stencilWritemask);     break;
1779      case GL_STENCIL_BACK_WRITEMASK:                   *params = clampToInt(mState.depthStencil.stencilBackWritemask); break;
1780      case GL_STENCIL_CLEAR_VALUE:                      *params = mState.stencilClearValue;                             break;
1781      case GL_SUBPIXEL_BITS:                            *params = 4;                                                    break;
1782      case GL_MAX_TEXTURE_SIZE:                         *params = getMaximum2DTextureDimension();                       break;
1783      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:                *params = getMaximumCubeTextureDimension();                     break;
1784      case GL_MAX_3D_TEXTURE_SIZE:                      *params = getMaximum3DTextureDimension();                       break;
1785      case GL_MAX_ARRAY_TEXTURE_LAYERS:                 *params = getMaximum2DArrayTextureLayers();                     break;
1786      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:          *params = getUniformBufferOffsetAlignment();                    break;
1787      case GL_MAX_UNIFORM_BUFFER_BINDINGS:              *params = getMaximumCombinedUniformBufferBindings();            break;
1788      case GL_MAX_VERTEX_UNIFORM_BLOCKS:                *params = mRenderer->getMaxVertexShaderUniformBuffers();        break;
1789      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:              *params = mRenderer->getMaxFragmentShaderUniformBuffers();      break;
1790      case GL_MAX_COMBINED_UNIFORM_BLOCKS:              *params = getMaximumCombinedUniformBufferBindings();            break;
1791      case GL_MAJOR_VERSION:                            *params = mClientVersion;                                       break;
1792      case GL_MINOR_VERSION:                            *params = 0;                                                    break;
1793      case GL_MAX_ELEMENTS_INDICES:                     *params = mRenderer->getMaxRecommendedElementsIndices();        break;
1794      case GL_MAX_ELEMENTS_VERTICES:                    *params = mRenderer->getMaxRecommendedElementsVertices();       break;
1795      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: *params = mRenderer->getMaxTransformFeedbackInterleavedComponents(); break;
1796      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:       *params = mRenderer->getMaxTransformFeedbackBuffers();               break;
1797      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:    *params = mRenderer->getMaxTransformFeedbackSeparateComponents();    break;
1798      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1799        params[0] = mNumCompressedTextureFormats;
1800        break;
1801      case GL_MAX_SAMPLES_ANGLE:
1802        *params = static_cast<GLint>(getMaxSupportedSamples());
1803        break;
1804      case GL_SAMPLE_BUFFERS:
1805      case GL_SAMPLES:
1806        {
1807            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1808            if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
1809            {
1810                switch (pname)
1811                {
1812                  case GL_SAMPLE_BUFFERS:
1813                    if (framebuffer->getSamples() != 0)
1814                    {
1815                        *params = 1;
1816                    }
1817                    else
1818                    {
1819                        *params = 0;
1820                    }
1821                    break;
1822                  case GL_SAMPLES:
1823                    *params = framebuffer->getSamples();
1824                    break;
1825                }
1826            }
1827            else
1828            {
1829                *params = 0;
1830            }
1831        }
1832        break;
1833      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1834      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1835        {
1836            GLenum internalFormat, format, type;
1837            getCurrentReadFormatType(&internalFormat, &format, &type);
1838            if (pname == GL_IMPLEMENTATION_COLOR_READ_FORMAT)
1839                *params = format;
1840            else
1841                *params = type;
1842        }
1843        break;
1844      case GL_MAX_VIEWPORT_DIMS:
1845        {
1846            params[0] = mMaxViewportDimension;
1847            params[1] = mMaxViewportDimension;
1848        }
1849        break;
1850      case GL_COMPRESSED_TEXTURE_FORMATS:
1851        {
1852            if (supportsDXT1Textures())
1853            {
1854                *params++ = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
1855                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
1856            }
1857            if (supportsDXT3Textures())
1858            {
1859                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE;
1860            }
1861            if (supportsDXT5Textures())
1862            {
1863                *params++ = GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE;
1864            }
1865        }
1866        break;
1867      case GL_VIEWPORT:
1868        params[0] = mState.viewport.x;
1869        params[1] = mState.viewport.y;
1870        params[2] = mState.viewport.width;
1871        params[3] = mState.viewport.height;
1872        break;
1873      case GL_SCISSOR_BOX:
1874        params[0] = mState.scissor.x;
1875        params[1] = mState.scissor.y;
1876        params[2] = mState.scissor.width;
1877        params[3] = mState.scissor.height;
1878        break;
1879      case GL_CULL_FACE_MODE:                   *params = mState.rasterizer.cullMode;   break;
1880      case GL_FRONT_FACE:                       *params = mState.rasterizer.frontFace;  break;
1881      case GL_RED_BITS:
1882      case GL_GREEN_BITS:
1883      case GL_BLUE_BITS:
1884      case GL_ALPHA_BITS:
1885        {
1886            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1887            gl::FramebufferAttachment *colorbuffer = framebuffer->getFirstColorbuffer();
1888
1889            if (colorbuffer)
1890            {
1891                switch (pname)
1892                {
1893                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();      break;
1894                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize();    break;
1895                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();     break;
1896                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize();    break;
1897                }
1898            }
1899            else
1900            {
1901                *params = 0;
1902            }
1903        }
1904        break;
1905      case GL_DEPTH_BITS:
1906        {
1907            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1908            gl::FramebufferAttachment *depthbuffer = framebuffer->getDepthbuffer();
1909
1910            if (depthbuffer)
1911            {
1912                *params = depthbuffer->getDepthSize();
1913            }
1914            else
1915            {
1916                *params = 0;
1917            }
1918        }
1919        break;
1920      case GL_STENCIL_BITS:
1921        {
1922            gl::Framebuffer *framebuffer = getDrawFramebuffer();
1923            gl::FramebufferAttachment *stencilbuffer = framebuffer->getStencilbuffer();
1924
1925            if (stencilbuffer)
1926            {
1927                *params = stencilbuffer->getStencilSize();
1928            }
1929            else
1930            {
1931                *params = 0;
1932            }
1933        }
1934        break;
1935      case GL_TEXTURE_BINDING_2D:
1936        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
1937        *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1938        break;
1939      case GL_TEXTURE_BINDING_CUBE_MAP:
1940        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
1941        *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1942        break;
1943      case GL_TEXTURE_BINDING_3D:
1944        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
1945        *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].id();
1946        break;
1947      case GL_TEXTURE_BINDING_2D_ARRAY:
1948        ASSERT(mState.activeSampler < mRenderer->getMaxCombinedTextureImageUnits());
1949        *params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].id();
1950        break;
1951      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
1952        *params = mResetStrategy;
1953        break;
1954      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
1955        *params = 1;
1956        break;
1957      case GL_PROGRAM_BINARY_FORMATS_OES:
1958        *params = GL_PROGRAM_BINARY_ANGLE;
1959        break;
1960      case GL_UNIFORM_BUFFER_BINDING:
1961        *params = mState.genericUniformBuffer.id();
1962        break;
1963      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
1964        *params = mState.genericTransformFeedbackBuffer.id();
1965        break;
1966      case GL_COPY_READ_BUFFER_BINDING:
1967        *params = mState.copyReadBuffer.id();
1968        break;
1969      case GL_COPY_WRITE_BUFFER_BINDING:
1970        *params = mState.copyWriteBuffer.id();
1971        break;
1972      case GL_PIXEL_PACK_BUFFER_BINDING:
1973        *params = mState.pack.pixelBuffer.id();
1974        break;
1975      case GL_PIXEL_UNPACK_BUFFER_BINDING:
1976        *params = mState.unpack.pixelBuffer.id();
1977        break;
1978      case GL_NUM_EXTENSIONS:
1979        *params = static_cast<GLint>(getNumExtensions());
1980        break;
1981      default:
1982        UNREACHABLE();
1983        break;
1984    }
1985}
1986
1987void Context::getInteger64v(GLenum pname, GLint64 *params)
1988{
1989    switch (pname)
1990    {
1991      case GL_MAX_ELEMENT_INDEX:
1992        *params = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
1993        break;
1994      case GL_MAX_UNIFORM_BLOCK_SIZE:
1995        *params = static_cast<GLint64>(mRenderer->getMaxUniformBufferSize());
1996        break;
1997      case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1998        {
1999            GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
2000            GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
2001            *params = uniformBufferComponents + defaultBufferComponents;
2002        }
2003        break;
2004      case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2005        {
2006            GLint64 uniformBufferComponents = static_cast<GLint64>(mRenderer->getMaxFragmentShaderUniformBuffers()) * static_cast<GLint64>(mRenderer->getMaxUniformBufferSize() / 4);
2007            GLint64 defaultBufferComponents = static_cast<GLint64>(mRenderer->getMaxVertexUniformVectors() * 4);
2008            *params = uniformBufferComponents + defaultBufferComponents;
2009        }
2010        break;
2011      case GL_MAX_SERVER_WAIT_TIMEOUT:
2012        // We do not wait for server fence objects internally, so report a max timeout of zero.
2013        *params = 0;
2014        break;
2015      default:
2016        UNREACHABLE();
2017        break;
2018    }
2019}
2020
2021bool Context::getIndexedIntegerv(GLenum target, GLuint index, GLint *data)
2022{
2023    switch (target)
2024    {
2025      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2026        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2027        {
2028            *data = mState.transformFeedbackBuffers[index].id();
2029        }
2030        break;
2031      case GL_UNIFORM_BUFFER_BINDING:
2032        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2033        {
2034            *data = mState.uniformBuffers[index].id();
2035        }
2036        break;
2037      default:
2038        return false;
2039    }
2040
2041    return true;
2042}
2043
2044bool Context::getIndexedInteger64v(GLenum target, GLuint index, GLint64 *data)
2045{
2046    switch (target)
2047    {
2048      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2049        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2050        {
2051            *data = mState.transformFeedbackBuffers[index].getOffset();
2052        }
2053        break;
2054      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2055        if (index < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS)
2056        {
2057            *data = mState.transformFeedbackBuffers[index].getSize();
2058        }
2059        break;
2060      case GL_UNIFORM_BUFFER_START:
2061        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2062        {
2063            *data = mState.uniformBuffers[index].getOffset();
2064        }
2065        break;
2066      case GL_UNIFORM_BUFFER_SIZE:
2067        if (index < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS)
2068        {
2069            *data = mState.uniformBuffers[index].getSize();
2070        }
2071        break;
2072      default:
2073        return false;
2074    }
2075
2076    return true;
2077}
2078
2079bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
2080{
2081    if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
2082    {
2083        *type = GL_INT;
2084        *numParams = 1;
2085        return true;
2086    }
2087
2088    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2089    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2090    // to the fact that it is stored internally as a float, and so would require conversion
2091    // if returned from Context::getIntegerv. Since this conversion is already implemented
2092    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2093    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2094    // application.
2095    switch (pname)
2096    {
2097      case GL_COMPRESSED_TEXTURE_FORMATS:
2098        {
2099            *type = GL_INT;
2100            *numParams = mNumCompressedTextureFormats;
2101        }
2102        return true;
2103      case GL_SHADER_BINARY_FORMATS:
2104        {
2105            *type = GL_INT;
2106            *numParams = 0;
2107        }
2108        return true;
2109      case GL_MAX_VERTEX_ATTRIBS:
2110      case GL_MAX_VERTEX_UNIFORM_VECTORS:
2111      case GL_MAX_VARYING_VECTORS:
2112      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2113      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2114      case GL_MAX_TEXTURE_IMAGE_UNITS:
2115      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2116      case GL_MAX_RENDERBUFFER_SIZE:
2117      case GL_MAX_COLOR_ATTACHMENTS_EXT:
2118      case GL_MAX_DRAW_BUFFERS_EXT:
2119      case GL_NUM_SHADER_BINARY_FORMATS:
2120      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2121      case GL_ARRAY_BUFFER_BINDING:
2122      //case GL_FRAMEBUFFER_BINDING: // equivalent to DRAW_FRAMEBUFFER_BINDING_ANGLE
2123      case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:
2124      case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
2125      case GL_RENDERBUFFER_BINDING:
2126      case GL_CURRENT_PROGRAM:
2127      case GL_PACK_ALIGNMENT:
2128      case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
2129      case GL_UNPACK_ALIGNMENT:
2130      case GL_GENERATE_MIPMAP_HINT:
2131      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2132      case GL_RED_BITS:
2133      case GL_GREEN_BITS:
2134      case GL_BLUE_BITS:
2135      case GL_ALPHA_BITS:
2136      case GL_DEPTH_BITS:
2137      case GL_STENCIL_BITS:
2138      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2139      case GL_CULL_FACE_MODE:
2140      case GL_FRONT_FACE:
2141      case GL_ACTIVE_TEXTURE:
2142      case GL_STENCIL_FUNC:
2143      case GL_STENCIL_VALUE_MASK:
2144      case GL_STENCIL_REF:
2145      case GL_STENCIL_FAIL:
2146      case GL_STENCIL_PASS_DEPTH_FAIL:
2147      case GL_STENCIL_PASS_DEPTH_PASS:
2148      case GL_STENCIL_BACK_FUNC:
2149      case GL_STENCIL_BACK_VALUE_MASK:
2150      case GL_STENCIL_BACK_REF:
2151      case GL_STENCIL_BACK_FAIL:
2152      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2153      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2154      case GL_DEPTH_FUNC:
2155      case GL_BLEND_SRC_RGB:
2156      case GL_BLEND_SRC_ALPHA:
2157      case GL_BLEND_DST_RGB:
2158      case GL_BLEND_DST_ALPHA:
2159      case GL_BLEND_EQUATION_RGB:
2160      case GL_BLEND_EQUATION_ALPHA:
2161      case GL_STENCIL_WRITEMASK:
2162      case GL_STENCIL_BACK_WRITEMASK:
2163      case GL_STENCIL_CLEAR_VALUE:
2164      case GL_SUBPIXEL_BITS:
2165      case GL_MAX_TEXTURE_SIZE:
2166      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2167      case GL_SAMPLE_BUFFERS:
2168      case GL_SAMPLES:
2169      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2170      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2171      case GL_TEXTURE_BINDING_2D:
2172      case GL_TEXTURE_BINDING_CUBE_MAP:
2173      case GL_RESET_NOTIFICATION_STRATEGY_EXT:
2174      case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
2175      case GL_PROGRAM_BINARY_FORMATS_OES:
2176        {
2177            *type = GL_INT;
2178            *numParams = 1;
2179        }
2180        return true;
2181      case GL_MAX_SAMPLES_ANGLE:
2182        {
2183            if (getMaxSupportedSamples() != 0)
2184            {
2185                *type = GL_INT;
2186                *numParams = 1;
2187            }
2188            else
2189            {
2190                return false;
2191            }
2192        }
2193        return true;
2194      case GL_PIXEL_PACK_BUFFER_BINDING:
2195      case GL_PIXEL_UNPACK_BUFFER_BINDING:
2196        {
2197            if (supportsPBOs())
2198            {
2199                *type = GL_INT;
2200                *numParams = 1;
2201            }
2202            else
2203            {
2204                return false;
2205            }
2206        }
2207        return true;
2208      case GL_MAX_VIEWPORT_DIMS:
2209        {
2210            *type = GL_INT;
2211            *numParams = 2;
2212        }
2213        return true;
2214      case GL_VIEWPORT:
2215      case GL_SCISSOR_BOX:
2216        {
2217            *type = GL_INT;
2218            *numParams = 4;
2219        }
2220        return true;
2221      case GL_SHADER_COMPILER:
2222      case GL_SAMPLE_COVERAGE_INVERT:
2223      case GL_DEPTH_WRITEMASK:
2224      case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
2225      case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
2226      case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2227      case GL_SAMPLE_COVERAGE:
2228      case GL_SCISSOR_TEST:
2229      case GL_STENCIL_TEST:
2230      case GL_DEPTH_TEST:
2231      case GL_BLEND:
2232      case GL_DITHER:
2233      case GL_CONTEXT_ROBUST_ACCESS_EXT:
2234        {
2235            *type = GL_BOOL;
2236            *numParams = 1;
2237        }
2238        return true;
2239      case GL_COLOR_WRITEMASK:
2240        {
2241            *type = GL_BOOL;
2242            *numParams = 4;
2243        }
2244        return true;
2245      case GL_POLYGON_OFFSET_FACTOR:
2246      case GL_POLYGON_OFFSET_UNITS:
2247      case GL_SAMPLE_COVERAGE_VALUE:
2248      case GL_DEPTH_CLEAR_VALUE:
2249      case GL_LINE_WIDTH:
2250        {
2251            *type = GL_FLOAT;
2252            *numParams = 1;
2253        }
2254        return true;
2255      case GL_ALIASED_LINE_WIDTH_RANGE:
2256      case GL_ALIASED_POINT_SIZE_RANGE:
2257      case GL_DEPTH_RANGE:
2258        {
2259            *type = GL_FLOAT;
2260            *numParams = 2;
2261        }
2262        return true;
2263      case GL_COLOR_CLEAR_VALUE:
2264      case GL_BLEND_COLOR:
2265        {
2266            *type = GL_FLOAT;
2267            *numParams = 4;
2268        }
2269        return true;
2270      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2271        if (!supportsTextureFilterAnisotropy())
2272        {
2273            return false;
2274        }
2275        *type = GL_FLOAT;
2276        *numParams = 1;
2277        return true;
2278    }
2279
2280    if (mClientVersion < 3)
2281    {
2282        return false;
2283    }
2284
2285    // Check for ES3.0+ parameter names
2286    switch (pname)
2287    {
2288      case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2289      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2290      case GL_UNIFORM_BUFFER_BINDING:
2291      case GL_TRANSFORM_FEEDBACK_BINDING:
2292      case GL_COPY_READ_BUFFER_BINDING:
2293      case GL_COPY_WRITE_BUFFER_BINDING:
2294      case GL_TEXTURE_BINDING_3D:
2295      case GL_TEXTURE_BINDING_2D_ARRAY:
2296      case GL_MAX_3D_TEXTURE_SIZE:
2297      case GL_MAX_ARRAY_TEXTURE_LAYERS:
2298      case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2299      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2300      case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2301      case GL_MAX_VARYING_COMPONENTS:
2302      case GL_VERTEX_ARRAY_BINDING:
2303      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2304      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2305      case GL_NUM_EXTENSIONS:
2306      case GL_MAJOR_VERSION:
2307      case GL_MINOR_VERSION:
2308      case GL_MAX_ELEMENTS_INDICES:
2309      case GL_MAX_ELEMENTS_VERTICES:
2310      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2311      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2312      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2313        {
2314            *type = GL_INT;
2315            *numParams = 1;
2316        }
2317        return true;
2318
2319      case GL_MAX_ELEMENT_INDEX:
2320      case GL_MAX_UNIFORM_BLOCK_SIZE:
2321      case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2322      case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2323      case GL_MAX_SERVER_WAIT_TIMEOUT:
2324        {
2325            *type = GL_INT_64_ANGLEX;
2326            *numParams = 1;
2327        }
2328        return true;
2329
2330      case GL_TRANSFORM_FEEDBACK_ACTIVE:
2331      case GL_TRANSFORM_FEEDBACK_PAUSED:
2332        {
2333            *type = GL_BOOL;
2334            *numParams = 1;
2335        }
2336        return true;
2337    }
2338
2339    return false;
2340}
2341
2342bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams)
2343{
2344    if (mClientVersion < 3)
2345    {
2346        return false;
2347    }
2348
2349    switch (target)
2350    {
2351      case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2352      case GL_UNIFORM_BUFFER_BINDING:
2353        {
2354            *type = GL_INT;
2355            *numParams = 1;
2356        }
2357        return true;
2358      case GL_TRANSFORM_FEEDBACK_BUFFER_START:
2359      case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
2360      case GL_UNIFORM_BUFFER_START:
2361      case GL_UNIFORM_BUFFER_SIZE:
2362        {
2363            *type = GL_INT_64_ANGLEX;
2364            *numParams = 1;
2365        }
2366    }
2367
2368    return false;
2369}
2370
2371// Applies the render target surface, depth stencil surface, viewport rectangle and
2372// scissor rectangle to the renderer
2373bool Context::applyRenderTarget(GLenum drawMode, bool ignoreViewport)
2374{
2375    Framebuffer *framebufferObject = getDrawFramebuffer();
2376
2377    if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
2378    {
2379        return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2380    }
2381
2382    mRenderer->applyRenderTarget(framebufferObject);
2383
2384    if (!mRenderer->setViewport(mState.viewport, mState.zNear, mState.zFar, drawMode, mState.rasterizer.frontFace,
2385                                ignoreViewport))
2386    {
2387        return false;
2388    }
2389
2390    mRenderer->setScissorRectangle(mState.scissor, mState.scissorTest);
2391
2392    return true;
2393}
2394
2395// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) to the Direct3D 9 device
2396void Context::applyState(GLenum drawMode)
2397{
2398    Framebuffer *framebufferObject = getDrawFramebuffer();
2399    int samples = framebufferObject->getSamples();
2400
2401    mState.rasterizer.pointDrawMode = (drawMode == GL_POINTS);
2402    mState.rasterizer.multiSample = (samples != 0);
2403    mRenderer->setRasterizerState(mState.rasterizer);
2404
2405    unsigned int mask = 0;
2406    if (mState.sampleCoverage)
2407    {
2408        if (mState.sampleCoverageValue != 0)
2409        {
2410
2411            float threshold = 0.5f;
2412
2413            for (int i = 0; i < samples; ++i)
2414            {
2415                mask <<= 1;
2416
2417                if ((i + 1) * mState.sampleCoverageValue >= threshold)
2418                {
2419                    threshold += 1.0f;
2420                    mask |= 1;
2421                }
2422            }
2423        }
2424
2425        if (mState.sampleCoverageInvert)
2426        {
2427            mask = ~mask;
2428        }
2429    }
2430    else
2431    {
2432        mask = 0xFFFFFFFF;
2433    }
2434    mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask);
2435
2436    mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef,
2437                                    mState.rasterizer.frontFace == GL_CCW);
2438}
2439
2440// Applies the shaders and shader constants to the Direct3D 9 device
2441void Context::applyShaders(ProgramBinary *programBinary, bool transformFeedbackActive)
2442{
2443    const VertexAttribute *vertexAttributes = getCurrentVertexArray()->getVertexAttributes();
2444
2445    VertexFormat inputLayout[gl::MAX_VERTEX_ATTRIBS];
2446    VertexFormat::GetInputLayout(inputLayout, programBinary, vertexAttributes, mState.vertexAttribCurrentValues);
2447
2448    mRenderer->applyShaders(programBinary, mState.rasterizer.rasterizerDiscard, transformFeedbackActive, inputLayout);
2449
2450    programBinary->applyUniforms();
2451}
2452
2453size_t Context::getCurrentTexturesAndSamplerStates(ProgramBinary *programBinary, SamplerType type, Texture **outTextures,
2454                                                   TextureType *outTextureTypes, SamplerState *outSamplers)
2455{
2456    size_t samplerRange = programBinary->getUsedSamplerRange(type);
2457    for (size_t i = 0; i < samplerRange; i++)
2458    {
2459        outTextureTypes[i] = programBinary->getSamplerTextureType(type, i);
2460        GLint textureUnit = programBinary->getSamplerMapping(type, i);   // OpenGL texture image unit index
2461        if (textureUnit != -1)
2462        {
2463            outTextures[i] = getSamplerTexture(textureUnit, outTextureTypes[i]);
2464            outTextures[i]->getSamplerState(&outSamplers[i]);
2465            if (mState.samplers[textureUnit] != 0)
2466            {
2467                Sampler *samplerObject = getSampler(mState.samplers[textureUnit]);
2468                samplerObject->getState(&outSamplers[i]);
2469            }
2470        }
2471        else
2472        {
2473            outTextures[i] = NULL;
2474        }
2475    }
2476
2477    return samplerRange;
2478}
2479
2480void Context::generateSwizzles(Texture *textures[], size_t count)
2481{
2482    for (size_t i = 0; i < count; i++)
2483    {
2484        if (textures[i] && textures[i]->isSwizzled())
2485        {
2486            mRenderer->generateSwizzle(textures[i]);
2487        }
2488    }
2489}
2490
2491// For each Direct3D sampler of either the pixel or vertex stage,
2492// looks up the corresponding OpenGL texture image unit and texture type,
2493// and sets the texture and its addressing/filtering state (or NULL when inactive).
2494void Context::applyTextures(SamplerType shaderType, Texture *textures[], TextureType *textureTypes, SamplerState *samplers,
2495                            size_t textureCount, const FramebufferTextureSerialArray& framebufferSerials,
2496                            size_t framebufferSerialCount)
2497{
2498    // Range of Direct3D samplers of given sampler type
2499    size_t samplerCount = (shaderType == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS
2500                                                        : mRenderer->getMaxVertexTextureImageUnits();
2501
2502    for (size_t samplerIndex = 0; samplerIndex < textureCount; samplerIndex++)
2503    {
2504        Texture *texture = textures[samplerIndex];
2505        const SamplerState &sampler = samplers[samplerIndex];
2506        TextureType textureType = textureTypes[samplerIndex];
2507
2508        if (texture)
2509        {
2510            // TODO: std::binary_search may become unavailable using older versions of GCC
2511            if (texture->isSamplerComplete(sampler) &&
2512                !std::binary_search(framebufferSerials.begin(), framebufferSerials.begin() + framebufferSerialCount, texture->getTextureSerial()))
2513            {
2514                mRenderer->setSamplerState(shaderType, samplerIndex, sampler);
2515                mRenderer->setTexture(shaderType, samplerIndex, texture);
2516                texture->resetDirty();
2517            }
2518            else
2519            {
2520                Texture *incompleteTexture = getIncompleteTexture(textureType);
2521                mRenderer->setTexture(shaderType, samplerIndex, incompleteTexture);
2522                incompleteTexture->resetDirty();
2523            }
2524        }
2525        else
2526        {
2527            mRenderer->setTexture(shaderType, samplerIndex, NULL);
2528        }
2529    }
2530
2531    for (size_t samplerIndex = textureCount; samplerIndex < samplerCount; samplerIndex++)
2532    {
2533        mRenderer->setTexture(shaderType, samplerIndex, NULL);
2534    }
2535}
2536
2537bool Context::applyUniformBuffers()
2538{
2539    Program *programObject = getProgram(mState.currentProgram);
2540    ProgramBinary *programBinary = programObject->getProgramBinary();
2541
2542    std::vector<gl::Buffer*> boundBuffers;
2543
2544    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < programBinary->getActiveUniformBlockCount(); uniformBlockIndex++)
2545    {
2546        GLuint blockBinding = programObject->getUniformBlockBinding(uniformBlockIndex);
2547        const OffsetBindingPointer<Buffer>& boundBuffer = mState.uniformBuffers[blockBinding];
2548        if (boundBuffer.id() == 0)
2549        {
2550            // undefined behaviour
2551            return false;
2552        }
2553        else
2554        {
2555            gl::Buffer *uniformBuffer = boundBuffer.get();
2556            ASSERT(uniformBuffer);
2557            boundBuffers.push_back(uniformBuffer);
2558        }
2559    }
2560
2561    return programBinary->applyUniformBuffers(boundBuffers);
2562}
2563
2564bool Context::applyTransformFeedbackBuffers()
2565{
2566    TransformFeedback *curTransformFeedback = getCurrentTransformFeedback();
2567    if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused())
2568    {
2569        Buffer *transformFeedbackBuffers[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
2570        GLintptr transformFeedbackOffsets[IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS];
2571        for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
2572        {
2573            transformFeedbackBuffers[i] = mState.transformFeedbackBuffers[i].get();
2574            transformFeedbackOffsets[i] = mState.transformFeedbackBuffers[i].getOffset();
2575        }
2576        mRenderer->applyTransformFeedbackBuffers(transformFeedbackBuffers, transformFeedbackOffsets);
2577        return true;
2578    }
2579    else
2580    {
2581        return false;
2582    }
2583}
2584
2585void Context::markTransformFeedbackUsage()
2586{
2587    for (size_t i = 0; i < IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_BUFFERS; i++)
2588    {
2589        Buffer *buffer = mState.transformFeedbackBuffers[i].get();
2590        if (buffer)
2591        {
2592            buffer->markTransformFeedbackUsage();
2593        }
2594    }
2595}
2596
2597void Context::clear(GLbitfield mask)
2598{
2599    if (isRasterizerDiscardEnabled())
2600    {
2601        return;
2602    }
2603
2604    ClearParameters clearParams = { 0 };
2605    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2606    {
2607        clearParams.clearColor[i] = false;
2608    }
2609    clearParams.colorFClearValue = mState.colorClearValue;
2610    clearParams.colorClearType = GL_FLOAT;
2611    clearParams.colorMaskRed = mState.blend.colorMaskRed;
2612    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2613    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2614    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2615    clearParams.clearDepth = false;
2616    clearParams.depthClearValue = mState.depthClearValue;
2617    clearParams.clearStencil = false;
2618    clearParams.stencilClearValue = mState.stencilClearValue;
2619    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2620    clearParams.scissorEnabled = mState.scissorTest;
2621    clearParams.scissor = mState.scissor;
2622
2623    Framebuffer *framebufferObject = getDrawFramebuffer();
2624    if (mask & GL_COLOR_BUFFER_BIT)
2625    {
2626        if (framebufferObject->hasEnabledColorAttachment())
2627        {
2628            for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2629            {
2630                clearParams.clearColor[i] = true;
2631            }
2632        }
2633    }
2634
2635    if (mask & GL_DEPTH_BUFFER_BIT)
2636    {
2637        if (mState.depthStencil.depthMask && framebufferObject->getDepthbufferType() != GL_NONE)
2638        {
2639            clearParams.clearDepth = true;
2640        }
2641    }
2642
2643    if (mask & GL_STENCIL_BUFFER_BIT)
2644    {
2645        if (framebufferObject->getStencilbufferType() != GL_NONE)
2646        {
2647            rx::RenderTarget *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
2648            if (!depthStencil)
2649            {
2650                ERR("Depth stencil pointer unexpectedly null.");
2651                return;
2652            }
2653
2654            if (gl::GetStencilBits(depthStencil->getActualFormat(), mClientVersion) > 0)
2655            {
2656                clearParams.clearStencil = true;
2657            }
2658        }
2659    }
2660
2661
2662    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
2663    {
2664        return;
2665    }
2666
2667    mRenderer->clear(clearParams, framebufferObject);
2668}
2669
2670void Context::clearBufferfv(GLenum buffer, int drawbuffer, const float *values)
2671{
2672    if (isRasterizerDiscardEnabled())
2673    {
2674        return;
2675    }
2676
2677    // glClearBufferfv can be called to clear the color buffer or depth buffer
2678    ClearParameters clearParams = { 0 };
2679
2680    if (buffer == GL_COLOR)
2681    {
2682        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2683        {
2684            clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2685        }
2686        clearParams.colorFClearValue = ColorF(values[0], values[1], values[2], values[3]);
2687        clearParams.colorClearType = GL_FLOAT;
2688    }
2689    else
2690    {
2691        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2692        {
2693            clearParams.clearColor[i] = false;
2694        }
2695        clearParams.colorFClearValue = mState.colorClearValue;
2696        clearParams.colorClearType = GL_FLOAT;
2697    }
2698
2699    clearParams.colorMaskRed = mState.blend.colorMaskRed;
2700    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2701    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2702    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2703
2704    if (buffer == GL_DEPTH)
2705    {
2706        clearParams.clearDepth = true;
2707        clearParams.depthClearValue = values[0];
2708    }
2709    else
2710    {
2711        clearParams.clearDepth = false;
2712        clearParams.depthClearValue = mState.depthClearValue;
2713    }
2714
2715    clearParams.clearStencil = false;
2716    clearParams.stencilClearValue = mState.stencilClearValue;
2717    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2718    clearParams.scissorEnabled = mState.scissorTest;
2719    clearParams.scissor = mState.scissor;
2720
2721    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
2722    {
2723        return;
2724    }
2725
2726    mRenderer->clear(clearParams, getDrawFramebuffer());
2727}
2728
2729void Context::clearBufferuiv(GLenum buffer, int drawbuffer, const unsigned int *values)
2730{
2731    if (isRasterizerDiscardEnabled())
2732    {
2733        return;
2734    }
2735
2736    // glClearBufferuv can only be called to clear a color buffer
2737    ClearParameters clearParams = { 0 };
2738    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2739    {
2740        clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2741    }
2742    clearParams.colorUIClearValue = ColorUI(values[0], values[1], values[2], values[3]);
2743    clearParams.colorClearType = GL_UNSIGNED_INT;
2744    clearParams.colorMaskRed = mState.blend.colorMaskRed;
2745    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2746    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2747    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2748    clearParams.clearDepth = false;
2749    clearParams.depthClearValue = mState.depthClearValue;
2750    clearParams.clearStencil = false;
2751    clearParams.stencilClearValue = mState.stencilClearValue;
2752    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2753    clearParams.scissorEnabled = mState.scissorTest;
2754    clearParams.scissor = mState.scissor;
2755
2756    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
2757    {
2758        return;
2759    }
2760
2761    mRenderer->clear(clearParams, getDrawFramebuffer());
2762}
2763
2764void Context::clearBufferiv(GLenum buffer, int drawbuffer, const int *values)
2765{
2766    if (isRasterizerDiscardEnabled())
2767    {
2768        return;
2769    }
2770
2771    // glClearBufferfv can be called to clear the color buffer or stencil buffer
2772    ClearParameters clearParams = { 0 };
2773
2774    if (buffer == GL_COLOR)
2775    {
2776        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2777        {
2778            clearParams.clearColor[i] = (drawbuffer == static_cast<int>(i));
2779        }
2780        clearParams.colorIClearValue = ColorI(values[0], values[1], values[2], values[3]);
2781        clearParams.colorClearType = GL_INT;
2782    }
2783    else
2784    {
2785        for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2786        {
2787            clearParams.clearColor[i] = false;
2788        }
2789        clearParams.colorFClearValue = mState.colorClearValue;
2790        clearParams.colorClearType = GL_FLOAT;
2791    }
2792
2793    clearParams.colorMaskRed = mState.blend.colorMaskRed;
2794    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2795    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2796    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2797
2798    clearParams.clearDepth = false;
2799    clearParams.depthClearValue = mState.depthClearValue;
2800
2801    if (buffer == GL_STENCIL)
2802    {
2803        clearParams.clearStencil = true;
2804        clearParams.stencilClearValue = values[1];
2805    }
2806    else
2807    {
2808        clearParams.clearStencil = false;
2809        clearParams.stencilClearValue = mState.stencilClearValue;
2810    }
2811    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2812
2813    clearParams.scissorEnabled = mState.scissorTest;
2814    clearParams.scissor = mState.scissor;
2815
2816    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
2817    {
2818        return;
2819    }
2820
2821    mRenderer->clear(clearParams, getDrawFramebuffer());
2822}
2823
2824void Context::clearBufferfi(GLenum buffer, int drawbuffer, float depth, int stencil)
2825{
2826    if (isRasterizerDiscardEnabled())
2827    {
2828        return;
2829    }
2830
2831    // glClearBufferfi can only be called to clear a depth stencil buffer
2832    ClearParameters clearParams = { 0 };
2833    for (unsigned int i = 0; i < ArraySize(clearParams.clearColor); i++)
2834    {
2835        clearParams.clearColor[i] = false;
2836    }
2837    clearParams.colorFClearValue = mState.colorClearValue;
2838    clearParams.colorClearType = GL_FLOAT;
2839    clearParams.colorMaskRed = mState.blend.colorMaskRed;
2840    clearParams.colorMaskGreen = mState.blend.colorMaskGreen;
2841    clearParams.colorMaskBlue = mState.blend.colorMaskBlue;
2842    clearParams.colorMaskAlpha = mState.blend.colorMaskAlpha;
2843    clearParams.clearDepth = true;
2844    clearParams.depthClearValue = depth;
2845    clearParams.clearStencil = true;
2846    clearParams.stencilClearValue = stencil;
2847    clearParams.stencilWriteMask = mState.depthStencil.stencilWritemask;
2848    clearParams.scissorEnabled = mState.scissorTest;
2849    clearParams.scissor = mState.scissor;
2850
2851    if (!applyRenderTarget(GL_TRIANGLES, true))   // Clips the clear to the scissor rectangle but not the viewport
2852    {
2853        return;
2854    }
2855
2856    mRenderer->clear(clearParams, getDrawFramebuffer());
2857}
2858
2859void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2860                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2861{
2862    gl::Framebuffer *framebuffer = getReadFramebuffer();
2863
2864    bool isSized = IsSizedInternalFormat(format, mClientVersion);
2865    GLenum sizedInternalFormat = (isSized ? format : GetSizedInternalFormat(format, type, mClientVersion));
2866    GLuint outputPitch = GetRowPitch(sizedInternalFormat, type, mClientVersion, width, mState.pack.alignment);
2867
2868    mRenderer->readPixels(framebuffer, x, y, width, height, format, type, outputPitch, mState.pack, pixels);
2869}
2870
2871void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
2872{
2873    if (!mState.currentProgram)
2874    {
2875        return gl::error(GL_INVALID_OPERATION);
2876    }
2877
2878    ProgramBinary *programBinary = getCurrentProgramBinary();
2879    programBinary->applyUniforms();
2880
2881    Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2882    TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2883    SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2884    size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
2885
2886    Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
2887    TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
2888    SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
2889    size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
2890
2891    generateSwizzles(vsTextures, vsTextureCount);
2892    generateSwizzles(psTextures, psTextureCount);
2893
2894    if (!mRenderer->applyPrimitiveType(mode, count))
2895    {
2896        return;
2897    }
2898
2899    if (!applyRenderTarget(mode, false))
2900    {
2901        return;
2902    }
2903
2904    applyState(mode);
2905
2906    GLenum err = mRenderer->applyVertexBuffer(programBinary, getCurrentVertexArray()->getVertexAttributes(), mState.vertexAttribCurrentValues, first, count, instances);
2907    if (err != GL_NO_ERROR)
2908    {
2909        return gl::error(err);
2910    }
2911
2912    bool transformFeedbackActive = applyTransformFeedbackBuffers();
2913
2914    applyShaders(programBinary, transformFeedbackActive);
2915
2916    FramebufferTextureSerialArray frameBufferSerials;
2917    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
2918
2919    applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
2920    applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
2921
2922    if (!applyUniformBuffers())
2923    {
2924        return;
2925    }
2926
2927    if (!programBinary->validateSamplers(NULL))
2928    {
2929        return gl::error(GL_INVALID_OPERATION);
2930    }
2931
2932    if (!skipDraw(mode))
2933    {
2934        mRenderer->drawArrays(mode, count, instances, transformFeedbackActive);
2935
2936        if (transformFeedbackActive)
2937        {
2938            markTransformFeedbackUsage();
2939        }
2940    }
2941}
2942
2943void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instances)
2944{
2945    if (!mState.currentProgram)
2946    {
2947        return gl::error(GL_INVALID_OPERATION);
2948    }
2949
2950    VertexArray *vao = getCurrentVertexArray();
2951    if (!indices && !vao->getElementArrayBuffer())
2952    {
2953        return gl::error(GL_INVALID_OPERATION);
2954    }
2955
2956    ProgramBinary *programBinary = getCurrentProgramBinary();
2957    programBinary->applyUniforms();
2958
2959    Texture *vsTextures[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2960    TextureType vsTextureTypes[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2961    SamplerState vsSamplers[IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS];
2962    size_t vsTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers);
2963
2964    Texture *psTextures[MAX_TEXTURE_IMAGE_UNITS];
2965    TextureType psTextureTypes[MAX_TEXTURE_IMAGE_UNITS];
2966    SamplerState psSamplers[MAX_TEXTURE_IMAGE_UNITS];
2967    size_t psTextureCount = getCurrentTexturesAndSamplerStates(programBinary, SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers);
2968
2969    generateSwizzles(vsTextures, vsTextureCount);
2970    generateSwizzles(psTextures, psTextureCount);
2971
2972    if (!mRenderer->applyPrimitiveType(mode, count))
2973    {
2974        return;
2975    }
2976
2977    if (!applyRenderTarget(mode, false))
2978    {
2979        return;
2980    }
2981
2982    applyState(mode);
2983
2984    rx::TranslatedIndexData indexInfo;
2985    GLenum err = mRenderer->applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo);
2986    if (err != GL_NO_ERROR)
2987    {
2988        return gl::error(err);
2989    }
2990
2991    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2992    err = mRenderer->applyVertexBuffer(programBinary, vao->getVertexAttributes(), mState.vertexAttribCurrentValues, indexInfo.minIndex, vertexCount, instances);
2993    if (err != GL_NO_ERROR)
2994    {
2995        return gl::error(err);
2996    }
2997
2998    bool transformFeedbackActive = applyTransformFeedbackBuffers();
2999    // Transform feedback is not allowed for DrawElements, this error should have been caught at the API validation
3000    // layer.
3001    ASSERT(!transformFeedbackActive);
3002
3003    applyShaders(programBinary, transformFeedbackActive);
3004
3005    FramebufferTextureSerialArray frameBufferSerials;
3006    size_t framebufferSerialCount = getBoundFramebufferTextureSerials(&frameBufferSerials);
3007
3008    applyTextures(SAMPLER_VERTEX, vsTextures, vsTextureTypes, vsSamplers, vsTextureCount, frameBufferSerials, framebufferSerialCount);
3009    applyTextures(SAMPLER_PIXEL, psTextures, psTextureTypes, psSamplers, psTextureCount, frameBufferSerials, framebufferSerialCount);
3010
3011    if (!applyUniformBuffers())
3012    {
3013        return;
3014    }
3015
3016    if (!programBinary->validateSamplers(NULL))
3017    {
3018        return gl::error(GL_INVALID_OPERATION);
3019    }
3020
3021    if (!skipDraw(mode))
3022    {
3023        mRenderer->drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances);
3024    }
3025}
3026
3027// Implements glFlush when block is false, glFinish when block is true
3028void Context::sync(bool block)
3029{
3030    mRenderer->sync(block);
3031}
3032
3033void Context::recordInvalidEnum()
3034{
3035    mInvalidEnum = true;
3036}
3037
3038void Context::recordInvalidValue()
3039{
3040    mInvalidValue = true;
3041}
3042
3043void Context::recordInvalidOperation()
3044{
3045    mInvalidOperation = true;
3046}
3047
3048void Context::recordOutOfMemory()
3049{
3050    mOutOfMemory = true;
3051}
3052
3053void Context::recordInvalidFramebufferOperation()
3054{
3055    mInvalidFramebufferOperation = true;
3056}
3057
3058// Get one of the recorded errors and clear its flag, if any.
3059// [OpenGL ES 2.0.24] section 2.5 page 13.
3060GLenum Context::getError()
3061{
3062    if (mInvalidEnum)
3063    {
3064        mInvalidEnum = false;
3065
3066        return GL_INVALID_ENUM;
3067    }
3068
3069    if (mInvalidValue)
3070    {
3071        mInvalidValue = false;
3072
3073        return GL_INVALID_VALUE;
3074    }
3075
3076    if (mInvalidOperation)
3077    {
3078        mInvalidOperation = false;
3079
3080        return GL_INVALID_OPERATION;
3081    }
3082
3083    if (mOutOfMemory)
3084    {
3085        mOutOfMemory = false;
3086
3087        return GL_OUT_OF_MEMORY;
3088    }
3089
3090    if (mInvalidFramebufferOperation)
3091    {
3092        mInvalidFramebufferOperation = false;
3093
3094        return GL_INVALID_FRAMEBUFFER_OPERATION;
3095    }
3096
3097    return GL_NO_ERROR;
3098}
3099
3100GLenum Context::getResetStatus()
3101{
3102    if (mResetStatus == GL_NO_ERROR && !mContextLost)
3103    {
3104        // mResetStatus will be set by the markContextLost callback
3105        // in the case a notification is sent
3106        mRenderer->testDeviceLost(true);
3107    }
3108
3109    GLenum status = mResetStatus;
3110
3111    if (mResetStatus != GL_NO_ERROR)
3112    {
3113        ASSERT(mContextLost);
3114
3115        if (mRenderer->testDeviceResettable())
3116        {
3117            mResetStatus = GL_NO_ERROR;
3118        }
3119    }
3120
3121    return status;
3122}
3123
3124bool Context::isResetNotificationEnabled()
3125{
3126    return (mResetStrategy == GL_LOSE_CONTEXT_ON_RESET_EXT);
3127}
3128
3129int Context::getClientVersion() const
3130{
3131    return mClientVersion;
3132}
3133
3134int Context::getMajorShaderModel() const
3135{
3136    return mMajorShaderModel;
3137}
3138
3139float Context::getMaximumPointSize() const
3140{
3141    return mMaximumPointSize;
3142}
3143
3144unsigned int Context::getMaximumCombinedTextureImageUnits() const
3145{
3146    return mRenderer->getMaxCombinedTextureImageUnits();
3147}
3148
3149unsigned int Context::getMaximumCombinedUniformBufferBindings() const
3150{
3151    return mRenderer->getMaxVertexShaderUniformBuffers() +
3152           mRenderer->getMaxFragmentShaderUniformBuffers();
3153}
3154
3155int Context::getMaxSupportedSamples() const
3156{
3157    return mRenderer->getMaxSupportedSamples();
3158}
3159
3160GLsizei Context::getMaxSupportedFormatSamples(GLenum internalFormat) const
3161{
3162    return mRenderer->getMaxSupportedFormatSamples(internalFormat);
3163}
3164
3165GLsizei Context::getNumSampleCounts(GLenum internalFormat) const
3166{
3167    return mRenderer->getNumSampleCounts(internalFormat);
3168}
3169
3170void Context::getSampleCounts(GLenum internalFormat, GLsizei bufSize, GLint *params) const
3171{
3172    mRenderer->getSampleCounts(internalFormat, bufSize, params);
3173}
3174
3175unsigned int Context::getMaxTransformFeedbackBufferBindings() const
3176{
3177    return mRenderer->getMaxTransformFeedbackBuffers();
3178}
3179
3180GLintptr Context::getUniformBufferOffsetAlignment() const
3181{
3182    // setting a large alignment forces uniform buffers to bind with zero offset
3183    return static_cast<GLintptr>(std::numeric_limits<GLint>::max());
3184}
3185
3186unsigned int Context::getMaximumRenderTargets() const
3187{
3188    return mRenderer->getMaxRenderTargets();
3189}
3190
3191bool Context::supportsEventQueries() const
3192{
3193    return mSupportsEventQueries;
3194}
3195
3196bool Context::supportsOcclusionQueries() const
3197{
3198    return mSupportsOcclusionQueries;
3199}
3200
3201bool Context::supportsBGRATextures() const
3202{
3203    return mSupportsBGRATextures;
3204}
3205
3206bool Context::supportsDXT1Textures() const
3207{
3208    return mSupportsDXT1Textures;
3209}
3210
3211bool Context::supportsDXT3Textures() const
3212{
3213    return mSupportsDXT3Textures;
3214}
3215
3216bool Context::supportsDXT5Textures() const
3217{
3218    return mSupportsDXT5Textures;
3219}
3220
3221bool Context::supportsFloat32Textures() const
3222{
3223    return mSupportsFloat32Textures;
3224}
3225
3226bool Context::supportsFloat32LinearFilter() const
3227{
3228    return mSupportsFloat32LinearFilter;
3229}
3230
3231bool Context::supportsFloat32RenderableTextures() const
3232{
3233    return mSupportsFloat32RenderableTextures;
3234}
3235
3236bool Context::supportsFloat16Textures() const
3237{
3238    return mSupportsFloat16Textures;
3239}
3240
3241bool Context::supportsFloat16LinearFilter() const
3242{
3243    return mSupportsFloat16LinearFilter;
3244}
3245
3246bool Context::supportsFloat16RenderableTextures() const
3247{
3248    return mSupportsFloat16RenderableTextures;
3249}
3250
3251int Context::getMaximumRenderbufferDimension() const
3252{
3253    return mMaxRenderbufferDimension;
3254}
3255
3256int Context::getMaximum2DTextureDimension() const
3257{
3258    return mMax2DTextureDimension;
3259}
3260
3261int Context::getMaximumCubeTextureDimension() const
3262{
3263    return mMaxCubeTextureDimension;
3264}
3265
3266int Context::getMaximum3DTextureDimension() const
3267{
3268    return mMax3DTextureDimension;
3269}
3270
3271int Context::getMaximum2DArrayTextureLayers() const
3272{
3273    return mMax2DArrayTextureLayers;
3274}
3275
3276int Context::getMaximum2DTextureLevel() const
3277{
3278    return mMax2DTextureLevel;
3279}
3280
3281int Context::getMaximumCubeTextureLevel() const
3282{
3283    return mMaxCubeTextureLevel;
3284}
3285
3286int Context::getMaximum3DTextureLevel() const
3287{
3288    return mMax3DTextureLevel;
3289}
3290
3291int Context::getMaximum2DArrayTextureLevel() const
3292{
3293    return mMax2DArrayTextureLevel;
3294}
3295
3296bool Context::supportsLuminanceTextures() const
3297{
3298    return mSupportsLuminanceTextures;
3299}
3300
3301bool Context::supportsLuminanceAlphaTextures() const
3302{
3303    return mSupportsLuminanceAlphaTextures;
3304}
3305
3306bool Context::supportsRGTextures() const
3307{
3308    return mSupportsRGTextures;
3309}
3310
3311bool Context::supportsDepthTextures() const
3312{
3313    return mSupportsDepthTextures;
3314}
3315
3316bool Context::supports32bitIndices() const
3317{
3318    return mSupports32bitIndices;
3319}
3320
3321bool Context::supportsNonPower2Texture() const
3322{
3323    return mSupportsNonPower2Texture;
3324}
3325
3326bool Context::supportsInstancing() const
3327{
3328    return mSupportsInstancing;
3329}
3330
3331bool Context::supportsTextureFilterAnisotropy() const
3332{
3333    return mSupportsTextureFilterAnisotropy;
3334}
3335
3336bool Context::supportsPBOs() const
3337{
3338    return mSupportsPBOs;
3339}
3340
3341float Context::getTextureMaxAnisotropy() const
3342{
3343    return mMaxTextureAnisotropy;
3344}
3345
3346void Context::getCurrentReadFormatType(GLenum *internalFormat, GLenum *format, GLenum *type)
3347{
3348    Framebuffer *framebuffer = getReadFramebuffer();
3349    ASSERT(framebuffer && framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE);
3350
3351    FramebufferAttachment *attachment = framebuffer->getReadColorbuffer();
3352    ASSERT(attachment);
3353
3354    *internalFormat = attachment->getActualFormat();
3355    *format = gl::GetFormat(attachment->getActualFormat(), mClientVersion);
3356    *type = gl::GetType(attachment->getActualFormat(), mClientVersion);
3357}
3358
3359void Context::detachBuffer(GLuint buffer)
3360{
3361    // [OpenGL ES 2.0.24] section 2.9 page 22:
3362    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3363    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3364
3365    if (mState.arrayBuffer.id() == buffer)
3366    {
3367        mState.arrayBuffer.set(NULL);
3368    }
3369
3370    // mark as freed among the vertex array objects
3371    for (auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++)
3372    {
3373        vaoIt->second->detachBuffer(buffer);
3374    }
3375}
3376
3377void Context::detachTexture(GLuint texture)
3378{
3379    // [OpenGL ES 2.0.24] section 3.8 page 84:
3380    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3381    // rebound to texture object zero
3382
3383    for (int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3384    {
3385        for (int sampler = 0; sampler < IMPLEMENTATION_MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3386        {
3387            if (mState.samplerTexture[type][sampler].id() == texture)
3388            {
3389                mState.samplerTexture[type][sampler].set(NULL);
3390            }
3391        }
3392    }
3393
3394    // [OpenGL ES 2.0.24] section 4.4 page 112:
3395    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3396    // as if Texture2DAttachment had been called, with a texture of 0, for each attachment point to which this
3397    // image was attached in the currently bound framebuffer.
3398
3399    Framebuffer *readFramebuffer = getReadFramebuffer();
3400    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3401
3402    if (readFramebuffer)
3403    {
3404        readFramebuffer->detachTexture(texture);
3405    }
3406
3407    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3408    {
3409        drawFramebuffer->detachTexture(texture);
3410    }
3411}
3412
3413void Context::detachFramebuffer(GLuint framebuffer)
3414{
3415    // [OpenGL ES 2.0.24] section 4.4 page 107:
3416    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3417    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3418
3419    if (mState.readFramebuffer == framebuffer)
3420    {
3421        bindReadFramebuffer(0);
3422    }
3423
3424    if (mState.drawFramebuffer == framebuffer)
3425    {
3426        bindDrawFramebuffer(0);
3427    }
3428}
3429
3430void Context::detachRenderbuffer(GLuint renderbuffer)
3431{
3432    // [OpenGL ES 2.0.24] section 4.4 page 109:
3433    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3434    // had been executed with the target RENDERBUFFER and name of zero.
3435
3436    if (mState.renderbuffer.id() == renderbuffer)
3437    {
3438        bindRenderbuffer(0);
3439    }
3440
3441    // [OpenGL ES 2.0.24] section 4.4 page 111:
3442    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3443    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3444    // point to which this image was attached in the currently bound framebuffer.
3445
3446    Framebuffer *readFramebuffer = getReadFramebuffer();
3447    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3448
3449    if (readFramebuffer)
3450    {
3451        readFramebuffer->detachRenderbuffer(renderbuffer);
3452    }
3453
3454    if (drawFramebuffer && drawFramebuffer != readFramebuffer)
3455    {
3456        drawFramebuffer->detachRenderbuffer(renderbuffer);
3457    }
3458}
3459
3460void Context::detachVertexArray(GLuint vertexArray)
3461{
3462    // [OpenGL ES 3.0.2] section 2.10 page 43:
3463    // If a vertex array object that is currently bound is deleted, the binding
3464    // for that object reverts to zero and the default vertex array becomes current.
3465    if (mState.vertexArray == vertexArray)
3466    {
3467        bindVertexArray(0);
3468    }
3469}
3470
3471void Context::detachTransformFeedback(GLuint transformFeedback)
3472{
3473    if (mState.transformFeedback.id() == transformFeedback)
3474    {
3475        bindTransformFeedback(0);
3476    }
3477}
3478
3479void Context::detachSampler(GLuint sampler)
3480{
3481    // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3482    // If a sampler object that is currently bound to one or more texture units is
3483    // deleted, it is as though BindSampler is called once for each texture unit to
3484    // which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3485    for (unsigned int textureUnit = 0; textureUnit < ArraySize(mState.samplers); textureUnit++)
3486    {
3487        if (mState.samplers[textureUnit] == sampler)
3488        {
3489            mState.samplers[textureUnit] = 0;
3490        }
3491    }
3492}
3493
3494Texture *Context::getIncompleteTexture(TextureType type)
3495{
3496    Texture *t = mIncompleteTextures[type].get();
3497
3498    if (t == NULL)
3499    {
3500        const GLubyte color[] = { 0, 0, 0, 255 };
3501        const PixelUnpackState incompleteUnpackState(1);
3502
3503        switch (type)
3504        {
3505          default:
3506            UNREACHABLE();
3507            // default falls through to TEXTURE_2D
3508
3509          case TEXTURE_2D:
3510            {
3511                Texture2D *incomplete2d = new Texture2D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3512                incomplete2d->setImage(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3513                t = incomplete2d;
3514            }
3515            break;
3516
3517          case TEXTURE_CUBE:
3518            {
3519              TextureCubeMap *incompleteCube = new TextureCubeMap(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3520
3521              incompleteCube->setImagePosX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3522              incompleteCube->setImageNegX(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3523              incompleteCube->setImagePosY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3524              incompleteCube->setImageNegY(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3525              incompleteCube->setImagePosZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3526              incompleteCube->setImageNegZ(0, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3527
3528              t = incompleteCube;
3529            }
3530            break;
3531
3532          case TEXTURE_3D:
3533            {
3534                Texture3D *incomplete3d = new Texture3D(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3535                incomplete3d->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3536
3537                t = incomplete3d;
3538            }
3539            break;
3540
3541          case TEXTURE_2D_ARRAY:
3542            {
3543                Texture2DArray *incomplete2darray = new Texture2DArray(mRenderer, Texture::INCOMPLETE_TEXTURE_ID);
3544                incomplete2darray->setImage(0, 1, 1, 1, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
3545
3546                t = incomplete2darray;
3547            }
3548            break;
3549        }
3550
3551        mIncompleteTextures[type].set(t);
3552    }
3553
3554    return t;
3555}
3556
3557bool Context::skipDraw(GLenum drawMode)
3558{
3559    if (drawMode == GL_POINTS)
3560    {
3561        // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
3562        // which affects varying interpolation. Since the value of gl_PointSize is
3563        // undefined when not written, just skip drawing to avoid unexpected results.
3564        if (!getCurrentProgramBinary()->usesPointSize())
3565        {
3566            // This is stictly speaking not an error, but developers should be
3567            // notified of risking undefined behavior.
3568            ERR("Point rendering without writing to gl_PointSize.");
3569
3570            return true;
3571        }
3572    }
3573    else if (IsTriangleMode(drawMode))
3574    {
3575        if (mState.rasterizer.cullFace && mState.rasterizer.cullMode == GL_FRONT_AND_BACK)
3576        {
3577            return true;
3578        }
3579    }
3580
3581    return false;
3582}
3583
3584void Context::setVertexAttribf(GLuint index, const GLfloat values[4])
3585{
3586    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
3587    mState.vertexAttribCurrentValues[index].setFloatValues(values);
3588}
3589
3590void Context::setVertexAttribu(GLuint index, const GLuint values[4])
3591{
3592    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
3593    mState.vertexAttribCurrentValues[index].setUnsignedIntValues(values);
3594}
3595
3596void Context::setVertexAttribi(GLuint index, const GLint values[4])
3597{
3598    ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
3599    mState.vertexAttribCurrentValues[index].setIntValues(values);
3600}
3601
3602void Context::setVertexAttribDivisor(GLuint index, GLuint divisor)
3603{
3604    getCurrentVertexArray()->setVertexAttribDivisor(index, divisor);
3605}
3606
3607void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
3608{
3609    mResourceManager->checkSamplerAllocation(sampler);
3610
3611    Sampler *samplerObject = getSampler(sampler);
3612    ASSERT(samplerObject);
3613
3614    switch (pname)
3615    {
3616      case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
3617      case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
3618      case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
3619      case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
3620      case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
3621      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
3622      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
3623      case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
3624      case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
3625      default:                       UNREACHABLE(); break;
3626    }
3627}
3628
3629void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
3630{
3631    mResourceManager->checkSamplerAllocation(sampler);
3632
3633    Sampler *samplerObject = getSampler(sampler);
3634    ASSERT(samplerObject);
3635
3636    switch (pname)
3637    {
3638      case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(uiround<GLenum>(param));       break;
3639      case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(uiround<GLenum>(param));       break;
3640      case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(uiround<GLenum>(param));           break;
3641      case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(uiround<GLenum>(param));           break;
3642      case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(uiround<GLenum>(param));           break;
3643      case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                      break;
3644      case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                      break;
3645      case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(uiround<GLenum>(param));  break;
3646      case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(uiround<GLenum>(param));  break;
3647      default:                       UNREACHABLE(); break;
3648    }
3649}
3650
3651GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
3652{
3653    mResourceManager->checkSamplerAllocation(sampler);
3654
3655    Sampler *samplerObject = getSampler(sampler);
3656    ASSERT(samplerObject);
3657
3658    switch (pname)
3659    {
3660      case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
3661      case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
3662      case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
3663      case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
3664      case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
3665      case GL_TEXTURE_MIN_LOD:       return uiround<GLint>(samplerObject->getMinLod());
3666      case GL_TEXTURE_MAX_LOD:       return uiround<GLint>(samplerObject->getMaxLod());
3667      case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
3668      case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
3669      default:                       UNREACHABLE(); return 0;
3670    }
3671}
3672
3673GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
3674{
3675    mResourceManager->checkSamplerAllocation(sampler);
3676
3677    Sampler *samplerObject = getSampler(sampler);
3678    ASSERT(samplerObject);
3679
3680    switch (pname)
3681    {
3682      case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
3683      case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
3684      case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
3685      case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
3686      case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
3687      case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
3688      case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
3689      case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
3690      case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
3691      default:                       UNREACHABLE(); return 0;
3692    }
3693}
3694
3695// keep list sorted in following order
3696// OES extensions
3697// EXT extensions
3698// Vendor extensions
3699void Context::initExtensionString()
3700{
3701    // Do not report extension in GLES 3 contexts for now
3702    if (mClientVersion == 2)
3703    {
3704        // OES extensions
3705        if (supports32bitIndices())
3706        {
3707            mExtensionStringList.push_back("GL_OES_element_index_uint");
3708        }
3709
3710        mExtensionStringList.push_back("GL_OES_packed_depth_stencil");
3711        mExtensionStringList.push_back("GL_OES_get_program_binary");
3712        mExtensionStringList.push_back("GL_OES_rgb8_rgba8");
3713
3714        if (supportsPBOs())
3715        {
3716            mExtensionStringList.push_back("NV_pixel_buffer_object");
3717            mExtensionStringList.push_back("GL_OES_mapbuffer");
3718            mExtensionStringList.push_back("GL_EXT_map_buffer_range");
3719        }
3720
3721        if (mRenderer->getDerivativeInstructionSupport())
3722        {
3723            mExtensionStringList.push_back("GL_OES_standard_derivatives");
3724        }
3725
3726        if (supportsFloat16Textures())
3727        {
3728            mExtensionStringList.push_back("GL_OES_texture_half_float");
3729        }
3730        if (supportsFloat16LinearFilter())
3731        {
3732            mExtensionStringList.push_back("GL_OES_texture_half_float_linear");
3733        }
3734        if (supportsFloat32Textures())
3735        {
3736            mExtensionStringList.push_back("GL_OES_texture_float");
3737        }
3738        if (supportsFloat32LinearFilter())
3739        {
3740            mExtensionStringList.push_back("GL_OES_texture_float_linear");
3741        }
3742
3743        if (supportsRGTextures())
3744        {
3745            mExtensionStringList.push_back("GL_EXT_texture_rg");
3746        }
3747
3748        if (supportsNonPower2Texture())
3749        {
3750            mExtensionStringList.push_back("GL_OES_texture_npot");
3751        }
3752
3753        // Multi-vendor (EXT) extensions
3754        if (supportsOcclusionQueries())
3755        {
3756            mExtensionStringList.push_back("GL_EXT_occlusion_query_boolean");
3757        }
3758
3759        mExtensionStringList.push_back("GL_EXT_read_format_bgra");
3760        mExtensionStringList.push_back("GL_EXT_robustness");
3761        mExtensionStringList.push_back("GL_EXT_shader_texture_lod");
3762
3763        if (supportsDXT1Textures())
3764        {
3765            mExtensionStringList.push_back("GL_EXT_texture_compression_dxt1");
3766        }
3767
3768        if (supportsTextureFilterAnisotropy())
3769        {
3770            mExtensionStringList.push_back("GL_EXT_texture_filter_anisotropic");
3771        }
3772
3773        if (supportsBGRATextures())
3774        {
3775            mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
3776        }
3777
3778        if (mRenderer->getMaxRenderTargets() > 1)
3779        {
3780            mExtensionStringList.push_back("GL_EXT_draw_buffers");
3781        }
3782
3783        mExtensionStringList.push_back("GL_EXT_texture_storage");
3784        mExtensionStringList.push_back("GL_EXT_frag_depth");
3785        mExtensionStringList.push_back("GL_EXT_blend_minmax");
3786
3787        // ANGLE-specific extensions
3788        if (supportsDepthTextures())
3789        {
3790            mExtensionStringList.push_back("GL_ANGLE_depth_texture");
3791        }
3792
3793        mExtensionStringList.push_back("GL_ANGLE_framebuffer_blit");
3794        if (getMaxSupportedSamples() != 0)
3795        {
3796            mExtensionStringList.push_back("GL_ANGLE_framebuffer_multisample");
3797        }
3798
3799        if (supportsInstancing())
3800        {
3801            mExtensionStringList.push_back("GL_ANGLE_instanced_arrays");
3802        }
3803
3804        mExtensionStringList.push_back("GL_ANGLE_pack_reverse_row_order");
3805
3806        if (supportsDXT3Textures())
3807        {
3808            mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt3");
3809        }
3810        if (supportsDXT5Textures())
3811        {
3812            mExtensionStringList.push_back("GL_ANGLE_texture_compression_dxt5");
3813        }
3814
3815        mExtensionStringList.push_back("GL_ANGLE_texture_usage");
3816        mExtensionStringList.push_back("GL_ANGLE_translated_shader_source");
3817
3818        // Other vendor-specific extensions
3819        if (supportsEventQueries())
3820        {
3821            mExtensionStringList.push_back("GL_NV_fence");
3822        }
3823    }
3824
3825    if (mClientVersion == 3)
3826    {
3827        mExtensionStringList.push_back("GL_EXT_color_buffer_float");
3828
3829        mExtensionStringList.push_back("GL_EXT_read_format_bgra");
3830
3831        if (supportsBGRATextures())
3832        {
3833            mExtensionStringList.push_back("GL_EXT_texture_format_BGRA8888");
3834        }
3835    }
3836
3837    // Join the extension strings to one long string for use with GetString
3838    std::stringstream strstr;
3839    for (unsigned int extensionIndex = 0; extensionIndex < mExtensionStringList.size(); extensionIndex++)
3840    {
3841        strstr << mExtensionStringList[extensionIndex];
3842        strstr << " ";
3843    }
3844
3845    mCombinedExtensionsString = makeStaticString(strstr.str());
3846}
3847
3848const char *Context::getCombinedExtensionsString() const
3849{
3850    return mCombinedExtensionsString;
3851}
3852
3853const char *Context::getExtensionString(const GLuint index) const
3854{
3855    ASSERT(index < mExtensionStringList.size());
3856    return mExtensionStringList[index].c_str();
3857}
3858
3859unsigned int Context::getNumExtensions() const
3860{
3861    return mExtensionStringList.size();
3862}
3863
3864void Context::initRendererString()
3865{
3866    std::ostringstream rendererString;
3867    rendererString << "ANGLE (";
3868    rendererString << mRenderer->getRendererDescription();
3869    rendererString << ")";
3870
3871    mRendererString = makeStaticString(rendererString.str());
3872}
3873
3874const char *Context::getRendererString() const
3875{
3876    return mRendererString;
3877}
3878
3879size_t Context::getBoundFramebufferTextureSerials(FramebufferTextureSerialArray *outSerialArray)
3880{
3881    size_t serialCount = 0;
3882
3883    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3884    for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++)
3885    {
3886        FramebufferAttachment *attachment = drawFramebuffer->getColorbuffer(i);
3887        if (attachment && attachment->isTexture())
3888        {
3889            (*outSerialArray)[serialCount++] = attachment->getTextureSerial();
3890        }
3891    }
3892
3893    FramebufferAttachment *depthStencilAttachment = drawFramebuffer->getDepthOrStencilbuffer();
3894    if (depthStencilAttachment && depthStencilAttachment->isTexture())
3895    {
3896        (*outSerialArray)[serialCount++] = depthStencilAttachment->getTextureSerial();
3897    }
3898
3899    std::sort(outSerialArray->begin(), outSerialArray->begin() + serialCount);
3900
3901    return serialCount;
3902}
3903
3904void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3905                              GLbitfield mask, GLenum filter)
3906{
3907    Framebuffer *readFramebuffer = getReadFramebuffer();
3908    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3909
3910    bool blitRenderTarget = false;
3911    bool blitDepth = false;
3912    bool blitStencil = false;
3913    if ((mask & GL_COLOR_BUFFER_BIT) && readFramebuffer->getReadColorbuffer() && drawFramebuffer->getFirstColorbuffer())
3914    {
3915        blitRenderTarget = true;
3916    }
3917    if ((mask & GL_STENCIL_BUFFER_BIT) && readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
3918    {
3919        blitStencil = true;
3920    }
3921    if ((mask & GL_DEPTH_BUFFER_BIT) && readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
3922    {
3923        blitDepth = true;
3924    }
3925
3926    gl::Rectangle srcRect(srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0);
3927    gl::Rectangle dstRect(dstX0, dstY0, dstX1 - dstX0, dstY1 - dstY0);
3928    if (blitRenderTarget || blitDepth || blitStencil)
3929    {
3930        const gl::Rectangle *scissor = mState.scissorTest ? &mState.scissor : NULL;
3931        mRenderer->blitRect(readFramebuffer, srcRect, drawFramebuffer, dstRect, scissor,
3932                            blitRenderTarget, blitDepth, blitStencil, filter);
3933    }
3934}
3935
3936void Context::invalidateFrameBuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments,
3937                                    GLint x, GLint y, GLsizei width, GLsizei height)
3938{
3939    Framebuffer *frameBuffer = NULL;
3940    switch (target)
3941    {
3942      case GL_FRAMEBUFFER:
3943      case GL_DRAW_FRAMEBUFFER:
3944        frameBuffer = getDrawFramebuffer();
3945        break;
3946      case GL_READ_FRAMEBUFFER:
3947        frameBuffer = getReadFramebuffer();
3948        break;
3949      default:
3950        UNREACHABLE();
3951    }
3952
3953    if (frameBuffer && frameBuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
3954    {
3955        for (int i = 0; i < numAttachments; ++i)
3956        {
3957            rx::RenderTarget *renderTarget = NULL;
3958
3959            if (attachments[i] >= GL_COLOR_ATTACHMENT0 && attachments[i] <= GL_COLOR_ATTACHMENT15)
3960            {
3961                gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(attachments[i] - GL_COLOR_ATTACHMENT0);
3962                if (attachment)
3963                {
3964                    renderTarget = attachment->getRenderTarget();
3965                }
3966            }
3967            else if (attachments[i] == GL_COLOR)
3968            {
3969                 gl::FramebufferAttachment *attachment = frameBuffer->getColorbuffer(0);
3970                 if (attachment)
3971                 {
3972                     renderTarget = attachment->getRenderTarget();
3973                 }
3974            }
3975            else
3976            {
3977                gl::FramebufferAttachment *attachment = NULL;
3978                switch (attachments[i])
3979                {
3980                  case GL_DEPTH_ATTACHMENT:
3981                  case GL_DEPTH:
3982                    attachment = frameBuffer->getDepthbuffer();
3983                    break;
3984                  case GL_STENCIL_ATTACHMENT:
3985                  case GL_STENCIL:
3986                    attachment = frameBuffer->getStencilbuffer();
3987                    break;
3988                  case GL_DEPTH_STENCIL_ATTACHMENT:
3989                    attachment = frameBuffer->getDepthOrStencilbuffer();
3990                    break;
3991                  default:
3992                    UNREACHABLE();
3993                }
3994
3995                if (attachment)
3996                {
3997                    renderTarget = attachment->getDepthStencil();
3998                }
3999            }
4000
4001            if (renderTarget)
4002            {
4003                renderTarget->invalidate(x, y, width, height);
4004            }
4005        }
4006    }
4007}
4008
4009bool Context::hasMappedBuffer(GLenum target) const
4010{
4011    if (target == GL_ARRAY_BUFFER)
4012    {
4013        for (unsigned int attribIndex = 0; attribIndex < gl::MAX_VERTEX_ATTRIBS; attribIndex++)
4014        {
4015            const gl::VertexAttribute &vertexAttrib = getVertexAttribState(attribIndex);
4016            gl::Buffer *boundBuffer = vertexAttrib.mBoundBuffer.get();
4017            if (vertexAttrib.mArrayEnabled && boundBuffer && boundBuffer->mapped())
4018            {
4019                return true;
4020            }
4021        }
4022    }
4023    else if (target == GL_ELEMENT_ARRAY_BUFFER)
4024    {
4025        Buffer *elementBuffer = getElementArrayBuffer();
4026        return (elementBuffer && elementBuffer->mapped());
4027    }
4028    else if (target == GL_TRANSFORM_FEEDBACK_BUFFER)
4029    {
4030        UNIMPLEMENTED();
4031    }
4032    else UNREACHABLE();
4033    return false;
4034}
4035
4036}
4037
4038extern "C"
4039{
4040gl::Context *glCreateContext(int clientVersion, const gl::Context *shareContext, rx::Renderer *renderer, bool notifyResets, bool robustAccess)
4041{
4042    return new gl::Context(clientVersion, shareContext, renderer, notifyResets, robustAccess);
4043}
4044
4045void glDestroyContext(gl::Context *context)
4046{
4047    delete context;
4048
4049    if (context == gl::getContext())
4050    {
4051        gl::makeCurrent(NULL, NULL, NULL);
4052    }
4053}
4054
4055void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface)
4056{
4057    gl::makeCurrent(context, display, surface);
4058}
4059
4060gl::Context *glGetCurrentContext()
4061{
4062    return gl::getContext();
4063}
4064
4065}
4066