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