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