Context.cpp revision 82b3d157918fa148b66aa00cf5152631d26bff67
1// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12// Context.cpp: Implements the es2::Context class, managing all GL state and performing
13// rendering operations. It is the GLES2 specific implementation of EGLContext.
14
15#include "Context.h"
16
17#include "main.h"
18#include "mathutil.h"
19#include "utilities.h"
20#include "ResourceManager.h"
21#include "Buffer.h"
22#include "Fence.h"
23#include "Framebuffer.h"
24#include "Program.h"
25#include "Query.h"
26#include "Renderbuffer.h"
27#include "Sampler.h"
28#include "Shader.h"
29#include "Texture.h"
30#include "TransformFeedback.h"
31#include "VertexArray.h"
32#include "VertexDataManager.h"
33#include "IndexDataManager.h"
34#include "libEGL/Display.h"
35#include "libEGL/Surface.h"
36#include "Common/Half.hpp"
37
38#include <EGL/eglext.h>
39
40namespace es2
41{
42Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)
43	: clientVersion(clientVersion), mConfig(config)
44{
45	sw::Context *context = new sw::Context();
46	device = new es2::Device(context);
47
48    mFenceNameSpace.setBaseHandle(0);
49
50    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
51
52    mState.depthClearValue = 1.0f;
53    mState.stencilClearValue = 0;
54
55    mState.cullFaceEnabled = false;
56    mState.cullMode = GL_BACK;
57    mState.frontFace = GL_CCW;
58    mState.depthTestEnabled = false;
59    mState.depthFunc = GL_LESS;
60    mState.blendEnabled = false;
61    mState.sourceBlendRGB = GL_ONE;
62    mState.sourceBlendAlpha = GL_ONE;
63    mState.destBlendRGB = GL_ZERO;
64    mState.destBlendAlpha = GL_ZERO;
65    mState.blendEquationRGB = GL_FUNC_ADD;
66    mState.blendEquationAlpha = GL_FUNC_ADD;
67    mState.blendColor.red = 0;
68    mState.blendColor.green = 0;
69    mState.blendColor.blue = 0;
70    mState.blendColor.alpha = 0;
71    mState.stencilTestEnabled = false;
72    mState.stencilFunc = GL_ALWAYS;
73    mState.stencilRef = 0;
74    mState.stencilMask = -1;
75    mState.stencilWritemask = -1;
76    mState.stencilBackFunc = GL_ALWAYS;
77    mState.stencilBackRef = 0;
78    mState.stencilBackMask = - 1;
79    mState.stencilBackWritemask = -1;
80    mState.stencilFail = GL_KEEP;
81    mState.stencilPassDepthFail = GL_KEEP;
82    mState.stencilPassDepthPass = GL_KEEP;
83    mState.stencilBackFail = GL_KEEP;
84    mState.stencilBackPassDepthFail = GL_KEEP;
85    mState.stencilBackPassDepthPass = GL_KEEP;
86    mState.polygonOffsetFillEnabled = false;
87    mState.polygonOffsetFactor = 0.0f;
88    mState.polygonOffsetUnits = 0.0f;
89    mState.sampleAlphaToCoverageEnabled = false;
90    mState.sampleCoverageEnabled = false;
91    mState.sampleCoverageValue = 1.0f;
92    mState.sampleCoverageInvert = false;
93    mState.scissorTestEnabled = false;
94    mState.ditherEnabled = true;
95    mState.primitiveRestartFixedIndexEnabled = false;
96    mState.rasterizerDiscardEnabled = false;
97    mState.generateMipmapHint = GL_DONT_CARE;
98    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99
100    mState.lineWidth = 1.0f;
101
102    mState.viewportX = 0;
103    mState.viewportY = 0;
104    mState.viewportWidth = 0;
105    mState.viewportHeight = 0;
106    mState.zNear = 0.0f;
107    mState.zFar = 1.0f;
108
109    mState.scissorX = 0;
110    mState.scissorY = 0;
111    mState.scissorWidth = 0;
112    mState.scissorHeight = 0;
113
114    mState.colorMaskRed = true;
115    mState.colorMaskGreen = true;
116    mState.colorMaskBlue = true;
117    mState.colorMaskAlpha = true;
118    mState.depthMask = true;
119
120    if(shareContext != NULL)
121    {
122        mResourceManager = shareContext->mResourceManager;
123        mResourceManager->addRef();
124    }
125    else
126    {
127        mResourceManager = new ResourceManager();
128    }
129
130    // [OpenGL ES 2.0.24] section 3.7 page 83:
131    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
132    // and cube map texture state vectors respectively associated with them.
133    // In order that access to these initial textures not be lost, they are treated as texture
134    // objects all of whose names are 0.
135
136    mTexture2DZero = new Texture2D(0);
137	mTexture3DZero = new Texture3D(0);
138	mTexture2DArrayZero = new Texture2DArray(0);
139    mTextureCubeMapZero = new TextureCubeMap(0);
140    mTextureExternalZero = new TextureExternal(0);
141
142    mState.activeSampler = 0;
143	bindVertexArray(0);
144    bindArrayBuffer(0);
145    bindElementArrayBuffer(0);
146    bindTextureCubeMap(0);
147    bindTexture2D(0);
148    bindReadFramebuffer(0);
149    bindDrawFramebuffer(0);
150    bindRenderbuffer(0);
151    bindGenericUniformBuffer(0);
152    bindTransformFeedback(0);
153
154    mState.currentProgram = 0;
155
156    mState.packAlignment = 4;
157	mState.unpackInfo.alignment = 4;
158	mState.packRowLength = 0;
159	mState.packImageHeight = 0;
160	mState.packSkipPixels = 0;
161	mState.packSkipRows = 0;
162	mState.packSkipImages = 0;
163	mState.unpackInfo.rowLength = 0;
164	mState.unpackInfo.imageHeight = 0;
165	mState.unpackInfo.skipPixels = 0;
166	mState.unpackInfo.skipRows = 0;
167	mState.unpackInfo.skipImages = 0;
168
169    mVertexDataManager = NULL;
170    mIndexDataManager = NULL;
171
172    mInvalidEnum = false;
173    mInvalidValue = false;
174    mInvalidOperation = false;
175    mOutOfMemory = false;
176    mInvalidFramebufferOperation = false;
177
178    mHasBeenCurrent = false;
179
180    markAllStateDirty();
181}
182
183Context::~Context()
184{
185	if(mState.currentProgram != 0)
186	{
187		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
188		if(programObject)
189		{
190			programObject->release();
191		}
192		mState.currentProgram = 0;
193	}
194
195	while(!mFramebufferMap.empty())
196	{
197		deleteFramebuffer(mFramebufferMap.begin()->first);
198	}
199
200	while(!mFenceMap.empty())
201	{
202		deleteFence(mFenceMap.begin()->first);
203	}
204
205	while(!mQueryMap.empty())
206	{
207		deleteQuery(mQueryMap.begin()->first);
208	}
209
210	while(!mVertexArrayMap.empty())
211	{
212		deleteVertexArray(mVertexArrayMap.begin()->first);
213	}
214
215	while(!mTransformFeedbackMap.empty())
216	{
217		deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
218	}
219
220	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
221	{
222		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
223		{
224			mState.samplerTexture[type][sampler] = NULL;
225		}
226	}
227
228	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
229	{
230		mState.vertexAttribute[i].mBoundBuffer = NULL;
231	}
232
233	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
234	{
235		mState.activeQuery[i] = NULL;
236	}
237
238	mState.arrayBuffer = NULL;
239	mState.copyReadBuffer = NULL;
240	mState.copyWriteBuffer = NULL;
241	mState.pixelPackBuffer = NULL;
242	mState.pixelUnpackBuffer = NULL;
243	mState.genericUniformBuffer = NULL;
244	mState.renderbuffer = NULL;
245
246	for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
247	{
248		mState.sampler[i] = NULL;
249	}
250
251    mTexture2DZero = NULL;
252	mTexture3DZero = NULL;
253	mTexture2DArrayZero = NULL;
254    mTextureCubeMapZero = NULL;
255    mTextureExternalZero = NULL;
256
257    delete mVertexDataManager;
258    delete mIndexDataManager;
259
260    mResourceManager->release();
261	delete device;
262}
263
264void Context::makeCurrent(egl::Surface *surface)
265{
266    if(!mHasBeenCurrent)
267    {
268        mVertexDataManager = new VertexDataManager(this);
269        mIndexDataManager = new IndexDataManager();
270
271        mState.viewportX = 0;
272        mState.viewportY = 0;
273        mState.viewportWidth = surface->getWidth();
274        mState.viewportHeight = surface->getHeight();
275
276        mState.scissorX = 0;
277        mState.scissorY = 0;
278        mState.scissorWidth = surface->getWidth();
279        mState.scissorHeight = surface->getHeight();
280
281        mHasBeenCurrent = true;
282    }
283
284    // Wrap the existing resources into GL objects and assign them to the '0' names
285    egl::Image *defaultRenderTarget = surface->getRenderTarget();
286    egl::Image *depthStencil = surface->getDepthStencil();
287
288    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
289    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
290    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
291
292    setFramebufferZero(framebufferZero);
293
294    if(defaultRenderTarget)
295    {
296        defaultRenderTarget->release();
297    }
298
299    if(depthStencil)
300    {
301        depthStencil->release();
302    }
303
304    markAllStateDirty();
305}
306
307EGLint Context::getClientVersion() const
308{
309	return clientVersion;
310}
311
312// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
313void Context::markAllStateDirty()
314{
315    mAppliedProgramSerial = 0;
316
317    mDepthStateDirty = true;
318    mMaskStateDirty = true;
319    mBlendStateDirty = true;
320    mStencilStateDirty = true;
321    mPolygonOffsetStateDirty = true;
322    mSampleStateDirty = true;
323    mDitherStateDirty = true;
324    mFrontFaceDirty = true;
325}
326
327void Context::setClearColor(float red, float green, float blue, float alpha)
328{
329    mState.colorClearValue.red = red;
330    mState.colorClearValue.green = green;
331    mState.colorClearValue.blue = blue;
332    mState.colorClearValue.alpha = alpha;
333}
334
335void Context::setClearDepth(float depth)
336{
337    mState.depthClearValue = depth;
338}
339
340void Context::setClearStencil(int stencil)
341{
342    mState.stencilClearValue = stencil;
343}
344
345void Context::setCullFaceEnabled(bool enabled)
346{
347    mState.cullFaceEnabled = enabled;
348}
349
350bool Context::isCullFaceEnabled() const
351{
352    return mState.cullFaceEnabled;
353}
354
355void Context::setCullMode(GLenum mode)
356{
357   mState.cullMode = mode;
358}
359
360void Context::setFrontFace(GLenum front)
361{
362    if(mState.frontFace != front)
363    {
364        mState.frontFace = front;
365        mFrontFaceDirty = true;
366    }
367}
368
369void Context::setDepthTestEnabled(bool enabled)
370{
371    if(mState.depthTestEnabled != enabled)
372    {
373        mState.depthTestEnabled = enabled;
374        mDepthStateDirty = true;
375    }
376}
377
378bool Context::isDepthTestEnabled() const
379{
380    return mState.depthTestEnabled;
381}
382
383void Context::setDepthFunc(GLenum depthFunc)
384{
385    if(mState.depthFunc != depthFunc)
386    {
387        mState.depthFunc = depthFunc;
388        mDepthStateDirty = true;
389    }
390}
391
392void Context::setDepthRange(float zNear, float zFar)
393{
394    mState.zNear = zNear;
395    mState.zFar = zFar;
396}
397
398void Context::setBlendEnabled(bool enabled)
399{
400    if(mState.blendEnabled != enabled)
401    {
402        mState.blendEnabled = enabled;
403        mBlendStateDirty = true;
404    }
405}
406
407bool Context::isBlendEnabled() const
408{
409    return mState.blendEnabled;
410}
411
412void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
413{
414    if(mState.sourceBlendRGB != sourceRGB ||
415       mState.sourceBlendAlpha != sourceAlpha ||
416       mState.destBlendRGB != destRGB ||
417       mState.destBlendAlpha != destAlpha)
418    {
419        mState.sourceBlendRGB = sourceRGB;
420        mState.destBlendRGB = destRGB;
421        mState.sourceBlendAlpha = sourceAlpha;
422        mState.destBlendAlpha = destAlpha;
423        mBlendStateDirty = true;
424    }
425}
426
427void Context::setBlendColor(float red, float green, float blue, float alpha)
428{
429    if(mState.blendColor.red != red ||
430       mState.blendColor.green != green ||
431       mState.blendColor.blue != blue ||
432       mState.blendColor.alpha != alpha)
433    {
434        mState.blendColor.red = red;
435        mState.blendColor.green = green;
436        mState.blendColor.blue = blue;
437        mState.blendColor.alpha = alpha;
438        mBlendStateDirty = true;
439    }
440}
441
442void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
443{
444    if(mState.blendEquationRGB != rgbEquation ||
445       mState.blendEquationAlpha != alphaEquation)
446    {
447        mState.blendEquationRGB = rgbEquation;
448        mState.blendEquationAlpha = alphaEquation;
449        mBlendStateDirty = true;
450    }
451}
452
453void Context::setStencilTestEnabled(bool enabled)
454{
455    if(mState.stencilTestEnabled != enabled)
456    {
457        mState.stencilTestEnabled = enabled;
458        mStencilStateDirty = true;
459    }
460}
461
462bool Context::isStencilTestEnabled() const
463{
464    return mState.stencilTestEnabled;
465}
466
467void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
468{
469    if(mState.stencilFunc != stencilFunc ||
470       mState.stencilRef != stencilRef ||
471       mState.stencilMask != stencilMask)
472    {
473        mState.stencilFunc = stencilFunc;
474        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
475        mState.stencilMask = stencilMask;
476        mStencilStateDirty = true;
477    }
478}
479
480void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
481{
482    if(mState.stencilBackFunc != stencilBackFunc ||
483       mState.stencilBackRef != stencilBackRef ||
484       mState.stencilBackMask != stencilBackMask)
485    {
486        mState.stencilBackFunc = stencilBackFunc;
487        mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
488        mState.stencilBackMask = stencilBackMask;
489        mStencilStateDirty = true;
490    }
491}
492
493void Context::setStencilWritemask(GLuint stencilWritemask)
494{
495    if(mState.stencilWritemask != stencilWritemask)
496    {
497        mState.stencilWritemask = stencilWritemask;
498        mStencilStateDirty = true;
499    }
500}
501
502void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
503{
504    if(mState.stencilBackWritemask != stencilBackWritemask)
505    {
506        mState.stencilBackWritemask = stencilBackWritemask;
507        mStencilStateDirty = true;
508    }
509}
510
511void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
512{
513    if(mState.stencilFail != stencilFail ||
514       mState.stencilPassDepthFail != stencilPassDepthFail ||
515       mState.stencilPassDepthPass != stencilPassDepthPass)
516    {
517        mState.stencilFail = stencilFail;
518        mState.stencilPassDepthFail = stencilPassDepthFail;
519        mState.stencilPassDepthPass = stencilPassDepthPass;
520        mStencilStateDirty = true;
521    }
522}
523
524void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
525{
526    if(mState.stencilBackFail != stencilBackFail ||
527       mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
528       mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
529    {
530        mState.stencilBackFail = stencilBackFail;
531        mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
532        mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
533        mStencilStateDirty = true;
534    }
535}
536
537void Context::setPolygonOffsetFillEnabled(bool enabled)
538{
539    if(mState.polygonOffsetFillEnabled != enabled)
540    {
541        mState.polygonOffsetFillEnabled = enabled;
542        mPolygonOffsetStateDirty = true;
543    }
544}
545
546bool Context::isPolygonOffsetFillEnabled() const
547{
548    return mState.polygonOffsetFillEnabled;
549}
550
551void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
552{
553    if(mState.polygonOffsetFactor != factor ||
554       mState.polygonOffsetUnits != units)
555    {
556        mState.polygonOffsetFactor = factor;
557        mState.polygonOffsetUnits = units;
558        mPolygonOffsetStateDirty = true;
559    }
560}
561
562void Context::setSampleAlphaToCoverageEnabled(bool enabled)
563{
564    if(mState.sampleAlphaToCoverageEnabled != enabled)
565    {
566        mState.sampleAlphaToCoverageEnabled = enabled;
567        mSampleStateDirty = true;
568    }
569}
570
571bool Context::isSampleAlphaToCoverageEnabled() const
572{
573    return mState.sampleAlphaToCoverageEnabled;
574}
575
576void Context::setSampleCoverageEnabled(bool enabled)
577{
578    if(mState.sampleCoverageEnabled != enabled)
579    {
580        mState.sampleCoverageEnabled = enabled;
581        mSampleStateDirty = true;
582    }
583}
584
585bool Context::isSampleCoverageEnabled() const
586{
587    return mState.sampleCoverageEnabled;
588}
589
590void Context::setSampleCoverageParams(GLclampf value, bool invert)
591{
592    if(mState.sampleCoverageValue != value ||
593       mState.sampleCoverageInvert != invert)
594    {
595        mState.sampleCoverageValue = value;
596        mState.sampleCoverageInvert = invert;
597        mSampleStateDirty = true;
598    }
599}
600
601void Context::setScissorTestEnabled(bool enabled)
602{
603    mState.scissorTestEnabled = enabled;
604}
605
606bool Context::isScissorTestEnabled() const
607{
608    return mState.scissorTestEnabled;
609}
610
611void Context::setDitherEnabled(bool enabled)
612{
613    if(mState.ditherEnabled != enabled)
614    {
615        mState.ditherEnabled = enabled;
616        mDitherStateDirty = true;
617    }
618}
619
620bool Context::isDitherEnabled() const
621{
622    return mState.ditherEnabled;
623}
624
625void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
626{
627    UNIMPLEMENTED();
628    mState.primitiveRestartFixedIndexEnabled = enabled;
629}
630
631bool Context::isPrimitiveRestartFixedIndexEnabled() const
632{
633    return mState.primitiveRestartFixedIndexEnabled;
634}
635
636void Context::setRasterizerDiscardEnabled(bool enabled)
637{
638    UNIMPLEMENTED();
639    mState.rasterizerDiscardEnabled = enabled;
640}
641
642bool Context::isRasterizerDiscardEnabled() const
643{
644    return mState.rasterizerDiscardEnabled;
645}
646
647void Context::setLineWidth(GLfloat width)
648{
649    mState.lineWidth = width;
650	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
651}
652
653void Context::setGenerateMipmapHint(GLenum hint)
654{
655    mState.generateMipmapHint = hint;
656}
657
658void Context::setFragmentShaderDerivativeHint(GLenum hint)
659{
660    mState.fragmentShaderDerivativeHint = hint;
661    // TODO: Propagate the hint to shader translator so we can write
662    // ddx, ddx_coarse, or ddx_fine depending on the hint.
663    // Ignore for now. It is valid for implementations to ignore hint.
664}
665
666void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
667{
668    mState.viewportX = x;
669    mState.viewportY = y;
670    mState.viewportWidth = width;
671    mState.viewportHeight = height;
672}
673
674void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
675{
676    mState.scissorX = x;
677    mState.scissorY = y;
678    mState.scissorWidth = width;
679    mState.scissorHeight = height;
680}
681
682void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
683{
684    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
685       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
686    {
687        mState.colorMaskRed = red;
688        mState.colorMaskGreen = green;
689        mState.colorMaskBlue = blue;
690        mState.colorMaskAlpha = alpha;
691        mMaskStateDirty = true;
692    }
693}
694
695unsigned int Context::getColorMask() const
696{
697	return (mState.colorMaskRed ? 0x1 : 0) |
698	       (mState.colorMaskGreen ? 0x2 : 0) |
699	       (mState.colorMaskBlue ? 0x4 : 0) |
700	       (mState.colorMaskAlpha ? 0x8 : 0);
701}
702
703void Context::setDepthMask(bool mask)
704{
705    if(mState.depthMask != mask)
706    {
707        mState.depthMask = mask;
708        mMaskStateDirty = true;
709    }
710}
711
712void Context::setActiveSampler(unsigned int active)
713{
714    mState.activeSampler = active;
715}
716
717GLuint Context::getReadFramebufferName() const
718{
719    return mState.readFramebuffer;
720}
721
722GLuint Context::getDrawFramebufferName() const
723{
724    return mState.drawFramebuffer;
725}
726
727GLuint Context::getRenderbufferName() const
728{
729    return mState.renderbuffer.name();
730}
731
732void Context::setFramebufferReadBuffer(GLuint buf)
733{
734	getReadFramebuffer()->setReadBuffer(buf);
735}
736
737void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
738{
739	Framebuffer* drawFramebuffer = getDrawFramebuffer();
740	for(int i = 0; i < n; ++i)
741	{
742		drawFramebuffer->setDrawBuffer(i, bufs[i]);
743	}
744}
745
746GLuint Context::getReadFramebufferColorIndex() const
747{
748	GLenum buf = getReadFramebuffer()->getReadBuffer();
749	switch(buf)
750	{
751	case GL_BACK:
752		return 0;
753	case GL_NONE:
754		return GL_INVALID_INDEX;
755	default:
756		return buf - GL_COLOR_ATTACHMENT0;
757}
758}
759
760GLuint Context::getArrayBufferName() const
761{
762    return mState.arrayBuffer.name();
763}
764
765GLuint Context::getElementArrayBufferName() const
766{
767	Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
768	return elementArrayBuffer ? elementArrayBuffer->name : 0;
769}
770
771GLuint Context::getActiveQuery(GLenum target) const
772{
773    Query *queryObject = NULL;
774
775    switch(target)
776    {
777    case GL_ANY_SAMPLES_PASSED_EXT:
778        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
779        break;
780    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
781        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
782        break;
783    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
784        queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
785        break;
786    default:
787        ASSERT(false);
788    }
789
790    if(queryObject)
791    {
792        return queryObject->name;
793    }
794
795	return 0;
796}
797
798void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
799{
800	getCurrentVertexArray()->enableAttribute(attribNum, enabled);
801}
802
803void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
804{
805	getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
806}
807
808const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
809{
810	return getCurrentVertexArray()->getVertexAttribute(attribNum);
811}
812
813void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
814                                   GLsizei stride, const void *pointer)
815{
816	getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, stride, pointer);
817}
818
819const void *Context::getVertexAttribPointer(unsigned int attribNum) const
820{
821	return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
822}
823
824const VertexAttributeArray &Context::getVertexArrayAttributes()
825{
826	return getCurrentVertexArray()->getVertexAttributes();
827}
828
829const VertexAttributeArray &Context::getCurrentVertexAttributes()
830{
831	return mState.vertexAttribute;
832}
833
834void Context::setPackAlignment(GLint alignment)
835{
836    mState.packAlignment = alignment;
837}
838
839void Context::setUnpackAlignment(GLint alignment)
840{
841	mState.unpackInfo.alignment = alignment;
842}
843
844const egl::Image::UnpackInfo& Context::getUnpackInfo() const
845{
846	return mState.unpackInfo;
847}
848
849void Context::setPackRowLength(GLint rowLength)
850{
851	mState.packRowLength = rowLength;
852}
853
854void Context::setPackImageHeight(GLint imageHeight)
855{
856	mState.packImageHeight = imageHeight;
857}
858
859void Context::setPackSkipPixels(GLint skipPixels)
860{
861	mState.packSkipPixels = skipPixels;
862}
863
864void Context::setPackSkipRows(GLint skipRows)
865{
866	mState.packSkipRows = skipRows;
867}
868
869void Context::setPackSkipImages(GLint skipImages)
870{
871	mState.packSkipImages = skipImages;
872}
873
874void Context::setUnpackRowLength(GLint rowLength)
875{
876	mState.unpackInfo.rowLength = rowLength;
877}
878
879void Context::setUnpackImageHeight(GLint imageHeight)
880{
881	mState.unpackInfo.imageHeight = imageHeight;
882}
883
884void Context::setUnpackSkipPixels(GLint skipPixels)
885{
886	mState.unpackInfo.skipPixels = skipPixels;
887}
888
889void Context::setUnpackSkipRows(GLint skipRows)
890{
891	mState.unpackInfo.skipRows = skipRows;
892}
893
894void Context::setUnpackSkipImages(GLint skipImages)
895{
896	mState.unpackInfo.skipImages = skipImages;
897}
898
899GLuint Context::createBuffer()
900{
901    return mResourceManager->createBuffer();
902}
903
904GLuint Context::createProgram()
905{
906    return mResourceManager->createProgram();
907}
908
909GLuint Context::createShader(GLenum type)
910{
911    return mResourceManager->createShader(type);
912}
913
914GLuint Context::createTexture()
915{
916    return mResourceManager->createTexture();
917}
918
919GLuint Context::createRenderbuffer()
920{
921    return mResourceManager->createRenderbuffer();
922}
923
924// Returns an unused framebuffer name
925GLuint Context::createFramebuffer()
926{
927    GLuint handle = mFramebufferNameSpace.allocate();
928
929    mFramebufferMap[handle] = NULL;
930
931    return handle;
932}
933
934GLuint Context::createFence()
935{
936    GLuint handle = mFenceNameSpace.allocate();
937
938    mFenceMap[handle] = new Fence;
939
940    return handle;
941}
942
943// Returns an unused query name
944GLuint Context::createQuery()
945{
946    GLuint handle = mQueryNameSpace.allocate();
947
948    mQueryMap[handle] = NULL;
949
950    return handle;
951}
952
953// Returns an unused vertex array name
954GLuint Context::createVertexArray()
955{
956	GLuint handle = mVertexArrayNameSpace.allocate();
957
958	mVertexArrayMap[handle] = nullptr;
959
960	return handle;
961}
962
963GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
964{
965	GLuint handle = mResourceManager->createFenceSync(condition, flags);
966
967	return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
968}
969
970// Returns an unused transform feedback name
971GLuint Context::createTransformFeedback()
972{
973	GLuint handle = mTransformFeedbackNameSpace.allocate();
974
975	mTransformFeedbackMap[handle] = NULL;
976
977	return handle;
978}
979
980// Returns an unused sampler name
981GLuint Context::createSampler()
982{
983	return mResourceManager->createSampler();
984}
985
986void Context::deleteBuffer(GLuint buffer)
987{
988    if(mResourceManager->getBuffer(buffer))
989    {
990        detachBuffer(buffer);
991    }
992
993    mResourceManager->deleteBuffer(buffer);
994}
995
996void Context::deleteShader(GLuint shader)
997{
998    mResourceManager->deleteShader(shader);
999}
1000
1001void Context::deleteProgram(GLuint program)
1002{
1003    mResourceManager->deleteProgram(program);
1004}
1005
1006void Context::deleteTexture(GLuint texture)
1007{
1008    if(mResourceManager->getTexture(texture))
1009    {
1010        detachTexture(texture);
1011    }
1012
1013    mResourceManager->deleteTexture(texture);
1014}
1015
1016void Context::deleteRenderbuffer(GLuint renderbuffer)
1017{
1018    if(mResourceManager->getRenderbuffer(renderbuffer))
1019    {
1020        detachRenderbuffer(renderbuffer);
1021    }
1022
1023    mResourceManager->deleteRenderbuffer(renderbuffer);
1024}
1025
1026void Context::deleteFramebuffer(GLuint framebuffer)
1027{
1028    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
1029
1030    if(framebufferObject != mFramebufferMap.end())
1031    {
1032        detachFramebuffer(framebuffer);
1033
1034        mFramebufferNameSpace.release(framebufferObject->first);
1035        delete framebufferObject->second;
1036        mFramebufferMap.erase(framebufferObject);
1037    }
1038}
1039
1040void Context::deleteFence(GLuint fence)
1041{
1042    FenceMap::iterator fenceObject = mFenceMap.find(fence);
1043
1044    if(fenceObject != mFenceMap.end())
1045    {
1046        mFenceNameSpace.release(fenceObject->first);
1047        delete fenceObject->second;
1048        mFenceMap.erase(fenceObject);
1049    }
1050}
1051
1052void Context::deleteQuery(GLuint query)
1053{
1054    QueryMap::iterator queryObject = mQueryMap.find(query);
1055
1056	if(queryObject != mQueryMap.end())
1057    {
1058        mQueryNameSpace.release(queryObject->first);
1059
1060		if(queryObject->second)
1061        {
1062            queryObject->second->release();
1063        }
1064
1065		mQueryMap.erase(queryObject);
1066    }
1067}
1068
1069void Context::deleteVertexArray(GLuint vertexArray)
1070{
1071	VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray);
1072
1073	if(vertexArrayObject != mVertexArrayMap.end())
1074	{
1075		// Vertex array detachment is handled by Context, because 0 is a valid
1076		// VAO, and a pointer to it must be passed from Context to State at
1077		// binding time.
1078
1079		// [OpenGL ES 3.0.2] section 2.10 page 43:
1080		// If a vertex array object that is currently bound is deleted, the binding
1081		// for that object reverts to zero and the default vertex array becomes current.
1082		if(getCurrentVertexArray()->name == vertexArray)
1083		{
1084			bindVertexArray(0);
1085		}
1086
1087		mVertexArrayNameSpace.release(vertexArrayObject->first);
1088		delete vertexArrayObject->second;
1089		mVertexArrayMap.erase(vertexArrayObject);
1090	}
1091}
1092
1093void Context::deleteFenceSync(GLsync fenceSync)
1094{
1095	// The spec specifies the underlying Fence object is not deleted until all current
1096	// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
1097	// and since our API is currently designed for being called from a single thread, we can delete
1098	// the fence immediately.
1099	mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
1100}
1101
1102void Context::deleteTransformFeedback(GLuint transformFeedback)
1103{
1104	TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback);
1105
1106	if(transformFeedbackObject != mTransformFeedbackMap.end())
1107	{
1108		mTransformFeedbackNameSpace.release(transformFeedbackObject->first);
1109		delete transformFeedbackObject->second;
1110		mTransformFeedbackMap.erase(transformFeedbackObject);
1111	}
1112}
1113
1114void Context::deleteSampler(GLuint sampler)
1115{
1116	if(mResourceManager->getSampler(sampler))
1117	{
1118		detachSampler(sampler);
1119	}
1120
1121	mResourceManager->deleteSampler(sampler);
1122}
1123
1124Buffer *Context::getBuffer(GLuint handle) const
1125{
1126    return mResourceManager->getBuffer(handle);
1127}
1128
1129Shader *Context::getShader(GLuint handle) const
1130{
1131    return mResourceManager->getShader(handle);
1132}
1133
1134Program *Context::getProgram(GLuint handle) const
1135{
1136    return mResourceManager->getProgram(handle);
1137}
1138
1139Texture *Context::getTexture(GLuint handle) const
1140{
1141    return mResourceManager->getTexture(handle);
1142}
1143
1144Renderbuffer *Context::getRenderbuffer(GLuint handle) const
1145{
1146    return mResourceManager->getRenderbuffer(handle);
1147}
1148
1149Framebuffer *Context::getReadFramebuffer() const
1150{
1151    return getFramebuffer(mState.readFramebuffer);
1152}
1153
1154Framebuffer *Context::getDrawFramebuffer() const
1155{
1156    return getFramebuffer(mState.drawFramebuffer);
1157}
1158
1159void Context::bindArrayBuffer(unsigned int buffer)
1160{
1161    mResourceManager->checkBufferAllocation(buffer);
1162
1163    mState.arrayBuffer = getBuffer(buffer);
1164}
1165
1166void Context::bindElementArrayBuffer(unsigned int buffer)
1167{
1168    mResourceManager->checkBufferAllocation(buffer);
1169
1170	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
1171}
1172
1173void Context::bindCopyReadBuffer(GLuint buffer)
1174{
1175	mResourceManager->checkBufferAllocation(buffer);
1176
1177	mState.copyReadBuffer = getBuffer(buffer);
1178}
1179
1180void Context::bindCopyWriteBuffer(GLuint buffer)
1181{
1182	mResourceManager->checkBufferAllocation(buffer);
1183
1184	mState.copyWriteBuffer = getBuffer(buffer);
1185}
1186
1187void Context::bindPixelPackBuffer(GLuint buffer)
1188{
1189	mResourceManager->checkBufferAllocation(buffer);
1190
1191	mState.pixelPackBuffer = getBuffer(buffer);
1192}
1193
1194void Context::bindPixelUnpackBuffer(GLuint buffer)
1195{
1196	mResourceManager->checkBufferAllocation(buffer);
1197
1198	mState.pixelUnpackBuffer = getBuffer(buffer);
1199}
1200
1201void Context::bindTransformFeedbackBuffer(GLuint buffer)
1202{
1203	mResourceManager->checkBufferAllocation(buffer);
1204
1205	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1206
1207	if(transformFeedback)
1208	{
1209		transformFeedback->setGenericBuffer(getBuffer(buffer));
1210	}
1211}
1212
1213void Context::bindTexture2D(GLuint texture)
1214{
1215    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
1216
1217    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
1218}
1219
1220void Context::bindTextureCubeMap(GLuint texture)
1221{
1222    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
1223
1224    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
1225}
1226
1227void Context::bindTextureExternal(GLuint texture)
1228{
1229    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
1230
1231    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
1232}
1233
1234void Context::bindTexture3D(GLuint texture)
1235{
1236	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
1237
1238	mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture);
1239}
1240
1241void Context::bindTexture2DArray(GLuint texture)
1242{
1243	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
1244
1245	mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture);
1246}
1247
1248void Context::bindReadFramebuffer(GLuint framebuffer)
1249{
1250    if(!getFramebuffer(framebuffer))
1251    {
1252        mFramebufferMap[framebuffer] = new Framebuffer();
1253    }
1254
1255    mState.readFramebuffer = framebuffer;
1256}
1257
1258void Context::bindDrawFramebuffer(GLuint framebuffer)
1259{
1260    if(!getFramebuffer(framebuffer))
1261    {
1262        mFramebufferMap[framebuffer] = new Framebuffer();
1263    }
1264
1265    mState.drawFramebuffer = framebuffer;
1266}
1267
1268void Context::bindRenderbuffer(GLuint renderbuffer)
1269{
1270	mResourceManager->checkRenderbufferAllocation(renderbuffer);
1271
1272    mState.renderbuffer = getRenderbuffer(renderbuffer);
1273}
1274
1275void Context::bindVertexArray(GLuint array)
1276{
1277	VertexArray *vertexArray = getVertexArray(array);
1278
1279	if(!vertexArray)
1280	{
1281		vertexArray = new VertexArray(array);
1282		mVertexArrayMap[array] = vertexArray;
1283	}
1284
1285	mState.vertexArray = array;
1286}
1287
1288void Context::bindGenericUniformBuffer(GLuint buffer)
1289{
1290	mResourceManager->checkBufferAllocation(buffer);
1291
1292	mState.genericUniformBuffer = getBuffer(buffer);
1293}
1294
1295void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1296{
1297	mResourceManager->checkBufferAllocation(buffer);
1298
1299	Buffer* bufferObject = getBuffer(buffer);
1300	mState.uniformBuffers[index].set(bufferObject, offset, size);
1301}
1302
1303void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
1304{
1305	mResourceManager->checkBufferAllocation(buffer);
1306
1307	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
1308}
1309
1310void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
1311{
1312	mResourceManager->checkBufferAllocation(buffer);
1313
1314	Buffer* bufferObject = getBuffer(buffer);
1315	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
1316}
1317
1318bool Context::bindTransformFeedback(GLuint id)
1319{
1320	if(!getTransformFeedback(id))
1321	{
1322		mTransformFeedbackMap[id] = new TransformFeedback(id);
1323	}
1324
1325	mState.transformFeedback = id;
1326
1327	return true;
1328}
1329
1330bool Context::bindSampler(GLuint unit, GLuint sampler)
1331{
1332	mResourceManager->checkSamplerAllocation(sampler);
1333
1334	Sampler* samplerObject = getSampler(sampler);
1335
1336	if(sampler)
1337	{
1338		mState.sampler[unit] = samplerObject;
1339	}
1340
1341	return !!samplerObject;
1342}
1343
1344void Context::useProgram(GLuint program)
1345{
1346    GLuint priorProgram = mState.currentProgram;
1347    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
1348
1349    if(priorProgram != program)
1350    {
1351        Program *newProgram = mResourceManager->getProgram(program);
1352        Program *oldProgram = mResourceManager->getProgram(priorProgram);
1353
1354        if(newProgram)
1355        {
1356            newProgram->addRef();
1357        }
1358
1359        if(oldProgram)
1360        {
1361            oldProgram->release();
1362        }
1363    }
1364}
1365
1366void Context::beginQuery(GLenum target, GLuint query)
1367{
1368    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1369    // of zero, if the active query object name for <target> is non-zero (for the
1370    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1371    // the active query for either target is non-zero), if <id> is the name of an
1372    // existing query object whose type does not match <target>, or if <id> is the
1373    // active query object name for any query type, the error INVALID_OPERATION is
1374    // generated.
1375
1376    // Ensure no other queries are active
1377    // NOTE: If other queries than occlusion are supported, we will need to check
1378    // separately that:
1379    //    a) The query ID passed is not the current active query for any target/type
1380    //    b) There are no active queries for the requested target (and in the case
1381    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1382    //       no query may be active for either if glBeginQuery targets either.
1383    for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1384    {
1385        if(mState.activeQuery[i] != NULL)
1386        {
1387            return error(GL_INVALID_OPERATION);
1388        }
1389    }
1390
1391    QueryType qType;
1392    switch(target)
1393    {
1394    case GL_ANY_SAMPLES_PASSED_EXT:
1395        qType = QUERY_ANY_SAMPLES_PASSED;
1396        break;
1397    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1398        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1399        break;
1400    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
1401        qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
1402        break;
1403    default:
1404        ASSERT(false);
1405    }
1406
1407    Query *queryObject = createQuery(query, target);
1408
1409    // Check that name was obtained with glGenQueries
1410    if(!queryObject)
1411    {
1412        return error(GL_INVALID_OPERATION);
1413    }
1414
1415    // Check for type mismatch
1416    if(queryObject->getType() != target)
1417    {
1418        return error(GL_INVALID_OPERATION);
1419    }
1420
1421    // Set query as active for specified target
1422    mState.activeQuery[qType] = queryObject;
1423
1424    // Begin query
1425    queryObject->begin();
1426}
1427
1428void Context::endQuery(GLenum target)
1429{
1430    QueryType qType;
1431
1432    switch(target)
1433    {
1434    case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;
1435    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;
1436    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
1437    default: UNREACHABLE(target); return;
1438    }
1439
1440    Query *queryObject = mState.activeQuery[qType];
1441
1442    if(queryObject == NULL)
1443    {
1444        return error(GL_INVALID_OPERATION);
1445    }
1446
1447    queryObject->end();
1448
1449    mState.activeQuery[qType] = NULL;
1450}
1451
1452void Context::setFramebufferZero(Framebuffer *buffer)
1453{
1454    delete mFramebufferMap[0];
1455    mFramebufferMap[0] = buffer;
1456}
1457
1458void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1459{
1460    Renderbuffer *renderbufferObject = mState.renderbuffer;
1461    renderbufferObject->setStorage(renderbuffer);
1462}
1463
1464Framebuffer *Context::getFramebuffer(unsigned int handle) const
1465{
1466    FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle);
1467
1468    if(framebuffer == mFramebufferMap.end())
1469    {
1470        return NULL;
1471    }
1472    else
1473    {
1474        return framebuffer->second;
1475    }
1476}
1477
1478Fence *Context::getFence(unsigned int handle) const
1479{
1480    FenceMap::const_iterator fence = mFenceMap.find(handle);
1481
1482    if(fence == mFenceMap.end())
1483    {
1484        return NULL;
1485    }
1486    else
1487    {
1488        return fence->second;
1489    }
1490}
1491
1492FenceSync *Context::getFenceSync(GLsync handle) const
1493{
1494	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
1495}
1496
1497Query *Context::getQuery(unsigned int handle) const
1498{
1499	QueryMap::const_iterator query = mQueryMap.find(handle);
1500
1501	if(query == mQueryMap.end())
1502	{
1503		return NULL;
1504	}
1505	else
1506	{
1507		return query->second;
1508	}
1509}
1510
1511Query *Context::createQuery(unsigned int handle, GLenum type)
1512{
1513	QueryMap::iterator query = mQueryMap.find(handle);
1514
1515	if(query == mQueryMap.end())
1516	{
1517		return NULL;
1518	}
1519	else
1520	{
1521		if(!query->second)
1522		{
1523			query->second = new Query(handle, type);
1524			query->second->addRef();
1525		}
1526
1527		return query->second;
1528	}
1529}
1530
1531VertexArray *Context::getVertexArray(GLuint array) const
1532{
1533	VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(array);
1534
1535	return (vertexArray == mVertexArrayMap.end()) ? nullptr : vertexArray->second;
1536}
1537
1538VertexArray *Context::getCurrentVertexArray() const
1539{
1540	return getVertexArray(mState.vertexArray);
1541}
1542
1543bool Context::isVertexArray(GLuint array) const
1544{
1545	VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(array);
1546
1547	return vertexArray != mVertexArrayMap.end();
1548}
1549
1550bool Context::hasZeroDivisor() const
1551{
1552	// Verify there is at least one active attribute with a divisor of zero
1553	es2::Program *programObject = getCurrentProgram();
1554	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
1555	{
1556		bool active = (programObject->getAttributeStream(attributeIndex) != -1);
1557		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
1558		{
1559			return true;
1560		}
1561	}
1562
1563	return false;
1564}
1565
1566TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
1567{
1568	TransformFeedbackMap::const_iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback);
1569
1570	return (transformFeedbackObject == mTransformFeedbackMap.end()) ? NULL : transformFeedbackObject->second;
1571}
1572
1573Sampler *Context::getSampler(GLuint sampler) const
1574{
1575	return mResourceManager->getSampler(sampler);
1576}
1577
1578bool Context::isSampler(GLuint sampler) const
1579{
1580	return mResourceManager->isSampler(sampler);
1581}
1582
1583Buffer *Context::getArrayBuffer() const
1584{
1585    return mState.arrayBuffer;
1586}
1587
1588Buffer *Context::getElementArrayBuffer() const
1589{
1590	return getCurrentVertexArray()->getElementArrayBuffer();
1591}
1592
1593Buffer *Context::getCopyReadBuffer() const
1594{
1595	return mState.copyReadBuffer;
1596}
1597
1598Buffer *Context::getCopyWriteBuffer() const
1599{
1600	return mState.copyWriteBuffer;
1601}
1602
1603Buffer *Context::getPixelPackBuffer() const
1604{
1605	return mState.pixelPackBuffer;
1606}
1607
1608Buffer *Context::getPixelUnpackBuffer() const
1609{
1610	return mState.pixelUnpackBuffer;
1611}
1612
1613Buffer *Context::getGenericUniformBuffer() const
1614{
1615	return mState.genericUniformBuffer;
1616}
1617
1618bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
1619{
1620	switch(target)
1621	{
1622	case GL_ARRAY_BUFFER:
1623		*buffer = getArrayBuffer();
1624		break;
1625	case GL_ELEMENT_ARRAY_BUFFER:
1626		*buffer = getElementArrayBuffer();
1627		break;
1628	case GL_COPY_READ_BUFFER:
1629		if(clientVersion >= 3)
1630		{
1631			*buffer = getCopyReadBuffer();
1632			break;
1633		}
1634		else return false;
1635	case GL_COPY_WRITE_BUFFER:
1636		if(clientVersion >= 3)
1637		{
1638			*buffer = getCopyWriteBuffer();
1639			break;
1640		}
1641		else return false;
1642	case GL_PIXEL_PACK_BUFFER:
1643		if(clientVersion >= 3)
1644		{
1645			*buffer = getPixelPackBuffer();
1646			break;
1647		}
1648		else return false;
1649	case GL_PIXEL_UNPACK_BUFFER:
1650		if(clientVersion >= 3)
1651		{
1652			*buffer = getPixelUnpackBuffer();
1653			break;
1654		}
1655		else return false;
1656	case GL_TRANSFORM_FEEDBACK_BUFFER:
1657		if(clientVersion >= 3)
1658		{
1659			TransformFeedback* transformFeedback = getTransformFeedback();
1660			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
1661			break;
1662		}
1663		else return false;
1664	case GL_UNIFORM_BUFFER:
1665		if(clientVersion >= 3)
1666		{
1667			*buffer = getGenericUniformBuffer();
1668			break;
1669		}
1670		else return false;
1671	default:
1672		return false;
1673	}
1674	return true;
1675}
1676
1677TransformFeedback *Context::getTransformFeedback() const
1678{
1679	return getTransformFeedback(mState.transformFeedback);
1680}
1681
1682Program *Context::getCurrentProgram() const
1683{
1684    return mResourceManager->getProgram(mState.currentProgram);
1685}
1686
1687Texture2D *Context::getTexture2D() const
1688{
1689	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1690}
1691
1692Texture3D *Context::getTexture3D() const
1693{
1694	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1695}
1696
1697Texture2DArray *Context::getTexture2DArray() const
1698{
1699	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
1700}
1701
1702TextureCubeMap *Context::getTextureCubeMap() const
1703{
1704    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1705}
1706
1707TextureExternal *Context::getTextureExternal() const
1708{
1709    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1710}
1711
1712Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
1713{
1714    GLuint texid = mState.samplerTexture[type][sampler].name();
1715
1716    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1717    {
1718        switch (type)
1719        {
1720        case TEXTURE_2D: return mTexture2DZero;
1721		case TEXTURE_3D: return mTexture3DZero;
1722		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
1723        case TEXTURE_CUBE: return mTextureCubeMapZero;
1724        case TEXTURE_EXTERNAL: return mTextureExternalZero;
1725        default: UNREACHABLE(type);
1726        }
1727    }
1728
1729    return mState.samplerTexture[type][sampler];
1730}
1731
1732void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
1733{
1734	mResourceManager->checkSamplerAllocation(sampler);
1735
1736	Sampler *samplerObject = getSampler(sampler);
1737	ASSERT(samplerObject);
1738
1739	switch(pname)
1740	{
1741	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
1742	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
1743	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
1744	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
1745	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
1746	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
1747	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
1748	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
1749	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
1750	default:                       UNREACHABLE(pname); break;
1751	}
1752}
1753
1754void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
1755{
1756	mResourceManager->checkSamplerAllocation(sampler);
1757
1758	Sampler *samplerObject = getSampler(sampler);
1759	ASSERT(samplerObject);
1760
1761	switch(pname)
1762	{
1763	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));       break;
1764	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));       break;
1765	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));           break;
1766	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));           break;
1767	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));           break;
1768	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                       break;
1769	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                       break;
1770	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(roundf(param)));  break;
1771	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(roundf(param)));  break;
1772	default:                       UNREACHABLE(pname); break;
1773	}
1774}
1775
1776GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
1777{
1778	mResourceManager->checkSamplerAllocation(sampler);
1779
1780	Sampler *samplerObject = getSampler(sampler);
1781	ASSERT(samplerObject);
1782
1783	switch(pname)
1784	{
1785	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
1786	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
1787	case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
1788	case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
1789	case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
1790	case GL_TEXTURE_MIN_LOD:       return static_cast<GLint>(roundf(samplerObject->getMinLod()));
1791	case GL_TEXTURE_MAX_LOD:       return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
1792	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
1793	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
1794	default:                       UNREACHABLE(pname); return 0;
1795	}
1796}
1797
1798GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
1799{
1800	mResourceManager->checkSamplerAllocation(sampler);
1801
1802	Sampler *samplerObject = getSampler(sampler);
1803	ASSERT(samplerObject);
1804
1805	switch(pname)
1806	{
1807	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
1808	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
1809	case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
1810	case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
1811	case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
1812	case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
1813	case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
1814	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
1815	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
1816	default:                       UNREACHABLE(pname); return 0;
1817	}
1818}
1819
1820bool Context::getBooleanv(GLenum pname, GLboolean *params) const
1821{
1822    switch(pname)
1823    {
1824    case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
1825    case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
1826    case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
1827    case GL_COLOR_WRITEMASK:
1828        params[0] = mState.colorMaskRed;
1829        params[1] = mState.colorMaskGreen;
1830        params[2] = mState.colorMaskBlue;
1831        params[3] = mState.colorMaskAlpha;
1832        break;
1833    case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;
1834    case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;
1835    case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;
1836    case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;
1837    case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;
1838    case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;
1839    case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;
1840    case GL_BLEND:                    *params = mState.blendEnabled;                     break;
1841    case GL_DITHER:                   *params = mState.ditherEnabled;                    break;
1842    case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
1843    case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;
1844	case GL_TRANSFORM_FEEDBACK_ACTIVE:
1845		{
1846			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1847			if(transformFeedback)
1848			{
1849				*params = transformFeedback->isActive();
1850				break;
1851			}
1852			else return false;
1853		}
1854     case GL_TRANSFORM_FEEDBACK_PAUSED:
1855		{
1856			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
1857			if(transformFeedback)
1858			{
1859				*params = transformFeedback->isPaused();
1860				break;
1861			}
1862			else return false;
1863		}
1864    default:
1865        return false;
1866    }
1867
1868    return true;
1869}
1870
1871bool Context::getFloatv(GLenum pname, GLfloat *params) const
1872{
1873    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1874    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1875    // GetIntegerv as its native query function. As it would require conversion in any
1876    // case, this should make no difference to the calling application.
1877    switch(pname)
1878    {
1879    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1880    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1881    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1882    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1883    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1884    case GL_ALIASED_LINE_WIDTH_RANGE:
1885        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1886        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1887        break;
1888    case GL_ALIASED_POINT_SIZE_RANGE:
1889        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1890        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1891        break;
1892    case GL_DEPTH_RANGE:
1893        params[0] = mState.zNear;
1894        params[1] = mState.zFar;
1895        break;
1896    case GL_COLOR_CLEAR_VALUE:
1897        params[0] = mState.colorClearValue.red;
1898        params[1] = mState.colorClearValue.green;
1899        params[2] = mState.colorClearValue.blue;
1900        params[3] = mState.colorClearValue.alpha;
1901        break;
1902    case GL_BLEND_COLOR:
1903        params[0] = mState.blendColor.red;
1904        params[1] = mState.blendColor.green;
1905        params[2] = mState.blendColor.blue;
1906        params[3] = mState.blendColor.alpha;
1907        break;
1908	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1909        *params = MAX_TEXTURE_MAX_ANISOTROPY;
1910		break;
1911    default:
1912        return false;
1913    }
1914
1915    return true;
1916}
1917
1918template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
1919template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
1920
1921template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
1922{
1923    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1924    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1925    // GetIntegerv as its native query function. As it would require conversion in any
1926    // case, this should make no difference to the calling application. You may find it in
1927    // Context::getFloatv.
1928    switch(pname)
1929    {
1930    case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
1931    case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
1932    case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
1933    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
1934    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
1935    case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
1936	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
1937	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
1938    case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1939    case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1940    case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 break;
1941    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          break;
1942//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1943    case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
1944    case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
1945    case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
1946    case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1947    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1948    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackInfo.alignment;          break;
1949    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1950    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1951    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1952    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1953    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1954	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); break;
1955    case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
1956    case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
1957	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); break;
1958    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1959    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1960    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1961    case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
1962    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
1963    case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
1964    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1965    case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
1966    case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
1967    case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
1968    case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
1969    case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
1970    case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
1971	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); break;
1972	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); break;
1973    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1974    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1975	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          break;
1976	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
1977    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;
1978	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;
1979    case GL_SAMPLE_BUFFERS:
1980    case GL_SAMPLES:
1981        {
1982            Framebuffer *framebuffer = getDrawFramebuffer();
1983			int width, height, samples;
1984
1985            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1986            {
1987                switch(pname)
1988                {
1989                case GL_SAMPLE_BUFFERS:
1990                    if(samples > 1)
1991                    {
1992                        *params = 1;
1993                    }
1994                    else
1995                    {
1996                        *params = 0;
1997                    }
1998                    break;
1999                case GL_SAMPLES:
2000                    *params = samples;
2001                    break;
2002                }
2003            }
2004            else
2005            {
2006                *params = 0;
2007            }
2008        }
2009        break;
2010    case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2011		{
2012			Framebuffer *framebuffer = getReadFramebuffer();
2013			*params = framebuffer->getImplementationColorReadType();
2014		}
2015		break;
2016    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2017		{
2018			Framebuffer *framebuffer = getReadFramebuffer();
2019			*params = framebuffer->getImplementationColorReadFormat();
2020		}
2021		break;
2022    case GL_MAX_VIEWPORT_DIMS:
2023        {
2024			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
2025            params[0] = maxDimension;
2026            params[1] = maxDimension;
2027        }
2028        break;
2029    case GL_COMPRESSED_TEXTURE_FORMATS:
2030        {
2031			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
2032            {
2033                params[i] = compressedTextureFormats[i];
2034            }
2035        }
2036        break;
2037    case GL_VIEWPORT:
2038        params[0] = mState.viewportX;
2039        params[1] = mState.viewportY;
2040        params[2] = mState.viewportWidth;
2041        params[3] = mState.viewportHeight;
2042        break;
2043    case GL_SCISSOR_BOX:
2044        params[0] = mState.scissorX;
2045        params[1] = mState.scissorY;
2046        params[2] = mState.scissorWidth;
2047        params[3] = mState.scissorHeight;
2048        break;
2049    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
2050    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
2051    case GL_RED_BITS:
2052    case GL_GREEN_BITS:
2053    case GL_BLUE_BITS:
2054    case GL_ALPHA_BITS:
2055        {
2056            Framebuffer *framebuffer = getDrawFramebuffer();
2057            Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
2058
2059            if(colorbuffer)
2060            {
2061                switch (pname)
2062                {
2063                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
2064                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
2065                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
2066                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
2067                }
2068            }
2069            else
2070            {
2071                *params = 0;
2072            }
2073        }
2074        break;
2075    case GL_DEPTH_BITS:
2076        {
2077            Framebuffer *framebuffer = getDrawFramebuffer();
2078            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2079
2080            if(depthbuffer)
2081            {
2082                *params = depthbuffer->getDepthSize();
2083            }
2084            else
2085            {
2086                *params = 0;
2087            }
2088        }
2089        break;
2090    case GL_STENCIL_BITS:
2091        {
2092            Framebuffer *framebuffer = getDrawFramebuffer();
2093            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2094
2095            if(stencilbuffer)
2096            {
2097                *params = stencilbuffer->getStencilSize();
2098            }
2099            else
2100            {
2101                *params = 0;
2102            }
2103        }
2104        break;
2105    case GL_TEXTURE_BINDING_2D:
2106        {
2107            if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2108            {
2109                error(GL_INVALID_OPERATION);
2110                return false;
2111            }
2112
2113            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
2114        }
2115        break;
2116    case GL_TEXTURE_BINDING_CUBE_MAP:
2117        {
2118            if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2119            {
2120                error(GL_INVALID_OPERATION);
2121                return false;
2122            }
2123
2124            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
2125        }
2126        break;
2127    case GL_TEXTURE_BINDING_EXTERNAL_OES:
2128        {
2129            if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2130            {
2131                error(GL_INVALID_OPERATION);
2132                return false;
2133            }
2134
2135            *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
2136        }
2137        break;
2138	case GL_TEXTURE_BINDING_3D_OES:
2139	case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0
2140	    {
2141			if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
2142			{
2143				error(GL_INVALID_OPERATION);
2144				return false;
2145			}
2146
2147			*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
2148		}
2149		break;
2150	case GL_COPY_READ_BUFFER_BINDING: // name, initially 0
2151		if(clientVersion >= 3)
2152		{
2153			*params = mState.copyReadBuffer.name();
2154		}
2155		else
2156		{
2157			return false;
2158		}
2159		break;
2160	case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0
2161		if(clientVersion >= 3)
2162		{
2163			*params = mState.copyWriteBuffer.name();
2164		}
2165		else
2166		{
2167			return false;
2168		}
2169		break;
2170	case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK​
2171	case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE
2172	case GL_DRAW_BUFFER2:
2173	case GL_DRAW_BUFFER3:
2174	case GL_DRAW_BUFFER4:
2175	case GL_DRAW_BUFFER5:
2176	case GL_DRAW_BUFFER6:
2177	case GL_DRAW_BUFFER7:
2178	case GL_DRAW_BUFFER8:
2179	case GL_DRAW_BUFFER9:
2180	case GL_DRAW_BUFFER10:
2181	case GL_DRAW_BUFFER11:
2182	case GL_DRAW_BUFFER12:
2183	case GL_DRAW_BUFFER13:
2184	case GL_DRAW_BUFFER14:
2185	case GL_DRAW_BUFFER15:
2186		*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);
2187		break;
2188	case GL_MAJOR_VERSION: // integer, at least 3
2189		if(clientVersion >= 3)
2190		{
2191			*params = clientVersion;
2192		}
2193		else
2194		{
2195			return false;
2196		}
2197		break;
2198	case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048
2199		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2200		break;
2201	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048
2202		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
2203		break;
2204	case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8
2205		UNIMPLEMENTED();
2206		*params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS;
2207		break;
2208	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048
2209		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
2210		break;
2211	case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70
2212		UNIMPLEMENTED();
2213		*params = 70;
2214		break;
2215	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176
2216		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
2217		break;
2218	case GL_MAX_DRAW_BUFFERS: // integer, at least 8
2219		UNIMPLEMENTED();
2220		*params = IMPLEMENTATION_MAX_DRAW_BUFFERS;
2221		break;
2222	case GL_MAX_ELEMENT_INDEX:
2223		*params = MAX_ELEMENT_INDEX;
2224		break;
2225	case GL_MAX_ELEMENTS_INDICES:
2226		*params = MAX_ELEMENTS_INDICES;
2227		break;
2228	case GL_MAX_ELEMENTS_VERTICES:
2229		*params = MAX_ELEMENTS_VERTICES;
2230		break;
2231	case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128
2232		UNIMPLEMENTED();
2233		*params = 128;
2234		break;
2235	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12
2236		*params = MAX_FRAGMENT_UNIFORM_BLOCKS;
2237		break;
2238	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 896
2239		*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
2240		break;
2241	case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7
2242		UNIMPLEMENTED();
2243		*params = 7;
2244		break;
2245	case GL_MAX_SERVER_WAIT_TIMEOUT: // integer
2246		UNIMPLEMENTED();
2247		*params = 0;
2248		break;
2249	case GL_MAX_TEXTURE_LOD_BIAS: // integer,  at least 2.0
2250		UNIMPLEMENTED();
2251		*params = 2;
2252		break;
2253	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64
2254		UNIMPLEMENTED();
2255		*params = 64;
2256		break;
2257	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4
2258		UNIMPLEMENTED();
2259		*params = IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
2260		break;
2261	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4
2262		UNIMPLEMENTED();
2263		*params = 4;
2264		break;
2265	case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384
2266		*params = MAX_UNIFORM_BLOCK_SIZE;
2267		break;
2268	case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 24
2269		*params = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS;
2270		break;
2271	case GL_MAX_VARYING_COMPONENTS: // integer, at least 60
2272		UNIMPLEMENTED();
2273		*params = 60;
2274		break;
2275	case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer,  at least 64
2276		UNIMPLEMENTED();
2277		*params = 64;
2278		break;
2279	case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer,  at least 12
2280		*params = MAX_VERTEX_UNIFORM_BLOCKS;
2281		break;
2282	case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer,  at least 1024
2283		*params = MAX_VERTEX_UNIFORM_COMPONENTS;
2284		break;
2285	case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8
2286		UNIMPLEMENTED();
2287		*params = -8;
2288		break;
2289	case GL_MINOR_VERSION: // integer
2290		UNIMPLEMENTED();
2291		*params = 0;
2292		break;
2293	case GL_NUM_EXTENSIONS: // integer
2294		GLuint numExtensions;
2295		getExtensions(0, &numExtensions);
2296		*params = numExtensions;
2297		break;
2298	case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0
2299		UNIMPLEMENTED();
2300		*params = 0;
2301		break;
2302	case GL_PACK_ROW_LENGTH: // integer, initially 0
2303		*params = mState.packRowLength;
2304		break;
2305	case GL_PACK_SKIP_PIXELS: // integer, initially 0
2306		*params = mState.packSkipPixels;
2307		break;
2308	case GL_PACK_SKIP_ROWS: // integer, initially 0
2309		*params = mState.packSkipRows;
2310		break;
2311	case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0
2312		if(clientVersion >= 3)
2313		{
2314			*params = mState.pixelPackBuffer.name();
2315		}
2316		else
2317		{
2318			return false;
2319		}
2320		break;
2321	case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0
2322		if(clientVersion >= 3)
2323		{
2324			*params = mState.pixelUnpackBuffer.name();
2325		}
2326		else
2327		{
2328			return false;
2329		}
2330		break;
2331	case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS​]
2332		UNIMPLEMENTED();
2333		*params = 0;
2334		break;
2335	case GL_READ_BUFFER: // symbolic constant,  initial value is GL_BACK​
2336		*params = getReadFramebuffer()->getReadBuffer();
2337		break;
2338	case GL_SAMPLER_BINDING: // GLint, default 0
2339		*params = mState.sampler[mState.activeSampler].name();
2340		break;
2341	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2342		if(clientVersion >= 3)
2343		{
2344			*params = mState.genericUniformBuffer.name();
2345		}
2346		else
2347		{
2348			return false;
2349		}
2350		break;
2351	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1
2352		*params = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT;
2353		break;
2354	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2355		if(clientVersion >= 3)
2356		{
2357			*params = mState.genericUniformBuffer->size();
2358		}
2359		else
2360		{
2361			return false;
2362		}
2363		break;
2364	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2365		if(clientVersion >= 3)
2366		{
2367			*params = mState.genericUniformBuffer->offset();
2368		}
2369		else
2370		{
2371			return false;
2372		}
2373		*params = 0;
2374		break;
2375	case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0
2376		*params = mState.unpackInfo.imageHeight;
2377		break;
2378	case GL_UNPACK_ROW_LENGTH: // integer, initially 0
2379		*params = mState.unpackInfo.rowLength;
2380		break;
2381	case GL_UNPACK_SKIP_IMAGES: // integer, initially 0
2382		*params = mState.unpackInfo.skipImages;
2383		break;
2384	case GL_UNPACK_SKIP_PIXELS: // integer, initially 0
2385		*params = mState.unpackInfo.skipPixels;
2386		break;
2387	case GL_UNPACK_SKIP_ROWS: // integer, initially 0
2388		*params = mState.unpackInfo.skipRows;
2389		break;
2390	case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0
2391		*params = getCurrentVertexArray()->name;
2392		break;
2393	case GL_TRANSFORM_FEEDBACK_BINDING:
2394		{
2395			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2396			if(transformFeedback)
2397			{
2398				*params = transformFeedback->name;
2399			}
2400			else
2401			{
2402				return false;
2403			}
2404		}
2405		break;
2406	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2407		{
2408			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2409			if(transformFeedback)
2410			{
2411				*params = transformFeedback->getGenericBufferName();
2412			}
2413			else
2414			{
2415				return false;
2416			}
2417		}
2418		break;
2419	default:
2420        return false;
2421    }
2422
2423    return true;
2424}
2425
2426template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2427template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2428
2429template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
2430{
2431	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
2432	if(!transformFeedback)
2433	{
2434		return false;
2435	}
2436
2437	switch(pname)
2438	{
2439	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
2440		*param = transformFeedback->name;
2441		break;
2442	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
2443		*param = transformFeedback->isActive();
2444		break;
2445	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
2446		*param = transformFeedback->getBufferName(index);
2447		break;
2448	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
2449		*param = transformFeedback->isPaused();
2450		break;
2451	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2452		if(transformFeedback->getBuffer(index))
2453		{
2454			*param = transformFeedback->getSize(index);
2455			break;
2456		}
2457		else return false;
2458	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2459		if(transformFeedback->getBuffer(index))
2460		{
2461			*param = transformFeedback->getOffset(index);
2462		break;
2463		}
2464		else return false;
2465	default:
2466		return false;
2467	}
2468
2469	return true;
2470}
2471
2472template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
2473template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
2474
2475template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
2476{
2477	const UniformBufferBinding& uniformBuffer = mState.uniformBuffers[index];
2478
2479	switch(pname)
2480	{
2481	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
2482		*param = uniformBuffer.get().name();
2483		break;
2484	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
2485		*param = uniformBuffer.getSize();
2486		break;
2487	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
2488		*param = uniformBuffer.getOffset();
2489		break;
2490	default:
2491		return false;
2492	}
2493
2494	return true;
2495}
2496
2497bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
2498{
2499    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2500    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2501    // to the fact that it is stored internally as a float, and so would require conversion
2502    // if returned from Context::getIntegerv. Since this conversion is already implemented
2503    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2504    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2505    // application.
2506    switch(pname)
2507    {
2508    case GL_COMPRESSED_TEXTURE_FORMATS:
2509		{
2510            *type = GL_INT;
2511			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
2512        }
2513		break;
2514    case GL_SHADER_BINARY_FORMATS:
2515        {
2516            *type = GL_INT;
2517            *numParams = 0;
2518        }
2519        break;
2520    case GL_MAX_VERTEX_ATTRIBS:
2521    case GL_MAX_VERTEX_UNIFORM_VECTORS:
2522    case GL_MAX_VARYING_VECTORS:
2523    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2524    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2525    case GL_MAX_TEXTURE_IMAGE_UNITS:
2526    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2527    case GL_MAX_RENDERBUFFER_SIZE:
2528    case GL_NUM_SHADER_BINARY_FORMATS:
2529    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2530    case GL_ARRAY_BUFFER_BINDING:
2531    case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2532    case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
2533    case GL_RENDERBUFFER_BINDING:
2534    case GL_CURRENT_PROGRAM:
2535    case GL_PACK_ALIGNMENT:
2536    case GL_UNPACK_ALIGNMENT:
2537    case GL_GENERATE_MIPMAP_HINT:
2538    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
2539    case GL_RED_BITS:
2540    case GL_GREEN_BITS:
2541    case GL_BLUE_BITS:
2542    case GL_ALPHA_BITS:
2543    case GL_DEPTH_BITS:
2544    case GL_STENCIL_BITS:
2545    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2546    case GL_CULL_FACE_MODE:
2547    case GL_FRONT_FACE:
2548    case GL_ACTIVE_TEXTURE:
2549    case GL_STENCIL_FUNC:
2550    case GL_STENCIL_VALUE_MASK:
2551    case GL_STENCIL_REF:
2552    case GL_STENCIL_FAIL:
2553    case GL_STENCIL_PASS_DEPTH_FAIL:
2554    case GL_STENCIL_PASS_DEPTH_PASS:
2555    case GL_STENCIL_BACK_FUNC:
2556    case GL_STENCIL_BACK_VALUE_MASK:
2557    case GL_STENCIL_BACK_REF:
2558    case GL_STENCIL_BACK_FAIL:
2559    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2560    case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2561    case GL_DEPTH_FUNC:
2562    case GL_BLEND_SRC_RGB:
2563    case GL_BLEND_SRC_ALPHA:
2564    case GL_BLEND_DST_RGB:
2565    case GL_BLEND_DST_ALPHA:
2566    case GL_BLEND_EQUATION_RGB:
2567    case GL_BLEND_EQUATION_ALPHA:
2568    case GL_STENCIL_WRITEMASK:
2569    case GL_STENCIL_BACK_WRITEMASK:
2570    case GL_STENCIL_CLEAR_VALUE:
2571    case GL_SUBPIXEL_BITS:
2572    case GL_MAX_TEXTURE_SIZE:
2573    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
2574    case GL_SAMPLE_BUFFERS:
2575    case GL_SAMPLES:
2576    case GL_IMPLEMENTATION_COLOR_READ_TYPE:
2577    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
2578    case GL_TEXTURE_BINDING_2D:
2579    case GL_TEXTURE_BINDING_CUBE_MAP:
2580    case GL_TEXTURE_BINDING_EXTERNAL_OES:
2581    case GL_TEXTURE_BINDING_3D_OES:
2582    case GL_COPY_READ_BUFFER_BINDING:
2583    case GL_COPY_WRITE_BUFFER_BINDING:
2584    case GL_DRAW_BUFFER0:
2585    case GL_DRAW_BUFFER1:
2586    case GL_DRAW_BUFFER2:
2587    case GL_DRAW_BUFFER3:
2588    case GL_DRAW_BUFFER4:
2589    case GL_DRAW_BUFFER5:
2590    case GL_DRAW_BUFFER6:
2591    case GL_DRAW_BUFFER7:
2592    case GL_DRAW_BUFFER8:
2593    case GL_DRAW_BUFFER9:
2594    case GL_DRAW_BUFFER10:
2595    case GL_DRAW_BUFFER11:
2596    case GL_DRAW_BUFFER12:
2597    case GL_DRAW_BUFFER13:
2598    case GL_DRAW_BUFFER14:
2599    case GL_DRAW_BUFFER15:
2600    case GL_MAJOR_VERSION:
2601    case GL_MAX_3D_TEXTURE_SIZE:
2602    case GL_MAX_ARRAY_TEXTURE_LAYERS:
2603    case GL_MAX_COLOR_ATTACHMENTS:
2604    case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
2605    case GL_MAX_COMBINED_UNIFORM_BLOCKS:
2606    case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
2607    case GL_MAX_DRAW_BUFFERS:
2608    case GL_MAX_ELEMENT_INDEX:
2609    case GL_MAX_ELEMENTS_INDICES:
2610    case GL_MAX_ELEMENTS_VERTICES:
2611    case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
2612    case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
2613    case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
2614    case GL_MAX_PROGRAM_TEXEL_OFFSET:
2615    case GL_MAX_SERVER_WAIT_TIMEOUT:
2616    case GL_MAX_TEXTURE_LOD_BIAS:
2617    case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
2618    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
2619    case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
2620    case GL_MAX_UNIFORM_BLOCK_SIZE:
2621    case GL_MAX_UNIFORM_BUFFER_BINDINGS:
2622    case GL_MAX_VARYING_COMPONENTS:
2623    case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
2624    case GL_MAX_VERTEX_UNIFORM_BLOCKS:
2625    case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
2626    case GL_MIN_PROGRAM_TEXEL_OFFSET:
2627    case GL_MINOR_VERSION:
2628    case GL_NUM_EXTENSIONS:
2629    case GL_NUM_PROGRAM_BINARY_FORMATS:
2630    case GL_PACK_ROW_LENGTH:
2631    case GL_PACK_SKIP_PIXELS:
2632    case GL_PACK_SKIP_ROWS:
2633    case GL_PIXEL_PACK_BUFFER_BINDING:
2634    case GL_PIXEL_UNPACK_BUFFER_BINDING:
2635    case GL_PROGRAM_BINARY_FORMATS:
2636    case GL_READ_BUFFER:
2637    case GL_SAMPLER_BINDING:
2638    case GL_TEXTURE_BINDING_2D_ARRAY:
2639    case GL_UNIFORM_BUFFER_BINDING:
2640    case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
2641    case GL_UNIFORM_BUFFER_SIZE:
2642    case GL_UNIFORM_BUFFER_START:
2643    case GL_UNPACK_IMAGE_HEIGHT:
2644    case GL_UNPACK_ROW_LENGTH:
2645    case GL_UNPACK_SKIP_IMAGES:
2646    case GL_UNPACK_SKIP_PIXELS:
2647    case GL_UNPACK_SKIP_ROWS:
2648    case GL_VERTEX_ARRAY_BINDING:
2649	case GL_TRANSFORM_FEEDBACK_BINDING:
2650	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
2651        {
2652            *type = GL_INT;
2653            *numParams = 1;
2654        }
2655        break;
2656    case GL_MAX_SAMPLES_ANGLE:
2657        {
2658            *type = GL_INT;
2659            *numParams = 1;
2660        }
2661        break;
2662    case GL_MAX_VIEWPORT_DIMS:
2663        {
2664            *type = GL_INT;
2665            *numParams = 2;
2666        }
2667        break;
2668    case GL_VIEWPORT:
2669    case GL_SCISSOR_BOX:
2670        {
2671            *type = GL_INT;
2672            *numParams = 4;
2673        }
2674        break;
2675    case GL_SHADER_COMPILER:
2676    case GL_SAMPLE_COVERAGE_INVERT:
2677    case GL_DEPTH_WRITEMASK:
2678    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
2679    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
2680    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
2681    case GL_SAMPLE_COVERAGE:
2682    case GL_SCISSOR_TEST:
2683    case GL_STENCIL_TEST:
2684    case GL_DEPTH_TEST:
2685    case GL_BLEND:
2686    case GL_DITHER:
2687    case GL_PRIMITIVE_RESTART_FIXED_INDEX:
2688    case GL_RASTERIZER_DISCARD:
2689    case GL_TRANSFORM_FEEDBACK_ACTIVE:
2690    case GL_TRANSFORM_FEEDBACK_PAUSED:
2691        {
2692            *type = GL_BOOL;
2693            *numParams = 1;
2694        }
2695        break;
2696    case GL_COLOR_WRITEMASK:
2697        {
2698            *type = GL_BOOL;
2699            *numParams = 4;
2700        }
2701        break;
2702    case GL_POLYGON_OFFSET_FACTOR:
2703    case GL_POLYGON_OFFSET_UNITS:
2704    case GL_SAMPLE_COVERAGE_VALUE:
2705    case GL_DEPTH_CLEAR_VALUE:
2706    case GL_LINE_WIDTH:
2707        {
2708            *type = GL_FLOAT;
2709            *numParams = 1;
2710        }
2711        break;
2712    case GL_ALIASED_LINE_WIDTH_RANGE:
2713    case GL_ALIASED_POINT_SIZE_RANGE:
2714    case GL_DEPTH_RANGE:
2715        {
2716            *type = GL_FLOAT;
2717            *numParams = 2;
2718        }
2719        break;
2720    case GL_COLOR_CLEAR_VALUE:
2721    case GL_BLEND_COLOR:
2722        {
2723            *type = GL_FLOAT;
2724            *numParams = 4;
2725        }
2726        break;
2727	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2728        *type = GL_FLOAT;
2729        *numParams = 1;
2730        break;
2731    default:
2732        return false;
2733    }
2734
2735    return true;
2736}
2737
2738void Context::applyScissor(int width, int height)
2739{
2740	if(mState.scissorTestEnabled)
2741	{
2742		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
2743		scissor.clip(0, 0, width, height);
2744
2745		device->setScissorRect(scissor);
2746		device->setScissorEnable(true);
2747	}
2748	else
2749	{
2750		device->setScissorEnable(false);
2751	}
2752}
2753
2754egl::Image *Context::getScissoredImage(GLint drawbuffer, int &x0, int &y0, int &width, int &height, bool depthStencil)
2755{
2756	Framebuffer* framebuffer = getDrawFramebuffer();
2757	egl::Image* image = depthStencil ? framebuffer->getDepthStencil() : framebuffer->getRenderTarget(drawbuffer);
2758
2759	applyScissor(image->getWidth(), image->getHeight());
2760
2761	device->getScissoredRegion(image, x0, y0, width, height);
2762
2763	return image;
2764}
2765
2766// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
2767bool Context::applyRenderTarget()
2768{
2769    Framebuffer *framebuffer = getDrawFramebuffer();
2770	int width, height, samples;
2771
2772    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
2773    {
2774        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2775    }
2776
2777	for(int i = 0; i < MAX_DRAW_BUFFERS; ++i)
2778	{
2779		egl::Image *renderTarget = framebuffer->getRenderTarget(i);
2780		device->setRenderTarget(i, renderTarget);
2781		if(renderTarget) renderTarget->release();
2782	}
2783
2784    egl::Image *depthStencil = framebuffer->getDepthStencil();
2785    device->setDepthStencilSurface(depthStencil);
2786	if(depthStencil) depthStencil->release();
2787
2788    Viewport viewport;
2789    float zNear = clamp01(mState.zNear);
2790    float zFar = clamp01(mState.zFar);
2791
2792    viewport.x0 = mState.viewportX;
2793    viewport.y0 = mState.viewportY;
2794    viewport.width = mState.viewportWidth;
2795    viewport.height = mState.viewportHeight;
2796    viewport.minZ = zNear;
2797    viewport.maxZ = zFar;
2798
2799    device->setViewport(viewport);
2800
2801	applyScissor(width, height);
2802
2803	Program *program = getCurrentProgram();
2804
2805	if(program)
2806	{
2807		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2808        program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2809		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2810		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2811    }
2812
2813    return true;
2814}
2815
2816// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
2817void Context::applyState(GLenum drawMode)
2818{
2819    Framebuffer *framebuffer = getDrawFramebuffer();
2820
2821    if(mState.cullFaceEnabled)
2822    {
2823        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
2824    }
2825    else
2826    {
2827		device->setCullMode(sw::CULL_NONE);
2828    }
2829
2830    if(mDepthStateDirty)
2831    {
2832        if(mState.depthTestEnabled)
2833        {
2834			device->setDepthBufferEnable(true);
2835			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2836        }
2837        else
2838        {
2839            device->setDepthBufferEnable(false);
2840        }
2841
2842        mDepthStateDirty = false;
2843    }
2844
2845    if(mBlendStateDirty)
2846    {
2847        if(mState.blendEnabled)
2848        {
2849			device->setAlphaBlendEnable(true);
2850			device->setSeparateAlphaBlendEnable(true);
2851
2852            device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2853
2854			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2855			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2856			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2857
2858            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2859			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2860			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2861        }
2862        else
2863        {
2864			device->setAlphaBlendEnable(false);
2865        }
2866
2867        mBlendStateDirty = false;
2868    }
2869
2870    if(mStencilStateDirty || mFrontFaceDirty)
2871    {
2872        if(mState.stencilTestEnabled && framebuffer->hasStencil())
2873        {
2874			device->setStencilEnable(true);
2875			device->setTwoSidedStencil(true);
2876
2877            // get the maximum size of the stencil ref
2878            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2879            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2880
2881			if(mState.frontFace == GL_CCW)
2882			{
2883				device->setStencilWriteMask(mState.stencilWritemask);
2884				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2885
2886				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2887				device->setStencilMask(mState.stencilMask);
2888
2889				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2890				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2891				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2892
2893				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2894				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2895
2896				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2897				device->setStencilMaskCCW(mState.stencilBackMask);
2898
2899				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2900				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2901				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2902			}
2903			else
2904			{
2905				device->setStencilWriteMaskCCW(mState.stencilWritemask);
2906				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2907
2908				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2909				device->setStencilMaskCCW(mState.stencilMask);
2910
2911				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2912				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2913				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2914
2915				device->setStencilWriteMask(mState.stencilBackWritemask);
2916				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2917
2918				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2919				device->setStencilMask(mState.stencilBackMask);
2920
2921				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2922				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2923				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2924			}
2925        }
2926        else
2927        {
2928			device->setStencilEnable(false);
2929        }
2930
2931        mStencilStateDirty = false;
2932        mFrontFaceDirty = false;
2933    }
2934
2935    if(mMaskStateDirty)
2936    {
2937		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2938		device->setDepthWriteEnable(mState.depthMask);
2939
2940        mMaskStateDirty = false;
2941    }
2942
2943    if(mPolygonOffsetStateDirty)
2944    {
2945        if(mState.polygonOffsetFillEnabled)
2946        {
2947            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2948            if(depthbuffer)
2949            {
2950				device->setSlopeDepthBias(mState.polygonOffsetFactor);
2951                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
2952				device->setDepthBias(depthBias);
2953            }
2954        }
2955        else
2956        {
2957            device->setSlopeDepthBias(0);
2958            device->setDepthBias(0);
2959        }
2960
2961        mPolygonOffsetStateDirty = false;
2962    }
2963
2964    if(mSampleStateDirty)
2965    {
2966        if(mState.sampleAlphaToCoverageEnabled)
2967        {
2968            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
2969        }
2970		else
2971		{
2972			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
2973		}
2974
2975        if(mState.sampleCoverageEnabled)
2976        {
2977            unsigned int mask = 0;
2978            if(mState.sampleCoverageValue != 0)
2979            {
2980				int width, height, samples;
2981				framebuffer->completeness(width, height, samples);
2982
2983                float threshold = 0.5f;
2984
2985                for(int i = 0; i < samples; i++)
2986                {
2987                    mask <<= 1;
2988
2989                    if((i + 1) * mState.sampleCoverageValue >= threshold)
2990                    {
2991                        threshold += 1.0f;
2992                        mask |= 1;
2993                    }
2994                }
2995            }
2996
2997            if(mState.sampleCoverageInvert)
2998            {
2999                mask = ~mask;
3000            }
3001
3002			device->setMultiSampleMask(mask);
3003        }
3004        else
3005        {
3006			device->setMultiSampleMask(0xFFFFFFFF);
3007        }
3008
3009        mSampleStateDirty = false;
3010    }
3011
3012    if(mDitherStateDirty)
3013    {
3014    //	UNIMPLEMENTED();   // FIXME
3015
3016        mDitherStateDirty = false;
3017    }
3018}
3019
3020GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
3021{
3022    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
3023
3024    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
3025    if(err != GL_NO_ERROR)
3026    {
3027        return err;
3028    }
3029
3030	Program *program = getCurrentProgram();
3031
3032	device->resetInputStreams(false);
3033
3034    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
3035	{
3036		if(program->getAttributeStream(i) == -1)
3037		{
3038			continue;
3039		}
3040
3041		sw::Resource *resource = attributes[i].vertexBuffer;
3042		const void *buffer = (char*)resource->data() + attributes[i].offset;
3043
3044		int stride = attributes[i].stride;
3045
3046		buffer = (char*)buffer + stride * base;
3047
3048		sw::Stream attribute(resource, buffer, stride);
3049
3050		attribute.type = attributes[i].type;
3051		attribute.count = attributes[i].count;
3052		attribute.normalized = attributes[i].normalized;
3053
3054		int stream = program->getAttributeStream(i);
3055		device->setInputStream(stream, attribute);
3056	}
3057
3058	return GL_NO_ERROR;
3059}
3060
3061// Applies the indices and element array bindings
3062GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
3063{
3064	GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo);
3065
3066    if(err == GL_NO_ERROR)
3067    {
3068        device->setIndexBuffer(indexInfo->indexBuffer);
3069    }
3070
3071    return err;
3072}
3073
3074// Applies the shaders and shader constants
3075void Context::applyShaders()
3076{
3077    Program *programObject = getCurrentProgram();
3078    sw::VertexShader *vertexShader = programObject->getVertexShader();
3079	sw::PixelShader *pixelShader = programObject->getPixelShader();
3080
3081    device->setVertexShader(vertexShader);
3082    device->setPixelShader(pixelShader);
3083
3084    if(programObject->getSerial() != mAppliedProgramSerial)
3085    {
3086        programObject->dirtyAllUniforms();
3087        mAppliedProgramSerial = programObject->getSerial();
3088    }
3089
3090    programObject->applyUniformBuffers(mState.uniformBuffers);
3091    programObject->applyUniforms();
3092}
3093
3094void Context::applyTextures()
3095{
3096    applyTextures(sw::SAMPLER_PIXEL);
3097	applyTextures(sw::SAMPLER_VERTEX);
3098}
3099
3100void Context::applyTextures(sw::SamplerType samplerType)
3101{
3102    Program *programObject = getCurrentProgram();
3103
3104    int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
3105
3106    for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
3107    {
3108        int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
3109
3110        if(textureUnit != -1)
3111        {
3112            TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
3113
3114            Texture *texture = getSamplerTexture(textureUnit, textureType);
3115
3116			if(texture->isSamplerComplete())
3117            {
3118				GLenum wrapS, wrapT, wrapR, minFilter, magFilter;
3119
3120				Sampler *samplerObject = mState.sampler[textureUnit];
3121				if(samplerObject)
3122				{
3123					wrapS = samplerObject->getWrapS();
3124					wrapT = samplerObject->getWrapT();
3125					wrapR = samplerObject->getWrapR();
3126					minFilter = samplerObject->getMinFilter();
3127					magFilter = samplerObject->getMagFilter();
3128				}
3129				else
3130				{
3131					wrapS = texture->getWrapS();
3132					wrapT = texture->getWrapT();
3133					wrapR = texture->getWrapR();
3134					minFilter = texture->getMinFilter();
3135					magFilter = texture->getMagFilter();
3136				}
3137				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
3138
3139				GLenum swizzleR = texture->getSwizzleR();
3140				GLenum swizzleG = texture->getSwizzleG();
3141				GLenum swizzleB = texture->getSwizzleB();
3142				GLenum swizzleA = texture->getSwizzleA();
3143
3144				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
3145				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
3146				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
3147				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
3148				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
3149				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
3150				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
3151
3152				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
3153				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
3154				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
3155
3156				applyTexture(samplerType, samplerIndex, texture);
3157            }
3158            else
3159            {
3160                applyTexture(samplerType, samplerIndex, nullptr);
3161            }
3162        }
3163        else
3164        {
3165            applyTexture(samplerType, samplerIndex, nullptr);
3166        }
3167    }
3168}
3169
3170void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
3171{
3172	Program *program = getCurrentProgram();
3173	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
3174	bool textureUsed = false;
3175
3176	if(type == sw::SAMPLER_PIXEL)
3177	{
3178		textureUsed = program->getPixelShader()->usesSampler(index);
3179	}
3180	else if(type == sw::SAMPLER_VERTEX)
3181	{
3182		textureUsed = program->getVertexShader()->usesSampler(index);
3183	}
3184	else UNREACHABLE(type);
3185
3186	sw::Resource *resource = 0;
3187
3188	if(baseTexture && textureUsed)
3189	{
3190		resource = baseTexture->getResource();
3191	}
3192
3193	device->setTextureResource(sampler, resource);
3194
3195	if(baseTexture && textureUsed)
3196	{
3197		int levelCount = baseTexture->getLevelCount();
3198
3199		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
3200		{
3201			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
3202
3203			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
3204			{
3205				int surfaceLevel = mipmapLevel;
3206
3207				if(surfaceLevel < 0)
3208				{
3209					surfaceLevel = 0;
3210				}
3211				else if(surfaceLevel >= levelCount)
3212				{
3213					surfaceLevel = levelCount - 1;
3214				}
3215
3216				egl::Image *surface = texture->getImage(surfaceLevel);
3217				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
3218			}
3219		}
3220		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)
3221		{
3222			Texture3D *texture = static_cast<Texture3D*>(baseTexture);
3223
3224			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
3225			{
3226				int surfaceLevel = mipmapLevel;
3227
3228				if(surfaceLevel < 0)
3229				{
3230					surfaceLevel = 0;
3231				}
3232				else if(surfaceLevel >= levelCount)
3233				{
3234					surfaceLevel = levelCount - 1;
3235				}
3236
3237				egl::Image *surface = texture->getImage(surfaceLevel);
3238				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
3239			}
3240		}
3241		else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)
3242		{
3243			Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
3244
3245			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
3246			{
3247				int surfaceLevel = mipmapLevel;
3248
3249				if(surfaceLevel < 0)
3250				{
3251					surfaceLevel = 0;
3252				}
3253				else if(surfaceLevel >= levelCount)
3254				{
3255					surfaceLevel = levelCount - 1;
3256				}
3257
3258				egl::Image *surface = texture->getImage(surfaceLevel);
3259				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
3260			}
3261		}
3262		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
3263		{
3264			for(int face = 0; face < 6; face++)
3265			{
3266				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
3267
3268				for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
3269				{
3270					int surfaceLevel = mipmapLevel;
3271
3272					if(surfaceLevel < 0)
3273					{
3274						surfaceLevel = 0;
3275					}
3276					else if(surfaceLevel >= levelCount)
3277					{
3278						surfaceLevel = levelCount - 1;
3279					}
3280
3281					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
3282					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
3283				}
3284			}
3285		}
3286		else UNIMPLEMENTED();
3287	}
3288	else
3289	{
3290		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
3291	}
3292}
3293
3294void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
3295                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
3296{
3297    Framebuffer *framebuffer = getReadFramebuffer();
3298	int framebufferWidth, framebufferHeight, framebufferSamples;
3299
3300    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
3301    {
3302        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3303    }
3304
3305    if(getReadFramebufferName() != 0 && framebufferSamples != 0)
3306    {
3307        return error(GL_INVALID_OPERATION);
3308    }
3309
3310	GLenum readFormat = framebuffer->getImplementationColorReadFormat();
3311	GLenum readType = framebuffer->getImplementationColorReadType();
3312
3313	if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))
3314	{
3315		return error(GL_INVALID_OPERATION);
3316	}
3317
3318	GLsizei outputPitch = egl::ComputePitch((mState.packRowLength > 0) ? mState.packRowLength : width, format, type, mState.packAlignment);
3319	GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;
3320	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
3321	pixels = ((char*)pixels) + (mState.packSkipImages * outputHeight + mState.packSkipRows) * outputPitch + mState.packSkipPixels;
3322
3323	// Sized query sanity check
3324    if(bufSize)
3325    {
3326        int requiredSize = outputPitch * height;
3327        if(requiredSize > *bufSize)
3328        {
3329            return error(GL_INVALID_OPERATION);
3330        }
3331    }
3332
3333    egl::Image *renderTarget = framebuffer->getReadRenderTarget();
3334
3335    if(!renderTarget)
3336    {
3337        return error(GL_OUT_OF_MEMORY);
3338    }
3339
3340	x += mState.packSkipPixels;
3341	y += mState.packSkipRows;
3342	sw::Rect rect = {x, y, x + width, y + height};
3343	sw::Rect dstRect = { 0, 0, width, height };
3344	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
3345
3346	sw::Surface externalSurface(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
3347	sw::SliceRect sliceRect(rect);
3348	sw::SliceRect dstSliceRect(dstRect);
3349	device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);
3350
3351	renderTarget->release();
3352}
3353
3354void Context::clear(GLbitfield mask)
3355{
3356    Framebuffer *framebuffer = getDrawFramebuffer();
3357
3358    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
3359    {
3360        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3361    }
3362
3363    if(!applyRenderTarget())
3364    {
3365        return;
3366    }
3367
3368	if(mask & GL_COLOR_BUFFER_BIT)
3369	{
3370		unsigned int rgbaMask = getColorMask();
3371
3372		if(rgbaMask != 0)
3373		{
3374			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
3375		}
3376	}
3377
3378	if(mask & GL_DEPTH_BUFFER_BIT)
3379	{
3380		if(mState.depthMask != 0)
3381		{
3382			float depth = clamp01(mState.depthClearValue);
3383			device->clearDepth(depth);
3384		}
3385	}
3386
3387	if(mask & GL_STENCIL_BUFFER_BIT)
3388	{
3389		if(mState.stencilWritemask != 0)
3390		{
3391			int stencil = mState.stencilClearValue & 0x000000FF;
3392			device->clearStencil(stencil, mState.stencilWritemask);
3393		}
3394	}
3395}
3396
3397void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
3398{
3399	unsigned int rgbaMask = getColorMask();
3400	if(device && rgbaMask)
3401	{
3402		int x0(0), y0(0), width(0), height(0);
3403		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false);
3404
3405		sw::SliceRect sliceRect;
3406		if(image->getClearRect(x0, y0, width, height, sliceRect))
3407		{
3408			device->clear(value, format, image, sliceRect, rgbaMask);
3409		}
3410
3411		image->release();
3412	}
3413}
3414
3415void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
3416{
3417	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
3418}
3419
3420void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
3421{
3422	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
3423}
3424
3425void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
3426{
3427	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
3428}
3429
3430void Context::clearDepthBuffer(GLint drawbuffer, const GLfloat *value)
3431{
3432	if(device && mState.depthMask)
3433	{
3434		int x0(0), y0(0), width(0), height(0);
3435		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);
3436
3437		float depth = clamp01(value[0]);
3438		image->clearDepthBuffer(depth, x0, y0, width, height);
3439
3440		image->release();
3441	}
3442}
3443
3444void Context::clearStencilBuffer(GLint drawbuffer, const GLint *value)
3445{
3446	if(device && mState.stencilWritemask)
3447	{
3448		int x0(0), y0(0), width(0), height(0);
3449		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);
3450
3451		unsigned char stencil = value[0] < 0 ? 0 : static_cast<unsigned char>(value[0] & 0x000000FF);
3452		image->clearStencilBuffer(stencil, static_cast<unsigned char>(mState.stencilWritemask), x0, y0, width, height);
3453
3454		image->release();
3455	}
3456}
3457
3458void Context::clearDepthStencilBuffer(GLint drawbuffer, GLfloat depth, GLint stencil)
3459{
3460	if(device && (mState.depthMask || mState.stencilWritemask))
3461	{
3462		int x0(0), y0(0), width(0), height(0);
3463		egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true);
3464
3465		if(mState.stencilWritemask)
3466		{
3467			image->clearStencilBuffer(static_cast<unsigned char>(stencil & 0x000000FF), static_cast<unsigned char>(mState.stencilWritemask), x0, y0, width, height);
3468		}
3469
3470		if(mState.depthMask)
3471		{
3472			image->clearDepthBuffer(clamp01(depth), x0, y0, width, height);
3473		}
3474
3475		image->release();
3476	}
3477}
3478
3479void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
3480{
3481    if(!mState.currentProgram)
3482    {
3483        return error(GL_INVALID_OPERATION);
3484    }
3485
3486    sw::DrawType primitiveType;
3487    int primitiveCount;
3488
3489    if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
3490        return error(GL_INVALID_ENUM);
3491
3492    if(primitiveCount <= 0)
3493    {
3494        return;
3495    }
3496
3497    if(!applyRenderTarget())
3498    {
3499        return;
3500    }
3501
3502    applyState(mode);
3503
3504	for(int i = 0; i < instanceCount; ++i)
3505	{
3506		device->setInstanceID(i);
3507
3508		GLenum err = applyVertexBuffer(0, first, count, i);
3509		if(err != GL_NO_ERROR)
3510		{
3511			return error(err);
3512		}
3513
3514		applyShaders();
3515		applyTextures();
3516
3517		if(!getCurrentProgram()->validateSamplers(false))
3518		{
3519			return error(GL_INVALID_OPERATION);
3520		}
3521
3522		if(!cullSkipsDraw(mode))
3523		{
3524			device->drawPrimitive(primitiveType, primitiveCount);
3525		}
3526	}
3527}
3528
3529void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
3530{
3531    if(!mState.currentProgram)
3532    {
3533        return error(GL_INVALID_OPERATION);
3534    }
3535
3536	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
3537    {
3538        return error(GL_INVALID_OPERATION);
3539    }
3540
3541    sw::DrawType primitiveType;
3542    int primitiveCount;
3543
3544    if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
3545        return error(GL_INVALID_ENUM);
3546
3547    if(primitiveCount <= 0)
3548    {
3549        return;
3550    }
3551
3552    if(!applyRenderTarget())
3553    {
3554        return;
3555    }
3556
3557    applyState(mode);
3558
3559	for(int i = 0; i < instanceCount; ++i)
3560	{
3561		device->setInstanceID(i);
3562
3563		TranslatedIndexData indexInfo;
3564		GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
3565		if(err != GL_NO_ERROR)
3566		{
3567			return error(err);
3568		}
3569
3570		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
3571		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
3572		if(err != GL_NO_ERROR)
3573		{
3574			return error(err);
3575		}
3576
3577		applyShaders();
3578		applyTextures();
3579
3580		if(!getCurrentProgram()->validateSamplers(false))
3581		{
3582			return error(GL_INVALID_OPERATION);
3583		}
3584
3585		if(!cullSkipsDraw(mode))
3586		{
3587			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
3588		}
3589	}
3590}
3591
3592void Context::finish()
3593{
3594	device->finish();
3595}
3596
3597void Context::flush()
3598{
3599    // We don't queue anything without processing it as fast as possible
3600}
3601
3602void Context::recordInvalidEnum()
3603{
3604    mInvalidEnum = true;
3605}
3606
3607void Context::recordInvalidValue()
3608{
3609    mInvalidValue = true;
3610}
3611
3612void Context::recordInvalidOperation()
3613{
3614    mInvalidOperation = true;
3615}
3616
3617void Context::recordOutOfMemory()
3618{
3619    mOutOfMemory = true;
3620}
3621
3622void Context::recordInvalidFramebufferOperation()
3623{
3624    mInvalidFramebufferOperation = true;
3625}
3626
3627// Get one of the recorded errors and clear its flag, if any.
3628// [OpenGL ES 2.0.24] section 2.5 page 13.
3629GLenum Context::getError()
3630{
3631    if(mInvalidEnum)
3632    {
3633        mInvalidEnum = false;
3634
3635        return GL_INVALID_ENUM;
3636    }
3637
3638    if(mInvalidValue)
3639    {
3640        mInvalidValue = false;
3641
3642        return GL_INVALID_VALUE;
3643    }
3644
3645    if(mInvalidOperation)
3646    {
3647        mInvalidOperation = false;
3648
3649        return GL_INVALID_OPERATION;
3650    }
3651
3652    if(mOutOfMemory)
3653    {
3654        mOutOfMemory = false;
3655
3656        return GL_OUT_OF_MEMORY;
3657    }
3658
3659    if(mInvalidFramebufferOperation)
3660    {
3661        mInvalidFramebufferOperation = false;
3662
3663        return GL_INVALID_FRAMEBUFFER_OPERATION;
3664    }
3665
3666    return GL_NO_ERROR;
3667}
3668
3669int Context::getSupportedMultisampleCount(int requested)
3670{
3671	int supported = 0;
3672
3673	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
3674	{
3675		if(supported >= requested)
3676		{
3677			return supported;
3678		}
3679
3680		supported = multisampleCount[i];
3681	}
3682
3683	return supported;
3684}
3685
3686void Context::detachBuffer(GLuint buffer)
3687{
3688	// [OpenGL ES 2.0.24] section 2.9 page 22:
3689	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
3690	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
3691
3692	if(mState.copyReadBuffer.name() == buffer)
3693	{
3694		mState.copyReadBuffer = nullptr;
3695	}
3696
3697	if(mState.copyWriteBuffer.name() == buffer)
3698	{
3699		mState.copyWriteBuffer = nullptr;
3700	}
3701
3702	if(mState.pixelPackBuffer.name() == buffer)
3703	{
3704		mState.pixelPackBuffer = nullptr;
3705	}
3706
3707	if(mState.pixelUnpackBuffer.name() == buffer)
3708	{
3709		mState.pixelUnpackBuffer = nullptr;
3710	}
3711
3712	if(mState.genericUniformBuffer.name() == buffer)
3713	{
3714		mState.genericUniformBuffer = nullptr;
3715	}
3716
3717	if(getArrayBufferName() == buffer)
3718	{
3719		mState.arrayBuffer = nullptr;
3720	}
3721
3722	// Only detach from the current transform feedback
3723	TransformFeedback* currentTransformFeedback = getTransformFeedback();
3724	if(currentTransformFeedback)
3725	{
3726		currentTransformFeedback->detachBuffer(buffer);
3727	}
3728
3729	// Only detach from the current vertex array
3730	VertexArray* currentVertexArray = getCurrentVertexArray();
3731	if(currentVertexArray)
3732	{
3733		currentVertexArray->detachBuffer(buffer);
3734	}
3735
3736	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3737	{
3738		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3739		{
3740			mState.vertexAttribute[attribute].mBoundBuffer = NULL;
3741		}
3742	}
3743}
3744
3745void Context::detachTexture(GLuint texture)
3746{
3747    // [OpenGL ES 2.0.24] section 3.8 page 84:
3748    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3749    // rebound to texture object zero
3750
3751    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3752    {
3753        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3754        {
3755            if(mState.samplerTexture[type][sampler].name() == texture)
3756            {
3757                mState.samplerTexture[type][sampler] = NULL;
3758            }
3759        }
3760    }
3761
3762    // [OpenGL ES 2.0.24] section 4.4 page 112:
3763    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3764    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3765    // image was attached in the currently bound framebuffer.
3766
3767    Framebuffer *readFramebuffer = getReadFramebuffer();
3768    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3769
3770    if(readFramebuffer)
3771    {
3772        readFramebuffer->detachTexture(texture);
3773    }
3774
3775    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3776    {
3777        drawFramebuffer->detachTexture(texture);
3778    }
3779}
3780
3781void Context::detachFramebuffer(GLuint framebuffer)
3782{
3783    // [OpenGL ES 2.0.24] section 4.4 page 107:
3784    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3785    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3786
3787    if(mState.readFramebuffer == framebuffer)
3788    {
3789        bindReadFramebuffer(0);
3790    }
3791
3792    if(mState.drawFramebuffer == framebuffer)
3793    {
3794        bindDrawFramebuffer(0);
3795    }
3796}
3797
3798void Context::detachRenderbuffer(GLuint renderbuffer)
3799{
3800    // [OpenGL ES 2.0.24] section 4.4 page 109:
3801    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3802    // had been executed with the target RENDERBUFFER and name of zero.
3803
3804    if(mState.renderbuffer.name() == renderbuffer)
3805    {
3806        bindRenderbuffer(0);
3807    }
3808
3809    // [OpenGL ES 2.0.24] section 4.4 page 111:
3810    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3811    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3812    // point to which this image was attached in the currently bound framebuffer.
3813
3814    Framebuffer *readFramebuffer = getReadFramebuffer();
3815    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3816
3817    if(readFramebuffer)
3818    {
3819        readFramebuffer->detachRenderbuffer(renderbuffer);
3820    }
3821
3822    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3823    {
3824        drawFramebuffer->detachRenderbuffer(renderbuffer);
3825    }
3826}
3827
3828void Context::detachSampler(GLuint sampler)
3829{
3830	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
3831	// If a sampler object that is currently bound to one or more texture units is
3832	// deleted, it is as though BindSampler is called once for each texture unit to
3833	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
3834	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
3835	{
3836		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
3837		if(samplerBinding.name() == sampler)
3838		{
3839			samplerBinding = NULL;
3840		}
3841	}
3842}
3843
3844bool Context::cullSkipsDraw(GLenum drawMode)
3845{
3846    return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3847}
3848
3849bool Context::isTriangleMode(GLenum drawMode)
3850{
3851    switch (drawMode)
3852    {
3853      case GL_TRIANGLES:
3854      case GL_TRIANGLE_FAN:
3855      case GL_TRIANGLE_STRIP:
3856        return true;
3857      case GL_POINTS:
3858      case GL_LINES:
3859      case GL_LINE_LOOP:
3860      case GL_LINE_STRIP:
3861        return false;
3862      default: UNREACHABLE(drawMode);
3863    }
3864
3865    return false;
3866}
3867
3868void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3869{
3870    ASSERT(index < MAX_VERTEX_ATTRIBS);
3871
3872    mState.vertexAttribute[index].setCurrentValue(values);
3873
3874    mVertexDataManager->dirtyCurrentValue(index);
3875}
3876
3877void Context::setVertexAttrib(GLuint index, const GLint *values)
3878{
3879	ASSERT(index < MAX_VERTEX_ATTRIBS);
3880
3881	mState.vertexAttribute[index].setCurrentValue(values);
3882
3883	mVertexDataManager->dirtyCurrentValue(index);
3884}
3885
3886void Context::setVertexAttrib(GLuint index, const GLuint *values)
3887{
3888	ASSERT(index < MAX_VERTEX_ATTRIBS);
3889
3890	mState.vertexAttribute[index].setCurrentValue(values);
3891
3892	mVertexDataManager->dirtyCurrentValue(index);
3893}
3894
3895void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
3896                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3897                              GLbitfield mask)
3898{
3899    Framebuffer *readFramebuffer = getReadFramebuffer();
3900    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3901
3902	int readBufferWidth, readBufferHeight, readBufferSamples;
3903    int drawBufferWidth, drawBufferHeight, drawBufferSamples;
3904
3905    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
3906       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
3907    {
3908        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3909    }
3910
3911    if(drawBufferSamples > 1)
3912    {
3913        return error(GL_INVALID_OPERATION);
3914    }
3915
3916    sw::SliceRect sourceRect;
3917    sw::SliceRect destRect;
3918	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
3919	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
3920
3921    if(srcX0 < srcX1)
3922    {
3923        sourceRect.x0 = srcX0;
3924        sourceRect.x1 = srcX1;
3925    }
3926    else
3927    {
3928        sourceRect.x0 = srcX1;
3929        sourceRect.x1 = srcX0;
3930    }
3931
3932	if(dstX0 < dstX1)
3933	{
3934		destRect.x0 = dstX0;
3935		destRect.x1 = dstX1;
3936	}
3937	else
3938	{
3939		destRect.x0 = dstX1;
3940		destRect.x1 = dstX0;
3941	}
3942
3943    if(srcY0 < srcY1)
3944    {
3945        sourceRect.y0 = srcY0;
3946        sourceRect.y1 = srcY1;
3947    }
3948    else
3949    {
3950        sourceRect.y0 = srcY1;
3951        sourceRect.y1 = srcY0;
3952    }
3953
3954	if(dstY0 < dstY1)
3955	{
3956		destRect.y0 = dstY0;
3957		destRect.y1 = dstY1;
3958	}
3959	else
3960	{
3961		destRect.y0 = dstY1;
3962		destRect.y1 = dstY0;
3963	}
3964
3965	sw::Rect sourceScissoredRect = sourceRect;
3966    sw::Rect destScissoredRect = destRect;
3967
3968    if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
3969    {
3970        if(destRect.x0 < mState.scissorX)
3971        {
3972            int xDiff = mState.scissorX - destRect.x0;
3973            destScissoredRect.x0 = mState.scissorX;
3974            sourceScissoredRect.x0 += xDiff;
3975        }
3976
3977        if(destRect.x1 > mState.scissorX + mState.scissorWidth)
3978        {
3979            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
3980            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
3981            sourceScissoredRect.x1 -= xDiff;
3982        }
3983
3984        if(destRect.y0 < mState.scissorY)
3985        {
3986            int yDiff = mState.scissorY - destRect.y0;
3987            destScissoredRect.y0 = mState.scissorY;
3988            sourceScissoredRect.y0 += yDiff;
3989        }
3990
3991        if(destRect.y1 > mState.scissorY + mState.scissorHeight)
3992        {
3993            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
3994            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
3995            sourceScissoredRect.y1 -= yDiff;
3996        }
3997    }
3998
3999    sw::Rect sourceTrimmedRect = sourceScissoredRect;
4000    sw::Rect destTrimmedRect = destScissoredRect;
4001
4002    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
4003    // the actual draw and read surfaces.
4004    if(sourceTrimmedRect.x0 < 0)
4005    {
4006        int xDiff = 0 - sourceTrimmedRect.x0;
4007        sourceTrimmedRect.x0 = 0;
4008        destTrimmedRect.x0 += xDiff;
4009    }
4010
4011    if(sourceTrimmedRect.x1 > readBufferWidth)
4012    {
4013        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
4014        sourceTrimmedRect.x1 = readBufferWidth;
4015        destTrimmedRect.x1 -= xDiff;
4016    }
4017
4018    if(sourceTrimmedRect.y0 < 0)
4019    {
4020        int yDiff = 0 - sourceTrimmedRect.y0;
4021        sourceTrimmedRect.y0 = 0;
4022        destTrimmedRect.y0 += yDiff;
4023    }
4024
4025    if(sourceTrimmedRect.y1 > readBufferHeight)
4026    {
4027        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
4028        sourceTrimmedRect.y1 = readBufferHeight;
4029        destTrimmedRect.y1 -= yDiff;
4030    }
4031
4032    if(destTrimmedRect.x0 < 0)
4033    {
4034        int xDiff = 0 - destTrimmedRect.x0;
4035        destTrimmedRect.x0 = 0;
4036        sourceTrimmedRect.x0 += xDiff;
4037    }
4038
4039    if(destTrimmedRect.x1 > drawBufferWidth)
4040    {
4041        int xDiff = destTrimmedRect.x1 - drawBufferWidth;
4042        destTrimmedRect.x1 = drawBufferWidth;
4043        sourceTrimmedRect.x1 -= xDiff;
4044    }
4045
4046    if(destTrimmedRect.y0 < 0)
4047    {
4048        int yDiff = 0 - destTrimmedRect.y0;
4049        destTrimmedRect.y0 = 0;
4050        sourceTrimmedRect.y0 += yDiff;
4051    }
4052
4053    if(destTrimmedRect.y1 > drawBufferHeight)
4054    {
4055        int yDiff = destTrimmedRect.y1 - drawBufferHeight;
4056        destTrimmedRect.y1 = drawBufferHeight;
4057        sourceTrimmedRect.y1 -= yDiff;
4058    }
4059
4060    bool partialBufferCopy = false;
4061
4062    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
4063       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
4064       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
4065       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
4066       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
4067    {
4068        partialBufferCopy = true;
4069    }
4070
4071	bool blitRenderTarget = false;
4072    bool blitDepthStencil = false;
4073
4074    if(mask & GL_COLOR_BUFFER_BIT)
4075    {
4076        const bool validReadType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_TEXTURE_2D ||
4077                                   readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_RENDERBUFFER;
4078        const bool validDrawType = drawFramebuffer->getColorbufferType(0) == GL_TEXTURE_2D ||
4079                                   drawFramebuffer->getColorbufferType(0) == GL_RENDERBUFFER;
4080        if(!validReadType || !validDrawType)
4081        {
4082            return error(GL_INVALID_OPERATION);
4083        }
4084
4085        if(partialBufferCopy && readBufferSamples > 1)
4086        {
4087            return error(GL_INVALID_OPERATION);
4088        }
4089
4090        blitRenderTarget = true;
4091    }
4092
4093    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
4094    {
4095        Renderbuffer *readDSBuffer = NULL;
4096        Renderbuffer *drawDSBuffer = NULL;
4097
4098        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
4099        // both a depth and stencil buffer, it will be the same buffer.
4100
4101        if(mask & GL_DEPTH_BUFFER_BIT)
4102        {
4103            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
4104            {
4105                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
4106                {
4107                    return error(GL_INVALID_OPERATION);
4108                }
4109
4110                blitDepthStencil = true;
4111                readDSBuffer = readFramebuffer->getDepthbuffer();
4112                drawDSBuffer = drawFramebuffer->getDepthbuffer();
4113            }
4114        }
4115
4116        if(mask & GL_STENCIL_BUFFER_BIT)
4117        {
4118            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
4119            {
4120                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
4121                {
4122                    return error(GL_INVALID_OPERATION);
4123                }
4124
4125                blitDepthStencil = true;
4126                readDSBuffer = readFramebuffer->getStencilbuffer();
4127                drawDSBuffer = drawFramebuffer->getStencilbuffer();
4128            }
4129        }
4130
4131        if(partialBufferCopy)
4132        {
4133            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
4134            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
4135        }
4136
4137        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
4138           (readDSBuffer && readDSBuffer->getSamples() > 1))
4139        {
4140            return error(GL_INVALID_OPERATION);
4141        }
4142    }
4143
4144    if(blitRenderTarget || blitDepthStencil)
4145    {
4146        if(blitRenderTarget)
4147        {
4148            egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
4149            egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
4150
4151			if(flipX)
4152			{
4153				swap(destRect.x0, destRect.x1);
4154			}
4155			if(flipy)
4156			{
4157				swap(destRect.y0, destRect.y1);
4158			}
4159
4160            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
4161
4162            readRenderTarget->release();
4163            drawRenderTarget->release();
4164
4165            if(!success)
4166            {
4167                ERR("BlitFramebuffer failed.");
4168                return;
4169            }
4170        }
4171
4172        if(blitDepthStencil)
4173        {
4174            bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false);
4175
4176            if(!success)
4177            {
4178                ERR("BlitFramebuffer failed.");
4179                return;
4180            }
4181        }
4182    }
4183}
4184
4185void Context::bindTexImage(egl::Surface *surface)
4186{
4187	es2::Texture2D *textureObject = getTexture2D();
4188
4189    if(textureObject)
4190    {
4191		textureObject->bindTexImage(surface);
4192	}
4193}
4194
4195EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4196{
4197    GLenum textureTarget = GL_NONE;
4198
4199    switch(target)
4200    {
4201    case EGL_GL_TEXTURE_2D_KHR:
4202        textureTarget = GL_TEXTURE_2D;
4203        break;
4204    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
4205    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
4206    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
4207    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
4208    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
4209    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
4210        textureTarget = GL_TEXTURE_CUBE_MAP;
4211        break;
4212    case EGL_GL_RENDERBUFFER_KHR:
4213        break;
4214    default:
4215        return EGL_BAD_PARAMETER;
4216    }
4217
4218    if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4219    {
4220        return EGL_BAD_MATCH;
4221    }
4222
4223    if(textureTarget != GL_NONE)
4224    {
4225        es2::Texture *texture = getTexture(name);
4226
4227        if(!texture || texture->getTarget() != textureTarget)
4228        {
4229            return EGL_BAD_PARAMETER;
4230        }
4231
4232        if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
4233        {
4234            return EGL_BAD_ACCESS;
4235        }
4236
4237        if(textureLevel != 0 && !texture->isSamplerComplete())
4238        {
4239            return EGL_BAD_PARAMETER;
4240        }
4241
4242        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
4243        {
4244            return EGL_BAD_PARAMETER;
4245        }
4246    }
4247    else if(target == EGL_GL_RENDERBUFFER_KHR)
4248    {
4249        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4250
4251        if(!renderbuffer)
4252        {
4253            return EGL_BAD_PARAMETER;
4254        }
4255
4256        if(renderbuffer->isShared())   // Already an EGLImage sibling
4257        {
4258            return EGL_BAD_ACCESS;
4259        }
4260    }
4261    else UNREACHABLE(target);
4262
4263	return EGL_SUCCESS;
4264}
4265
4266egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
4267{
4268	GLenum textureTarget = GL_NONE;
4269
4270    switch(target)
4271    {
4272    case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
4273    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
4274    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
4275    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
4276    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
4277    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
4278    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
4279    }
4280
4281    if(textureTarget != GL_NONE)
4282    {
4283        es2::Texture *texture = getTexture(name);
4284
4285        return texture->createSharedImage(textureTarget, textureLevel);
4286    }
4287    else if(target == EGL_GL_RENDERBUFFER_KHR)
4288    {
4289        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
4290
4291        return renderbuffer->createSharedImage();
4292    }
4293    else UNREACHABLE(target);
4294
4295	return 0;
4296}
4297
4298Device *Context::getDevice()
4299{
4300	return device;
4301}
4302
4303const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const
4304{
4305	// Keep list sorted in following order:
4306	// OES extensions
4307	// EXT extensions
4308	// Vendor extensions
4309	static const GLubyte* extensions[] = {
4310		(const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture",
4311		(const GLubyte*)"GL_OES_depth24",
4312		(const GLubyte*)"GL_OES_depth32",
4313		(const GLubyte*)"GL_OES_depth_texture",
4314		(const GLubyte*)"GL_OES_depth_texture_cube_map",
4315		(const GLubyte*)"GL_OES_EGL_image",
4316		(const GLubyte*)"GL_OES_EGL_image_external",
4317		(const GLubyte*)"GL_OES_EGL_sync",
4318		(const GLubyte*)"GL_OES_element_index_uint",
4319		(const GLubyte*)"GL_OES_framebuffer_object",
4320		(const GLubyte*)"GL_OES_packed_depth_stencil",
4321		(const GLubyte*)"GL_OES_rgb8_rgba8",
4322		(const GLubyte*)"GL_OES_standard_derivatives",
4323		(const GLubyte*)"GL_OES_texture_float",
4324		(const GLubyte*)"GL_OES_texture_float_linear",
4325		(const GLubyte*)"GL_OES_texture_half_float",
4326		(const GLubyte*)"GL_OES_texture_half_float_linear",
4327		(const GLubyte*)"GL_OES_texture_npot",
4328		(const GLubyte*)"GL_OES_texture_3D",
4329		(const GLubyte*)"GL_EXT_blend_minmax",
4330		(const GLubyte*)"GL_EXT_color_buffer_half_float",
4331		(const GLubyte*)"GL_EXT_occlusion_query_boolean",
4332		(const GLubyte*)"GL_EXT_read_format_bgra",
4333#if (S3TC_SUPPORT)
4334		(const GLubyte*)"GL_EXT_texture_compression_dxt1",
4335#endif
4336		(const GLubyte*)"GL_EXT_texture_filter_anisotropic",
4337		(const GLubyte*)"GL_EXT_texture_format_BGRA8888",
4338		(const GLubyte*)"GL_ANGLE_framebuffer_blit",
4339		(const GLubyte*)"GL_NV_framebuffer_blit",
4340		(const GLubyte*)"GL_ANGLE_framebuffer_multisample",
4341#if (S3TC_SUPPORT)
4342		(const GLubyte*)"GL_ANGLE_texture_compression_dxt3",
4343		(const GLubyte*)"GL_ANGLE_texture_compression_dxt5",
4344#endif
4345		(const GLubyte*)"GL_NV_fence",
4346		(const GLubyte*)"GL_EXT_instanced_arrays",
4347		(const GLubyte*)"GL_ANGLE_instanced_arrays",
4348	};
4349	static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions);
4350
4351	if(numExt)
4352	{
4353		*numExt = numExtensions;
4354		return nullptr;
4355	}
4356
4357	if(index == GL_INVALID_INDEX)
4358	{
4359		static GLubyte* extensionsCat = nullptr;
4360		if((extensionsCat == nullptr) && (numExtensions > 0))
4361		{
4362			int totalLength = numExtensions; // 1 space between each extension name + terminating null
4363			for(unsigned int i = 0; i < numExtensions; i++)
4364			{
4365				totalLength += strlen(reinterpret_cast<const char*>(extensions[i]));
4366			}
4367			extensionsCat = new GLubyte[totalLength];
4368			extensionsCat[0] = '\0';
4369			for(unsigned int i = 0; i < numExtensions; i++)
4370			{
4371				if(i != 0)
4372				{
4373					strcat(reinterpret_cast<char*>(extensionsCat), " ");
4374				}
4375				strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i]));
4376			}
4377		}
4378		return extensionsCat;
4379	}
4380
4381	if(index >= numExtensions)
4382	{
4383		return nullptr;
4384	}
4385
4386	return extensions[index];
4387}
4388
4389}
4390
4391egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion)
4392{
4393	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext
4394	return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion);
4395}
4396