Context.cpp revision 0300e3c7a5ef70b53ad742e348b2cd4d848b42b9
1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// SwiftShader Software Renderer
2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//
3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright(c) 2005-2013 TransGaming Inc.
4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//
5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// All rights reserved. No part of this software may be copied, distributed, transmitted,
6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// transcribed, stored in a retrieval system, translated into any human or computer
7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// language by any means, or disclosed to third parties without the explicit written
80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// or implied, including but not limited to any patent rights, are granted to you.
10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat//
11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Context.cpp: Implements the es2::Context class, managing all GL state and performing
13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// rendering operations. It is the GLES2 specific implementation of EGLContext.
1445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko
15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Context.h"
16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "main.h"
18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "mathutil.h"
19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "utilities.h"
20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "ResourceManager.h"
21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Buffer.h"
22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Fence.h"
23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Framebuffer.h"
24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Program.h"
25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Query.h"
26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Renderbuffer.h"
27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Shader.h"
28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Texture.h"
29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "VertexDataManager.h"
30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "IndexDataManager.h"
31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "libEGL/Display.h"
32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "libEGL/Surface.h"
33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Common/Half.hpp"
34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <EGL/eglext.h>
36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#undef near
38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#undef far
39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace es2
41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat{
42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratContext::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)
43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat	: mConfig(config), clientVersion(clientVersion)
44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat{
45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat	sw::Context *context = new sw::Context();
46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat	device = new es2::Device(context);
47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mFenceNameSpace.setBaseHandle(0);
49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.depthClearValue = 1.0f;
53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilClearValue = 0;
54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.cullFace = false;
56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.cullMode = GL_BACK;
57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.frontFace = GL_CCW;
58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.depthTest = false;
59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.depthFunc = GL_LESS;
60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blend = false;
61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.sourceBlendRGB = GL_ONE;
6245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko    mState.sourceBlendAlpha = GL_ONE;
63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.destBlendRGB = GL_ZERO;
64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.destBlendAlpha = GL_ZERO;
65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendEquationRGB = GL_FUNC_ADD;
66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendEquationAlpha = GL_FUNC_ADD;
67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendColor.red = 0;
68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendColor.green = 0;
69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendColor.blue = 0;
70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.blendColor.alpha = 0;
71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilTest = false;
72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilFunc = GL_ALWAYS;
73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilRef = 0;
74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilMask = -1;
75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilWritemask = -1;
76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackFunc = GL_ALWAYS;
77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackRef = 0;
78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackMask = - 1;
79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackWritemask = -1;
80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilFail = GL_KEEP;
81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilPassDepthFail = GL_KEEP;
82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilPassDepthPass = GL_KEEP;
83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackFail = GL_KEEP;
84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackPassDepthFail = GL_KEEP;
85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.stencilBackPassDepthPass = GL_KEEP;
86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.polygonOffsetFill = false;
87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.polygonOffsetFactor = 0.0f;
88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.polygonOffsetUnits = 0.0f;
89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.sampleAlphaToCoverage = false;
90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.sampleCoverage = false;
91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.sampleCoverageValue = 1.0f;
92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.sampleCoverageInvert = false;
93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.scissorTest = false;
94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.dither = true;
95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.primitiveRestartFixedIndex = false;
96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.rasterizerDiscard = false;
97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.generateMipmapHint = GL_DONT_CARE;
98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
1003a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli    mState.lineWidth = 1.0f;
101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.viewportX = 0;
103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.viewportY = 0;
104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.viewportWidth = config->mDisplayMode.width;
105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.viewportHeight = config->mDisplayMode.height;
106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.zNear = 0.0f;
107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.zFar = 1.0f;
108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat
109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.scissorX = 0;
110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat    mState.scissorY = 0;
111    mState.scissorWidth = config->mDisplayMode.width;
112    mState.scissorHeight = config->mDisplayMode.height;
113
114    mState.colorMaskRed = true;
115    mState.colorMaskGreen = true;
116    mState.colorMaskBlue = true;
117    mState.colorMaskAlpha = true;
118    mState.depthMask = true;
119
120    if(shareContext != NULL)
121    {
122        mResourceManager = shareContext->mResourceManager;
123        mResourceManager->addRef();
124    }
125    else
126    {
127        mResourceManager = new ResourceManager();
128    }
129
130    // [OpenGL ES 2.0.24] section 3.7 page 83:
131    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
132    // and cube map texture state vectors respectively associated with them.
133    // In order that access to these initial textures not be lost, they are treated as texture
134    // objects all of whose names are 0.
135
136    mTexture2DZero = new Texture2D(0);
137	mTexture3DZero = new Texture3D(0);
138    mTextureCubeMapZero = new TextureCubeMap(0);
139    mTextureExternalZero = new TextureExternal(0);
140
141    mState.activeSampler = 0;
142    bindArrayBuffer(0);
143    bindElementArrayBuffer(0);
144    bindTextureCubeMap(0);
145    bindTexture2D(0);
146    bindReadFramebuffer(0);
147    bindDrawFramebuffer(0);
148    bindRenderbuffer(0);
149
150    mState.currentProgram = 0;
151
152    mState.packAlignment = 4;
153    mState.unpackAlignment = 4;
154
155    mVertexDataManager = NULL;
156    mIndexDataManager = NULL;
157
158    mInvalidEnum = false;
159    mInvalidValue = false;
160    mInvalidOperation = false;
161    mOutOfMemory = false;
162    mInvalidFramebufferOperation = false;
163
164    mHasBeenCurrent = false;
165
166    markAllStateDirty();
167}
168
169Context::~Context()
170{
171    if(mState.currentProgram != 0)
172    {
173        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
174        if(programObject)
175        {
176            programObject->release();
177        }
178        mState.currentProgram = 0;
179    }
180
181    while(!mFramebufferMap.empty())
182    {
183        deleteFramebuffer(mFramebufferMap.begin()->first);
184    }
185
186    while(!mFenceMap.empty())
187    {
188        deleteFence(mFenceMap.begin()->first);
189    }
190
191	while(!mQueryMap.empty())
192    {
193        deleteQuery(mQueryMap.begin()->first);
194    }
195
196    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
197    {
198        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
199        {
200            mState.samplerTexture[type][sampler] = NULL;
201        }
202    }
203
204    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
205    {
206        mState.vertexAttribute[i].mBoundBuffer = NULL;
207    }
208
209	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
210    {
211        mState.activeQuery[i] = NULL;
212    }
213
214    mState.arrayBuffer = NULL;
215    mState.elementArrayBuffer = NULL;
216    mState.renderbuffer = NULL;
217
218    mTexture2DZero = NULL;
219	mTexture3DZero = NULL;
220    mTextureCubeMapZero = NULL;
221    mTextureExternalZero = NULL;
222
223    delete mVertexDataManager;
224    delete mIndexDataManager;
225
226    mResourceManager->release();
227	delete device;
228}
229
230void Context::makeCurrent(egl::Surface *surface)
231{
232    if(!mHasBeenCurrent)
233    {
234        mVertexDataManager = new VertexDataManager(this);
235        mIndexDataManager = new IndexDataManager();
236
237        mState.viewportX = 0;
238        mState.viewportY = 0;
239        mState.viewportWidth = surface->getWidth();
240        mState.viewportHeight = surface->getHeight();
241
242        mState.scissorX = 0;
243        mState.scissorY = 0;
244        mState.scissorWidth = surface->getWidth();
245        mState.scissorHeight = surface->getHeight();
246
247        mHasBeenCurrent = true;
248    }
249
250    // Wrap the existing resources into GL objects and assign them to the '0' names
251    egl::Image *defaultRenderTarget = surface->getRenderTarget();
252    egl::Image *depthStencil = surface->getDepthStencil();
253
254    Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
255    DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
256    Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
257
258    setFramebufferZero(framebufferZero);
259
260    if(defaultRenderTarget)
261    {
262        defaultRenderTarget->release();
263    }
264
265    if(depthStencil)
266    {
267        depthStencil->release();
268    }
269
270    markAllStateDirty();
271}
272
273void Context::destroy()
274{
275	delete this;
276}
277
278EGLint Context::getClientVersion()
279{
280	return clientVersion;
281}
282
283// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
284void Context::markAllStateDirty()
285{
286    mAppliedProgramSerial = 0;
287
288    mDepthStateDirty = true;
289    mMaskStateDirty = true;
290    mBlendStateDirty = true;
291    mStencilStateDirty = true;
292    mPolygonOffsetStateDirty = true;
293    mSampleStateDirty = true;
294    mDitherStateDirty = true;
295    mFrontFaceDirty = true;
296}
297
298void Context::setClearColor(float red, float green, float blue, float alpha)
299{
300    mState.colorClearValue.red = red;
301    mState.colorClearValue.green = green;
302    mState.colorClearValue.blue = blue;
303    mState.colorClearValue.alpha = alpha;
304}
305
306void Context::setClearDepth(float depth)
307{
308    mState.depthClearValue = depth;
309}
310
311void Context::setClearStencil(int stencil)
312{
313    mState.stencilClearValue = stencil;
314}
315
316void Context::setCullFace(bool enabled)
317{
318    mState.cullFace = enabled;
319}
320
321bool Context::isCullFaceEnabled() const
322{
323    return mState.cullFace;
324}
325
326void Context::setCullMode(GLenum mode)
327{
328   mState.cullMode = mode;
329}
330
331void Context::setFrontFace(GLenum front)
332{
333    if(mState.frontFace != front)
334    {
335        mState.frontFace = front;
336        mFrontFaceDirty = true;
337    }
338}
339
340void Context::setDepthTest(bool enabled)
341{
342    if(mState.depthTest != enabled)
343    {
344        mState.depthTest = enabled;
345        mDepthStateDirty = true;
346    }
347}
348
349bool Context::isDepthTestEnabled() const
350{
351    return mState.depthTest;
352}
353
354void Context::setDepthFunc(GLenum depthFunc)
355{
356    if(mState.depthFunc != depthFunc)
357    {
358        mState.depthFunc = depthFunc;
359        mDepthStateDirty = true;
360    }
361}
362
363void Context::setDepthRange(float zNear, float zFar)
364{
365    mState.zNear = zNear;
366    mState.zFar = zFar;
367}
368
369void Context::setBlend(bool enabled)
370{
371    if(mState.blend != enabled)
372    {
373        mState.blend = enabled;
374        mBlendStateDirty = true;
375    }
376}
377
378bool Context::isBlendEnabled() const
379{
380    return mState.blend;
381}
382
383void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
384{
385    if(mState.sourceBlendRGB != sourceRGB ||
386       mState.sourceBlendAlpha != sourceAlpha ||
387       mState.destBlendRGB != destRGB ||
388       mState.destBlendAlpha != destAlpha)
389    {
390        mState.sourceBlendRGB = sourceRGB;
391        mState.destBlendRGB = destRGB;
392        mState.sourceBlendAlpha = sourceAlpha;
393        mState.destBlendAlpha = destAlpha;
394        mBlendStateDirty = true;
395    }
396}
397
398void Context::setBlendColor(float red, float green, float blue, float alpha)
399{
400    if(mState.blendColor.red != red ||
401       mState.blendColor.green != green ||
402       mState.blendColor.blue != blue ||
403       mState.blendColor.alpha != alpha)
404    {
405        mState.blendColor.red = red;
406        mState.blendColor.green = green;
407        mState.blendColor.blue = blue;
408        mState.blendColor.alpha = alpha;
409        mBlendStateDirty = true;
410    }
411}
412
413void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
414{
415    if(mState.blendEquationRGB != rgbEquation ||
416       mState.blendEquationAlpha != alphaEquation)
417    {
418        mState.blendEquationRGB = rgbEquation;
419        mState.blendEquationAlpha = alphaEquation;
420        mBlendStateDirty = true;
421    }
422}
423
424void Context::setStencilTest(bool enabled)
425{
426    if(mState.stencilTest != enabled)
427    {
428        mState.stencilTest = enabled;
429        mStencilStateDirty = true;
430    }
431}
432
433bool Context::isStencilTestEnabled() const
434{
435    return mState.stencilTest;
436}
437
438void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
439{
440    if(mState.stencilFunc != stencilFunc ||
441        mState.stencilRef != stencilRef ||
442        mState.stencilMask != stencilMask)
443    {
444        mState.stencilFunc = stencilFunc;
445        mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
446        mState.stencilMask = stencilMask;
447        mStencilStateDirty = true;
448    }
449}
450
451void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
452{
453    if(mState.stencilBackFunc != stencilBackFunc ||
454        mState.stencilBackRef != stencilBackRef ||
455        mState.stencilBackMask != stencilBackMask)
456    {
457        mState.stencilBackFunc = stencilBackFunc;
458        mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
459        mState.stencilBackMask = stencilBackMask;
460        mStencilStateDirty = true;
461    }
462}
463
464void Context::setStencilWritemask(GLuint stencilWritemask)
465{
466    if(mState.stencilWritemask != stencilWritemask)
467    {
468        mState.stencilWritemask = stencilWritemask;
469        mStencilStateDirty = true;
470    }
471}
472
473void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
474{
475    if(mState.stencilBackWritemask != stencilBackWritemask)
476    {
477        mState.stencilBackWritemask = stencilBackWritemask;
478        mStencilStateDirty = true;
479    }
480}
481
482void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
483{
484    if(mState.stencilFail != stencilFail ||
485        mState.stencilPassDepthFail != stencilPassDepthFail ||
486        mState.stencilPassDepthPass != stencilPassDepthPass)
487    {
488        mState.stencilFail = stencilFail;
489        mState.stencilPassDepthFail = stencilPassDepthFail;
490        mState.stencilPassDepthPass = stencilPassDepthPass;
491        mStencilStateDirty = true;
492    }
493}
494
495void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
496{
497    if(mState.stencilBackFail != stencilBackFail ||
498        mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
499        mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
500    {
501        mState.stencilBackFail = stencilBackFail;
502        mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
503        mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
504        mStencilStateDirty = true;
505    }
506}
507
508void Context::setPolygonOffsetFill(bool enabled)
509{
510    if(mState.polygonOffsetFill != enabled)
511    {
512        mState.polygonOffsetFill = enabled;
513        mPolygonOffsetStateDirty = true;
514    }
515}
516
517bool Context::isPolygonOffsetFillEnabled() const
518{
519    return mState.polygonOffsetFill;
520}
521
522void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
523{
524    if(mState.polygonOffsetFactor != factor ||
525        mState.polygonOffsetUnits != units)
526    {
527        mState.polygonOffsetFactor = factor;
528        mState.polygonOffsetUnits = units;
529        mPolygonOffsetStateDirty = true;
530    }
531}
532
533void Context::setSampleAlphaToCoverage(bool enabled)
534{
535    if(mState.sampleAlphaToCoverage != enabled)
536    {
537        mState.sampleAlphaToCoverage = enabled;
538        mSampleStateDirty = true;
539    }
540}
541
542bool Context::isSampleAlphaToCoverageEnabled() const
543{
544    return mState.sampleAlphaToCoverage;
545}
546
547void Context::setSampleCoverage(bool enabled)
548{
549    if(mState.sampleCoverage != enabled)
550    {
551        mState.sampleCoverage = enabled;
552        mSampleStateDirty = true;
553    }
554}
555
556bool Context::isSampleCoverageEnabled() const
557{
558    return mState.sampleCoverage;
559}
560
561void Context::setSampleCoverageParams(GLclampf value, bool invert)
562{
563    if(mState.sampleCoverageValue != value ||
564        mState.sampleCoverageInvert != invert)
565    {
566        mState.sampleCoverageValue = value;
567        mState.sampleCoverageInvert = invert;
568        mSampleStateDirty = true;
569    }
570}
571
572void Context::setScissorTest(bool enabled)
573{
574    mState.scissorTest = enabled;
575}
576
577bool Context::isScissorTestEnabled() const
578{
579    return mState.scissorTest;
580}
581
582void Context::setDither(bool enabled)
583{
584    if(mState.dither != enabled)
585    {
586        mState.dither = enabled;
587        mDitherStateDirty = true;
588    }
589}
590
591bool Context::isDitherEnabled() const
592{
593    return mState.dither;
594}
595
596void Context::setPrimitiveRestartFixedIndex(bool enabled)
597{
598    UNIMPLEMENTED();
599    mState.primitiveRestartFixedIndex = enabled;
600}
601
602bool Context::isPrimitiveRestartFixedIndexEnabled() const
603{
604    return mState.primitiveRestartFixedIndex;
605}
606
607void Context::setRasterizerDiscard(bool enabled)
608{
609    UNIMPLEMENTED();
610    mState.rasterizerDiscard = enabled;
611}
612
613bool Context::isRasterizerDiscardEnabled() const
614{
615    return mState.rasterizerDiscard;
616}
617
618void Context::setLineWidth(GLfloat width)
619{
620    mState.lineWidth = width;
621	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
622}
623
624void Context::setGenerateMipmapHint(GLenum hint)
625{
626    mState.generateMipmapHint = hint;
627}
628
629void Context::setFragmentShaderDerivativeHint(GLenum hint)
630{
631    mState.fragmentShaderDerivativeHint = hint;
632    // TODO: Propagate the hint to shader translator so we can write
633    // ddx, ddx_coarse, or ddx_fine depending on the hint.
634    // Ignore for now. It is valid for implementations to ignore hint.
635}
636
637void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
638{
639    mState.viewportX = x;
640    mState.viewportY = y;
641    mState.viewportWidth = width;
642    mState.viewportHeight = height;
643}
644
645void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
646{
647    mState.scissorX = x;
648    mState.scissorY = y;
649    mState.scissorWidth = width;
650    mState.scissorHeight = height;
651}
652
653void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
654{
655    if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
656       mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
657    {
658        mState.colorMaskRed = red;
659        mState.colorMaskGreen = green;
660        mState.colorMaskBlue = blue;
661        mState.colorMaskAlpha = alpha;
662        mMaskStateDirty = true;
663    }
664}
665
666void Context::setDepthMask(bool mask)
667{
668    if(mState.depthMask != mask)
669    {
670        mState.depthMask = mask;
671        mMaskStateDirty = true;
672    }
673}
674
675void Context::setActiveSampler(unsigned int active)
676{
677    mState.activeSampler = active;
678}
679
680GLuint Context::getReadFramebufferName() const
681{
682    return mState.readFramebuffer;
683}
684
685GLuint Context::getDrawFramebufferName() const
686{
687    return mState.drawFramebuffer;
688}
689
690GLuint Context::getRenderbufferName() const
691{
692    return mState.renderbuffer.name();
693}
694
695GLuint Context::getArrayBufferName() const
696{
697    return mState.arrayBuffer.name();
698}
699
700GLuint Context::getActiveQuery(GLenum target) const
701{
702    Query *queryObject = NULL;
703
704    switch(target)
705    {
706    case GL_ANY_SAMPLES_PASSED_EXT:
707        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
708        break;
709    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
710        queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
711        break;
712    default:
713        ASSERT(false);
714    }
715
716    if(queryObject)
717    {
718        return queryObject->name;
719    }
720
721	return 0;
722}
723
724void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled)
725{
726    mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
727}
728
729const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
730{
731    return mState.vertexAttribute[attribNum];
732}
733
734void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
735                                   GLsizei stride, const void *pointer)
736{
737    mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
738    mState.vertexAttribute[attribNum].mSize = size;
739    mState.vertexAttribute[attribNum].mType = type;
740    mState.vertexAttribute[attribNum].mNormalized = normalized;
741    mState.vertexAttribute[attribNum].mStride = stride;
742    mState.vertexAttribute[attribNum].mPointer = pointer;
743}
744
745const void *Context::getVertexAttribPointer(unsigned int attribNum) const
746{
747    return mState.vertexAttribute[attribNum].mPointer;
748}
749
750const VertexAttributeArray &Context::getVertexAttributes()
751{
752    return mState.vertexAttribute;
753}
754
755void Context::setPackAlignment(GLint alignment)
756{
757    mState.packAlignment = alignment;
758}
759
760GLint Context::getPackAlignment() const
761{
762    return mState.packAlignment;
763}
764
765void Context::setUnpackAlignment(GLint alignment)
766{
767    mState.unpackAlignment = alignment;
768}
769
770GLint Context::getUnpackAlignment() const
771{
772    return mState.unpackAlignment;
773}
774
775GLuint Context::createBuffer()
776{
777    return mResourceManager->createBuffer();
778}
779
780GLuint Context::createProgram()
781{
782    return mResourceManager->createProgram();
783}
784
785GLuint Context::createShader(GLenum type)
786{
787    return mResourceManager->createShader(type);
788}
789
790GLuint Context::createTexture()
791{
792    return mResourceManager->createTexture();
793}
794
795GLuint Context::createRenderbuffer()
796{
797    return mResourceManager->createRenderbuffer();
798}
799
800// Returns an unused framebuffer name
801GLuint Context::createFramebuffer()
802{
803    GLuint handle = mFramebufferNameSpace.allocate();
804
805    mFramebufferMap[handle] = NULL;
806
807    return handle;
808}
809
810GLuint Context::createFence()
811{
812    GLuint handle = mFenceNameSpace.allocate();
813
814    mFenceMap[handle] = new Fence;
815
816    return handle;
817}
818
819// Returns an unused query name
820GLuint Context::createQuery()
821{
822    GLuint handle = mQueryNameSpace.allocate();
823
824    mQueryMap[handle] = NULL;
825
826    return handle;
827}
828
829void Context::deleteBuffer(GLuint buffer)
830{
831    if(mResourceManager->getBuffer(buffer))
832    {
833        detachBuffer(buffer);
834    }
835
836    mResourceManager->deleteBuffer(buffer);
837}
838
839void Context::deleteShader(GLuint shader)
840{
841    mResourceManager->deleteShader(shader);
842}
843
844void Context::deleteProgram(GLuint program)
845{
846    mResourceManager->deleteProgram(program);
847}
848
849void Context::deleteTexture(GLuint texture)
850{
851    if(mResourceManager->getTexture(texture))
852    {
853        detachTexture(texture);
854    }
855
856    mResourceManager->deleteTexture(texture);
857}
858
859void Context::deleteRenderbuffer(GLuint renderbuffer)
860{
861    if(mResourceManager->getRenderbuffer(renderbuffer))
862    {
863        detachRenderbuffer(renderbuffer);
864    }
865
866    mResourceManager->deleteRenderbuffer(renderbuffer);
867}
868
869void Context::deleteFramebuffer(GLuint framebuffer)
870{
871    FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer);
872
873    if(framebufferObject != mFramebufferMap.end())
874    {
875        detachFramebuffer(framebuffer);
876
877        mFramebufferNameSpace.release(framebufferObject->first);
878        delete framebufferObject->second;
879        mFramebufferMap.erase(framebufferObject);
880    }
881}
882
883void Context::deleteFence(GLuint fence)
884{
885    FenceMap::iterator fenceObject = mFenceMap.find(fence);
886
887    if(fenceObject != mFenceMap.end())
888    {
889        mFenceNameSpace.release(fenceObject->first);
890        delete fenceObject->second;
891        mFenceMap.erase(fenceObject);
892    }
893}
894
895void Context::deleteQuery(GLuint query)
896{
897    QueryMap::iterator queryObject = mQueryMap.find(query);
898
899	if(queryObject != mQueryMap.end())
900    {
901        mQueryNameSpace.release(queryObject->first);
902
903		if(queryObject->second)
904        {
905            queryObject->second->release();
906        }
907
908		mQueryMap.erase(queryObject);
909    }
910}
911
912Buffer *Context::getBuffer(GLuint handle)
913{
914    return mResourceManager->getBuffer(handle);
915}
916
917Shader *Context::getShader(GLuint handle)
918{
919    return mResourceManager->getShader(handle);
920}
921
922Program *Context::getProgram(GLuint handle)
923{
924    return mResourceManager->getProgram(handle);
925}
926
927Texture *Context::getTexture(GLuint handle)
928{
929    return mResourceManager->getTexture(handle);
930}
931
932Renderbuffer *Context::getRenderbuffer(GLuint handle)
933{
934    return mResourceManager->getRenderbuffer(handle);
935}
936
937Framebuffer *Context::getReadFramebuffer()
938{
939    return getFramebuffer(mState.readFramebuffer);
940}
941
942Framebuffer *Context::getDrawFramebuffer()
943{
944    return getFramebuffer(mState.drawFramebuffer);
945}
946
947void Context::bindArrayBuffer(unsigned int buffer)
948{
949    mResourceManager->checkBufferAllocation(buffer);
950
951    mState.arrayBuffer = getBuffer(buffer);
952}
953
954void Context::bindElementArrayBuffer(unsigned int buffer)
955{
956    mResourceManager->checkBufferAllocation(buffer);
957
958    mState.elementArrayBuffer = getBuffer(buffer);
959}
960
961void Context::bindTexture2D(GLuint texture)
962{
963    mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
964
965    mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
966}
967
968void Context::bindTextureCubeMap(GLuint texture)
969{
970    mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
971
972    mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
973}
974
975void Context::bindTextureExternal(GLuint texture)
976{
977    mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
978
979    mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
980}
981
982void Context::bindTexture3D(GLuint texture)
983{
984	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
985
986	mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture);
987}
988
989void Context::bindReadFramebuffer(GLuint framebuffer)
990{
991    if(!getFramebuffer(framebuffer))
992    {
993        mFramebufferMap[framebuffer] = new Framebuffer();
994    }
995
996    mState.readFramebuffer = framebuffer;
997}
998
999void Context::bindDrawFramebuffer(GLuint framebuffer)
1000{
1001    if(!getFramebuffer(framebuffer))
1002    {
1003        mFramebufferMap[framebuffer] = new Framebuffer();
1004    }
1005
1006    mState.drawFramebuffer = framebuffer;
1007}
1008
1009void Context::bindRenderbuffer(GLuint renderbuffer)
1010{
1011    mState.renderbuffer = getRenderbuffer(renderbuffer);
1012}
1013
1014void Context::useProgram(GLuint program)
1015{
1016    GLuint priorProgram = mState.currentProgram;
1017    mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
1018
1019    if(priorProgram != program)
1020    {
1021        Program *newProgram = mResourceManager->getProgram(program);
1022        Program *oldProgram = mResourceManager->getProgram(priorProgram);
1023
1024        if(newProgram)
1025        {
1026            newProgram->addRef();
1027        }
1028
1029        if(oldProgram)
1030        {
1031            oldProgram->release();
1032        }
1033    }
1034}
1035
1036void Context::beginQuery(GLenum target, GLuint query)
1037{
1038    // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
1039    // of zero, if the active query object name for <target> is non-zero (for the
1040    // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
1041    // the active query for either target is non-zero), if <id> is the name of an
1042    // existing query object whose type does not match <target>, or if <id> is the
1043    // active query object name for any query type, the error INVALID_OPERATION is
1044    // generated.
1045
1046    // Ensure no other queries are active
1047    // NOTE: If other queries than occlusion are supported, we will need to check
1048    // separately that:
1049    //    a) The query ID passed is not the current active query for any target/type
1050    //    b) There are no active queries for the requested target (and in the case
1051    //       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
1052    //       no query may be active for either if glBeginQuery targets either.
1053    for(int i = 0; i < QUERY_TYPE_COUNT; i++)
1054    {
1055        if(mState.activeQuery[i] != NULL)
1056        {
1057            return error(GL_INVALID_OPERATION);
1058        }
1059    }
1060
1061    QueryType qType;
1062    switch(target)
1063    {
1064    case GL_ANY_SAMPLES_PASSED_EXT:
1065        qType = QUERY_ANY_SAMPLES_PASSED;
1066        break;
1067    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1068        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1069        break;
1070    default:
1071        ASSERT(false);
1072    }
1073
1074    Query *queryObject = getQuery(query, true, target);
1075
1076    // Check that name was obtained with glGenQueries
1077    if(!queryObject)
1078    {
1079        return error(GL_INVALID_OPERATION);
1080    }
1081
1082    // Check for type mismatch
1083    if(queryObject->getType() != target)
1084    {
1085        return error(GL_INVALID_OPERATION);
1086    }
1087
1088    // Set query as active for specified target
1089    mState.activeQuery[qType] = queryObject;
1090
1091    // Begin query
1092    queryObject->begin();
1093}
1094
1095void Context::endQuery(GLenum target)
1096{
1097    QueryType qType;
1098
1099    switch(target)
1100    {
1101    case GL_ANY_SAMPLES_PASSED_EXT:
1102        qType = QUERY_ANY_SAMPLES_PASSED;
1103        break;
1104    case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
1105        qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
1106        break;
1107    default:
1108        ASSERT(false);
1109    }
1110
1111    Query *queryObject = mState.activeQuery[qType];
1112
1113    if(queryObject == NULL)
1114    {
1115        return error(GL_INVALID_OPERATION);
1116    }
1117
1118    queryObject->end();
1119
1120    mState.activeQuery[qType] = NULL;
1121}
1122
1123void Context::setFramebufferZero(Framebuffer *buffer)
1124{
1125    delete mFramebufferMap[0];
1126    mFramebufferMap[0] = buffer;
1127}
1128
1129void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
1130{
1131    Renderbuffer *renderbufferObject = mState.renderbuffer;
1132    renderbufferObject->setStorage(renderbuffer);
1133}
1134
1135Framebuffer *Context::getFramebuffer(unsigned int handle)
1136{
1137    FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
1138
1139    if(framebuffer == mFramebufferMap.end())
1140    {
1141        return NULL;
1142    }
1143    else
1144    {
1145        return framebuffer->second;
1146    }
1147}
1148
1149Fence *Context::getFence(unsigned int handle)
1150{
1151    FenceMap::iterator fence = mFenceMap.find(handle);
1152
1153    if(fence == mFenceMap.end())
1154    {
1155        return NULL;
1156    }
1157    else
1158    {
1159        return fence->second;
1160    }
1161}
1162
1163Query *Context::getQuery(unsigned int handle, bool create, GLenum type)
1164{
1165    QueryMap::iterator query = mQueryMap.find(handle);
1166
1167    if(query == mQueryMap.end())
1168    {
1169        return NULL;
1170    }
1171    else
1172    {
1173        if(!query->second && create)
1174        {
1175            query->second = new Query(handle, type);
1176            query->second->addRef();
1177        }
1178
1179        return query->second;
1180    }
1181}
1182
1183Buffer *Context::getArrayBuffer()
1184{
1185    return mState.arrayBuffer;
1186}
1187
1188Buffer *Context::getElementArrayBuffer()
1189{
1190    return mState.elementArrayBuffer;
1191}
1192
1193Program *Context::getCurrentProgram()
1194{
1195    return mResourceManager->getProgram(mState.currentProgram);
1196}
1197
1198Texture2D *Context::getTexture2D()
1199{
1200	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
1201}
1202
1203Texture3D *Context::getTexture3D()
1204{
1205	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
1206}
1207
1208TextureCubeMap *Context::getTextureCubeMap()
1209{
1210    return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
1211}
1212
1213TextureExternal *Context::getTextureExternal()
1214{
1215    return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
1216}
1217
1218Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
1219{
1220    GLuint texid = mState.samplerTexture[type][sampler].name();
1221
1222    if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
1223    {
1224        switch (type)
1225        {
1226        case TEXTURE_2D: return mTexture2DZero;
1227		case TEXTURE_3D: return mTexture3DZero;
1228        case TEXTURE_CUBE: return mTextureCubeMapZero;
1229        case TEXTURE_EXTERNAL: return mTextureExternalZero;
1230        default: UNREACHABLE();
1231        }
1232    }
1233
1234    return mState.samplerTexture[type][sampler];
1235}
1236
1237bool Context::getBooleanv(GLenum pname, GLboolean *params)
1238{
1239    switch (pname)
1240    {
1241      case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
1242      case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
1243      case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
1244      case GL_COLOR_WRITEMASK:
1245        params[0] = mState.colorMaskRed;
1246        params[1] = mState.colorMaskGreen;
1247        params[2] = mState.colorMaskBlue;
1248        params[3] = mState.colorMaskAlpha;
1249        break;
1250      case GL_CULL_FACE:                *params = mState.cullFace;                  break;
1251      case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFill;         break;
1252      case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage;     break;
1253      case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverage;            break;
1254      case GL_SCISSOR_TEST:             *params = mState.scissorTest;               break;
1255      case GL_STENCIL_TEST:             *params = mState.stencilTest;               break;
1256      case GL_DEPTH_TEST:               *params = mState.depthTest;                 break;
1257      case GL_BLEND:                    *params = mState.blend;                     break;
1258      case GL_DITHER:                   *params = mState.dither;                    break;
1259      case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndex; break;
1260      case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscard;         break;
1261      default:
1262        return false;
1263    }
1264
1265    return true;
1266}
1267
1268bool Context::getFloatv(GLenum pname, GLfloat *params)
1269{
1270    // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
1271    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1272    // GetIntegerv as its native query function. As it would require conversion in any
1273    // case, this should make no difference to the calling application.
1274    switch (pname)
1275    {
1276      case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
1277      case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
1278      case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
1279      case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
1280      case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
1281      case GL_ALIASED_LINE_WIDTH_RANGE:
1282        params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
1283        params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
1284        break;
1285      case GL_ALIASED_POINT_SIZE_RANGE:
1286        params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
1287        params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
1288        break;
1289      case GL_DEPTH_RANGE:
1290        params[0] = mState.zNear;
1291        params[1] = mState.zFar;
1292        break;
1293      case GL_COLOR_CLEAR_VALUE:
1294        params[0] = mState.colorClearValue.red;
1295        params[1] = mState.colorClearValue.green;
1296        params[2] = mState.colorClearValue.blue;
1297        params[3] = mState.colorClearValue.alpha;
1298        break;
1299      case GL_BLEND_COLOR:
1300        params[0] = mState.blendColor.red;
1301        params[1] = mState.blendColor.green;
1302        params[2] = mState.blendColor.blue;
1303        params[3] = mState.blendColor.alpha;
1304        break;
1305	  case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1306        *params = MAX_TEXTURE_MAX_ANISOTROPY;
1307		break;
1308      default:
1309        return false;
1310    }
1311
1312    return true;
1313}
1314
1315bool Context::getIntegerv(GLenum pname, GLint *params)
1316{
1317    // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
1318    // because it is stored as a float, despite the fact that the GL ES 2.0 spec names
1319    // GetIntegerv as its native query function. As it would require conversion in any
1320    // case, this should make no difference to the calling application. You may find it in
1321    // Context::getFloatv.
1322    switch (pname)
1323    {
1324    case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
1325    case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
1326    case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
1327    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
1328    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
1329    case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
1330	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
1331	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
1332    case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
1333    case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
1334    case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
1335    case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
1336//	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
1337    case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
1338    case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
1339    case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
1340    case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
1341    case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
1342    case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
1343    case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
1344    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
1345    case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
1346    case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
1347    case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
1348    case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
1349    case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
1350    case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
1351    case GL_STENCIL_BACK_VALUE_MASK:          *params = mState.stencilBackMask;               break;
1352    case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
1353    case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
1354    case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
1355    case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
1356    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
1357    case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
1358    case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
1359    case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
1360    case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
1361    case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
1362    case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
1363    case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
1364    case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
1365    case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
1366    case GL_STENCIL_BACK_WRITEMASK:           *params = mState.stencilBackWritemask;          break;
1367    case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
1368    case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
1369	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          break;
1370	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
1371    case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;
1372	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;
1373    case GL_SAMPLE_BUFFERS:
1374    case GL_SAMPLES:
1375        {
1376            Framebuffer *framebuffer = getDrawFramebuffer();
1377			int width, height, samples;
1378
1379            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1380            {
1381                switch(pname)
1382                {
1383                case GL_SAMPLE_BUFFERS:
1384                    if(samples > 1)
1385                    {
1386                        *params = 1;
1387                    }
1388                    else
1389                    {
1390                        *params = 0;
1391                    }
1392                    break;
1393                case GL_SAMPLES:
1394                    *params = samples & ~1;
1395                    break;
1396                }
1397            }
1398            else
1399            {
1400                *params = 0;
1401            }
1402        }
1403        break;
1404    case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1405		{
1406			Framebuffer *framebuffer = getReadFramebuffer();
1407			*params = framebuffer->getImplementationColorReadType();
1408		}
1409		break;
1410    case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1411		{
1412			Framebuffer *framebuffer = getReadFramebuffer();
1413			*params = framebuffer->getImplementationColorReadFormat();
1414		}
1415		break;
1416    case GL_MAX_VIEWPORT_DIMS:
1417        {
1418			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1419            params[0] = maxDimension;
1420            params[1] = maxDimension;
1421        }
1422        break;
1423    case GL_COMPRESSED_TEXTURE_FORMATS:
1424        {
1425			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1426            {
1427                params[i] = compressedTextureFormats[i];
1428            }
1429        }
1430        break;
1431    case GL_VIEWPORT:
1432        params[0] = mState.viewportX;
1433        params[1] = mState.viewportY;
1434        params[2] = mState.viewportWidth;
1435        params[3] = mState.viewportHeight;
1436        break;
1437    case GL_SCISSOR_BOX:
1438        params[0] = mState.scissorX;
1439        params[1] = mState.scissorY;
1440        params[2] = mState.scissorWidth;
1441        params[3] = mState.scissorHeight;
1442        break;
1443    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1444    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1445    case GL_RED_BITS:
1446    case GL_GREEN_BITS:
1447    case GL_BLUE_BITS:
1448    case GL_ALPHA_BITS:
1449        {
1450            Framebuffer *framebuffer = getDrawFramebuffer();
1451            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1452
1453            if(colorbuffer)
1454            {
1455                switch (pname)
1456                {
1457                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1458                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1459                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1460                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1461                }
1462            }
1463            else
1464            {
1465                *params = 0;
1466            }
1467        }
1468        break;
1469    case GL_DEPTH_BITS:
1470        {
1471            Framebuffer *framebuffer = getDrawFramebuffer();
1472            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1473
1474            if(depthbuffer)
1475            {
1476                *params = depthbuffer->getDepthSize();
1477            }
1478            else
1479            {
1480                *params = 0;
1481            }
1482        }
1483        break;
1484    case GL_STENCIL_BITS:
1485        {
1486            Framebuffer *framebuffer = getDrawFramebuffer();
1487            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1488
1489            if(stencilbuffer)
1490            {
1491                *params = stencilbuffer->getStencilSize();
1492            }
1493            else
1494            {
1495                *params = 0;
1496            }
1497        }
1498        break;
1499    case GL_TEXTURE_BINDING_2D:
1500        {
1501            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1502            {
1503                error(GL_INVALID_OPERATION);
1504                return false;
1505            }
1506
1507            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
1508        }
1509        break;
1510    case GL_TEXTURE_BINDING_CUBE_MAP:
1511        {
1512            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1513            {
1514                error(GL_INVALID_OPERATION);
1515                return false;
1516            }
1517
1518            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
1519        }
1520        break;
1521    case GL_TEXTURE_BINDING_EXTERNAL_OES:
1522        {
1523            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1524            {
1525                error(GL_INVALID_OPERATION);
1526                return false;
1527            }
1528
1529            *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
1530        }
1531        break;
1532	case GL_TEXTURE_BINDING_3D_OES:
1533	case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0
1534	    {
1535			if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1536			{
1537				error(GL_INVALID_OPERATION);
1538				return false;
1539			}
1540
1541			*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
1542		}
1543		break;
1544	case GL_COPY_READ_BUFFER_BINDING: // name, initially 0
1545		UNIMPLEMENTED();
1546		*params = 0;
1547		break;
1548	case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0
1549		UNIMPLEMENTED();
1550		*params = 0;
1551		break;
1552	case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK​
1553		UNIMPLEMENTED();
1554		*params = GL_BACK;
1555		break;
1556	case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE
1557	case GL_DRAW_BUFFER2:
1558	case GL_DRAW_BUFFER3:
1559	case GL_DRAW_BUFFER4:
1560	case GL_DRAW_BUFFER5:
1561	case GL_DRAW_BUFFER6:
1562	case GL_DRAW_BUFFER7:
1563	case GL_DRAW_BUFFER8:
1564	case GL_DRAW_BUFFER9:
1565	case GL_DRAW_BUFFER10:
1566	case GL_DRAW_BUFFER11:
1567	case GL_DRAW_BUFFER12:
1568	case GL_DRAW_BUFFER13:
1569	case GL_DRAW_BUFFER14:
1570	case GL_DRAW_BUFFER15:
1571		UNIMPLEMENTED();
1572		*params = GL_NONE;
1573		break;
1574	case GL_MAJOR_VERSION: // integer, at least 3
1575		UNIMPLEMENTED();
1576		*params = 3;
1577		break;
1578	case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048
1579		UNIMPLEMENTED();
1580		*params = 2048;
1581		break;
1582	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048
1583		UNIMPLEMENTED();
1584		*params = 2048;
1585		break;
1586	case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8
1587		UNIMPLEMENTED();
1588		*params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS;
1589		break;
1590	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1
1591		UNIMPLEMENTED();
1592		*params = 1;
1593		break;
1594	case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70
1595		UNIMPLEMENTED();
1596		*params = 70;
1597		break;
1598	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1
1599		UNIMPLEMENTED();
1600		*params = 1;
1601		break;
1602	case GL_MAX_DRAW_BUFFERS: // integer, at least 8
1603		UNIMPLEMENTED();
1604		*params = 8;
1605		break;
1606	case GL_MAX_ELEMENT_INDEX: // integer, at least 16777215
1607		UNIMPLEMENTED();
1608		*params = 16777215;
1609		break;
1610	case GL_MAX_ELEMENTS_INDICES: // integer
1611		UNIMPLEMENTED();
1612		*params = 0;
1613		break;
1614	case GL_MAX_ELEMENTS_VERTICES: // integer
1615		UNIMPLEMENTED();
1616		*params = 0;
1617		break;
1618	case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128
1619		UNIMPLEMENTED();
1620		*params = 128;
1621		break;
1622	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12
1623		UNIMPLEMENTED();
1624		*params = 12;
1625		break;
1626	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1024
1627		UNIMPLEMENTED();
1628		*params = 1024;
1629		break;
1630	case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7
1631		UNIMPLEMENTED();
1632		*params = 7;
1633		break;
1634	case GL_MAX_SERVER_WAIT_TIMEOUT: // integer
1635		UNIMPLEMENTED();
1636		*params = 0;
1637		break;
1638	case GL_MAX_TEXTURE_LOD_BIAS: // integer,  at least 2.0
1639		UNIMPLEMENTED();
1640		*params = 2;
1641		break;
1642	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64
1643		UNIMPLEMENTED();
1644		*params = 64;
1645		break;
1646	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4
1647		UNIMPLEMENTED();
1648		*params = 4;
1649		break;
1650	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4
1651		UNIMPLEMENTED();
1652		*params = 4;
1653		break;
1654	case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384
1655		UNIMPLEMENTED();
1656		*params = 16384;
1657		break;
1658	case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36
1659		UNIMPLEMENTED();
1660		*params = 36;
1661		break;
1662	case GL_MAX_VARYING_COMPONENTS: // integer, at least 60
1663		UNIMPLEMENTED();
1664		*params = 60;
1665		break;
1666	case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer,  at least 64
1667		UNIMPLEMENTED();
1668		*params = 64;
1669		break;
1670	case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer,  at least 12
1671		UNIMPLEMENTED();
1672		*params = 12;
1673		break;
1674	case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer,  at least 1024
1675		UNIMPLEMENTED();
1676		*params = 1024;
1677		break;
1678	case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8
1679		UNIMPLEMENTED();
1680		*params = -8;
1681		break;
1682	case GL_MINOR_VERSION: // integer
1683		UNIMPLEMENTED();
1684		*params = 0;
1685		break;
1686	case GL_NUM_EXTENSIONS: // integer
1687		UNIMPLEMENTED();
1688		*params = 0;
1689		break;
1690	case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0
1691		UNIMPLEMENTED();
1692		*params = 0;
1693		break;
1694	case GL_PACK_ROW_LENGTH: // integer, initially 0
1695		UNIMPLEMENTED();
1696		*params = 0;
1697		break;
1698	case GL_PACK_SKIP_PIXELS: // integer, initially 0
1699		UNIMPLEMENTED();
1700		*params = 0;
1701		break;
1702	case GL_PACK_SKIP_ROWS: // integer, initially 0
1703		UNIMPLEMENTED();
1704		*params = 0;
1705		break;
1706	case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0
1707		UNIMPLEMENTED();
1708		*params = 0;
1709		break;
1710	case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0
1711		UNIMPLEMENTED();
1712		*params = 0;
1713		break;
1714	case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS​]
1715		UNIMPLEMENTED();
1716		*params = 0;
1717		break;
1718	case GL_READ_BUFFER: // symbolic constant,  initial value is GL_BACK​
1719		UNIMPLEMENTED();
1720		*params = GL_BACK;
1721		break;
1722	case GL_SAMPLER_BINDING: // GLint, default 0
1723		UNIMPLEMENTED();
1724		*params = 0;
1725		break;
1726	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
1727		UNIMPLEMENTED();
1728		*params = 0;
1729		break;
1730	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1
1731		UNIMPLEMENTED();
1732		*params = 1;
1733		break;
1734	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
1735		UNIMPLEMENTED();
1736		*params = 0;
1737		break;
1738	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
1739		UNIMPLEMENTED();
1740		*params = 0;
1741		break;
1742	case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0
1743		UNIMPLEMENTED();
1744		*params = 0;
1745		break;
1746	case GL_UNPACK_ROW_LENGTH: // integer, initially 0
1747		UNIMPLEMENTED();
1748		*params = 0;
1749		break;
1750	case GL_UNPACK_SKIP_IMAGES: // integer, initially 0
1751		UNIMPLEMENTED();
1752		*params = 0;
1753		break;
1754	case GL_UNPACK_SKIP_PIXELS: // integer, initially 0
1755		UNIMPLEMENTED();
1756		*params = 0;
1757		break;
1758	case GL_UNPACK_SKIP_ROWS: // integer, initially 0
1759		UNIMPLEMENTED();
1760		*params = 0;
1761		break;
1762	case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0
1763		UNIMPLEMENTED();
1764		*params = 0;
1765		break;
1766	default:
1767        return false;
1768    }
1769
1770    return true;
1771}
1772
1773bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param)
1774{
1775	UNIMPLEMENTED();
1776
1777	switch(pname)
1778	{
1779	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
1780		*param = 0;
1781		break;
1782	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
1783		*param = GL_FALSE;
1784		break;
1785	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
1786		*param = 0;
1787		break;
1788	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
1789		*param = GL_FALSE;
1790		break;
1791	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
1792		*param = 0;
1793		break;
1794	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
1795		*param = 0;
1796		break;
1797	default:
1798		return false;
1799	}
1800
1801	return true;
1802}
1803
1804bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1805{
1806    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1807    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1808    // to the fact that it is stored internally as a float, and so would require conversion
1809    // if returned from Context::getIntegerv. Since this conversion is already implemented
1810    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1811    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1812    // application.
1813    switch (pname)
1814    {
1815      case GL_COMPRESSED_TEXTURE_FORMATS:
1816		{
1817            *type = GL_INT;
1818			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
1819        }
1820		break;
1821      case GL_SHADER_BINARY_FORMATS:
1822        {
1823            *type = GL_INT;
1824            *numParams = 0;
1825        }
1826        break;
1827      case GL_MAX_VERTEX_ATTRIBS:
1828      case GL_MAX_VERTEX_UNIFORM_VECTORS:
1829      case GL_MAX_VARYING_VECTORS:
1830      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1831      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1832      case GL_MAX_TEXTURE_IMAGE_UNITS:
1833      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1834      case GL_MAX_RENDERBUFFER_SIZE:
1835      case GL_NUM_SHADER_BINARY_FORMATS:
1836      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1837      case GL_ARRAY_BUFFER_BINDING:
1838      case GL_FRAMEBUFFER_BINDING:
1839      case GL_RENDERBUFFER_BINDING:
1840      case GL_CURRENT_PROGRAM:
1841      case GL_PACK_ALIGNMENT:
1842      case GL_UNPACK_ALIGNMENT:
1843      case GL_GENERATE_MIPMAP_HINT:
1844      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1845      case GL_RED_BITS:
1846      case GL_GREEN_BITS:
1847      case GL_BLUE_BITS:
1848      case GL_ALPHA_BITS:
1849      case GL_DEPTH_BITS:
1850      case GL_STENCIL_BITS:
1851      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1852      case GL_CULL_FACE_MODE:
1853      case GL_FRONT_FACE:
1854      case GL_ACTIVE_TEXTURE:
1855      case GL_STENCIL_FUNC:
1856      case GL_STENCIL_VALUE_MASK:
1857      case GL_STENCIL_REF:
1858      case GL_STENCIL_FAIL:
1859      case GL_STENCIL_PASS_DEPTH_FAIL:
1860      case GL_STENCIL_PASS_DEPTH_PASS:
1861      case GL_STENCIL_BACK_FUNC:
1862      case GL_STENCIL_BACK_VALUE_MASK:
1863      case GL_STENCIL_BACK_REF:
1864      case GL_STENCIL_BACK_FAIL:
1865      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1866      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1867      case GL_DEPTH_FUNC:
1868      case GL_BLEND_SRC_RGB:
1869      case GL_BLEND_SRC_ALPHA:
1870      case GL_BLEND_DST_RGB:
1871      case GL_BLEND_DST_ALPHA:
1872      case GL_BLEND_EQUATION_RGB:
1873      case GL_BLEND_EQUATION_ALPHA:
1874      case GL_STENCIL_WRITEMASK:
1875      case GL_STENCIL_BACK_WRITEMASK:
1876      case GL_STENCIL_CLEAR_VALUE:
1877      case GL_SUBPIXEL_BITS:
1878      case GL_MAX_TEXTURE_SIZE:
1879      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1880      case GL_SAMPLE_BUFFERS:
1881      case GL_SAMPLES:
1882      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1883      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1884      case GL_TEXTURE_BINDING_2D:
1885      case GL_TEXTURE_BINDING_CUBE_MAP:
1886      case GL_TEXTURE_BINDING_EXTERNAL_OES:
1887      case GL_TEXTURE_BINDING_3D_OES:
1888      case GL_COPY_READ_BUFFER_BINDING:
1889      case GL_COPY_WRITE_BUFFER_BINDING:
1890      case GL_DRAW_BUFFER0:
1891      case GL_DRAW_BUFFER1:
1892      case GL_DRAW_BUFFER2:
1893      case GL_DRAW_BUFFER3:
1894      case GL_DRAW_BUFFER4:
1895      case GL_DRAW_BUFFER5:
1896      case GL_DRAW_BUFFER6:
1897      case GL_DRAW_BUFFER7:
1898      case GL_DRAW_BUFFER8:
1899      case GL_DRAW_BUFFER9:
1900      case GL_DRAW_BUFFER10:
1901      case GL_DRAW_BUFFER11:
1902      case GL_DRAW_BUFFER12:
1903      case GL_DRAW_BUFFER13:
1904      case GL_DRAW_BUFFER14:
1905      case GL_DRAW_BUFFER15:
1906      case GL_MAJOR_VERSION:
1907      case GL_MAX_3D_TEXTURE_SIZE:
1908      case GL_MAX_ARRAY_TEXTURE_LAYERS:
1909      case GL_MAX_COLOR_ATTACHMENTS:
1910      case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
1911      case GL_MAX_COMBINED_UNIFORM_BLOCKS:
1912      case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
1913      case GL_MAX_DRAW_BUFFERS:
1914      case GL_MAX_ELEMENT_INDEX:
1915      case GL_MAX_ELEMENTS_INDICES:
1916      case GL_MAX_ELEMENTS_VERTICES:
1917      case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
1918      case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
1919      case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
1920      case GL_MAX_PROGRAM_TEXEL_OFFSET:
1921      case GL_MAX_SERVER_WAIT_TIMEOUT:
1922      case GL_MAX_TEXTURE_LOD_BIAS:
1923      case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
1924      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
1925      case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
1926      case GL_MAX_UNIFORM_BLOCK_SIZE:
1927      case GL_MAX_UNIFORM_BUFFER_BINDINGS:
1928      case GL_MAX_VARYING_COMPONENTS:
1929      case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
1930      case GL_MAX_VERTEX_UNIFORM_BLOCKS:
1931      case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
1932      case GL_MIN_PROGRAM_TEXEL_OFFSET:
1933      case GL_MINOR_VERSION:
1934      case GL_NUM_EXTENSIONS:
1935      case GL_NUM_PROGRAM_BINARY_FORMATS:
1936      case GL_PACK_ROW_LENGTH:
1937      case GL_PACK_SKIP_PIXELS:
1938      case GL_PACK_SKIP_ROWS:
1939      case GL_PIXEL_PACK_BUFFER_BINDING:
1940      case GL_PIXEL_UNPACK_BUFFER_BINDING:
1941      case GL_PROGRAM_BINARY_FORMATS:
1942      case GL_READ_BUFFER:
1943      case GL_SAMPLER_BINDING:
1944      case GL_TEXTURE_BINDING_2D_ARRAY:
1945      case GL_UNIFORM_BUFFER_BINDING:
1946      case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
1947      case GL_UNIFORM_BUFFER_SIZE:
1948      case GL_UNIFORM_BUFFER_START:
1949      case GL_UNPACK_IMAGE_HEIGHT:
1950      case GL_UNPACK_ROW_LENGTH:
1951      case GL_UNPACK_SKIP_IMAGES:
1952      case GL_UNPACK_SKIP_PIXELS:
1953      case GL_UNPACK_SKIP_ROWS:
1954      case GL_VERTEX_ARRAY_BINDING:
1955        {
1956            *type = GL_INT;
1957            *numParams = 1;
1958        }
1959        break;
1960      case GL_MAX_SAMPLES_ANGLE:
1961        {
1962            *type = GL_INT;
1963            *numParams = 1;
1964        }
1965        break;
1966      case GL_MAX_VIEWPORT_DIMS:
1967        {
1968            *type = GL_INT;
1969            *numParams = 2;
1970        }
1971        break;
1972      case GL_VIEWPORT:
1973      case GL_SCISSOR_BOX:
1974        {
1975            *type = GL_INT;
1976            *numParams = 4;
1977        }
1978        break;
1979      case GL_SHADER_COMPILER:
1980      case GL_SAMPLE_COVERAGE_INVERT:
1981      case GL_DEPTH_WRITEMASK:
1982      case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1983      case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1984      case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1985      case GL_SAMPLE_COVERAGE:
1986      case GL_SCISSOR_TEST:
1987      case GL_STENCIL_TEST:
1988      case GL_DEPTH_TEST:
1989      case GL_BLEND:
1990      case GL_DITHER:
1991      case GL_PRIMITIVE_RESTART_FIXED_INDEX:
1992      case GL_RASTERIZER_DISCARD:
1993        {
1994            *type = GL_BOOL;
1995            *numParams = 1;
1996        }
1997        break;
1998      case GL_COLOR_WRITEMASK:
1999        {
2000            *type = GL_BOOL;
2001            *numParams = 4;
2002        }
2003        break;
2004      case GL_POLYGON_OFFSET_FACTOR:
2005      case GL_POLYGON_OFFSET_UNITS:
2006      case GL_SAMPLE_COVERAGE_VALUE:
2007      case GL_DEPTH_CLEAR_VALUE:
2008      case GL_LINE_WIDTH:
2009        {
2010            *type = GL_FLOAT;
2011            *numParams = 1;
2012        }
2013        break;
2014      case GL_ALIASED_LINE_WIDTH_RANGE:
2015      case GL_ALIASED_POINT_SIZE_RANGE:
2016      case GL_DEPTH_RANGE:
2017        {
2018            *type = GL_FLOAT;
2019            *numParams = 2;
2020        }
2021        break;
2022      case GL_COLOR_CLEAR_VALUE:
2023      case GL_BLEND_COLOR:
2024        {
2025            *type = GL_FLOAT;
2026            *numParams = 4;
2027        }
2028        break;
2029	  case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
2030        *type = GL_FLOAT;
2031        *numParams = 1;
2032        break;
2033      default:
2034        return false;
2035    }
2036
2037    return true;
2038}
2039
2040// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
2041bool Context::applyRenderTarget()
2042{
2043    Framebuffer *framebuffer = getDrawFramebuffer();
2044	int width, height, samples;
2045
2046    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
2047    {
2048        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
2049    }
2050
2051    egl::Image *renderTarget = framebuffer->getRenderTarget();
2052	device->setRenderTarget(renderTarget);
2053	if(renderTarget) renderTarget->release();
2054
2055    egl::Image *depthStencil = framebuffer->getDepthStencil();
2056    device->setDepthStencilSurface(depthStencil);
2057	if(depthStencil) depthStencil->release();
2058
2059    Viewport viewport;
2060    float zNear = clamp01(mState.zNear);
2061    float zFar = clamp01(mState.zFar);
2062
2063    viewport.x0 = mState.viewportX;
2064    viewport.y0 = mState.viewportY;
2065    viewport.width = mState.viewportWidth;
2066    viewport.height = mState.viewportHeight;
2067    viewport.minZ = zNear;
2068    viewport.maxZ = zFar;
2069
2070    device->setViewport(viewport);
2071
2072    if(mState.scissorTest)
2073    {
2074		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
2075		scissor.clip(0, 0, width, height);
2076
2077		device->setScissorRect(scissor);
2078        device->setScissorEnable(true);
2079    }
2080    else
2081    {
2082        device->setScissorEnable(false);
2083    }
2084
2085	Program *program = getCurrentProgram();
2086
2087	if(program)
2088	{
2089		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
2090        program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
2091		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
2092		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
2093    }
2094
2095    return true;
2096}
2097
2098// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
2099void Context::applyState(GLenum drawMode)
2100{
2101    Framebuffer *framebuffer = getDrawFramebuffer();
2102
2103    if(mState.cullFace)
2104    {
2105        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
2106    }
2107    else
2108    {
2109		device->setCullMode(sw::CULL_NONE);
2110    }
2111
2112    if(mDepthStateDirty)
2113    {
2114        if(mState.depthTest)
2115        {
2116			device->setDepthBufferEnable(true);
2117			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
2118        }
2119        else
2120        {
2121            device->setDepthBufferEnable(false);
2122        }
2123
2124        mDepthStateDirty = false;
2125    }
2126
2127    if(mBlendStateDirty)
2128    {
2129        if(mState.blend)
2130        {
2131			device->setAlphaBlendEnable(true);
2132			device->setSeparateAlphaBlendEnable(true);
2133
2134            device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
2135
2136			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
2137			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
2138			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
2139
2140            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
2141			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
2142			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
2143        }
2144        else
2145        {
2146			device->setAlphaBlendEnable(false);
2147        }
2148
2149        mBlendStateDirty = false;
2150    }
2151
2152    if(mStencilStateDirty || mFrontFaceDirty)
2153    {
2154        if(mState.stencilTest && framebuffer->hasStencil())
2155        {
2156			device->setStencilEnable(true);
2157			device->setTwoSidedStencil(true);
2158
2159            if(mState.stencilWritemask != mState.stencilBackWritemask ||
2160               mState.stencilRef != mState.stencilBackRef ||
2161               mState.stencilMask != mState.stencilBackMask)
2162            {
2163				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
2164                return error(GL_INVALID_OPERATION);
2165            }
2166
2167            // get the maximum size of the stencil ref
2168            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
2169            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
2170
2171			if(mState.frontFace == GL_CCW)
2172			{
2173				device->setStencilWriteMask(mState.stencilWritemask);
2174				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
2175
2176				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2177				device->setStencilMask(mState.stencilMask);
2178
2179				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
2180				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2181				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2182
2183				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
2184				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2185
2186				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2187				device->setStencilMaskCCW(mState.stencilBackMask);
2188
2189				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
2190				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2191				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2192			}
2193			else
2194			{
2195				device->setStencilWriteMaskCCW(mState.stencilWritemask);
2196				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
2197
2198				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
2199				device->setStencilMaskCCW(mState.stencilMask);
2200
2201				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
2202				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
2203				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
2204
2205				device->setStencilWriteMask(mState.stencilBackWritemask);
2206				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
2207
2208				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
2209				device->setStencilMask(mState.stencilBackMask);
2210
2211				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
2212				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
2213				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
2214			}
2215        }
2216        else
2217        {
2218			device->setStencilEnable(false);
2219        }
2220
2221        mStencilStateDirty = false;
2222        mFrontFaceDirty = false;
2223    }
2224
2225    if(mMaskStateDirty)
2226    {
2227		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
2228		device->setDepthWriteEnable(mState.depthMask);
2229
2230        mMaskStateDirty = false;
2231    }
2232
2233    if(mPolygonOffsetStateDirty)
2234    {
2235        if(mState.polygonOffsetFill)
2236        {
2237            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
2238            if(depthbuffer)
2239            {
2240				device->setSlopeDepthBias(mState.polygonOffsetFactor);
2241                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
2242				device->setDepthBias(depthBias);
2243            }
2244        }
2245        else
2246        {
2247            device->setSlopeDepthBias(0);
2248            device->setDepthBias(0);
2249        }
2250
2251        mPolygonOffsetStateDirty = false;
2252    }
2253
2254    if(mSampleStateDirty)
2255    {
2256        if(mState.sampleAlphaToCoverage)
2257        {
2258            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
2259        }
2260		else
2261		{
2262			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
2263		}
2264
2265        if(mState.sampleCoverage)
2266        {
2267            unsigned int mask = 0;
2268            if(mState.sampleCoverageValue != 0)
2269            {
2270				int width, height, samples;
2271				framebuffer->completeness(width, height, samples);
2272
2273                float threshold = 0.5f;
2274
2275                for(int i = 0; i < samples; i++)
2276                {
2277                    mask <<= 1;
2278
2279                    if((i + 1) * mState.sampleCoverageValue >= threshold)
2280                    {
2281                        threshold += 1.0f;
2282                        mask |= 1;
2283                    }
2284                }
2285            }
2286
2287            if(mState.sampleCoverageInvert)
2288            {
2289                mask = ~mask;
2290            }
2291
2292			device->setMultiSampleMask(mask);
2293        }
2294        else
2295        {
2296			device->setMultiSampleMask(0xFFFFFFFF);
2297        }
2298
2299        mSampleStateDirty = false;
2300    }
2301
2302    if(mDitherStateDirty)
2303    {
2304    //	UNIMPLEMENTED();   // FIXME
2305
2306        mDitherStateDirty = false;
2307    }
2308}
2309
2310GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
2311{
2312    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
2313
2314    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
2315    if(err != GL_NO_ERROR)
2316    {
2317        return err;
2318    }
2319
2320	Program *program = getCurrentProgram();
2321
2322	device->resetInputStreams(false);
2323
2324    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
2325	{
2326		if(program->getAttributeStream(i) == -1)
2327		{
2328			continue;
2329		}
2330
2331		sw::Resource *resource = attributes[i].vertexBuffer;
2332		const void *buffer = (char*)resource->data() + attributes[i].offset;
2333
2334		int stride = attributes[i].stride;
2335
2336		buffer = (char*)buffer + stride * base;
2337
2338		sw::Stream attribute(resource, buffer, stride);
2339
2340		attribute.type = attributes[i].type;
2341		attribute.count = attributes[i].count;
2342		attribute.normalized = attributes[i].normalized;
2343
2344		int stream = program->getAttributeStream(i);
2345		device->setInputStream(stream, attribute);
2346	}
2347
2348	return GL_NO_ERROR;
2349}
2350
2351// Applies the indices and element array bindings
2352GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
2353{
2354    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
2355
2356    if(err == GL_NO_ERROR)
2357    {
2358        device->setIndexBuffer(indexInfo->indexBuffer);
2359    }
2360
2361    return err;
2362}
2363
2364// Applies the shaders and shader constants
2365void Context::applyShaders()
2366{
2367    Program *programObject = getCurrentProgram();
2368    sw::VertexShader *vertexShader = programObject->getVertexShader();
2369	sw::PixelShader *pixelShader = programObject->getPixelShader();
2370
2371    device->setVertexShader(vertexShader);
2372    device->setPixelShader(pixelShader);
2373
2374    if(programObject->getSerial() != mAppliedProgramSerial)
2375    {
2376        programObject->dirtyAllUniforms();
2377        mAppliedProgramSerial = programObject->getSerial();
2378    }
2379
2380    programObject->applyUniforms();
2381}
2382
2383void Context::applyTextures()
2384{
2385    applyTextures(sw::SAMPLER_PIXEL);
2386	applyTextures(sw::SAMPLER_VERTEX);
2387}
2388
2389void Context::applyTextures(sw::SamplerType samplerType)
2390{
2391    Program *programObject = getCurrentProgram();
2392
2393    int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
2394
2395    for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
2396    {
2397        int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
2398
2399        if(textureUnit != -1)
2400        {
2401            TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
2402
2403            Texture *texture = getSamplerTexture(textureUnit, textureType);
2404
2405			if(texture->isSamplerComplete())
2406            {
2407                GLenum wrapS = texture->getWrapS();
2408                GLenum wrapT = texture->getWrapT();
2409				GLenum wrapR = texture->getWrapR();
2410                GLenum texFilter = texture->getMinFilter();
2411                GLenum magFilter = texture->getMagFilter();
2412				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2413
2414				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
2415				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
2416				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
2417
2418				sw::FilterType minFilter;
2419				sw::MipmapType mipFilter;
2420                es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy);
2421			//	ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter));
2422
2423				device->setTextureFilter(samplerType, samplerIndex, minFilter);
2424			//	device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter));
2425				device->setMipmapFilter(samplerType, samplerIndex, mipFilter);
2426				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
2427
2428				applyTexture(samplerType, samplerIndex, texture);
2429            }
2430            else
2431            {
2432                applyTexture(samplerType, samplerIndex, 0);
2433            }
2434        }
2435        else
2436        {
2437            applyTexture(samplerType, samplerIndex, NULL);
2438        }
2439    }
2440}
2441
2442void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
2443{
2444	Program *program = getCurrentProgram();
2445	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
2446	bool textureUsed = false;
2447
2448	if(type == sw::SAMPLER_PIXEL)
2449	{
2450		textureUsed = program->getPixelShader()->usesSampler(index);
2451	}
2452	else if(type == sw::SAMPLER_VERTEX)
2453	{
2454		textureUsed = program->getVertexShader()->usesSampler(index);
2455	}
2456	else UNREACHABLE();
2457
2458	sw::Resource *resource = 0;
2459
2460	if(baseTexture && textureUsed)
2461	{
2462		resource = baseTexture->getResource();
2463	}
2464
2465	device->setTextureResource(sampler, resource);
2466
2467	if(baseTexture && textureUsed)
2468	{
2469		int levelCount = baseTexture->getLevelCount();
2470
2471		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
2472		{
2473			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2474
2475			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2476			{
2477				int surfaceLevel = mipmapLevel;
2478
2479				if(surfaceLevel < 0)
2480				{
2481					surfaceLevel = 0;
2482				}
2483				else if(surfaceLevel >= levelCount)
2484				{
2485					surfaceLevel = levelCount - 1;
2486				}
2487
2488				egl::Image *surface = texture->getImage(surfaceLevel);
2489				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2490			}
2491		}
2492		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)
2493		{
2494			Texture3D *texture = static_cast<Texture3D*>(baseTexture);
2495
2496			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2497			{
2498				int surfaceLevel = mipmapLevel;
2499
2500				if(surfaceLevel < 0)
2501				{
2502					surfaceLevel = 0;
2503				}
2504				else if(surfaceLevel >= levelCount)
2505				{
2506					surfaceLevel = levelCount - 1;
2507				}
2508
2509				egl::Image *surface = texture->getImage(surfaceLevel);
2510				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
2511			}
2512		}
2513		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
2514		{
2515			for(int face = 0; face < 6; face++)
2516			{
2517				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
2518
2519				for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2520				{
2521					int surfaceLevel = mipmapLevel;
2522
2523					if(surfaceLevel < 0)
2524					{
2525						surfaceLevel = 0;
2526					}
2527					else if(surfaceLevel >= levelCount)
2528					{
2529						surfaceLevel = levelCount - 1;
2530					}
2531
2532					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
2533					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
2534				}
2535			}
2536		}
2537		else UNIMPLEMENTED();
2538	}
2539	else
2540	{
2541		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
2542	}
2543}
2544
2545void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2546                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2547{
2548    Framebuffer *framebuffer = getReadFramebuffer();
2549	int framebufferWidth, framebufferHeight, framebufferSamples;
2550
2551    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2552    {
2553        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2554    }
2555
2556    if(getReadFramebufferName() != 0 && framebufferSamples != 0)
2557    {
2558        return error(GL_INVALID_OPERATION);
2559    }
2560
2561	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
2562	{
2563		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
2564		{
2565			return error(GL_INVALID_OPERATION);
2566		}
2567	}
2568
2569	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
2570
2571	// Sized query sanity check
2572    if(bufSize)
2573    {
2574        int requiredSize = outputPitch * height;
2575        if(requiredSize > *bufSize)
2576        {
2577            return error(GL_INVALID_OPERATION);
2578        }
2579    }
2580
2581    egl::Image *renderTarget = framebuffer->getRenderTarget();
2582
2583    if(!renderTarget)
2584    {
2585        return error(GL_OUT_OF_MEMORY);
2586    }
2587
2588	sw::Rect rect = {x, y, x + width, y + height};
2589	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2590
2591    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2592    unsigned char *dest = (unsigned char*)pixels;
2593    int inputPitch = (int)renderTarget->getPitch();
2594
2595    for(int j = 0; j < rect.y1 - rect.y0; j++)
2596    {
2597		unsigned short *dest16 = (unsigned short*)dest;
2598		unsigned int *dest32 = (unsigned int*)dest;
2599
2600		if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2601           format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2602        {
2603            for(int i = 0; i < rect.x1 - rect.x0; i++)
2604			{
2605				unsigned int argb = *(unsigned int*)(source + 4 * i);
2606
2607				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
2608			}
2609        }
2610		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2611                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2612        {
2613            for(int i = 0; i < rect.x1 - rect.x0; i++)
2614			{
2615				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2616
2617				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
2618			}
2619        }
2620		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2621                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2622        {
2623            for(int i = 0; i < rect.x1 - rect.x0; i++)
2624			{
2625				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2626
2627				dest32[i] = xrgb | 0xFF000000;
2628			}
2629        }
2630        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2631                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2632        {
2633            memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2634        }
2635		else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F &&
2636                format == GL_RGBA && type == GL_HALF_FLOAT_OES)
2637        {
2638            memcpy(dest, source, (rect.x1 - rect.x0) * 8);
2639        }
2640		else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F &&
2641                format == GL_RGBA && type == GL_FLOAT)
2642        {
2643            memcpy(dest, source, (rect.x1 - rect.x0) * 16);
2644        }
2645		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
2646                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
2647        {
2648            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2649        }
2650		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
2651                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
2652        {
2653            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2654        }
2655		else
2656		{
2657			for(int i = 0; i < rect.x1 - rect.x0; i++)
2658			{
2659				float r;
2660				float g;
2661				float b;
2662				float a;
2663
2664				switch(renderTarget->getInternalFormat())
2665				{
2666				case sw::FORMAT_R5G6B5:
2667					{
2668						unsigned short rgb = *(unsigned short*)(source + 2 * i);
2669
2670						a = 1.0f;
2671						b = (rgb & 0x001F) * (1.0f / 0x001F);
2672						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2673						r = (rgb & 0xF800) * (1.0f / 0xF800);
2674					}
2675					break;
2676				case sw::FORMAT_A1R5G5B5:
2677					{
2678						unsigned short argb = *(unsigned short*)(source + 2 * i);
2679
2680						a = (argb & 0x8000) ? 1.0f : 0.0f;
2681						b = (argb & 0x001F) * (1.0f / 0x001F);
2682						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2683						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2684					}
2685					break;
2686				case sw::FORMAT_A8R8G8B8:
2687					{
2688						unsigned int argb = *(unsigned int*)(source + 4 * i);
2689
2690						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2691						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2692						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2693						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2694					}
2695					break;
2696				case sw::FORMAT_X8R8G8B8:
2697					{
2698						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2699
2700						a = 1.0f;
2701						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2702						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2703						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2704					}
2705					break;
2706				case sw::FORMAT_A2R10G10B10:
2707					{
2708						unsigned int argb = *(unsigned int*)(source + 4 * i);
2709
2710						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2711						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2712						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2713						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2714					}
2715					break;
2716				case sw::FORMAT_A32B32G32R32F:
2717					{
2718						r = *((float*)(source + 16 * i) + 0);
2719						g = *((float*)(source + 16 * i) + 1);
2720						b = *((float*)(source + 16 * i) + 2);
2721						a = *((float*)(source + 16 * i) + 3);
2722					}
2723					break;
2724				case sw::FORMAT_A16B16G16R16F:
2725					{
2726						r = (float)*((sw::half*)(source + 8 * i) + 0);
2727						g = (float)*((sw::half*)(source + 8 * i) + 1);
2728						b = (float)*((sw::half*)(source + 8 * i) + 2);
2729						a = (float)*((sw::half*)(source + 8 * i) + 3);
2730					}
2731					break;
2732				default:
2733					UNIMPLEMENTED();   // FIXME
2734					UNREACHABLE();
2735				}
2736
2737				switch(format)
2738				{
2739				case GL_RGBA:
2740					switch(type)
2741					{
2742					case GL_UNSIGNED_BYTE:
2743						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
2744						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2745						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
2746						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2747						break;
2748					default: UNREACHABLE();
2749					}
2750					break;
2751				case GL_BGRA_EXT:
2752					switch(type)
2753					{
2754					case GL_UNSIGNED_BYTE:
2755						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
2756						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2757						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
2758						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2759						break;
2760					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2761						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2762						// this type is packed as follows:
2763						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2764						//  --------------------------------------------------------------------------------
2765						// |       4th         |        3rd         |        2nd        |   1st component   |
2766						//  --------------------------------------------------------------------------------
2767						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2768						dest16[i] =
2769							((unsigned short)(15 * a + 0.5f) << 12)|
2770							((unsigned short)(15 * r + 0.5f) << 8) |
2771							((unsigned short)(15 * g + 0.5f) << 4) |
2772							((unsigned short)(15 * b + 0.5f) << 0);
2773						break;
2774					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2775						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2776						// this type is packed as follows:
2777						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2778						//  --------------------------------------------------------------------------------
2779						// | 4th |          3rd           |           2nd          |      1st component     |
2780						//  --------------------------------------------------------------------------------
2781						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2782						dest16[i] =
2783							((unsigned short)(     a + 0.5f) << 15) |
2784							((unsigned short)(31 * r + 0.5f) << 10) |
2785							((unsigned short)(31 * g + 0.5f) << 5) |
2786							((unsigned short)(31 * b + 0.5f) << 0);
2787						break;
2788					default: UNREACHABLE();
2789					}
2790					break;
2791				case GL_RGB:
2792					switch(type)
2793					{
2794					case GL_UNSIGNED_SHORT_5_6_5:
2795						dest16[i] =
2796							((unsigned short)(31 * b + 0.5f) << 0) |
2797							((unsigned short)(63 * g + 0.5f) << 5) |
2798							((unsigned short)(31 * r + 0.5f) << 11);
2799						break;
2800					default: UNREACHABLE();
2801					}
2802					break;
2803				default: UNREACHABLE();
2804				}
2805			}
2806        }
2807
2808		source += inputPitch;
2809		dest += outputPitch;
2810    }
2811
2812	renderTarget->unlock();
2813	renderTarget->release();
2814}
2815
2816void Context::clear(GLbitfield mask)
2817{
2818    Framebuffer *framebuffer = getDrawFramebuffer();
2819
2820    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2821    {
2822        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2823    }
2824
2825    if(!applyRenderTarget())
2826    {
2827        return;
2828    }
2829
2830	unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
2831                         (unorm<8>(mState.colorClearValue.red) << 16) |
2832                         (unorm<8>(mState.colorClearValue.green) << 8) |
2833                         (unorm<8>(mState.colorClearValue.blue) << 0);
2834    float depth = clamp01(mState.depthClearValue);
2835    int stencil = mState.stencilClearValue & 0x000000FF;
2836
2837	if(mask & GL_COLOR_BUFFER_BIT)
2838	{
2839		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2840		                        (mState.colorMaskGreen ? 0x2 : 0) |
2841		                        (mState.colorMaskBlue ? 0x4 : 0) |
2842		                        (mState.colorMaskAlpha ? 0x8 : 0);
2843
2844		if(rgbaMask != 0)
2845		{
2846			device->clearColor(color, rgbaMask);
2847		}
2848	}
2849
2850	if(mask & GL_DEPTH_BUFFER_BIT)
2851	{
2852		if(mState.depthMask != 0)
2853		{
2854			device->clearDepth(depth);
2855		}
2856	}
2857
2858	if(mask & GL_STENCIL_BUFFER_BIT)
2859	{
2860		if(mState.stencilWritemask != 0)
2861		{
2862			device->clearStencil(stencil, mState.stencilWritemask);
2863		}
2864	}
2865}
2866
2867void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2868{
2869    if(!mState.currentProgram)
2870    {
2871        return error(GL_INVALID_OPERATION);
2872    }
2873
2874    PrimitiveType primitiveType;
2875    int primitiveCount;
2876
2877    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2878        return error(GL_INVALID_ENUM);
2879
2880    if(primitiveCount <= 0)
2881    {
2882        return;
2883    }
2884
2885    if(!applyRenderTarget())
2886    {
2887        return;
2888    }
2889
2890    applyState(mode);
2891
2892    GLenum err = applyVertexBuffer(0, first, count);
2893    if(err != GL_NO_ERROR)
2894    {
2895        return error(err);
2896    }
2897
2898    applyShaders();
2899    applyTextures();
2900
2901    if(!getCurrentProgram()->validateSamplers(false))
2902    {
2903        return error(GL_INVALID_OPERATION);
2904    }
2905
2906    if(!cullSkipsDraw(mode))
2907    {
2908        device->drawPrimitive(primitiveType, primitiveCount);
2909    }
2910}
2911
2912void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2913{
2914    if(!mState.currentProgram)
2915    {
2916        return error(GL_INVALID_OPERATION);
2917    }
2918
2919    if(!indices && !mState.elementArrayBuffer)
2920    {
2921        return error(GL_INVALID_OPERATION);
2922    }
2923
2924    PrimitiveType primitiveType;
2925    int primitiveCount;
2926
2927    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2928        return error(GL_INVALID_ENUM);
2929
2930    if(primitiveCount <= 0)
2931    {
2932        return;
2933    }
2934
2935    if(!applyRenderTarget())
2936    {
2937        return;
2938    }
2939
2940    applyState(mode);
2941
2942    TranslatedIndexData indexInfo;
2943    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2944    if(err != GL_NO_ERROR)
2945    {
2946        return error(err);
2947    }
2948
2949    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2950    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2951    if(err != GL_NO_ERROR)
2952    {
2953        return error(err);
2954    }
2955
2956    applyShaders();
2957    applyTextures();
2958
2959    if(!getCurrentProgram()->validateSamplers(false))
2960    {
2961        return error(GL_INVALID_OPERATION);
2962    }
2963
2964    if(!cullSkipsDraw(mode))
2965    {
2966		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2967    }
2968}
2969
2970void Context::finish()
2971{
2972	device->finish();
2973}
2974
2975void Context::flush()
2976{
2977    // We don't queue anything without processing it as fast as possible
2978}
2979
2980void Context::recordInvalidEnum()
2981{
2982    mInvalidEnum = true;
2983}
2984
2985void Context::recordInvalidValue()
2986{
2987    mInvalidValue = true;
2988}
2989
2990void Context::recordInvalidOperation()
2991{
2992    mInvalidOperation = true;
2993}
2994
2995void Context::recordOutOfMemory()
2996{
2997    mOutOfMemory = true;
2998}
2999
3000void Context::recordInvalidFramebufferOperation()
3001{
3002    mInvalidFramebufferOperation = true;
3003}
3004
3005// Get one of the recorded errors and clear its flag, if any.
3006// [OpenGL ES 2.0.24] section 2.5 page 13.
3007GLenum Context::getError()
3008{
3009    if(mInvalidEnum)
3010    {
3011        mInvalidEnum = false;
3012
3013        return GL_INVALID_ENUM;
3014    }
3015
3016    if(mInvalidValue)
3017    {
3018        mInvalidValue = false;
3019
3020        return GL_INVALID_VALUE;
3021    }
3022
3023    if(mInvalidOperation)
3024    {
3025        mInvalidOperation = false;
3026
3027        return GL_INVALID_OPERATION;
3028    }
3029
3030    if(mOutOfMemory)
3031    {
3032        mOutOfMemory = false;
3033
3034        return GL_OUT_OF_MEMORY;
3035    }
3036
3037    if(mInvalidFramebufferOperation)
3038    {
3039        mInvalidFramebufferOperation = false;
3040
3041        return GL_INVALID_FRAMEBUFFER_OPERATION;
3042    }
3043
3044    return GL_NO_ERROR;
3045}
3046
3047int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
3048{
3049    if(requested <= 1)
3050    {
3051        return 1;
3052    }
3053
3054	if(requested == 2)
3055	{
3056		return 2;
3057	}
3058
3059	return 4;
3060}
3061
3062void Context::detachBuffer(GLuint buffer)
3063{
3064    // [OpenGL ES 2.0.24] section 2.9 page 22:
3065    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3066    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3067
3068    if(mState.arrayBuffer.name() == buffer)
3069    {
3070        mState.arrayBuffer = NULL;
3071    }
3072
3073    if(mState.elementArrayBuffer.name() == buffer)
3074    {
3075        mState.elementArrayBuffer = NULL;
3076    }
3077
3078    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3079    {
3080        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3081        {
3082            mState.vertexAttribute[attribute].mBoundBuffer = NULL;
3083        }
3084    }
3085}
3086
3087void Context::detachTexture(GLuint texture)
3088{
3089    // [OpenGL ES 2.0.24] section 3.8 page 84:
3090    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3091    // rebound to texture object zero
3092
3093    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3094    {
3095        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3096        {
3097            if(mState.samplerTexture[type][sampler].name() == texture)
3098            {
3099                mState.samplerTexture[type][sampler] = NULL;
3100            }
3101        }
3102    }
3103
3104    // [OpenGL ES 2.0.24] section 4.4 page 112:
3105    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3106    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3107    // image was attached in the currently bound framebuffer.
3108
3109    Framebuffer *readFramebuffer = getReadFramebuffer();
3110    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3111
3112    if(readFramebuffer)
3113    {
3114        readFramebuffer->detachTexture(texture);
3115    }
3116
3117    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3118    {
3119        drawFramebuffer->detachTexture(texture);
3120    }
3121}
3122
3123void Context::detachFramebuffer(GLuint framebuffer)
3124{
3125    // [OpenGL ES 2.0.24] section 4.4 page 107:
3126    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3127    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3128
3129    if(mState.readFramebuffer == framebuffer)
3130    {
3131        bindReadFramebuffer(0);
3132    }
3133
3134    if(mState.drawFramebuffer == framebuffer)
3135    {
3136        bindDrawFramebuffer(0);
3137    }
3138}
3139
3140void Context::detachRenderbuffer(GLuint renderbuffer)
3141{
3142    // [OpenGL ES 2.0.24] section 4.4 page 109:
3143    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3144    // had been executed with the target RENDERBUFFER and name of zero.
3145
3146    if(mState.renderbuffer.name() == renderbuffer)
3147    {
3148        bindRenderbuffer(0);
3149    }
3150
3151    // [OpenGL ES 2.0.24] section 4.4 page 111:
3152    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3153    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3154    // point to which this image was attached in the currently bound framebuffer.
3155
3156    Framebuffer *readFramebuffer = getReadFramebuffer();
3157    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3158
3159    if(readFramebuffer)
3160    {
3161        readFramebuffer->detachRenderbuffer(renderbuffer);
3162    }
3163
3164    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3165    {
3166        drawFramebuffer->detachRenderbuffer(renderbuffer);
3167    }
3168}
3169
3170bool Context::cullSkipsDraw(GLenum drawMode)
3171{
3172    return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3173}
3174
3175bool Context::isTriangleMode(GLenum drawMode)
3176{
3177    switch (drawMode)
3178    {
3179      case GL_TRIANGLES:
3180      case GL_TRIANGLE_FAN:
3181      case GL_TRIANGLE_STRIP:
3182        return true;
3183      case GL_POINTS:
3184      case GL_LINES:
3185      case GL_LINE_LOOP:
3186      case GL_LINE_STRIP:
3187        return false;
3188      default: UNREACHABLE();
3189    }
3190
3191    return false;
3192}
3193
3194void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3195{
3196    ASSERT(index < MAX_VERTEX_ATTRIBS);
3197
3198    mState.vertexAttribute[index].mCurrentValue[0] = values[0];
3199    mState.vertexAttribute[index].mCurrentValue[1] = values[1];
3200    mState.vertexAttribute[index].mCurrentValue[2] = values[2];
3201    mState.vertexAttribute[index].mCurrentValue[3] = values[3];
3202
3203    mVertexDataManager->dirtyCurrentValue(index);
3204}
3205
3206void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
3207                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3208                              GLbitfield mask)
3209{
3210    Framebuffer *readFramebuffer = getReadFramebuffer();
3211    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3212
3213	int readBufferWidth, readBufferHeight, readBufferSamples;
3214    int drawBufferWidth, drawBufferHeight, drawBufferSamples;
3215
3216    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
3217       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
3218    {
3219        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3220    }
3221
3222    if(drawBufferSamples > 1)
3223    {
3224        return error(GL_INVALID_OPERATION);
3225    }
3226
3227    sw::SliceRect sourceRect;
3228    sw::SliceRect destRect;
3229	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
3230	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
3231
3232    if(srcX0 < srcX1)
3233    {
3234        sourceRect.x0 = srcX0;
3235        sourceRect.x1 = srcX1;
3236    }
3237    else
3238    {
3239        sourceRect.x0 = srcX1;
3240        sourceRect.x1 = srcX0;
3241    }
3242
3243	if(dstX0 < dstX1)
3244	{
3245		destRect.x0 = dstX0;
3246		destRect.x1 = dstX1;
3247	}
3248	else
3249	{
3250		destRect.x0 = dstX1;
3251		destRect.x1 = dstX0;
3252	}
3253
3254    if(srcY0 < srcY1)
3255    {
3256        sourceRect.y0 = srcY0;
3257        sourceRect.y1 = srcY1;
3258    }
3259    else
3260    {
3261        sourceRect.y0 = srcY1;
3262        sourceRect.y1 = srcY0;
3263    }
3264
3265	if(dstY0 < dstY1)
3266	{
3267		destRect.y0 = dstY0;
3268		destRect.y1 = dstY1;
3269	}
3270	else
3271	{
3272		destRect.y0 = dstY1;
3273		destRect.y1 = dstY0;
3274	}
3275
3276	sw::Rect sourceScissoredRect = sourceRect;
3277    sw::Rect destScissoredRect = destRect;
3278
3279    if(mState.scissorTest)   // Only write to parts of the destination framebuffer which pass the scissor test
3280    {
3281        if(destRect.x0 < mState.scissorX)
3282        {
3283            int xDiff = mState.scissorX - destRect.x0;
3284            destScissoredRect.x0 = mState.scissorX;
3285            sourceScissoredRect.x0 += xDiff;
3286        }
3287
3288        if(destRect.x1 > mState.scissorX + mState.scissorWidth)
3289        {
3290            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
3291            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
3292            sourceScissoredRect.x1 -= xDiff;
3293        }
3294
3295        if(destRect.y0 < mState.scissorY)
3296        {
3297            int yDiff = mState.scissorY - destRect.y0;
3298            destScissoredRect.y0 = mState.scissorY;
3299            sourceScissoredRect.y0 += yDiff;
3300        }
3301
3302        if(destRect.y1 > mState.scissorY + mState.scissorHeight)
3303        {
3304            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
3305            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
3306            sourceScissoredRect.y1 -= yDiff;
3307        }
3308    }
3309
3310    sw::Rect sourceTrimmedRect = sourceScissoredRect;
3311    sw::Rect destTrimmedRect = destScissoredRect;
3312
3313    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
3314    // the actual draw and read surfaces.
3315    if(sourceTrimmedRect.x0 < 0)
3316    {
3317        int xDiff = 0 - sourceTrimmedRect.x0;
3318        sourceTrimmedRect.x0 = 0;
3319        destTrimmedRect.x0 += xDiff;
3320    }
3321
3322    if(sourceTrimmedRect.x1 > readBufferWidth)
3323    {
3324        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
3325        sourceTrimmedRect.x1 = readBufferWidth;
3326        destTrimmedRect.x1 -= xDiff;
3327    }
3328
3329    if(sourceTrimmedRect.y0 < 0)
3330    {
3331        int yDiff = 0 - sourceTrimmedRect.y0;
3332        sourceTrimmedRect.y0 = 0;
3333        destTrimmedRect.y0 += yDiff;
3334    }
3335
3336    if(sourceTrimmedRect.y1 > readBufferHeight)
3337    {
3338        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
3339        sourceTrimmedRect.y1 = readBufferHeight;
3340        destTrimmedRect.y1 -= yDiff;
3341    }
3342
3343    if(destTrimmedRect.x0 < 0)
3344    {
3345        int xDiff = 0 - destTrimmedRect.x0;
3346        destTrimmedRect.x0 = 0;
3347        sourceTrimmedRect.x0 += xDiff;
3348    }
3349
3350    if(destTrimmedRect.x1 > drawBufferWidth)
3351    {
3352        int xDiff = destTrimmedRect.x1 - drawBufferWidth;
3353        destTrimmedRect.x1 = drawBufferWidth;
3354        sourceTrimmedRect.x1 -= xDiff;
3355    }
3356
3357    if(destTrimmedRect.y0 < 0)
3358    {
3359        int yDiff = 0 - destTrimmedRect.y0;
3360        destTrimmedRect.y0 = 0;
3361        sourceTrimmedRect.y0 += yDiff;
3362    }
3363
3364    if(destTrimmedRect.y1 > drawBufferHeight)
3365    {
3366        int yDiff = destTrimmedRect.y1 - drawBufferHeight;
3367        destTrimmedRect.y1 = drawBufferHeight;
3368        sourceTrimmedRect.y1 -= yDiff;
3369    }
3370
3371    bool partialBufferCopy = false;
3372
3373    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
3374       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
3375       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
3376       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
3377       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
3378    {
3379        partialBufferCopy = true;
3380    }
3381
3382	bool blitRenderTarget = false;
3383    bool blitDepthStencil = false;
3384
3385    if(mask & GL_COLOR_BUFFER_BIT)
3386    {
3387        const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
3388                                   readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
3389        const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
3390                                   drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
3391        if(!validReadType || !validDrawType)
3392        {
3393            return error(GL_INVALID_OPERATION);
3394        }
3395
3396        if(partialBufferCopy && readBufferSamples > 1)
3397        {
3398            return error(GL_INVALID_OPERATION);
3399        }
3400
3401        blitRenderTarget = true;
3402    }
3403
3404    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
3405    {
3406        Renderbuffer *readDSBuffer = NULL;
3407        Renderbuffer *drawDSBuffer = NULL;
3408
3409        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
3410        // both a depth and stencil buffer, it will be the same buffer.
3411
3412        if(mask & GL_DEPTH_BUFFER_BIT)
3413        {
3414            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
3415            {
3416                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
3417                {
3418                    return error(GL_INVALID_OPERATION);
3419                }
3420
3421                blitDepthStencil = true;
3422                readDSBuffer = readFramebuffer->getDepthbuffer();
3423                drawDSBuffer = drawFramebuffer->getDepthbuffer();
3424            }
3425        }
3426
3427        if(mask & GL_STENCIL_BUFFER_BIT)
3428        {
3429            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
3430            {
3431                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
3432                {
3433                    return error(GL_INVALID_OPERATION);
3434                }
3435
3436                blitDepthStencil = true;
3437                readDSBuffer = readFramebuffer->getStencilbuffer();
3438                drawDSBuffer = drawFramebuffer->getStencilbuffer();
3439            }
3440        }
3441
3442        if(partialBufferCopy)
3443        {
3444            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
3445            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
3446        }
3447
3448        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
3449           (readDSBuffer && readDSBuffer->getSamples() > 1))
3450        {
3451            return error(GL_INVALID_OPERATION);
3452        }
3453    }
3454
3455    if(blitRenderTarget || blitDepthStencil)
3456    {
3457        if(blitRenderTarget)
3458        {
3459            egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
3460            egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
3461
3462			if(flipX)
3463			{
3464				swap(destRect.x0, destRect.x1);
3465			}
3466			if(flipy)
3467			{
3468				swap(destRect.y0, destRect.y1);
3469			}
3470
3471            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
3472
3473            readRenderTarget->release();
3474            drawRenderTarget->release();
3475
3476            if(!success)
3477            {
3478                ERR("BlitFramebuffer failed.");
3479                return;
3480            }
3481        }
3482
3483        if(blitDepthStencil)
3484        {
3485            bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false);
3486
3487            if(!success)
3488            {
3489                ERR("BlitFramebuffer failed.");
3490                return;
3491            }
3492        }
3493    }
3494}
3495
3496void Context::bindTexImage(egl::Surface *surface)
3497{
3498	es2::Texture2D *textureObject = getTexture2D();
3499
3500    if(textureObject)
3501    {
3502		textureObject->bindTexImage(surface);
3503	}
3504}
3505
3506EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3507{
3508    GLenum textureTarget = GL_NONE;
3509
3510    switch(target)
3511    {
3512    case EGL_GL_TEXTURE_2D_KHR:
3513        textureTarget = GL_TEXTURE_2D;
3514        break;
3515    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
3516    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
3517    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
3518    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
3519    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
3520    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
3521        textureTarget = GL_TEXTURE_CUBE_MAP;
3522        break;
3523    case EGL_GL_RENDERBUFFER_KHR:
3524        break;
3525    default:
3526        return EGL_BAD_PARAMETER;
3527    }
3528
3529    if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3530    {
3531        return EGL_BAD_MATCH;
3532    }
3533
3534    if(textureTarget != GL_NONE)
3535    {
3536        es2::Texture *texture = getTexture(name);
3537
3538        if(!texture || texture->getTarget() != textureTarget)
3539        {
3540            return EGL_BAD_PARAMETER;
3541        }
3542
3543        if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
3544        {
3545            return EGL_BAD_ACCESS;
3546        }
3547
3548        if(textureLevel != 0 && !texture->isSamplerComplete())
3549        {
3550            return EGL_BAD_PARAMETER;
3551        }
3552
3553        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
3554        {
3555            return EGL_BAD_PARAMETER;
3556        }
3557    }
3558    else if(target == EGL_GL_RENDERBUFFER_KHR)
3559    {
3560        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3561
3562        if(!renderbuffer)
3563        {
3564            return EGL_BAD_PARAMETER;
3565        }
3566
3567        if(renderbuffer->isShared())   // Already an EGLImage sibling
3568        {
3569            return EGL_BAD_ACCESS;
3570        }
3571    }
3572    else UNREACHABLE();
3573
3574	return EGL_SUCCESS;
3575}
3576
3577egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3578{
3579	GLenum textureTarget = GL_NONE;
3580
3581    switch(target)
3582    {
3583    case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
3584    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
3585    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
3586    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
3587    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
3588    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
3589    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
3590    }
3591
3592    if(textureTarget != GL_NONE)
3593    {
3594        es2::Texture *texture = getTexture(name);
3595
3596        return texture->createSharedImage(textureTarget, textureLevel);
3597    }
3598    else if(target == EGL_GL_RENDERBUFFER_KHR)
3599    {
3600        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3601
3602        return renderbuffer->createSharedImage();
3603    }
3604    else UNREACHABLE();
3605
3606	return 0;
3607}
3608
3609Device *Context::getDevice()
3610{
3611	return device;
3612}
3613
3614}
3615
3616// Exported functions for use by EGL
3617extern "C"
3618{
3619	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion)
3620	{
3621		return new es2::Context(config, shareContext, clientVersion);
3622	}
3623}
3624