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