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