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