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