Context.cpp revision ef6df8f0dd5f6de3d6f1fda901c220a23f6d56f2
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 es1::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 "Framebuffer.h"
23#include "Renderbuffer.h"
24#include "Texture.h"
25#include "VertexDataManager.h"
26#include "IndexDataManager.h"
27#include "libEGL/Display.h"
28#include "libEGL/Surface.h"
29#include "Common/Half.hpp"
30
31#include <EGL/eglext.h>
32
33#include <algorithm>
34
35#undef near
36#undef far
37
38namespace es1
39{
40Context::Context(const egl::Config *config, const Context *shareContext)
41    : modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
42      projectionStack(MAX_PROJECTION_STACK_DEPTH),
43	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
44	  textureStack1(MAX_TEXTURE_STACK_DEPTH)
45{
46	sw::Context *context = new sw::Context();
47	device = new es1::Device(context);
48
49	mVertexDataManager = new VertexDataManager(this);
50    mIndexDataManager = new IndexDataManager();
51
52    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
53
54    mState.depthClearValue = 1.0f;
55    mState.stencilClearValue = 0;
56
57    mState.cullFace = false;
58    mState.cullMode = GL_BACK;
59    mState.frontFace = GL_CCW;
60    mState.depthTest = false;
61    mState.depthFunc = GL_LESS;
62    mState.blend = false;
63    mState.sourceBlendRGB = GL_ONE;
64    mState.sourceBlendAlpha = GL_ONE;
65    mState.destBlendRGB = GL_ZERO;
66    mState.destBlendAlpha = GL_ZERO;
67    mState.blendEquationRGB = GL_FUNC_ADD_OES;
68    mState.blendEquationAlpha = GL_FUNC_ADD_OES;
69    mState.stencilTest = false;
70    mState.stencilFunc = GL_ALWAYS;
71    mState.stencilRef = 0;
72    mState.stencilMask = -1;
73    mState.stencilWritemask = -1;
74    mState.stencilFail = GL_KEEP;
75    mState.stencilPassDepthFail = GL_KEEP;
76    mState.stencilPassDepthPass = GL_KEEP;
77    mState.polygonOffsetFill = false;
78    mState.polygonOffsetFactor = 0.0f;
79    mState.polygonOffsetUnits = 0.0f;
80    mState.sampleAlphaToCoverage = false;
81    mState.sampleCoverage = false;
82    mState.sampleCoverageValue = 1.0f;
83    mState.sampleCoverageInvert = false;
84    mState.scissorTest = false;
85    mState.dither = true;
86	mState.shadeModel = GL_SMOOTH;
87    mState.generateMipmapHint = GL_DONT_CARE;
88	mState.perspectiveCorrectionHint = GL_DONT_CARE;
89
90    mState.lineWidth = 1.0f;
91
92    mState.viewportX = 0;
93    mState.viewportY = 0;
94    mState.viewportWidth = config->mDisplayMode.width;
95    mState.viewportHeight = config->mDisplayMode.height;
96    mState.zNear = 0.0f;
97    mState.zFar = 1.0f;
98
99    mState.scissorX = 0;
100    mState.scissorY = 0;
101    mState.scissorWidth = config->mDisplayMode.width;
102    mState.scissorHeight = config->mDisplayMode.height;
103
104    mState.colorMaskRed = true;
105    mState.colorMaskGreen = true;
106    mState.colorMaskBlue = true;
107    mState.colorMaskAlpha = true;
108    mState.depthMask = true;
109
110	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
111	{
112		mState.textureUnit[i].environmentMode = GL_MODULATE;
113		mState.textureUnit[i].combineRGB = GL_MODULATE;
114		mState.textureUnit[i].combineAlpha = GL_MODULATE;
115		mState.textureUnit[i].src0RGB = GL_TEXTURE;
116		mState.textureUnit[i].src1RGB = GL_PREVIOUS;
117		mState.textureUnit[i].src2RGB = GL_CONSTANT;
118		mState.textureUnit[i].src0Alpha = GL_TEXTURE;
119		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
120		mState.textureUnit[i].src2Alpha = GL_CONSTANT;
121		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
122		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
123		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
124		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
125		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
126		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
127	}
128
129    if(shareContext != NULL)
130    {
131        mResourceManager = shareContext->mResourceManager;
132        mResourceManager->addRef();
133    }
134    else
135    {
136        mResourceManager = new ResourceManager();
137    }
138
139    // [OpenGL ES 2.0.24] section 3.7 page 83:
140    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
141    // and cube map texture state vectors respectively associated with them.
142    // In order that access to these initial textures not be lost, they are treated as texture
143    // objects all of whose names are 0.
144
145    mTexture2DZero = new Texture2D(0);
146    mTextureExternalZero = new TextureExternal(0);
147
148    mState.activeSampler = 0;
149    bindArrayBuffer(0);
150    bindElementArrayBuffer(0);
151    bindTexture2D(0);
152    bindFramebuffer(0);
153    bindRenderbuffer(0);
154
155    mState.packAlignment = 4;
156    mState.unpackAlignment = 4;
157
158    mInvalidEnum = false;
159    mInvalidValue = false;
160    mInvalidOperation = false;
161    mOutOfMemory = false;
162    mInvalidFramebufferOperation = false;
163
164	lighting = false;
165
166	for(int i = 0; i < MAX_LIGHTS; i++)
167	{
168		light[i].enable = false;
169		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
170		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
171		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
172		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
173		light[i].direction = {0.0f, 0.0f, -1.0f};
174		light[i].attenuation = {1.0f, 0.0f, 0.0f};
175	}
176
177	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
178	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
179
180	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
181	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
182	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
183	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
184	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
185	materialShininess = 0.0f;
186
187	matrixMode = GL_MODELVIEW;
188
189	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
190	{
191		texture2Denabled[i] = false;
192		textureExternalEnabled[i] = false;
193	}
194
195	clientTexture = GL_TEXTURE0;
196
197	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
198
199	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
200	{
201		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
202	}
203
204	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
205	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
206
207    mHasBeenCurrent = false;
208
209    markAllStateDirty();
210}
211
212Context::~Context()
213{
214    while(!mFramebufferMap.empty())
215    {
216        deleteFramebuffer(mFramebufferMap.begin()->first);
217    }
218
219    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
220    {
221        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
222        {
223            mState.samplerTexture[type][sampler] = NULL;
224        }
225    }
226
227    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
228    {
229        mState.vertexAttribute[i].mBoundBuffer = NULL;
230    }
231
232    mState.arrayBuffer = NULL;
233    mState.elementArrayBuffer = NULL;
234    mState.renderbuffer = NULL;
235
236    mTexture2DZero = NULL;
237    mTextureExternalZero = NULL;
238
239    delete mVertexDataManager;
240    delete mIndexDataManager;
241
242    mResourceManager->release();
243	delete device;
244}
245
246void Context::makeCurrent(egl::Surface *surface)
247{
248    if(!mHasBeenCurrent)
249    {
250        mState.viewportX = 0;
251        mState.viewportY = 0;
252        mState.viewportWidth = surface->getWidth();
253        mState.viewportHeight = surface->getHeight();
254
255        mState.scissorX = 0;
256        mState.scissorY = 0;
257        mState.scissorWidth = surface->getWidth();
258        mState.scissorHeight = surface->getHeight();
259
260        mHasBeenCurrent = true;
261    }
262
263    // Wrap the existing resources into GL objects and assign them to the '0' names
264    egl::Image *defaultRenderTarget = surface->getRenderTarget();
265    egl::Image *depthStencil = surface->getDepthStencil();
266
267    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
268    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
269    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
270
271    setFramebufferZero(framebufferZero);
272
273    if(defaultRenderTarget)
274    {
275        defaultRenderTarget->release();
276    }
277
278    if(depthStencil)
279    {
280        depthStencil->release();
281    }
282
283    markAllStateDirty();
284}
285
286int Context::getClientVersion() const
287{
288	return 1;
289}
290
291// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
292void Context::markAllStateDirty()
293{
294    mDepthStateDirty = true;
295    mMaskStateDirty = true;
296    mBlendStateDirty = true;
297    mStencilStateDirty = true;
298    mPolygonOffsetStateDirty = true;
299    mSampleStateDirty = true;
300    mDitherStateDirty = true;
301    mFrontFaceDirty = true;
302}
303
304void Context::setClearColor(float red, float green, float blue, float alpha)
305{
306    mState.colorClearValue.red = red;
307    mState.colorClearValue.green = green;
308    mState.colorClearValue.blue = blue;
309    mState.colorClearValue.alpha = alpha;
310}
311
312void Context::setClearDepth(float depth)
313{
314    mState.depthClearValue = depth;
315}
316
317void Context::setClearStencil(int stencil)
318{
319    mState.stencilClearValue = stencil;
320}
321
322void Context::setCullFace(bool enabled)
323{
324    mState.cullFace = enabled;
325}
326
327bool Context::isCullFaceEnabled() const
328{
329    return mState.cullFace;
330}
331
332void Context::setCullMode(GLenum mode)
333{
334   mState.cullMode = mode;
335}
336
337void Context::setFrontFace(GLenum front)
338{
339    if(mState.frontFace != front)
340    {
341        mState.frontFace = front;
342        mFrontFaceDirty = true;
343    }
344}
345
346void Context::setDepthTest(bool enabled)
347{
348    if(mState.depthTest != enabled)
349    {
350        mState.depthTest = enabled;
351        mDepthStateDirty = true;
352    }
353}
354
355bool Context::isDepthTestEnabled() const
356{
357    return mState.depthTest;
358}
359
360void Context::setDepthFunc(GLenum depthFunc)
361{
362    if(mState.depthFunc != depthFunc)
363    {
364        mState.depthFunc = depthFunc;
365        mDepthStateDirty = true;
366    }
367}
368
369void Context::setDepthRange(float zNear, float zFar)
370{
371    mState.zNear = zNear;
372    mState.zFar = zFar;
373}
374
375void Context::setBlend(bool enabled)
376{
377    if(mState.blend != enabled)
378    {
379        mState.blend = enabled;
380        mBlendStateDirty = true;
381    }
382}
383
384bool Context::isBlendEnabled() const
385{
386    return mState.blend;
387}
388
389void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
390{
391    if(mState.sourceBlendRGB != sourceRGB ||
392       mState.sourceBlendAlpha != sourceAlpha ||
393       mState.destBlendRGB != destRGB ||
394       mState.destBlendAlpha != destAlpha)
395    {
396        mState.sourceBlendRGB = sourceRGB;
397        mState.destBlendRGB = destRGB;
398        mState.sourceBlendAlpha = sourceAlpha;
399        mState.destBlendAlpha = destAlpha;
400        mBlendStateDirty = true;
401    }
402}
403
404void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
405{
406    if(mState.blendEquationRGB != rgbEquation ||
407       mState.blendEquationAlpha != alphaEquation)
408    {
409        mState.blendEquationRGB = rgbEquation;
410        mState.blendEquationAlpha = alphaEquation;
411        mBlendStateDirty = true;
412    }
413}
414
415void Context::setStencilTest(bool enabled)
416{
417    if(mState.stencilTest != enabled)
418    {
419        mState.stencilTest = enabled;
420        mStencilStateDirty = true;
421    }
422}
423
424bool Context::isStencilTestEnabled() const
425{
426    return mState.stencilTest;
427}
428
429void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
430{
431    if(mState.stencilFunc != stencilFunc ||
432        mState.stencilRef != stencilRef ||
433        mState.stencilMask != stencilMask)
434    {
435        mState.stencilFunc = stencilFunc;
436        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
437        mState.stencilMask = stencilMask;
438        mStencilStateDirty = true;
439    }
440}
441
442void Context::setStencilWritemask(GLuint stencilWritemask)
443{
444    if(mState.stencilWritemask != stencilWritemask)
445    {
446        mState.stencilWritemask = stencilWritemask;
447        mStencilStateDirty = true;
448    }
449}
450
451void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
452{
453    if(mState.stencilFail != stencilFail ||
454        mState.stencilPassDepthFail != stencilPassDepthFail ||
455        mState.stencilPassDepthPass != stencilPassDepthPass)
456    {
457        mState.stencilFail = stencilFail;
458        mState.stencilPassDepthFail = stencilPassDepthFail;
459        mState.stencilPassDepthPass = stencilPassDepthPass;
460        mStencilStateDirty = true;
461    }
462}
463
464void Context::setPolygonOffsetFill(bool enabled)
465{
466    if(mState.polygonOffsetFill != enabled)
467    {
468        mState.polygonOffsetFill = enabled;
469        mPolygonOffsetStateDirty = true;
470    }
471}
472
473bool Context::isPolygonOffsetFillEnabled() const
474{
475    return mState.polygonOffsetFill;
476}
477
478void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
479{
480    if(mState.polygonOffsetFactor != factor ||
481        mState.polygonOffsetUnits != units)
482    {
483        mState.polygonOffsetFactor = factor;
484        mState.polygonOffsetUnits = units;
485        mPolygonOffsetStateDirty = true;
486    }
487}
488
489void Context::setSampleAlphaToCoverage(bool enabled)
490{
491    if(mState.sampleAlphaToCoverage != enabled)
492    {
493        mState.sampleAlphaToCoverage = enabled;
494        mSampleStateDirty = true;
495    }
496}
497
498bool Context::isSampleAlphaToCoverageEnabled() const
499{
500    return mState.sampleAlphaToCoverage;
501}
502
503void Context::setSampleCoverage(bool enabled)
504{
505    if(mState.sampleCoverage != enabled)
506    {
507        mState.sampleCoverage = enabled;
508        mSampleStateDirty = true;
509    }
510}
511
512bool Context::isSampleCoverageEnabled() const
513{
514    return mState.sampleCoverage;
515}
516
517void Context::setSampleCoverageParams(GLclampf value, bool invert)
518{
519    if(mState.sampleCoverageValue != value ||
520       mState.sampleCoverageInvert != invert)
521    {
522        mState.sampleCoverageValue = value;
523        mState.sampleCoverageInvert = invert;
524        mSampleStateDirty = true;
525    }
526}
527
528void Context::setScissorTest(bool enabled)
529{
530    mState.scissorTest = enabled;
531}
532
533bool Context::isScissorTestEnabled() const
534{
535    return mState.scissorTest;
536}
537
538void Context::setShadeModel(GLenum mode)
539{
540    mState.shadeModel = mode;
541}
542
543void Context::setDither(bool enabled)
544{
545    if(mState.dither != enabled)
546    {
547        mState.dither = enabled;
548        mDitherStateDirty = true;
549    }
550}
551
552bool Context::isDitherEnabled() const
553{
554    return mState.dither;
555}
556
557void Context::setLighting(bool enable)
558{
559    lighting = enable;
560}
561
562void Context::setLight(int index, bool enable)
563{
564    light[index].enable = enable;
565}
566
567void Context::setLightAmbient(int index, float r, float g, float b, float a)
568{
569	light[index].ambient = {r, g, b, a};
570}
571
572void Context::setLightDiffuse(int index, float r, float g, float b, float a)
573{
574	light[index].diffuse = {r, g, b, a};
575}
576
577void Context::setLightSpecular(int index, float r, float g, float b, float a)
578{
579	light[index].specular = {r, g, b, a};
580}
581
582void Context::setLightPosition(int index, float x, float y, float z, float w)
583{
584	sw::float4 v = {x, y, z, w};
585
586	// Transform from object coordinates to eye coordinates
587	v = modelViewStack.current() * v;
588
589	light[index].position = {v.x, v.y, v.z, v.w};
590}
591
592void Context::setLightDirection(int index, float x, float y, float z)
593{
594	// FIXME: Transform by inverse of 3x3 model-view matrix
595	light[index].direction = {x, y, z};
596}
597
598void Context::setLightAttenuationConstant(int index, float constant)
599{
600	light[index].attenuation.constant = constant;
601}
602
603void Context::setLightAttenuationLinear(int index, float linear)
604{
605	light[index].attenuation.linear = linear;
606}
607
608void Context::setLightAttenuationQuadratic(int index, float quadratic)
609{
610	light[index].attenuation.quadratic = quadratic;
611}
612
613void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
614{
615	globalAmbient.red = red;
616	globalAmbient.green = green;
617	globalAmbient.blue = blue;
618	globalAmbient.alpha = alpha;
619}
620
621void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
622{
623	materialAmbient.red = red;
624	materialAmbient.green = green;
625	materialAmbient.blue = blue;
626	materialAmbient.alpha = alpha;
627}
628
629void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
630{
631	materialDiffuse.red = red;
632	materialDiffuse.green = green;
633	materialDiffuse.blue = blue;
634	materialDiffuse.alpha = alpha;
635}
636
637void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
638{
639	materialSpecular.red = red;
640	materialSpecular.green = green;
641	materialSpecular.blue = blue;
642	materialSpecular.alpha = alpha;
643}
644
645void Context::setMaterialEmission(float red, float green, float blue, float alpha)
646{
647	materialEmission.red = red;
648	materialEmission.green = green;
649	materialEmission.blue = blue;
650	materialEmission.alpha = alpha;
651}
652
653void Context::setMaterialShininess(float shininess)
654{
655	materialShininess = shininess;
656}
657
658void Context::setFog(bool enable)
659{
660	device->setFogEnable(enable);
661}
662
663void Context::setFogMode(GLenum mode)
664{
665	switch(mode)
666	{
667	case GL_LINEAR:
668		device->setPixelFogMode(sw::FOG_LINEAR);
669		break;
670	case GL_EXP:
671		device->setPixelFogMode(sw::FOG_EXP);
672		break;
673	case GL_EXP2:
674		device->setPixelFogMode(sw::FOG_EXP2);
675		break;
676	default:
677		UNREACHABLE(mode);
678	}
679}
680
681void Context::setFogDensity(float fogDensity)
682{
683	device->setFogDensity(fogDensity);
684}
685
686void Context::setFogStart(float fogStart)
687{
688	device->setFogStart(fogStart);
689}
690
691void Context::setFogEnd(float fogEnd)
692{
693	device->setFogEnd(fogEnd);
694}
695
696void Context::setFogColor(float r, float g, float b, float a)
697{
698	device->setFogColor(sw::Color<float>(r, g, b, a));
699}
700
701void Context::setTexture2Denabled(bool enable)
702{
703    texture2Denabled[mState.activeSampler] = enable;
704}
705
706void Context::setTextureExternalEnabled(bool enable)
707{
708    textureExternalEnabled[mState.activeSampler] = enable;
709}
710
711void Context::setLineWidth(GLfloat width)
712{
713    mState.lineWidth = width;
714	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
715}
716
717void Context::setGenerateMipmapHint(GLenum hint)
718{
719    mState.generateMipmapHint = hint;
720}
721
722void Context::setPerspectiveCorrectionHint(GLenum hint)
723{
724    mState.perspectiveCorrectionHint = hint;
725}
726
727void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
728{
729    mState.viewportX = x;
730    mState.viewportY = y;
731    mState.viewportWidth = width;
732    mState.viewportHeight = height;
733}
734
735void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
736{
737    mState.scissorX = x;
738    mState.scissorY = y;
739    mState.scissorWidth = width;
740    mState.scissorHeight = height;
741}
742
743void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
744{
745    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
746       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
747    {
748        mState.colorMaskRed = red;
749        mState.colorMaskGreen = green;
750        mState.colorMaskBlue = blue;
751        mState.colorMaskAlpha = alpha;
752        mMaskStateDirty = true;
753    }
754}
755
756void Context::setDepthMask(bool mask)
757{
758    if(mState.depthMask != mask)
759    {
760        mState.depthMask = mask;
761        mMaskStateDirty = true;
762    }
763}
764
765void Context::setActiveSampler(unsigned int active)
766{
767    mState.activeSampler = active;
768}
769
770GLuint Context::getFramebufferName() const
771{
772    return mState.framebuffer;
773}
774
775GLuint Context::getRenderbufferName() const
776{
777    return mState.renderbuffer.name();
778}
779
780GLuint Context::getArrayBufferName() const
781{
782    return mState.arrayBuffer.name();
783}
784
785void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
786{
787    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
788}
789
790const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
791{
792    return mState.vertexAttribute[attribNum];
793}
794
795void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
796                                   GLsizei stride, const void *pointer)
797{
798    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
799    mState.vertexAttribute[attribNum].mSize = size;
800    mState.vertexAttribute[attribNum].mType = type;
801    mState.vertexAttribute[attribNum].mNormalized = normalized;
802    mState.vertexAttribute[attribNum].mStride = stride;
803    mState.vertexAttribute[attribNum].mPointer = pointer;
804}
805
806const void *Context::getVertexAttribPointer(unsigned int attribNum) const
807{
808    return mState.vertexAttribute[attribNum].mPointer;
809}
810
811const VertexAttributeArray &Context::getVertexAttributes()
812{
813    return mState.vertexAttribute;
814}
815
816void Context::setPackAlignment(GLint alignment)
817{
818    mState.packAlignment = alignment;
819}
820
821GLint Context::getPackAlignment() const
822{
823    return mState.packAlignment;
824}
825
826void Context::setUnpackAlignment(GLint alignment)
827{
828    mState.unpackAlignment = alignment;
829}
830
831GLint Context::getUnpackAlignment() const
832{
833    return mState.unpackAlignment;
834}
835
836GLuint Context::createBuffer()
837{
838    return mResourceManager->createBuffer();
839}
840
841GLuint Context::createTexture()
842{
843    return mResourceManager->createTexture();
844}
845
846GLuint Context::createRenderbuffer()
847{
848    return mResourceManager->createRenderbuffer();
849}
850
851// Returns an unused framebuffer name
852GLuint Context::createFramebuffer()
853{
854    GLuint handle = mFramebufferNameSpace.allocate();
855
856    mFramebufferMap[handle] = NULL;
857
858    return handle;
859}
860
861void Context::deleteBuffer(GLuint buffer)
862{
863    if(mResourceManager->getBuffer(buffer))
864    {
865        detachBuffer(buffer);
866    }
867
868    mResourceManager->deleteBuffer(buffer);
869}
870
871void Context::deleteTexture(GLuint texture)
872{
873    if(mResourceManager->getTexture(texture))
874    {
875        detachTexture(texture);
876    }
877
878    mResourceManager->deleteTexture(texture);
879}
880
881void Context::deleteRenderbuffer(GLuint renderbuffer)
882{
883    if(mResourceManager->getRenderbuffer(renderbuffer))
884    {
885        detachRenderbuffer(renderbuffer);
886    }
887
888    mResourceManager->deleteRenderbuffer(renderbuffer);
889}
890
891void Context::deleteFramebuffer(GLuint framebuffer)
892{
893    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
894
895    if(framebufferObject != mFramebufferMap.end())
896    {
897        detachFramebuffer(framebuffer);
898
899        mFramebufferNameSpace.release(framebufferObject->first);
900        delete framebufferObject->second;
901        mFramebufferMap.erase(framebufferObject);
902    }
903}
904
905Buffer *Context::getBuffer(GLuint handle)
906{
907    return mResourceManager->getBuffer(handle);
908}
909
910Texture *Context::getTexture(GLuint handle)
911{
912    return mResourceManager->getTexture(handle);
913}
914
915Renderbuffer *Context::getRenderbuffer(GLuint handle)
916{
917    return mResourceManager->getRenderbuffer(handle);
918}
919
920Framebuffer *Context::getFramebuffer()
921{
922    return getFramebuffer(mState.framebuffer);
923}
924
925void Context::bindArrayBuffer(unsigned int buffer)
926{
927    mResourceManager->checkBufferAllocation(buffer);
928
929    mState.arrayBuffer = getBuffer(buffer);
930}
931
932void Context::bindElementArrayBuffer(unsigned int buffer)
933{
934    mResourceManager->checkBufferAllocation(buffer);
935
936    mState.elementArrayBuffer = getBuffer(buffer);
937}
938
939void Context::bindTexture2D(GLuint texture)
940{
941    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
942
943    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
944}
945
946void Context::bindTextureExternal(GLuint texture)
947{
948    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
949
950    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
951}
952
953void Context::bindFramebuffer(GLuint framebuffer)
954{
955    if(!getFramebuffer(framebuffer))
956    {
957        mFramebufferMap[framebuffer] = new Framebuffer();
958    }
959
960    mState.framebuffer = framebuffer;
961}
962
963void Context::bindRenderbuffer(GLuint renderbuffer)
964{
965    mState.renderbuffer = getRenderbuffer(renderbuffer);
966}
967
968void Context::setFramebufferZero(Framebuffer *buffer)
969{
970    delete mFramebufferMap[0];
971    mFramebufferMap[0] = buffer;
972}
973
974void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
975{
976    Renderbuffer *renderbufferObject = mState.renderbuffer;
977    renderbufferObject->setStorage(renderbuffer);
978}
979
980Framebuffer *Context::getFramebuffer(unsigned int handle)
981{
982    FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
983
984    if(framebuffer == mFramebufferMap.end())
985    {
986        return NULL;
987    }
988    else
989    {
990        return framebuffer->second;
991    }
992}
993
994Buffer *Context::getArrayBuffer()
995{
996    return mState.arrayBuffer;
997}
998
999Buffer *Context::getElementArrayBuffer()
1000{
1001    return mState.elementArrayBuffer;
1002}
1003
1004Texture2D *Context::getTexture2D()
1005{
1006    return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1007}
1008
1009TextureExternal *Context::getTextureExternal()
1010{
1011    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1012}
1013
1014Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1015{
1016    GLuint texid = mState.samplerTexture[type][sampler].name();
1017
1018    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1019    {
1020        switch (type)
1021        {
1022        case TEXTURE_2D: return mTexture2DZero;
1023        case TEXTURE_EXTERNAL: return mTextureExternalZero;
1024        default: UNREACHABLE(type);
1025        }
1026    }
1027
1028    return mState.samplerTexture[type][sampler];
1029}
1030
1031bool Context::getBooleanv(GLenum pname, GLboolean *params)
1032{
1033    switch (pname)
1034    {
1035      case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
1036      case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
1037      case GL_COLOR_WRITEMASK:
1038        params[0] = mState.colorMaskRed;
1039        params[1] = mState.colorMaskGreen;
1040        params[2] = mState.colorMaskBlue;
1041        params[3] = mState.colorMaskAlpha;
1042        break;
1043      case GL_CULL_FACE:                *params = mState.cullFace;                  break;
1044      case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFill;         break;
1045      case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage;     break;
1046      case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverage;            break;
1047      case GL_SCISSOR_TEST:             *params = mState.scissorTest;               break;
1048      case GL_STENCIL_TEST:             *params = mState.stencilTest;               break;
1049      case GL_DEPTH_TEST:               *params = mState.depthTest;                 break;
1050      case GL_BLEND:                    *params = mState.blend;                     break;
1051      case GL_DITHER:                   *params = mState.dither;                    break;
1052      default:
1053        return false;
1054    }
1055
1056    return true;
1057}
1058
1059bool Context::getFloatv(GLenum pname, GLfloat *params)
1060{
1061    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1062    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1063    // GetIntegerv as its native query function. As it would require conversion in any
1064    // case, this should make no difference to the calling application.
1065    switch(pname)
1066    {
1067    case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1068    case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1069    case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1070    case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1071    case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1072    case GL_ALIASED_LINE_WIDTH_RANGE:
1073        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1074        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1075        break;
1076    case GL_ALIASED_POINT_SIZE_RANGE:
1077        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1078        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1079        break;
1080    case GL_DEPTH_RANGE:
1081        params[0] = mState.zNear;
1082        params[1] = mState.zFar;
1083        break;
1084    case GL_COLOR_CLEAR_VALUE:
1085        params[0] = mState.colorClearValue.red;
1086        params[1] = mState.colorClearValue.green;
1087        params[2] = mState.colorClearValue.blue;
1088        params[3] = mState.colorClearValue.alpha;
1089        break;
1090	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1091        *params = MAX_TEXTURE_MAX_ANISOTROPY;
1092		break;
1093	case GL_MODELVIEW_MATRIX:
1094		for(int i = 0; i < 16; i++)
1095		{
1096			params[i] = modelViewStack.current()[i % 4][i / 4];
1097		}
1098		break;
1099	case GL_PROJECTION_MATRIX:
1100		for(int i = 0; i < 16; i++)
1101		{
1102			params[i] = projectionStack.current()[i % 4][i / 4];
1103		}
1104		break;
1105    default:
1106        return false;
1107    }
1108
1109    return true;
1110}
1111
1112bool Context::getIntegerv(GLenum pname, GLint *params)
1113{
1114    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1115    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1116    // GetIntegerv as its native query function. As it would require conversion in any
1117    // case, this should make no difference to the calling application. You may find it in
1118    // Context::getFloatv.
1119    switch (pname)
1120    {
1121    case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
1122    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
1123	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;
1124    case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;
1125    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1126    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1127    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1128	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;
1129    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1130    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1131    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1132    case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
1133    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1134    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1135    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1136    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1137    case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;
1138    case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;
1139    case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;
1140    case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;
1141    case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;
1142    case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;
1143    case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
1144    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1145    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1146	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
1147	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
1148	case GL_SAMPLE_BUFFERS:
1149    case GL_SAMPLES:
1150        {
1151            Framebuffer *framebuffer = getFramebuffer();
1152			int width, height, samples;
1153
1154            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES)
1155            {
1156                switch(pname)
1157                {
1158                case GL_SAMPLE_BUFFERS:
1159                    if(samples > 1)
1160                    {
1161                        *params = 1;
1162                    }
1163                    else
1164                    {
1165                        *params = 0;
1166                    }
1167                    break;
1168                case GL_SAMPLES:
1169                    *params = samples & ~1;
1170                    break;
1171                }
1172            }
1173            else
1174            {
1175                *params = 0;
1176            }
1177        }
1178        break;
1179    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1180		{
1181			Framebuffer *framebuffer = getFramebuffer();
1182			*params = framebuffer->getImplementationColorReadType();
1183		}
1184		break;
1185    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1186		{
1187			Framebuffer *framebuffer = getFramebuffer();
1188			*params = framebuffer->getImplementationColorReadFormat();
1189		}
1190		break;
1191    case GL_MAX_VIEWPORT_DIMS:
1192        {
1193			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1194            params[0] = maxDimension;
1195            params[1] = maxDimension;
1196        }
1197        break;
1198    case GL_COMPRESSED_TEXTURE_FORMATS:
1199        {
1200			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1201			{
1202				params[i] = compressedTextureFormats[i];
1203			}
1204        }
1205        break;
1206    case GL_VIEWPORT:
1207        params[0] = mState.viewportX;
1208        params[1] = mState.viewportY;
1209        params[2] = mState.viewportWidth;
1210        params[3] = mState.viewportHeight;
1211        break;
1212    case GL_SCISSOR_BOX:
1213        params[0] = mState.scissorX;
1214        params[1] = mState.scissorY;
1215        params[2] = mState.scissorWidth;
1216        params[3] = mState.scissorHeight;
1217        break;
1218    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1219    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1220    case GL_RED_BITS:
1221    case GL_GREEN_BITS:
1222    case GL_BLUE_BITS:
1223    case GL_ALPHA_BITS:
1224        {
1225            Framebuffer *framebuffer = getFramebuffer();
1226            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1227
1228            if(colorbuffer)
1229            {
1230                switch (pname)
1231                {
1232                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1233                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1234                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1235                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1236                }
1237            }
1238            else
1239            {
1240                *params = 0;
1241            }
1242        }
1243        break;
1244    case GL_DEPTH_BITS:
1245        {
1246            Framebuffer *framebuffer = getFramebuffer();
1247            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1248
1249            if(depthbuffer)
1250            {
1251                *params = depthbuffer->getDepthSize();
1252            }
1253            else
1254            {
1255                *params = 0;
1256            }
1257        }
1258        break;
1259    case GL_STENCIL_BITS:
1260        {
1261            Framebuffer *framebuffer = getFramebuffer();
1262            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1263
1264            if(stencilbuffer)
1265            {
1266                *params = stencilbuffer->getStencilSize();
1267            }
1268            else
1269            {
1270                *params = 0;
1271            }
1272        }
1273        break;
1274    case GL_TEXTURE_BINDING_2D:
1275        {
1276            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)
1277            {
1278                error(GL_INVALID_OPERATION);
1279                return false;
1280            }
1281
1282            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
1283        }
1284        break;
1285    case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1286        {
1287            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)
1288            {
1289                error(GL_INVALID_OPERATION);
1290                return false;
1291            }
1292
1293            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
1294        }
1295        break;
1296    case GL_TEXTURE_BINDING_EXTERNAL_OES:
1297        {
1298            if(mState.activeSampler < 0 || mState.activeSampler > MAX_TEXTURE_UNITS - 1)
1299            {
1300                error(GL_INVALID_OPERATION);
1301                return false;
1302            }
1303
1304            *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
1305        }
1306        break;
1307	case GL_MAX_LIGHTS:                 *params = MAX_LIGHTS;                 break;
1308    case GL_MAX_MODELVIEW_STACK_DEPTH:  *params = MAX_MODELVIEW_STACK_DEPTH;  break;
1309	case GL_MAX_PROJECTION_STACK_DEPTH: *params = MAX_PROJECTION_STACK_DEPTH; break;
1310	case GL_MAX_TEXTURE_STACK_DEPTH:    *params = MAX_TEXTURE_STACK_DEPTH;    break;
1311	case GL_MAX_TEXTURE_UNITS:          *params = MAX_TEXTURE_UNITS;          break;
1312    default:
1313        return false;
1314    }
1315
1316    return true;
1317}
1318
1319int Context::getQueryParameterNum(GLenum pname)
1320{
1321    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1322    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1323    // to the fact that it is stored internally as a float, and so would require conversion
1324    // if returned from Context::getIntegerv. Since this conversion is already implemented
1325    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1326    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1327    // application.
1328    switch (pname)
1329    {
1330    case GL_COMPRESSED_TEXTURE_FORMATS:
1331		return NUM_COMPRESSED_TEXTURE_FORMATS;
1332    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1333    case GL_ARRAY_BUFFER_BINDING:
1334    case GL_FRAMEBUFFER_BINDING_OES:
1335    case GL_RENDERBUFFER_BINDING_OES:
1336    case GL_PACK_ALIGNMENT:
1337    case GL_UNPACK_ALIGNMENT:
1338    case GL_GENERATE_MIPMAP_HINT:
1339    case GL_RED_BITS:
1340    case GL_GREEN_BITS:
1341    case GL_BLUE_BITS:
1342    case GL_ALPHA_BITS:
1343    case GL_DEPTH_BITS:
1344    case GL_STENCIL_BITS:
1345    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1346    case GL_CULL_FACE_MODE:
1347    case GL_FRONT_FACE:
1348    case GL_ACTIVE_TEXTURE:
1349    case GL_STENCIL_FUNC:
1350    case GL_STENCIL_VALUE_MASK:
1351    case GL_STENCIL_REF:
1352    case GL_STENCIL_FAIL:
1353    case GL_STENCIL_PASS_DEPTH_FAIL:
1354    case GL_STENCIL_PASS_DEPTH_PASS:
1355    case GL_DEPTH_FUNC:
1356    case GL_BLEND_SRC_RGB_OES:
1357    case GL_BLEND_SRC_ALPHA_OES:
1358    case GL_BLEND_DST_RGB_OES:
1359    case GL_BLEND_DST_ALPHA_OES:
1360    case GL_BLEND_EQUATION_RGB_OES:
1361    case GL_BLEND_EQUATION_ALPHA_OES:
1362    case GL_STENCIL_WRITEMASK:
1363    case GL_STENCIL_CLEAR_VALUE:
1364    case GL_SUBPIXEL_BITS:
1365    case GL_MAX_TEXTURE_SIZE:
1366    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1367    case GL_SAMPLE_BUFFERS:
1368    case GL_SAMPLES:
1369    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1370    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1371    case GL_TEXTURE_BINDING_2D:
1372    case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1373    case GL_TEXTURE_BINDING_EXTERNAL_OES:
1374        return 1;
1375    case GL_MAX_VIEWPORT_DIMS:
1376        return 2;
1377    case GL_VIEWPORT:
1378    case GL_SCISSOR_BOX:
1379        return 4;
1380    case GL_SAMPLE_COVERAGE_INVERT:
1381    case GL_DEPTH_WRITEMASK:
1382    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1383    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1384    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1385    case GL_SAMPLE_COVERAGE:
1386    case GL_SCISSOR_TEST:
1387    case GL_STENCIL_TEST:
1388    case GL_DEPTH_TEST:
1389    case GL_BLEND:
1390    case GL_DITHER:
1391        return 1;
1392    case GL_COLOR_WRITEMASK:
1393        return 4;
1394    case GL_POLYGON_OFFSET_FACTOR:
1395    case GL_POLYGON_OFFSET_UNITS:
1396    case GL_SAMPLE_COVERAGE_VALUE:
1397    case GL_DEPTH_CLEAR_VALUE:
1398    case GL_LINE_WIDTH:
1399        return 1;
1400    case GL_ALIASED_LINE_WIDTH_RANGE:
1401    case GL_ALIASED_POINT_SIZE_RANGE:
1402    case GL_DEPTH_RANGE:
1403        return 2;
1404    case GL_COLOR_CLEAR_VALUE:
1405        return 4;
1406	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1407	case GL_MAX_LIGHTS:
1408	case GL_MAX_MODELVIEW_STACK_DEPTH:
1409	case GL_MAX_PROJECTION_STACK_DEPTH:
1410	case GL_MAX_TEXTURE_STACK_DEPTH:
1411	case GL_MAX_TEXTURE_UNITS:
1412        return 1;
1413	default:
1414		UNREACHABLE(pname);
1415    }
1416
1417    return -1;
1418}
1419
1420bool Context::isQueryParameterInt(GLenum pname)
1421{
1422    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1423    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1424    // to the fact that it is stored internally as a float, and so would require conversion
1425    // if returned from Context::getIntegerv. Since this conversion is already implemented
1426    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1427    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1428    // application.
1429    switch(pname)
1430    {
1431    case GL_COMPRESSED_TEXTURE_FORMATS:
1432    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1433    case GL_ARRAY_BUFFER_BINDING:
1434    case GL_FRAMEBUFFER_BINDING_OES:
1435    case GL_RENDERBUFFER_BINDING_OES:
1436    case GL_PACK_ALIGNMENT:
1437    case GL_UNPACK_ALIGNMENT:
1438    case GL_GENERATE_MIPMAP_HINT:
1439    case GL_RED_BITS:
1440    case GL_GREEN_BITS:
1441    case GL_BLUE_BITS:
1442    case GL_ALPHA_BITS:
1443    case GL_DEPTH_BITS:
1444    case GL_STENCIL_BITS:
1445    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1446    case GL_CULL_FACE_MODE:
1447    case GL_FRONT_FACE:
1448    case GL_ACTIVE_TEXTURE:
1449    case GL_STENCIL_FUNC:
1450    case GL_STENCIL_VALUE_MASK:
1451    case GL_STENCIL_REF:
1452    case GL_STENCIL_FAIL:
1453    case GL_STENCIL_PASS_DEPTH_FAIL:
1454    case GL_STENCIL_PASS_DEPTH_PASS:
1455    case GL_DEPTH_FUNC:
1456    case GL_BLEND_SRC_RGB_OES:
1457    case GL_BLEND_SRC_ALPHA_OES:
1458    case GL_BLEND_DST_RGB_OES:
1459    case GL_BLEND_DST_ALPHA_OES:
1460    case GL_BLEND_EQUATION_RGB_OES:
1461    case GL_BLEND_EQUATION_ALPHA_OES:
1462    case GL_STENCIL_WRITEMASK:
1463    case GL_STENCIL_CLEAR_VALUE:
1464    case GL_SUBPIXEL_BITS:
1465    case GL_MAX_TEXTURE_SIZE:
1466    case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
1467    case GL_SAMPLE_BUFFERS:
1468    case GL_SAMPLES:
1469    case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
1470    case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
1471    case GL_TEXTURE_BINDING_2D:
1472    case GL_TEXTURE_BINDING_CUBE_MAP_OES:
1473    case GL_TEXTURE_BINDING_EXTERNAL_OES:
1474    case GL_MAX_VIEWPORT_DIMS:
1475    case GL_VIEWPORT:
1476    case GL_SCISSOR_BOX:
1477	case GL_MAX_LIGHTS:
1478	case GL_MAX_MODELVIEW_STACK_DEPTH:
1479	case GL_MAX_PROJECTION_STACK_DEPTH:
1480	case GL_MAX_TEXTURE_STACK_DEPTH:
1481	case GL_MAX_TEXTURE_UNITS:
1482        return true;
1483	default:
1484		ASSERT(isQueryParameterFloat(pname) || isQueryParameterBool(pname));
1485    }
1486
1487    return false;
1488}
1489
1490bool Context::isQueryParameterFloat(GLenum pname)
1491{
1492    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1493    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1494    // to the fact that it is stored internally as a float, and so would require conversion
1495    // if returned from Context::getIntegerv. Since this conversion is already implemented
1496    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1497    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1498    // application.
1499    switch(pname)
1500    {
1501    case GL_POLYGON_OFFSET_FACTOR:
1502    case GL_POLYGON_OFFSET_UNITS:
1503    case GL_SAMPLE_COVERAGE_VALUE:
1504    case GL_DEPTH_CLEAR_VALUE:
1505    case GL_LINE_WIDTH:
1506    case GL_ALIASED_LINE_WIDTH_RANGE:
1507    case GL_ALIASED_POINT_SIZE_RANGE:
1508    case GL_DEPTH_RANGE:
1509    case GL_COLOR_CLEAR_VALUE:
1510	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1511        return true;
1512    default:
1513        ASSERT(isQueryParameterInt(pname) || isQueryParameterBool(pname));
1514    }
1515
1516    return false;
1517}
1518
1519bool Context::isQueryParameterBool(GLenum pname)
1520{
1521    switch(pname)
1522    {
1523    case GL_SAMPLE_COVERAGE_INVERT:
1524    case GL_DEPTH_WRITEMASK:
1525    case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1526    case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1527    case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1528    case GL_SAMPLE_COVERAGE:
1529    case GL_SCISSOR_TEST:
1530    case GL_STENCIL_TEST:
1531    case GL_DEPTH_TEST:
1532    case GL_BLEND:
1533    case GL_DITHER:
1534    case GL_COLOR_WRITEMASK:
1535        return true;
1536    default:
1537        ASSERT(isQueryParameterInt(pname) || isQueryParameterFloat(pname));
1538    }
1539
1540    return false;
1541}
1542
1543// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
1544bool Context::applyRenderTarget()
1545{
1546    Framebuffer *framebuffer = getFramebuffer();
1547	int width, height, samples;
1548
1549    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
1550    {
1551        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
1552    }
1553
1554    egl::Image *renderTarget = framebuffer->getRenderTarget();
1555	device->setRenderTarget(renderTarget);
1556	if(renderTarget) renderTarget->release();
1557
1558    egl::Image *depthStencil = framebuffer->getDepthStencil();
1559    device->setDepthStencilSurface(depthStencil);
1560	if(depthStencil) depthStencil->release();
1561
1562    Viewport viewport;
1563    float zNear = clamp01(mState.zNear);
1564    float zFar = clamp01(mState.zFar);
1565
1566    viewport.x0 = mState.viewportX;
1567    viewport.y0 = mState.viewportY;
1568    viewport.width = mState.viewportWidth;
1569    viewport.height = mState.viewportHeight;
1570    viewport.minZ = zNear;
1571    viewport.maxZ = zFar;
1572
1573    device->setViewport(viewport);
1574
1575    if(mState.scissorTest)
1576    {
1577		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1578		scissor.clip(0, 0, width, height);
1579
1580		device->setScissorRect(scissor);
1581        device->setScissorEnable(true);
1582    }
1583    else
1584    {
1585        device->setScissorEnable(false);
1586    }
1587
1588    return true;
1589}
1590
1591// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
1592void Context::applyState(GLenum drawMode)
1593{
1594    Framebuffer *framebuffer = getFramebuffer();
1595
1596    if(mState.cullFace)
1597    {
1598        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1599    }
1600    else
1601    {
1602		device->setCullMode(sw::CULL_NONE);
1603    }
1604
1605    if(mDepthStateDirty)
1606    {
1607        if(mState.depthTest)
1608        {
1609			device->setDepthBufferEnable(true);
1610			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1611        }
1612        else
1613        {
1614            device->setDepthBufferEnable(false);
1615        }
1616
1617        mDepthStateDirty = false;
1618    }
1619
1620    if(mBlendStateDirty)
1621    {
1622        if(mState.blend)
1623        {
1624			device->setAlphaBlendEnable(true);
1625			device->setSeparateAlphaBlendEnable(true);
1626
1627			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1628			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1629			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1630
1631            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1632			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1633			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1634        }
1635        else
1636        {
1637			device->setAlphaBlendEnable(false);
1638        }
1639
1640        mBlendStateDirty = false;
1641    }
1642
1643    if(mStencilStateDirty || mFrontFaceDirty)
1644    {
1645        if(mState.stencilTest && framebuffer->hasStencil())
1646        {
1647			device->setStencilEnable(true);
1648			device->setTwoSidedStencil(true);
1649
1650            // get the maximum size of the stencil ref
1651            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1652            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1653
1654			device->setStencilWriteMask(mState.stencilWritemask);
1655			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1656
1657			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1658			device->setStencilMask(mState.stencilMask);
1659
1660			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1661			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1662			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1663
1664			device->setStencilWriteMaskCCW(mState.stencilWritemask);
1665			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1666
1667			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1668			device->setStencilMaskCCW(mState.stencilMask);
1669
1670			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1671			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1672			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1673        }
1674        else
1675        {
1676			device->setStencilEnable(false);
1677        }
1678
1679        mStencilStateDirty = false;
1680        mFrontFaceDirty = false;
1681    }
1682
1683    if(mMaskStateDirty)
1684    {
1685		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1686		device->setDepthWriteEnable(mState.depthMask);
1687
1688        mMaskStateDirty = false;
1689    }
1690
1691    if(mPolygonOffsetStateDirty)
1692    {
1693        if(mState.polygonOffsetFill)
1694        {
1695            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1696            if(depthbuffer)
1697            {
1698				device->setSlopeDepthBias(mState.polygonOffsetFactor);
1699                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1700				device->setDepthBias(depthBias);
1701            }
1702        }
1703        else
1704        {
1705            device->setSlopeDepthBias(0);
1706            device->setDepthBias(0);
1707        }
1708
1709        mPolygonOffsetStateDirty = false;
1710    }
1711
1712    if(mSampleStateDirty)
1713    {
1714        if(mState.sampleAlphaToCoverage)
1715        {
1716            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1717        }
1718		else
1719		{
1720			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1721		}
1722
1723        if(mState.sampleCoverage)
1724        {
1725            unsigned int mask = 0;
1726            if(mState.sampleCoverageValue != 0)
1727            {
1728				int width, height, samples;
1729				framebuffer->completeness(width, height, samples);
1730
1731                float threshold = 0.5f;
1732
1733                for(int i = 0; i < samples; i++)
1734                {
1735                    mask <<= 1;
1736
1737                    if((i + 1) * mState.sampleCoverageValue >= threshold)
1738                    {
1739                        threshold += 1.0f;
1740                        mask |= 1;
1741                    }
1742                }
1743            }
1744
1745            if(mState.sampleCoverageInvert)
1746            {
1747                mask = ~mask;
1748            }
1749
1750			device->setMultiSampleMask(mask);
1751        }
1752        else
1753        {
1754			device->setMultiSampleMask(0xFFFFFFFF);
1755        }
1756
1757        mSampleStateDirty = false;
1758    }
1759
1760    if(mDitherStateDirty)
1761    {
1762    //	UNIMPLEMENTED();   // FIXME
1763
1764        mDitherStateDirty = false;
1765    }
1766
1767	switch(mState.shadeModel)
1768	{
1769	default: UNREACHABLE(mState.shadeModel);
1770	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
1771	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
1772	}
1773
1774	device->setLightingEnable(lighting);
1775	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
1776
1777	for(int i = 0; i < MAX_LIGHTS; i++)
1778	{
1779		device->setLightEnable(i, light[i].enable);
1780		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
1781		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
1782		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
1783		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
1784
1785		if(light[i].position.w != 0.0f)
1786		{
1787			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
1788		}
1789		else   // Directional light
1790		{
1791			// Hack: set the position far way
1792			float max = std::max(std::max(abs(light[i].position.x), abs(light[i].position.y)), abs(light[i].position.z));
1793			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
1794		}
1795	}
1796
1797	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
1798	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
1799	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
1800	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
1801	device->setMaterialShininess(materialShininess);
1802
1803    device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
1804	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
1805	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
1806	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
1807
1808    device->setProjectionMatrix(projectionStack.current());
1809    device->setModelMatrix(modelViewStack.current());
1810    device->setTextureMatrix(0, textureStack0.current());
1811	device->setTextureMatrix(1, textureStack1.current());
1812	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
1813	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
1814	device->setTexGen(0, sw::TEXGEN_NONE);
1815	device->setTexGen(1, sw::TEXGEN_NONE);
1816}
1817
1818GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1819{
1820    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1821
1822    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
1823    if(err != GL_NO_ERROR)
1824    {
1825        return err;
1826    }
1827
1828	device->resetInputStreams(false);
1829
1830    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
1831	{
1832		sw::Resource *resource = attributes[i].vertexBuffer;
1833		const void *buffer = (char*)resource->data() + attributes[i].offset;
1834
1835		int stride = attributes[i].stride;
1836
1837		buffer = (char*)buffer + stride * base;
1838
1839		sw::Stream attribute(resource, buffer, stride);
1840
1841		attribute.type = attributes[i].type;
1842		attribute.count = attributes[i].count;
1843		attribute.normalized = attributes[i].normalized;
1844
1845		device->setInputStream(i, attribute);
1846	}
1847
1848	return GL_NO_ERROR;
1849}
1850
1851// Applies the indices and element array bindings
1852GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
1853{
1854    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
1855
1856    if(err == GL_NO_ERROR)
1857    {
1858        device->setIndexBuffer(indexInfo->indexBuffer);
1859    }
1860
1861    return err;
1862}
1863
1864void Context::applyTextures()
1865{
1866	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
1867    {
1868        Texture *texture = nullptr;
1869
1870		if(textureExternalEnabled[unit])
1871		{
1872			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
1873		}
1874		else if(texture2Denabled[unit])
1875		{
1876			texture = getSamplerTexture(unit, TEXTURE_2D);
1877		}
1878
1879		if(texture && texture->isSamplerComplete())
1880        {
1881			texture->autoGenerateMipmaps();
1882
1883            GLenum wrapS = texture->getWrapS();
1884            GLenum wrapT = texture->getWrapT();
1885            GLenum texFilter = texture->getMinFilter();
1886            GLenum magFilter = texture->getMagFilter();
1887			GLfloat maxAnisotropy = texture->getMaxAnisotropy();
1888
1889			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
1890            device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
1891
1892			sw::FilterType minFilter;
1893			sw::MipmapType mipFilter;
1894            es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy);
1895		//	ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter));
1896
1897			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, minFilter);
1898		//	device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMagFilter(magFilter));
1899			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, mipFilter);
1900			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
1901
1902			applyTexture(unit, texture);
1903
1904			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
1905			{
1906				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs
1907				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
1908				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp
1909				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
1910				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc
1911				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
1912
1913				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As
1914				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
1915				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap
1916				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
1917				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac
1918				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
1919
1920				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
1921
1922				switch(mState.textureUnit[unit].environmentMode)
1923				{
1924				case GL_REPLACE:
1925					if(IsAlpha(texFormat))   // GL_ALPHA
1926					{
1927						// Cv = Cp, Av = As
1928						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
1929						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
1930					}
1931					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
1932					{
1933						// Cv = Cs, Av = Ap
1934						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
1935						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
1936					}
1937					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
1938					{
1939						// Cv = Cs, Av = As
1940						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
1941						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
1942					}
1943					else UNREACHABLE(texFormat);
1944					break;
1945				case GL_MODULATE:
1946					if(IsAlpha(texFormat))   // GL_ALPHA
1947					{
1948						// Cv = Cp, Av = ApAs
1949						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
1950						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
1951					}
1952					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
1953					{
1954						// Cv = CpCs, Av = Ap
1955						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
1956						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
1957					}
1958					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
1959					{
1960						// Cv = CpCs, Av = ApAs
1961						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
1962						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
1963					}
1964					else UNREACHABLE(texFormat);
1965					break;
1966				case GL_DECAL:
1967					if(texFormat == GL_ALPHA ||
1968					   texFormat == GL_LUMINANCE ||
1969					   texFormat == GL_LUMINANCE_ALPHA)
1970					{
1971						// undefined   // FIXME: Log
1972						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
1973						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
1974					}
1975					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
1976					{
1977						// Cv = Cs, Av = Ap
1978						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
1979						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
1980					}
1981					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
1982					{
1983						// Cv = Cp(1 - As) + CsAs, Av = Ap
1984						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2
1985						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
1986					}
1987					else UNREACHABLE(texFormat);
1988					break;
1989				case GL_BLEND:
1990					if(IsAlpha(texFormat))   // GL_ALPHA
1991					{
1992						// Cv = Cp, Av = ApAs
1993						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
1994						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
1995					}
1996					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
1997					{
1998						// Cv = Cp(1 - Cs) + CcCs, Av = Ap
1999						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
2000						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2001					}
2002					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2003					{
2004						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs
2005						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
2006						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2007					}
2008					else UNREACHABLE(texFormat);
2009					break;
2010				case GL_ADD:
2011					if(IsAlpha(texFormat))   // GL_ALPHA
2012					{
2013						// Cv = Cp, Av = ApAs
2014						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
2015						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2016					}
2017					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
2018					{
2019						// Cv = Cp + Cs, Av = Ap
2020						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2021						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
2022					}
2023					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
2024					{
2025						// Cv = Cp + Cs, Av = ApAs
2026						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
2027						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
2028					}
2029					else UNREACHABLE(texFormat);
2030					break;
2031				default:
2032					UNREACHABLE(mState.textureUnit[unit].environmentMode);
2033				}
2034			}
2035			else   // GL_COMBINE
2036			{
2037				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
2038				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
2039				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
2040				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
2041				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
2042				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
2043
2044				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
2045
2046				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
2047				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
2048				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
2049				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
2050				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
2051				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
2052
2053				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
2054			}
2055        }
2056        else
2057        {
2058            applyTexture(unit, 0);
2059
2060			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
2061			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
2062			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
2063
2064			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
2065			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
2066			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
2067        }
2068    }
2069}
2070
2071void Context::setTextureEnvMode(GLenum texEnvMode)
2072{
2073	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
2074}
2075
2076void Context::setCombineRGB(GLenum combineRGB)
2077{
2078	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
2079}
2080
2081void Context::setCombineAlpha(GLenum combineAlpha)
2082{
2083	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
2084}
2085
2086void Context::applyTexture(int index, Texture *baseTexture)
2087{
2088	sw::Resource *resource = 0;
2089
2090	if(baseTexture)
2091	{
2092		resource = baseTexture->getResource();
2093	}
2094
2095	device->setTextureResource(index, resource);
2096
2097	if(baseTexture)
2098	{
2099		int levelCount = baseTexture->getLevelCount();
2100
2101		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
2102		{
2103			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2104
2105			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2106			{
2107				int surfaceLevel = mipmapLevel;
2108
2109				if(surfaceLevel < 0)
2110				{
2111					surfaceLevel = 0;
2112				}
2113				else if(surfaceLevel >= levelCount)
2114				{
2115					surfaceLevel = levelCount - 1;
2116				}
2117
2118				egl::Image *surface = texture->getImage(surfaceLevel);
2119				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2120			}
2121		}
2122		else UNIMPLEMENTED();
2123	}
2124	else
2125	{
2126		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
2127	}
2128}
2129
2130void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2131                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2132{
2133    Framebuffer *framebuffer = getFramebuffer();
2134	int framebufferWidth, framebufferHeight, framebufferSamples;
2135
2136    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES)
2137    {
2138        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2139    }
2140
2141    if(getFramebufferName() != 0 && framebufferSamples != 0)
2142    {
2143        return error(GL_INVALID_OPERATION);
2144    }
2145
2146	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
2147	{
2148		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
2149		{
2150			return error(GL_INVALID_OPERATION);
2151		}
2152	}
2153
2154	GLsizei outputPitch = egl::ComputePitch(width, format, type, mState.packAlignment);
2155
2156	// Sized query sanity check
2157    if(bufSize)
2158    {
2159        int requiredSize = outputPitch * height;
2160        if(requiredSize > *bufSize)
2161        {
2162            return error(GL_INVALID_OPERATION);
2163        }
2164    }
2165
2166    egl::Image *renderTarget = framebuffer->getRenderTarget();
2167
2168    if(!renderTarget)
2169    {
2170        return error(GL_OUT_OF_MEMORY);
2171    }
2172
2173	sw::Rect rect = {x, y, x + width, y + height};
2174	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2175
2176    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2177    unsigned char *dest = (unsigned char*)pixels;
2178    int inputPitch = (int)renderTarget->getPitch();
2179
2180    for(int j = 0; j < rect.y1 - rect.y0; j++)
2181    {
2182		unsigned short *dest16 = (unsigned short*)dest;
2183		unsigned int *dest32 = (unsigned int*)dest;
2184
2185		if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 &&
2186           format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2187        {
2188            memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2189        }
2190		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2191                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2192        {
2193            for(int i = 0; i < rect.x1 - rect.x0; i++)
2194			{
2195				unsigned int argb = *(unsigned int*)(source + 4 * i);
2196
2197				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
2198			}
2199        }
2200		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2201                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2202        {
2203            for(int i = 0; i < rect.x1 - rect.x0; i++)
2204			{
2205				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2206
2207				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
2208			}
2209        }
2210		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2211                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2212        {
2213            for(int i = 0; i < rect.x1 - rect.x0; i++)
2214			{
2215				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2216
2217				dest32[i] = xrgb | 0xFF000000;
2218			}
2219        }
2220        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2221                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2222        {
2223            memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2224        }
2225		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
2226                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
2227        {
2228            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2229        }
2230		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
2231                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
2232        {
2233            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2234        }
2235		else
2236		{
2237			for(int i = 0; i < rect.x1 - rect.x0; i++)
2238			{
2239				float r;
2240				float g;
2241				float b;
2242				float a;
2243
2244				switch(renderTarget->getInternalFormat())
2245				{
2246				case sw::FORMAT_R5G6B5:
2247					{
2248						unsigned short rgb = *(unsigned short*)(source + 2 * i);
2249
2250						a = 1.0f;
2251						b = (rgb & 0x001F) * (1.0f / 0x001F);
2252						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2253						r = (rgb & 0xF800) * (1.0f / 0xF800);
2254					}
2255					break;
2256				case sw::FORMAT_A1R5G5B5:
2257					{
2258						unsigned short argb = *(unsigned short*)(source + 2 * i);
2259
2260						a = (argb & 0x8000) ? 1.0f : 0.0f;
2261						b = (argb & 0x001F) * (1.0f / 0x001F);
2262						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2263						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2264					}
2265					break;
2266				case sw::FORMAT_A8R8G8B8:
2267					{
2268						unsigned int argb = *(unsigned int*)(source + 4 * i);
2269
2270						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2271						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2272						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2273						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2274					}
2275					break;
2276				case sw::FORMAT_A8B8G8R8:
2277					{
2278						unsigned int abgr = *(unsigned int*)(source + 4 * i);
2279
2280						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
2281						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2282						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2283						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
2284					}
2285					break;
2286				case sw::FORMAT_X8R8G8B8:
2287					{
2288						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2289
2290						a = 1.0f;
2291						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2292						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2293						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2294					}
2295					break;
2296				case sw::FORMAT_X8B8G8R8:
2297					{
2298						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
2299
2300						a = 1.0f;
2301						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2302						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2303						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
2304					}
2305					break;
2306				case sw::FORMAT_A2R10G10B10:
2307					{
2308						unsigned int argb = *(unsigned int*)(source + 4 * i);
2309
2310						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2311						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2312						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2313						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2314					}
2315					break;
2316				default:
2317					UNIMPLEMENTED();   // FIXME
2318					UNREACHABLE(renderTarget->getInternalFormat());
2319				}
2320
2321				switch(format)
2322				{
2323				case GL_RGBA:
2324					switch(type)
2325					{
2326					case GL_UNSIGNED_BYTE:
2327						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
2328						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2329						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
2330						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2331						break;
2332					default: UNREACHABLE(type);
2333					}
2334					break;
2335				case GL_BGRA_EXT:
2336					switch(type)
2337					{
2338					case GL_UNSIGNED_BYTE:
2339						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
2340						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2341						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
2342						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2343						break;
2344					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2345						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2346						// this type is packed as follows:
2347						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2348						//  --------------------------------------------------------------------------------
2349						// |       4th         |        3rd         |        2nd        |   1st component   |
2350						//  --------------------------------------------------------------------------------
2351						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2352						dest16[i] =
2353							((unsigned short)(15 * a + 0.5f) << 12)|
2354							((unsigned short)(15 * r + 0.5f) << 8) |
2355							((unsigned short)(15 * g + 0.5f) << 4) |
2356							((unsigned short)(15 * b + 0.5f) << 0);
2357						break;
2358					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2359						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2360						// this type is packed as follows:
2361						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2362						//  --------------------------------------------------------------------------------
2363						// | 4th |          3rd           |           2nd          |      1st component     |
2364						//  --------------------------------------------------------------------------------
2365						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2366						dest16[i] =
2367							((unsigned short)(     a + 0.5f) << 15) |
2368							((unsigned short)(31 * r + 0.5f) << 10) |
2369							((unsigned short)(31 * g + 0.5f) << 5) |
2370							((unsigned short)(31 * b + 0.5f) << 0);
2371						break;
2372					default: UNREACHABLE(type);
2373					}
2374					break;
2375				case GL_RGB:
2376					switch(type)
2377					{
2378					case GL_UNSIGNED_SHORT_5_6_5:
2379						dest16[i] =
2380							((unsigned short)(31 * b + 0.5f) << 0) |
2381							((unsigned short)(63 * g + 0.5f) << 5) |
2382							((unsigned short)(31 * r + 0.5f) << 11);
2383						break;
2384					default: UNREACHABLE(type);
2385					}
2386					break;
2387				default: UNREACHABLE(format);
2388				}
2389			}
2390        }
2391
2392		source += inputPitch;
2393		dest += outputPitch;
2394    }
2395
2396	renderTarget->unlock();
2397	renderTarget->release();
2398}
2399
2400void Context::clear(GLbitfield mask)
2401{
2402    Framebuffer *framebuffer = getFramebuffer();
2403
2404    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
2405    {
2406        return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
2407    }
2408
2409    if(!applyRenderTarget())
2410    {
2411        return;
2412    }
2413
2414	unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
2415                         (unorm<8>(mState.colorClearValue.red) << 16) |
2416                         (unorm<8>(mState.colorClearValue.green) << 8) |
2417                         (unorm<8>(mState.colorClearValue.blue) << 0);
2418    float depth = clamp01(mState.depthClearValue);
2419    int stencil = mState.stencilClearValue & 0x000000FF;
2420
2421	if(mask & GL_COLOR_BUFFER_BIT)
2422	{
2423		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2424		                        (mState.colorMaskGreen ? 0x2 : 0) |
2425		                        (mState.colorMaskBlue ? 0x4 : 0) |
2426		                        (mState.colorMaskAlpha ? 0x8 : 0);
2427
2428		if(rgbaMask != 0)
2429		{
2430			device->clearColor(color, rgbaMask);
2431		}
2432	}
2433
2434	if(mask & GL_DEPTH_BUFFER_BIT)
2435	{
2436		if(mState.depthMask != 0)
2437		{
2438			device->clearDepth(depth);
2439		}
2440	}
2441
2442	if(mask & GL_STENCIL_BUFFER_BIT)
2443	{
2444		if(mState.stencilWritemask != 0)
2445		{
2446			device->clearStencil(stencil, mState.stencilWritemask);
2447		}
2448	}
2449}
2450
2451void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2452{
2453    PrimitiveType primitiveType;
2454    int primitiveCount;
2455
2456    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2457        return error(GL_INVALID_ENUM);
2458
2459    if(primitiveCount <= 0)
2460    {
2461        return;
2462    }
2463
2464    if(!applyRenderTarget())
2465    {
2466        return;
2467    }
2468
2469    applyState(mode);
2470
2471    GLenum err = applyVertexBuffer(0, first, count);
2472    if(err != GL_NO_ERROR)
2473    {
2474        return error(err);
2475    }
2476
2477    applyTextures();
2478
2479    if(!cullSkipsDraw(mode))
2480    {
2481        device->drawPrimitive(primitiveType, primitiveCount);
2482    }
2483}
2484
2485void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2486{
2487    if(!indices && !mState.elementArrayBuffer)
2488    {
2489        return error(GL_INVALID_OPERATION);
2490    }
2491
2492    PrimitiveType primitiveType;
2493    int primitiveCount;
2494
2495    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2496        return error(GL_INVALID_ENUM);
2497
2498    if(primitiveCount <= 0)
2499    {
2500        return;
2501    }
2502
2503    if(!applyRenderTarget())
2504    {
2505        return;
2506    }
2507
2508    applyState(mode);
2509
2510    TranslatedIndexData indexInfo;
2511    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2512    if(err != GL_NO_ERROR)
2513    {
2514        return error(err);
2515    }
2516
2517    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2518    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2519    if(err != GL_NO_ERROR)
2520    {
2521        return error(err);
2522    }
2523
2524    applyTextures();
2525
2526    if(!cullSkipsDraw(mode))
2527    {
2528		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2529    }
2530}
2531
2532void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
2533{
2534	es1::Framebuffer *framebuffer = getFramebuffer();
2535	es1::Renderbuffer *renderbuffer = framebuffer->getColorbuffer();
2536	float targetWidth = renderbuffer->getWidth();
2537	float targetHeight = renderbuffer->getHeight();
2538	float x0 = 2.0f * x / targetWidth - 1.0f;
2539	float y0 = 2.0f * y / targetHeight - 1.0f;
2540	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
2541	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
2542	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
2543
2544	float vertices[][3] = {{x0, y0, Zw},
2545						   {x0, y1, Zw},
2546						   {x1, y0, Zw},
2547						   {x1, y1, Zw}};
2548
2549	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented
2550	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
2551	float textureWidth = texture->getWidth(GL_TEXTURE_2D, 0);
2552	float textureHeight = texture->getHeight(GL_TEXTURE_2D, 0);
2553	int Ucr = texture->getCropRectU();
2554	int Vcr = texture->getCropRectV();
2555	int Wcr = texture->getCropRectW();
2556	int Hcr = texture->getCropRectH();
2557
2558	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
2559							{Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
2560							{(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
2561							{(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
2562
2563	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
2564	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
2565
2566	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
2567	glEnableClientState(GL_VERTEX_ARRAY);
2568	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
2569	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
2570
2571	textureStack0.push();
2572	textureStack0.identity();   // Disable texture coordinate transformation
2573
2574	drawArrays(GL_TRIANGLE_STRIP, 0, 4);
2575
2576	// Restore state
2577	mState.vertexAttribute[sw::Position] = oldPositionAttribute;
2578	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
2579	textureStack0.pop();
2580}
2581
2582void Context::finish()
2583{
2584	device->finish();
2585}
2586
2587void Context::flush()
2588{
2589    // We don't queue anything without processing it as fast as possible
2590}
2591
2592void Context::recordInvalidEnum()
2593{
2594    mInvalidEnum = true;
2595}
2596
2597void Context::recordInvalidValue()
2598{
2599    mInvalidValue = true;
2600}
2601
2602void Context::recordInvalidOperation()
2603{
2604    mInvalidOperation = true;
2605}
2606
2607void Context::recordOutOfMemory()
2608{
2609    mOutOfMemory = true;
2610}
2611
2612void Context::recordInvalidFramebufferOperation()
2613{
2614    mInvalidFramebufferOperation = true;
2615}
2616
2617// Get one of the recorded errors and clear its flag, if any.
2618// [OpenGL ES 2.0.24] section 2.5 page 13.
2619GLenum Context::getError()
2620{
2621    if(mInvalidEnum)
2622    {
2623        mInvalidEnum = false;
2624
2625        return GL_INVALID_ENUM;
2626    }
2627
2628    if(mInvalidValue)
2629    {
2630        mInvalidValue = false;
2631
2632        return GL_INVALID_VALUE;
2633    }
2634
2635    if(mInvalidOperation)
2636    {
2637        mInvalidOperation = false;
2638
2639        return GL_INVALID_OPERATION;
2640    }
2641
2642    if(mOutOfMemory)
2643    {
2644        mOutOfMemory = false;
2645
2646        return GL_OUT_OF_MEMORY;
2647    }
2648
2649    if(mInvalidFramebufferOperation)
2650    {
2651        mInvalidFramebufferOperation = false;
2652
2653        return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
2654    }
2655
2656    return GL_NO_ERROR;
2657}
2658
2659int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
2660{
2661    if(requested <= 1)
2662    {
2663        return 1;
2664    }
2665
2666	if(requested == 2)
2667	{
2668		return 2;
2669	}
2670
2671	return 4;
2672}
2673
2674void Context::detachBuffer(GLuint buffer)
2675{
2676    // [OpenGL ES 2.0.24] section 2.9 page 22:
2677    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2678    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2679
2680    if(mState.arrayBuffer.name() == buffer)
2681    {
2682        mState.arrayBuffer = NULL;
2683    }
2684
2685    if(mState.elementArrayBuffer.name() == buffer)
2686    {
2687        mState.elementArrayBuffer = NULL;
2688    }
2689
2690    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2691    {
2692        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
2693        {
2694            mState.vertexAttribute[attribute].mBoundBuffer = NULL;
2695        }
2696    }
2697}
2698
2699void Context::detachTexture(GLuint texture)
2700{
2701    // [OpenGL ES 2.0.24] section 3.8 page 84:
2702    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2703    // rebound to texture object zero
2704
2705    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2706    {
2707        for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
2708        {
2709            if(mState.samplerTexture[type][sampler].name() == texture)
2710            {
2711                mState.samplerTexture[type][sampler] = NULL;
2712            }
2713        }
2714    }
2715
2716    // [OpenGL ES 2.0.24] section 4.4 page 112:
2717    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2718    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2719    // image was attached in the currently bound framebuffer.
2720
2721    Framebuffer *framebuffer = getFramebuffer();
2722
2723    if(framebuffer)
2724    {
2725        framebuffer->detachTexture(texture);
2726    }
2727}
2728
2729void Context::detachFramebuffer(GLuint framebuffer)
2730{
2731    // [OpenGL ES 2.0.24] section 4.4 page 107:
2732    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2733    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2734
2735    if(mState.framebuffer == framebuffer)
2736    {
2737        bindFramebuffer(0);
2738    }
2739}
2740
2741void Context::detachRenderbuffer(GLuint renderbuffer)
2742{
2743    // [OpenGL ES 2.0.24] section 4.4 page 109:
2744    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2745    // had been executed with the target RENDERBUFFER and name of zero.
2746
2747    if(mState.renderbuffer.name() == renderbuffer)
2748    {
2749        bindRenderbuffer(0);
2750    }
2751
2752    // [OpenGL ES 2.0.24] section 4.4 page 111:
2753    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2754    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2755    // point to which this image was attached in the currently bound framebuffer.
2756
2757    Framebuffer *framebuffer = getFramebuffer();
2758
2759    if(framebuffer)
2760    {
2761        framebuffer->detachRenderbuffer(renderbuffer);
2762    }
2763}
2764
2765bool Context::cullSkipsDraw(GLenum drawMode)
2766{
2767    return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
2768}
2769
2770bool Context::isTriangleMode(GLenum drawMode)
2771{
2772    switch (drawMode)
2773    {
2774      case GL_TRIANGLES:
2775      case GL_TRIANGLE_FAN:
2776      case GL_TRIANGLE_STRIP:
2777        return true;
2778      case GL_POINTS:
2779      case GL_LINES:
2780      case GL_LINE_LOOP:
2781      case GL_LINE_STRIP:
2782        return false;
2783      default: UNREACHABLE(drawMode);
2784    }
2785
2786    return false;
2787}
2788
2789void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2790{
2791    ASSERT(index < MAX_VERTEX_ATTRIBS);
2792
2793    mState.vertexAttribute[index].mCurrentValue[0] = x;
2794    mState.vertexAttribute[index].mCurrentValue[1] = y;
2795    mState.vertexAttribute[index].mCurrentValue[2] = z;
2796    mState.vertexAttribute[index].mCurrentValue[3] = w;
2797
2798    mVertexDataManager->dirtyCurrentValue(index);
2799}
2800
2801void Context::bindTexImage(egl::Surface *surface)
2802{
2803	es1::Texture2D *textureObject = getTexture2D();
2804
2805    if(textureObject)
2806    {
2807		textureObject->bindTexImage(surface);
2808	}
2809}
2810
2811EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
2812{
2813    switch(target)
2814    {
2815    case EGL_GL_TEXTURE_2D_KHR:
2816        break;
2817    case EGL_GL_RENDERBUFFER_KHR:
2818        break;
2819    default:
2820        return EGL_BAD_PARAMETER;
2821    }
2822
2823    if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
2824    {
2825        return EGL_BAD_MATCH;
2826    }
2827
2828	if(target == EGL_GL_TEXTURE_2D_KHR)
2829    {
2830        Texture *texture = getTexture(name);
2831
2832        if(!texture || texture->getTarget() != GL_TEXTURE_2D)
2833        {
2834            return EGL_BAD_PARAMETER;
2835        }
2836
2837        if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
2838        {
2839            return EGL_BAD_ACCESS;
2840        }
2841
2842        if(textureLevel != 0 && !texture->isSamplerComplete())
2843        {
2844            return EGL_BAD_PARAMETER;
2845        }
2846
2847        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
2848        {
2849            return EGL_BAD_PARAMETER;
2850        }
2851    }
2852    else if(target == EGL_GL_RENDERBUFFER_KHR)
2853    {
2854        Renderbuffer *renderbuffer = getRenderbuffer(name);
2855
2856        if(!renderbuffer)
2857        {
2858            return EGL_BAD_PARAMETER;
2859        }
2860
2861        if(renderbuffer->isShared())   // Already an EGLImage sibling
2862        {
2863            return EGL_BAD_ACCESS;
2864        }
2865    }
2866    else UNREACHABLE(target);
2867
2868	return EGL_SUCCESS;
2869}
2870
2871egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
2872{
2873    if(target == EGL_GL_TEXTURE_2D_KHR)
2874    {
2875        es1::Texture *texture = getTexture(name);
2876
2877        return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
2878    }
2879    else if(target == EGL_GL_RENDERBUFFER_KHR)
2880    {
2881        es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
2882
2883        return renderbuffer->createSharedImage();
2884    }
2885    else UNREACHABLE(target);
2886
2887	return 0;
2888}
2889
2890Device *Context::getDevice()
2891{
2892	return device;
2893}
2894
2895void Context::setMatrixMode(GLenum mode)
2896{
2897    matrixMode = mode;
2898}
2899
2900sw::MatrixStack &Context::currentMatrixStack()
2901{
2902	switch(matrixMode)
2903	{
2904	case GL_MODELVIEW:
2905		return modelViewStack;
2906	case GL_PROJECTION:
2907		return projectionStack;
2908	case GL_TEXTURE:
2909		switch(mState.activeSampler)
2910		{
2911		case 0: return textureStack0;
2912		case 1: return textureStack1;
2913		}
2914		break;
2915	}
2916
2917	UNREACHABLE(matrixMode);
2918	return textureStack0;
2919}
2920
2921void Context::loadIdentity()
2922{
2923	currentMatrixStack().identity();
2924}
2925
2926void Context::load(const GLfloat *m)
2927{
2928    currentMatrixStack().load(m);
2929}
2930
2931void Context::pushMatrix()
2932{
2933	if(!currentMatrixStack().push())
2934	{
2935		return error(GL_STACK_OVERFLOW);
2936	}
2937}
2938
2939void Context::popMatrix()
2940{
2941    if(!currentMatrixStack().pop())
2942	{
2943		return error(GL_STACK_OVERFLOW);
2944	}
2945}
2946
2947void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
2948{
2949    currentMatrixStack().rotate(angle, x, y, z);
2950}
2951
2952void Context::translate(GLfloat x, GLfloat y, GLfloat z)
2953{
2954    currentMatrixStack().translate(x, y, z);
2955}
2956
2957void Context::scale(GLfloat x, GLfloat y, GLfloat z)
2958{
2959    currentMatrixStack().scale(x, y, z);
2960}
2961
2962void Context::multiply(const GLfloat *m)
2963{
2964    currentMatrixStack().multiply(m);
2965}
2966
2967void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
2968{
2969	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
2970}
2971
2972void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
2973{
2974	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
2975}
2976
2977void Context::clientActiveTexture(GLenum texture)
2978{
2979	clientTexture = texture;
2980}
2981
2982GLenum Context::getClientActiveTexture() const
2983{
2984	return clientTexture;
2985}
2986
2987unsigned int Context::getActiveTexture() const
2988{
2989	return mState.activeSampler;
2990}
2991
2992}
2993
2994egl::Context *es1CreateContext(const egl::Config *config, const egl::Context *shareContext)
2995{
2996	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
2997	return new es1::Context(config, static_cast<const es1::Context*>(shareContext));
2998}
2999