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