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