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