Context.cpp revision 0b65c5e3903233839197fd689895ba57b7f61a5b
1// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12// Context.cpp: Implements the es2::Context class, managing all GL state and performing
13// rendering operations. It is the GLES2 specific implementation of EGLContext.
14
15#include "Context.h"
16
17#include "main.h"
18#include "mathutil.h"
19#include "utilities.h"
20#include "ResourceManager.h"
21#include "Buffer.h"
22#include "Fence.h"
23#include "Framebuffer.h"
24#include "Program.h"
25#include "Query.h"
26#include "Renderbuffer.h"
27#include "Shader.h"
28#include "Texture.h"
29#include "VertexDataManager.h"
30#include "IndexDataManager.h"
31#include "libEGL/Display.h"
32#include "libEGL/Surface.h"
33#include "Common/Half.hpp"
34
35#include <EGL/eglext.h>
36
37#undef near
38#undef far
39
40namespace es2
41{
42Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)
43	: mConfig(config), clientVersion(clientVersion)
44{
45	sw::Context *context = new sw::Context();
46	device = new es2::Device(context);
47
48    mFenceNameSpace.setBaseHandle(0);
49
50    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
51
52    mState.depthClearValue = 1.0f;
53    mState.stencilClearValue = 0;
54
55    mState.cullFace = false;
56    mState.cullMode = GL_BACK;
57    mState.frontFace = GL_CCW;
58    mState.depthTest = false;
59    mState.depthFunc = GL_LESS;
60    mState.blend = false;
61    mState.sourceBlendRGB = GL_ONE;
62    mState.sourceBlendAlpha = GL_ONE;
63    mState.destBlendRGB = GL_ZERO;
64    mState.destBlendAlpha = GL_ZERO;
65    mState.blendEquationRGB = GL_FUNC_ADD;
66    mState.blendEquationAlpha = GL_FUNC_ADD;
67    mState.blendColor.red = 0;
68    mState.blendColor.green = 0;
69    mState.blendColor.blue = 0;
70    mState.blendColor.alpha = 0;
71    mState.stencilTest = false;
72    mState.stencilFunc = GL_ALWAYS;
73    mState.stencilRef = 0;
74    mState.stencilMask = -1;
75    mState.stencilWritemask = -1;
76    mState.stencilBackFunc = GL_ALWAYS;
77    mState.stencilBackRef = 0;
78    mState.stencilBackMask = - 1;
79    mState.stencilBackWritemask = -1;
80    mState.stencilFail = GL_KEEP;
81    mState.stencilPassDepthFail = GL_KEEP;
82    mState.stencilPassDepthPass = GL_KEEP;
83    mState.stencilBackFail = GL_KEEP;
84    mState.stencilBackPassDepthFail = GL_KEEP;
85    mState.stencilBackPassDepthPass = GL_KEEP;
86    mState.polygonOffsetFill = false;
87    mState.polygonOffsetFactor = 0.0f;
88    mState.polygonOffsetUnits = 0.0f;
89    mState.sampleAlphaToCoverage = false;
90    mState.sampleCoverage = false;
91    mState.sampleCoverageValue = 1.0f;
92    mState.sampleCoverageInvert = false;
93    mState.scissorTest = false;
94    mState.dither = true;
95    mState.primitiveRestartFixedIndex = false;
96    mState.rasterizerDiscard = false;
97    mState.generateMipmapHint = GL_DONT_CARE;
98    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
99
100    mState.lineWidth = 1.0f;
101
102    mState.viewportX = 0;
103    mState.viewportY = 0;
104    mState.viewportWidth = config->mDisplayMode.width;
105    mState.viewportHeight = config->mDisplayMode.height;
106    mState.zNear = 0.0f;
107    mState.zFar = 1.0f;
108
109    mState.scissorX = 0;
110    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 50048
1591		UNIMPLEMENTED();
1592		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
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 50176
1599		UNIMPLEMENTED();
1600		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
1601		break;
1602	case GL_MAX_DRAW_BUFFERS: // integer, at least 8
1603		UNIMPLEMENTED();
1604		*params = IMPLEMENTATION_MAX_DRAW_BUFFERS;
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 = IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
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 = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS;
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 = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT;
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_A8B8G8R8 &&
2601           format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2602        {
2603            memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2604        }
2605		else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2606                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2607        {
2608            for(int i = 0; i < rect.x1 - rect.x0; i++)
2609			{
2610				unsigned int argb = *(unsigned int*)(source + 4 * i);
2611
2612				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
2613			}
2614        }
2615		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2616                format == GL_RGBA && type == GL_UNSIGNED_BYTE)
2617        {
2618            for(int i = 0; i < rect.x1 - rect.x0; i++)
2619			{
2620				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2621
2622				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
2623			}
2624        }
2625		else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 &&
2626                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2627        {
2628            for(int i = 0; i < rect.x1 - rect.x0; i++)
2629			{
2630				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2631
2632				dest32[i] = xrgb | 0xFF000000;
2633			}
2634        }
2635        else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2636                format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2637        {
2638            memcpy(dest, source, (rect.x1 - rect.x0) * 4);
2639        }
2640		else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F &&
2641                format == GL_RGBA && type == GL_HALF_FLOAT_OES)
2642        {
2643            memcpy(dest, source, (rect.x1 - rect.x0) * 8);
2644        }
2645		else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F &&
2646                format == GL_RGBA && type == GL_FLOAT)
2647        {
2648            memcpy(dest, source, (rect.x1 - rect.x0) * 16);
2649        }
2650		else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 &&
2651                format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
2652        {
2653            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2654        }
2655		else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 &&
2656                format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
2657        {
2658            memcpy(dest, source, (rect.x1 - rect.x0) * 2);
2659        }
2660		else
2661		{
2662			for(int i = 0; i < rect.x1 - rect.x0; i++)
2663			{
2664				float r;
2665				float g;
2666				float b;
2667				float a;
2668
2669				switch(renderTarget->getInternalFormat())
2670				{
2671				case sw::FORMAT_R5G6B5:
2672					{
2673						unsigned short rgb = *(unsigned short*)(source + 2 * i);
2674
2675						a = 1.0f;
2676						b = (rgb & 0x001F) * (1.0f / 0x001F);
2677						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2678						r = (rgb & 0xF800) * (1.0f / 0xF800);
2679					}
2680					break;
2681				case sw::FORMAT_A1R5G5B5:
2682					{
2683						unsigned short argb = *(unsigned short*)(source + 2 * i);
2684
2685						a = (argb & 0x8000) ? 1.0f : 0.0f;
2686						b = (argb & 0x001F) * (1.0f / 0x001F);
2687						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2688						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2689					}
2690					break;
2691				case sw::FORMAT_A8R8G8B8:
2692					{
2693						unsigned int argb = *(unsigned int*)(source + 4 * i);
2694
2695						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2696						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2697						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2698						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2699					}
2700					break;
2701				case sw::FORMAT_A8B8G8R8:
2702					{
2703						unsigned int abgr = *(unsigned int*)(source + 4 * i);
2704
2705						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
2706						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2707						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2708						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
2709					}
2710					break;
2711				case sw::FORMAT_X8R8G8B8:
2712					{
2713						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
2714
2715						a = 1.0f;
2716						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2717						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2718						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2719					}
2720					break;
2721				case sw::FORMAT_X8B8G8R8:
2722					{
2723						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
2724
2725						a = 1.0f;
2726						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
2727						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
2728						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
2729					}
2730					break;
2731				case sw::FORMAT_A2R10G10B10:
2732					{
2733						unsigned int argb = *(unsigned int*)(source + 4 * i);
2734
2735						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2736						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2737						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2738						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2739					}
2740					break;
2741				case sw::FORMAT_A32B32G32R32F:
2742					{
2743						r = *((float*)(source + 16 * i) + 0);
2744						g = *((float*)(source + 16 * i) + 1);
2745						b = *((float*)(source + 16 * i) + 2);
2746						a = *((float*)(source + 16 * i) + 3);
2747					}
2748					break;
2749				case sw::FORMAT_A16B16G16R16F:
2750					{
2751						r = (float)*((sw::half*)(source + 8 * i) + 0);
2752						g = (float)*((sw::half*)(source + 8 * i) + 1);
2753						b = (float)*((sw::half*)(source + 8 * i) + 2);
2754						a = (float)*((sw::half*)(source + 8 * i) + 3);
2755					}
2756					break;
2757				default:
2758					UNIMPLEMENTED();   // FIXME
2759					UNREACHABLE();
2760				}
2761
2762				switch(format)
2763				{
2764				case GL_RGBA:
2765					switch(type)
2766					{
2767					case GL_UNSIGNED_BYTE:
2768						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
2769						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2770						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
2771						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2772						break;
2773					default: UNREACHABLE();
2774					}
2775					break;
2776				case GL_BGRA_EXT:
2777					switch(type)
2778					{
2779					case GL_UNSIGNED_BYTE:
2780						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
2781						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
2782						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
2783						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
2784						break;
2785					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2786						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2787						// this type is packed as follows:
2788						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2789						//  --------------------------------------------------------------------------------
2790						// |       4th         |        3rd         |        2nd        |   1st component   |
2791						//  --------------------------------------------------------------------------------
2792						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2793						dest16[i] =
2794							((unsigned short)(15 * a + 0.5f) << 12)|
2795							((unsigned short)(15 * r + 0.5f) << 8) |
2796							((unsigned short)(15 * g + 0.5f) << 4) |
2797							((unsigned short)(15 * b + 0.5f) << 0);
2798						break;
2799					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2800						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2801						// this type is packed as follows:
2802						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2803						//  --------------------------------------------------------------------------------
2804						// | 4th |          3rd           |           2nd          |      1st component     |
2805						//  --------------------------------------------------------------------------------
2806						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2807						dest16[i] =
2808							((unsigned short)(     a + 0.5f) << 15) |
2809							((unsigned short)(31 * r + 0.5f) << 10) |
2810							((unsigned short)(31 * g + 0.5f) << 5) |
2811							((unsigned short)(31 * b + 0.5f) << 0);
2812						break;
2813					default: UNREACHABLE();
2814					}
2815					break;
2816				case GL_RGB:
2817					switch(type)
2818					{
2819					case GL_UNSIGNED_SHORT_5_6_5:
2820						dest16[i] =
2821							((unsigned short)(31 * b + 0.5f) << 0) |
2822							((unsigned short)(63 * g + 0.5f) << 5) |
2823							((unsigned short)(31 * r + 0.5f) << 11);
2824						break;
2825					default: UNREACHABLE();
2826					}
2827					break;
2828				default: UNREACHABLE();
2829				}
2830			}
2831        }
2832
2833		source += inputPitch;
2834		dest += outputPitch;
2835    }
2836
2837	renderTarget->unlock();
2838	renderTarget->release();
2839}
2840
2841void Context::clear(GLbitfield mask)
2842{
2843    Framebuffer *framebuffer = getDrawFramebuffer();
2844
2845    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2846    {
2847        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2848    }
2849
2850    if(!applyRenderTarget())
2851    {
2852        return;
2853    }
2854
2855	unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
2856                         (unorm<8>(mState.colorClearValue.red) << 16) |
2857                         (unorm<8>(mState.colorClearValue.green) << 8) |
2858                         (unorm<8>(mState.colorClearValue.blue) << 0);
2859    float depth = clamp01(mState.depthClearValue);
2860    int stencil = mState.stencilClearValue & 0x000000FF;
2861
2862	if(mask & GL_COLOR_BUFFER_BIT)
2863	{
2864		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2865		                        (mState.colorMaskGreen ? 0x2 : 0) |
2866		                        (mState.colorMaskBlue ? 0x4 : 0) |
2867		                        (mState.colorMaskAlpha ? 0x8 : 0);
2868
2869		if(rgbaMask != 0)
2870		{
2871			device->clearColor(color, rgbaMask);
2872		}
2873	}
2874
2875	if(mask & GL_DEPTH_BUFFER_BIT)
2876	{
2877		if(mState.depthMask != 0)
2878		{
2879			device->clearDepth(depth);
2880		}
2881	}
2882
2883	if(mask & GL_STENCIL_BUFFER_BIT)
2884	{
2885		if(mState.stencilWritemask != 0)
2886		{
2887			device->clearStencil(stencil, mState.stencilWritemask);
2888		}
2889	}
2890}
2891
2892void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2893{
2894    if(!mState.currentProgram)
2895    {
2896        return error(GL_INVALID_OPERATION);
2897    }
2898
2899    PrimitiveType primitiveType;
2900    int primitiveCount;
2901
2902    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2903        return error(GL_INVALID_ENUM);
2904
2905    if(primitiveCount <= 0)
2906    {
2907        return;
2908    }
2909
2910    if(!applyRenderTarget())
2911    {
2912        return;
2913    }
2914
2915    applyState(mode);
2916
2917    GLenum err = applyVertexBuffer(0, first, count);
2918    if(err != GL_NO_ERROR)
2919    {
2920        return error(err);
2921    }
2922
2923    applyShaders();
2924    applyTextures();
2925
2926    if(!getCurrentProgram()->validateSamplers(false))
2927    {
2928        return error(GL_INVALID_OPERATION);
2929    }
2930
2931    if(!cullSkipsDraw(mode))
2932    {
2933        device->drawPrimitive(primitiveType, primitiveCount);
2934    }
2935}
2936
2937void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2938{
2939    if(!mState.currentProgram)
2940    {
2941        return error(GL_INVALID_OPERATION);
2942    }
2943
2944    if(!indices && !mState.elementArrayBuffer)
2945    {
2946        return error(GL_INVALID_OPERATION);
2947    }
2948
2949    PrimitiveType primitiveType;
2950    int primitiveCount;
2951
2952    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2953        return error(GL_INVALID_ENUM);
2954
2955    if(primitiveCount <= 0)
2956    {
2957        return;
2958    }
2959
2960    if(!applyRenderTarget())
2961    {
2962        return;
2963    }
2964
2965    applyState(mode);
2966
2967    TranslatedIndexData indexInfo;
2968    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2969    if(err != GL_NO_ERROR)
2970    {
2971        return error(err);
2972    }
2973
2974    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2975    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2976    if(err != GL_NO_ERROR)
2977    {
2978        return error(err);
2979    }
2980
2981    applyShaders();
2982    applyTextures();
2983
2984    if(!getCurrentProgram()->validateSamplers(false))
2985    {
2986        return error(GL_INVALID_OPERATION);
2987    }
2988
2989    if(!cullSkipsDraw(mode))
2990    {
2991		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2992    }
2993}
2994
2995void Context::finish()
2996{
2997	device->finish();
2998}
2999
3000void Context::flush()
3001{
3002    // We don't queue anything without processing it as fast as possible
3003}
3004
3005void Context::recordInvalidEnum()
3006{
3007    mInvalidEnum = true;
3008}
3009
3010void Context::recordInvalidValue()
3011{
3012    mInvalidValue = true;
3013}
3014
3015void Context::recordInvalidOperation()
3016{
3017    mInvalidOperation = true;
3018}
3019
3020void Context::recordOutOfMemory()
3021{
3022    mOutOfMemory = true;
3023}
3024
3025void Context::recordInvalidFramebufferOperation()
3026{
3027    mInvalidFramebufferOperation = true;
3028}
3029
3030// Get one of the recorded errors and clear its flag, if any.
3031// [OpenGL ES 2.0.24] section 2.5 page 13.
3032GLenum Context::getError()
3033{
3034    if(mInvalidEnum)
3035    {
3036        mInvalidEnum = false;
3037
3038        return GL_INVALID_ENUM;
3039    }
3040
3041    if(mInvalidValue)
3042    {
3043        mInvalidValue = false;
3044
3045        return GL_INVALID_VALUE;
3046    }
3047
3048    if(mInvalidOperation)
3049    {
3050        mInvalidOperation = false;
3051
3052        return GL_INVALID_OPERATION;
3053    }
3054
3055    if(mOutOfMemory)
3056    {
3057        mOutOfMemory = false;
3058
3059        return GL_OUT_OF_MEMORY;
3060    }
3061
3062    if(mInvalidFramebufferOperation)
3063    {
3064        mInvalidFramebufferOperation = false;
3065
3066        return GL_INVALID_FRAMEBUFFER_OPERATION;
3067    }
3068
3069    return GL_NO_ERROR;
3070}
3071
3072int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
3073{
3074    if(requested <= 1)
3075    {
3076        return 1;
3077    }
3078
3079	if(requested == 2)
3080	{
3081		return 2;
3082	}
3083
3084	return 4;
3085}
3086
3087void Context::detachBuffer(GLuint buffer)
3088{
3089    // [OpenGL ES 2.0.24] section 2.9 page 22:
3090    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
3091    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
3092
3093    if(mState.arrayBuffer.name() == buffer)
3094    {
3095        mState.arrayBuffer = NULL;
3096    }
3097
3098    if(mState.elementArrayBuffer.name() == buffer)
3099    {
3100        mState.elementArrayBuffer = NULL;
3101    }
3102
3103    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
3104    {
3105        if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
3106        {
3107            mState.vertexAttribute[attribute].mBoundBuffer = NULL;
3108        }
3109    }
3110}
3111
3112void Context::detachTexture(GLuint texture)
3113{
3114    // [OpenGL ES 2.0.24] section 3.8 page 84:
3115    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
3116    // rebound to texture object zero
3117
3118    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
3119    {
3120        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
3121        {
3122            if(mState.samplerTexture[type][sampler].name() == texture)
3123            {
3124                mState.samplerTexture[type][sampler] = NULL;
3125            }
3126        }
3127    }
3128
3129    // [OpenGL ES 2.0.24] section 4.4 page 112:
3130    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
3131    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
3132    // image was attached in the currently bound framebuffer.
3133
3134    Framebuffer *readFramebuffer = getReadFramebuffer();
3135    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3136
3137    if(readFramebuffer)
3138    {
3139        readFramebuffer->detachTexture(texture);
3140    }
3141
3142    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3143    {
3144        drawFramebuffer->detachTexture(texture);
3145    }
3146}
3147
3148void Context::detachFramebuffer(GLuint framebuffer)
3149{
3150    // [OpenGL ES 2.0.24] section 4.4 page 107:
3151    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
3152    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
3153
3154    if(mState.readFramebuffer == framebuffer)
3155    {
3156        bindReadFramebuffer(0);
3157    }
3158
3159    if(mState.drawFramebuffer == framebuffer)
3160    {
3161        bindDrawFramebuffer(0);
3162    }
3163}
3164
3165void Context::detachRenderbuffer(GLuint renderbuffer)
3166{
3167    // [OpenGL ES 2.0.24] section 4.4 page 109:
3168    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
3169    // had been executed with the target RENDERBUFFER and name of zero.
3170
3171    if(mState.renderbuffer.name() == renderbuffer)
3172    {
3173        bindRenderbuffer(0);
3174    }
3175
3176    // [OpenGL ES 2.0.24] section 4.4 page 111:
3177    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
3178    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
3179    // point to which this image was attached in the currently bound framebuffer.
3180
3181    Framebuffer *readFramebuffer = getReadFramebuffer();
3182    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3183
3184    if(readFramebuffer)
3185    {
3186        readFramebuffer->detachRenderbuffer(renderbuffer);
3187    }
3188
3189    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
3190    {
3191        drawFramebuffer->detachRenderbuffer(renderbuffer);
3192    }
3193}
3194
3195bool Context::cullSkipsDraw(GLenum drawMode)
3196{
3197    return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
3198}
3199
3200bool Context::isTriangleMode(GLenum drawMode)
3201{
3202    switch (drawMode)
3203    {
3204      case GL_TRIANGLES:
3205      case GL_TRIANGLE_FAN:
3206      case GL_TRIANGLE_STRIP:
3207        return true;
3208      case GL_POINTS:
3209      case GL_LINES:
3210      case GL_LINE_LOOP:
3211      case GL_LINE_STRIP:
3212        return false;
3213      default: UNREACHABLE();
3214    }
3215
3216    return false;
3217}
3218
3219void Context::setVertexAttrib(GLuint index, const GLfloat *values)
3220{
3221    ASSERT(index < MAX_VERTEX_ATTRIBS);
3222
3223    mState.vertexAttribute[index].mCurrentValue[0] = values[0];
3224    mState.vertexAttribute[index].mCurrentValue[1] = values[1];
3225    mState.vertexAttribute[index].mCurrentValue[2] = values[2];
3226    mState.vertexAttribute[index].mCurrentValue[3] = values[3];
3227
3228    mVertexDataManager->dirtyCurrentValue(index);
3229}
3230
3231void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
3232                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
3233                              GLbitfield mask)
3234{
3235    Framebuffer *readFramebuffer = getReadFramebuffer();
3236    Framebuffer *drawFramebuffer = getDrawFramebuffer();
3237
3238	int readBufferWidth, readBufferHeight, readBufferSamples;
3239    int drawBufferWidth, drawBufferHeight, drawBufferSamples;
3240
3241    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
3242       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
3243    {
3244        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
3245    }
3246
3247    if(drawBufferSamples > 1)
3248    {
3249        return error(GL_INVALID_OPERATION);
3250    }
3251
3252    sw::SliceRect sourceRect;
3253    sw::SliceRect destRect;
3254	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
3255	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
3256
3257    if(srcX0 < srcX1)
3258    {
3259        sourceRect.x0 = srcX0;
3260        sourceRect.x1 = srcX1;
3261    }
3262    else
3263    {
3264        sourceRect.x0 = srcX1;
3265        sourceRect.x1 = srcX0;
3266    }
3267
3268	if(dstX0 < dstX1)
3269	{
3270		destRect.x0 = dstX0;
3271		destRect.x1 = dstX1;
3272	}
3273	else
3274	{
3275		destRect.x0 = dstX1;
3276		destRect.x1 = dstX0;
3277	}
3278
3279    if(srcY0 < srcY1)
3280    {
3281        sourceRect.y0 = srcY0;
3282        sourceRect.y1 = srcY1;
3283    }
3284    else
3285    {
3286        sourceRect.y0 = srcY1;
3287        sourceRect.y1 = srcY0;
3288    }
3289
3290	if(dstY0 < dstY1)
3291	{
3292		destRect.y0 = dstY0;
3293		destRect.y1 = dstY1;
3294	}
3295	else
3296	{
3297		destRect.y0 = dstY1;
3298		destRect.y1 = dstY0;
3299	}
3300
3301	sw::Rect sourceScissoredRect = sourceRect;
3302    sw::Rect destScissoredRect = destRect;
3303
3304    if(mState.scissorTest)   // Only write to parts of the destination framebuffer which pass the scissor test
3305    {
3306        if(destRect.x0 < mState.scissorX)
3307        {
3308            int xDiff = mState.scissorX - destRect.x0;
3309            destScissoredRect.x0 = mState.scissorX;
3310            sourceScissoredRect.x0 += xDiff;
3311        }
3312
3313        if(destRect.x1 > mState.scissorX + mState.scissorWidth)
3314        {
3315            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
3316            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
3317            sourceScissoredRect.x1 -= xDiff;
3318        }
3319
3320        if(destRect.y0 < mState.scissorY)
3321        {
3322            int yDiff = mState.scissorY - destRect.y0;
3323            destScissoredRect.y0 = mState.scissorY;
3324            sourceScissoredRect.y0 += yDiff;
3325        }
3326
3327        if(destRect.y1 > mState.scissorY + mState.scissorHeight)
3328        {
3329            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
3330            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
3331            sourceScissoredRect.y1 -= yDiff;
3332        }
3333    }
3334
3335    sw::Rect sourceTrimmedRect = sourceScissoredRect;
3336    sw::Rect destTrimmedRect = destScissoredRect;
3337
3338    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
3339    // the actual draw and read surfaces.
3340    if(sourceTrimmedRect.x0 < 0)
3341    {
3342        int xDiff = 0 - sourceTrimmedRect.x0;
3343        sourceTrimmedRect.x0 = 0;
3344        destTrimmedRect.x0 += xDiff;
3345    }
3346
3347    if(sourceTrimmedRect.x1 > readBufferWidth)
3348    {
3349        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
3350        sourceTrimmedRect.x1 = readBufferWidth;
3351        destTrimmedRect.x1 -= xDiff;
3352    }
3353
3354    if(sourceTrimmedRect.y0 < 0)
3355    {
3356        int yDiff = 0 - sourceTrimmedRect.y0;
3357        sourceTrimmedRect.y0 = 0;
3358        destTrimmedRect.y0 += yDiff;
3359    }
3360
3361    if(sourceTrimmedRect.y1 > readBufferHeight)
3362    {
3363        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
3364        sourceTrimmedRect.y1 = readBufferHeight;
3365        destTrimmedRect.y1 -= yDiff;
3366    }
3367
3368    if(destTrimmedRect.x0 < 0)
3369    {
3370        int xDiff = 0 - destTrimmedRect.x0;
3371        destTrimmedRect.x0 = 0;
3372        sourceTrimmedRect.x0 += xDiff;
3373    }
3374
3375    if(destTrimmedRect.x1 > drawBufferWidth)
3376    {
3377        int xDiff = destTrimmedRect.x1 - drawBufferWidth;
3378        destTrimmedRect.x1 = drawBufferWidth;
3379        sourceTrimmedRect.x1 -= xDiff;
3380    }
3381
3382    if(destTrimmedRect.y0 < 0)
3383    {
3384        int yDiff = 0 - destTrimmedRect.y0;
3385        destTrimmedRect.y0 = 0;
3386        sourceTrimmedRect.y0 += yDiff;
3387    }
3388
3389    if(destTrimmedRect.y1 > drawBufferHeight)
3390    {
3391        int yDiff = destTrimmedRect.y1 - drawBufferHeight;
3392        destTrimmedRect.y1 = drawBufferHeight;
3393        sourceTrimmedRect.y1 -= yDiff;
3394    }
3395
3396    bool partialBufferCopy = false;
3397
3398    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
3399       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
3400       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
3401       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
3402       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
3403    {
3404        partialBufferCopy = true;
3405    }
3406
3407	bool blitRenderTarget = false;
3408    bool blitDepthStencil = false;
3409
3410    if(mask & GL_COLOR_BUFFER_BIT)
3411    {
3412        const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
3413                                   readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
3414        const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
3415                                   drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
3416        if(!validReadType || !validDrawType)
3417        {
3418            return error(GL_INVALID_OPERATION);
3419        }
3420
3421        if(partialBufferCopy && readBufferSamples > 1)
3422        {
3423            return error(GL_INVALID_OPERATION);
3424        }
3425
3426        blitRenderTarget = true;
3427    }
3428
3429    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
3430    {
3431        Renderbuffer *readDSBuffer = NULL;
3432        Renderbuffer *drawDSBuffer = NULL;
3433
3434        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
3435        // both a depth and stencil buffer, it will be the same buffer.
3436
3437        if(mask & GL_DEPTH_BUFFER_BIT)
3438        {
3439            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
3440            {
3441                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
3442                {
3443                    return error(GL_INVALID_OPERATION);
3444                }
3445
3446                blitDepthStencil = true;
3447                readDSBuffer = readFramebuffer->getDepthbuffer();
3448                drawDSBuffer = drawFramebuffer->getDepthbuffer();
3449            }
3450        }
3451
3452        if(mask & GL_STENCIL_BUFFER_BIT)
3453        {
3454            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
3455            {
3456                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
3457                {
3458                    return error(GL_INVALID_OPERATION);
3459                }
3460
3461                blitDepthStencil = true;
3462                readDSBuffer = readFramebuffer->getStencilbuffer();
3463                drawDSBuffer = drawFramebuffer->getStencilbuffer();
3464            }
3465        }
3466
3467        if(partialBufferCopy)
3468        {
3469            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
3470            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
3471        }
3472
3473        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
3474           (readDSBuffer && readDSBuffer->getSamples() > 1))
3475        {
3476            return error(GL_INVALID_OPERATION);
3477        }
3478    }
3479
3480    if(blitRenderTarget || blitDepthStencil)
3481    {
3482        if(blitRenderTarget)
3483        {
3484            egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
3485            egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
3486
3487			if(flipX)
3488			{
3489				swap(destRect.x0, destRect.x1);
3490			}
3491			if(flipy)
3492			{
3493				swap(destRect.y0, destRect.y1);
3494			}
3495
3496            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
3497
3498            readRenderTarget->release();
3499            drawRenderTarget->release();
3500
3501            if(!success)
3502            {
3503                ERR("BlitFramebuffer failed.");
3504                return;
3505            }
3506        }
3507
3508        if(blitDepthStencil)
3509        {
3510            bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false);
3511
3512            if(!success)
3513            {
3514                ERR("BlitFramebuffer failed.");
3515                return;
3516            }
3517        }
3518    }
3519}
3520
3521void Context::bindTexImage(egl::Surface *surface)
3522{
3523	es2::Texture2D *textureObject = getTexture2D();
3524
3525    if(textureObject)
3526    {
3527		textureObject->bindTexImage(surface);
3528	}
3529}
3530
3531EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3532{
3533    GLenum textureTarget = GL_NONE;
3534
3535    switch(target)
3536    {
3537    case EGL_GL_TEXTURE_2D_KHR:
3538        textureTarget = GL_TEXTURE_2D;
3539        break;
3540    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
3541    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
3542    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
3543    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
3544    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
3545    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
3546        textureTarget = GL_TEXTURE_CUBE_MAP;
3547        break;
3548    case EGL_GL_RENDERBUFFER_KHR:
3549        break;
3550    #if defined(__ANDROID__)
3551    case EGL_NATIVE_BUFFER_ANDROID:
3552        break;
3553    #endif
3554    default:
3555        return EGL_BAD_PARAMETER;
3556    }
3557
3558    if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3559    {
3560        return EGL_BAD_MATCH;
3561    }
3562
3563    if(textureTarget != GL_NONE)
3564    {
3565        es2::Texture *texture = getTexture(name);
3566
3567        if(!texture || texture->getTarget() != textureTarget)
3568        {
3569            return EGL_BAD_PARAMETER;
3570        }
3571
3572        if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
3573        {
3574            return EGL_BAD_ACCESS;
3575        }
3576
3577        if(textureLevel != 0 && !texture->isSamplerComplete())
3578        {
3579            return EGL_BAD_PARAMETER;
3580        }
3581
3582        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
3583        {
3584            return EGL_BAD_PARAMETER;
3585        }
3586    }
3587    else if(target == EGL_GL_RENDERBUFFER_KHR)
3588    {
3589        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3590
3591        if(!renderbuffer)
3592        {
3593            return EGL_BAD_PARAMETER;
3594        }
3595
3596        if(renderbuffer->isShared())   // Already an EGLImage sibling
3597        {
3598            return EGL_BAD_ACCESS;
3599        }
3600    }
3601    #if defined(__ANDROID__)
3602    else if(target == EGL_NATIVE_BUFFER_ANDROID)
3603    {
3604        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
3605
3606		if(nativeBuffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC)
3607        {
3608            return EGL_BAD_PARAMETER;
3609        }
3610
3611        if(nativeBuffer->common.version != sizeof(ANativeWindowBuffer))
3612        {
3613            return EGL_BAD_PARAMETER;
3614        }
3615
3616        switch(nativeBuffer->format)
3617		{
3618        case HAL_PIXEL_FORMAT_RGBA_8888:
3619        case HAL_PIXEL_FORMAT_RGBX_8888:
3620        case HAL_PIXEL_FORMAT_RGB_565:
3621            break;
3622        default:
3623            return EGL_BAD_PARAMETER;
3624        }
3625    }
3626    #endif
3627    else UNREACHABLE();
3628
3629	return EGL_SUCCESS;
3630}
3631
3632egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3633{
3634	GLenum textureTarget = GL_NONE;
3635
3636    switch(target)
3637    {
3638    case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
3639    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
3640    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
3641    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
3642    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
3643    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
3644    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
3645    }
3646
3647    if(textureTarget != GL_NONE)
3648    {
3649        es2::Texture *texture = getTexture(name);
3650
3651        return texture->createSharedImage(textureTarget, textureLevel);
3652    }
3653    else if(target == EGL_GL_RENDERBUFFER_KHR)
3654    {
3655        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3656
3657        return renderbuffer->createSharedImage();
3658    }
3659    #if defined(__ANDROID__)
3660    else if(target == EGL_NATIVE_BUFFER_ANDROID)
3661    {
3662        ANativeWindowBuffer *nativeBuffer = reinterpret_cast<ANativeWindowBuffer*>(name);
3663        nativeBuffer->common.incRef(&nativeBuffer->common);
3664
3665        GLenum format = Image::getColorFormatFromAndroid(nativeBuffer->format);
3666        GLenum type = Image::getPixelFormatFromAndroid(nativeBuffer->format);
3667
3668        es2::Image *image = new Image(0, nativeBuffer->width, nativeBuffer->height, format, type);
3669        image->setNativeBuffer(nativeBuffer);
3670        image->markShared();
3671
3672        return image;
3673    }
3674    #endif
3675    else UNREACHABLE();
3676
3677	return 0;
3678}
3679
3680Device *Context::getDevice()
3681{
3682	return device;
3683}
3684
3685}
3686
3687// Exported functions for use by EGL
3688extern "C"
3689{
3690	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion)
3691	{
3692		return new es2::Context(config, shareContext, clientVersion);
3693	}
3694}
3695