Home | History | Annotate | Download | only in libGLES_CM
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Context.cpp: Implements the es1::Context class, managing all GL state and performing
     16 // rendering operations. It is the GLES2 specific implementation of EGLContext.
     17 
     18 #include "Context.h"
     19 
     20 #include "main.h"
     21 #include "mathutil.h"
     22 #include "utilities.h"
     23 #include "ResourceManager.h"
     24 #include "Buffer.h"
     25 #include "Framebuffer.h"
     26 #include "Renderbuffer.h"
     27 #include "Texture.h"
     28 #include "VertexDataManager.h"
     29 #include "IndexDataManager.h"
     30 #include "libEGL/Display.h"
     31 #include "common/Surface.hpp"
     32 #include "Common/Half.hpp"
     33 
     34 #include <EGL/eglext.h>
     35 
     36 using std::abs;
     37 
     38 namespace es1
     39 {
     40 Context::Context(egl::Display *const display, const Context *shareContext, const egl::Config *config)
     41 	: egl::Context(display), config(config),
     42 	  modelViewStack(MAX_MODELVIEW_STACK_DEPTH),
     43 	  projectionStack(MAX_PROJECTION_STACK_DEPTH),
     44 	  textureStack0(MAX_TEXTURE_STACK_DEPTH),
     45 	  textureStack1(MAX_TEXTURE_STACK_DEPTH)
     46 {
     47 	sw::Context *context = new sw::Context();
     48 	device = new es1::Device(context);
     49 
     50 	mVertexDataManager = new VertexDataManager(this);
     51 	mIndexDataManager = new IndexDataManager();
     52 
     53 	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     54 
     55 	mState.depthClearValue = 1.0f;
     56 	mState.stencilClearValue = 0;
     57 
     58 	mState.cullFaceEnabled = false;
     59 	mState.cullMode = GL_BACK;
     60 	mState.frontFace = GL_CCW;
     61 	mState.depthTestEnabled = false;
     62 	mState.depthFunc = GL_LESS;
     63 	mState.blendEnabled = false;
     64 	mState.sourceBlendRGB = GL_ONE;
     65 	mState.sourceBlendAlpha = GL_ONE;
     66 	mState.destBlendRGB = GL_ZERO;
     67 	mState.destBlendAlpha = GL_ZERO;
     68 	mState.blendEquationRGB = GL_FUNC_ADD_OES;
     69 	mState.blendEquationAlpha = GL_FUNC_ADD_OES;
     70 	mState.stencilTestEnabled = false;
     71 	mState.stencilFunc = GL_ALWAYS;
     72 	mState.stencilRef = 0;
     73 	mState.stencilMask = -1;
     74 	mState.stencilWritemask = -1;
     75 	mState.stencilFail = GL_KEEP;
     76 	mState.stencilPassDepthFail = GL_KEEP;
     77 	mState.stencilPassDepthPass = GL_KEEP;
     78 	mState.polygonOffsetFillEnabled = false;
     79 	mState.polygonOffsetFactor = 0.0f;
     80 	mState.polygonOffsetUnits = 0.0f;
     81 	mState.sampleAlphaToCoverageEnabled = false;
     82 	mState.sampleCoverageEnabled = false;
     83 	mState.sampleCoverageValue = 1.0f;
     84 	mState.sampleCoverageInvert = false;
     85 	mState.scissorTestEnabled = false;
     86 	mState.ditherEnabled = true;
     87 	mState.shadeModel = GL_SMOOTH;
     88 	mState.generateMipmapHint = GL_DONT_CARE;
     89 	mState.perspectiveCorrectionHint = GL_DONT_CARE;
     90 	mState.fogHint = GL_DONT_CARE;
     91 
     92 	mState.lineWidth = 1.0f;
     93 
     94 	mState.viewportX = 0;
     95 	mState.viewportY = 0;
     96 	mState.viewportWidth = 0;
     97 	mState.viewportHeight = 0;
     98 	mState.zNear = 0.0f;
     99 	mState.zFar = 1.0f;
    100 
    101 	mState.scissorX = 0;
    102 	mState.scissorY = 0;
    103 	mState.scissorWidth = 0;
    104 	mState.scissorHeight = 0;
    105 
    106 	mState.colorMaskRed = true;
    107 	mState.colorMaskGreen = true;
    108 	mState.colorMaskBlue = true;
    109 	mState.colorMaskAlpha = true;
    110 	mState.depthMask = true;
    111 
    112 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
    113 	{
    114 		mState.textureUnit[i].color = {0, 0, 0, 0};
    115 		mState.textureUnit[i].environmentMode = GL_MODULATE;
    116 		mState.textureUnit[i].combineRGB = GL_MODULATE;
    117 		mState.textureUnit[i].combineAlpha = GL_MODULATE;
    118 		mState.textureUnit[i].src0RGB = GL_TEXTURE;
    119 		mState.textureUnit[i].src1RGB = GL_PREVIOUS;
    120 		mState.textureUnit[i].src2RGB = GL_CONSTANT;
    121 		mState.textureUnit[i].src0Alpha = GL_TEXTURE;
    122 		mState.textureUnit[i].src1Alpha = GL_PREVIOUS;
    123 		mState.textureUnit[i].src2Alpha = GL_CONSTANT;
    124 		mState.textureUnit[i].operand0RGB = GL_SRC_COLOR;
    125 		mState.textureUnit[i].operand1RGB = GL_SRC_COLOR;
    126 		mState.textureUnit[i].operand2RGB = GL_SRC_ALPHA;
    127 		mState.textureUnit[i].operand0Alpha = GL_SRC_ALPHA;
    128 		mState.textureUnit[i].operand1Alpha = GL_SRC_ALPHA;
    129 		mState.textureUnit[i].operand2Alpha = GL_SRC_ALPHA;
    130 	}
    131 
    132 	if(shareContext)
    133 	{
    134 		mResourceManager = shareContext->mResourceManager;
    135 		mResourceManager->addRef();
    136 	}
    137 	else
    138 	{
    139 		mResourceManager = new ResourceManager();
    140 	}
    141 
    142 	// [OpenGL ES 2.0.24] section 3.7 page 83:
    143 	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
    144 	// and cube map texture state vectors respectively associated with them.
    145 	// In order that access to these initial textures not be lost, they are treated as texture
    146 	// objects all of whose names are 0.
    147 
    148 	mTexture2DZero = new Texture2D(0);
    149 	mTextureExternalZero = new TextureExternal(0);
    150 
    151 	mState.activeSampler = 0;
    152 
    153 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    154 	{
    155 		bindTexture((TextureType)type, 0);
    156 	}
    157 
    158 	bindArrayBuffer(0);
    159 	bindElementArrayBuffer(0);
    160 	bindFramebuffer(0);
    161 	bindRenderbuffer(0);
    162 
    163 	mState.packAlignment = 4;
    164 	mState.unpackAlignment = 4;
    165 
    166 	mInvalidEnum = false;
    167 	mInvalidValue = false;
    168 	mInvalidOperation = false;
    169 	mOutOfMemory = false;
    170 	mInvalidFramebufferOperation = false;
    171 	mMatrixStackOverflow = false;
    172 	mMatrixStackUnderflow = false;
    173 
    174 	lightingEnabled = false;
    175 
    176 	for(int i = 0; i < MAX_LIGHTS; i++)
    177 	{
    178 		light[i].enabled = false;
    179 		light[i].ambient = {0.0f, 0.0f, 0.0f, 1.0f};
    180 		light[i].diffuse = {0.0f, 0.0f, 0.0f, 1.0f};
    181 		light[i].specular = {0.0f, 0.0f, 0.0f, 1.0f};
    182 		light[i].position = {0.0f, 0.0f, 1.0f, 0.0f};
    183 		light[i].direction = {0.0f, 0.0f, -1.0f};
    184 		light[i].attenuation = {1.0f, 0.0f, 0.0f};
    185 		light[i].spotExponent = 0.0f;
    186 		light[i].spotCutoffAngle = 180.0f;
    187 	}
    188 
    189 	light[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
    190 	light[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
    191 
    192 	globalAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
    193 	materialAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
    194 	materialDiffuse = {0.8f, 0.8f, 0.8f, 1.0f};
    195 	materialSpecular = {0.0f, 0.0f, 0.0f, 1.0f};
    196 	materialEmission = {0.0f, 0.0f, 0.0f, 1.0f};
    197 	materialShininess = 0.0f;
    198 	lightModelTwoSide = false;
    199 
    200 	matrixMode = GL_MODELVIEW;
    201 
    202 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
    203 	{
    204 		texture2Denabled[i] = false;
    205 		textureExternalEnabled[i] = false;
    206 	}
    207 
    208 	clientTexture = GL_TEXTURE0;
    209 
    210 	setVertexAttrib(sw::Color0, 1.0f, 1.0f, 1.0f, 1.0f);
    211 
    212 	for(int i = 0; i < MAX_TEXTURE_UNITS; i++)
    213 	{
    214 		setVertexAttrib(sw::TexCoord0 + i, 0.0f, 0.0f, 0.0f, 1.0f);
    215 	}
    216 
    217 	setVertexAttrib(sw::Normal, 0.0f, 0.0f, 1.0f, 1.0f);
    218 	setVertexAttrib(sw::PointSize, 1.0f, 1.0f, 1.0f, 1.0f);
    219 
    220 	clipFlags = 0;
    221 
    222 	alphaTestEnabled = false;
    223 	alphaTestFunc = GL_ALWAYS;
    224 	alphaTestRef = 0;
    225 
    226 	fogEnabled = false;
    227 	fogMode = GL_EXP;
    228 	fogDensity = 1.0f;
    229 	fogStart = 0.0f;
    230 	fogEnd = 1.0f;
    231 	fogColor = {0, 0, 0, 0};
    232 
    233 	lineSmoothEnabled = false;
    234 	colorMaterialEnabled = false;
    235 	normalizeEnabled = false;
    236 	rescaleNormalEnabled = false;
    237 	multisampleEnabled = true;
    238 	sampleAlphaToOneEnabled = false;
    239 
    240 	colorLogicOpEnabled = false;
    241 	logicalOperation = GL_COPY;
    242 
    243 	pointSpriteEnabled = false;
    244 	pointSmoothEnabled = false;
    245 	pointSizeMin = 0.0f;
    246 	pointSizeMax = 1.0f;
    247 	pointDistanceAttenuation = {1.0f, 0.0f, 0.0f};
    248 	pointFadeThresholdSize = 1.0f;
    249 
    250 	mHasBeenCurrent = false;
    251 
    252 	markAllStateDirty();
    253 }
    254 
    255 Context::~Context()
    256 {
    257 	while(!mFramebufferNameSpace.empty())
    258 	{
    259 		deleteFramebuffer(mFramebufferNameSpace.firstName());
    260 	}
    261 
    262 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    263 	{
    264 		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
    265 		{
    266 			mState.samplerTexture[type][sampler] = nullptr;
    267 		}
    268 	}
    269 
    270 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
    271 	{
    272 		mState.vertexAttribute[i].mBoundBuffer = nullptr;
    273 	}
    274 
    275 	mState.arrayBuffer = nullptr;
    276 	mState.elementArrayBuffer = nullptr;
    277 	mState.renderbuffer = nullptr;
    278 
    279 	mTexture2DZero = nullptr;
    280 	mTextureExternalZero = nullptr;
    281 
    282 	delete mVertexDataManager;
    283 	delete mIndexDataManager;
    284 
    285 	mResourceManager->release();
    286 	delete device;
    287 }
    288 
    289 void Context::makeCurrent(gl::Surface *surface)
    290 {
    291 	if(!mHasBeenCurrent)
    292 	{
    293 		mState.viewportX = 0;
    294 		mState.viewportY = 0;
    295 		mState.viewportWidth = surface ? surface->getWidth() : 0;
    296 		mState.viewportHeight = surface ? surface->getHeight() : 0;
    297 
    298 		mState.scissorX = 0;
    299 		mState.scissorY = 0;
    300 		mState.scissorWidth = surface ? surface->getWidth() : 0;
    301 		mState.scissorHeight = surface ? surface->getHeight() : 0;
    302 
    303 		mHasBeenCurrent = true;
    304 	}
    305 
    306 	// Wrap the existing resources into GL objects and assign them to the '0' names
    307 	egl::Image *defaultRenderTarget = surface ? surface->getRenderTarget() : nullptr;
    308 	egl::Image *depthStencil = surface ? surface->getDepthStencil() : nullptr;
    309 
    310 	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
    311 	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
    312 	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
    313 
    314 	setFramebufferZero(framebufferZero);
    315 
    316 	if(defaultRenderTarget)
    317 	{
    318 		defaultRenderTarget->release();
    319 	}
    320 
    321 	if(depthStencil)
    322 	{
    323 		depthStencil->release();
    324 	}
    325 
    326 	markAllStateDirty();
    327 }
    328 
    329 EGLint Context::getClientVersion() const
    330 {
    331 	return 1;
    332 }
    333 
    334 EGLint Context::getConfigID() const
    335 {
    336 	return config->mConfigID;
    337 }
    338 
    339 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
    340 void Context::markAllStateDirty()
    341 {
    342 	mDepthStateDirty = true;
    343 	mMaskStateDirty = true;
    344 	mBlendStateDirty = true;
    345 	mStencilStateDirty = true;
    346 	mPolygonOffsetStateDirty = true;
    347 	mSampleStateDirty = true;
    348 	mDitherStateDirty = true;
    349 	mFrontFaceDirty = true;
    350 }
    351 
    352 void Context::setClearColor(float red, float green, float blue, float alpha)
    353 {
    354 	mState.colorClearValue.red = red;
    355 	mState.colorClearValue.green = green;
    356 	mState.colorClearValue.blue = blue;
    357 	mState.colorClearValue.alpha = alpha;
    358 }
    359 
    360 void Context::setClearDepth(float depth)
    361 {
    362 	mState.depthClearValue = depth;
    363 }
    364 
    365 void Context::setClearStencil(int stencil)
    366 {
    367 	mState.stencilClearValue = stencil;
    368 }
    369 
    370 void Context::setCullFaceEnabled(bool enabled)
    371 {
    372 	mState.cullFaceEnabled = enabled;
    373 }
    374 
    375 bool Context::isCullFaceEnabled() const
    376 {
    377 	return mState.cullFaceEnabled;
    378 }
    379 
    380 void Context::setCullMode(GLenum mode)
    381 {
    382    mState.cullMode = mode;
    383 }
    384 
    385 void Context::setFrontFace(GLenum front)
    386 {
    387 	if(mState.frontFace != front)
    388 	{
    389 		mState.frontFace = front;
    390 		mFrontFaceDirty = true;
    391 	}
    392 }
    393 
    394 void Context::setDepthTestEnabled(bool enabled)
    395 {
    396 	if(mState.depthTestEnabled != enabled)
    397 	{
    398 		mState.depthTestEnabled = enabled;
    399 		mDepthStateDirty = true;
    400 	}
    401 }
    402 
    403 bool Context::isDepthTestEnabled() const
    404 {
    405 	return mState.depthTestEnabled;
    406 }
    407 
    408 void Context::setDepthFunc(GLenum depthFunc)
    409 {
    410 	if(mState.depthFunc != depthFunc)
    411 	{
    412 		mState.depthFunc = depthFunc;
    413 		mDepthStateDirty = true;
    414 	}
    415 }
    416 
    417 void Context::setDepthRange(float zNear, float zFar)
    418 {
    419 	mState.zNear = zNear;
    420 	mState.zFar = zFar;
    421 }
    422 
    423 void Context::setAlphaTestEnabled(bool enabled)
    424 {
    425 	alphaTestEnabled = enabled;
    426 }
    427 
    428 bool Context::isAlphaTestEnabled() const
    429 {
    430 	return alphaTestEnabled;
    431 }
    432 
    433 void Context::setAlphaFunc(GLenum alphaFunc, GLclampf reference)
    434 {
    435 	alphaTestFunc = alphaFunc;
    436 	alphaTestRef = reference;
    437 }
    438 
    439 void Context::setBlendEnabled(bool enabled)
    440 {
    441 	if(mState.blendEnabled != enabled)
    442 	{
    443 		mState.blendEnabled = enabled;
    444 		mBlendStateDirty = true;
    445 	}
    446 }
    447 
    448 bool Context::isBlendEnabled() const
    449 {
    450 	return mState.blendEnabled;
    451 }
    452 
    453 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    454 {
    455 	if(mState.sourceBlendRGB != sourceRGB ||
    456 	   mState.sourceBlendAlpha != sourceAlpha ||
    457 	   mState.destBlendRGB != destRGB ||
    458 	   mState.destBlendAlpha != destAlpha)
    459 	{
    460 		mState.sourceBlendRGB = sourceRGB;
    461 		mState.destBlendRGB = destRGB;
    462 		mState.sourceBlendAlpha = sourceAlpha;
    463 		mState.destBlendAlpha = destAlpha;
    464 		mBlendStateDirty = true;
    465 	}
    466 }
    467 
    468 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
    469 {
    470 	if(mState.blendEquationRGB != rgbEquation ||
    471 	   mState.blendEquationAlpha != alphaEquation)
    472 	{
    473 		mState.blendEquationRGB = rgbEquation;
    474 		mState.blendEquationAlpha = alphaEquation;
    475 		mBlendStateDirty = true;
    476 	}
    477 }
    478 
    479 void Context::setStencilTestEnabled(bool enabled)
    480 {
    481 	if(mState.stencilTestEnabled != enabled)
    482 	{
    483 		mState.stencilTestEnabled = enabled;
    484 		mStencilStateDirty = true;
    485 	}
    486 }
    487 
    488 bool Context::isStencilTestEnabled() const
    489 {
    490 	return mState.stencilTestEnabled;
    491 }
    492 
    493 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
    494 {
    495 	if(mState.stencilFunc != stencilFunc ||
    496 	   mState.stencilRef != stencilRef ||
    497 	   mState.stencilMask != stencilMask)
    498 	{
    499 		mState.stencilFunc = stencilFunc;
    500 		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
    501 		mState.stencilMask = stencilMask;
    502 		mStencilStateDirty = true;
    503 	}
    504 }
    505 
    506 void Context::setStencilWritemask(GLuint stencilWritemask)
    507 {
    508 	if(mState.stencilWritemask != stencilWritemask)
    509 	{
    510 		mState.stencilWritemask = stencilWritemask;
    511 		mStencilStateDirty = true;
    512 	}
    513 }
    514 
    515 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
    516 {
    517 	if(mState.stencilFail != stencilFail ||
    518 	   mState.stencilPassDepthFail != stencilPassDepthFail ||
    519 	   mState.stencilPassDepthPass != stencilPassDepthPass)
    520 	{
    521 		mState.stencilFail = stencilFail;
    522 		mState.stencilPassDepthFail = stencilPassDepthFail;
    523 		mState.stencilPassDepthPass = stencilPassDepthPass;
    524 		mStencilStateDirty = true;
    525 	}
    526 }
    527 
    528 void Context::setPolygonOffsetFillEnabled(bool enabled)
    529 {
    530 	if(mState.polygonOffsetFillEnabled != enabled)
    531 	{
    532 		mState.polygonOffsetFillEnabled = enabled;
    533 		mPolygonOffsetStateDirty = true;
    534 	}
    535 }
    536 
    537 bool Context::isPolygonOffsetFillEnabled() const
    538 {
    539 	return mState.polygonOffsetFillEnabled;
    540 }
    541 
    542 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
    543 {
    544 	if(mState.polygonOffsetFactor != factor ||
    545 	   mState.polygonOffsetUnits != units)
    546 	{
    547 		mState.polygonOffsetFactor = factor;
    548 		mState.polygonOffsetUnits = units;
    549 		mPolygonOffsetStateDirty = true;
    550 	}
    551 }
    552 
    553 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
    554 {
    555 	if(mState.sampleAlphaToCoverageEnabled != enabled)
    556 	{
    557 		mState.sampleAlphaToCoverageEnabled = enabled;
    558 		mSampleStateDirty = true;
    559 	}
    560 }
    561 
    562 bool Context::isSampleAlphaToCoverageEnabled() const
    563 {
    564 	return mState.sampleAlphaToCoverageEnabled;
    565 }
    566 
    567 void Context::setSampleCoverageEnabled(bool enabled)
    568 {
    569 	if(mState.sampleCoverageEnabled != enabled)
    570 	{
    571 		mState.sampleCoverageEnabled = enabled;
    572 		mSampleStateDirty = true;
    573 	}
    574 }
    575 
    576 bool Context::isSampleCoverageEnabled() const
    577 {
    578 	return mState.sampleCoverageEnabled;
    579 }
    580 
    581 void Context::setSampleCoverageParams(GLclampf value, bool invert)
    582 {
    583 	if(mState.sampleCoverageValue != value ||
    584 	   mState.sampleCoverageInvert != invert)
    585 	{
    586 		mState.sampleCoverageValue = value;
    587 		mState.sampleCoverageInvert = invert;
    588 		mSampleStateDirty = true;
    589 	}
    590 }
    591 
    592 void Context::setScissorTestEnabled(bool enabled)
    593 {
    594 	mState.scissorTestEnabled = enabled;
    595 }
    596 
    597 bool Context::isScissorTestEnabled() const
    598 {
    599 	return mState.scissorTestEnabled;
    600 }
    601 
    602 void Context::setShadeModel(GLenum mode)
    603 {
    604 	mState.shadeModel = mode;
    605 }
    606 
    607 void Context::setDitherEnabled(bool enabled)
    608 {
    609 	if(mState.ditherEnabled != enabled)
    610 	{
    611 		mState.ditherEnabled = enabled;
    612 		mDitherStateDirty = true;
    613 	}
    614 }
    615 
    616 bool Context::isDitherEnabled() const
    617 {
    618 	return mState.ditherEnabled;
    619 }
    620 
    621 void Context::setLightingEnabled(bool enable)
    622 {
    623 	lightingEnabled = enable;
    624 }
    625 
    626 bool Context::isLightingEnabled() const
    627 {
    628 	return lightingEnabled;
    629 }
    630 
    631 void Context::setLightEnabled(int index, bool enable)
    632 {
    633 	light[index].enabled = enable;
    634 }
    635 
    636 bool Context::isLightEnabled(int index) const
    637 {
    638 	return light[index].enabled;
    639 }
    640 
    641 void Context::setLightAmbient(int index, float r, float g, float b, float a)
    642 {
    643 	light[index].ambient = {r, g, b, a};
    644 }
    645 
    646 void Context::setLightDiffuse(int index, float r, float g, float b, float a)
    647 {
    648 	light[index].diffuse = {r, g, b, a};
    649 }
    650 
    651 void Context::setLightSpecular(int index, float r, float g, float b, float a)
    652 {
    653 	light[index].specular = {r, g, b, a};
    654 }
    655 
    656 void Context::setLightPosition(int index, float x, float y, float z, float w)
    657 {
    658 	sw::float4 v = {x, y, z, w};
    659 
    660 	// Transform from object coordinates to eye coordinates
    661 	v = modelViewStack.current() * v;
    662 
    663 	light[index].position = {v.x, v.y, v.z, v.w};
    664 }
    665 
    666 void Context::setLightDirection(int index, float x, float y, float z)
    667 {
    668 	// FIXME: Transform by inverse of 3x3 model-view matrix
    669 	light[index].direction = {x, y, z};
    670 }
    671 
    672 void Context::setLightAttenuationConstant(int index, float constant)
    673 {
    674 	light[index].attenuation.constant = constant;
    675 }
    676 
    677 void Context::setLightAttenuationLinear(int index, float linear)
    678 {
    679 	light[index].attenuation.linear = linear;
    680 }
    681 
    682 void Context::setLightAttenuationQuadratic(int index, float quadratic)
    683 {
    684 	light[index].attenuation.quadratic = quadratic;
    685 }
    686 
    687 void Context::setSpotLightExponent(int index, float exponent)
    688 {
    689 	light[index].spotExponent = exponent;
    690 }
    691 
    692 void Context::setSpotLightCutoff(int index, float cutoff)
    693 {
    694 	light[index].spotCutoffAngle = cutoff;
    695 }
    696 
    697 void Context::setGlobalAmbient(float red, float green, float blue, float alpha)
    698 {
    699 	globalAmbient.red = red;
    700 	globalAmbient.green = green;
    701 	globalAmbient.blue = blue;
    702 	globalAmbient.alpha = alpha;
    703 }
    704 
    705 void Context::setMaterialAmbient(float red, float green, float blue, float alpha)
    706 {
    707 	materialAmbient.red = red;
    708 	materialAmbient.green = green;
    709 	materialAmbient.blue = blue;
    710 	materialAmbient.alpha = alpha;
    711 }
    712 
    713 void Context::setMaterialDiffuse(float red, float green, float blue, float alpha)
    714 {
    715 	materialDiffuse.red = red;
    716 	materialDiffuse.green = green;
    717 	materialDiffuse.blue = blue;
    718 	materialDiffuse.alpha = alpha;
    719 }
    720 
    721 void Context::setMaterialSpecular(float red, float green, float blue, float alpha)
    722 {
    723 	materialSpecular.red = red;
    724 	materialSpecular.green = green;
    725 	materialSpecular.blue = blue;
    726 	materialSpecular.alpha = alpha;
    727 }
    728 
    729 void Context::setMaterialEmission(float red, float green, float blue, float alpha)
    730 {
    731 	materialEmission.red = red;
    732 	materialEmission.green = green;
    733 	materialEmission.blue = blue;
    734 	materialEmission.alpha = alpha;
    735 }
    736 
    737 void Context::setMaterialShininess(float shininess)
    738 {
    739 	materialShininess = shininess;
    740 }
    741 
    742 void Context::setLightModelTwoSide(bool enable)
    743 {
    744 	lightModelTwoSide = enable;
    745 }
    746 
    747 void Context::setFogEnabled(bool enable)
    748 {
    749 	fogEnabled = enable;
    750 }
    751 
    752 bool Context::isFogEnabled() const
    753 {
    754 	return fogEnabled;
    755 }
    756 
    757 void Context::setFogMode(GLenum mode)
    758 {
    759 	fogMode = mode;
    760 }
    761 
    762 void Context::setFogDensity(float fogDensity)
    763 {
    764 	this->fogDensity = fogDensity;
    765 }
    766 
    767 void Context::setFogStart(float fogStart)
    768 {
    769 	this->fogStart = fogStart;
    770 }
    771 
    772 void Context::setFogEnd(float fogEnd)
    773 {
    774 	this->fogEnd = fogEnd;
    775 }
    776 
    777 void Context::setFogColor(float r, float g, float b, float a)
    778 {
    779 	this->fogColor = {r, g, b, a};
    780 }
    781 
    782 void Context::setTexture2Denabled(bool enable)
    783 {
    784 	texture2Denabled[mState.activeSampler] = enable;
    785 }
    786 
    787 bool Context::isTexture2Denabled() const
    788 {
    789 	return texture2Denabled[mState.activeSampler];
    790 }
    791 
    792 void Context::setTextureExternalEnabled(bool enable)
    793 {
    794 	textureExternalEnabled[mState.activeSampler] = enable;
    795 }
    796 
    797 bool Context::isTextureExternalEnabled() const
    798 {
    799 	return textureExternalEnabled[mState.activeSampler];
    800 }
    801 
    802 void Context::setLineWidth(GLfloat width)
    803 {
    804 	mState.lineWidth = width;
    805 	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
    806 }
    807 
    808 void Context::setGenerateMipmapHint(GLenum hint)
    809 {
    810 	mState.generateMipmapHint = hint;
    811 }
    812 
    813 void Context::setPerspectiveCorrectionHint(GLenum hint)
    814 {
    815 	mState.perspectiveCorrectionHint = hint;
    816 }
    817 
    818 void Context::setFogHint(GLenum hint)
    819 {
    820 	mState.fogHint = hint;
    821 }
    822 
    823 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
    824 {
    825 	mState.viewportX = x;
    826 	mState.viewportY = y;
    827 	mState.viewportWidth = width;
    828 	mState.viewportHeight = height;
    829 }
    830 
    831 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
    832 {
    833 	mState.scissorX = x;
    834 	mState.scissorY = y;
    835 	mState.scissorWidth = width;
    836 	mState.scissorHeight = height;
    837 }
    838 
    839 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
    840 {
    841 	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
    842 	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
    843 	{
    844 		mState.colorMaskRed = red;
    845 		mState.colorMaskGreen = green;
    846 		mState.colorMaskBlue = blue;
    847 		mState.colorMaskAlpha = alpha;
    848 		mMaskStateDirty = true;
    849 	}
    850 }
    851 
    852 void Context::setDepthMask(bool mask)
    853 {
    854 	if(mState.depthMask != mask)
    855 	{
    856 		mState.depthMask = mask;
    857 		mMaskStateDirty = true;
    858 	}
    859 }
    860 
    861 void Context::setActiveSampler(unsigned int active)
    862 {
    863 	mState.activeSampler = active;
    864 }
    865 
    866 GLuint Context::getFramebufferName() const
    867 {
    868 	return mState.framebuffer;
    869 }
    870 
    871 GLuint Context::getRenderbufferName() const
    872 {
    873 	return mState.renderbuffer.name();
    874 }
    875 
    876 GLuint Context::getArrayBufferName() const
    877 {
    878 	return mState.arrayBuffer.name();
    879 }
    880 
    881 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
    882 {
    883 	mState.vertexAttribute[attribNum].mArrayEnabled = enabled;
    884 }
    885 
    886 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum)
    887 {
    888 	return mState.vertexAttribute[attribNum];
    889 }
    890 
    891 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
    892                                    GLsizei stride, const void *pointer)
    893 {
    894 	mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
    895 	mState.vertexAttribute[attribNum].mSize = size;
    896 	mState.vertexAttribute[attribNum].mType = type;
    897 	mState.vertexAttribute[attribNum].mNormalized = normalized;
    898 	mState.vertexAttribute[attribNum].mStride = stride;
    899 	mState.vertexAttribute[attribNum].mPointer = pointer;
    900 }
    901 
    902 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
    903 {
    904 	return mState.vertexAttribute[attribNum].mPointer;
    905 }
    906 
    907 const VertexAttributeArray &Context::getVertexAttributes()
    908 {
    909 	return mState.vertexAttribute;
    910 }
    911 
    912 void Context::setPackAlignment(GLint alignment)
    913 {
    914 	mState.packAlignment = alignment;
    915 }
    916 
    917 GLint Context::getPackAlignment() const
    918 {
    919 	return mState.packAlignment;
    920 }
    921 
    922 void Context::setUnpackAlignment(GLint alignment)
    923 {
    924 	mState.unpackAlignment = alignment;
    925 }
    926 
    927 GLint Context::getUnpackAlignment() const
    928 {
    929 	return mState.unpackAlignment;
    930 }
    931 
    932 GLuint Context::createBuffer()
    933 {
    934 	return mResourceManager->createBuffer();
    935 }
    936 
    937 GLuint Context::createTexture()
    938 {
    939 	return mResourceManager->createTexture();
    940 }
    941 
    942 GLuint Context::createRenderbuffer()
    943 {
    944 	return mResourceManager->createRenderbuffer();
    945 }
    946 
    947 // Returns an unused framebuffer name
    948 GLuint Context::createFramebuffer()
    949 {
    950 	return mFramebufferNameSpace.allocate();
    951 }
    952 
    953 void Context::deleteBuffer(GLuint buffer)
    954 {
    955 	detachBuffer(buffer);
    956 
    957 	mResourceManager->deleteBuffer(buffer);
    958 }
    959 
    960 void Context::deleteTexture(GLuint texture)
    961 {
    962 	detachTexture(texture);
    963 
    964 	mResourceManager->deleteTexture(texture);
    965 }
    966 
    967 void Context::deleteRenderbuffer(GLuint renderbuffer)
    968 {
    969 	detachRenderbuffer(renderbuffer);
    970 
    971 	mResourceManager->deleteRenderbuffer(renderbuffer);
    972 }
    973 
    974 void Context::deleteFramebuffer(GLuint framebuffer)
    975 {
    976 	detachFramebuffer(framebuffer);
    977 
    978 	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
    979 
    980 	if(framebufferObject)
    981 	{
    982 		delete framebufferObject;
    983 	}
    984 }
    985 
    986 Buffer *Context::getBuffer(GLuint handle)
    987 {
    988 	return mResourceManager->getBuffer(handle);
    989 }
    990 
    991 Texture *Context::getTexture(GLuint handle)
    992 {
    993 	return mResourceManager->getTexture(handle);
    994 }
    995 
    996 Renderbuffer *Context::getRenderbuffer(GLuint handle)
    997 {
    998 	return mResourceManager->getRenderbuffer(handle);
    999 }
   1000 
   1001 Framebuffer *Context::getFramebuffer()
   1002 {
   1003 	return getFramebuffer(mState.framebuffer);
   1004 }
   1005 
   1006 void Context::bindArrayBuffer(unsigned int buffer)
   1007 {
   1008 	mResourceManager->checkBufferAllocation(buffer);
   1009 
   1010 	mState.arrayBuffer = getBuffer(buffer);
   1011 }
   1012 
   1013 void Context::bindElementArrayBuffer(unsigned int buffer)
   1014 {
   1015 	mResourceManager->checkBufferAllocation(buffer);
   1016 
   1017 	mState.elementArrayBuffer = getBuffer(buffer);
   1018 }
   1019 
   1020 void Context::bindTexture(TextureType type, GLuint texture)
   1021 {
   1022 	mResourceManager->checkTextureAllocation(texture, type);
   1023 
   1024 	mState.samplerTexture[type][mState.activeSampler] = getTexture(texture);
   1025 }
   1026 
   1027 void Context::bindFramebuffer(GLuint framebuffer)
   1028 {
   1029 	if(!getFramebuffer(framebuffer))
   1030 	{
   1031 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
   1032 	}
   1033 
   1034 	mState.framebuffer = framebuffer;
   1035 }
   1036 
   1037 void Context::bindRenderbuffer(GLuint renderbuffer)
   1038 {
   1039 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
   1040 
   1041 	mState.renderbuffer = getRenderbuffer(renderbuffer);
   1042 }
   1043 
   1044 void Context::setFramebufferZero(Framebuffer *buffer)
   1045 {
   1046 	delete mFramebufferNameSpace.remove(0);
   1047 	mFramebufferNameSpace.insert(0, buffer);
   1048 }
   1049 
   1050 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
   1051 {
   1052 	Renderbuffer *renderbufferObject = mState.renderbuffer;
   1053 	renderbufferObject->setStorage(renderbuffer);
   1054 }
   1055 
   1056 Framebuffer *Context::getFramebuffer(unsigned int handle)
   1057 {
   1058 	return mFramebufferNameSpace.find(handle);
   1059 }
   1060 
   1061 Buffer *Context::getArrayBuffer()
   1062 {
   1063 	return mState.arrayBuffer;
   1064 }
   1065 
   1066 Buffer *Context::getElementArrayBuffer()
   1067 {
   1068 	return mState.elementArrayBuffer;
   1069 }
   1070 
   1071 Texture2D *Context::getTexture2D()
   1072 {
   1073 	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
   1074 }
   1075 
   1076 TextureExternal *Context::getTextureExternal()
   1077 {
   1078 	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
   1079 }
   1080 
   1081 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type)
   1082 {
   1083 	GLuint texid = mState.samplerTexture[type][sampler].name();
   1084 
   1085 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
   1086 	{
   1087 		switch(type)
   1088 		{
   1089 		case TEXTURE_2D: return mTexture2DZero;
   1090 		case TEXTURE_EXTERNAL: return mTextureExternalZero;
   1091 		default: UNREACHABLE(type);
   1092 		}
   1093 	}
   1094 
   1095 	return mState.samplerTexture[type][sampler];
   1096 }
   1097 
   1098 bool Context::getBooleanv(GLenum pname, GLboolean *params)
   1099 {
   1100 	switch(pname)
   1101 	{
   1102 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;         break;
   1103 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                    break;
   1104 	case GL_COLOR_WRITEMASK:
   1105 		params[0] = mState.colorMaskRed;
   1106 		params[1] = mState.colorMaskGreen;
   1107 		params[2] = mState.colorMaskBlue;
   1108 		params[3] = mState.colorMaskAlpha;
   1109 		break;
   1110 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;              break;
   1111 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;     break;
   1112 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break;
   1113 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;        break;
   1114 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;           break;
   1115 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;           break;
   1116 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;             break;
   1117 	case GL_BLEND:                    *params = mState.blendEnabled;                 break;
   1118 	case GL_DITHER:                   *params = mState.ditherEnabled;                break;
   1119 	case GL_LIGHT_MODEL_TWO_SIDE:     *params = lightModelTwoSide;                   break;
   1120 	default:
   1121 		return false;
   1122 	}
   1123 
   1124 	return true;
   1125 }
   1126 
   1127 bool Context::getFloatv(GLenum pname, GLfloat *params)
   1128 {
   1129 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   1130 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1131 	// GetIntegerv as its native query function. As it would require conversion in any
   1132 	// case, this should make no difference to the calling application.
   1133 	switch(pname)
   1134 	{
   1135 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
   1136 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
   1137 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
   1138 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
   1139 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
   1140 	case GL_ALIASED_LINE_WIDTH_RANGE:
   1141 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
   1142 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
   1143 		break;
   1144 	case GL_ALIASED_POINT_SIZE_RANGE:
   1145 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
   1146 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
   1147 		break;
   1148 	case GL_SMOOTH_LINE_WIDTH_RANGE:
   1149 		params[0] = SMOOTH_LINE_WIDTH_RANGE_MIN;
   1150 		params[1] = SMOOTH_LINE_WIDTH_RANGE_MAX;
   1151 		break;
   1152 	case GL_SMOOTH_POINT_SIZE_RANGE:
   1153 		params[0] = SMOOTH_POINT_SIZE_RANGE_MIN;
   1154 		params[1] = SMOOTH_POINT_SIZE_RANGE_MAX;
   1155 		break;
   1156 	case GL_DEPTH_RANGE:
   1157 		params[0] = mState.zNear;
   1158 		params[1] = mState.zFar;
   1159 		break;
   1160 	case GL_COLOR_CLEAR_VALUE:
   1161 		params[0] = mState.colorClearValue.red;
   1162 		params[1] = mState.colorClearValue.green;
   1163 		params[2] = mState.colorClearValue.blue;
   1164 		params[3] = mState.colorClearValue.alpha;
   1165 		break;
   1166 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1167 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
   1168 		break;
   1169 	case GL_MODELVIEW_MATRIX:
   1170 		for(int i = 0; i < 16; i++)
   1171 		{
   1172 			params[i] = modelViewStack.current()[i % 4][i / 4];
   1173 		}
   1174 		break;
   1175 	case GL_PROJECTION_MATRIX:
   1176 		for(int i = 0; i < 16; i++)
   1177 		{
   1178 			params[i] = projectionStack.current()[i % 4][i / 4];
   1179 		}
   1180 		break;
   1181 	case GL_CURRENT_COLOR:
   1182 		for(int i = 0; i < 4; i++)
   1183 		{
   1184 			params[i] = mState.vertexAttribute[sw::Color0].mCurrentValue[i];
   1185 		}
   1186 		break;
   1187 	case GL_CURRENT_NORMAL:
   1188 		for(int i = 0; i < 3; i++)
   1189 		{
   1190 			params[i] = mState.vertexAttribute[sw::Normal].mCurrentValue[i];
   1191 		}
   1192 		break;
   1193 	case GL_CURRENT_TEXTURE_COORDS:
   1194 		for(int i = 0; i < 4; i++)
   1195 		{
   1196 			params[i] = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[i];
   1197 		}
   1198 		break;
   1199 	default:
   1200 		return false;
   1201 	}
   1202 
   1203 	return true;
   1204 }
   1205 
   1206 bool Context::getIntegerv(GLenum pname, GLint *params)
   1207 {
   1208 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   1209 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1210 	// GetIntegerv as its native query function. As it would require conversion in any
   1211 	// case, this should make no difference to the calling application. You may find it in
   1212 	// Context::getFloatv.
   1213 	switch(pname)
   1214 	{
   1215 	case GL_ARRAY_BUFFER_BINDING:             *params = mState.arrayBuffer.name();            break;
   1216 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = mState.elementArrayBuffer.name();     break;
   1217 	case GL_FRAMEBUFFER_BINDING_OES:          *params = mState.framebuffer;                   break;
   1218 	case GL_RENDERBUFFER_BINDING_OES:         *params = mState.renderbuffer.name();           break;
   1219 	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
   1220 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackAlignment;               break;
   1221 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
   1222 	case GL_PERSPECTIVE_CORRECTION_HINT:      *params = mState.perspectiveCorrectionHint;     break;
   1223 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
   1224 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
   1225 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
   1226 	case GL_STENCIL_VALUE_MASK:               *params = mState.stencilMask;                   break;
   1227 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
   1228 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
   1229 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
   1230 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
   1231 	case GL_BLEND_SRC_RGB_OES:                *params = mState.sourceBlendRGB;                break;
   1232 	case GL_BLEND_SRC_ALPHA_OES:              *params = mState.sourceBlendAlpha;              break;
   1233 	case GL_BLEND_DST_RGB_OES:                *params = mState.destBlendRGB;                  break;
   1234 	case GL_BLEND_DST_ALPHA_OES:              *params = mState.destBlendAlpha;                break;
   1235 	case GL_BLEND_EQUATION_RGB_OES:           *params = mState.blendEquationRGB;              break;
   1236 	case GL_BLEND_EQUATION_ALPHA_OES:         *params = mState.blendEquationAlpha;            break;
   1237 	case GL_STENCIL_WRITEMASK:                *params = mState.stencilWritemask;              break;
   1238 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
   1239 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
   1240 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;      break;
   1241 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;       break;
   1242 	case GL_SAMPLE_BUFFERS:
   1243 	case GL_SAMPLES:
   1244 		{
   1245 			Framebuffer *framebuffer = getFramebuffer();
   1246 			int width, height, samples;
   1247 
   1248 			if(framebuffer && (framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE_OES))
   1249 			{
   1250 				switch(pname)
   1251 				{
   1252 				case GL_SAMPLE_BUFFERS:
   1253 					if(samples > 1)
   1254 					{
   1255 						*params = 1;
   1256 					}
   1257 					else
   1258 					{
   1259 						*params = 0;
   1260 					}
   1261 					break;
   1262 				case GL_SAMPLES:
   1263 					*params = samples;
   1264 					break;
   1265 				}
   1266 			}
   1267 			else
   1268 			{
   1269 				*params = 0;
   1270 			}
   1271 		}
   1272 		break;
   1273 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
   1274 		{
   1275 			Framebuffer *framebuffer = getFramebuffer();
   1276 			if(framebuffer)
   1277 			{
   1278 				*params = framebuffer->getImplementationColorReadType();
   1279 			}
   1280 			else
   1281 			{
   1282 				return error(GL_INVALID_OPERATION, true);
   1283 			}
   1284 		}
   1285 		break;
   1286 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
   1287 		{
   1288 			Framebuffer *framebuffer = getFramebuffer();
   1289 			if(framebuffer)
   1290 			{
   1291 				*params = framebuffer->getImplementationColorReadFormat();
   1292 			}
   1293 			else
   1294 			{
   1295 				return error(GL_INVALID_OPERATION, true);
   1296 			}
   1297 		}
   1298 		break;
   1299 	case GL_MAX_VIEWPORT_DIMS:
   1300 		{
   1301 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
   1302 			params[0] = maxDimension;
   1303 			params[1] = maxDimension;
   1304 		}
   1305 		break;
   1306 	case GL_COMPRESSED_TEXTURE_FORMATS:
   1307 		{
   1308 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
   1309 			{
   1310 				params[i] = compressedTextureFormats[i];
   1311 			}
   1312 		}
   1313 		break;
   1314 	case GL_VIEWPORT:
   1315 		params[0] = mState.viewportX;
   1316 		params[1] = mState.viewportY;
   1317 		params[2] = mState.viewportWidth;
   1318 		params[3] = mState.viewportHeight;
   1319 		break;
   1320 	case GL_SCISSOR_BOX:
   1321 		params[0] = mState.scissorX;
   1322 		params[1] = mState.scissorY;
   1323 		params[2] = mState.scissorWidth;
   1324 		params[3] = mState.scissorHeight;
   1325 		break;
   1326 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
   1327 	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
   1328 	case GL_RED_BITS:
   1329 	case GL_GREEN_BITS:
   1330 	case GL_BLUE_BITS:
   1331 	case GL_ALPHA_BITS:
   1332 		{
   1333 			Framebuffer *framebuffer = getFramebuffer();
   1334 			Renderbuffer *colorbuffer = framebuffer ? framebuffer->getColorbuffer() : nullptr;
   1335 
   1336 			if(colorbuffer)
   1337 			{
   1338 				switch(pname)
   1339 				{
   1340 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
   1341 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
   1342 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
   1343 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
   1344 				}
   1345 			}
   1346 			else
   1347 			{
   1348 				*params = 0;
   1349 			}
   1350 		}
   1351 		break;
   1352 	case GL_DEPTH_BITS:
   1353 		{
   1354 			Framebuffer *framebuffer = getFramebuffer();
   1355 			Renderbuffer *depthbuffer = framebuffer ? framebuffer->getDepthbuffer() : nullptr;
   1356 
   1357 			if(depthbuffer)
   1358 			{
   1359 				*params = depthbuffer->getDepthSize();
   1360 			}
   1361 			else
   1362 			{
   1363 				*params = 0;
   1364 			}
   1365 		}
   1366 		break;
   1367 	case GL_STENCIL_BITS:
   1368 		{
   1369 			Framebuffer *framebuffer = getFramebuffer();
   1370 			Renderbuffer *stencilbuffer = framebuffer ? framebuffer->getStencilbuffer() : nullptr;
   1371 
   1372 			if(stencilbuffer)
   1373 			{
   1374 				*params = stencilbuffer->getStencilSize();
   1375 			}
   1376 			else
   1377 			{
   1378 				*params = 0;
   1379 			}
   1380 		}
   1381 		break;
   1382 	case GL_TEXTURE_BINDING_2D:                  *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();                   break;
   1383 	case GL_TEXTURE_BINDING_EXTERNAL_OES:        *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();             break;
   1384 	case GL_MAX_LIGHTS:                          *params = MAX_LIGHTS;                                                                       break;
   1385 	case GL_MAX_MODELVIEW_STACK_DEPTH:           *params = MAX_MODELVIEW_STACK_DEPTH;                                                        break;
   1386 	case GL_MAX_PROJECTION_STACK_DEPTH:          *params = MAX_PROJECTION_STACK_DEPTH;                                                       break;
   1387 	case GL_MAX_TEXTURE_STACK_DEPTH:             *params = MAX_TEXTURE_STACK_DEPTH;                                                          break;
   1388 	case GL_MAX_TEXTURE_UNITS:                   *params = MAX_TEXTURE_UNITS;                                                                break;
   1389 	case GL_MAX_CLIP_PLANES:                     *params = MAX_CLIP_PLANES;                                                                  break;
   1390 	case GL_POINT_SIZE_ARRAY_TYPE_OES:           *params = mState.vertexAttribute[sw::PointSize].mType;                                      break;
   1391 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:         *params = mState.vertexAttribute[sw::PointSize].mStride;                                    break;
   1392 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: *params = mState.vertexAttribute[sw::PointSize].mBoundBuffer.name();                        break;
   1393 	case GL_VERTEX_ARRAY_SIZE:                   *params = mState.vertexAttribute[sw::Position].mSize;                                       break;
   1394 	case GL_VERTEX_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Position].mType;                                       break;
   1395 	case GL_VERTEX_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Position].mStride;                                     break;
   1396 	case GL_VERTEX_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Position].mBoundBuffer.name();                         break;
   1397 	case GL_NORMAL_ARRAY_TYPE:                   *params = mState.vertexAttribute[sw::Normal].mType;                                         break;
   1398 	case GL_NORMAL_ARRAY_STRIDE:                 *params = mState.vertexAttribute[sw::Normal].mStride;                                       break;
   1399 	case GL_NORMAL_ARRAY_BUFFER_BINDING:         *params = mState.vertexAttribute[sw::Normal].mBoundBuffer.name();                           break;
   1400 	case GL_COLOR_ARRAY_SIZE:                    *params = mState.vertexAttribute[sw::Color0].mSize;                                         break;
   1401 	case GL_COLOR_ARRAY_TYPE:                    *params = mState.vertexAttribute[sw::Color0].mType;                                         break;
   1402 	case GL_COLOR_ARRAY_STRIDE:                  *params = mState.vertexAttribute[sw::Color0].mStride;                                       break;
   1403 	case GL_COLOR_ARRAY_BUFFER_BINDING:          *params = mState.vertexAttribute[sw::Color0].mBoundBuffer.name();                           break;
   1404 	case GL_TEXTURE_COORD_ARRAY_SIZE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mSize;               break;
   1405 	case GL_TEXTURE_COORD_ARRAY_TYPE:            *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mType;               break;
   1406 	case GL_TEXTURE_COORD_ARRAY_STRIDE:          *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mStride;             break;
   1407 	case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mBoundBuffer.name(); break;
   1408 	default:
   1409 		return false;
   1410 	}
   1411 
   1412 	return true;
   1413 }
   1414 
   1415 bool Context::getPointerv(GLenum pname, const GLvoid **params)
   1416 {
   1417 	switch(pname)
   1418 	{
   1419 	case GL_VERTEX_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Position].mPointer;                         break;
   1420 	case GL_NORMAL_ARRAY_POINTER:         *params = mState.vertexAttribute[sw::Normal].mPointer;                           break;
   1421 	case GL_COLOR_ARRAY_POINTER:          *params = mState.vertexAttribute[sw::Color0].mPointer;                           break;
   1422 	case GL_POINT_SIZE_ARRAY_POINTER_OES: *params = mState.vertexAttribute[sw::PointSize].mPointer;                        break;
   1423 	case GL_TEXTURE_COORD_ARRAY_POINTER:  *params = mState.vertexAttribute[sw::TexCoord0 + mState.activeSampler].mPointer; break;
   1424 	default:
   1425 		return false;
   1426 	}
   1427 
   1428 	return true;
   1429 }
   1430 
   1431 int Context::getQueryParameterNum(GLenum pname)
   1432 {
   1433 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   1434 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   1435 	// to the fact that it is stored internally as a float, and so would require conversion
   1436 	// if returned from Context::getIntegerv. Since this conversion is already implemented
   1437 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   1438 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   1439 	// application.
   1440 	switch(pname)
   1441 	{
   1442 	case GL_COMPRESSED_TEXTURE_FORMATS:
   1443 		return NUM_COMPRESSED_TEXTURE_FORMATS;
   1444 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1445 	case GL_ARRAY_BUFFER_BINDING:
   1446 	case GL_FRAMEBUFFER_BINDING_OES:
   1447 	case GL_RENDERBUFFER_BINDING_OES:
   1448 	case GL_PACK_ALIGNMENT:
   1449 	case GL_UNPACK_ALIGNMENT:
   1450 	case GL_GENERATE_MIPMAP_HINT:
   1451 	case GL_RED_BITS:
   1452 	case GL_GREEN_BITS:
   1453 	case GL_BLUE_BITS:
   1454 	case GL_ALPHA_BITS:
   1455 	case GL_DEPTH_BITS:
   1456 	case GL_STENCIL_BITS:
   1457 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   1458 	case GL_CULL_FACE_MODE:
   1459 	case GL_FRONT_FACE:
   1460 	case GL_ACTIVE_TEXTURE:
   1461 	case GL_STENCIL_FUNC:
   1462 	case GL_STENCIL_VALUE_MASK:
   1463 	case GL_STENCIL_REF:
   1464 	case GL_STENCIL_FAIL:
   1465 	case GL_STENCIL_PASS_DEPTH_FAIL:
   1466 	case GL_STENCIL_PASS_DEPTH_PASS:
   1467 	case GL_DEPTH_FUNC:
   1468 	case GL_BLEND_SRC_RGB_OES:
   1469 	case GL_BLEND_SRC_ALPHA_OES:
   1470 	case GL_BLEND_DST_RGB_OES:
   1471 	case GL_BLEND_DST_ALPHA_OES:
   1472 	case GL_BLEND_EQUATION_RGB_OES:
   1473 	case GL_BLEND_EQUATION_ALPHA_OES:
   1474 	case GL_STENCIL_WRITEMASK:
   1475 	case GL_STENCIL_CLEAR_VALUE:
   1476 	case GL_SUBPIXEL_BITS:
   1477 	case GL_MAX_TEXTURE_SIZE:
   1478 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
   1479 	case GL_SAMPLE_BUFFERS:
   1480 	case GL_SAMPLES:
   1481 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
   1482 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
   1483 	case GL_TEXTURE_BINDING_2D:
   1484 	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
   1485 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
   1486 		return 1;
   1487 	case GL_MAX_VIEWPORT_DIMS:
   1488 		return 2;
   1489 	case GL_VIEWPORT:
   1490 	case GL_SCISSOR_BOX:
   1491 		return 4;
   1492 	case GL_SAMPLE_COVERAGE_INVERT:
   1493 	case GL_DEPTH_WRITEMASK:
   1494 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   1495 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   1496 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   1497 	case GL_SAMPLE_COVERAGE:
   1498 	case GL_SCISSOR_TEST:
   1499 	case GL_STENCIL_TEST:
   1500 	case GL_DEPTH_TEST:
   1501 	case GL_BLEND:
   1502 	case GL_DITHER:
   1503 		return 1;
   1504 	case GL_COLOR_WRITEMASK:
   1505 		return 4;
   1506 	case GL_POLYGON_OFFSET_FACTOR:
   1507 	case GL_POLYGON_OFFSET_UNITS:
   1508 	case GL_SAMPLE_COVERAGE_VALUE:
   1509 	case GL_DEPTH_CLEAR_VALUE:
   1510 	case GL_LINE_WIDTH:
   1511 		return 1;
   1512 	case GL_ALIASED_LINE_WIDTH_RANGE:
   1513 	case GL_ALIASED_POINT_SIZE_RANGE:
   1514 	case GL_DEPTH_RANGE:
   1515 		return 2;
   1516 	case GL_COLOR_CLEAR_VALUE:
   1517 		return 4;
   1518 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1519 	case GL_MAX_LIGHTS:
   1520 	case GL_MAX_MODELVIEW_STACK_DEPTH:
   1521 	case GL_MAX_PROJECTION_STACK_DEPTH:
   1522 	case GL_MAX_TEXTURE_STACK_DEPTH:
   1523 	case GL_MAX_TEXTURE_UNITS:
   1524 	case GL_MAX_CLIP_PLANES:
   1525 	case GL_POINT_SIZE_ARRAY_TYPE_OES:
   1526 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
   1527 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
   1528 		return 1;
   1529 	case GL_CURRENT_COLOR:
   1530 		return 4;
   1531 	case GL_CURRENT_NORMAL:
   1532 		return 3;
   1533 	case GL_CURRENT_TEXTURE_COORDS:
   1534 		return 4;
   1535 	case GL_POINT_SIZE:
   1536 	case GL_POINT_SIZE_MIN:
   1537 	case GL_POINT_SIZE_MAX:
   1538 	case GL_POINT_FADE_THRESHOLD_SIZE:
   1539 		return 1;
   1540 	case GL_POINT_DISTANCE_ATTENUATION:
   1541 		return 3;
   1542 	case GL_SMOOTH_POINT_SIZE_RANGE:
   1543 	case GL_SMOOTH_LINE_WIDTH_RANGE:
   1544 		return 2;
   1545 	case GL_SHADE_MODEL:
   1546 	case GL_MATRIX_MODE:
   1547 	case GL_MODELVIEW_STACK_DEPTH:
   1548 	case GL_PROJECTION_STACK_DEPTH:
   1549 	case GL_TEXTURE_STACK_DEPTH:
   1550 		return 1;
   1551 	case GL_MODELVIEW_MATRIX:
   1552 	case GL_PROJECTION_MATRIX:
   1553 	case GL_TEXTURE_MATRIX:
   1554 		return 16;
   1555 	case GL_ALPHA_TEST_FUNC:
   1556 	case GL_ALPHA_TEST_REF:
   1557 	case GL_BLEND_DST:
   1558 	case GL_BLEND_SRC:
   1559 	case GL_LOGIC_OP_MODE:
   1560 	case GL_VERTEX_ARRAY_SIZE:
   1561 	case GL_VERTEX_ARRAY_TYPE:
   1562 	case GL_VERTEX_ARRAY_STRIDE:
   1563 	case GL_NORMAL_ARRAY_TYPE:
   1564 	case GL_NORMAL_ARRAY_STRIDE:
   1565 	case GL_COLOR_ARRAY_SIZE:
   1566 	case GL_COLOR_ARRAY_TYPE:
   1567 	case GL_COLOR_ARRAY_STRIDE:
   1568 	case GL_TEXTURE_COORD_ARRAY_SIZE:
   1569 	case GL_TEXTURE_COORD_ARRAY_TYPE:
   1570 	case GL_TEXTURE_COORD_ARRAY_STRIDE:
   1571 	case GL_VERTEX_ARRAY_POINTER:
   1572 	case GL_NORMAL_ARRAY_POINTER:
   1573 	case GL_COLOR_ARRAY_POINTER:
   1574 	case GL_TEXTURE_COORD_ARRAY_POINTER:
   1575 	case GL_LIGHT_MODEL_TWO_SIDE:
   1576 		return 1;
   1577 	default:
   1578 		UNREACHABLE(pname);
   1579 	}
   1580 
   1581 	return -1;
   1582 }
   1583 
   1584 bool Context::isQueryParameterInt(GLenum pname)
   1585 {
   1586 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   1587 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   1588 	// to the fact that it is stored internally as a float, and so would require conversion
   1589 	// if returned from Context::getIntegerv. Since this conversion is already implemented
   1590 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   1591 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   1592 	// application.
   1593 	switch(pname)
   1594 	{
   1595 	case GL_COMPRESSED_TEXTURE_FORMATS:
   1596 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   1597 	case GL_ARRAY_BUFFER_BINDING:
   1598 	case GL_FRAMEBUFFER_BINDING_OES:
   1599 	case GL_RENDERBUFFER_BINDING_OES:
   1600 	case GL_PACK_ALIGNMENT:
   1601 	case GL_UNPACK_ALIGNMENT:
   1602 	case GL_GENERATE_MIPMAP_HINT:
   1603 	case GL_RED_BITS:
   1604 	case GL_GREEN_BITS:
   1605 	case GL_BLUE_BITS:
   1606 	case GL_ALPHA_BITS:
   1607 	case GL_DEPTH_BITS:
   1608 	case GL_STENCIL_BITS:
   1609 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   1610 	case GL_CULL_FACE_MODE:
   1611 	case GL_FRONT_FACE:
   1612 	case GL_ACTIVE_TEXTURE:
   1613 	case GL_STENCIL_FUNC:
   1614 	case GL_STENCIL_VALUE_MASK:
   1615 	case GL_STENCIL_REF:
   1616 	case GL_STENCIL_FAIL:
   1617 	case GL_STENCIL_PASS_DEPTH_FAIL:
   1618 	case GL_STENCIL_PASS_DEPTH_PASS:
   1619 	case GL_DEPTH_FUNC:
   1620 	case GL_BLEND_SRC_RGB_OES:
   1621 	case GL_BLEND_SRC_ALPHA_OES:
   1622 	case GL_BLEND_DST_RGB_OES:
   1623 	case GL_BLEND_DST_ALPHA_OES:
   1624 	case GL_BLEND_EQUATION_RGB_OES:
   1625 	case GL_BLEND_EQUATION_ALPHA_OES:
   1626 	case GL_STENCIL_WRITEMASK:
   1627 	case GL_STENCIL_CLEAR_VALUE:
   1628 	case GL_SUBPIXEL_BITS:
   1629 	case GL_MAX_TEXTURE_SIZE:
   1630 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES:
   1631 	case GL_SAMPLE_BUFFERS:
   1632 	case GL_SAMPLES:
   1633 	case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
   1634 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
   1635 	case GL_TEXTURE_BINDING_2D:
   1636 	case GL_TEXTURE_BINDING_CUBE_MAP_OES:
   1637 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
   1638 	case GL_MAX_VIEWPORT_DIMS:
   1639 	case GL_VIEWPORT:
   1640 	case GL_SCISSOR_BOX:
   1641 	case GL_MAX_LIGHTS:
   1642 	case GL_MAX_MODELVIEW_STACK_DEPTH:
   1643 	case GL_MAX_PROJECTION_STACK_DEPTH:
   1644 	case GL_MAX_TEXTURE_STACK_DEPTH:
   1645 	case GL_MAX_TEXTURE_UNITS:
   1646 	case GL_MAX_CLIP_PLANES:
   1647 	case GL_POINT_SIZE_ARRAY_TYPE_OES:
   1648 	case GL_POINT_SIZE_ARRAY_STRIDE_OES:
   1649 	case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
   1650 		return true;
   1651 	}
   1652 
   1653 	return false;
   1654 }
   1655 
   1656 bool Context::isQueryParameterFloat(GLenum pname)
   1657 {
   1658 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   1659 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   1660 	// to the fact that it is stored internally as a float, and so would require conversion
   1661 	// if returned from Context::getIntegerv. Since this conversion is already implemented
   1662 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   1663 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   1664 	// application.
   1665 	switch(pname)
   1666 	{
   1667 	case GL_POLYGON_OFFSET_FACTOR:
   1668 	case GL_POLYGON_OFFSET_UNITS:
   1669 	case GL_SAMPLE_COVERAGE_VALUE:
   1670 	case GL_DEPTH_CLEAR_VALUE:
   1671 	case GL_LINE_WIDTH:
   1672 	case GL_ALIASED_LINE_WIDTH_RANGE:
   1673 	case GL_ALIASED_POINT_SIZE_RANGE:
   1674 	case GL_SMOOTH_LINE_WIDTH_RANGE:
   1675 	case GL_SMOOTH_POINT_SIZE_RANGE:
   1676 	case GL_DEPTH_RANGE:
   1677 	case GL_COLOR_CLEAR_VALUE:
   1678 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1679 	case GL_LIGHT_MODEL_AMBIENT:
   1680 	case GL_POINT_SIZE_MIN:
   1681 	case GL_POINT_SIZE_MAX:
   1682 	case GL_POINT_DISTANCE_ATTENUATION:
   1683 	case GL_POINT_FADE_THRESHOLD_SIZE:
   1684 		return true;
   1685 	}
   1686 
   1687 	return false;
   1688 }
   1689 
   1690 bool Context::isQueryParameterBool(GLenum pname)
   1691 {
   1692 	switch(pname)
   1693 	{
   1694 	case GL_SAMPLE_COVERAGE_INVERT:
   1695 	case GL_DEPTH_WRITEMASK:
   1696 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   1697 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   1698 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   1699 	case GL_SAMPLE_COVERAGE:
   1700 	case GL_SCISSOR_TEST:
   1701 	case GL_STENCIL_TEST:
   1702 	case GL_DEPTH_TEST:
   1703 	case GL_BLEND:
   1704 	case GL_DITHER:
   1705 	case GL_COLOR_WRITEMASK:
   1706 	case GL_LIGHT_MODEL_TWO_SIDE:
   1707 		return true;
   1708 	}
   1709 
   1710 	return false;
   1711 }
   1712 
   1713 bool Context::isQueryParameterPointer(GLenum pname)
   1714 {
   1715 	switch(pname)
   1716 	{
   1717 	case GL_VERTEX_ARRAY_POINTER:
   1718 	case GL_NORMAL_ARRAY_POINTER:
   1719 	case GL_COLOR_ARRAY_POINTER:
   1720 	case GL_TEXTURE_COORD_ARRAY_POINTER:
   1721 	case GL_POINT_SIZE_ARRAY_POINTER_OES:
   1722 		return true;
   1723 	}
   1724 
   1725 	return false;
   1726 }
   1727 
   1728 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
   1729 bool Context::applyRenderTarget()
   1730 {
   1731 	Framebuffer *framebuffer = getFramebuffer();
   1732 	int width, height, samples;
   1733 
   1734 	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE_OES)
   1735 	{
   1736 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES, false);
   1737 	}
   1738 
   1739 	egl::Image *renderTarget = framebuffer->getRenderTarget();
   1740 	device->setRenderTarget(0, renderTarget);
   1741 	if(renderTarget) renderTarget->release();
   1742 
   1743 	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
   1744 	device->setDepthBuffer(depthBuffer);
   1745 	if(depthBuffer) depthBuffer->release();
   1746 
   1747 	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
   1748 	device->setStencilBuffer(stencilBuffer);
   1749 	if(stencilBuffer) stencilBuffer->release();
   1750 
   1751 	Viewport viewport;
   1752 	float zNear = clamp01(mState.zNear);
   1753 	float zFar = clamp01(mState.zFar);
   1754 
   1755 	viewport.x0 = mState.viewportX;
   1756 	viewport.y0 = mState.viewportY;
   1757 	viewport.width = mState.viewportWidth;
   1758 	viewport.height = mState.viewportHeight;
   1759 	viewport.minZ = zNear;
   1760 	viewport.maxZ = zFar;
   1761 
   1762 	device->setViewport(viewport);
   1763 
   1764 	if(mState.scissorTestEnabled)
   1765 	{
   1766 		sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight};
   1767 		scissor.clip(0, 0, width, height);
   1768 
   1769 		device->setScissorRect(scissor);
   1770 		device->setScissorEnable(true);
   1771 	}
   1772 	else
   1773 	{
   1774 		device->setScissorEnable(false);
   1775 	}
   1776 
   1777 	return true;
   1778 }
   1779 
   1780 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
   1781 void Context::applyState(GLenum drawMode)
   1782 {
   1783 	Framebuffer *framebuffer = getFramebuffer();
   1784 
   1785 	if(mState.cullFaceEnabled)
   1786 	{
   1787 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
   1788 	}
   1789 	else
   1790 	{
   1791 		device->setCullMode(sw::CULL_NONE);
   1792 	}
   1793 
   1794 	if(mDepthStateDirty)
   1795 	{
   1796 		if(mState.depthTestEnabled)
   1797 		{
   1798 			device->setDepthBufferEnable(true);
   1799 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
   1800 		}
   1801 		else
   1802 		{
   1803 			device->setDepthBufferEnable(false);
   1804 		}
   1805 
   1806 		mDepthStateDirty = false;
   1807 	}
   1808 
   1809 	if(mBlendStateDirty)
   1810 	{
   1811 		if(mState.blendEnabled)
   1812 		{
   1813 			device->setAlphaBlendEnable(true);
   1814 			device->setSeparateAlphaBlendEnable(true);
   1815 
   1816 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
   1817 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
   1818 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
   1819 
   1820 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
   1821 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
   1822 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
   1823 		}
   1824 		else
   1825 		{
   1826 			device->setAlphaBlendEnable(false);
   1827 		}
   1828 
   1829 		mBlendStateDirty = false;
   1830 	}
   1831 
   1832 	if(mStencilStateDirty || mFrontFaceDirty)
   1833 	{
   1834 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
   1835 		{
   1836 			device->setStencilEnable(true);
   1837 			device->setTwoSidedStencil(true);
   1838 
   1839 			// get the maximum size of the stencil ref
   1840 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
   1841 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
   1842 
   1843 			device->setStencilWriteMask(mState.stencilWritemask);
   1844 			device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
   1845 
   1846 			device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
   1847 			device->setStencilMask(mState.stencilMask);
   1848 
   1849 			device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
   1850 			device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
   1851 			device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
   1852 
   1853 			device->setStencilWriteMaskCCW(mState.stencilWritemask);
   1854 			device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
   1855 
   1856 			device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
   1857 			device->setStencilMaskCCW(mState.stencilMask);
   1858 
   1859 			device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
   1860 			device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
   1861 			device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
   1862 		}
   1863 		else
   1864 		{
   1865 			device->setStencilEnable(false);
   1866 		}
   1867 
   1868 		mStencilStateDirty = false;
   1869 		mFrontFaceDirty = false;
   1870 	}
   1871 
   1872 	if(mMaskStateDirty)
   1873 	{
   1874 		device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
   1875 		device->setDepthWriteEnable(mState.depthMask);
   1876 
   1877 		mMaskStateDirty = false;
   1878 	}
   1879 
   1880 	if(mPolygonOffsetStateDirty)
   1881 	{
   1882 		if(mState.polygonOffsetFillEnabled)
   1883 		{
   1884 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
   1885 			if(depthbuffer)
   1886 			{
   1887 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
   1888 				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
   1889 				device->setDepthBias(depthBias);
   1890 			}
   1891 		}
   1892 		else
   1893 		{
   1894 			device->setSlopeDepthBias(0);
   1895 			device->setDepthBias(0);
   1896 		}
   1897 
   1898 		mPolygonOffsetStateDirty = false;
   1899 	}
   1900 
   1901 	if(mSampleStateDirty)
   1902 	{
   1903 		if(mState.sampleAlphaToCoverageEnabled)
   1904 		{
   1905 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
   1906 		}
   1907 		else
   1908 		{
   1909 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
   1910 		}
   1911 
   1912 		if(mState.sampleCoverageEnabled)
   1913 		{
   1914 			unsigned int mask = 0;
   1915 			if(mState.sampleCoverageValue != 0)
   1916 			{
   1917 				int width, height, samples;
   1918 				framebuffer->completeness(width, height, samples);
   1919 
   1920 				float threshold = 0.5f;
   1921 
   1922 				for(int i = 0; i < samples; i++)
   1923 				{
   1924 					mask <<= 1;
   1925 
   1926 					if((i + 1) * mState.sampleCoverageValue >= threshold)
   1927 					{
   1928 						threshold += 1.0f;
   1929 						mask |= 1;
   1930 					}
   1931 				}
   1932 			}
   1933 
   1934 			if(mState.sampleCoverageInvert)
   1935 			{
   1936 				mask = ~mask;
   1937 			}
   1938 
   1939 			device->setMultiSampleMask(mask);
   1940 		}
   1941 		else
   1942 		{
   1943 			device->setMultiSampleMask(0xFFFFFFFF);
   1944 		}
   1945 
   1946 		mSampleStateDirty = false;
   1947 	}
   1948 
   1949 	if(mDitherStateDirty)
   1950 	{
   1951 	//	UNIMPLEMENTED();   // FIXME
   1952 
   1953 		mDitherStateDirty = false;
   1954 	}
   1955 
   1956 	switch(mState.shadeModel)
   1957 	{
   1958 	default: UNREACHABLE(mState.shadeModel);
   1959 	case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break;
   1960 	case GL_FLAT:   device->setShadingMode(sw::SHADING_FLAT);    break;
   1961 	}
   1962 
   1963 	device->setLightingEnable(lightingEnabled);
   1964 	device->setGlobalAmbient(sw::Color<float>(globalAmbient.red, globalAmbient.green, globalAmbient.blue, globalAmbient.alpha));
   1965 
   1966 	for(int i = 0; i < MAX_LIGHTS; i++)
   1967 	{
   1968 		device->setLightEnable(i, light[i].enabled);
   1969 		device->setLightAmbient(i, sw::Color<float>(light[i].ambient.red, light[i].ambient.green, light[i].ambient.blue, light[i].ambient.alpha));
   1970 		device->setLightDiffuse(i, sw::Color<float>(light[i].diffuse.red, light[i].diffuse.green, light[i].diffuse.blue, light[i].diffuse.alpha));
   1971 		device->setLightSpecular(i, sw::Color<float>(light[i].specular.red, light[i].specular.green, light[i].specular.blue, light[i].specular.alpha));
   1972 		device->setLightAttenuation(i, light[i].attenuation.constant, light[i].attenuation.linear, light[i].attenuation.quadratic);
   1973 
   1974 		if(light[i].position.w != 0.0f)
   1975 		{
   1976 			device->setLightPosition(i, sw::Point(light[i].position.x / light[i].position.w, light[i].position.y / light[i].position.w, light[i].position.z / light[i].position.w));
   1977 		}
   1978 		else   // Directional light
   1979 		{
   1980 			// Hack: set the position far way
   1981 			float max = sw::max(abs(light[i].position.x), abs(light[i].position.y), abs(light[i].position.z));
   1982 			device->setLightPosition(i, sw::Point(1e10f * (light[i].position.x / max), 1e10f * (light[i].position.y / max), 1e10f * (light[i].position.z / max)));
   1983 		}
   1984 	}
   1985 
   1986 	device->setMaterialAmbient(sw::Color<float>(materialAmbient.red, materialAmbient.green, materialAmbient.blue, materialAmbient.alpha));
   1987 	device->setMaterialDiffuse(sw::Color<float>(materialDiffuse.red, materialDiffuse.green, materialDiffuse.blue, materialDiffuse.alpha));
   1988 	device->setMaterialSpecular(sw::Color<float>(materialSpecular.red, materialSpecular.green, materialSpecular.blue, materialSpecular.alpha));
   1989 	device->setMaterialEmission(sw::Color<float>(materialEmission.red, materialEmission.green, materialEmission.blue, materialEmission.alpha));
   1990 	device->setMaterialShininess(materialShininess);
   1991 
   1992 	device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL);
   1993 	device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL);
   1994 	device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL);
   1995 	device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL);
   1996 
   1997 	device->setProjectionMatrix(projectionStack.current());
   1998 	device->setModelMatrix(modelViewStack.current());
   1999 	device->setTextureMatrix(0, textureStack0.current());
   2000 	device->setTextureMatrix(1, textureStack1.current());
   2001 	device->setTextureTransform(0, textureStack0.isIdentity() ? 0 : 4, false);
   2002 	device->setTextureTransform(1, textureStack1.isIdentity() ? 0 : 4, false);
   2003 	device->setTexGen(0, sw::TEXGEN_NONE);
   2004 	device->setTexGen(1, sw::TEXGEN_NONE);
   2005 
   2006 	device->setAlphaTestEnable(alphaTestEnabled);
   2007 	device->setAlphaCompare(es2sw::ConvertAlphaComparison(alphaTestFunc));
   2008 	device->setAlphaReference(alphaTestRef * 0xFF);
   2009 
   2010 	device->setFogEnable(fogEnabled);
   2011 	device->setFogColor(sw::Color<float>(fogColor.red, fogColor.green, fogColor.blue, fogColor.alpha));
   2012 	device->setFogDensity(fogDensity);
   2013 	device->setFogStart(fogStart);
   2014 	device->setFogEnd(fogEnd);
   2015 
   2016 	switch(fogMode)
   2017 	{
   2018 	case GL_LINEAR: device->setVertexFogMode(sw::FOG_LINEAR); break;
   2019 	case GL_EXP:    device->setVertexFogMode(sw::FOG_EXP);    break;
   2020 	case GL_EXP2:   device->setVertexFogMode(sw::FOG_EXP2);   break;
   2021 	default: UNREACHABLE(fogMode);
   2022 	}
   2023 
   2024 	device->setColorLogicOpEnabled(colorLogicOpEnabled);
   2025 	device->setLogicalOperation(es2sw::ConvertLogicalOperation(logicalOperation));
   2026 
   2027 	device->setNormalizeNormals(normalizeEnabled || rescaleNormalEnabled);
   2028 }
   2029 
   2030 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count)
   2031 {
   2032 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
   2033 
   2034 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes);
   2035 	if(err != GL_NO_ERROR)
   2036 	{
   2037 		return err;
   2038 	}
   2039 
   2040 	device->resetInputStreams(false);
   2041 
   2042 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
   2043 	{
   2044 		sw::Resource *resource = attributes[i].vertexBuffer;
   2045 		const void *buffer = (char*)resource->data() + attributes[i].offset;
   2046 
   2047 		int stride = attributes[i].stride;
   2048 
   2049 		buffer = (char*)buffer + stride * base;
   2050 
   2051 		sw::Stream attribute(resource, buffer, stride);
   2052 
   2053 		attribute.type = attributes[i].type;
   2054 		attribute.count = attributes[i].count;
   2055 		attribute.normalized = attributes[i].normalized;
   2056 
   2057 		device->setInputStream(i, attribute);
   2058 	}
   2059 
   2060 	return GL_NO_ERROR;
   2061 }
   2062 
   2063 // Applies the indices and element array bindings
   2064 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
   2065 {
   2066 	GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo);
   2067 
   2068 	if(err == GL_NO_ERROR)
   2069 	{
   2070 		device->setIndexBuffer(indexInfo->indexBuffer);
   2071 	}
   2072 
   2073 	return err;
   2074 }
   2075 
   2076 void Context::applyTextures()
   2077 {
   2078 	for(int unit = 0; unit < MAX_TEXTURE_UNITS; unit++)
   2079 	{
   2080 		Texture *texture = nullptr;
   2081 
   2082 		if(textureExternalEnabled[unit])
   2083 		{
   2084 			texture = getSamplerTexture(unit, TEXTURE_EXTERNAL);
   2085 		}
   2086 		else if(texture2Denabled[unit])
   2087 		{
   2088 			texture = getSamplerTexture(unit, TEXTURE_2D);
   2089 		}
   2090 
   2091 		if(texture && texture->isSamplerComplete())
   2092 		{
   2093 			texture->autoGenerateMipmaps();
   2094 
   2095 			GLenum wrapS = texture->getWrapS();
   2096 			GLenum wrapT = texture->getWrapT();
   2097 			GLenum minFilter = texture->getMinFilter();
   2098 			GLenum magFilter = texture->getMagFilter();
   2099 			GLfloat maxAnisotropy = texture->getMaxAnisotropy();
   2100 
   2101 			device->setAddressingModeU(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapS));
   2102 			device->setAddressingModeV(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureWrap(wrapT));
   2103 
   2104 			device->setTextureFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
   2105 			device->setMipmapFilter(sw::SAMPLER_PIXEL, unit, es2sw::ConvertMipMapFilter(minFilter));
   2106 			device->setMaxAnisotropy(sw::SAMPLER_PIXEL, unit, maxAnisotropy);
   2107 
   2108 			applyTexture(unit, texture);
   2109 
   2110 			device->setConstantColor(unit, sw::Color<float>(mState.textureUnit[unit].color.red, mState.textureUnit[unit].color.green, mState.textureUnit[unit].color.blue, mState.textureUnit[unit].color.alpha));
   2111 
   2112 			if(mState.textureUnit[unit].environmentMode != GL_COMBINE)
   2113 			{
   2114 				device->setFirstArgument(unit, sw::TextureStage::SOURCE_TEXTURE);    // Cs
   2115 				device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
   2116 				device->setSecondArgument(unit, sw::TextureStage::SOURCE_CURRENT);   // Cp
   2117 				device->setSecondModifier(unit, sw::TextureStage::MODIFIER_COLOR);
   2118 				device->setThirdArgument(unit, sw::TextureStage::SOURCE_CONSTANT);   // Cc
   2119 				device->setThirdModifier(unit, sw::TextureStage::MODIFIER_COLOR);
   2120 
   2121 				device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_TEXTURE);    // As
   2122 				device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
   2123 				device->setSecondArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);   // Ap
   2124 				device->setSecondModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
   2125 				device->setThirdArgumentAlpha(unit, sw::TextureStage::SOURCE_CONSTANT);   // Ac
   2126 				device->setThirdModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
   2127 
   2128 				GLenum texFormat = texture->getFormat(GL_TEXTURE_2D, 0);
   2129 
   2130 				switch(mState.textureUnit[unit].environmentMode)
   2131 				{
   2132 				case GL_REPLACE:
   2133 					if(IsAlpha(texFormat))   // GL_ALPHA
   2134 					{
   2135 						// Cv = Cp, Av = As
   2136 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
   2137 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
   2138 					}
   2139 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
   2140 					{
   2141 						// Cv = Cs, Av = Ap
   2142 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
   2143 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2144 					}
   2145 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
   2146 					{
   2147 						// Cv = Cs, Av = As
   2148 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
   2149 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
   2150 					}
   2151 					else UNREACHABLE(texFormat);
   2152 					break;
   2153 				case GL_MODULATE:
   2154 					if(IsAlpha(texFormat))   // GL_ALPHA
   2155 					{
   2156 						// Cv = Cp, Av = ApAs
   2157 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
   2158 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2159 					}
   2160 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
   2161 					{
   2162 						// Cv = CpCs, Av = Ap
   2163 						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
   2164 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2165 					}
   2166 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
   2167 					{
   2168 						// Cv = CpCs, Av = ApAs
   2169 						device->setStageOperation(unit, sw::TextureStage::STAGE_MODULATE);
   2170 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2171 					}
   2172 					else UNREACHABLE(texFormat);
   2173 					break;
   2174 				case GL_DECAL:
   2175 					if(texFormat == GL_ALPHA ||
   2176 					   texFormat == GL_LUMINANCE ||
   2177 					   texFormat == GL_LUMINANCE_ALPHA)
   2178 					{
   2179 						// undefined   // FIXME: Log
   2180 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
   2181 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2182 					}
   2183 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
   2184 					{
   2185 						// Cv = Cs, Av = Ap
   2186 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
   2187 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2188 					}
   2189 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
   2190 					{
   2191 						// Cv = Cp(1 - As) + CsAs, Av = Ap
   2192 						device->setStageOperation(unit, sw::TextureStage::STAGE_BLENDTEXTUREALPHA);   // Alpha * (Arg1 - Arg2) + Arg2
   2193 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2194 					}
   2195 					else UNREACHABLE(texFormat);
   2196 					break;
   2197 				case GL_BLEND:
   2198 					if(IsAlpha(texFormat))   // GL_ALPHA
   2199 					{
   2200 						// Cv = Cp, Av = ApAs
   2201 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
   2202 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2203 					}
   2204 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
   2205 					{
   2206 						// Cv = Cp(1 - Cs) + CcCs, Av = Ap
   2207 						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
   2208 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2209 					}
   2210 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
   2211 					{
   2212 						// Cv = Cp(1 - Cs) + CcCs, Av = ApAs
   2213 						device->setStageOperation(unit, sw::TextureStage::STAGE_LERP);   // Arg3 * (Arg1 - Arg2) + Arg2
   2214 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2215 					}
   2216 					else UNREACHABLE(texFormat);
   2217 					break;
   2218 				case GL_ADD:
   2219 					if(IsAlpha(texFormat))   // GL_ALPHA
   2220 					{
   2221 						// Cv = Cp, Av = ApAs
   2222 						device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG2);
   2223 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2224 					}
   2225 					else if(IsRGB(texFormat))   // GL_LUMINANCE (or 1) / GL_RGB (or 3)
   2226 					{
   2227 						// Cv = Cp + Cs, Av = Ap
   2228 						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
   2229 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG2);
   2230 					}
   2231 					else if(IsRGBA(texFormat))   // GL_LUMINANCE_ALPHA (or 2) / GL_RGBA (or 4)
   2232 					{
   2233 						// Cv = Cp + Cs, Av = ApAs
   2234 						device->setStageOperation(unit, sw::TextureStage::STAGE_ADD);
   2235 						device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_MODULATE);
   2236 					}
   2237 					else UNREACHABLE(texFormat);
   2238 					break;
   2239 				default:
   2240 					UNREACHABLE(mState.textureUnit[unit].environmentMode);
   2241 				}
   2242 			}
   2243 			else   // GL_COMBINE
   2244 			{
   2245 				device->setFirstArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0RGB));
   2246 				device->setFirstModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0RGB));
   2247 				device->setSecondArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1RGB));
   2248 				device->setSecondModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1RGB));
   2249 				device->setThirdArgument(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2RGB));
   2250 				device->setThirdModifier(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2RGB));
   2251 
   2252 				device->setStageOperation(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineRGB));
   2253 
   2254 				device->setFirstArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src0Alpha));
   2255 				device->setFirstModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand0Alpha));
   2256 				device->setSecondArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src1Alpha));
   2257 				device->setSecondModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand1Alpha));
   2258 				device->setThirdArgumentAlpha(unit, es2sw::ConvertSourceArgument(mState.textureUnit[unit].src2Alpha));
   2259 				device->setThirdModifierAlpha(unit, es2sw::ConvertSourceOperand(mState.textureUnit[unit].operand2Alpha));
   2260 
   2261 				device->setStageOperationAlpha(unit, es2sw::ConvertCombineOperation(mState.textureUnit[unit].combineAlpha));
   2262 			}
   2263 		}
   2264 		else
   2265 		{
   2266 			applyTexture(unit, nullptr);
   2267 
   2268 			device->setFirstArgument(unit, sw::TextureStage::SOURCE_CURRENT);
   2269 			device->setFirstModifier(unit, sw::TextureStage::MODIFIER_COLOR);
   2270 			device->setStageOperation(unit, sw::TextureStage::STAGE_SELECTARG1);
   2271 
   2272 			device->setFirstArgumentAlpha(unit, sw::TextureStage::SOURCE_CURRENT);
   2273 			device->setFirstModifierAlpha(unit, sw::TextureStage::MODIFIER_ALPHA);
   2274 			device->setStageOperationAlpha(unit, sw::TextureStage::STAGE_SELECTARG1);
   2275 		}
   2276 	}
   2277 }
   2278 
   2279 void Context::setTextureEnvMode(GLenum texEnvMode)
   2280 {
   2281 	mState.textureUnit[mState.activeSampler].environmentMode = texEnvMode;
   2282 }
   2283 
   2284 void Context::setTextureEnvColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
   2285 {
   2286 	mState.textureUnit[mState.activeSampler].color = {red, green, blue, alpha};
   2287 }
   2288 
   2289 void Context::setCombineRGB(GLenum combineRGB)
   2290 {
   2291 	mState.textureUnit[mState.activeSampler].combineRGB = combineRGB;
   2292 }
   2293 
   2294 void Context::setCombineAlpha(GLenum combineAlpha)
   2295 {
   2296 	mState.textureUnit[mState.activeSampler].combineAlpha = combineAlpha;
   2297 }
   2298 
   2299 void Context::setOperand0RGB(GLenum operand)
   2300 {
   2301 	mState.textureUnit[mState.activeSampler].operand0RGB = operand;
   2302 }
   2303 
   2304 void Context::setOperand1RGB(GLenum operand)
   2305 {
   2306 	mState.textureUnit[mState.activeSampler].operand1RGB = operand;
   2307 }
   2308 
   2309 void Context::setOperand2RGB(GLenum operand)
   2310 {
   2311 	mState.textureUnit[mState.activeSampler].operand2RGB = operand;
   2312 }
   2313 
   2314 void Context::setOperand0Alpha(GLenum operand)
   2315 {
   2316 	mState.textureUnit[mState.activeSampler].operand0Alpha = operand;
   2317 }
   2318 
   2319 void Context::setOperand1Alpha(GLenum operand)
   2320 {
   2321 	mState.textureUnit[mState.activeSampler].operand1Alpha = operand;
   2322 }
   2323 
   2324 void Context::setOperand2Alpha(GLenum operand)
   2325 {
   2326 	mState.textureUnit[mState.activeSampler].operand2Alpha = operand;
   2327 }
   2328 
   2329 void Context::setSrc0RGB(GLenum src)
   2330 {
   2331 	mState.textureUnit[mState.activeSampler].src0RGB = src;
   2332 }
   2333 
   2334 void Context::setSrc1RGB(GLenum src)
   2335 {
   2336 	mState.textureUnit[mState.activeSampler].src1RGB = src;
   2337 }
   2338 
   2339 void Context::setSrc2RGB(GLenum src)
   2340 {
   2341 	mState.textureUnit[mState.activeSampler].src2RGB = src;
   2342 }
   2343 
   2344 void Context::setSrc0Alpha(GLenum src)
   2345 {
   2346 	mState.textureUnit[mState.activeSampler].src0Alpha = src;
   2347 }
   2348 
   2349 void Context::setSrc1Alpha(GLenum src)
   2350 {
   2351 	mState.textureUnit[mState.activeSampler].src1Alpha = src;
   2352 }
   2353 
   2354 void Context::setSrc2Alpha(GLenum src)
   2355 {
   2356 	mState.textureUnit[mState.activeSampler].src2Alpha = src;
   2357 }
   2358 
   2359 void Context::applyTexture(int index, Texture *baseTexture)
   2360 {
   2361 	sw::Resource *resource = 0;
   2362 
   2363 	if(baseTexture)
   2364 	{
   2365 		resource = baseTexture->getResource();
   2366 	}
   2367 
   2368 	device->setTextureResource(index, resource);
   2369 
   2370 	if(baseTexture)
   2371 	{
   2372 		int topLevel = baseTexture->getTopLevel();
   2373 
   2374 		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
   2375 		{
   2376 			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
   2377 
   2378 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   2379 			{
   2380 				int surfaceLevel = mipmapLevel;
   2381 
   2382 				if(surfaceLevel < 0)
   2383 				{
   2384 					surfaceLevel = 0;
   2385 				}
   2386 				else if(surfaceLevel > topLevel)
   2387 				{
   2388 					surfaceLevel = topLevel;
   2389 				}
   2390 
   2391 				egl::Image *surface = texture->getImage(surfaceLevel);
   2392 				device->setTextureLevel(index, 0, mipmapLevel, surface, sw::TEXTURE_2D);
   2393 			}
   2394 		}
   2395 		else UNIMPLEMENTED();
   2396 	}
   2397 	else
   2398 	{
   2399 		device->setTextureLevel(index, 0, 0, 0, sw::TEXTURE_NULL);
   2400 	}
   2401 }
   2402 
   2403 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   2404                          GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   2405 {
   2406 	Framebuffer *framebuffer = getFramebuffer();
   2407 	int framebufferWidth, framebufferHeight, framebufferSamples;
   2408 
   2409 	if(!framebuffer || (framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE_OES))
   2410 	{
   2411 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
   2412 	}
   2413 
   2414 	if(getFramebufferName() != 0 && framebufferSamples != 0)
   2415 	{
   2416 		return error(GL_INVALID_OPERATION);
   2417 	}
   2418 
   2419 	if(format != GL_RGBA || type != GL_UNSIGNED_BYTE)
   2420 	{
   2421 		if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType())
   2422 		{
   2423 			return error(GL_INVALID_OPERATION);
   2424 		}
   2425 	}
   2426 
   2427 	GLsizei outputPitch = gl::ComputePitch(width, format, type, mState.packAlignment);
   2428 
   2429 	// Sized query sanity check
   2430 	if(bufSize)
   2431 	{
   2432 		int requiredSize = outputPitch * height;
   2433 		if(requiredSize > *bufSize)
   2434 		{
   2435 			return error(GL_INVALID_OPERATION);
   2436 		}
   2437 	}
   2438 
   2439 	egl::Image *renderTarget = framebuffer->getRenderTarget();
   2440 
   2441 	if(!renderTarget)
   2442 	{
   2443 		return error(GL_OUT_OF_MEMORY);
   2444 	}
   2445 
   2446 	sw::Rect rect = {x, y, x + width, y + height};
   2447 	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
   2448 
   2449 	unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, 0, sw::LOCK_READONLY);
   2450 	unsigned char *dest = (unsigned char*)pixels;
   2451 	int inputPitch = (int)renderTarget->getPitch();
   2452 
   2453 	for(int j = 0; j < rect.y1 - rect.y0; j++)
   2454 	{
   2455 		unsigned short *dest16 = (unsigned short*)dest;
   2456 		unsigned int *dest32 = (unsigned int*)dest;
   2457 
   2458 		if(renderTarget->getExternalFormat() == sw::FORMAT_A8B8G8R8 &&
   2459 		   format == GL_RGBA && type == GL_UNSIGNED_BYTE)
   2460 		{
   2461 			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
   2462 		}
   2463 		else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
   2464 				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
   2465 		{
   2466 			for(int i = 0; i < rect.x1 - rect.x0; i++)
   2467 			{
   2468 				unsigned int argb = *(unsigned int*)(source + 4 * i);
   2469 
   2470 				dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16);
   2471 			}
   2472 		}
   2473 		else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
   2474 				format == GL_RGBA && type == GL_UNSIGNED_BYTE)
   2475 		{
   2476 			for(int i = 0; i < rect.x1 - rect.x0; i++)
   2477 			{
   2478 				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
   2479 
   2480 				dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000;
   2481 			}
   2482 		}
   2483 		else if(renderTarget->getExternalFormat() == sw::FORMAT_X8R8G8B8 &&
   2484 				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
   2485 		{
   2486 			for(int i = 0; i < rect.x1 - rect.x0; i++)
   2487 			{
   2488 				unsigned int xrgb = *(unsigned int*)(source + 4 * i);
   2489 
   2490 				dest32[i] = xrgb | 0xFF000000;
   2491 			}
   2492 		}
   2493 		else if(renderTarget->getExternalFormat() == sw::FORMAT_A8R8G8B8 &&
   2494 				format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE)
   2495 		{
   2496 			memcpy(dest, source, (rect.x1 - rect.x0) * 4);
   2497 		}
   2498 		else if(renderTarget->getExternalFormat() == sw::FORMAT_A1R5G5B5 &&
   2499 				format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)
   2500 		{
   2501 			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
   2502 		}
   2503 		else if(renderTarget->getExternalFormat() == sw::FORMAT_R5G6B5 &&
   2504 				format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5)   // GL_BGR_EXT
   2505 		{
   2506 			memcpy(dest, source, (rect.x1 - rect.x0) * 2);
   2507 		}
   2508 		else
   2509 		{
   2510 			for(int i = 0; i < rect.x1 - rect.x0; i++)
   2511 			{
   2512 				float r;
   2513 				float g;
   2514 				float b;
   2515 				float a;
   2516 
   2517 				switch(renderTarget->getExternalFormat())
   2518 				{
   2519 				case sw::FORMAT_R5G6B5:
   2520 					{
   2521 						unsigned short rgb = *(unsigned short*)(source + 2 * i);
   2522 
   2523 						a = 1.0f;
   2524 						b = (rgb & 0x001F) * (1.0f / 0x001F);
   2525 						g = (rgb & 0x07E0) * (1.0f / 0x07E0);
   2526 						r = (rgb & 0xF800) * (1.0f / 0xF800);
   2527 					}
   2528 					break;
   2529 				case sw::FORMAT_A1R5G5B5:
   2530 					{
   2531 						unsigned short argb = *(unsigned short*)(source + 2 * i);
   2532 
   2533 						a = (argb & 0x8000) ? 1.0f : 0.0f;
   2534 						b = (argb & 0x001F) * (1.0f / 0x001F);
   2535 						g = (argb & 0x03E0) * (1.0f / 0x03E0);
   2536 						r = (argb & 0x7C00) * (1.0f / 0x7C00);
   2537 					}
   2538 					break;
   2539 				case sw::FORMAT_A8R8G8B8:
   2540 					{
   2541 						unsigned int argb = *(unsigned int*)(source + 4 * i);
   2542 
   2543 						a = (argb & 0xFF000000) * (1.0f / 0xFF000000);
   2544 						b = (argb & 0x000000FF) * (1.0f / 0x000000FF);
   2545 						g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00);
   2546 						r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000);
   2547 					}
   2548 					break;
   2549 				case sw::FORMAT_A8B8G8R8:
   2550 					{
   2551 						unsigned int abgr = *(unsigned int*)(source + 4 * i);
   2552 
   2553 						a = (abgr & 0xFF000000) * (1.0f / 0xFF000000);
   2554 						b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000);
   2555 						g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00);
   2556 						r = (abgr & 0x000000FF) * (1.0f / 0x000000FF);
   2557 					}
   2558 					break;
   2559 				case sw::FORMAT_X8R8G8B8:
   2560 					{
   2561 						unsigned int xrgb = *(unsigned int*)(source + 4 * i);
   2562 
   2563 						a = 1.0f;
   2564 						b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF);
   2565 						g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00);
   2566 						r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000);
   2567 					}
   2568 					break;
   2569 				case sw::FORMAT_X8B8G8R8:
   2570 					{
   2571 						unsigned int xbgr = *(unsigned int*)(source + 4 * i);
   2572 
   2573 						a = 1.0f;
   2574 						b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000);
   2575 						g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00);
   2576 						r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF);
   2577 					}
   2578 					break;
   2579 				case sw::FORMAT_A2R10G10B10:
   2580 					{
   2581 						unsigned int argb = *(unsigned int*)(source + 4 * i);
   2582 
   2583 						a = (argb & 0xC0000000) * (1.0f / 0xC0000000);
   2584 						b = (argb & 0x000003FF) * (1.0f / 0x000003FF);
   2585 						g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00);
   2586 						r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000);
   2587 					}
   2588 					break;
   2589 				default:
   2590 					UNIMPLEMENTED();   // FIXME
   2591 					UNREACHABLE(renderTarget->getExternalFormat());
   2592 				}
   2593 
   2594 				switch(format)
   2595 				{
   2596 				case GL_RGBA:
   2597 					switch(type)
   2598 					{
   2599 					case GL_UNSIGNED_BYTE:
   2600 						dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f);
   2601 						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
   2602 						dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f);
   2603 						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
   2604 						break;
   2605 					default: UNREACHABLE(type);
   2606 					}
   2607 					break;
   2608 				case GL_BGRA_EXT:
   2609 					switch(type)
   2610 					{
   2611 					case GL_UNSIGNED_BYTE:
   2612 						dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f);
   2613 						dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f);
   2614 						dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f);
   2615 						dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f);
   2616 						break;
   2617 					case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
   2618 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
   2619 						// this type is packed as follows:
   2620 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
   2621 						//  --------------------------------------------------------------------------------
   2622 						// |       4th         |        3rd         |        2nd        |   1st component   |
   2623 						//  --------------------------------------------------------------------------------
   2624 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
   2625 						dest16[i] =
   2626 							((unsigned short)(15 * a + 0.5f) << 12)|
   2627 							((unsigned short)(15 * r + 0.5f) << 8) |
   2628 							((unsigned short)(15 * g + 0.5f) << 4) |
   2629 							((unsigned short)(15 * b + 0.5f) << 0);
   2630 						break;
   2631 					case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
   2632 						// According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
   2633 						// this type is packed as follows:
   2634 						//   15   14   13   12   11   10    9    8    7    6    5    4    3    2    1    0
   2635 						//  --------------------------------------------------------------------------------
   2636 						// | 4th |          3rd           |           2nd          |      1st component     |
   2637 						//  --------------------------------------------------------------------------------
   2638 						// in the case of BGRA_EXT, B is the first component, G the second, and so forth.
   2639 						dest16[i] =
   2640 							((unsigned short)(     a + 0.5f) << 15) |
   2641 							((unsigned short)(31 * r + 0.5f) << 10) |
   2642 							((unsigned short)(31 * g + 0.5f) << 5) |
   2643 							((unsigned short)(31 * b + 0.5f) << 0);
   2644 						break;
   2645 					default: UNREACHABLE(type);
   2646 					}
   2647 					break;
   2648 				case GL_RGB:
   2649 					switch(type)
   2650 					{
   2651 					case GL_UNSIGNED_SHORT_5_6_5:
   2652 						dest16[i] =
   2653 							((unsigned short)(31 * b + 0.5f) << 0) |
   2654 							((unsigned short)(63 * g + 0.5f) << 5) |
   2655 							((unsigned short)(31 * r + 0.5f) << 11);
   2656 						break;
   2657 					default: UNREACHABLE(type);
   2658 					}
   2659 					break;
   2660 				default: UNREACHABLE(format);
   2661 				}
   2662 			}
   2663 		}
   2664 
   2665 		source += inputPitch;
   2666 		dest += outputPitch;
   2667 	}
   2668 
   2669 	renderTarget->unlock();
   2670 	renderTarget->release();
   2671 }
   2672 
   2673 void Context::clear(GLbitfield mask)
   2674 {
   2675 	Framebuffer *framebuffer = getFramebuffer();
   2676 
   2677 	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES)
   2678 	{
   2679 		return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
   2680 	}
   2681 
   2682 	if(!applyRenderTarget())
   2683 	{
   2684 		return;
   2685 	}
   2686 
   2687 	float depth = clamp01(mState.depthClearValue);
   2688 	int stencil = mState.stencilClearValue & 0x000000FF;
   2689 
   2690 	if(mask & GL_COLOR_BUFFER_BIT)
   2691 	{
   2692 		unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) |
   2693 		                        (mState.colorMaskGreen ? 0x2 : 0) |
   2694 		                        (mState.colorMaskBlue ? 0x4 : 0) |
   2695 		                        (mState.colorMaskAlpha ? 0x8 : 0);
   2696 
   2697 		if(rgbaMask != 0)
   2698 		{
   2699 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
   2700 		}
   2701 	}
   2702 
   2703 	if(mask & GL_DEPTH_BUFFER_BIT)
   2704 	{
   2705 		if(mState.depthMask != 0)
   2706 		{
   2707 			device->clearDepth(depth);
   2708 		}
   2709 	}
   2710 
   2711 	if(mask & GL_STENCIL_BUFFER_BIT)
   2712 	{
   2713 		if(mState.stencilWritemask != 0)
   2714 		{
   2715 			device->clearStencil(stencil, mState.stencilWritemask);
   2716 		}
   2717 	}
   2718 }
   2719 
   2720 void Context::drawArrays(GLenum mode, GLint first, GLsizei count)
   2721 {
   2722 	sw::DrawType primitiveType;
   2723 	int primitiveCount;
   2724 
   2725 	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount))
   2726 		return error(GL_INVALID_ENUM);
   2727 
   2728 	if(primitiveCount <= 0)
   2729 	{
   2730 		return;
   2731 	}
   2732 
   2733 	if(!applyRenderTarget())
   2734 	{
   2735 		return;
   2736 	}
   2737 
   2738 	applyState(mode);
   2739 
   2740 	GLenum err = applyVertexBuffer(0, first, count);
   2741 	if(err != GL_NO_ERROR)
   2742 	{
   2743 		return error(err);
   2744 	}
   2745 
   2746 	applyTextures();
   2747 
   2748 	if(!cullSkipsDraw(mode))
   2749 	{
   2750 		device->drawPrimitive(primitiveType, primitiveCount);
   2751 	}
   2752 }
   2753 
   2754 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices)
   2755 {
   2756 	if(!indices && !mState.elementArrayBuffer)
   2757 	{
   2758 		return error(GL_INVALID_OPERATION);
   2759 	}
   2760 
   2761 	sw::DrawType primitiveType;
   2762 	int primitiveCount;
   2763 
   2764 	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount))
   2765 		return error(GL_INVALID_ENUM);
   2766 
   2767 	if(primitiveCount <= 0)
   2768 	{
   2769 		return;
   2770 	}
   2771 
   2772 	if(!applyRenderTarget())
   2773 	{
   2774 		return;
   2775 	}
   2776 
   2777 	applyState(mode);
   2778 
   2779 	TranslatedIndexData indexInfo;
   2780 	GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo);
   2781 	if(err != GL_NO_ERROR)
   2782 	{
   2783 		return error(err);
   2784 	}
   2785 
   2786 	GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
   2787 	err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount);
   2788 	if(err != GL_NO_ERROR)
   2789 	{
   2790 		return error(err);
   2791 	}
   2792 
   2793 	applyTextures();
   2794 
   2795 	if(!cullSkipsDraw(mode))
   2796 	{
   2797 		device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
   2798 	}
   2799 }
   2800 
   2801 void Context::drawTexture(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
   2802 {
   2803 	es1::Framebuffer *framebuffer = getFramebuffer();
   2804 	es1::Renderbuffer *renderbuffer = framebuffer ? framebuffer->getColorbuffer() : nullptr;
   2805 	if(!renderbuffer)
   2806 	{
   2807 		return;
   2808 	}
   2809 
   2810 	float targetWidth = (float)renderbuffer->getWidth();
   2811 	float targetHeight = (float)renderbuffer->getHeight();
   2812 	float x0 = 2.0f * x / targetWidth - 1.0f;
   2813 	float y0 = 2.0f * y / targetHeight - 1.0f;
   2814 	float x1 = 2.0f * (x + width) / targetWidth - 1.0f;
   2815 	float y1 = 2.0f * (y + height) / targetHeight - 1.0f;
   2816 	float Zw = sw::clamp(mState.zNear + z * (mState.zFar - mState.zNear), mState.zNear, mState.zFar);
   2817 
   2818 	float vertices[][3] = {{x0, y0, Zw},
   2819 	                       {x0, y1, Zw},
   2820 	                       {x1, y0, Zw},
   2821 	                       {x1, y1, Zw}};
   2822 
   2823 	ASSERT(mState.samplerTexture[TEXTURE_2D][1].name() == 0);   // Multi-texturing unimplemented
   2824 	es1::Texture *texture = getSamplerTexture(0, TEXTURE_2D);
   2825 	float textureWidth = (float)texture->getWidth(GL_TEXTURE_2D, 0);
   2826 	float textureHeight = (float)texture->getHeight(GL_TEXTURE_2D, 0);
   2827 	int Ucr = texture->getCropRectU();
   2828 	int Vcr = texture->getCropRectV();
   2829 	int Wcr = texture->getCropRectW();
   2830 	int Hcr = texture->getCropRectH();
   2831 
   2832 	float texCoords[][2] = {{Ucr / textureWidth, Vcr / textureHeight},
   2833 	                        {Ucr / textureWidth, (Vcr + Hcr) / textureHeight},
   2834 	                        {(Ucr + Wcr) / textureWidth, Vcr / textureHeight},
   2835 	                        {(Ucr + Wcr) / textureWidth, (Vcr + Hcr) / textureHeight}};
   2836 
   2837 	VertexAttribute oldPositionAttribute = mState.vertexAttribute[sw::Position];
   2838 	VertexAttribute oldTexCoord0Attribute = mState.vertexAttribute[sw::TexCoord0];
   2839 	gl::BindingPointer<Buffer> oldArrayBuffer = mState.arrayBuffer;
   2840 	mState.arrayBuffer = nullptr;
   2841 
   2842 	glVertexPointer(3, GL_FLOAT, 3 * sizeof(float), vertices);
   2843 	glEnableClientState(GL_VERTEX_ARRAY);
   2844 	glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(float), texCoords);
   2845 	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
   2846 
   2847 	sw::Matrix P = projectionStack.current();
   2848 	sw::Matrix M = modelViewStack.current();
   2849 	sw::Matrix T = textureStack0.current();
   2850 
   2851 	projectionStack.identity();
   2852 	modelViewStack.identity();
   2853 	textureStack0.identity();
   2854 
   2855 	drawArrays(GL_TRIANGLE_STRIP, 0, 4);
   2856 
   2857 	// Restore state
   2858 	mState.vertexAttribute[sw::Position] = oldPositionAttribute;
   2859 	mState.vertexAttribute[sw::TexCoord0] = oldTexCoord0Attribute;
   2860 	mState.arrayBuffer = oldArrayBuffer;
   2861 	oldArrayBuffer = nullptr;
   2862 	oldPositionAttribute.mBoundBuffer = nullptr;
   2863 	oldTexCoord0Attribute.mBoundBuffer = nullptr;
   2864 	textureStack0.load(T);
   2865 	modelViewStack.load(M);
   2866 	projectionStack.load(P);
   2867 }
   2868 
   2869 void Context::blit(sw::Surface *source, const sw::SliceRect &sRect, sw::Surface *dest, const sw::SliceRect &dRect)
   2870 {
   2871 	sw::SliceRectF sRectF((float)sRect.x0, (float)sRect.y0, (float)sRect.x1, (float)sRect.y1, sRect.slice);
   2872 	device->blit(source, sRectF, dest, dRect, false);
   2873 }
   2874 
   2875 void Context::finish()
   2876 {
   2877 	device->finish();
   2878 }
   2879 
   2880 void Context::flush()
   2881 {
   2882 	// We don't queue anything without processing it as fast as possible
   2883 }
   2884 
   2885 void Context::recordInvalidEnum()
   2886 {
   2887 	mInvalidEnum = true;
   2888 }
   2889 
   2890 void Context::recordInvalidValue()
   2891 {
   2892 	mInvalidValue = true;
   2893 }
   2894 
   2895 void Context::recordInvalidOperation()
   2896 {
   2897 	mInvalidOperation = true;
   2898 }
   2899 
   2900 void Context::recordOutOfMemory()
   2901 {
   2902 	mOutOfMemory = true;
   2903 }
   2904 
   2905 void Context::recordInvalidFramebufferOperation()
   2906 {
   2907 	mInvalidFramebufferOperation = true;
   2908 }
   2909 
   2910 void Context::recordMatrixStackOverflow()
   2911 {
   2912 	mMatrixStackOverflow = true;
   2913 }
   2914 
   2915 void Context::recordMatrixStackUnderflow()
   2916 {
   2917 	mMatrixStackUnderflow = true;
   2918 }
   2919 
   2920 // Get one of the recorded errors and clear its flag, if any.
   2921 // [OpenGL ES 2.0.24] section 2.5 page 13.
   2922 GLenum Context::getError()
   2923 {
   2924 	if(mInvalidEnum)
   2925 	{
   2926 		mInvalidEnum = false;
   2927 
   2928 		return GL_INVALID_ENUM;
   2929 	}
   2930 
   2931 	if(mInvalidValue)
   2932 	{
   2933 		mInvalidValue = false;
   2934 
   2935 		return GL_INVALID_VALUE;
   2936 	}
   2937 
   2938 	if(mInvalidOperation)
   2939 	{
   2940 		mInvalidOperation = false;
   2941 
   2942 		return GL_INVALID_OPERATION;
   2943 	}
   2944 
   2945 	if(mOutOfMemory)
   2946 	{
   2947 		mOutOfMemory = false;
   2948 
   2949 		return GL_OUT_OF_MEMORY;
   2950 	}
   2951 
   2952 	if(mInvalidFramebufferOperation)
   2953 	{
   2954 		mInvalidFramebufferOperation = false;
   2955 
   2956 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
   2957 	}
   2958 
   2959 	if(mMatrixStackOverflow)
   2960 	{
   2961 		mMatrixStackOverflow = false;
   2962 
   2963 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
   2964 	}
   2965 
   2966 	if(mMatrixStackUnderflow)
   2967 	{
   2968 		mMatrixStackUnderflow = false;
   2969 
   2970 		return GL_INVALID_FRAMEBUFFER_OPERATION_OES;
   2971 	}
   2972 
   2973 	return GL_NO_ERROR;
   2974 }
   2975 
   2976 int Context::getSupportedMultisampleCount(int requested)
   2977 {
   2978 	int supported = 0;
   2979 
   2980 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
   2981 	{
   2982 		if(supported >= requested)
   2983 		{
   2984 			return supported;
   2985 		}
   2986 
   2987 		supported = multisampleCount[i];
   2988 	}
   2989 
   2990 	return supported;
   2991 }
   2992 
   2993 void Context::detachBuffer(GLuint buffer)
   2994 {
   2995 	// [OpenGL ES 2.0.24] section 2.9 page 22:
   2996 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
   2997 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
   2998 
   2999 	if(mState.arrayBuffer.name() == buffer)
   3000 	{
   3001 		mState.arrayBuffer = nullptr;
   3002 	}
   3003 
   3004 	if(mState.elementArrayBuffer.name() == buffer)
   3005 	{
   3006 		mState.elementArrayBuffer = nullptr;
   3007 	}
   3008 
   3009 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
   3010 	{
   3011 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
   3012 		{
   3013 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
   3014 		}
   3015 	}
   3016 }
   3017 
   3018 void Context::detachTexture(GLuint texture)
   3019 {
   3020 	// [OpenGL ES 2.0.24] section 3.8 page 84:
   3021 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
   3022 	// rebound to texture object zero
   3023 
   3024 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   3025 	{
   3026 		for(int sampler = 0; sampler < MAX_TEXTURE_UNITS; sampler++)
   3027 		{
   3028 			if(mState.samplerTexture[type][sampler].name() == texture)
   3029 			{
   3030 				mState.samplerTexture[type][sampler] = nullptr;
   3031 			}
   3032 		}
   3033 	}
   3034 
   3035 	// [OpenGL ES 2.0.24] section 4.4 page 112:
   3036 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
   3037 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
   3038 	// image was attached in the currently bound framebuffer.
   3039 
   3040 	Framebuffer *framebuffer = getFramebuffer();
   3041 
   3042 	if(framebuffer)
   3043 	{
   3044 		framebuffer->detachTexture(texture);
   3045 	}
   3046 }
   3047 
   3048 void Context::detachFramebuffer(GLuint framebuffer)
   3049 {
   3050 	// [OpenGL ES 2.0.24] section 4.4 page 107:
   3051 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   3052 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   3053 
   3054 	if(mState.framebuffer == framebuffer)
   3055 	{
   3056 		bindFramebuffer(0);
   3057 	}
   3058 }
   3059 
   3060 void Context::detachRenderbuffer(GLuint renderbuffer)
   3061 {
   3062 	// [OpenGL ES 2.0.24] section 4.4 page 109:
   3063 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
   3064 	// had been executed with the target RENDERBUFFER and name of zero.
   3065 
   3066 	if(mState.renderbuffer.name() == renderbuffer)
   3067 	{
   3068 		bindRenderbuffer(0);
   3069 	}
   3070 
   3071 	// [OpenGL ES 2.0.24] section 4.4 page 111:
   3072 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
   3073 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
   3074 	// point to which this image was attached in the currently bound framebuffer.
   3075 
   3076 	Framebuffer *framebuffer = getFramebuffer();
   3077 
   3078 	if(framebuffer)
   3079 	{
   3080 		framebuffer->detachRenderbuffer(renderbuffer);
   3081 	}
   3082 }
   3083 
   3084 bool Context::cullSkipsDraw(GLenum drawMode)
   3085 {
   3086 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
   3087 }
   3088 
   3089 bool Context::isTriangleMode(GLenum drawMode)
   3090 {
   3091 	switch(drawMode)
   3092 	{
   3093 	case GL_TRIANGLES:
   3094 	case GL_TRIANGLE_FAN:
   3095 	case GL_TRIANGLE_STRIP:
   3096 		return true;
   3097 	case GL_POINTS:
   3098 	case GL_LINES:
   3099 	case GL_LINE_LOOP:
   3100 	case GL_LINE_STRIP:
   3101 		return false;
   3102 	default: UNREACHABLE(drawMode);
   3103 	}
   3104 
   3105 	return false;
   3106 }
   3107 
   3108 void Context::setVertexAttrib(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
   3109 {
   3110 	ASSERT(index < MAX_VERTEX_ATTRIBS);
   3111 
   3112 	mState.vertexAttribute[index].mCurrentValue[0] = x;
   3113 	mState.vertexAttribute[index].mCurrentValue[1] = y;
   3114 	mState.vertexAttribute[index].mCurrentValue[2] = z;
   3115 	mState.vertexAttribute[index].mCurrentValue[3] = w;
   3116 
   3117 	mVertexDataManager->dirtyCurrentValue(index);
   3118 }
   3119 
   3120 void Context::bindTexImage(gl::Surface *surface)
   3121 {
   3122 	es1::Texture2D *textureObject = getTexture2D();
   3123 
   3124 	if(textureObject)
   3125 	{
   3126 		textureObject->bindTexImage(surface);
   3127 	}
   3128 }
   3129 
   3130 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
   3131 {
   3132 	switch(target)
   3133 	{
   3134 	case EGL_GL_TEXTURE_2D_KHR:
   3135 		break;
   3136 	case EGL_GL_RENDERBUFFER_KHR:
   3137 		break;
   3138 	default:
   3139 		return EGL_BAD_PARAMETER;
   3140 	}
   3141 
   3142 	if(textureLevel >= IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   3143 	{
   3144 		return EGL_BAD_MATCH;
   3145 	}
   3146 
   3147 	if(target == EGL_GL_TEXTURE_2D_KHR)
   3148 	{
   3149 		Texture *texture = getTexture(name);
   3150 
   3151 		if(!texture || texture->getTarget() != GL_TEXTURE_2D)
   3152 		{
   3153 			return EGL_BAD_PARAMETER;
   3154 		}
   3155 
   3156 		if(texture->isShared(GL_TEXTURE_2D, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
   3157 		{
   3158 			return EGL_BAD_ACCESS;
   3159 		}
   3160 
   3161 		if(textureLevel != 0 && !texture->isSamplerComplete())
   3162 		{
   3163 			return EGL_BAD_PARAMETER;
   3164 		}
   3165 
   3166 		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getTopLevel() == 0))
   3167 		{
   3168 			return EGL_BAD_PARAMETER;
   3169 		}
   3170 	}
   3171 	else if(target == EGL_GL_RENDERBUFFER_KHR)
   3172 	{
   3173 		Renderbuffer *renderbuffer = getRenderbuffer(name);
   3174 
   3175 		if(!renderbuffer)
   3176 		{
   3177 			return EGL_BAD_PARAMETER;
   3178 		}
   3179 
   3180 		if(renderbuffer->isShared())   // Already an EGLImage sibling
   3181 		{
   3182 			return EGL_BAD_ACCESS;
   3183 		}
   3184 	}
   3185 	else UNREACHABLE(target);
   3186 
   3187 	return EGL_SUCCESS;
   3188 }
   3189 
   3190 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
   3191 {
   3192 	if(target == EGL_GL_TEXTURE_2D_KHR)
   3193 	{
   3194 		es1::Texture *texture = getTexture(name);
   3195 
   3196 		return texture->createSharedImage(GL_TEXTURE_2D, textureLevel);
   3197 	}
   3198 	else if(target == EGL_GL_RENDERBUFFER_KHR)
   3199 	{
   3200 		es1::Renderbuffer *renderbuffer = getRenderbuffer(name);
   3201 
   3202 		return renderbuffer->createSharedImage();
   3203 	}
   3204 	else UNREACHABLE(target);
   3205 
   3206 	return nullptr;
   3207 }
   3208 
   3209 egl::Image *Context::getSharedImage(GLeglImageOES image)
   3210 {
   3211 	return display->getSharedImage(image);
   3212 }
   3213 
   3214 Device *Context::getDevice()
   3215 {
   3216 	return device;
   3217 }
   3218 
   3219 void Context::setMatrixMode(GLenum mode)
   3220 {
   3221 	matrixMode = mode;
   3222 }
   3223 
   3224 sw::MatrixStack &Context::currentMatrixStack()
   3225 {
   3226 	switch(matrixMode)
   3227 	{
   3228 	case GL_MODELVIEW:
   3229 		return modelViewStack;
   3230 	case GL_PROJECTION:
   3231 		return projectionStack;
   3232 	case GL_TEXTURE:
   3233 		switch(mState.activeSampler)
   3234 		{
   3235 		case 0: return textureStack0;
   3236 		case 1: return textureStack1;
   3237 		}
   3238 		break;
   3239 	}
   3240 
   3241 	UNREACHABLE(matrixMode);
   3242 	return textureStack0;
   3243 }
   3244 
   3245 void Context::loadIdentity()
   3246 {
   3247 	currentMatrixStack().identity();
   3248 }
   3249 
   3250 void Context::load(const GLfloat *m)
   3251 {
   3252 	currentMatrixStack().load(m);
   3253 }
   3254 
   3255 void Context::pushMatrix()
   3256 {
   3257 	if(!currentMatrixStack().push())
   3258 	{
   3259 		return error(GL_STACK_OVERFLOW);
   3260 	}
   3261 }
   3262 
   3263 void Context::popMatrix()
   3264 {
   3265 	if(!currentMatrixStack().pop())
   3266 	{
   3267 		return error(GL_STACK_OVERFLOW);
   3268 	}
   3269 }
   3270 
   3271 void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
   3272 {
   3273 	currentMatrixStack().rotate(angle, x, y, z);
   3274 }
   3275 
   3276 void Context::translate(GLfloat x, GLfloat y, GLfloat z)
   3277 {
   3278 	currentMatrixStack().translate(x, y, z);
   3279 }
   3280 
   3281 void Context::scale(GLfloat x, GLfloat y, GLfloat z)
   3282 {
   3283 	currentMatrixStack().scale(x, y, z);
   3284 }
   3285 
   3286 void Context::multiply(const GLfloat *m)
   3287 {
   3288 	currentMatrixStack().multiply(m);
   3289 }
   3290 
   3291 void Context::frustum(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
   3292 {
   3293 	currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar);
   3294 }
   3295 
   3296 void Context::ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
   3297 {
   3298 	currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar);
   3299 }
   3300 
   3301 void Context::setClipPlane(int index, const float plane[4])
   3302 {
   3303 	sw::Plane clipPlane = modelViewStack.current() * sw::Plane(plane);
   3304 	device->setClipPlane(index, &clipPlane.A);
   3305 }
   3306 
   3307 void Context::setClipPlaneEnabled(int index, bool enable)
   3308 {
   3309 	clipFlags = (clipFlags & ~((int)!enable << index)) | ((int)enable << index);
   3310 	device->setClipFlags(clipFlags);
   3311 }
   3312 
   3313 bool Context::isClipPlaneEnabled(int index) const
   3314 {
   3315 	return (clipFlags & (1 << index)) != 0;
   3316 }
   3317 
   3318 void Context::setColorLogicOpEnabled(bool enable)
   3319 {
   3320 	colorLogicOpEnabled = enable;
   3321 }
   3322 
   3323 bool Context::isColorLogicOpEnabled() const
   3324 {
   3325 	return colorLogicOpEnabled;
   3326 }
   3327 
   3328 void Context::setLogicalOperation(GLenum logicOp)
   3329 {
   3330 	logicalOperation = logicOp;
   3331 }
   3332 
   3333 void Context::setLineSmoothEnabled(bool enable)
   3334 {
   3335 	lineSmoothEnabled = enable;
   3336 }
   3337 
   3338 bool Context::isLineSmoothEnabled() const
   3339 {
   3340 	return lineSmoothEnabled;
   3341 }
   3342 
   3343 void Context::setColorMaterialEnabled(bool enable)
   3344 {
   3345 	colorMaterialEnabled = enable;
   3346 }
   3347 
   3348 bool Context::isColorMaterialEnabled() const
   3349 {
   3350 	return colorMaterialEnabled;
   3351 }
   3352 
   3353 void Context::setNormalizeEnabled(bool enable)
   3354 {
   3355 	normalizeEnabled = enable;
   3356 }
   3357 
   3358 bool Context::isNormalizeEnabled() const
   3359 {
   3360 	return normalizeEnabled;
   3361 }
   3362 
   3363 void Context::setRescaleNormalEnabled(bool enable)
   3364 {
   3365 	rescaleNormalEnabled = enable;
   3366 }
   3367 
   3368 bool Context::isRescaleNormalEnabled() const
   3369 {
   3370 	return rescaleNormalEnabled;
   3371 }
   3372 
   3373 void Context::setVertexArrayEnabled(bool enable)
   3374 {
   3375 	mState.vertexAttribute[sw::Position].mArrayEnabled = enable;
   3376 }
   3377 
   3378 bool Context::isVertexArrayEnabled() const
   3379 {
   3380 	return mState.vertexAttribute[sw::Position].mArrayEnabled;
   3381 }
   3382 
   3383 void Context::setNormalArrayEnabled(bool enable)
   3384 {
   3385 	mState.vertexAttribute[sw::Normal].mArrayEnabled = enable;
   3386 }
   3387 
   3388 bool Context::isNormalArrayEnabled() const
   3389 {
   3390 	return mState.vertexAttribute[sw::Normal].mArrayEnabled;
   3391 }
   3392 
   3393 void Context::setColorArrayEnabled(bool enable)
   3394 {
   3395 	mState.vertexAttribute[sw::Color0].mArrayEnabled = enable;
   3396 }
   3397 
   3398 bool Context::isColorArrayEnabled() const
   3399 {
   3400 	return mState.vertexAttribute[sw::Color0].mArrayEnabled;
   3401 }
   3402 
   3403 void Context::setPointSizeArrayEnabled(bool enable)
   3404 {
   3405 	mState.vertexAttribute[sw::PointSize].mArrayEnabled = enable;
   3406 }
   3407 
   3408 bool Context::isPointSizeArrayEnabled() const
   3409 {
   3410 	return mState.vertexAttribute[sw::PointSize].mArrayEnabled;
   3411 }
   3412 
   3413 void Context::setTextureCoordArrayEnabled(bool enable)
   3414 {
   3415 	mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled = enable;
   3416 }
   3417 
   3418 bool Context::isTextureCoordArrayEnabled() const
   3419 {
   3420 	return mState.vertexAttribute[sw::TexCoord0 + clientTexture].mArrayEnabled;
   3421 }
   3422 
   3423 void Context::setMultisampleEnabled(bool enable)
   3424 {
   3425 	multisampleEnabled = enable;
   3426 }
   3427 
   3428 bool Context::isMultisampleEnabled() const
   3429 {
   3430 	return multisampleEnabled;
   3431 }
   3432 
   3433 void Context::setSampleAlphaToOneEnabled(bool enable)
   3434 {
   3435 	sampleAlphaToOneEnabled = enable;
   3436 }
   3437 
   3438 bool Context::isSampleAlphaToOneEnabled() const
   3439 {
   3440 	return sampleAlphaToOneEnabled;
   3441 }
   3442 
   3443 void Context::setPointSpriteEnabled(bool enable)
   3444 {
   3445 	pointSpriteEnabled = enable;
   3446 }
   3447 
   3448 bool Context::isPointSpriteEnabled() const
   3449 {
   3450 	return pointSpriteEnabled;
   3451 }
   3452 
   3453 void Context::setPointSmoothEnabled(bool enable)
   3454 {
   3455 	pointSmoothEnabled = enable;
   3456 }
   3457 
   3458 bool Context::isPointSmoothEnabled() const
   3459 {
   3460 	return pointSmoothEnabled;
   3461 }
   3462 
   3463 void Context::setPointSizeMin(float min)
   3464 {
   3465 	pointSizeMin = min;
   3466 }
   3467 
   3468 void Context::setPointSizeMax(float max)
   3469 {
   3470 	pointSizeMax = max;
   3471 }
   3472 
   3473 void Context::setPointDistanceAttenuation(float a, float b, float c)
   3474 {
   3475 	pointDistanceAttenuation = {a, b, c};
   3476 }
   3477 
   3478 void Context::setPointFadeThresholdSize(float threshold)
   3479 {
   3480 	pointFadeThresholdSize = threshold;
   3481 }
   3482 
   3483 void Context::clientActiveTexture(GLenum texture)
   3484 {
   3485 	clientTexture = texture;
   3486 }
   3487 
   3488 GLenum Context::getClientActiveTexture() const
   3489 {
   3490 	return clientTexture;
   3491 }
   3492 
   3493 unsigned int Context::getActiveTexture() const
   3494 {
   3495 	return mState.activeSampler;
   3496 }
   3497 
   3498 }
   3499 
   3500 egl::Context *es1CreateContext(egl::Display *display, const egl::Context *shareContext, const egl::Config *config)
   3501 {
   3502 	ASSERT(!shareContext || shareContext->getClientVersion() == 1);   // Should be checked by eglCreateContext
   3503 	return new es1::Context(display, static_cast<const es1::Context*>(shareContext), config);
   3504 }
   3505