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