Context.cpp revision 2265824443967db3003a2a875f75d3ec6d8fad96
1// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12// Context.cpp: Implements the es2::Context class, managing all GL state and performing
13// rendering operations. It is the GLES2 specific implementation of EGLContext.
14
15#include "Context.h"
16
17#include "main.h"
18#include "mathutil.h"
19#include "utilities.h"
20#include "ResourceManager.h"
21#include "Buffer.h"
22#include "Fence.h"
23#include "Framebuffer.h"
24#include "Program.h"
25#include "Query.h"
26#include "Renderbuffer.h"
27#include "Shader.h"
28#include "Texture.h"
29#include "VertexDataManager.h"
30#include "IndexDataManager.h"
31#include "libEGL/Display.h"
32#include "libEGL/Surface.h"
33#include "Common/Half.hpp"
34
35#include <EGL/eglext.h>
36
37#undef near
38#undef far
39
40namespace es2
41{
42Context::Context(const egl::Config *config, const Context *shareContext) : mConfig(config)
43{
44	sw::Context *context = new sw::Context();
45	device = new es2::Device(context);
46
47    mFenceHandleAllocator.setBaseHandle(0);
48
49    setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
50
51    mState.depthClearValue = 1.0f;
52    mState.stencilClearValue = 0;
53
54    mState.cullFace = false;
55    mState.cullMode = GL_BACK;
56    mState.frontFace = GL_CCW;
57    mState.depthTest = false;
58    mState.depthFunc = GL_LESS;
59    mState.blend = false;
60    mState.sourceBlendRGB = GL_ONE;
61    mState.sourceBlendAlpha = GL_ONE;
62    mState.destBlendRGB = GL_ZERO;
63    mState.destBlendAlpha = GL_ZERO;
64    mState.blendEquationRGB = GL_FUNC_ADD;
65    mState.blendEquationAlpha = GL_FUNC_ADD;
66    mState.blendColor.red = 0;
67    mState.blendColor.green = 0;
68    mState.blendColor.blue = 0;
69    mState.blendColor.alpha = 0;
70    mState.stencilTest = false;
71    mState.stencilFunc = GL_ALWAYS;
72    mState.stencilRef = 0;
73    mState.stencilMask = -1;
74    mState.stencilWritemask = -1;
75    mState.stencilBackFunc = GL_ALWAYS;
76    mState.stencilBackRef = 0;
77    mState.stencilBackMask = - 1;
78    mState.stencilBackWritemask = -1;
79    mState.stencilFail = GL_KEEP;
80    mState.stencilPassDepthFail = GL_KEEP;
81    mState.stencilPassDepthPass = GL_KEEP;
82    mState.stencilBackFail = GL_KEEP;
83    mState.stencilBackPassDepthFail = GL_KEEP;
84    mState.stencilBackPassDepthPass = GL_KEEP;
85    mState.polygonOffsetFill = false;
86    mState.polygonOffsetFactor = 0.0f;
87    mState.polygonOffsetUnits = 0.0f;
88    mState.sampleAlphaToCoverage = false;
89    mState.sampleCoverage = false;
90    mState.sampleCoverageValue = 1.0f;
91    mState.sampleCoverageInvert = false;
92    mState.scissorTest = false;
93    mState.dither = true;
94    mState.generateMipmapHint = GL_DONT_CARE;
95    mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
96
97    mState.lineWidth = 1.0f;
98
99    mState.viewportX = 0;
100    mState.viewportY = 0;
101    mState.viewportWidth = config->mDisplayMode.width;
102    mState.viewportHeight = config->mDisplayMode.height;
103    mState.zNear = 0.0f;
104    mState.zFar = 1.0f;
105
106    mState.scissorX = 0;
107    mState.scissorY = 0;
108    mState.scissorWidth = config->mDisplayMode.width;
109    mState.scissorHeight = config->mDisplayMode.height;
110
111    mState.colorMaskRed = true;
112    mState.colorMaskGreen = true;
113    mState.colorMaskBlue = true;
114    mState.colorMaskAlpha = true;
115    mState.depthMask = true;
116
117    if(shareContext != NULL)
118    {
119        mResourceManager = shareContext->mResourceManager;
120        mResourceManager->addRef();
121    }
122    else
123    {
124        mResourceManager = new ResourceManager();
125    }
126
127    // [OpenGL ES 2.0.24] section 3.7 page 83:
128    // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
129    // and cube map texture state vectors respectively associated with them.
130    // In order that access to these initial textures not be lost, they are treated as texture
131    // objects all of whose names are 0.
132
133    mTexture2DZero.set(new Texture2D(0));
134    mTextureCubeMapZero.set(new TextureCubeMap(0));
135    mTextureExternalZero.set(new TextureExternal(0));
136
137    mState.activeSampler = 0;
138    bindArrayBuffer(0);
139    bindElementArrayBuffer(0);
140    bindTextureCubeMap(0);
141    bindTexture2D(0);
142    bindReadFramebuffer(0);
143    bindDrawFramebuffer(0);
144    bindRenderbuffer(0);
145
146    mState.currentProgram = 0;
147
148    mState.packAlignment = 4;
149    mState.unpackAlignment = 4;
150
151    mVertexDataManager = NULL;
152    mIndexDataManager = NULL;
153
154    mInvalidEnum = false;
155    mInvalidValue = false;
156    mInvalidOperation = false;
157    mOutOfMemory = false;
158    mInvalidFramebufferOperation = false;
159
160    mHasBeenCurrent = false;
161
162    markAllStateDirty();
163}
164
165Context::~Context()
166{
167    if(mState.currentProgram != 0)
168    {
169        Program *programObject = mResourceManager->getProgram(mState.currentProgram);
170        if(programObject)
171        {
172            programObject->release();
173        }
174        mState.currentProgram = 0;
175    }
176
177    while(!mFramebufferMap.empty())
178    {
179        deleteFramebuffer(mFramebufferMap.begin()->first);
180    }
181
182    while(!mFenceMap.empty())
183    {
184        deleteFence(mFenceMap.begin()->first);
185    }
186
187	while(!mQueryMap.empty())
188    {
189        deleteQuery(mQueryMap.begin()->first);
190    }
191
192    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
193    {
194        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
195        {
196            mState.samplerTexture[type][sampler].set(NULL);
197        }
198    }
199
200    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
201    {
202        mState.vertexAttribute[i].mBoundBuffer.set(NULL);
203    }
204
205	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
206    {
207        mState.activeQuery[i].set(NULL);
208    }
209
210    mState.arrayBuffer.set(NULL);
211    mState.elementArrayBuffer.set(NULL);
212    mState.renderbuffer.set(NULL);
213
214    mTexture2DZero.set(NULL);
215    mTextureCubeMapZero.set(NULL);
216    mTextureExternalZero.set(NULL);
217
218    delete mVertexDataManager;
219    delete mIndexDataManager;
220
221    mResourceManager->release();
222	delete device;
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:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;
1329	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;
1330    case GL_SAMPLE_BUFFERS:
1331    case GL_SAMPLES:
1332        {
1333            Framebuffer *framebuffer = getDrawFramebuffer();
1334			int width, height, samples;
1335
1336            if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
1337            {
1338                switch(pname)
1339                {
1340                case GL_SAMPLE_BUFFERS:
1341                    if(samples > 1)
1342                    {
1343                        *params = 1;
1344                    }
1345                    else
1346                    {
1347                        *params = 0;
1348                    }
1349                    break;
1350                case GL_SAMPLES:
1351                    *params = samples & ~1;
1352                    break;
1353                }
1354            }
1355            else
1356            {
1357                *params = 0;
1358            }
1359        }
1360        break;
1361    case GL_IMPLEMENTATION_COLOR_READ_TYPE:   *params = IMPLEMENTATION_COLOR_READ_TYPE;   break;
1362    case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break;
1363    case GL_MAX_VIEWPORT_DIMS:
1364        {
1365			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
1366            params[0] = maxDimension;
1367            params[1] = maxDimension;
1368        }
1369        break;
1370    case GL_COMPRESSED_TEXTURE_FORMATS:
1371        {
1372			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
1373            {
1374                params[i] = compressedTextureFormats[i];
1375            }
1376        }
1377        break;
1378    case GL_VIEWPORT:
1379        params[0] = mState.viewportX;
1380        params[1] = mState.viewportY;
1381        params[2] = mState.viewportWidth;
1382        params[3] = mState.viewportHeight;
1383        break;
1384    case GL_SCISSOR_BOX:
1385        params[0] = mState.scissorX;
1386        params[1] = mState.scissorY;
1387        params[2] = mState.scissorWidth;
1388        params[3] = mState.scissorHeight;
1389        break;
1390    case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
1391    case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
1392    case GL_RED_BITS:
1393    case GL_GREEN_BITS:
1394    case GL_BLUE_BITS:
1395    case GL_ALPHA_BITS:
1396        {
1397            Framebuffer *framebuffer = getDrawFramebuffer();
1398            Renderbuffer *colorbuffer = framebuffer->getColorbuffer();
1399
1400            if(colorbuffer)
1401            {
1402                switch (pname)
1403                {
1404                  case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
1405                  case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
1406                  case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
1407                  case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
1408                }
1409            }
1410            else
1411            {
1412                *params = 0;
1413            }
1414        }
1415        break;
1416    case GL_DEPTH_BITS:
1417        {
1418            Framebuffer *framebuffer = getDrawFramebuffer();
1419            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1420
1421            if(depthbuffer)
1422            {
1423                *params = depthbuffer->getDepthSize();
1424            }
1425            else
1426            {
1427                *params = 0;
1428            }
1429        }
1430        break;
1431    case GL_STENCIL_BITS:
1432        {
1433            Framebuffer *framebuffer = getDrawFramebuffer();
1434            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1435
1436            if(stencilbuffer)
1437            {
1438                *params = stencilbuffer->getStencilSize();
1439            }
1440            else
1441            {
1442                *params = 0;
1443            }
1444        }
1445        break;
1446    case GL_TEXTURE_BINDING_2D:
1447        {
1448            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1449            {
1450                error(GL_INVALID_OPERATION);
1451                return false;
1452            }
1453
1454            *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].id();
1455        }
1456        break;
1457    case GL_TEXTURE_BINDING_CUBE_MAP:
1458        {
1459            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1460            {
1461                error(GL_INVALID_OPERATION);
1462                return false;
1463            }
1464
1465            *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].id();
1466        }
1467        break;
1468    case GL_TEXTURE_BINDING_EXTERNAL_OES:
1469        {
1470            if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
1471            {
1472                error(GL_INVALID_OPERATION);
1473                return false;
1474            }
1475
1476            *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].id();
1477        }
1478        break;
1479    default:
1480        return false;
1481    }
1482
1483    return true;
1484}
1485
1486bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams)
1487{
1488    // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
1489    // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
1490    // to the fact that it is stored internally as a float, and so would require conversion
1491    // if returned from Context::getIntegerv. Since this conversion is already implemented
1492    // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
1493    // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
1494    // application.
1495    switch (pname)
1496    {
1497      case GL_COMPRESSED_TEXTURE_FORMATS:
1498		{
1499            *type = GL_INT;
1500			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
1501        }
1502		break;
1503      case GL_SHADER_BINARY_FORMATS:
1504        {
1505            *type = GL_INT;
1506            *numParams = 0;
1507        }
1508        break;
1509      case GL_MAX_VERTEX_ATTRIBS:
1510      case GL_MAX_VERTEX_UNIFORM_VECTORS:
1511      case GL_MAX_VARYING_VECTORS:
1512      case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
1513      case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
1514      case GL_MAX_TEXTURE_IMAGE_UNITS:
1515      case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
1516      case GL_MAX_RENDERBUFFER_SIZE:
1517      case GL_NUM_SHADER_BINARY_FORMATS:
1518      case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
1519      case GL_ARRAY_BUFFER_BINDING:
1520      case GL_FRAMEBUFFER_BINDING:
1521      case GL_RENDERBUFFER_BINDING:
1522      case GL_CURRENT_PROGRAM:
1523      case GL_PACK_ALIGNMENT:
1524      case GL_UNPACK_ALIGNMENT:
1525      case GL_GENERATE_MIPMAP_HINT:
1526      case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1527      case GL_RED_BITS:
1528      case GL_GREEN_BITS:
1529      case GL_BLUE_BITS:
1530      case GL_ALPHA_BITS:
1531      case GL_DEPTH_BITS:
1532      case GL_STENCIL_BITS:
1533      case GL_ELEMENT_ARRAY_BUFFER_BINDING:
1534      case GL_CULL_FACE_MODE:
1535      case GL_FRONT_FACE:
1536      case GL_ACTIVE_TEXTURE:
1537      case GL_STENCIL_FUNC:
1538      case GL_STENCIL_VALUE_MASK:
1539      case GL_STENCIL_REF:
1540      case GL_STENCIL_FAIL:
1541      case GL_STENCIL_PASS_DEPTH_FAIL:
1542      case GL_STENCIL_PASS_DEPTH_PASS:
1543      case GL_STENCIL_BACK_FUNC:
1544      case GL_STENCIL_BACK_VALUE_MASK:
1545      case GL_STENCIL_BACK_REF:
1546      case GL_STENCIL_BACK_FAIL:
1547      case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1548      case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1549      case GL_DEPTH_FUNC:
1550      case GL_BLEND_SRC_RGB:
1551      case GL_BLEND_SRC_ALPHA:
1552      case GL_BLEND_DST_RGB:
1553      case GL_BLEND_DST_ALPHA:
1554      case GL_BLEND_EQUATION_RGB:
1555      case GL_BLEND_EQUATION_ALPHA:
1556      case GL_STENCIL_WRITEMASK:
1557      case GL_STENCIL_BACK_WRITEMASK:
1558      case GL_STENCIL_CLEAR_VALUE:
1559      case GL_SUBPIXEL_BITS:
1560      case GL_MAX_TEXTURE_SIZE:
1561      case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
1562      case GL_SAMPLE_BUFFERS:
1563      case GL_SAMPLES:
1564      case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1565      case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1566      case GL_TEXTURE_BINDING_2D:
1567      case GL_TEXTURE_BINDING_CUBE_MAP:
1568      case GL_TEXTURE_BINDING_EXTERNAL_OES:
1569        {
1570            *type = GL_INT;
1571            *numParams = 1;
1572        }
1573        break;
1574      case GL_MAX_SAMPLES_ANGLE:
1575        {
1576            *type = GL_INT;
1577            *numParams = 1;
1578        }
1579        break;
1580      case GL_MAX_VIEWPORT_DIMS:
1581        {
1582            *type = GL_INT;
1583            *numParams = 2;
1584        }
1585        break;
1586      case GL_VIEWPORT:
1587      case GL_SCISSOR_BOX:
1588        {
1589            *type = GL_INT;
1590            *numParams = 4;
1591        }
1592        break;
1593      case GL_SHADER_COMPILER:
1594      case GL_SAMPLE_COVERAGE_INVERT:
1595      case GL_DEPTH_WRITEMASK:
1596      case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
1597      case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
1598      case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
1599      case GL_SAMPLE_COVERAGE:
1600      case GL_SCISSOR_TEST:
1601      case GL_STENCIL_TEST:
1602      case GL_DEPTH_TEST:
1603      case GL_BLEND:
1604      case GL_DITHER:
1605        {
1606            *type = GL_BOOL;
1607            *numParams = 1;
1608        }
1609        break;
1610      case GL_COLOR_WRITEMASK:
1611        {
1612            *type = GL_BOOL;
1613            *numParams = 4;
1614        }
1615        break;
1616      case GL_POLYGON_OFFSET_FACTOR:
1617      case GL_POLYGON_OFFSET_UNITS:
1618      case GL_SAMPLE_COVERAGE_VALUE:
1619      case GL_DEPTH_CLEAR_VALUE:
1620      case GL_LINE_WIDTH:
1621        {
1622            *type = GL_FLOAT;
1623            *numParams = 1;
1624        }
1625        break;
1626      case GL_ALIASED_LINE_WIDTH_RANGE:
1627      case GL_ALIASED_POINT_SIZE_RANGE:
1628      case GL_DEPTH_RANGE:
1629        {
1630            *type = GL_FLOAT;
1631            *numParams = 2;
1632        }
1633        break;
1634      case GL_COLOR_CLEAR_VALUE:
1635      case GL_BLEND_COLOR:
1636        {
1637            *type = GL_FLOAT;
1638            *numParams = 4;
1639        }
1640        break;
1641	  case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
1642        *type = GL_FLOAT;
1643        *numParams = 1;
1644        break;
1645      default:
1646        return false;
1647    }
1648
1649    return true;
1650}
1651
1652// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
1653bool Context::applyRenderTarget()
1654{
1655    Framebuffer *framebuffer = getDrawFramebuffer();
1656	int width, height, samples;
1657
1658    if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
1659    {
1660        return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
1661    }
1662
1663    egl::Image *renderTarget = framebuffer->getRenderTarget();
1664	device->setRenderTarget(renderTarget);
1665	if(renderTarget) renderTarget->release();
1666
1667    egl::Image *depthStencil = framebuffer->getDepthStencil();
1668    device->setDepthStencilSurface(depthStencil);
1669	if(depthStencil) depthStencil->release();
1670
1671    Viewport viewport;
1672    float zNear = clamp01(mState.zNear);
1673    float zFar = clamp01(mState.zFar);
1674
1675    viewport.x0 = mState.viewportX;
1676    viewport.y0 = mState.viewportY;
1677    viewport.width = mState.viewportWidth;
1678    viewport.height = mState.viewportHeight;
1679    viewport.minZ = zNear;
1680    viewport.maxZ = zFar;
1681
1682    device->setViewport(viewport);
1683
1684    if(mState.scissorTest)
1685    {
1686		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
1687		scissor.clip(0, 0, width, height);
1688
1689		device->setScissorRect(scissor);
1690        device->setScissorEnable(true);
1691    }
1692    else
1693    {
1694        device->setScissorEnable(false);
1695    }
1696
1697	Program *program = getCurrentProgram();
1698
1699	if(program)
1700	{
1701		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
1702        program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
1703		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
1704		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
1705    }
1706
1707    return true;
1708}
1709
1710// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
1711void Context::applyState(GLenum drawMode)
1712{
1713    Framebuffer *framebuffer = getDrawFramebuffer();
1714
1715    if(mState.cullFace)
1716    {
1717        device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
1718    }
1719    else
1720    {
1721		device->setCullMode(sw::CULL_NONE);
1722    }
1723
1724    if(mDepthStateDirty)
1725    {
1726        if(mState.depthTest)
1727        {
1728			device->setDepthBufferEnable(true);
1729			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
1730        }
1731        else
1732        {
1733            device->setDepthBufferEnable(false);
1734        }
1735
1736        mDepthStateDirty = false;
1737    }
1738
1739    if(mBlendStateDirty)
1740    {
1741        if(mState.blend)
1742        {
1743			device->setAlphaBlendEnable(true);
1744			device->setSeparateAlphaBlendEnable(true);
1745
1746            device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
1747
1748			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
1749			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
1750			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
1751
1752            device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
1753			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
1754			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
1755        }
1756        else
1757        {
1758			device->setAlphaBlendEnable(false);
1759        }
1760
1761        mBlendStateDirty = false;
1762    }
1763
1764    if(mStencilStateDirty || mFrontFaceDirty)
1765    {
1766        if(mState.stencilTest && framebuffer->hasStencil())
1767        {
1768			device->setStencilEnable(true);
1769			device->setTwoSidedStencil(true);
1770
1771            if(mState.stencilWritemask != mState.stencilBackWritemask ||
1772               mState.stencilRef != mState.stencilBackRef ||
1773               mState.stencilMask != mState.stencilBackMask)
1774            {
1775				ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL.");
1776                return error(GL_INVALID_OPERATION);
1777            }
1778
1779            // get the maximum size of the stencil ref
1780            Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
1781            GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
1782
1783			if(mState.frontFace == GL_CCW)
1784			{
1785				device->setStencilWriteMask(mState.stencilWritemask);
1786				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
1787
1788				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1789				device->setStencilMask(mState.stencilMask);
1790
1791				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
1792				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1793				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1794
1795				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
1796				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1797
1798				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1799				device->setStencilMaskCCW(mState.stencilBackMask);
1800
1801				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
1802				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1803				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1804			}
1805			else
1806			{
1807				device->setStencilWriteMaskCCW(mState.stencilWritemask);
1808				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
1809
1810				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
1811				device->setStencilMaskCCW(mState.stencilMask);
1812
1813				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
1814				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
1815				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
1816
1817				device->setStencilWriteMask(mState.stencilBackWritemask);
1818				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
1819
1820				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
1821				device->setStencilMask(mState.stencilBackMask);
1822
1823				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
1824				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
1825				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
1826			}
1827        }
1828        else
1829        {
1830			device->setStencilEnable(false);
1831        }
1832
1833        mStencilStateDirty = false;
1834        mFrontFaceDirty = false;
1835    }
1836
1837    if(mMaskStateDirty)
1838    {
1839		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
1840		device->setDepthWriteEnable(mState.depthMask);
1841
1842        mMaskStateDirty = false;
1843    }
1844
1845    if(mPolygonOffsetStateDirty)
1846    {
1847        if(mState.polygonOffsetFill)
1848        {
1849            Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
1850            if(depthbuffer)
1851            {
1852				device->setSlopeDepthBias(mState.polygonOffsetFactor);
1853                float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
1854				device->setDepthBias(depthBias);
1855            }
1856        }
1857        else
1858        {
1859            device->setSlopeDepthBias(0);
1860            device->setDepthBias(0);
1861        }
1862
1863        mPolygonOffsetStateDirty = false;
1864    }
1865
1866    if(mSampleStateDirty)
1867    {
1868        if(mState.sampleAlphaToCoverage)
1869        {
1870            device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
1871        }
1872		else
1873		{
1874			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
1875		}
1876
1877        if(mState.sampleCoverage)
1878        {
1879            unsigned int mask = 0;
1880            if(mState.sampleCoverageValue != 0)
1881            {
1882				int width, height, samples;
1883				framebuffer->completeness(width, height, samples);
1884
1885                float threshold = 0.5f;
1886
1887                for(int i = 0; i < samples; i++)
1888                {
1889                    mask <<= 1;
1890
1891                    if((i + 1) * mState.sampleCoverageValue >= threshold)
1892                    {
1893                        threshold += 1.0f;
1894                        mask |= 1;
1895                    }
1896                }
1897            }
1898
1899            if(mState.sampleCoverageInvert)
1900            {
1901                mask = ~mask;
1902            }
1903
1904			device->setMultiSampleMask(mask);
1905        }
1906        else
1907        {
1908			device->setMultiSampleMask(0xFFFFFFFF);
1909        }
1910
1911        mSampleStateDirty = false;
1912    }
1913
1914    if(mDitherStateDirty)
1915    {
1916    //	UNIMPLEMENTED();   // FIXME
1917
1918        mDitherStateDirty = false;
1919    }
1920}
1921
1922GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
1923{
1924    TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
1925
1926    GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
1927    if(err != GL_NO_ERROR)
1928    {
1929        return err;
1930    }
1931
1932	Program *program = getCurrentProgram();
1933
1934	device->resetInputStreams(false);
1935
1936    for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
1937	{
1938		if(program->getAttributeStream(i) == -1)
1939		{
1940			continue;
1941		}
1942
1943		sw::Resource *resource = attributes[i].vertexBuffer;
1944		const void *buffer = (char*)resource->getBuffer() + attributes[i].offset;
1945
1946		int stride = attributes[i].stride;
1947
1948		buffer = (char*)buffer + stride * base;
1949
1950		sw::Stream attribute(resource, buffer, stride);
1951
1952		attribute.type = attributes[i].type;
1953		attribute.count = attributes[i].count;
1954		attribute.normalized = attributes[i].normalized;
1955
1956		int stream = program->getAttributeStream(i);
1957		device->setInputStream(stream, attribute);
1958	}
1959
1960	return GL_NO_ERROR;
1961}
1962
1963// Applies the indices and element array bindings
1964GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
1965{
1966    GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
1967
1968    if(err == GL_NO_ERROR)
1969    {
1970        device->setIndexBuffer(indexInfo->indexBuffer);
1971    }
1972
1973    return err;
1974}
1975
1976// Applies the shaders and shader constants
1977void Context::applyShaders()
1978{
1979    Program *programObject = getCurrentProgram();
1980    sw::VertexShader *vertexShader = programObject->getVertexShader();
1981	sw::PixelShader *pixelShader = programObject->getPixelShader();
1982
1983    device->setVertexShader(vertexShader);
1984    device->setPixelShader(pixelShader);
1985
1986    if(programObject->getSerial() != mAppliedProgramSerial)
1987    {
1988        programObject->dirtyAllUniforms();
1989        mAppliedProgramSerial = programObject->getSerial();
1990    }
1991
1992    programObject->applyUniforms();
1993}
1994
1995void Context::applyTextures()
1996{
1997    applyTextures(sw::SAMPLER_PIXEL);
1998	applyTextures(sw::SAMPLER_VERTEX);
1999}
2000
2001void Context::applyTextures(sw::SamplerType samplerType)
2002{
2003    Program *programObject = getCurrentProgram();
2004
2005    int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
2006
2007    for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
2008    {
2009        int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
2010
2011        if(textureUnit != -1)
2012        {
2013            TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
2014
2015            Texture *texture = getSamplerTexture(textureUnit, textureType);
2016
2017			if(texture->isSamplerComplete())
2018            {
2019                GLenum wrapS = texture->getWrapS();
2020                GLenum wrapT = texture->getWrapT();
2021                GLenum texFilter = texture->getMinFilter();
2022                GLenum magFilter = texture->getMagFilter();
2023				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
2024
2025				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
2026                device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
2027
2028				sw::FilterType minFilter;
2029				sw::MipmapType mipFilter;
2030                es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy);
2031			//	ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter));
2032
2033				device->setTextureFilter(samplerType, samplerIndex, minFilter);
2034			//	device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter));
2035				device->setMipmapFilter(samplerType, samplerIndex, mipFilter);
2036				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
2037
2038				applyTexture(samplerType, samplerIndex, texture);
2039            }
2040            else
2041            {
2042                applyTexture(samplerType, samplerIndex, 0);
2043            }
2044        }
2045        else
2046        {
2047            applyTexture(samplerType, samplerIndex, NULL);
2048        }
2049    }
2050}
2051
2052void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
2053{
2054	Program *program = getCurrentProgram();
2055	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
2056	bool textureUsed = false;
2057
2058	if(type == sw::SAMPLER_PIXEL)
2059	{
2060		textureUsed = program->getPixelShader()->usesSampler(index);
2061	}
2062	else if(type == sw::SAMPLER_VERTEX)
2063	{
2064		textureUsed = program->getVertexShader()->usesSampler(index);
2065	}
2066	else UNREACHABLE();
2067
2068	sw::Resource *resource = 0;
2069
2070	if(baseTexture && textureUsed)
2071	{
2072		resource = baseTexture->getResource();
2073	}
2074
2075	device->setTextureResource(sampler, resource);
2076
2077	if(baseTexture && textureUsed)
2078	{
2079		int levelCount = baseTexture->getLevelCount();
2080
2081		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
2082		{
2083			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
2084
2085			for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2086			{
2087				int surfaceLevel = mipmapLevel;
2088
2089				if(surfaceLevel < 0)
2090				{
2091					surfaceLevel = 0;
2092				}
2093				else if(surfaceLevel >= levelCount)
2094				{
2095					surfaceLevel = levelCount - 1;
2096				}
2097
2098				egl::Image *surface = texture->getImage(surfaceLevel);
2099				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
2100			}
2101		}
2102		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
2103		{
2104			for(int face = 0; face < 6; face++)
2105			{
2106				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
2107
2108				for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++)
2109				{
2110					int surfaceLevel = mipmapLevel;
2111
2112					if(surfaceLevel < 0)
2113					{
2114						surfaceLevel = 0;
2115					}
2116					else if(surfaceLevel >= levelCount)
2117					{
2118						surfaceLevel = levelCount - 1;
2119					}
2120
2121					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
2122					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
2123				}
2124			}
2125		}
2126		else UNIMPLEMENTED();
2127	}
2128	else
2129	{
2130		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
2131	}
2132}
2133
2134void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
2135                         GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
2136{
2137    Framebuffer *framebuffer = getReadFramebuffer();
2138	int framebufferWidth, framebufferHeight, framebufferSamples;
2139
2140    if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2141    {
2142        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2143    }
2144
2145    if(getReadFramebufferHandle() != 0 && framebufferSamples != 0)
2146    {
2147        return error(GL_INVALID_OPERATION);
2148    }
2149
2150	GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment);
2151
2152	// Sized query sanity check
2153    if(bufSize)
2154    {
2155        int requiredSize = outputPitch * height;
2156        if(requiredSize > *bufSize)
2157        {
2158            return error(GL_INVALID_OPERATION);
2159        }
2160    }
2161
2162    egl::Image *renderTarget = framebuffer->getRenderTarget();
2163
2164    if(!renderTarget)
2165    {
2166        return error(GL_OUT_OF_MEMORY);
2167    }
2168
2169	sw::Rect rect = {x, y, x + width, y + height};
2170	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
2171
2172    unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY);
2173    unsigned char *dest = (unsigned char*)pixels;
2174    unsigned short *dest16 = (unsigned short*)pixels;
2175    int inputPitch = (int)renderTarget->getPitch();
2176
2177    for(int j = 0; j < rect.y1 - rect.y0; j++)
2178    {
2179        if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 &&
2180           format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
2181        {
2182            // Fast path for EXT_read_format_bgra, given an RGBA source buffer
2183			// Note that buffers with no alpha go through the slow path below
2184            memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4);
2185        }
2186		else
2187		{
2188			for(int i = 0; i < rect.x1 - rect.x0; i++)
2189			{
2190				float r;
2191				float g;
2192				float b;
2193				float a;
2194
2195				switch(renderTarget->getInternalFormat())
2196				{
2197				case sw::FORMAT_R5G6B5:
2198					{
2199						unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2200
2201						a = 1.0f;
2202						b = (rgb & 0x001F) * (1.0f / 0x001F);
2203						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
2204						r = (rgb & 0xF800) * (1.0f / 0xF800);
2205					}
2206					break;
2207				case sw::FORMAT_A1R5G5B5:
2208					{
2209						unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch);
2210
2211						a = (argb & 0x8000) ? 1.0f : 0.0f;
2212						b = (argb & 0x001F) * (1.0f / 0x001F);
2213						g = (argb & 0x03E0) * (1.0f / 0x03E0);
2214						r = (argb & 0x7C00) * (1.0f / 0x7C00);
2215					}
2216					break;
2217				case sw::FORMAT_A8R8G8B8:
2218					{
2219						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2220
2221						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
2222						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
2223						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
2224						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
2225					}
2226					break;
2227				case sw::FORMAT_X8R8G8B8:
2228					{
2229						unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2230
2231						a = 1.0f;
2232						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
2233						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
2234						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
2235					}
2236					break;
2237				case sw::FORMAT_A2R10G10B10:
2238					{
2239						unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch);
2240
2241						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
2242						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
2243						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
2244						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
2245					}
2246					break;
2247				case sw::FORMAT_A32B32G32R32F:
2248					{
2249						r = *((float*)(source + 16 * i + j * inputPitch) + 0);
2250						g = *((float*)(source + 16 * i + j * inputPitch) + 1);
2251						b = *((float*)(source + 16 * i + j * inputPitch) + 2);
2252						a = *((float*)(source + 16 * i + j * inputPitch) + 3);
2253					}
2254					break;
2255				case sw::FORMAT_A16B16G16R16F:
2256					{
2257						r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0);
2258						g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1);
2259						b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2);
2260						a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3);
2261					}
2262					break;
2263				default:
2264					UNIMPLEMENTED();   // FIXME
2265					UNREACHABLE();
2266				}
2267
2268				switch(format)
2269				{
2270				case GL_RGBA:
2271					switch(type)
2272					{
2273					case GL_UNSIGNED_BYTE:
2274						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f);
2275						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2276						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f);
2277						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2278						break;
2279					default: UNREACHABLE();
2280					}
2281					break;
2282				case GL_BGRA_EXT:
2283					switch(type)
2284					{
2285					case GL_UNSIGNED_BYTE:
2286						dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
2287						dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
2288						dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
2289						dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
2290						break;
2291					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
2292						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2293						// this type is packed as follows:
2294						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2295						//  --------------------------------------------------------------------------------
2296						// |       4th         |        3rd         |        2nd        |   1st component   |
2297						//  --------------------------------------------------------------------------------
2298						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2299						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2300							((unsigned short)(15 * a + 0.5f) << 12)|
2301							((unsigned short)(15 * r + 0.5f) << 8) |
2302							((unsigned short)(15 * g + 0.5f) << 4) |
2303							((unsigned short)(15 * b + 0.5f) << 0);
2304						break;
2305					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
2306						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
2307						// this type is packed as follows:
2308						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
2309						//  --------------------------------------------------------------------------------
2310						// | 4th |          3rd           |           2nd          |      1st component     |
2311						//  --------------------------------------------------------------------------------
2312						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
2313						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2314							((unsigned short)(     a + 0.5f) << 15) |
2315							((unsigned short)(31 * r + 0.5f) << 10) |
2316							((unsigned short)(31 * g + 0.5f) << 5) |
2317							((unsigned short)(31 * b + 0.5f) << 0);
2318						break;
2319					default: UNREACHABLE();
2320					}
2321					break;
2322				case GL_RGB:   // IMPLEMENTATION_COLOR_READ_FORMAT
2323					switch(type)
2324					{
2325					case GL_UNSIGNED_SHORT_5_6_5:   // IMPLEMENTATION_COLOR_READ_TYPE
2326						dest16[i + j * outputPitch / sizeof(unsigned short)] =
2327							((unsigned short)(31 * b + 0.5f) << 0) |
2328							((unsigned short)(63 * g + 0.5f) << 5) |
2329							((unsigned short)(31 * r + 0.5f) << 11);
2330						break;
2331					default: UNREACHABLE();
2332					}
2333					break;
2334				default: UNREACHABLE();
2335				}
2336			}
2337        }
2338    }
2339
2340	renderTarget->unlock();
2341	renderTarget->release();
2342}
2343
2344void Context::clear(GLbitfield mask)
2345{
2346    Framebuffer *framebuffer = getDrawFramebuffer();
2347
2348    if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
2349    {
2350        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2351    }
2352
2353    if(!applyRenderTarget())
2354    {
2355        return;
2356    }
2357
2358	unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) |
2359                         (unorm<8>(mState.colorClearValue.red) << 16) |
2360                         (unorm<8>(mState.colorClearValue.green) << 8) |
2361                         (unorm<8>(mState.colorClearValue.blue) << 0);
2362    float depth = clamp01(mState.depthClearValue);
2363    int stencil = mState.stencilClearValue & 0x000000FF;
2364
2365	if(mask & GL_COLOR_BUFFER_BIT)
2366	{
2367		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
2368		                        (mState.colorMaskGreen ? 0x2 : 0) |
2369		                        (mState.colorMaskBlue ? 0x4 : 0) |
2370		                        (mState.colorMaskAlpha ? 0x8 : 0);
2371
2372		if(rgbaMask != 0)
2373		{
2374			device->clearColor(color, rgbaMask);
2375		}
2376	}
2377
2378	if(mask & GL_DEPTH_BUFFER_BIT)
2379	{
2380		if(mState.depthMask != 0)
2381		{
2382			device->clearDepth(depth);
2383		}
2384	}
2385
2386	if(mask & GL_STENCIL_BUFFER_BIT)
2387	{
2388		if(mState.stencilWritemask != 0)
2389		{
2390			device->clearStencil(stencil, mState.stencilWritemask);
2391		}
2392	}
2393}
2394
2395void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
2396{
2397    if(!mState.currentProgram)
2398    {
2399        return error(GL_INVALID_OPERATION);
2400    }
2401
2402    PrimitiveType primitiveType;
2403    int primitiveCount;
2404
2405    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2406        return error(GL_INVALID_ENUM);
2407
2408    if(primitiveCount <= 0)
2409    {
2410        return;
2411    }
2412
2413    if(!applyRenderTarget())
2414    {
2415        return;
2416    }
2417
2418    applyState(mode);
2419
2420    GLenum err = applyVertexBuffer(0, first, count);
2421    if(err != GL_NO_ERROR)
2422    {
2423        return error(err);
2424    }
2425
2426    applyShaders();
2427    applyTextures();
2428
2429    if(!getCurrentProgram()->validateSamplers(false))
2430    {
2431        return error(GL_INVALID_OPERATION);
2432    }
2433
2434    if(!cullSkipsDraw(mode))
2435    {
2436        device->drawPrimitive(primitiveType, primitiveCount);
2437    }
2438}
2439
2440void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
2441{
2442    if(!mState.currentProgram)
2443    {
2444        return error(GL_INVALID_OPERATION);
2445    }
2446
2447    if(!indices && !mState.elementArrayBuffer)
2448    {
2449        return error(GL_INVALID_OPERATION);
2450    }
2451
2452    PrimitiveType primitiveType;
2453    int primitiveCount;
2454
2455    if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount))
2456        return error(GL_INVALID_ENUM);
2457
2458    if(primitiveCount <= 0)
2459    {
2460        return;
2461    }
2462
2463    if(!applyRenderTarget())
2464    {
2465        return;
2466    }
2467
2468    applyState(mode);
2469
2470    TranslatedIndexData indexInfo;
2471    GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
2472    if(err != GL_NO_ERROR)
2473    {
2474        return error(err);
2475    }
2476
2477    GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
2478    err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
2479    if(err != GL_NO_ERROR)
2480    {
2481        return error(err);
2482    }
2483
2484    applyShaders();
2485    applyTextures();
2486
2487    if(!getCurrentProgram()->validateSamplers(false))
2488    {
2489        return error(GL_INVALID_OPERATION);
2490    }
2491
2492    if(!cullSkipsDraw(mode))
2493    {
2494		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type));
2495    }
2496}
2497
2498void Context::finish()
2499{
2500	device->finish();
2501}
2502
2503void Context::flush()
2504{
2505    // We don't queue anything without processing it as fast as possible
2506}
2507
2508void Context::recordInvalidEnum()
2509{
2510    mInvalidEnum = true;
2511}
2512
2513void Context::recordInvalidValue()
2514{
2515    mInvalidValue = true;
2516}
2517
2518void Context::recordInvalidOperation()
2519{
2520    mInvalidOperation = true;
2521}
2522
2523void Context::recordOutOfMemory()
2524{
2525    mOutOfMemory = true;
2526}
2527
2528void Context::recordInvalidFramebufferOperation()
2529{
2530    mInvalidFramebufferOperation = true;
2531}
2532
2533// Get one of the recorded errors and clear its flag, if any.
2534// [OpenGL ES 2.0.24] section 2.5 page 13.
2535GLenum Context::getError()
2536{
2537    if(mInvalidEnum)
2538    {
2539        mInvalidEnum = false;
2540
2541        return GL_INVALID_ENUM;
2542    }
2543
2544    if(mInvalidValue)
2545    {
2546        mInvalidValue = false;
2547
2548        return GL_INVALID_VALUE;
2549    }
2550
2551    if(mInvalidOperation)
2552    {
2553        mInvalidOperation = false;
2554
2555        return GL_INVALID_OPERATION;
2556    }
2557
2558    if(mOutOfMemory)
2559    {
2560        mOutOfMemory = false;
2561
2562        return GL_OUT_OF_MEMORY;
2563    }
2564
2565    if(mInvalidFramebufferOperation)
2566    {
2567        mInvalidFramebufferOperation = false;
2568
2569        return GL_INVALID_FRAMEBUFFER_OPERATION;
2570    }
2571
2572    return GL_NO_ERROR;
2573}
2574
2575int Context::getSupportedMultiSampleDepth(sw::Format format, int requested)
2576{
2577    if(requested <= 1)
2578    {
2579        return 1;
2580    }
2581
2582	if(requested == 2)
2583	{
2584		return 2;
2585	}
2586
2587	return 4;
2588}
2589
2590void Context::detachBuffer(GLuint buffer)
2591{
2592    // [OpenGL ES 2.0.24] section 2.9 page 22:
2593    // If a buffer object is deleted while it is bound, all bindings to that object in the current context
2594    // (i.e. in the thread that called Delete-Buffers) are reset to zero.
2595
2596    if(mState.arrayBuffer.id() == buffer)
2597    {
2598        mState.arrayBuffer.set(NULL);
2599    }
2600
2601    if(mState.elementArrayBuffer.id() == buffer)
2602    {
2603        mState.elementArrayBuffer.set(NULL);
2604    }
2605
2606    for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
2607    {
2608        if(mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
2609        {
2610            mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
2611        }
2612    }
2613}
2614
2615void Context::detachTexture(GLuint texture)
2616{
2617    // [OpenGL ES 2.0.24] section 3.8 page 84:
2618    // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
2619    // rebound to texture object zero
2620
2621    for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
2622    {
2623        for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
2624        {
2625            if(mState.samplerTexture[type][sampler].id() == texture)
2626            {
2627                mState.samplerTexture[type][sampler].set(NULL);
2628            }
2629        }
2630    }
2631
2632    // [OpenGL ES 2.0.24] section 4.4 page 112:
2633    // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
2634    // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
2635    // image was attached in the currently bound framebuffer.
2636
2637    Framebuffer *readFramebuffer = getReadFramebuffer();
2638    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2639
2640    if(readFramebuffer)
2641    {
2642        readFramebuffer->detachTexture(texture);
2643    }
2644
2645    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2646    {
2647        drawFramebuffer->detachTexture(texture);
2648    }
2649}
2650
2651void Context::detachFramebuffer(GLuint framebuffer)
2652{
2653    // [OpenGL ES 2.0.24] section 4.4 page 107:
2654    // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
2655    // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
2656
2657    if(mState.readFramebuffer == framebuffer)
2658    {
2659        bindReadFramebuffer(0);
2660    }
2661
2662    if(mState.drawFramebuffer == framebuffer)
2663    {
2664        bindDrawFramebuffer(0);
2665    }
2666}
2667
2668void Context::detachRenderbuffer(GLuint renderbuffer)
2669{
2670    // [OpenGL ES 2.0.24] section 4.4 page 109:
2671    // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
2672    // had been executed with the target RENDERBUFFER and name of zero.
2673
2674    if(mState.renderbuffer.id() == renderbuffer)
2675    {
2676        bindRenderbuffer(0);
2677    }
2678
2679    // [OpenGL ES 2.0.24] section 4.4 page 111:
2680    // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
2681    // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
2682    // point to which this image was attached in the currently bound framebuffer.
2683
2684    Framebuffer *readFramebuffer = getReadFramebuffer();
2685    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2686
2687    if(readFramebuffer)
2688    {
2689        readFramebuffer->detachRenderbuffer(renderbuffer);
2690    }
2691
2692    if(drawFramebuffer && drawFramebuffer != readFramebuffer)
2693    {
2694        drawFramebuffer->detachRenderbuffer(renderbuffer);
2695    }
2696}
2697
2698bool Context::cullSkipsDraw(GLenum drawMode)
2699{
2700    return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
2701}
2702
2703bool Context::isTriangleMode(GLenum drawMode)
2704{
2705    switch (drawMode)
2706    {
2707      case GL_TRIANGLES:
2708      case GL_TRIANGLE_FAN:
2709      case GL_TRIANGLE_STRIP:
2710        return true;
2711      case GL_POINTS:
2712      case GL_LINES:
2713      case GL_LINE_LOOP:
2714      case GL_LINE_STRIP:
2715        return false;
2716      default: UNREACHABLE();
2717    }
2718
2719    return false;
2720}
2721
2722void Context::setVertexAttrib(GLuint index, const GLfloat *values)
2723{
2724    ASSERT(index < MAX_VERTEX_ATTRIBS);
2725
2726    mState.vertexAttribute[index].mCurrentValue[0] = values[0];
2727    mState.vertexAttribute[index].mCurrentValue[1] = values[1];
2728    mState.vertexAttribute[index].mCurrentValue[2] = values[2];
2729    mState.vertexAttribute[index].mCurrentValue[3] = values[3];
2730
2731    mVertexDataManager->dirtyCurrentValue(index);
2732}
2733
2734void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
2735                              GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
2736                              GLbitfield mask)
2737{
2738    Framebuffer *readFramebuffer = getReadFramebuffer();
2739    Framebuffer *drawFramebuffer = getDrawFramebuffer();
2740
2741	int readBufferWidth, readBufferHeight, readBufferSamples;
2742    int drawBufferWidth, drawBufferHeight, drawBufferSamples;
2743
2744    if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
2745       !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
2746    {
2747        return error(GL_INVALID_FRAMEBUFFER_OPERATION);
2748    }
2749
2750    if(drawBufferSamples > 1)
2751    {
2752        return error(GL_INVALID_OPERATION);
2753    }
2754
2755    sw::Rect sourceRect;
2756    sw::Rect destRect;
2757
2758    if(srcX0 < srcX1)
2759    {
2760        sourceRect.x0 = srcX0;
2761        sourceRect.x1 = srcX1;
2762        destRect.x0 = dstX0;
2763        destRect.x1 = dstX1;
2764    }
2765    else
2766    {
2767        sourceRect.x0 = srcX1;
2768        destRect.x0 = dstX1;
2769        sourceRect.x1 = srcX0;
2770        destRect.x1 = dstX0;
2771    }
2772
2773    if(srcY0 < srcY1)
2774    {
2775        sourceRect.y0 = srcY0;
2776        destRect.y0 = dstY0;
2777        sourceRect.y1 = srcY1;
2778        destRect.y1 = dstY1;
2779    }
2780    else
2781    {
2782        sourceRect.y0 = srcY1;
2783        destRect.y0 = dstY1;
2784        sourceRect.y1 = srcY0;
2785        destRect.y1 = dstY0;
2786    }
2787
2788    sw::Rect sourceScissoredRect = sourceRect;
2789    sw::Rect destScissoredRect = destRect;
2790
2791    if(mState.scissorTest)   // Only write to parts of the destination framebuffer which pass the scissor test
2792    {
2793        if(destRect.x0 < mState.scissorX)
2794        {
2795            int xDiff = mState.scissorX - destRect.x0;
2796            destScissoredRect.x0 = mState.scissorX;
2797            sourceScissoredRect.x0 += xDiff;
2798        }
2799
2800        if(destRect.x1 > mState.scissorX + mState.scissorWidth)
2801        {
2802            int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
2803            destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
2804            sourceScissoredRect.x1 -= xDiff;
2805        }
2806
2807        if(destRect.y0 < mState.scissorY)
2808        {
2809            int yDiff = mState.scissorY - destRect.y0;
2810            destScissoredRect.y0 = mState.scissorY;
2811            sourceScissoredRect.y0 += yDiff;
2812        }
2813
2814        if(destRect.y1 > mState.scissorY + mState.scissorHeight)
2815        {
2816            int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
2817            destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
2818            sourceScissoredRect.y1 -= yDiff;
2819        }
2820    }
2821
2822    sw::Rect sourceTrimmedRect = sourceScissoredRect;
2823    sw::Rect destTrimmedRect = destScissoredRect;
2824
2825    // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
2826    // the actual draw and read surfaces.
2827    if(sourceTrimmedRect.x0 < 0)
2828    {
2829        int xDiff = 0 - sourceTrimmedRect.x0;
2830        sourceTrimmedRect.x0 = 0;
2831        destTrimmedRect.x0 += xDiff;
2832    }
2833
2834    if(sourceTrimmedRect.x1 > readBufferWidth)
2835    {
2836        int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
2837        sourceTrimmedRect.x1 = readBufferWidth;
2838        destTrimmedRect.x1 -= xDiff;
2839    }
2840
2841    if(sourceTrimmedRect.y0 < 0)
2842    {
2843        int yDiff = 0 - sourceTrimmedRect.y0;
2844        sourceTrimmedRect.y0 = 0;
2845        destTrimmedRect.y0 += yDiff;
2846    }
2847
2848    if(sourceTrimmedRect.y1 > readBufferHeight)
2849    {
2850        int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
2851        sourceTrimmedRect.y1 = readBufferHeight;
2852        destTrimmedRect.y1 -= yDiff;
2853    }
2854
2855    if(destTrimmedRect.x0 < 0)
2856    {
2857        int xDiff = 0 - destTrimmedRect.x0;
2858        destTrimmedRect.x0 = 0;
2859        sourceTrimmedRect.x0 += xDiff;
2860    }
2861
2862    if(destTrimmedRect.x1 > drawBufferWidth)
2863    {
2864        int xDiff = destTrimmedRect.x1 - drawBufferWidth;
2865        destTrimmedRect.x1 = drawBufferWidth;
2866        sourceTrimmedRect.x1 -= xDiff;
2867    }
2868
2869    if(destTrimmedRect.y0 < 0)
2870    {
2871        int yDiff = 0 - destTrimmedRect.y0;
2872        destTrimmedRect.y0 = 0;
2873        sourceTrimmedRect.y0 += yDiff;
2874    }
2875
2876    if(destTrimmedRect.y1 > drawBufferHeight)
2877    {
2878        int yDiff = destTrimmedRect.y1 - drawBufferHeight;
2879        destTrimmedRect.y1 = drawBufferHeight;
2880        sourceTrimmedRect.y1 -= yDiff;
2881    }
2882
2883    bool partialBufferCopy = false;
2884
2885    if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
2886       sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
2887       destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
2888       destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
2889       sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
2890    {
2891        partialBufferCopy = true;
2892    }
2893
2894	bool blitRenderTarget = false;
2895    bool blitDepthStencil = false;
2896
2897    if(mask & GL_COLOR_BUFFER_BIT)
2898    {
2899        const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2900                                   readFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2901        const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D ||
2902                                   drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER;
2903        if(!validReadType || !validDrawType ||
2904           readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat())
2905        {
2906            ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
2907            return error(GL_INVALID_OPERATION);
2908        }
2909
2910        if(partialBufferCopy && readBufferSamples > 1)
2911        {
2912            return error(GL_INVALID_OPERATION);
2913        }
2914
2915        blitRenderTarget = true;
2916    }
2917
2918    if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
2919    {
2920        Renderbuffer *readDSBuffer = NULL;
2921        Renderbuffer *drawDSBuffer = NULL;
2922
2923        // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
2924        // both a depth and stencil buffer, it will be the same buffer.
2925
2926        if(mask & GL_DEPTH_BUFFER_BIT)
2927        {
2928            if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
2929            {
2930                if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
2931                   readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat())
2932                {
2933                    return error(GL_INVALID_OPERATION);
2934                }
2935
2936                blitDepthStencil = true;
2937                readDSBuffer = readFramebuffer->getDepthbuffer();
2938                drawDSBuffer = drawFramebuffer->getDepthbuffer();
2939            }
2940        }
2941
2942        if(mask & GL_STENCIL_BUFFER_BIT)
2943        {
2944            if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
2945            {
2946                if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
2947                   readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat())
2948                {
2949                    return error(GL_INVALID_OPERATION);
2950                }
2951
2952                blitDepthStencil = true;
2953                readDSBuffer = readFramebuffer->getStencilbuffer();
2954                drawDSBuffer = drawFramebuffer->getStencilbuffer();
2955            }
2956        }
2957
2958        if(partialBufferCopy)
2959        {
2960            ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
2961            return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
2962        }
2963
2964        if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
2965           (readDSBuffer && readDSBuffer->getSamples() > 1))
2966        {
2967            return error(GL_INVALID_OPERATION);
2968        }
2969    }
2970
2971    if(blitRenderTarget || blitDepthStencil)
2972    {
2973        if(blitRenderTarget)
2974        {
2975            egl::Image *readRenderTarget = readFramebuffer->getRenderTarget();
2976            egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget();
2977
2978            bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
2979
2980            readRenderTarget->release();
2981            drawRenderTarget->release();
2982
2983            if(!success)
2984            {
2985                ERR("BlitFramebufferANGLE failed.");
2986                return;
2987            }
2988        }
2989
2990        if(blitDepthStencil)
2991        {
2992            bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false);
2993
2994            if(!success)
2995            {
2996                ERR("BlitFramebufferANGLE failed.");
2997                return;
2998            }
2999        }
3000    }
3001}
3002
3003void Context::bindTexImage(egl::Surface *surface)
3004{
3005	es2::Texture2D *textureObject = getTexture2D();
3006
3007    if(textureObject)
3008    {
3009		textureObject->bindTexImage(surface);
3010	}
3011}
3012
3013EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3014{
3015    GLenum textureTarget = GL_NONE;
3016
3017    switch(target)
3018    {
3019    case EGL_GL_TEXTURE_2D_KHR:
3020        textureTarget = GL_TEXTURE_2D;
3021        break;
3022    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
3023    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
3024    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
3025    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
3026    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
3027    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
3028        textureTarget = GL_TEXTURE_CUBE_MAP;
3029        break;
3030    case EGL_GL_RENDERBUFFER_KHR:
3031        break;
3032    default:
3033        return EGL_BAD_PARAMETER;
3034    }
3035
3036    if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
3037    {
3038        return EGL_BAD_MATCH;
3039    }
3040
3041    if(textureTarget != GL_NONE)
3042    {
3043        es2::Texture *texture = getTexture(name);
3044
3045        if(!texture || texture->getTarget() != textureTarget)
3046        {
3047            return EGL_BAD_PARAMETER;
3048        }
3049
3050        if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
3051        {
3052            return EGL_BAD_ACCESS;
3053        }
3054
3055        if(textureLevel != 0 && !texture->isSamplerComplete())
3056        {
3057            return EGL_BAD_PARAMETER;
3058        }
3059
3060        if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
3061        {
3062            return EGL_BAD_PARAMETER;
3063        }
3064    }
3065    else if(target == EGL_GL_RENDERBUFFER_KHR)
3066    {
3067        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3068
3069        if(!renderbuffer)
3070        {
3071            return EGL_BAD_PARAMETER;
3072        }
3073
3074        if(renderbuffer->isShared())   // Already an EGLImage sibling
3075        {
3076            return EGL_BAD_ACCESS;
3077        }
3078    }
3079    else UNREACHABLE();
3080
3081	return EGL_SUCCESS;
3082}
3083
3084egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
3085{
3086	GLenum textureTarget = GL_NONE;
3087
3088    switch(target)
3089    {
3090    case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
3091    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
3092    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
3093    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
3094    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
3095    case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
3096    case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
3097    }
3098
3099    if(textureTarget != GL_NONE)
3100    {
3101        es2::Texture *texture = getTexture(name);
3102
3103        return texture->createSharedImage(textureTarget, textureLevel);
3104    }
3105    else if(target == EGL_GL_RENDERBUFFER_KHR)
3106    {
3107        es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
3108
3109        return renderbuffer->createSharedImage();
3110    }
3111    else UNREACHABLE();
3112
3113	return 0;
3114}
3115
3116Device *Context::getDevice()
3117{
3118	return device;
3119}
3120
3121}
3122
3123// Exported functions for use by EGL
3124extern "C"
3125{
3126	es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext)
3127	{
3128		return new es2::Context(config, shareContext);
3129	}
3130}
3131