Home | History | Annotate | Download | only in libGLESv2
      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 es2::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 "Fence.h"
     26 #include "Framebuffer.h"
     27 #include "Program.h"
     28 #include "Query.h"
     29 #include "Renderbuffer.h"
     30 #include "Sampler.h"
     31 #include "Shader.h"
     32 #include "Texture.h"
     33 #include "TransformFeedback.h"
     34 #include "VertexArray.h"
     35 #include "VertexDataManager.h"
     36 #include "IndexDataManager.h"
     37 #include "libEGL/Display.h"
     38 #include "libEGL/Surface.h"
     39 #include "Common/Half.hpp"
     40 
     41 #include <EGL/eglext.h>
     42 
     43 namespace es2
     44 {
     45 Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion)
     46 	: clientVersion(clientVersion), mConfig(config)
     47 {
     48 	sw::Context *context = new sw::Context();
     49 	device = new es2::Device(context);
     50 
     51 	setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     52 
     53 	mState.depthClearValue = 1.0f;
     54 	mState.stencilClearValue = 0;
     55 
     56 	mState.cullFaceEnabled = false;
     57 	mState.cullMode = GL_BACK;
     58 	mState.frontFace = GL_CCW;
     59 	mState.depthTestEnabled = false;
     60 	mState.depthFunc = GL_LESS;
     61 	mState.blendEnabled = false;
     62 	mState.sourceBlendRGB = GL_ONE;
     63 	mState.sourceBlendAlpha = GL_ONE;
     64 	mState.destBlendRGB = GL_ZERO;
     65 	mState.destBlendAlpha = GL_ZERO;
     66 	mState.blendEquationRGB = GL_FUNC_ADD;
     67 	mState.blendEquationAlpha = GL_FUNC_ADD;
     68 	mState.blendColor.red = 0;
     69 	mState.blendColor.green = 0;
     70 	mState.blendColor.blue = 0;
     71 	mState.blendColor.alpha = 0;
     72 	mState.stencilTestEnabled = false;
     73 	mState.stencilFunc = GL_ALWAYS;
     74 	mState.stencilRef = 0;
     75 	mState.stencilMask = -1;
     76 	mState.stencilWritemask = -1;
     77 	mState.stencilBackFunc = GL_ALWAYS;
     78 	mState.stencilBackRef = 0;
     79 	mState.stencilBackMask = - 1;
     80 	mState.stencilBackWritemask = -1;
     81 	mState.stencilFail = GL_KEEP;
     82 	mState.stencilPassDepthFail = GL_KEEP;
     83 	mState.stencilPassDepthPass = GL_KEEP;
     84 	mState.stencilBackFail = GL_KEEP;
     85 	mState.stencilBackPassDepthFail = GL_KEEP;
     86 	mState.stencilBackPassDepthPass = GL_KEEP;
     87 	mState.polygonOffsetFillEnabled = false;
     88 	mState.polygonOffsetFactor = 0.0f;
     89 	mState.polygonOffsetUnits = 0.0f;
     90 	mState.sampleAlphaToCoverageEnabled = false;
     91 	mState.sampleCoverageEnabled = false;
     92 	mState.sampleCoverageValue = 1.0f;
     93 	mState.sampleCoverageInvert = false;
     94 	mState.scissorTestEnabled = false;
     95 	mState.ditherEnabled = true;
     96 	mState.primitiveRestartFixedIndexEnabled = false;
     97 	mState.rasterizerDiscardEnabled = false;
     98 	mState.generateMipmapHint = GL_DONT_CARE;
     99 	mState.fragmentShaderDerivativeHint = GL_DONT_CARE;
    100 
    101 	mState.lineWidth = 1.0f;
    102 
    103 	mState.viewportX = 0;
    104 	mState.viewportY = 0;
    105 	mState.viewportWidth = 0;
    106 	mState.viewportHeight = 0;
    107 	mState.zNear = 0.0f;
    108 	mState.zFar = 1.0f;
    109 
    110 	mState.scissorX = 0;
    111 	mState.scissorY = 0;
    112 	mState.scissorWidth = 0;
    113 	mState.scissorHeight = 0;
    114 
    115 	mState.colorMaskRed = true;
    116 	mState.colorMaskGreen = true;
    117 	mState.colorMaskBlue = true;
    118 	mState.colorMaskAlpha = true;
    119 	mState.depthMask = true;
    120 
    121 	if(shareContext)
    122 	{
    123 		mResourceManager = shareContext->mResourceManager;
    124 		mResourceManager->addRef();
    125 	}
    126 	else
    127 	{
    128 		mResourceManager = new ResourceManager();
    129 	}
    130 
    131 	// [OpenGL ES 2.0.24] section 3.7 page 83:
    132 	// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
    133 	// and cube map texture state vectors respectively associated with them.
    134 	// In order that access to these initial textures not be lost, they are treated as texture
    135 	// objects all of whose names are 0.
    136 
    137 	mTexture2DZero = new Texture2D(0);
    138 	mTexture3DZero = new Texture3D(0);
    139 	mTexture2DArrayZero = new Texture2DArray(0);
    140 	mTextureCubeMapZero = new TextureCubeMap(0);
    141 	mTextureExternalZero = new TextureExternal(0);
    142 
    143 	mState.activeSampler = 0;
    144 	bindVertexArray(0);
    145 	bindArrayBuffer(0);
    146 	bindElementArrayBuffer(0);
    147 	bindTextureCubeMap(0);
    148 	bindTexture2D(0);
    149 	bindReadFramebuffer(0);
    150 	bindDrawFramebuffer(0);
    151 	bindRenderbuffer(0);
    152 	bindGenericUniformBuffer(0);
    153 	bindTransformFeedback(0);
    154 
    155 	mState.currentProgram = 0;
    156 
    157 	mState.packAlignment = 4;
    158 	mState.unpackInfo.alignment = 4;
    159 	mState.packRowLength = 0;
    160 	mState.packImageHeight = 0;
    161 	mState.packSkipPixels = 0;
    162 	mState.packSkipRows = 0;
    163 	mState.packSkipImages = 0;
    164 	mState.unpackInfo.rowLength = 0;
    165 	mState.unpackInfo.imageHeight = 0;
    166 	mState.unpackInfo.skipPixels = 0;
    167 	mState.unpackInfo.skipRows = 0;
    168 	mState.unpackInfo.skipImages = 0;
    169 
    170 	mVertexDataManager = nullptr;
    171 	mIndexDataManager = nullptr;
    172 
    173 	mInvalidEnum = false;
    174 	mInvalidValue = false;
    175 	mInvalidOperation = false;
    176 	mOutOfMemory = false;
    177 	mInvalidFramebufferOperation = false;
    178 
    179 	mHasBeenCurrent = false;
    180 
    181 	markAllStateDirty();
    182 }
    183 
    184 Context::~Context()
    185 {
    186 	if(mState.currentProgram != 0)
    187 	{
    188 		Program *programObject = mResourceManager->getProgram(mState.currentProgram);
    189 		if(programObject)
    190 		{
    191 			programObject->release();
    192 		}
    193 		mState.currentProgram = 0;
    194 	}
    195 
    196 	while(!mFramebufferNameSpace.empty())
    197 	{
    198 		deleteFramebuffer(mFramebufferNameSpace.firstName());
    199 	}
    200 
    201 	while(!mFenceNameSpace.empty())
    202 	{
    203 		deleteFence(mFenceNameSpace.firstName());
    204 	}
    205 
    206 	while(!mQueryNameSpace.empty())
    207 	{
    208 		deleteQuery(mQueryNameSpace.firstName());
    209 	}
    210 
    211 	while(!mVertexArrayNameSpace.empty())
    212 	{
    213 		deleteVertexArray(mVertexArrayNameSpace.firstName());
    214 	}
    215 
    216 	while(!mTransformFeedbackNameSpace.empty())
    217 	{
    218 		deleteTransformFeedback(mTransformFeedbackNameSpace.firstName());
    219 	}
    220 
    221 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
    222 	{
    223 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
    224 		{
    225 			mState.samplerTexture[type][sampler] = nullptr;
    226 		}
    227 	}
    228 
    229 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
    230 	{
    231 		mState.vertexAttribute[i].mBoundBuffer = nullptr;
    232 	}
    233 
    234 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
    235 	{
    236 		mState.activeQuery[i] = nullptr;
    237 	}
    238 
    239 	mState.arrayBuffer = nullptr;
    240 	mState.copyReadBuffer = nullptr;
    241 	mState.copyWriteBuffer = nullptr;
    242 	mState.pixelPackBuffer = nullptr;
    243 	mState.pixelUnpackBuffer = nullptr;
    244 	mState.genericUniformBuffer = nullptr;
    245 	mState.renderbuffer = nullptr;
    246 
    247 	for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i)
    248 	{
    249 		mState.sampler[i] = nullptr;
    250 	}
    251 
    252 	mTexture2DZero = nullptr;
    253 	mTexture3DZero = nullptr;
    254 	mTexture2DArrayZero = nullptr;
    255 	mTextureCubeMapZero = nullptr;
    256 	mTextureExternalZero = nullptr;
    257 
    258 	delete mVertexDataManager;
    259 	delete mIndexDataManager;
    260 
    261 	mResourceManager->release();
    262 	delete device;
    263 }
    264 
    265 void Context::makeCurrent(egl::Surface *surface)
    266 {
    267 	if(!mHasBeenCurrent)
    268 	{
    269 		mVertexDataManager = new VertexDataManager(this);
    270 		mIndexDataManager = new IndexDataManager();
    271 
    272 		mState.viewportX = 0;
    273 		mState.viewportY = 0;
    274 		mState.viewportWidth = surface->getWidth();
    275 		mState.viewportHeight = surface->getHeight();
    276 
    277 		mState.scissorX = 0;
    278 		mState.scissorY = 0;
    279 		mState.scissorWidth = surface->getWidth();
    280 		mState.scissorHeight = surface->getHeight();
    281 
    282 		mHasBeenCurrent = true;
    283 	}
    284 
    285 	// Wrap the existing resources into GL objects and assign them to the '0' names
    286 	egl::Image *defaultRenderTarget = surface->getRenderTarget();
    287 	egl::Image *depthStencil = surface->getDepthStencil();
    288 
    289 	Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
    290 	DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
    291 	Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
    292 
    293 	setFramebufferZero(framebufferZero);
    294 
    295 	if(defaultRenderTarget)
    296 	{
    297 		defaultRenderTarget->release();
    298 	}
    299 
    300 	if(depthStencil)
    301 	{
    302 		depthStencil->release();
    303 	}
    304 
    305 	markAllStateDirty();
    306 }
    307 
    308 EGLint Context::getClientVersion() const
    309 {
    310 	return clientVersion;
    311 }
    312 
    313 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw.
    314 void Context::markAllStateDirty()
    315 {
    316 	mAppliedProgramSerial = 0;
    317 
    318 	mDepthStateDirty = true;
    319 	mMaskStateDirty = true;
    320 	mBlendStateDirty = true;
    321 	mStencilStateDirty = true;
    322 	mPolygonOffsetStateDirty = true;
    323 	mSampleStateDirty = true;
    324 	mDitherStateDirty = true;
    325 	mFrontFaceDirty = true;
    326 }
    327 
    328 void Context::setClearColor(float red, float green, float blue, float alpha)
    329 {
    330 	mState.colorClearValue.red = red;
    331 	mState.colorClearValue.green = green;
    332 	mState.colorClearValue.blue = blue;
    333 	mState.colorClearValue.alpha = alpha;
    334 }
    335 
    336 void Context::setClearDepth(float depth)
    337 {
    338 	mState.depthClearValue = depth;
    339 }
    340 
    341 void Context::setClearStencil(int stencil)
    342 {
    343 	mState.stencilClearValue = stencil;
    344 }
    345 
    346 void Context::setCullFaceEnabled(bool enabled)
    347 {
    348 	mState.cullFaceEnabled = enabled;
    349 }
    350 
    351 bool Context::isCullFaceEnabled() const
    352 {
    353 	return mState.cullFaceEnabled;
    354 }
    355 
    356 void Context::setCullMode(GLenum mode)
    357 {
    358    mState.cullMode = mode;
    359 }
    360 
    361 void Context::setFrontFace(GLenum front)
    362 {
    363 	if(mState.frontFace != front)
    364 	{
    365 		mState.frontFace = front;
    366 		mFrontFaceDirty = true;
    367 	}
    368 }
    369 
    370 void Context::setDepthTestEnabled(bool enabled)
    371 {
    372 	if(mState.depthTestEnabled != enabled)
    373 	{
    374 		mState.depthTestEnabled = enabled;
    375 		mDepthStateDirty = true;
    376 	}
    377 }
    378 
    379 bool Context::isDepthTestEnabled() const
    380 {
    381 	return mState.depthTestEnabled;
    382 }
    383 
    384 void Context::setDepthFunc(GLenum depthFunc)
    385 {
    386 	if(mState.depthFunc != depthFunc)
    387 	{
    388 		mState.depthFunc = depthFunc;
    389 		mDepthStateDirty = true;
    390 	}
    391 }
    392 
    393 void Context::setDepthRange(float zNear, float zFar)
    394 {
    395 	mState.zNear = zNear;
    396 	mState.zFar = zFar;
    397 }
    398 
    399 void Context::setBlendEnabled(bool enabled)
    400 {
    401 	if(mState.blendEnabled != enabled)
    402 	{
    403 		mState.blendEnabled = enabled;
    404 		mBlendStateDirty = true;
    405 	}
    406 }
    407 
    408 bool Context::isBlendEnabled() const
    409 {
    410 	return mState.blendEnabled;
    411 }
    412 
    413 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
    414 {
    415 	if(mState.sourceBlendRGB != sourceRGB ||
    416 	   mState.sourceBlendAlpha != sourceAlpha ||
    417 	   mState.destBlendRGB != destRGB ||
    418 	   mState.destBlendAlpha != destAlpha)
    419 	{
    420 		mState.sourceBlendRGB = sourceRGB;
    421 		mState.destBlendRGB = destRGB;
    422 		mState.sourceBlendAlpha = sourceAlpha;
    423 		mState.destBlendAlpha = destAlpha;
    424 		mBlendStateDirty = true;
    425 	}
    426 }
    427 
    428 void Context::setBlendColor(float red, float green, float blue, float alpha)
    429 {
    430 	if(mState.blendColor.red != red ||
    431 	   mState.blendColor.green != green ||
    432 	   mState.blendColor.blue != blue ||
    433 	   mState.blendColor.alpha != alpha)
    434 	{
    435 		mState.blendColor.red = red;
    436 		mState.blendColor.green = green;
    437 		mState.blendColor.blue = blue;
    438 		mState.blendColor.alpha = alpha;
    439 		mBlendStateDirty = true;
    440 	}
    441 }
    442 
    443 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
    444 {
    445 	if(mState.blendEquationRGB != rgbEquation ||
    446 	   mState.blendEquationAlpha != alphaEquation)
    447 	{
    448 		mState.blendEquationRGB = rgbEquation;
    449 		mState.blendEquationAlpha = alphaEquation;
    450 		mBlendStateDirty = true;
    451 	}
    452 }
    453 
    454 void Context::setStencilTestEnabled(bool enabled)
    455 {
    456 	if(mState.stencilTestEnabled != enabled)
    457 	{
    458 		mState.stencilTestEnabled = enabled;
    459 		mStencilStateDirty = true;
    460 	}
    461 }
    462 
    463 bool Context::isStencilTestEnabled() const
    464 {
    465 	return mState.stencilTestEnabled;
    466 }
    467 
    468 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
    469 {
    470 	if(mState.stencilFunc != stencilFunc ||
    471 	   mState.stencilRef != stencilRef ||
    472 	   mState.stencilMask != stencilMask)
    473 	{
    474 		mState.stencilFunc = stencilFunc;
    475 		mState.stencilRef = (stencilRef > 0) ? stencilRef : 0;
    476 		mState.stencilMask = stencilMask;
    477 		mStencilStateDirty = true;
    478 	}
    479 }
    480 
    481 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
    482 {
    483 	if(mState.stencilBackFunc != stencilBackFunc ||
    484 	   mState.stencilBackRef != stencilBackRef ||
    485 	   mState.stencilBackMask != stencilBackMask)
    486 	{
    487 		mState.stencilBackFunc = stencilBackFunc;
    488 		mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
    489 		mState.stencilBackMask = stencilBackMask;
    490 		mStencilStateDirty = true;
    491 	}
    492 }
    493 
    494 void Context::setStencilWritemask(GLuint stencilWritemask)
    495 {
    496 	if(mState.stencilWritemask != stencilWritemask)
    497 	{
    498 		mState.stencilWritemask = stencilWritemask;
    499 		mStencilStateDirty = true;
    500 	}
    501 }
    502 
    503 void Context::setStencilBackWritemask(GLuint stencilBackWritemask)
    504 {
    505 	if(mState.stencilBackWritemask != stencilBackWritemask)
    506 	{
    507 		mState.stencilBackWritemask = stencilBackWritemask;
    508 		mStencilStateDirty = true;
    509 	}
    510 }
    511 
    512 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
    513 {
    514 	if(mState.stencilFail != stencilFail ||
    515 	   mState.stencilPassDepthFail != stencilPassDepthFail ||
    516 	   mState.stencilPassDepthPass != stencilPassDepthPass)
    517 	{
    518 		mState.stencilFail = stencilFail;
    519 		mState.stencilPassDepthFail = stencilPassDepthFail;
    520 		mState.stencilPassDepthPass = stencilPassDepthPass;
    521 		mStencilStateDirty = true;
    522 	}
    523 }
    524 
    525 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
    526 {
    527 	if(mState.stencilBackFail != stencilBackFail ||
    528 	   mState.stencilBackPassDepthFail != stencilBackPassDepthFail ||
    529 	   mState.stencilBackPassDepthPass != stencilBackPassDepthPass)
    530 	{
    531 		mState.stencilBackFail = stencilBackFail;
    532 		mState.stencilBackPassDepthFail = stencilBackPassDepthFail;
    533 		mState.stencilBackPassDepthPass = stencilBackPassDepthPass;
    534 		mStencilStateDirty = true;
    535 	}
    536 }
    537 
    538 void Context::setPolygonOffsetFillEnabled(bool enabled)
    539 {
    540 	if(mState.polygonOffsetFillEnabled != enabled)
    541 	{
    542 		mState.polygonOffsetFillEnabled = enabled;
    543 		mPolygonOffsetStateDirty = true;
    544 	}
    545 }
    546 
    547 bool Context::isPolygonOffsetFillEnabled() const
    548 {
    549 	return mState.polygonOffsetFillEnabled;
    550 }
    551 
    552 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units)
    553 {
    554 	if(mState.polygonOffsetFactor != factor ||
    555 	   mState.polygonOffsetUnits != units)
    556 	{
    557 		mState.polygonOffsetFactor = factor;
    558 		mState.polygonOffsetUnits = units;
    559 		mPolygonOffsetStateDirty = true;
    560 	}
    561 }
    562 
    563 void Context::setSampleAlphaToCoverageEnabled(bool enabled)
    564 {
    565 	if(mState.sampleAlphaToCoverageEnabled != enabled)
    566 	{
    567 		mState.sampleAlphaToCoverageEnabled = enabled;
    568 		mSampleStateDirty = true;
    569 	}
    570 }
    571 
    572 bool Context::isSampleAlphaToCoverageEnabled() const
    573 {
    574 	return mState.sampleAlphaToCoverageEnabled;
    575 }
    576 
    577 void Context::setSampleCoverageEnabled(bool enabled)
    578 {
    579 	if(mState.sampleCoverageEnabled != enabled)
    580 	{
    581 		mState.sampleCoverageEnabled = enabled;
    582 		mSampleStateDirty = true;
    583 	}
    584 }
    585 
    586 bool Context::isSampleCoverageEnabled() const
    587 {
    588 	return mState.sampleCoverageEnabled;
    589 }
    590 
    591 void Context::setSampleCoverageParams(GLclampf value, bool invert)
    592 {
    593 	if(mState.sampleCoverageValue != value ||
    594 	   mState.sampleCoverageInvert != invert)
    595 	{
    596 		mState.sampleCoverageValue = value;
    597 		mState.sampleCoverageInvert = invert;
    598 		mSampleStateDirty = true;
    599 	}
    600 }
    601 
    602 void Context::setScissorTestEnabled(bool enabled)
    603 {
    604 	mState.scissorTestEnabled = enabled;
    605 }
    606 
    607 bool Context::isScissorTestEnabled() const
    608 {
    609 	return mState.scissorTestEnabled;
    610 }
    611 
    612 void Context::setDitherEnabled(bool enabled)
    613 {
    614 	if(mState.ditherEnabled != enabled)
    615 	{
    616 		mState.ditherEnabled = enabled;
    617 		mDitherStateDirty = true;
    618 	}
    619 }
    620 
    621 bool Context::isDitherEnabled() const
    622 {
    623 	return mState.ditherEnabled;
    624 }
    625 
    626 void Context::setPrimitiveRestartFixedIndexEnabled(bool enabled)
    627 {
    628 	UNIMPLEMENTED();
    629 	mState.primitiveRestartFixedIndexEnabled = enabled;
    630 }
    631 
    632 bool Context::isPrimitiveRestartFixedIndexEnabled() const
    633 {
    634 	return mState.primitiveRestartFixedIndexEnabled;
    635 }
    636 
    637 void Context::setRasterizerDiscardEnabled(bool enabled)
    638 {
    639 	mState.rasterizerDiscardEnabled = enabled;
    640 }
    641 
    642 bool Context::isRasterizerDiscardEnabled() const
    643 {
    644 	return mState.rasterizerDiscardEnabled;
    645 }
    646 
    647 void Context::setLineWidth(GLfloat width)
    648 {
    649 	mState.lineWidth = width;
    650 	device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX));
    651 }
    652 
    653 void Context::setGenerateMipmapHint(GLenum hint)
    654 {
    655 	mState.generateMipmapHint = hint;
    656 }
    657 
    658 void Context::setFragmentShaderDerivativeHint(GLenum hint)
    659 {
    660 	mState.fragmentShaderDerivativeHint = hint;
    661 	// TODO: Propagate the hint to shader translator so we can write
    662 	// ddx, ddx_coarse, or ddx_fine depending on the hint.
    663 	// Ignore for now. It is valid for implementations to ignore hint.
    664 }
    665 
    666 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
    667 {
    668 	mState.viewportX = x;
    669 	mState.viewportY = y;
    670 	mState.viewportWidth = width;
    671 	mState.viewportHeight = height;
    672 }
    673 
    674 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
    675 {
    676 	mState.scissorX = x;
    677 	mState.scissorY = y;
    678 	mState.scissorWidth = width;
    679 	mState.scissorHeight = height;
    680 }
    681 
    682 void Context::setColorMask(bool red, bool green, bool blue, bool alpha)
    683 {
    684 	if(mState.colorMaskRed != red || mState.colorMaskGreen != green ||
    685 	   mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha)
    686 	{
    687 		mState.colorMaskRed = red;
    688 		mState.colorMaskGreen = green;
    689 		mState.colorMaskBlue = blue;
    690 		mState.colorMaskAlpha = alpha;
    691 		mMaskStateDirty = true;
    692 	}
    693 }
    694 
    695 unsigned int Context::getColorMask() const
    696 {
    697 	return (mState.colorMaskRed ? 0x1 : 0) |
    698 	       (mState.colorMaskGreen ? 0x2 : 0) |
    699 	       (mState.colorMaskBlue ? 0x4 : 0) |
    700 	       (mState.colorMaskAlpha ? 0x8 : 0);
    701 }
    702 
    703 void Context::setDepthMask(bool mask)
    704 {
    705 	if(mState.depthMask != mask)
    706 	{
    707 		mState.depthMask = mask;
    708 		mMaskStateDirty = true;
    709 	}
    710 }
    711 
    712 void Context::setActiveSampler(unsigned int active)
    713 {
    714 	mState.activeSampler = active;
    715 }
    716 
    717 GLuint Context::getReadFramebufferName() const
    718 {
    719 	return mState.readFramebuffer;
    720 }
    721 
    722 GLuint Context::getDrawFramebufferName() const
    723 {
    724 	return mState.drawFramebuffer;
    725 }
    726 
    727 GLuint Context::getRenderbufferName() const
    728 {
    729 	return mState.renderbuffer.name();
    730 }
    731 
    732 void Context::setFramebufferReadBuffer(GLuint buf)
    733 {
    734 	getReadFramebuffer()->setReadBuffer(buf);
    735 }
    736 
    737 void Context::setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs)
    738 {
    739 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
    740 
    741 	for(int i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
    742 	{
    743 		drawFramebuffer->setDrawBuffer(i, (i < n) ? bufs[i] : GL_NONE);
    744 	}
    745 }
    746 
    747 GLuint Context::getReadFramebufferColorIndex() const
    748 {
    749 	GLenum buf = getReadFramebuffer()->getReadBuffer();
    750 	switch(buf)
    751 	{
    752 	case GL_BACK:
    753 		return 0;
    754 	case GL_NONE:
    755 		return GL_INVALID_INDEX;
    756 	default:
    757 		return buf - GL_COLOR_ATTACHMENT0;
    758 }
    759 }
    760 
    761 GLuint Context::getArrayBufferName() const
    762 {
    763 	return mState.arrayBuffer.name();
    764 }
    765 
    766 GLuint Context::getElementArrayBufferName() const
    767 {
    768 	Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer();
    769 	return elementArrayBuffer ? elementArrayBuffer->name : 0;
    770 }
    771 
    772 GLuint Context::getActiveQuery(GLenum target) const
    773 {
    774 	Query *queryObject = nullptr;
    775 
    776 	switch(target)
    777 	{
    778 	case GL_ANY_SAMPLES_PASSED_EXT:
    779 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED];
    780 		break;
    781 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
    782 		queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE];
    783 		break;
    784 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
    785 		queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN];
    786 		break;
    787 	default:
    788 		ASSERT(false);
    789 	}
    790 
    791 	if(queryObject)
    792 	{
    793 		return queryObject->name;
    794 	}
    795 
    796 	return 0;
    797 }
    798 
    799 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled)
    800 {
    801 	getCurrentVertexArray()->enableAttribute(attribNum, enabled);
    802 }
    803 
    804 void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor)
    805 {
    806 	getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor);
    807 }
    808 
    809 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const
    810 {
    811 	return getCurrentVertexArray()->getVertexAttribute(attribNum);
    812 }
    813 
    814 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
    815                                    GLsizei stride, const void *pointer)
    816 {
    817 	getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, stride, pointer);
    818 }
    819 
    820 const void *Context::getVertexAttribPointer(unsigned int attribNum) const
    821 {
    822 	return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer;
    823 }
    824 
    825 const VertexAttributeArray &Context::getVertexArrayAttributes()
    826 {
    827 	return getCurrentVertexArray()->getVertexAttributes();
    828 }
    829 
    830 const VertexAttributeArray &Context::getCurrentVertexAttributes()
    831 {
    832 	return mState.vertexAttribute;
    833 }
    834 
    835 void Context::setPackAlignment(GLint alignment)
    836 {
    837 	mState.packAlignment = alignment;
    838 }
    839 
    840 void Context::setUnpackAlignment(GLint alignment)
    841 {
    842 	mState.unpackInfo.alignment = alignment;
    843 }
    844 
    845 const egl::Image::UnpackInfo& Context::getUnpackInfo() const
    846 {
    847 	return mState.unpackInfo;
    848 }
    849 
    850 void Context::setPackRowLength(GLint rowLength)
    851 {
    852 	mState.packRowLength = rowLength;
    853 }
    854 
    855 void Context::setPackImageHeight(GLint imageHeight)
    856 {
    857 	mState.packImageHeight = imageHeight;
    858 }
    859 
    860 void Context::setPackSkipPixels(GLint skipPixels)
    861 {
    862 	mState.packSkipPixels = skipPixels;
    863 }
    864 
    865 void Context::setPackSkipRows(GLint skipRows)
    866 {
    867 	mState.packSkipRows = skipRows;
    868 }
    869 
    870 void Context::setPackSkipImages(GLint skipImages)
    871 {
    872 	mState.packSkipImages = skipImages;
    873 }
    874 
    875 void Context::setUnpackRowLength(GLint rowLength)
    876 {
    877 	mState.unpackInfo.rowLength = rowLength;
    878 }
    879 
    880 void Context::setUnpackImageHeight(GLint imageHeight)
    881 {
    882 	mState.unpackInfo.imageHeight = imageHeight;
    883 }
    884 
    885 void Context::setUnpackSkipPixels(GLint skipPixels)
    886 {
    887 	mState.unpackInfo.skipPixels = skipPixels;
    888 }
    889 
    890 void Context::setUnpackSkipRows(GLint skipRows)
    891 {
    892 	mState.unpackInfo.skipRows = skipRows;
    893 }
    894 
    895 void Context::setUnpackSkipImages(GLint skipImages)
    896 {
    897 	mState.unpackInfo.skipImages = skipImages;
    898 }
    899 
    900 GLuint Context::createBuffer()
    901 {
    902 	return mResourceManager->createBuffer();
    903 }
    904 
    905 GLuint Context::createProgram()
    906 {
    907 	return mResourceManager->createProgram();
    908 }
    909 
    910 GLuint Context::createShader(GLenum type)
    911 {
    912 	return mResourceManager->createShader(type);
    913 }
    914 
    915 GLuint Context::createTexture()
    916 {
    917 	return mResourceManager->createTexture();
    918 }
    919 
    920 GLuint Context::createRenderbuffer()
    921 {
    922 	return mResourceManager->createRenderbuffer();
    923 }
    924 
    925 // Returns an unused framebuffer name
    926 GLuint Context::createFramebuffer()
    927 {
    928 	return mFramebufferNameSpace.allocate();
    929 }
    930 
    931 GLuint Context::createFence()
    932 {
    933 	return mFenceNameSpace.allocate(new Fence());
    934 }
    935 
    936 // Returns an unused query name
    937 GLuint Context::createQuery()
    938 {
    939 	return mQueryNameSpace.allocate();
    940 }
    941 
    942 // Returns an unused vertex array name
    943 GLuint Context::createVertexArray()
    944 {
    945 	return mVertexArrayNameSpace.allocate();
    946 }
    947 
    948 GLsync Context::createFenceSync(GLenum condition, GLbitfield flags)
    949 {
    950 	GLuint handle = mResourceManager->createFenceSync(condition, flags);
    951 
    952 	return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle));
    953 }
    954 
    955 // Returns an unused transform feedback name
    956 GLuint Context::createTransformFeedback()
    957 {
    958 	return mTransformFeedbackNameSpace.allocate();
    959 }
    960 
    961 // Returns an unused sampler name
    962 GLuint Context::createSampler()
    963 {
    964 	return mResourceManager->createSampler();
    965 }
    966 
    967 void Context::deleteBuffer(GLuint buffer)
    968 {
    969 	detachBuffer(buffer);
    970 
    971 	mResourceManager->deleteBuffer(buffer);
    972 }
    973 
    974 void Context::deleteShader(GLuint shader)
    975 {
    976 	mResourceManager->deleteShader(shader);
    977 }
    978 
    979 void Context::deleteProgram(GLuint program)
    980 {
    981 	mResourceManager->deleteProgram(program);
    982 }
    983 
    984 void Context::deleteTexture(GLuint texture)
    985 {
    986 	detachTexture(texture);
    987 
    988 	mResourceManager->deleteTexture(texture);
    989 }
    990 
    991 void Context::deleteRenderbuffer(GLuint renderbuffer)
    992 {
    993 	if(mResourceManager->getRenderbuffer(renderbuffer))
    994 	{
    995 		detachRenderbuffer(renderbuffer);
    996 	}
    997 
    998 	mResourceManager->deleteRenderbuffer(renderbuffer);
    999 }
   1000 
   1001 void Context::deleteFramebuffer(GLuint framebuffer)
   1002 {
   1003 	detachFramebuffer(framebuffer);
   1004 
   1005 	Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer);
   1006 
   1007 	if(framebufferObject)
   1008 	{
   1009 		delete framebufferObject;
   1010 	}
   1011 }
   1012 
   1013 void Context::deleteFence(GLuint fence)
   1014 {
   1015 	Fence *fenceObject = mFenceNameSpace.remove(fence);
   1016 
   1017 	if(fenceObject)
   1018 	{
   1019 		delete fenceObject;
   1020 	}
   1021 }
   1022 
   1023 void Context::deleteQuery(GLuint query)
   1024 {
   1025 	Query *queryObject = mQueryNameSpace.remove(query);
   1026 
   1027 	if(queryObject)
   1028 	{
   1029 		queryObject->release();
   1030 	}
   1031 }
   1032 
   1033 void Context::deleteVertexArray(GLuint vertexArray)
   1034 {
   1035 	// [OpenGL ES 3.0.2] section 2.10 page 43:
   1036 	// If a vertex array object that is currently bound is deleted, the binding
   1037 	// for that object reverts to zero and the default vertex array becomes current.
   1038 	if(getCurrentVertexArray()->name == vertexArray)
   1039 	{
   1040 		bindVertexArray(0);
   1041 	}
   1042 
   1043 	VertexArray *vertexArrayObject = mVertexArrayNameSpace.remove(vertexArray);
   1044 
   1045 	if(vertexArrayObject)
   1046 	{
   1047 		delete vertexArrayObject;
   1048 	}
   1049 }
   1050 
   1051 void Context::deleteFenceSync(GLsync fenceSync)
   1052 {
   1053 	// The spec specifies the underlying Fence object is not deleted until all current
   1054 	// wait commands finish. However, since the name becomes invalid, we cannot query the fence,
   1055 	// and since our API is currently designed for being called from a single thread, we can delete
   1056 	// the fence immediately.
   1057 	mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync)));
   1058 }
   1059 
   1060 void Context::deleteTransformFeedback(GLuint transformFeedback)
   1061 {
   1062 	TransformFeedback *transformFeedbackObject = mTransformFeedbackNameSpace.remove(transformFeedback);
   1063 
   1064 	if(transformFeedbackObject)
   1065 	{
   1066 		delete transformFeedbackObject;
   1067 	}
   1068 }
   1069 
   1070 void Context::deleteSampler(GLuint sampler)
   1071 {
   1072 	detachSampler(sampler);
   1073 
   1074 	mResourceManager->deleteSampler(sampler);
   1075 }
   1076 
   1077 Buffer *Context::getBuffer(GLuint handle) const
   1078 {
   1079 	return mResourceManager->getBuffer(handle);
   1080 }
   1081 
   1082 Shader *Context::getShader(GLuint handle) const
   1083 {
   1084 	return mResourceManager->getShader(handle);
   1085 }
   1086 
   1087 Program *Context::getProgram(GLuint handle) const
   1088 {
   1089 	return mResourceManager->getProgram(handle);
   1090 }
   1091 
   1092 Texture *Context::getTexture(GLuint handle) const
   1093 {
   1094 	return mResourceManager->getTexture(handle);
   1095 }
   1096 
   1097 Renderbuffer *Context::getRenderbuffer(GLuint handle) const
   1098 {
   1099 	return mResourceManager->getRenderbuffer(handle);
   1100 }
   1101 
   1102 Framebuffer *Context::getReadFramebuffer() const
   1103 {
   1104 	return getFramebuffer(mState.readFramebuffer);
   1105 }
   1106 
   1107 Framebuffer *Context::getDrawFramebuffer() const
   1108 {
   1109 	return getFramebuffer(mState.drawFramebuffer);
   1110 }
   1111 
   1112 void Context::bindArrayBuffer(unsigned int buffer)
   1113 {
   1114 	mResourceManager->checkBufferAllocation(buffer);
   1115 
   1116 	mState.arrayBuffer = getBuffer(buffer);
   1117 }
   1118 
   1119 void Context::bindElementArrayBuffer(unsigned int buffer)
   1120 {
   1121 	mResourceManager->checkBufferAllocation(buffer);
   1122 
   1123 	getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer));
   1124 }
   1125 
   1126 void Context::bindCopyReadBuffer(GLuint buffer)
   1127 {
   1128 	mResourceManager->checkBufferAllocation(buffer);
   1129 
   1130 	mState.copyReadBuffer = getBuffer(buffer);
   1131 }
   1132 
   1133 void Context::bindCopyWriteBuffer(GLuint buffer)
   1134 {
   1135 	mResourceManager->checkBufferAllocation(buffer);
   1136 
   1137 	mState.copyWriteBuffer = getBuffer(buffer);
   1138 }
   1139 
   1140 void Context::bindPixelPackBuffer(GLuint buffer)
   1141 {
   1142 	mResourceManager->checkBufferAllocation(buffer);
   1143 
   1144 	mState.pixelPackBuffer = getBuffer(buffer);
   1145 }
   1146 
   1147 void Context::bindPixelUnpackBuffer(GLuint buffer)
   1148 {
   1149 	mResourceManager->checkBufferAllocation(buffer);
   1150 
   1151 	mState.pixelUnpackBuffer = getBuffer(buffer);
   1152 }
   1153 
   1154 void Context::bindTransformFeedbackBuffer(GLuint buffer)
   1155 {
   1156 	mResourceManager->checkBufferAllocation(buffer);
   1157 
   1158 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   1159 
   1160 	if(transformFeedback)
   1161 	{
   1162 		transformFeedback->setGenericBuffer(getBuffer(buffer));
   1163 	}
   1164 }
   1165 
   1166 void Context::bindTexture2D(GLuint texture)
   1167 {
   1168 	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D);
   1169 
   1170 	mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture);
   1171 }
   1172 
   1173 void Context::bindTextureCubeMap(GLuint texture)
   1174 {
   1175 	mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE);
   1176 
   1177 	mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture);
   1178 }
   1179 
   1180 void Context::bindTextureExternal(GLuint texture)
   1181 {
   1182 	mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL);
   1183 
   1184 	mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture);
   1185 }
   1186 
   1187 void Context::bindTexture3D(GLuint texture)
   1188 {
   1189 	mResourceManager->checkTextureAllocation(texture, TEXTURE_3D);
   1190 
   1191 	mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture);
   1192 }
   1193 
   1194 void Context::bindTexture2DArray(GLuint texture)
   1195 {
   1196 	mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY);
   1197 
   1198 	mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture);
   1199 }
   1200 
   1201 void Context::bindReadFramebuffer(GLuint framebuffer)
   1202 {
   1203 	if(!getFramebuffer(framebuffer))
   1204 	{
   1205 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
   1206 	}
   1207 
   1208 	mState.readFramebuffer = framebuffer;
   1209 }
   1210 
   1211 void Context::bindDrawFramebuffer(GLuint framebuffer)
   1212 {
   1213 	if(!getFramebuffer(framebuffer))
   1214 	{
   1215 		mFramebufferNameSpace.insert(framebuffer, new Framebuffer());
   1216 	}
   1217 
   1218 	mState.drawFramebuffer = framebuffer;
   1219 }
   1220 
   1221 void Context::bindRenderbuffer(GLuint renderbuffer)
   1222 {
   1223 	mResourceManager->checkRenderbufferAllocation(renderbuffer);
   1224 
   1225 	mState.renderbuffer = getRenderbuffer(renderbuffer);
   1226 }
   1227 
   1228 void Context::bindVertexArray(GLuint array)
   1229 {
   1230 	VertexArray *vertexArray = getVertexArray(array);
   1231 
   1232 	if(!vertexArray)
   1233 	{
   1234 		vertexArray = new VertexArray(array);
   1235 		mVertexArrayNameSpace.insert(array, vertexArray);
   1236 	}
   1237 
   1238 	mState.vertexArray = array;
   1239 }
   1240 
   1241 void Context::bindGenericUniformBuffer(GLuint buffer)
   1242 {
   1243 	mResourceManager->checkBufferAllocation(buffer);
   1244 
   1245 	mState.genericUniformBuffer = getBuffer(buffer);
   1246 }
   1247 
   1248 void Context::bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
   1249 {
   1250 	mResourceManager->checkBufferAllocation(buffer);
   1251 
   1252 	Buffer* bufferObject = getBuffer(buffer);
   1253 	mState.uniformBuffers[index].set(bufferObject, offset, size);
   1254 }
   1255 
   1256 void Context::bindGenericTransformFeedbackBuffer(GLuint buffer)
   1257 {
   1258 	mResourceManager->checkBufferAllocation(buffer);
   1259 
   1260 	getTransformFeedback()->setGenericBuffer(getBuffer(buffer));
   1261 }
   1262 
   1263 void Context::bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size)
   1264 {
   1265 	mResourceManager->checkBufferAllocation(buffer);
   1266 
   1267 	Buffer* bufferObject = getBuffer(buffer);
   1268 	getTransformFeedback()->setBuffer(index, bufferObject, offset, size);
   1269 }
   1270 
   1271 void Context::bindTransformFeedback(GLuint id)
   1272 {
   1273 	if(!getTransformFeedback(id))
   1274 	{
   1275 		mTransformFeedbackNameSpace.insert(id, new TransformFeedback(id));
   1276 	}
   1277 
   1278 	mState.transformFeedback = id;
   1279 }
   1280 
   1281 bool Context::bindSampler(GLuint unit, GLuint sampler)
   1282 {
   1283 	mResourceManager->checkSamplerAllocation(sampler);
   1284 
   1285 	Sampler* samplerObject = getSampler(sampler);
   1286 
   1287 	if(sampler)
   1288 	{
   1289 		mState.sampler[unit] = samplerObject;
   1290 	}
   1291 
   1292 	return !!samplerObject;
   1293 }
   1294 
   1295 void Context::useProgram(GLuint program)
   1296 {
   1297 	GLuint priorProgram = mState.currentProgram;
   1298 	mState.currentProgram = program;               // Must switch before trying to delete, otherwise it only gets flagged.
   1299 
   1300 	if(priorProgram != program)
   1301 	{
   1302 		Program *newProgram = mResourceManager->getProgram(program);
   1303 		Program *oldProgram = mResourceManager->getProgram(priorProgram);
   1304 
   1305 		if(newProgram)
   1306 		{
   1307 			newProgram->addRef();
   1308 		}
   1309 
   1310 		if(oldProgram)
   1311 		{
   1312 			oldProgram->release();
   1313 		}
   1314 	}
   1315 }
   1316 
   1317 void Context::beginQuery(GLenum target, GLuint query)
   1318 {
   1319 	// From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id>
   1320 	// of zero, if the active query object name for <target> is non-zero (for the
   1321 	// targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if
   1322 	// the active query for either target is non-zero), if <id> is the name of an
   1323 	// existing query object whose type does not match <target>, or if <id> is the
   1324 	// active query object name for any query type, the error INVALID_OPERATION is
   1325 	// generated.
   1326 
   1327 	// Ensure no other queries are active
   1328 	// NOTE: If other queries than occlusion are supported, we will need to check
   1329 	// separately that:
   1330 	//    a) The query ID passed is not the current active query for any target/type
   1331 	//    b) There are no active queries for the requested target (and in the case
   1332 	//       of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT,
   1333 	//       no query may be active for either if glBeginQuery targets either.
   1334 	for(int i = 0; i < QUERY_TYPE_COUNT; i++)
   1335 	{
   1336 		if(mState.activeQuery[i])
   1337 		{
   1338 			return error(GL_INVALID_OPERATION);
   1339 		}
   1340 	}
   1341 
   1342 	QueryType qType;
   1343 	switch(target)
   1344 	{
   1345 	case GL_ANY_SAMPLES_PASSED_EXT:
   1346 		qType = QUERY_ANY_SAMPLES_PASSED;
   1347 		break;
   1348 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:
   1349 		qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;
   1350 		break;
   1351 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
   1352 		qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN;
   1353 		break;
   1354 	default:
   1355 		ASSERT(false);
   1356 	}
   1357 
   1358 	Query *queryObject = createQuery(query, target);
   1359 
   1360 	// Check that name was obtained with glGenQueries
   1361 	if(!queryObject)
   1362 	{
   1363 		return error(GL_INVALID_OPERATION);
   1364 	}
   1365 
   1366 	// Check for type mismatch
   1367 	if(queryObject->getType() != target)
   1368 	{
   1369 		return error(GL_INVALID_OPERATION);
   1370 	}
   1371 
   1372 	// Set query as active for specified target
   1373 	mState.activeQuery[qType] = queryObject;
   1374 
   1375 	// Begin query
   1376 	queryObject->begin();
   1377 }
   1378 
   1379 void Context::endQuery(GLenum target)
   1380 {
   1381 	QueryType qType;
   1382 
   1383 	switch(target)
   1384 	{
   1385 	case GL_ANY_SAMPLES_PASSED_EXT:                qType = QUERY_ANY_SAMPLES_PASSED;                    break;
   1386 	case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:   qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE;       break;
   1387 	case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; break;
   1388 	default: UNREACHABLE(target); return;
   1389 	}
   1390 
   1391 	Query *queryObject = mState.activeQuery[qType];
   1392 
   1393 	if(!queryObject)
   1394 	{
   1395 		return error(GL_INVALID_OPERATION);
   1396 	}
   1397 
   1398 	queryObject->end();
   1399 
   1400 	mState.activeQuery[qType] = nullptr;
   1401 }
   1402 
   1403 void Context::setFramebufferZero(Framebuffer *buffer)
   1404 {
   1405 	delete mFramebufferNameSpace.remove(0);
   1406 	mFramebufferNameSpace.insert(0, buffer);
   1407 }
   1408 
   1409 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
   1410 {
   1411 	Renderbuffer *renderbufferObject = mState.renderbuffer;
   1412 	renderbufferObject->setStorage(renderbuffer);
   1413 }
   1414 
   1415 Framebuffer *Context::getFramebuffer(unsigned int handle) const
   1416 {
   1417 	return mFramebufferNameSpace.find(handle);
   1418 }
   1419 
   1420 Fence *Context::getFence(unsigned int handle) const
   1421 {
   1422 	return mFenceNameSpace.find(handle);
   1423 }
   1424 
   1425 FenceSync *Context::getFenceSync(GLsync handle) const
   1426 {
   1427 	return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle)));
   1428 }
   1429 
   1430 Query *Context::getQuery(unsigned int handle) const
   1431 {
   1432 	return mQueryNameSpace.find(handle);
   1433 }
   1434 
   1435 Query *Context::createQuery(unsigned int handle, GLenum type)
   1436 {
   1437 	if(!mQueryNameSpace.isReserved(handle))
   1438 	{
   1439 		return nullptr;
   1440 	}
   1441 	else
   1442 	{
   1443 		Query *query = mQueryNameSpace.find(handle);
   1444 		if(!query)
   1445 		{
   1446 			query = new Query(handle, type);
   1447 			query->addRef();
   1448 			mQueryNameSpace.insert(handle, query);
   1449 		}
   1450 
   1451 		return query;
   1452 	}
   1453 }
   1454 
   1455 VertexArray *Context::getVertexArray(GLuint array) const
   1456 {
   1457 	return mVertexArrayNameSpace.find(array);
   1458 }
   1459 
   1460 VertexArray *Context::getCurrentVertexArray() const
   1461 {
   1462 	return getVertexArray(mState.vertexArray);
   1463 }
   1464 
   1465 bool Context::isVertexArray(GLuint array) const
   1466 {
   1467 	return mVertexArrayNameSpace.isReserved(array);
   1468 }
   1469 
   1470 bool Context::hasZeroDivisor() const
   1471 {
   1472 	// Verify there is at least one active attribute with a divisor of zero
   1473 	es2::Program *programObject = getCurrentProgram();
   1474 	for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
   1475 	{
   1476 		bool active = (programObject->getAttributeStream(attributeIndex) != -1);
   1477 		if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0)
   1478 		{
   1479 			return true;
   1480 		}
   1481 	}
   1482 
   1483 	return false;
   1484 }
   1485 
   1486 TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const
   1487 {
   1488 	return mTransformFeedbackNameSpace.find(transformFeedback);
   1489 }
   1490 
   1491 Sampler *Context::getSampler(GLuint sampler) const
   1492 {
   1493 	return mResourceManager->getSampler(sampler);
   1494 }
   1495 
   1496 bool Context::isSampler(GLuint sampler) const
   1497 {
   1498 	return mResourceManager->isSampler(sampler);
   1499 }
   1500 
   1501 Buffer *Context::getArrayBuffer() const
   1502 {
   1503 	return mState.arrayBuffer;
   1504 }
   1505 
   1506 Buffer *Context::getElementArrayBuffer() const
   1507 {
   1508 	return getCurrentVertexArray()->getElementArrayBuffer();
   1509 }
   1510 
   1511 Buffer *Context::getCopyReadBuffer() const
   1512 {
   1513 	return mState.copyReadBuffer;
   1514 }
   1515 
   1516 Buffer *Context::getCopyWriteBuffer() const
   1517 {
   1518 	return mState.copyWriteBuffer;
   1519 }
   1520 
   1521 Buffer *Context::getPixelPackBuffer() const
   1522 {
   1523 	return mState.pixelPackBuffer;
   1524 }
   1525 
   1526 Buffer *Context::getPixelUnpackBuffer() const
   1527 {
   1528 	return mState.pixelUnpackBuffer;
   1529 }
   1530 
   1531 Buffer *Context::getGenericUniformBuffer() const
   1532 {
   1533 	return mState.genericUniformBuffer;
   1534 }
   1535 
   1536 bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const
   1537 {
   1538 	switch(target)
   1539 	{
   1540 	case GL_ARRAY_BUFFER:
   1541 		*buffer = getArrayBuffer();
   1542 		break;
   1543 	case GL_ELEMENT_ARRAY_BUFFER:
   1544 		*buffer = getElementArrayBuffer();
   1545 		break;
   1546 	case GL_COPY_READ_BUFFER:
   1547 		if(clientVersion >= 3)
   1548 		{
   1549 			*buffer = getCopyReadBuffer();
   1550 			break;
   1551 		}
   1552 		else return false;
   1553 	case GL_COPY_WRITE_BUFFER:
   1554 		if(clientVersion >= 3)
   1555 		{
   1556 			*buffer = getCopyWriteBuffer();
   1557 			break;
   1558 		}
   1559 		else return false;
   1560 	case GL_PIXEL_PACK_BUFFER:
   1561 		if(clientVersion >= 3)
   1562 		{
   1563 			*buffer = getPixelPackBuffer();
   1564 			break;
   1565 		}
   1566 		else return false;
   1567 	case GL_PIXEL_UNPACK_BUFFER:
   1568 		if(clientVersion >= 3)
   1569 		{
   1570 			*buffer = getPixelUnpackBuffer();
   1571 			break;
   1572 		}
   1573 		else return false;
   1574 	case GL_TRANSFORM_FEEDBACK_BUFFER:
   1575 		if(clientVersion >= 3)
   1576 		{
   1577 			TransformFeedback* transformFeedback = getTransformFeedback();
   1578 			*buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr;
   1579 			break;
   1580 		}
   1581 		else return false;
   1582 	case GL_UNIFORM_BUFFER:
   1583 		if(clientVersion >= 3)
   1584 		{
   1585 			*buffer = getGenericUniformBuffer();
   1586 			break;
   1587 		}
   1588 		else return false;
   1589 	default:
   1590 		return false;
   1591 	}
   1592 	return true;
   1593 }
   1594 
   1595 TransformFeedback *Context::getTransformFeedback() const
   1596 {
   1597 	return getTransformFeedback(mState.transformFeedback);
   1598 }
   1599 
   1600 Program *Context::getCurrentProgram() const
   1601 {
   1602 	return mResourceManager->getProgram(mState.currentProgram);
   1603 }
   1604 
   1605 Texture2D *Context::getTexture2D() const
   1606 {
   1607 	return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D));
   1608 }
   1609 
   1610 Texture3D *Context::getTexture3D() const
   1611 {
   1612 	return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D));
   1613 }
   1614 
   1615 Texture2DArray *Context::getTexture2DArray() const
   1616 {
   1617 	return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY));
   1618 }
   1619 
   1620 TextureCubeMap *Context::getTextureCubeMap() const
   1621 {
   1622 	return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE));
   1623 }
   1624 
   1625 TextureExternal *Context::getTextureExternal() const
   1626 {
   1627 	return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL));
   1628 }
   1629 
   1630 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const
   1631 {
   1632 	GLuint texid = mState.samplerTexture[type][sampler].name();
   1633 
   1634 	if(texid == 0)   // Special case: 0 refers to different initial textures based on the target
   1635 	{
   1636 		switch(type)
   1637 		{
   1638 		case TEXTURE_2D: return mTexture2DZero;
   1639 		case TEXTURE_3D: return mTexture3DZero;
   1640 		case TEXTURE_2D_ARRAY: return mTexture2DArrayZero;
   1641 		case TEXTURE_CUBE: return mTextureCubeMapZero;
   1642 		case TEXTURE_EXTERNAL: return mTextureExternalZero;
   1643 		default: UNREACHABLE(type);
   1644 		}
   1645 	}
   1646 
   1647 	return mState.samplerTexture[type][sampler];
   1648 }
   1649 
   1650 void Context::samplerParameteri(GLuint sampler, GLenum pname, GLint param)
   1651 {
   1652 	mResourceManager->checkSamplerAllocation(sampler);
   1653 
   1654 	Sampler *samplerObject = getSampler(sampler);
   1655 	ASSERT(samplerObject);
   1656 
   1657 	switch(pname)
   1658 	{
   1659 	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(param));       break;
   1660 	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(param));       break;
   1661 	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(param));           break;
   1662 	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(param));           break;
   1663 	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(param));           break;
   1664 	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(static_cast<GLfloat>(param));         break;
   1665 	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(static_cast<GLfloat>(param));         break;
   1666 	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(param));  break;
   1667 	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(param));  break;
   1668 	default:                       UNREACHABLE(pname); break;
   1669 	}
   1670 }
   1671 
   1672 void Context::samplerParameterf(GLuint sampler, GLenum pname, GLfloat param)
   1673 {
   1674 	mResourceManager->checkSamplerAllocation(sampler);
   1675 
   1676 	Sampler *samplerObject = getSampler(sampler);
   1677 	ASSERT(samplerObject);
   1678 
   1679 	switch(pname)
   1680 	{
   1681 	case GL_TEXTURE_MIN_FILTER:    samplerObject->setMinFilter(static_cast<GLenum>(roundf(param)));       break;
   1682 	case GL_TEXTURE_MAG_FILTER:    samplerObject->setMagFilter(static_cast<GLenum>(roundf(param)));       break;
   1683 	case GL_TEXTURE_WRAP_S:        samplerObject->setWrapS(static_cast<GLenum>(roundf(param)));           break;
   1684 	case GL_TEXTURE_WRAP_T:        samplerObject->setWrapT(static_cast<GLenum>(roundf(param)));           break;
   1685 	case GL_TEXTURE_WRAP_R:        samplerObject->setWrapR(static_cast<GLenum>(roundf(param)));           break;
   1686 	case GL_TEXTURE_MIN_LOD:       samplerObject->setMinLod(param);                                       break;
   1687 	case GL_TEXTURE_MAX_LOD:       samplerObject->setMaxLod(param);                                       break;
   1688 	case GL_TEXTURE_COMPARE_MODE:  samplerObject->setComparisonMode(static_cast<GLenum>(roundf(param)));  break;
   1689 	case GL_TEXTURE_COMPARE_FUNC:  samplerObject->setComparisonFunc(static_cast<GLenum>(roundf(param)));  break;
   1690 	default:                       UNREACHABLE(pname); break;
   1691 	}
   1692 }
   1693 
   1694 GLint Context::getSamplerParameteri(GLuint sampler, GLenum pname)
   1695 {
   1696 	mResourceManager->checkSamplerAllocation(sampler);
   1697 
   1698 	Sampler *samplerObject = getSampler(sampler);
   1699 	ASSERT(samplerObject);
   1700 
   1701 	switch(pname)
   1702 	{
   1703 	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLint>(samplerObject->getMinFilter());
   1704 	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLint>(samplerObject->getMagFilter());
   1705 	case GL_TEXTURE_WRAP_S:        return static_cast<GLint>(samplerObject->getWrapS());
   1706 	case GL_TEXTURE_WRAP_T:        return static_cast<GLint>(samplerObject->getWrapT());
   1707 	case GL_TEXTURE_WRAP_R:        return static_cast<GLint>(samplerObject->getWrapR());
   1708 	case GL_TEXTURE_MIN_LOD:       return static_cast<GLint>(roundf(samplerObject->getMinLod()));
   1709 	case GL_TEXTURE_MAX_LOD:       return static_cast<GLint>(roundf(samplerObject->getMaxLod()));
   1710 	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLint>(samplerObject->getComparisonMode());
   1711 	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLint>(samplerObject->getComparisonFunc());
   1712 	default:                       UNREACHABLE(pname); return 0;
   1713 	}
   1714 }
   1715 
   1716 GLfloat Context::getSamplerParameterf(GLuint sampler, GLenum pname)
   1717 {
   1718 	mResourceManager->checkSamplerAllocation(sampler);
   1719 
   1720 	Sampler *samplerObject = getSampler(sampler);
   1721 	ASSERT(samplerObject);
   1722 
   1723 	switch(pname)
   1724 	{
   1725 	case GL_TEXTURE_MIN_FILTER:    return static_cast<GLfloat>(samplerObject->getMinFilter());
   1726 	case GL_TEXTURE_MAG_FILTER:    return static_cast<GLfloat>(samplerObject->getMagFilter());
   1727 	case GL_TEXTURE_WRAP_S:        return static_cast<GLfloat>(samplerObject->getWrapS());
   1728 	case GL_TEXTURE_WRAP_T:        return static_cast<GLfloat>(samplerObject->getWrapT());
   1729 	case GL_TEXTURE_WRAP_R:        return static_cast<GLfloat>(samplerObject->getWrapR());
   1730 	case GL_TEXTURE_MIN_LOD:       return samplerObject->getMinLod();
   1731 	case GL_TEXTURE_MAX_LOD:       return samplerObject->getMaxLod();
   1732 	case GL_TEXTURE_COMPARE_MODE:  return static_cast<GLfloat>(samplerObject->getComparisonMode());
   1733 	case GL_TEXTURE_COMPARE_FUNC:  return static_cast<GLfloat>(samplerObject->getComparisonFunc());
   1734 	default:                       UNREACHABLE(pname); return 0;
   1735 	}
   1736 }
   1737 
   1738 bool Context::getBooleanv(GLenum pname, GLboolean *params) const
   1739 {
   1740 	switch(pname)
   1741 	{
   1742 	case GL_SHADER_COMPILER:          *params = GL_TRUE;                          break;
   1743 	case GL_SAMPLE_COVERAGE_INVERT:   *params = mState.sampleCoverageInvert;      break;
   1744 	case GL_DEPTH_WRITEMASK:          *params = mState.depthMask;                 break;
   1745 	case GL_COLOR_WRITEMASK:
   1746 		params[0] = mState.colorMaskRed;
   1747 		params[1] = mState.colorMaskGreen;
   1748 		params[2] = mState.colorMaskBlue;
   1749 		params[3] = mState.colorMaskAlpha;
   1750 		break;
   1751 	case GL_CULL_FACE:                *params = mState.cullFaceEnabled;                  break;
   1752 	case GL_POLYGON_OFFSET_FILL:      *params = mState.polygonOffsetFillEnabled;         break;
   1753 	case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled;     break;
   1754 	case GL_SAMPLE_COVERAGE:          *params = mState.sampleCoverageEnabled;            break;
   1755 	case GL_SCISSOR_TEST:             *params = mState.scissorTestEnabled;               break;
   1756 	case GL_STENCIL_TEST:             *params = mState.stencilTestEnabled;               break;
   1757 	case GL_DEPTH_TEST:               *params = mState.depthTestEnabled;                 break;
   1758 	case GL_BLEND:                    *params = mState.blendEnabled;                     break;
   1759 	case GL_DITHER:                   *params = mState.ditherEnabled;                    break;
   1760 	case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndexEnabled; break;
   1761 	case GL_RASTERIZER_DISCARD:       *params = mState.rasterizerDiscardEnabled;         break;
   1762 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
   1763 		{
   1764 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   1765 			if(transformFeedback)
   1766 			{
   1767 				*params = transformFeedback->isActive();
   1768 				break;
   1769 			}
   1770 			else return false;
   1771 		}
   1772 	 case GL_TRANSFORM_FEEDBACK_PAUSED:
   1773 		{
   1774 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   1775 			if(transformFeedback)
   1776 			{
   1777 				*params = transformFeedback->isPaused();
   1778 				break;
   1779 			}
   1780 			else return false;
   1781 		}
   1782 	default:
   1783 		return false;
   1784 	}
   1785 
   1786 	return true;
   1787 }
   1788 
   1789 bool Context::getFloatv(GLenum pname, GLfloat *params) const
   1790 {
   1791 	// Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation
   1792 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1793 	// GetIntegerv as its native query function. As it would require conversion in any
   1794 	// case, this should make no difference to the calling application.
   1795 	switch(pname)
   1796 	{
   1797 	case GL_LINE_WIDTH:               *params = mState.lineWidth;            break;
   1798 	case GL_SAMPLE_COVERAGE_VALUE:    *params = mState.sampleCoverageValue;  break;
   1799 	case GL_DEPTH_CLEAR_VALUE:        *params = mState.depthClearValue;      break;
   1800 	case GL_POLYGON_OFFSET_FACTOR:    *params = mState.polygonOffsetFactor;  break;
   1801 	case GL_POLYGON_OFFSET_UNITS:     *params = mState.polygonOffsetUnits;   break;
   1802 	case GL_ALIASED_LINE_WIDTH_RANGE:
   1803 		params[0] = ALIASED_LINE_WIDTH_RANGE_MIN;
   1804 		params[1] = ALIASED_LINE_WIDTH_RANGE_MAX;
   1805 		break;
   1806 	case GL_ALIASED_POINT_SIZE_RANGE:
   1807 		params[0] = ALIASED_POINT_SIZE_RANGE_MIN;
   1808 		params[1] = ALIASED_POINT_SIZE_RANGE_MAX;
   1809 		break;
   1810 	case GL_DEPTH_RANGE:
   1811 		params[0] = mState.zNear;
   1812 		params[1] = mState.zFar;
   1813 		break;
   1814 	case GL_COLOR_CLEAR_VALUE:
   1815 		params[0] = mState.colorClearValue.red;
   1816 		params[1] = mState.colorClearValue.green;
   1817 		params[2] = mState.colorClearValue.blue;
   1818 		params[3] = mState.colorClearValue.alpha;
   1819 		break;
   1820 	case GL_BLEND_COLOR:
   1821 		params[0] = mState.blendColor.red;
   1822 		params[1] = mState.blendColor.green;
   1823 		params[2] = mState.blendColor.blue;
   1824 		params[3] = mState.blendColor.alpha;
   1825 		break;
   1826 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   1827 		*params = MAX_TEXTURE_MAX_ANISOTROPY;
   1828 		break;
   1829 	default:
   1830 		return false;
   1831 	}
   1832 
   1833 	return true;
   1834 }
   1835 
   1836 template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const;
   1837 template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const;
   1838 
   1839 template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const
   1840 {
   1841 	// Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation
   1842 	// because it is stored as a float, despite the fact that the GL ES 2.0 spec names
   1843 	// GetIntegerv as its native query function. As it would require conversion in any
   1844 	// case, this should make no difference to the calling application. You may find it in
   1845 	// Context::getFloatv.
   1846 	switch(pname)
   1847 	{
   1848 	case GL_MAX_VERTEX_ATTRIBS:               *params = MAX_VERTEX_ATTRIBS;               break;
   1849 	case GL_MAX_VERTEX_UNIFORM_VECTORS:       *params = MAX_VERTEX_UNIFORM_VECTORS;       break;
   1850 	case GL_MAX_VARYING_VECTORS:              *params = MAX_VARYING_VECTORS;              break;
   1851 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break;
   1852 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS;   break;
   1853 	case GL_MAX_TEXTURE_IMAGE_UNITS:          *params = MAX_TEXTURE_IMAGE_UNITS;          break;
   1854 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:     *params = MAX_FRAGMENT_UNIFORM_VECTORS;     break;
   1855 	case GL_MAX_RENDERBUFFER_SIZE:            *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break;
   1856 	case GL_NUM_SHADER_BINARY_FORMATS:        *params = 0;                                    break;
   1857 	case GL_SHADER_BINARY_FORMATS:      /* no shader binary formats are supported */          break;
   1858 	case GL_ARRAY_BUFFER_BINDING:             *params = getArrayBufferName();                 break;
   1859 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:     *params = getElementArrayBufferName();          break;
   1860 //	case GL_FRAMEBUFFER_BINDING:            // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
   1861 	case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.drawFramebuffer;               break;
   1862 	case GL_READ_FRAMEBUFFER_BINDING_ANGLE:   *params = mState.readFramebuffer;               break;
   1863 	case GL_RENDERBUFFER_BINDING:             *params = mState.renderbuffer.name();           break;
   1864 	case GL_CURRENT_PROGRAM:                  *params = mState.currentProgram;                break;
   1865 	case GL_PACK_ALIGNMENT:                   *params = mState.packAlignment;                 break;
   1866 	case GL_UNPACK_ALIGNMENT:                 *params = mState.unpackInfo.alignment;          break;
   1867 	case GL_GENERATE_MIPMAP_HINT:             *params = mState.generateMipmapHint;            break;
   1868 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break;
   1869 	case GL_ACTIVE_TEXTURE:                   *params = (mState.activeSampler + GL_TEXTURE0); break;
   1870 	case GL_STENCIL_FUNC:                     *params = mState.stencilFunc;                   break;
   1871 	case GL_STENCIL_REF:                      *params = mState.stencilRef;                    break;
   1872 	case GL_STENCIL_VALUE_MASK:               *params = sw::clampToSignedInt(mState.stencilMask); break;
   1873 	case GL_STENCIL_BACK_FUNC:                *params = mState.stencilBackFunc;               break;
   1874 	case GL_STENCIL_BACK_REF:                 *params = mState.stencilBackRef;                break;
   1875 	case GL_STENCIL_BACK_VALUE_MASK:          *params = sw::clampToSignedInt(mState.stencilBackMask); break;
   1876 	case GL_STENCIL_FAIL:                     *params = mState.stencilFail;                   break;
   1877 	case GL_STENCIL_PASS_DEPTH_FAIL:          *params = mState.stencilPassDepthFail;          break;
   1878 	case GL_STENCIL_PASS_DEPTH_PASS:          *params = mState.stencilPassDepthPass;          break;
   1879 	case GL_STENCIL_BACK_FAIL:                *params = mState.stencilBackFail;               break;
   1880 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:     *params = mState.stencilBackPassDepthFail;      break;
   1881 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:     *params = mState.stencilBackPassDepthPass;      break;
   1882 	case GL_DEPTH_FUNC:                       *params = mState.depthFunc;                     break;
   1883 	case GL_BLEND_SRC_RGB:                    *params = mState.sourceBlendRGB;                break;
   1884 	case GL_BLEND_SRC_ALPHA:                  *params = mState.sourceBlendAlpha;              break;
   1885 	case GL_BLEND_DST_RGB:                    *params = mState.destBlendRGB;                  break;
   1886 	case GL_BLEND_DST_ALPHA:                  *params = mState.destBlendAlpha;                break;
   1887 	case GL_BLEND_EQUATION_RGB:               *params = mState.blendEquationRGB;              break;
   1888 	case GL_BLEND_EQUATION_ALPHA:             *params = mState.blendEquationAlpha;            break;
   1889 	case GL_STENCIL_WRITEMASK:                *params = sw::clampToSignedInt(mState.stencilWritemask); break;
   1890 	case GL_STENCIL_BACK_WRITEMASK:           *params = sw::clampToSignedInt(mState.stencilBackWritemask); break;
   1891 	case GL_STENCIL_CLEAR_VALUE:              *params = mState.stencilClearValue;             break;
   1892 	case GL_SUBPIXEL_BITS:                    *params = 4;                                    break;
   1893 	case GL_MAX_TEXTURE_SIZE:                 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE;          break;
   1894 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:        *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break;
   1895 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:   *params = NUM_COMPRESSED_TEXTURE_FORMATS;           break;
   1896 	case GL_MAX_SAMPLES_ANGLE:                *params = IMPLEMENTATION_MAX_SAMPLES;               break;
   1897 	case GL_SAMPLE_BUFFERS:
   1898 	case GL_SAMPLES:
   1899 		{
   1900 			Framebuffer *framebuffer = getDrawFramebuffer();
   1901 			int width, height, samples;
   1902 
   1903 			if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE)
   1904 			{
   1905 				switch(pname)
   1906 				{
   1907 				case GL_SAMPLE_BUFFERS:
   1908 					if(samples > 1)
   1909 					{
   1910 						*params = 1;
   1911 					}
   1912 					else
   1913 					{
   1914 						*params = 0;
   1915 					}
   1916 					break;
   1917 				case GL_SAMPLES:
   1918 					*params = samples;
   1919 					break;
   1920 				}
   1921 			}
   1922 			else
   1923 			{
   1924 				*params = 0;
   1925 			}
   1926 		}
   1927 		break;
   1928 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   1929 		{
   1930 			Framebuffer *framebuffer = getReadFramebuffer();
   1931 			*params = framebuffer->getImplementationColorReadType();
   1932 		}
   1933 		break;
   1934 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   1935 		{
   1936 			Framebuffer *framebuffer = getReadFramebuffer();
   1937 			*params = framebuffer->getImplementationColorReadFormat();
   1938 		}
   1939 		break;
   1940 	case GL_MAX_VIEWPORT_DIMS:
   1941 		{
   1942 			int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE;
   1943 			params[0] = maxDimension;
   1944 			params[1] = maxDimension;
   1945 		}
   1946 		break;
   1947 	case GL_COMPRESSED_TEXTURE_FORMATS:
   1948 		{
   1949 			for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++)
   1950 			{
   1951 				params[i] = compressedTextureFormats[i];
   1952 			}
   1953 		}
   1954 		break;
   1955 	case GL_VIEWPORT:
   1956 		params[0] = mState.viewportX;
   1957 		params[1] = mState.viewportY;
   1958 		params[2] = mState.viewportWidth;
   1959 		params[3] = mState.viewportHeight;
   1960 		break;
   1961 	case GL_SCISSOR_BOX:
   1962 		params[0] = mState.scissorX;
   1963 		params[1] = mState.scissorY;
   1964 		params[2] = mState.scissorWidth;
   1965 		params[3] = mState.scissorHeight;
   1966 		break;
   1967 	case GL_CULL_FACE_MODE:                   *params = mState.cullMode;                 break;
   1968 	case GL_FRONT_FACE:                       *params = mState.frontFace;                break;
   1969 	case GL_RED_BITS:
   1970 	case GL_GREEN_BITS:
   1971 	case GL_BLUE_BITS:
   1972 	case GL_ALPHA_BITS:
   1973 		{
   1974 			Framebuffer *framebuffer = getDrawFramebuffer();
   1975 			Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0);
   1976 
   1977 			if(colorbuffer)
   1978 			{
   1979 				switch(pname)
   1980 				{
   1981 				case GL_RED_BITS:   *params = colorbuffer->getRedSize();   break;
   1982 				case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break;
   1983 				case GL_BLUE_BITS:  *params = colorbuffer->getBlueSize();  break;
   1984 				case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break;
   1985 				}
   1986 			}
   1987 			else
   1988 			{
   1989 				*params = 0;
   1990 			}
   1991 		}
   1992 		break;
   1993 	case GL_DEPTH_BITS:
   1994 		{
   1995 			Framebuffer *framebuffer = getDrawFramebuffer();
   1996 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
   1997 
   1998 			if(depthbuffer)
   1999 			{
   2000 				*params = depthbuffer->getDepthSize();
   2001 			}
   2002 			else
   2003 			{
   2004 				*params = 0;
   2005 			}
   2006 		}
   2007 		break;
   2008 	case GL_STENCIL_BITS:
   2009 		{
   2010 			Framebuffer *framebuffer = getDrawFramebuffer();
   2011 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
   2012 
   2013 			if(stencilbuffer)
   2014 			{
   2015 				*params = stencilbuffer->getStencilSize();
   2016 			}
   2017 			else
   2018 			{
   2019 				*params = 0;
   2020 			}
   2021 		}
   2022 		break;
   2023 	case GL_TEXTURE_BINDING_2D:
   2024 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
   2025 		{
   2026 			error(GL_INVALID_OPERATION);
   2027 			return false;
   2028 		}
   2029 
   2030 		*params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name();
   2031 		break;
   2032 	case GL_TEXTURE_BINDING_CUBE_MAP:
   2033 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
   2034 		{
   2035 			error(GL_INVALID_OPERATION);
   2036 			return false;
   2037 		}
   2038 
   2039 		*params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name();
   2040 		break;
   2041 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
   2042 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
   2043 		{
   2044 			error(GL_INVALID_OPERATION);
   2045 			return false;
   2046 		}
   2047 
   2048 		*params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name();
   2049 		break;
   2050 	case GL_TEXTURE_BINDING_3D_OES:
   2051 		if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
   2052 		{
   2053 			error(GL_INVALID_OPERATION);
   2054 			return false;
   2055 		}
   2056 
   2057 		*params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name();
   2058 		break;
   2059 	case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0
   2060 		if(clientVersion < 3)
   2061 		{
   2062 			return false;
   2063 		}
   2064 		else if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)
   2065 		{
   2066 			error(GL_INVALID_OPERATION);
   2067 			return false;
   2068 		}
   2069 
   2070 		*params = mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler].name();
   2071 		break;
   2072 	case GL_COPY_READ_BUFFER_BINDING: // name, initially 0
   2073 		if(clientVersion >= 3)
   2074 		{
   2075 			*params = mState.copyReadBuffer.name();
   2076 		}
   2077 		else
   2078 		{
   2079 			return false;
   2080 		}
   2081 		break;
   2082 	case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0
   2083 		if(clientVersion >= 3)
   2084 		{
   2085 			*params = mState.copyWriteBuffer.name();
   2086 		}
   2087 		else
   2088 		{
   2089 			return false;
   2090 		}
   2091 		break;
   2092 	case GL_DRAW_BUFFER0:
   2093 	case GL_DRAW_BUFFER1:
   2094 	case GL_DRAW_BUFFER2:
   2095 	case GL_DRAW_BUFFER3:
   2096 	case GL_DRAW_BUFFER4:
   2097 	case GL_DRAW_BUFFER5:
   2098 	case GL_DRAW_BUFFER6:
   2099 	case GL_DRAW_BUFFER7:
   2100 	case GL_DRAW_BUFFER8:
   2101 	case GL_DRAW_BUFFER9:
   2102 	case GL_DRAW_BUFFER10:
   2103 	case GL_DRAW_BUFFER11:
   2104 	case GL_DRAW_BUFFER12:
   2105 	case GL_DRAW_BUFFER13:
   2106 	case GL_DRAW_BUFFER14:
   2107 	case GL_DRAW_BUFFER15:
   2108 		*params = getDrawFramebuffer()->getDrawBuffer(pname - GL_DRAW_BUFFER0);
   2109 		break;
   2110 	case GL_MAJOR_VERSION:
   2111 		if(clientVersion >= 3)
   2112 		{
   2113 			*params = clientVersion;
   2114 		}
   2115 		else
   2116 		{
   2117 			return false;
   2118 		}
   2119 		break;
   2120 	case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048
   2121 		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
   2122 		break;
   2123 	case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048
   2124 		*params = IMPLEMENTATION_MAX_TEXTURE_SIZE;
   2125 		break;
   2126 	case GL_MAX_COLOR_ATTACHMENTS:
   2127 		*params = MAX_COLOR_ATTACHMENTS;
   2128 		break;
   2129 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048
   2130 		*params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS;
   2131 		break;
   2132 	case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70
   2133 		UNIMPLEMENTED();
   2134 		*params = 70;
   2135 		break;
   2136 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176
   2137 		*params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS;
   2138 		break;
   2139 	case GL_MAX_DRAW_BUFFERS:
   2140 		*params = MAX_DRAW_BUFFERS;
   2141 		break;
   2142 	case GL_MAX_ELEMENT_INDEX:
   2143 		*params = MAX_ELEMENT_INDEX;
   2144 		break;
   2145 	case GL_MAX_ELEMENTS_INDICES:
   2146 		*params = MAX_ELEMENTS_INDICES;
   2147 		break;
   2148 	case GL_MAX_ELEMENTS_VERTICES:
   2149 		*params = MAX_ELEMENTS_VERTICES;
   2150 		break;
   2151 	case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128
   2152 		UNIMPLEMENTED();
   2153 		*params = 128;
   2154 		break;
   2155 	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12
   2156 		*params = MAX_FRAGMENT_UNIFORM_BLOCKS;
   2157 		break;
   2158 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 896
   2159 		*params = MAX_FRAGMENT_UNIFORM_COMPONENTS;
   2160 		break;
   2161 	case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7
   2162 		UNIMPLEMENTED();
   2163 		*params = 7;
   2164 		break;
   2165 	case GL_MAX_SERVER_WAIT_TIMEOUT: // integer
   2166 		UNIMPLEMENTED();
   2167 		*params = 0;
   2168 		break;
   2169 	case GL_MAX_TEXTURE_LOD_BIAS: // integer,  at least 2.0
   2170 		UNIMPLEMENTED();
   2171 		*params = 2;
   2172 		break;
   2173 	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64
   2174 		*params = sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS;
   2175 		break;
   2176 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4
   2177 		UNIMPLEMENTED();
   2178 		*params = MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS;
   2179 		break;
   2180 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4
   2181 		*params = sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS;
   2182 		break;
   2183 	case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384
   2184 		*params = MAX_UNIFORM_BLOCK_SIZE;
   2185 		break;
   2186 	case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 24
   2187 		*params = MAX_UNIFORM_BUFFER_BINDINGS;
   2188 		break;
   2189 	case GL_MAX_VARYING_COMPONENTS: // integer, at least 60
   2190 		UNIMPLEMENTED();
   2191 		*params = 60;
   2192 		break;
   2193 	case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer,  at least 64
   2194 		UNIMPLEMENTED();
   2195 		*params = 64;
   2196 		break;
   2197 	case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer,  at least 12
   2198 		*params = MAX_VERTEX_UNIFORM_BLOCKS;
   2199 		break;
   2200 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer,  at least 1024
   2201 		*params = MAX_VERTEX_UNIFORM_COMPONENTS;
   2202 		break;
   2203 	case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8
   2204 		UNIMPLEMENTED();
   2205 		*params = -8;
   2206 		break;
   2207 	case GL_MINOR_VERSION: // integer
   2208 		UNIMPLEMENTED();
   2209 		*params = 0;
   2210 		break;
   2211 	case GL_NUM_EXTENSIONS: // integer
   2212 		GLuint numExtensions;
   2213 		getExtensions(0, &numExtensions);
   2214 		*params = numExtensions;
   2215 		break;
   2216 	case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0
   2217 		UNIMPLEMENTED();
   2218 		*params = 0;
   2219 		break;
   2220 	case GL_PACK_ROW_LENGTH: // integer, initially 0
   2221 		*params = mState.packRowLength;
   2222 		break;
   2223 	case GL_PACK_SKIP_PIXELS: // integer, initially 0
   2224 		*params = mState.packSkipPixels;
   2225 		break;
   2226 	case GL_PACK_SKIP_ROWS: // integer, initially 0
   2227 		*params = mState.packSkipRows;
   2228 		break;
   2229 	case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0
   2230 		if(clientVersion >= 3)
   2231 		{
   2232 			*params = mState.pixelPackBuffer.name();
   2233 		}
   2234 		else
   2235 		{
   2236 			return false;
   2237 		}
   2238 		break;
   2239 	case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0
   2240 		if(clientVersion >= 3)
   2241 		{
   2242 			*params = mState.pixelUnpackBuffer.name();
   2243 		}
   2244 		else
   2245 		{
   2246 			return false;
   2247 		}
   2248 		break;
   2249 	case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS]
   2250 		UNIMPLEMENTED();
   2251 		*params = 0;
   2252 		break;
   2253 	case GL_READ_BUFFER: // symbolic constant,  initial value is GL_BACK
   2254 		*params = getReadFramebuffer()->getReadBuffer();
   2255 		break;
   2256 	case GL_SAMPLER_BINDING: // GLint, default 0
   2257 		*params = mState.sampler[mState.activeSampler].name();
   2258 		break;
   2259 	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
   2260 		if(clientVersion >= 3)
   2261 		{
   2262 			*params = mState.genericUniformBuffer.name();
   2263 		}
   2264 		else
   2265 		{
   2266 			return false;
   2267 		}
   2268 		break;
   2269 	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1
   2270 		*params = UNIFORM_BUFFER_OFFSET_ALIGNMENT;
   2271 		break;
   2272 	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
   2273 		if(clientVersion >= 3)
   2274 		{
   2275 			*params = mState.genericUniformBuffer->size();
   2276 		}
   2277 		else
   2278 		{
   2279 			return false;
   2280 		}
   2281 		break;
   2282 	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
   2283 		if(clientVersion >= 3)
   2284 		{
   2285 			*params = mState.genericUniformBuffer->offset();
   2286 		}
   2287 		else
   2288 		{
   2289 			return false;
   2290 		}
   2291 		*params = 0;
   2292 		break;
   2293 	case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0
   2294 		*params = mState.unpackInfo.imageHeight;
   2295 		break;
   2296 	case GL_UNPACK_ROW_LENGTH: // integer, initially 0
   2297 		*params = mState.unpackInfo.rowLength;
   2298 		break;
   2299 	case GL_UNPACK_SKIP_IMAGES: // integer, initially 0
   2300 		*params = mState.unpackInfo.skipImages;
   2301 		break;
   2302 	case GL_UNPACK_SKIP_PIXELS: // integer, initially 0
   2303 		*params = mState.unpackInfo.skipPixels;
   2304 		break;
   2305 	case GL_UNPACK_SKIP_ROWS: // integer, initially 0
   2306 		*params = mState.unpackInfo.skipRows;
   2307 		break;
   2308 	case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0
   2309 		*params = getCurrentVertexArray()->name;
   2310 		break;
   2311 	case GL_TRANSFORM_FEEDBACK_BINDING:
   2312 		{
   2313 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   2314 			if(transformFeedback)
   2315 			{
   2316 				*params = transformFeedback->name;
   2317 			}
   2318 			else
   2319 			{
   2320 				return false;
   2321 			}
   2322 		}
   2323 		break;
   2324 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   2325 		{
   2326 			TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   2327 			if(transformFeedback)
   2328 			{
   2329 				*params = transformFeedback->getGenericBufferName();
   2330 			}
   2331 			else
   2332 			{
   2333 				return false;
   2334 			}
   2335 		}
   2336 		break;
   2337 	default:
   2338 		return false;
   2339 	}
   2340 
   2341 	return true;
   2342 }
   2343 
   2344 template bool Context::getTransformFeedbackiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
   2345 template bool Context::getTransformFeedbackiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
   2346 
   2347 template<typename T> bool Context::getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const
   2348 {
   2349 	TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback);
   2350 	if(!transformFeedback)
   2351 	{
   2352 		return false;
   2353 	}
   2354 
   2355 	switch(pname)
   2356 	{
   2357 	case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0
   2358 		*param = transformFeedback->name;
   2359 		break;
   2360 	case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE
   2361 		*param = transformFeedback->isActive();
   2362 		break;
   2363 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0
   2364 		*param = transformFeedback->getBufferName(index);
   2365 		break;
   2366 	case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE
   2367 		*param = transformFeedback->isPaused();
   2368 		break;
   2369 	case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
   2370 		if(transformFeedback->getBuffer(index))
   2371 		{
   2372 			*param = transformFeedback->getSize(index);
   2373 			break;
   2374 		}
   2375 		else return false;
   2376 	case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0
   2377 		if(transformFeedback->getBuffer(index))
   2378 		{
   2379 			*param = transformFeedback->getOffset(index);
   2380 		break;
   2381 		}
   2382 		else return false;
   2383 	default:
   2384 		return false;
   2385 	}
   2386 
   2387 	return true;
   2388 }
   2389 
   2390 template bool Context::getUniformBufferiv<GLint>(GLuint index, GLenum pname, GLint *param) const;
   2391 template bool Context::getUniformBufferiv<GLint64>(GLuint index, GLenum pname, GLint64 *param) const;
   2392 
   2393 template<typename T> bool Context::getUniformBufferiv(GLuint index, GLenum pname, T *param) const
   2394 {
   2395 	const BufferBinding& uniformBuffer = mState.uniformBuffers[index];
   2396 
   2397 	switch(pname)
   2398 	{
   2399 	case GL_UNIFORM_BUFFER_BINDING: // name, initially 0
   2400 		*param = uniformBuffer.get().name();
   2401 		break;
   2402 	case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0
   2403 		*param = uniformBuffer.getSize();
   2404 		break;
   2405 	case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0
   2406 		*param = uniformBuffer.getOffset();
   2407 		break;
   2408 	default:
   2409 		return false;
   2410 	}
   2411 
   2412 	return true;
   2413 }
   2414 
   2415 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const
   2416 {
   2417 	// Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
   2418 	// is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
   2419 	// to the fact that it is stored internally as a float, and so would require conversion
   2420 	// if returned from Context::getIntegerv. Since this conversion is already implemented
   2421 	// in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
   2422 	// place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
   2423 	// application.
   2424 	switch(pname)
   2425 	{
   2426 	case GL_COMPRESSED_TEXTURE_FORMATS:
   2427 		{
   2428 			*type = GL_INT;
   2429 			*numParams = NUM_COMPRESSED_TEXTURE_FORMATS;
   2430 		}
   2431 		break;
   2432 	case GL_SHADER_BINARY_FORMATS:
   2433 		{
   2434 			*type = GL_INT;
   2435 			*numParams = 0;
   2436 		}
   2437 		break;
   2438 	case GL_MAX_VERTEX_ATTRIBS:
   2439 	case GL_MAX_VERTEX_UNIFORM_VECTORS:
   2440 	case GL_MAX_VARYING_VECTORS:
   2441 	case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
   2442 	case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
   2443 	case GL_MAX_TEXTURE_IMAGE_UNITS:
   2444 	case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
   2445 	case GL_MAX_RENDERBUFFER_SIZE:
   2446 	case GL_NUM_SHADER_BINARY_FORMATS:
   2447 	case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
   2448 	case GL_ARRAY_BUFFER_BINDING:
   2449 	case GL_FRAMEBUFFER_BINDING: // Same as GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
   2450 	case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
   2451 	case GL_RENDERBUFFER_BINDING:
   2452 	case GL_CURRENT_PROGRAM:
   2453 	case GL_PACK_ALIGNMENT:
   2454 	case GL_UNPACK_ALIGNMENT:
   2455 	case GL_GENERATE_MIPMAP_HINT:
   2456 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
   2457 	case GL_RED_BITS:
   2458 	case GL_GREEN_BITS:
   2459 	case GL_BLUE_BITS:
   2460 	case GL_ALPHA_BITS:
   2461 	case GL_DEPTH_BITS:
   2462 	case GL_STENCIL_BITS:
   2463 	case GL_ELEMENT_ARRAY_BUFFER_BINDING:
   2464 	case GL_CULL_FACE_MODE:
   2465 	case GL_FRONT_FACE:
   2466 	case GL_ACTIVE_TEXTURE:
   2467 	case GL_STENCIL_FUNC:
   2468 	case GL_STENCIL_VALUE_MASK:
   2469 	case GL_STENCIL_REF:
   2470 	case GL_STENCIL_FAIL:
   2471 	case GL_STENCIL_PASS_DEPTH_FAIL:
   2472 	case GL_STENCIL_PASS_DEPTH_PASS:
   2473 	case GL_STENCIL_BACK_FUNC:
   2474 	case GL_STENCIL_BACK_VALUE_MASK:
   2475 	case GL_STENCIL_BACK_REF:
   2476 	case GL_STENCIL_BACK_FAIL:
   2477 	case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
   2478 	case GL_STENCIL_BACK_PASS_DEPTH_PASS:
   2479 	case GL_DEPTH_FUNC:
   2480 	case GL_BLEND_SRC_RGB:
   2481 	case GL_BLEND_SRC_ALPHA:
   2482 	case GL_BLEND_DST_RGB:
   2483 	case GL_BLEND_DST_ALPHA:
   2484 	case GL_BLEND_EQUATION_RGB:
   2485 	case GL_BLEND_EQUATION_ALPHA:
   2486 	case GL_STENCIL_WRITEMASK:
   2487 	case GL_STENCIL_BACK_WRITEMASK:
   2488 	case GL_STENCIL_CLEAR_VALUE:
   2489 	case GL_SUBPIXEL_BITS:
   2490 	case GL_MAX_TEXTURE_SIZE:
   2491 	case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
   2492 	case GL_SAMPLE_BUFFERS:
   2493 	case GL_SAMPLES:
   2494 	case GL_IMPLEMENTATION_COLOR_READ_TYPE:
   2495 	case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
   2496 	case GL_TEXTURE_BINDING_2D:
   2497 	case GL_TEXTURE_BINDING_CUBE_MAP:
   2498 	case GL_TEXTURE_BINDING_EXTERNAL_OES:
   2499 	case GL_TEXTURE_BINDING_3D_OES:
   2500 	case GL_COPY_READ_BUFFER_BINDING:
   2501 	case GL_COPY_WRITE_BUFFER_BINDING:
   2502 	case GL_DRAW_BUFFER0:
   2503 	case GL_DRAW_BUFFER1:
   2504 	case GL_DRAW_BUFFER2:
   2505 	case GL_DRAW_BUFFER3:
   2506 	case GL_DRAW_BUFFER4:
   2507 	case GL_DRAW_BUFFER5:
   2508 	case GL_DRAW_BUFFER6:
   2509 	case GL_DRAW_BUFFER7:
   2510 	case GL_DRAW_BUFFER8:
   2511 	case GL_DRAW_BUFFER9:
   2512 	case GL_DRAW_BUFFER10:
   2513 	case GL_DRAW_BUFFER11:
   2514 	case GL_DRAW_BUFFER12:
   2515 	case GL_DRAW_BUFFER13:
   2516 	case GL_DRAW_BUFFER14:
   2517 	case GL_DRAW_BUFFER15:
   2518 	case GL_MAJOR_VERSION:
   2519 	case GL_MAX_3D_TEXTURE_SIZE:
   2520 	case GL_MAX_ARRAY_TEXTURE_LAYERS:
   2521 	case GL_MAX_COLOR_ATTACHMENTS:
   2522 	case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
   2523 	case GL_MAX_COMBINED_UNIFORM_BLOCKS:
   2524 	case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
   2525 	case GL_MAX_DRAW_BUFFERS:
   2526 	case GL_MAX_ELEMENT_INDEX:
   2527 	case GL_MAX_ELEMENTS_INDICES:
   2528 	case GL_MAX_ELEMENTS_VERTICES:
   2529 	case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
   2530 	case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
   2531 	case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
   2532 	case GL_MAX_PROGRAM_TEXEL_OFFSET:
   2533 	case GL_MAX_SERVER_WAIT_TIMEOUT:
   2534 	case GL_MAX_TEXTURE_LOD_BIAS:
   2535 	case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
   2536 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
   2537 	case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
   2538 	case GL_MAX_UNIFORM_BLOCK_SIZE:
   2539 	case GL_MAX_UNIFORM_BUFFER_BINDINGS:
   2540 	case GL_MAX_VARYING_COMPONENTS:
   2541 	case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
   2542 	case GL_MAX_VERTEX_UNIFORM_BLOCKS:
   2543 	case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
   2544 	case GL_MIN_PROGRAM_TEXEL_OFFSET:
   2545 	case GL_MINOR_VERSION:
   2546 	case GL_NUM_EXTENSIONS:
   2547 	case GL_NUM_PROGRAM_BINARY_FORMATS:
   2548 	case GL_PACK_ROW_LENGTH:
   2549 	case GL_PACK_SKIP_PIXELS:
   2550 	case GL_PACK_SKIP_ROWS:
   2551 	case GL_PIXEL_PACK_BUFFER_BINDING:
   2552 	case GL_PIXEL_UNPACK_BUFFER_BINDING:
   2553 	case GL_PROGRAM_BINARY_FORMATS:
   2554 	case GL_READ_BUFFER:
   2555 	case GL_SAMPLER_BINDING:
   2556 	case GL_TEXTURE_BINDING_2D_ARRAY:
   2557 	case GL_UNIFORM_BUFFER_BINDING:
   2558 	case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
   2559 	case GL_UNIFORM_BUFFER_SIZE:
   2560 	case GL_UNIFORM_BUFFER_START:
   2561 	case GL_UNPACK_IMAGE_HEIGHT:
   2562 	case GL_UNPACK_ROW_LENGTH:
   2563 	case GL_UNPACK_SKIP_IMAGES:
   2564 	case GL_UNPACK_SKIP_PIXELS:
   2565 	case GL_UNPACK_SKIP_ROWS:
   2566 	case GL_VERTEX_ARRAY_BINDING:
   2567 	case GL_TRANSFORM_FEEDBACK_BINDING:
   2568 	case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
   2569 		{
   2570 			*type = GL_INT;
   2571 			*numParams = 1;
   2572 		}
   2573 		break;
   2574 	case GL_MAX_SAMPLES_ANGLE:
   2575 		{
   2576 			*type = GL_INT;
   2577 			*numParams = 1;
   2578 		}
   2579 		break;
   2580 	case GL_MAX_VIEWPORT_DIMS:
   2581 		{
   2582 			*type = GL_INT;
   2583 			*numParams = 2;
   2584 		}
   2585 		break;
   2586 	case GL_VIEWPORT:
   2587 	case GL_SCISSOR_BOX:
   2588 		{
   2589 			*type = GL_INT;
   2590 			*numParams = 4;
   2591 		}
   2592 		break;
   2593 	case GL_SHADER_COMPILER:
   2594 	case GL_SAMPLE_COVERAGE_INVERT:
   2595 	case GL_DEPTH_WRITEMASK:
   2596 	case GL_CULL_FACE:                // CULL_FACE through DITHER are natural to IsEnabled,
   2597 	case GL_POLYGON_OFFSET_FILL:      // but can be retrieved through the Get{Type}v queries.
   2598 	case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural
   2599 	case GL_SAMPLE_COVERAGE:
   2600 	case GL_SCISSOR_TEST:
   2601 	case GL_STENCIL_TEST:
   2602 	case GL_DEPTH_TEST:
   2603 	case GL_BLEND:
   2604 	case GL_DITHER:
   2605 	case GL_PRIMITIVE_RESTART_FIXED_INDEX:
   2606 	case GL_RASTERIZER_DISCARD:
   2607 	case GL_TRANSFORM_FEEDBACK_ACTIVE:
   2608 	case GL_TRANSFORM_FEEDBACK_PAUSED:
   2609 		{
   2610 			*type = GL_BOOL;
   2611 			*numParams = 1;
   2612 		}
   2613 		break;
   2614 	case GL_COLOR_WRITEMASK:
   2615 		{
   2616 			*type = GL_BOOL;
   2617 			*numParams = 4;
   2618 		}
   2619 		break;
   2620 	case GL_POLYGON_OFFSET_FACTOR:
   2621 	case GL_POLYGON_OFFSET_UNITS:
   2622 	case GL_SAMPLE_COVERAGE_VALUE:
   2623 	case GL_DEPTH_CLEAR_VALUE:
   2624 	case GL_LINE_WIDTH:
   2625 		{
   2626 			*type = GL_FLOAT;
   2627 			*numParams = 1;
   2628 		}
   2629 		break;
   2630 	case GL_ALIASED_LINE_WIDTH_RANGE:
   2631 	case GL_ALIASED_POINT_SIZE_RANGE:
   2632 	case GL_DEPTH_RANGE:
   2633 		{
   2634 			*type = GL_FLOAT;
   2635 			*numParams = 2;
   2636 		}
   2637 		break;
   2638 	case GL_COLOR_CLEAR_VALUE:
   2639 	case GL_BLEND_COLOR:
   2640 		{
   2641 			*type = GL_FLOAT;
   2642 			*numParams = 4;
   2643 		}
   2644 		break;
   2645 	case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
   2646 		*type = GL_FLOAT;
   2647 		*numParams = 1;
   2648 		break;
   2649 	default:
   2650 		return false;
   2651 	}
   2652 
   2653 	return true;
   2654 }
   2655 
   2656 void Context::applyScissor(int width, int height)
   2657 {
   2658 	if(mState.scissorTestEnabled)
   2659 	{
   2660 		sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight };
   2661 		scissor.clip(0, 0, width, height);
   2662 
   2663 		device->setScissorRect(scissor);
   2664 		device->setScissorEnable(true);
   2665 	}
   2666 	else
   2667 	{
   2668 		device->setScissorEnable(false);
   2669 	}
   2670 }
   2671 
   2672 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle
   2673 bool Context::applyRenderTarget()
   2674 {
   2675 	Framebuffer *framebuffer = getDrawFramebuffer();
   2676 	int width, height, samples;
   2677 
   2678 	if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE)
   2679 	{
   2680 		return error(GL_INVALID_FRAMEBUFFER_OPERATION, false);
   2681 	}
   2682 
   2683 	for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
   2684 	{
   2685 		if(framebuffer->getDrawBuffer(i) != GL_NONE)
   2686 		{
   2687 			egl::Image *renderTarget = framebuffer->getRenderTarget(i);
   2688 			device->setRenderTarget(i, renderTarget);
   2689 			if(renderTarget) renderTarget->release();
   2690 		}
   2691 		else
   2692 		{
   2693 			device->setRenderTarget(i, nullptr);
   2694 		}
   2695 	}
   2696 
   2697 	egl::Image *depthBuffer = framebuffer->getDepthBuffer();
   2698 	device->setDepthBuffer(depthBuffer);
   2699 	if(depthBuffer) depthBuffer->release();
   2700 
   2701 	egl::Image *stencilBuffer = framebuffer->getStencilBuffer();
   2702 	device->setStencilBuffer(stencilBuffer);
   2703 	if(stencilBuffer) stencilBuffer->release();
   2704 
   2705 	Viewport viewport;
   2706 	float zNear = clamp01(mState.zNear);
   2707 	float zFar = clamp01(mState.zFar);
   2708 
   2709 	viewport.x0 = mState.viewportX;
   2710 	viewport.y0 = mState.viewportY;
   2711 	viewport.width = mState.viewportWidth;
   2712 	viewport.height = mState.viewportHeight;
   2713 	viewport.minZ = zNear;
   2714 	viewport.maxZ = zFar;
   2715 
   2716 	device->setViewport(viewport);
   2717 
   2718 	applyScissor(width, height);
   2719 
   2720 	Program *program = getCurrentProgram();
   2721 
   2722 	if(program)
   2723 	{
   2724 		GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear};
   2725 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]);
   2726 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]);
   2727 		program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]);
   2728 	}
   2729 
   2730 	return true;
   2731 }
   2732 
   2733 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc)
   2734 void Context::applyState(GLenum drawMode)
   2735 {
   2736 	Framebuffer *framebuffer = getDrawFramebuffer();
   2737 
   2738 	if(mState.cullFaceEnabled)
   2739 	{
   2740 		device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace));
   2741 	}
   2742 	else
   2743 	{
   2744 		device->setCullMode(sw::CULL_NONE);
   2745 	}
   2746 
   2747 	if(mDepthStateDirty)
   2748 	{
   2749 		if(mState.depthTestEnabled)
   2750 		{
   2751 			device->setDepthBufferEnable(true);
   2752 			device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc));
   2753 		}
   2754 		else
   2755 		{
   2756 			device->setDepthBufferEnable(false);
   2757 		}
   2758 
   2759 		mDepthStateDirty = false;
   2760 	}
   2761 
   2762 	if(mBlendStateDirty)
   2763 	{
   2764 		if(mState.blendEnabled)
   2765 		{
   2766 			device->setAlphaBlendEnable(true);
   2767 			device->setSeparateAlphaBlendEnable(true);
   2768 
   2769 			device->setBlendConstant(es2sw::ConvertColor(mState.blendColor));
   2770 
   2771 			device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB));
   2772 			device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB));
   2773 			device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB));
   2774 
   2775 			device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha));
   2776 			device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha));
   2777 			device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha));
   2778 		}
   2779 		else
   2780 		{
   2781 			device->setAlphaBlendEnable(false);
   2782 		}
   2783 
   2784 		mBlendStateDirty = false;
   2785 	}
   2786 
   2787 	if(mStencilStateDirty || mFrontFaceDirty)
   2788 	{
   2789 		if(mState.stencilTestEnabled && framebuffer->hasStencil())
   2790 		{
   2791 			device->setStencilEnable(true);
   2792 			device->setTwoSidedStencil(true);
   2793 
   2794 			// get the maximum size of the stencil ref
   2795 			Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer();
   2796 			GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
   2797 
   2798 			if(mState.frontFace == GL_CCW)
   2799 			{
   2800 				device->setStencilWriteMask(mState.stencilWritemask);
   2801 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc));
   2802 
   2803 				device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
   2804 				device->setStencilMask(mState.stencilMask);
   2805 
   2806 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail));
   2807 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
   2808 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
   2809 
   2810 				device->setStencilWriteMaskCCW(mState.stencilBackWritemask);
   2811 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
   2812 
   2813 				device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
   2814 				device->setStencilMaskCCW(mState.stencilBackMask);
   2815 
   2816 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail));
   2817 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
   2818 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
   2819 			}
   2820 			else
   2821 			{
   2822 				device->setStencilWriteMaskCCW(mState.stencilWritemask);
   2823 				device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc));
   2824 
   2825 				device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil);
   2826 				device->setStencilMaskCCW(mState.stencilMask);
   2827 
   2828 				device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail));
   2829 				device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail));
   2830 				device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass));
   2831 
   2832 				device->setStencilWriteMask(mState.stencilBackWritemask);
   2833 				device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc));
   2834 
   2835 				device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil);
   2836 				device->setStencilMask(mState.stencilBackMask);
   2837 
   2838 				device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail));
   2839 				device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail));
   2840 				device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass));
   2841 			}
   2842 		}
   2843 		else
   2844 		{
   2845 			device->setStencilEnable(false);
   2846 		}
   2847 
   2848 		mStencilStateDirty = false;
   2849 		mFrontFaceDirty = false;
   2850 	}
   2851 
   2852 	if(mMaskStateDirty)
   2853 	{
   2854 		for(int i = 0; i < MAX_DRAW_BUFFERS; i++)
   2855 		{
   2856 			device->setColorWriteMask(i, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha));
   2857 		}
   2858 
   2859 		device->setDepthWriteEnable(mState.depthMask);
   2860 
   2861 		mMaskStateDirty = false;
   2862 	}
   2863 
   2864 	if(mPolygonOffsetStateDirty)
   2865 	{
   2866 		if(mState.polygonOffsetFillEnabled)
   2867 		{
   2868 			Renderbuffer *depthbuffer = framebuffer->getDepthbuffer();
   2869 			if(depthbuffer)
   2870 			{
   2871 				device->setSlopeDepthBias(mState.polygonOffsetFactor);
   2872 				float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize()));
   2873 				device->setDepthBias(depthBias);
   2874 			}
   2875 		}
   2876 		else
   2877 		{
   2878 			device->setSlopeDepthBias(0);
   2879 			device->setDepthBias(0);
   2880 		}
   2881 
   2882 		mPolygonOffsetStateDirty = false;
   2883 	}
   2884 
   2885 	if(mSampleStateDirty)
   2886 	{
   2887 		if(mState.sampleAlphaToCoverageEnabled)
   2888 		{
   2889 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE);
   2890 		}
   2891 		else
   2892 		{
   2893 			device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE);
   2894 		}
   2895 
   2896 		if(mState.sampleCoverageEnabled)
   2897 		{
   2898 			unsigned int mask = 0;
   2899 			if(mState.sampleCoverageValue != 0)
   2900 			{
   2901 				int width, height, samples;
   2902 				framebuffer->completeness(width, height, samples);
   2903 
   2904 				float threshold = 0.5f;
   2905 
   2906 				for(int i = 0; i < samples; i++)
   2907 				{
   2908 					mask <<= 1;
   2909 
   2910 					if((i + 1) * mState.sampleCoverageValue >= threshold)
   2911 					{
   2912 						threshold += 1.0f;
   2913 						mask |= 1;
   2914 					}
   2915 				}
   2916 			}
   2917 
   2918 			if(mState.sampleCoverageInvert)
   2919 			{
   2920 				mask = ~mask;
   2921 			}
   2922 
   2923 			device->setMultiSampleMask(mask);
   2924 		}
   2925 		else
   2926 		{
   2927 			device->setMultiSampleMask(0xFFFFFFFF);
   2928 		}
   2929 
   2930 		mSampleStateDirty = false;
   2931 	}
   2932 
   2933 	if(mDitherStateDirty)
   2934 	{
   2935 	//	UNIMPLEMENTED();   // FIXME
   2936 
   2937 		mDitherStateDirty = false;
   2938 	}
   2939 
   2940 	device->setRasterizerDiscard(mState.rasterizerDiscardEnabled);
   2941 }
   2942 
   2943 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId)
   2944 {
   2945 	TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS];
   2946 
   2947 	GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId);
   2948 	if(err != GL_NO_ERROR)
   2949 	{
   2950 		return err;
   2951 	}
   2952 
   2953 	Program *program = getCurrentProgram();
   2954 
   2955 	device->resetInputStreams(false);
   2956 
   2957 	for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
   2958 	{
   2959 		if(program->getAttributeStream(i) == -1)
   2960 		{
   2961 			continue;
   2962 		}
   2963 
   2964 		sw::Resource *resource = attributes[i].vertexBuffer;
   2965 		const void *buffer = (char*)resource->data() + attributes[i].offset;
   2966 
   2967 		int stride = attributes[i].stride;
   2968 
   2969 		buffer = (char*)buffer + stride * base;
   2970 
   2971 		sw::Stream attribute(resource, buffer, stride);
   2972 
   2973 		attribute.type = attributes[i].type;
   2974 		attribute.count = attributes[i].count;
   2975 		attribute.normalized = attributes[i].normalized;
   2976 
   2977 		int stream = program->getAttributeStream(i);
   2978 		device->setInputStream(stream, attribute);
   2979 	}
   2980 
   2981 	return GL_NO_ERROR;
   2982 }
   2983 
   2984 // Applies the indices and element array bindings
   2985 GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
   2986 {
   2987 	GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo);
   2988 
   2989 	if(err == GL_NO_ERROR)
   2990 	{
   2991 		device->setIndexBuffer(indexInfo->indexBuffer);
   2992 	}
   2993 
   2994 	return err;
   2995 }
   2996 
   2997 // Applies the shaders and shader constants
   2998 void Context::applyShaders()
   2999 {
   3000 	Program *programObject = getCurrentProgram();
   3001 	sw::VertexShader *vertexShader = programObject->getVertexShader();
   3002 	sw::PixelShader *pixelShader = programObject->getPixelShader();
   3003 
   3004 	device->setVertexShader(vertexShader);
   3005 	device->setPixelShader(pixelShader);
   3006 
   3007 	if(programObject->getSerial() != mAppliedProgramSerial)
   3008 	{
   3009 		programObject->dirtyAllUniforms();
   3010 		mAppliedProgramSerial = programObject->getSerial();
   3011 	}
   3012 
   3013 	programObject->applyTransformFeedback(getTransformFeedback());
   3014 	programObject->applyUniformBuffers(mState.uniformBuffers);
   3015 	programObject->applyUniforms();
   3016 }
   3017 
   3018 void Context::applyTextures()
   3019 {
   3020 	applyTextures(sw::SAMPLER_PIXEL);
   3021 	applyTextures(sw::SAMPLER_VERTEX);
   3022 }
   3023 
   3024 void Context::applyTextures(sw::SamplerType samplerType)
   3025 {
   3026 	Program *programObject = getCurrentProgram();
   3027 
   3028 	int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;   // Range of samplers of given sampler type
   3029 
   3030 	for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++)
   3031 	{
   3032 		int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex);   // OpenGL texture image unit index
   3033 
   3034 		if(textureUnit != -1)
   3035 		{
   3036 			TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex);
   3037 
   3038 			Texture *texture = getSamplerTexture(textureUnit, textureType);
   3039 
   3040 			if(texture->isSamplerComplete())
   3041 			{
   3042 				GLenum wrapS, wrapT, wrapR, minFilter, magFilter;
   3043 
   3044 				Sampler *samplerObject = mState.sampler[textureUnit];
   3045 				if(samplerObject)
   3046 				{
   3047 					wrapS = samplerObject->getWrapS();
   3048 					wrapT = samplerObject->getWrapT();
   3049 					wrapR = samplerObject->getWrapR();
   3050 					minFilter = samplerObject->getMinFilter();
   3051 					magFilter = samplerObject->getMagFilter();
   3052 				}
   3053 				else
   3054 				{
   3055 					wrapS = texture->getWrapS();
   3056 					wrapT = texture->getWrapT();
   3057 					wrapR = texture->getWrapR();
   3058 					minFilter = texture->getMinFilter();
   3059 					magFilter = texture->getMagFilter();
   3060 				}
   3061 				GLfloat maxAnisotropy = texture->getMaxAnisotropy();
   3062 
   3063 				GLenum swizzleR = texture->getSwizzleR();
   3064 				GLenum swizzleG = texture->getSwizzleG();
   3065 				GLenum swizzleB = texture->getSwizzleB();
   3066 				GLenum swizzleA = texture->getSwizzleA();
   3067 
   3068 				device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS));
   3069 				device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT));
   3070 				device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR));
   3071 				device->setSwizzleR(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleR));
   3072 				device->setSwizzleG(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleG));
   3073 				device->setSwizzleB(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleB));
   3074 				device->setSwizzleA(samplerType, samplerIndex, es2sw::ConvertSwizzleType(swizzleA));
   3075 
   3076 				device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy));
   3077 				device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter));
   3078 				device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy);
   3079 
   3080 				applyTexture(samplerType, samplerIndex, texture);
   3081 			}
   3082 			else
   3083 			{
   3084 				applyTexture(samplerType, samplerIndex, nullptr);
   3085 			}
   3086 		}
   3087 		else
   3088 		{
   3089 			applyTexture(samplerType, samplerIndex, nullptr);
   3090 		}
   3091 	}
   3092 }
   3093 
   3094 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture)
   3095 {
   3096 	Program *program = getCurrentProgram();
   3097 	int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index;
   3098 	bool textureUsed = false;
   3099 
   3100 	if(type == sw::SAMPLER_PIXEL)
   3101 	{
   3102 		textureUsed = program->getPixelShader()->usesSampler(index);
   3103 	}
   3104 	else if(type == sw::SAMPLER_VERTEX)
   3105 	{
   3106 		textureUsed = program->getVertexShader()->usesSampler(index);
   3107 	}
   3108 	else UNREACHABLE(type);
   3109 
   3110 	sw::Resource *resource = 0;
   3111 
   3112 	if(baseTexture && textureUsed)
   3113 	{
   3114 		resource = baseTexture->getResource();
   3115 	}
   3116 
   3117 	device->setTextureResource(sampler, resource);
   3118 
   3119 	if(baseTexture && textureUsed)
   3120 	{
   3121 		int levelCount = baseTexture->getLevelCount();
   3122 
   3123 		if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES)
   3124 		{
   3125 			Texture2D *texture = static_cast<Texture2D*>(baseTexture);
   3126 
   3127 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   3128 			{
   3129 				int surfaceLevel = mipmapLevel;
   3130 
   3131 				if(surfaceLevel < 0)
   3132 				{
   3133 					surfaceLevel = 0;
   3134 				}
   3135 				else if(surfaceLevel >= levelCount)
   3136 				{
   3137 					surfaceLevel = levelCount - 1;
   3138 				}
   3139 
   3140 				egl::Image *surface = texture->getImage(surfaceLevel);
   3141 				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D);
   3142 			}
   3143 		}
   3144 		else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES)
   3145 		{
   3146 			Texture3D *texture = static_cast<Texture3D*>(baseTexture);
   3147 
   3148 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   3149 			{
   3150 				int surfaceLevel = mipmapLevel;
   3151 
   3152 				if(surfaceLevel < 0)
   3153 				{
   3154 					surfaceLevel = 0;
   3155 				}
   3156 				else if(surfaceLevel >= levelCount)
   3157 				{
   3158 					surfaceLevel = levelCount - 1;
   3159 				}
   3160 
   3161 				egl::Image *surface = texture->getImage(surfaceLevel);
   3162 				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D);
   3163 			}
   3164 		}
   3165 		else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY)
   3166 		{
   3167 			Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture);
   3168 
   3169 			for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   3170 			{
   3171 				int surfaceLevel = mipmapLevel;
   3172 
   3173 				if(surfaceLevel < 0)
   3174 				{
   3175 					surfaceLevel = 0;
   3176 				}
   3177 				else if(surfaceLevel >= levelCount)
   3178 				{
   3179 					surfaceLevel = levelCount - 1;
   3180 				}
   3181 
   3182 				egl::Image *surface = texture->getImage(surfaceLevel);
   3183 				device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY);
   3184 			}
   3185 		}
   3186 		else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP)
   3187 		{
   3188 			for(int face = 0; face < 6; face++)
   3189 			{
   3190 				TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture);
   3191 
   3192 				for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++)
   3193 				{
   3194 					int surfaceLevel = mipmapLevel;
   3195 
   3196 					if(surfaceLevel < 0)
   3197 					{
   3198 						surfaceLevel = 0;
   3199 					}
   3200 					else if(surfaceLevel >= levelCount)
   3201 					{
   3202 						surfaceLevel = levelCount - 1;
   3203 					}
   3204 
   3205 					egl::Image *surface = cubeTexture->getImage(face, surfaceLevel);
   3206 					device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE);
   3207 				}
   3208 			}
   3209 		}
   3210 		else UNIMPLEMENTED();
   3211 	}
   3212 	else
   3213 	{
   3214 		device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL);
   3215 	}
   3216 }
   3217 
   3218 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels)
   3219 {
   3220 	Framebuffer *framebuffer = getReadFramebuffer();
   3221 	int framebufferWidth, framebufferHeight, framebufferSamples;
   3222 
   3223 	if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE)
   3224 	{
   3225 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
   3226 	}
   3227 
   3228 	if(getReadFramebufferName() != 0 && framebufferSamples != 0)
   3229 	{
   3230 		return error(GL_INVALID_OPERATION);
   3231 	}
   3232 
   3233 	GLenum readFormat = GL_NONE;
   3234 	GLenum readType = GL_NONE;
   3235 	switch(format)
   3236 	{
   3237 	case GL_DEPTH_COMPONENT:
   3238 		readFormat = framebuffer->getDepthReadFormat();
   3239 		readType = framebuffer->getDepthReadType();
   3240 		break;
   3241 	default:
   3242 		readFormat = framebuffer->getImplementationColorReadFormat();
   3243 		readType = framebuffer->getImplementationColorReadType();
   3244 		break;
   3245 	}
   3246 
   3247 	if(!(readFormat == format && readType == type) && !ValidReadPixelsFormatType(readFormat, readType, format, type, clientVersion))
   3248 	{
   3249 		return error(GL_INVALID_OPERATION);
   3250 	}
   3251 
   3252 	GLsizei outputWidth = (mState.packRowLength > 0) ? mState.packRowLength : width;
   3253 	GLsizei outputPitch = egl::ComputePitch(outputWidth, format, type, mState.packAlignment);
   3254 	GLsizei outputHeight = (mState.packImageHeight == 0) ? height : mState.packImageHeight;
   3255 	pixels = getPixelPackBuffer() ? (unsigned char*)getPixelPackBuffer()->data() + (ptrdiff_t)pixels : (unsigned char*)pixels;
   3256 	pixels = ((char*)pixels) + egl::ComputePackingOffset(format, type, outputWidth, outputHeight, mState.packAlignment, mState.packSkipImages, mState.packSkipRows, mState.packSkipPixels);
   3257 
   3258 	// Sized query sanity check
   3259 	if(bufSize)
   3260 	{
   3261 		int requiredSize = outputPitch * height;
   3262 		if(requiredSize > *bufSize)
   3263 		{
   3264 			return error(GL_INVALID_OPERATION);
   3265 		}
   3266 	}
   3267 
   3268 	egl::Image *renderTarget = nullptr;
   3269 	switch(format)
   3270 	{
   3271 	case GL_DEPTH_COMPONENT:
   3272 		renderTarget = framebuffer->getDepthBuffer();
   3273 		break;
   3274 	default:
   3275 		renderTarget = framebuffer->getReadRenderTarget();
   3276 		break;
   3277 	}
   3278 
   3279 	if(!renderTarget)
   3280 	{
   3281 		return error(GL_INVALID_OPERATION);
   3282 	}
   3283 
   3284 	sw::Rect rect = {x, y, x + width, y + height};
   3285 	sw::Rect dstRect = { 0, 0, width, height };
   3286 	rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight());
   3287 
   3288 	sw::Surface externalSurface(width, height, 1, egl::ConvertFormatType(format, type), pixels, outputPitch, outputPitch * outputHeight);
   3289 	sw::SliceRect sliceRect(rect);
   3290 	sw::SliceRect dstSliceRect(dstRect);
   3291 	device->blit(renderTarget, sliceRect, &externalSurface, dstSliceRect, false);
   3292 
   3293 	renderTarget->release();
   3294 }
   3295 
   3296 void Context::clear(GLbitfield mask)
   3297 {
   3298 	if(mState.rasterizerDiscardEnabled)
   3299 	{
   3300 		return;
   3301 	}
   3302 
   3303 	Framebuffer *framebuffer = getDrawFramebuffer();
   3304 
   3305 	if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
   3306 	{
   3307 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
   3308 	}
   3309 
   3310 	if(!applyRenderTarget())
   3311 	{
   3312 		return;
   3313 	}
   3314 
   3315 	if(mask & GL_COLOR_BUFFER_BIT)
   3316 	{
   3317 		unsigned int rgbaMask = getColorMask();
   3318 
   3319 		if(rgbaMask != 0)
   3320 		{
   3321 			device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask);
   3322 		}
   3323 	}
   3324 
   3325 	if(mask & GL_DEPTH_BUFFER_BIT)
   3326 	{
   3327 		if(mState.depthMask != 0)
   3328 		{
   3329 			float depth = clamp01(mState.depthClearValue);
   3330 			device->clearDepth(depth);
   3331 		}
   3332 	}
   3333 
   3334 	if(mask & GL_STENCIL_BUFFER_BIT)
   3335 	{
   3336 		if(mState.stencilWritemask != 0)
   3337 		{
   3338 			int stencil = mState.stencilClearValue & 0x000000FF;
   3339 			device->clearStencil(stencil, mState.stencilWritemask);
   3340 		}
   3341 	}
   3342 }
   3343 
   3344 void Context::clearColorBuffer(GLint drawbuffer, void *value, sw::Format format)
   3345 {
   3346 	unsigned int rgbaMask = getColorMask();
   3347 	if(rgbaMask && !mState.rasterizerDiscardEnabled)
   3348 	{
   3349 		Framebuffer *framebuffer = getDrawFramebuffer();
   3350 		egl::Image *colorbuffer = framebuffer->getRenderTarget(drawbuffer);
   3351 
   3352 		if(colorbuffer)
   3353 		{
   3354 			sw::SliceRect clearRect = colorbuffer->getRect();
   3355 
   3356 			if(mState.scissorTestEnabled)
   3357 			{
   3358 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
   3359 			}
   3360 
   3361 			device->clear(value, format, colorbuffer, clearRect, rgbaMask);
   3362 
   3363 			colorbuffer->release();
   3364 		}
   3365 	}
   3366 }
   3367 
   3368 void Context::clearColorBuffer(GLint drawbuffer, const GLint *value)
   3369 {
   3370 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32I);
   3371 }
   3372 
   3373 void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value)
   3374 {
   3375 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32UI);
   3376 }
   3377 
   3378 void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value)
   3379 {
   3380 	clearColorBuffer(drawbuffer, (void*)value, sw::FORMAT_A32B32G32R32F);
   3381 }
   3382 
   3383 void Context::clearDepthBuffer(const GLfloat value)
   3384 {
   3385 	if(mState.depthMask && !mState.rasterizerDiscardEnabled)
   3386 	{
   3387 		Framebuffer *framebuffer = getDrawFramebuffer();
   3388 		egl::Image *depthbuffer = framebuffer->getDepthBuffer();
   3389 
   3390 		if(depthbuffer)
   3391 		{
   3392 			float depth = clamp01(value);
   3393 			sw::SliceRect clearRect = depthbuffer->getRect();
   3394 
   3395 			if(mState.scissorTestEnabled)
   3396 			{
   3397 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
   3398 			}
   3399 
   3400 			depthbuffer->clearDepth(depth, clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
   3401 
   3402 			depthbuffer->release();
   3403 		}
   3404 	}
   3405 }
   3406 
   3407 void Context::clearStencilBuffer(const GLint value)
   3408 {
   3409 	if(mState.stencilWritemask && !mState.rasterizerDiscardEnabled)
   3410 	{
   3411 		Framebuffer *framebuffer = getDrawFramebuffer();
   3412 		egl::Image *stencilbuffer = framebuffer->getStencilBuffer();
   3413 
   3414 		if(stencilbuffer)
   3415 		{
   3416 			unsigned char stencil = value < 0 ? 0 : static_cast<unsigned char>(value & 0x000000FF);
   3417 			sw::SliceRect clearRect = stencilbuffer->getRect();
   3418 
   3419 			if(mState.scissorTestEnabled)
   3420 			{
   3421 				clearRect.clip(mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight);
   3422 			}
   3423 
   3424 			stencilbuffer->clearStencil(stencil, static_cast<unsigned char>(mState.stencilWritemask), clearRect.x0, clearRect.y0, clearRect.width(), clearRect.height());
   3425 
   3426 			stencilbuffer->release();
   3427 		}
   3428 	}
   3429 }
   3430 
   3431 void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)
   3432 {
   3433 	if(!mState.currentProgram)
   3434 	{
   3435 		return error(GL_INVALID_OPERATION);
   3436 	}
   3437 
   3438 	sw::DrawType primitiveType;
   3439 	int primitiveCount;
   3440 	int verticesPerPrimitive;
   3441 
   3442 	if(!es2sw::ConvertPrimitiveType(mode, count, GL_NONE, primitiveType, primitiveCount, verticesPerPrimitive))
   3443 		return error(GL_INVALID_ENUM);
   3444 
   3445 	if(primitiveCount <= 0)
   3446 	{
   3447 		return;
   3448 	}
   3449 
   3450 	if(!applyRenderTarget())
   3451 	{
   3452 		return;
   3453 	}
   3454 
   3455 	applyState(mode);
   3456 
   3457 	for(int i = 0; i < instanceCount; ++i)
   3458 	{
   3459 		device->setInstanceID(i);
   3460 
   3461 		GLenum err = applyVertexBuffer(0, first, count, i);
   3462 		if(err != GL_NO_ERROR)
   3463 		{
   3464 			return error(err);
   3465 		}
   3466 
   3467 		applyShaders();
   3468 		applyTextures();
   3469 
   3470 		if(!getCurrentProgram()->validateSamplers(false))
   3471 		{
   3472 			return error(GL_INVALID_OPERATION);
   3473 		}
   3474 
   3475 		TransformFeedback* transformFeedback = getTransformFeedback();
   3476 		if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
   3477 		{
   3478 			device->drawPrimitive(primitiveType, primitiveCount);
   3479 		}
   3480 		if(transformFeedback)
   3481 		{
   3482 			transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
   3483 		}
   3484 	}
   3485 }
   3486 
   3487 void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)
   3488 {
   3489 	if(!mState.currentProgram)
   3490 	{
   3491 		return error(GL_INVALID_OPERATION);
   3492 	}
   3493 
   3494 	if(!indices && !getCurrentVertexArray()->getElementArrayBuffer())
   3495 	{
   3496 		return error(GL_INVALID_OPERATION);
   3497 	}
   3498 
   3499 	sw::DrawType primitiveType;
   3500 	int primitiveCount;
   3501 	int verticesPerPrimitive;
   3502 
   3503 	if(!es2sw::ConvertPrimitiveType(mode, count, type, primitiveType, primitiveCount, verticesPerPrimitive))
   3504 		return error(GL_INVALID_ENUM);
   3505 
   3506 	if(primitiveCount <= 0)
   3507 	{
   3508 		return;
   3509 	}
   3510 
   3511 	if(!applyRenderTarget())
   3512 	{
   3513 		return;
   3514 	}
   3515 
   3516 	applyState(mode);
   3517 
   3518 	for(int i = 0; i < instanceCount; ++i)
   3519 	{
   3520 		device->setInstanceID(i);
   3521 
   3522 		TranslatedIndexData indexInfo;
   3523 		GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo);
   3524 		if(err != GL_NO_ERROR)
   3525 		{
   3526 			return error(err);
   3527 		}
   3528 
   3529 		GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1;
   3530 		err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i);
   3531 		if(err != GL_NO_ERROR)
   3532 		{
   3533 			return error(err);
   3534 		}
   3535 
   3536 		applyShaders();
   3537 		applyTextures();
   3538 
   3539 		if(!getCurrentProgram()->validateSamplers(false))
   3540 		{
   3541 			return error(GL_INVALID_OPERATION);
   3542 		}
   3543 
   3544 		TransformFeedback* transformFeedback = getTransformFeedback();
   3545 		if(!cullSkipsDraw(mode) || (transformFeedback->isActive() && !transformFeedback->isPaused()))
   3546 		{
   3547 			device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount);
   3548 		}
   3549 		if(transformFeedback)
   3550 		{
   3551 			transformFeedback->addVertexOffset(primitiveCount * verticesPerPrimitive);
   3552 		}
   3553 	}
   3554 }
   3555 
   3556 void Context::finish()
   3557 {
   3558 	device->finish();
   3559 }
   3560 
   3561 void Context::flush()
   3562 {
   3563 	// We don't queue anything without processing it as fast as possible
   3564 }
   3565 
   3566 void Context::recordInvalidEnum()
   3567 {
   3568 	mInvalidEnum = true;
   3569 }
   3570 
   3571 void Context::recordInvalidValue()
   3572 {
   3573 	mInvalidValue = true;
   3574 }
   3575 
   3576 void Context::recordInvalidOperation()
   3577 {
   3578 	mInvalidOperation = true;
   3579 }
   3580 
   3581 void Context::recordOutOfMemory()
   3582 {
   3583 	mOutOfMemory = true;
   3584 }
   3585 
   3586 void Context::recordInvalidFramebufferOperation()
   3587 {
   3588 	mInvalidFramebufferOperation = true;
   3589 }
   3590 
   3591 // Get one of the recorded errors and clear its flag, if any.
   3592 // [OpenGL ES 2.0.24] section 2.5 page 13.
   3593 GLenum Context::getError()
   3594 {
   3595 	if(mInvalidEnum)
   3596 	{
   3597 		mInvalidEnum = false;
   3598 
   3599 		return GL_INVALID_ENUM;
   3600 	}
   3601 
   3602 	if(mInvalidValue)
   3603 	{
   3604 		mInvalidValue = false;
   3605 
   3606 		return GL_INVALID_VALUE;
   3607 	}
   3608 
   3609 	if(mInvalidOperation)
   3610 	{
   3611 		mInvalidOperation = false;
   3612 
   3613 		return GL_INVALID_OPERATION;
   3614 	}
   3615 
   3616 	if(mOutOfMemory)
   3617 	{
   3618 		mOutOfMemory = false;
   3619 
   3620 		return GL_OUT_OF_MEMORY;
   3621 	}
   3622 
   3623 	if(mInvalidFramebufferOperation)
   3624 	{
   3625 		mInvalidFramebufferOperation = false;
   3626 
   3627 		return GL_INVALID_FRAMEBUFFER_OPERATION;
   3628 	}
   3629 
   3630 	return GL_NO_ERROR;
   3631 }
   3632 
   3633 int Context::getSupportedMultisampleCount(int requested)
   3634 {
   3635 	int supported = 0;
   3636 
   3637 	for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--)
   3638 	{
   3639 		if(supported >= requested)
   3640 		{
   3641 			return supported;
   3642 		}
   3643 
   3644 		supported = multisampleCount[i];
   3645 	}
   3646 
   3647 	return supported;
   3648 }
   3649 
   3650 void Context::detachBuffer(GLuint buffer)
   3651 {
   3652 	// [OpenGL ES 2.0.24] section 2.9 page 22:
   3653 	// If a buffer object is deleted while it is bound, all bindings to that object in the current context
   3654 	// (i.e. in the thread that called Delete-Buffers) are reset to zero.
   3655 
   3656 	if(mState.copyReadBuffer.name() == buffer)
   3657 	{
   3658 		mState.copyReadBuffer = nullptr;
   3659 	}
   3660 
   3661 	if(mState.copyWriteBuffer.name() == buffer)
   3662 	{
   3663 		mState.copyWriteBuffer = nullptr;
   3664 	}
   3665 
   3666 	if(mState.pixelPackBuffer.name() == buffer)
   3667 	{
   3668 		mState.pixelPackBuffer = nullptr;
   3669 	}
   3670 
   3671 	if(mState.pixelUnpackBuffer.name() == buffer)
   3672 	{
   3673 		mState.pixelUnpackBuffer = nullptr;
   3674 	}
   3675 
   3676 	if(mState.genericUniformBuffer.name() == buffer)
   3677 	{
   3678 		mState.genericUniformBuffer = nullptr;
   3679 	}
   3680 
   3681 	if(getArrayBufferName() == buffer)
   3682 	{
   3683 		mState.arrayBuffer = nullptr;
   3684 	}
   3685 
   3686 	// Only detach from the current transform feedback
   3687 	TransformFeedback* currentTransformFeedback = getTransformFeedback();
   3688 	if(currentTransformFeedback)
   3689 	{
   3690 		currentTransformFeedback->detachBuffer(buffer);
   3691 	}
   3692 
   3693 	// Only detach from the current vertex array
   3694 	VertexArray* currentVertexArray = getCurrentVertexArray();
   3695 	if(currentVertexArray)
   3696 	{
   3697 		currentVertexArray->detachBuffer(buffer);
   3698 	}
   3699 
   3700 	for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
   3701 	{
   3702 		if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer)
   3703 		{
   3704 			mState.vertexAttribute[attribute].mBoundBuffer = nullptr;
   3705 		}
   3706 	}
   3707 }
   3708 
   3709 void Context::detachTexture(GLuint texture)
   3710 {
   3711 	// [OpenGL ES 2.0.24] section 3.8 page 84:
   3712 	// If a texture object is deleted, it is as if all texture units which are bound to that texture object are
   3713 	// rebound to texture object zero
   3714 
   3715 	for(int type = 0; type < TEXTURE_TYPE_COUNT; type++)
   3716 	{
   3717 		for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++)
   3718 		{
   3719 			if(mState.samplerTexture[type][sampler].name() == texture)
   3720 			{
   3721 				mState.samplerTexture[type][sampler] = nullptr;
   3722 			}
   3723 		}
   3724 	}
   3725 
   3726 	// [OpenGL ES 2.0.24] section 4.4 page 112:
   3727 	// If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is
   3728 	// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
   3729 	// image was attached in the currently bound framebuffer.
   3730 
   3731 	Framebuffer *readFramebuffer = getReadFramebuffer();
   3732 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3733 
   3734 	if(readFramebuffer)
   3735 	{
   3736 		readFramebuffer->detachTexture(texture);
   3737 	}
   3738 
   3739 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
   3740 	{
   3741 		drawFramebuffer->detachTexture(texture);
   3742 	}
   3743 }
   3744 
   3745 void Context::detachFramebuffer(GLuint framebuffer)
   3746 {
   3747 	// [OpenGL ES 2.0.24] section 4.4 page 107:
   3748 	// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
   3749 	// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
   3750 
   3751 	if(mState.readFramebuffer == framebuffer)
   3752 	{
   3753 		bindReadFramebuffer(0);
   3754 	}
   3755 
   3756 	if(mState.drawFramebuffer == framebuffer)
   3757 	{
   3758 		bindDrawFramebuffer(0);
   3759 	}
   3760 }
   3761 
   3762 void Context::detachRenderbuffer(GLuint renderbuffer)
   3763 {
   3764 	// [OpenGL ES 2.0.24] section 4.4 page 109:
   3765 	// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
   3766 	// had been executed with the target RENDERBUFFER and name of zero.
   3767 
   3768 	if(mState.renderbuffer.name() == renderbuffer)
   3769 	{
   3770 		bindRenderbuffer(0);
   3771 	}
   3772 
   3773 	// [OpenGL ES 2.0.24] section 4.4 page 111:
   3774 	// If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer,
   3775 	// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
   3776 	// point to which this image was attached in the currently bound framebuffer.
   3777 
   3778 	Framebuffer *readFramebuffer = getReadFramebuffer();
   3779 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3780 
   3781 	if(readFramebuffer)
   3782 	{
   3783 		readFramebuffer->detachRenderbuffer(renderbuffer);
   3784 	}
   3785 
   3786 	if(drawFramebuffer && drawFramebuffer != readFramebuffer)
   3787 	{
   3788 		drawFramebuffer->detachRenderbuffer(renderbuffer);
   3789 	}
   3790 }
   3791 
   3792 void Context::detachSampler(GLuint sampler)
   3793 {
   3794 	// [OpenGL ES 3.0.2] section 3.8.2 pages 123-124:
   3795 	// If a sampler object that is currently bound to one or more texture units is
   3796 	// deleted, it is as though BindSampler is called once for each texture unit to
   3797 	// which the sampler is bound, with unit set to the texture unit and sampler set to zero.
   3798 	for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit)
   3799 	{
   3800 		gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit];
   3801 		if(samplerBinding.name() == sampler)
   3802 		{
   3803 			samplerBinding = nullptr;
   3804 		}
   3805 	}
   3806 }
   3807 
   3808 bool Context::cullSkipsDraw(GLenum drawMode)
   3809 {
   3810 	return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode);
   3811 }
   3812 
   3813 bool Context::isTriangleMode(GLenum drawMode)
   3814 {
   3815 	switch(drawMode)
   3816 	{
   3817 	case GL_TRIANGLES:
   3818 	case GL_TRIANGLE_FAN:
   3819 	case GL_TRIANGLE_STRIP:
   3820 		return true;
   3821 	case GL_POINTS:
   3822 	case GL_LINES:
   3823 	case GL_LINE_LOOP:
   3824 	case GL_LINE_STRIP:
   3825 		return false;
   3826 	default: UNREACHABLE(drawMode);
   3827 	}
   3828 
   3829 	return false;
   3830 }
   3831 
   3832 void Context::setVertexAttrib(GLuint index, const GLfloat *values)
   3833 {
   3834 	ASSERT(index < MAX_VERTEX_ATTRIBS);
   3835 
   3836 	mState.vertexAttribute[index].setCurrentValue(values);
   3837 
   3838 	mVertexDataManager->dirtyCurrentValue(index);
   3839 }
   3840 
   3841 void Context::setVertexAttrib(GLuint index, const GLint *values)
   3842 {
   3843 	ASSERT(index < MAX_VERTEX_ATTRIBS);
   3844 
   3845 	mState.vertexAttribute[index].setCurrentValue(values);
   3846 
   3847 	mVertexDataManager->dirtyCurrentValue(index);
   3848 }
   3849 
   3850 void Context::setVertexAttrib(GLuint index, const GLuint *values)
   3851 {
   3852 	ASSERT(index < MAX_VERTEX_ATTRIBS);
   3853 
   3854 	mState.vertexAttribute[index].setCurrentValue(values);
   3855 
   3856 	mVertexDataManager->dirtyCurrentValue(index);
   3857 }
   3858 
   3859 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
   3860                               GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
   3861                               GLbitfield mask)
   3862 {
   3863 	Framebuffer *readFramebuffer = getReadFramebuffer();
   3864 	Framebuffer *drawFramebuffer = getDrawFramebuffer();
   3865 
   3866 	int readBufferWidth, readBufferHeight, readBufferSamples;
   3867 	int drawBufferWidth, drawBufferHeight, drawBufferSamples;
   3868 
   3869 	if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE ||
   3870 	   !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE)
   3871 	{
   3872 		return error(GL_INVALID_FRAMEBUFFER_OPERATION);
   3873 	}
   3874 
   3875 	if(drawBufferSamples > 1)
   3876 	{
   3877 		return error(GL_INVALID_OPERATION);
   3878 	}
   3879 
   3880 	sw::SliceRect sourceRect;
   3881 	sw::SliceRect destRect;
   3882 	bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1);
   3883 	bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1);
   3884 
   3885 	if(srcX0 < srcX1)
   3886 	{
   3887 		sourceRect.x0 = srcX0;
   3888 		sourceRect.x1 = srcX1;
   3889 	}
   3890 	else
   3891 	{
   3892 		sourceRect.x0 = srcX1;
   3893 		sourceRect.x1 = srcX0;
   3894 	}
   3895 
   3896 	if(dstX0 < dstX1)
   3897 	{
   3898 		destRect.x0 = dstX0;
   3899 		destRect.x1 = dstX1;
   3900 	}
   3901 	else
   3902 	{
   3903 		destRect.x0 = dstX1;
   3904 		destRect.x1 = dstX0;
   3905 	}
   3906 
   3907 	if(srcY0 < srcY1)
   3908 	{
   3909 		sourceRect.y0 = srcY0;
   3910 		sourceRect.y1 = srcY1;
   3911 	}
   3912 	else
   3913 	{
   3914 		sourceRect.y0 = srcY1;
   3915 		sourceRect.y1 = srcY0;
   3916 	}
   3917 
   3918 	if(dstY0 < dstY1)
   3919 	{
   3920 		destRect.y0 = dstY0;
   3921 		destRect.y1 = dstY1;
   3922 	}
   3923 	else
   3924 	{
   3925 		destRect.y0 = dstY1;
   3926 		destRect.y1 = dstY0;
   3927 	}
   3928 
   3929 	sw::Rect sourceScissoredRect = sourceRect;
   3930 	sw::Rect destScissoredRect = destRect;
   3931 
   3932 	if(mState.scissorTestEnabled)   // Only write to parts of the destination framebuffer which pass the scissor test
   3933 	{
   3934 		if(destRect.x0 < mState.scissorX)
   3935 		{
   3936 			int xDiff = mState.scissorX - destRect.x0;
   3937 			destScissoredRect.x0 = mState.scissorX;
   3938 			sourceScissoredRect.x0 += xDiff;
   3939 		}
   3940 
   3941 		if(destRect.x1 > mState.scissorX + mState.scissorWidth)
   3942 		{
   3943 			int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth);
   3944 			destScissoredRect.x1 = mState.scissorX + mState.scissorWidth;
   3945 			sourceScissoredRect.x1 -= xDiff;
   3946 		}
   3947 
   3948 		if(destRect.y0 < mState.scissorY)
   3949 		{
   3950 			int yDiff = mState.scissorY - destRect.y0;
   3951 			destScissoredRect.y0 = mState.scissorY;
   3952 			sourceScissoredRect.y0 += yDiff;
   3953 		}
   3954 
   3955 		if(destRect.y1 > mState.scissorY + mState.scissorHeight)
   3956 		{
   3957 			int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight);
   3958 			destScissoredRect.y1 = mState.scissorY + mState.scissorHeight;
   3959 			sourceScissoredRect.y1 -= yDiff;
   3960 		}
   3961 	}
   3962 
   3963 	sw::Rect sourceTrimmedRect = sourceScissoredRect;
   3964 	sw::Rect destTrimmedRect = destScissoredRect;
   3965 
   3966 	// The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
   3967 	// the actual draw and read surfaces.
   3968 	if(sourceTrimmedRect.x0 < 0)
   3969 	{
   3970 		int xDiff = 0 - sourceTrimmedRect.x0;
   3971 		sourceTrimmedRect.x0 = 0;
   3972 		destTrimmedRect.x0 += xDiff;
   3973 	}
   3974 
   3975 	if(sourceTrimmedRect.x1 > readBufferWidth)
   3976 	{
   3977 		int xDiff = sourceTrimmedRect.x1 - readBufferWidth;
   3978 		sourceTrimmedRect.x1 = readBufferWidth;
   3979 		destTrimmedRect.x1 -= xDiff;
   3980 	}
   3981 
   3982 	if(sourceTrimmedRect.y0 < 0)
   3983 	{
   3984 		int yDiff = 0 - sourceTrimmedRect.y0;
   3985 		sourceTrimmedRect.y0 = 0;
   3986 		destTrimmedRect.y0 += yDiff;
   3987 	}
   3988 
   3989 	if(sourceTrimmedRect.y1 > readBufferHeight)
   3990 	{
   3991 		int yDiff = sourceTrimmedRect.y1 - readBufferHeight;
   3992 		sourceTrimmedRect.y1 = readBufferHeight;
   3993 		destTrimmedRect.y1 -= yDiff;
   3994 	}
   3995 
   3996 	if(destTrimmedRect.x0 < 0)
   3997 	{
   3998 		int xDiff = 0 - destTrimmedRect.x0;
   3999 		destTrimmedRect.x0 = 0;
   4000 		sourceTrimmedRect.x0 += xDiff;
   4001 	}
   4002 
   4003 	if(destTrimmedRect.x1 > drawBufferWidth)
   4004 	{
   4005 		int xDiff = destTrimmedRect.x1 - drawBufferWidth;
   4006 		destTrimmedRect.x1 = drawBufferWidth;
   4007 		sourceTrimmedRect.x1 -= xDiff;
   4008 	}
   4009 
   4010 	if(destTrimmedRect.y0 < 0)
   4011 	{
   4012 		int yDiff = 0 - destTrimmedRect.y0;
   4013 		destTrimmedRect.y0 = 0;
   4014 		sourceTrimmedRect.y0 += yDiff;
   4015 	}
   4016 
   4017 	if(destTrimmedRect.y1 > drawBufferHeight)
   4018 	{
   4019 		int yDiff = destTrimmedRect.y1 - drawBufferHeight;
   4020 		destTrimmedRect.y1 = drawBufferHeight;
   4021 		sourceTrimmedRect.y1 -= yDiff;
   4022 	}
   4023 
   4024 	bool partialBufferCopy = false;
   4025 
   4026 	if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight ||
   4027 	   sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth ||
   4028 	   destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight ||
   4029 	   destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth ||
   4030 	   sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0)
   4031 	{
   4032 		partialBufferCopy = true;
   4033 	}
   4034 
   4035 	bool blitRenderTarget = false;
   4036 	bool blitDepthStencil = false;
   4037 
   4038 	if(mask & GL_COLOR_BUFFER_BIT)
   4039 	{
   4040 		GLenum readColorbufferType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex());
   4041 		GLenum drawColorbufferType = drawFramebuffer->getColorbufferType(0);
   4042 		const bool validReadType = readColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(readColorbufferType);
   4043 		const bool validDrawType = drawColorbufferType == GL_TEXTURE_2D || Framebuffer::IsRenderbuffer(drawColorbufferType);
   4044 		if(!validReadType || !validDrawType)
   4045 		{
   4046 			return error(GL_INVALID_OPERATION);
   4047 		}
   4048 
   4049 		if(partialBufferCopy && readBufferSamples > 1)
   4050 		{
   4051 			return error(GL_INVALID_OPERATION);
   4052 		}
   4053 
   4054 		blitRenderTarget = true;
   4055 	}
   4056 
   4057 	if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
   4058 	{
   4059 		Renderbuffer *readDSBuffer = nullptr;
   4060 		Renderbuffer *drawDSBuffer = nullptr;
   4061 
   4062 		if(mask & GL_DEPTH_BUFFER_BIT)
   4063 		{
   4064 			if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
   4065 			{
   4066 				if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType())
   4067 				{
   4068 					return error(GL_INVALID_OPERATION);
   4069 				}
   4070 
   4071 				blitDepthStencil = true;
   4072 				readDSBuffer = readFramebuffer->getDepthbuffer();
   4073 				drawDSBuffer = drawFramebuffer->getDepthbuffer();
   4074 			}
   4075 		}
   4076 
   4077 		if(mask & GL_STENCIL_BUFFER_BIT)
   4078 		{
   4079 			if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
   4080 			{
   4081 				if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType())
   4082 				{
   4083 					return error(GL_INVALID_OPERATION);
   4084 				}
   4085 
   4086 				blitDepthStencil = true;
   4087 				readDSBuffer = readFramebuffer->getStencilbuffer();
   4088 				drawDSBuffer = drawFramebuffer->getStencilbuffer();
   4089 			}
   4090 		}
   4091 
   4092 		if(partialBufferCopy)
   4093 		{
   4094 			ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
   4095 			return error(GL_INVALID_OPERATION);   // Only whole-buffer copies are permitted
   4096 		}
   4097 
   4098 		if((drawDSBuffer && drawDSBuffer->getSamples() > 1) ||
   4099 		   (readDSBuffer && readDSBuffer->getSamples() > 1))
   4100 		{
   4101 			return error(GL_INVALID_OPERATION);
   4102 		}
   4103 	}
   4104 
   4105 	if(blitRenderTarget || blitDepthStencil)
   4106 	{
   4107 		if(blitRenderTarget)
   4108 		{
   4109 			egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget();
   4110 			egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0);
   4111 
   4112 			if(flipX)
   4113 			{
   4114 				swap(destRect.x0, destRect.x1);
   4115 			}
   4116 			if(flipy)
   4117 			{
   4118 				swap(destRect.y0, destRect.y1);
   4119 			}
   4120 
   4121 			bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false);
   4122 
   4123 			readRenderTarget->release();
   4124 			drawRenderTarget->release();
   4125 
   4126 			if(!success)
   4127 			{
   4128 				ERR("BlitFramebuffer failed.");
   4129 				return;
   4130 			}
   4131 		}
   4132 
   4133 		if(blitDepthStencil)
   4134 		{
   4135 			bool success = device->stretchRect(readFramebuffer->getDepthBuffer(), nullptr, drawFramebuffer->getDepthBuffer(), nullptr, false);
   4136 
   4137 			if(!success)
   4138 			{
   4139 				ERR("BlitFramebuffer failed.");
   4140 				return;
   4141 			}
   4142 		}
   4143 	}
   4144 }
   4145 
   4146 void Context::bindTexImage(egl::Surface *surface)
   4147 {
   4148 	es2::Texture2D *textureObject = getTexture2D();
   4149 
   4150 	if(textureObject)
   4151 	{
   4152 		textureObject->bindTexImage(surface);
   4153 	}
   4154 }
   4155 
   4156 EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
   4157 {
   4158 	GLenum textureTarget = GL_NONE;
   4159 
   4160 	switch(target)
   4161 	{
   4162 	case EGL_GL_TEXTURE_2D_KHR:
   4163 		textureTarget = GL_TEXTURE_2D;
   4164 		break;
   4165 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
   4166 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
   4167 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
   4168 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
   4169 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
   4170 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
   4171 		textureTarget = GL_TEXTURE_CUBE_MAP;
   4172 		break;
   4173 	case EGL_GL_RENDERBUFFER_KHR:
   4174 		break;
   4175 	default:
   4176 		return EGL_BAD_PARAMETER;
   4177 	}
   4178 
   4179 	if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   4180 	{
   4181 		return EGL_BAD_MATCH;
   4182 	}
   4183 
   4184 	if(textureTarget != GL_NONE)
   4185 	{
   4186 		es2::Texture *texture = getTexture(name);
   4187 
   4188 		if(!texture || texture->getTarget() != textureTarget)
   4189 		{
   4190 			return EGL_BAD_PARAMETER;
   4191 		}
   4192 
   4193 		if(texture->isShared(textureTarget, textureLevel))   // Bound to an EGLSurface or already an EGLImage sibling
   4194 		{
   4195 			return EGL_BAD_ACCESS;
   4196 		}
   4197 
   4198 		if(textureLevel != 0 && !texture->isSamplerComplete())
   4199 		{
   4200 			return EGL_BAD_PARAMETER;
   4201 		}
   4202 
   4203 		if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1))
   4204 		{
   4205 			return EGL_BAD_PARAMETER;
   4206 		}
   4207 	}
   4208 	else if(target == EGL_GL_RENDERBUFFER_KHR)
   4209 	{
   4210 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
   4211 
   4212 		if(!renderbuffer)
   4213 		{
   4214 			return EGL_BAD_PARAMETER;
   4215 		}
   4216 
   4217 		if(renderbuffer->isShared())   // Already an EGLImage sibling
   4218 		{
   4219 			return EGL_BAD_ACCESS;
   4220 		}
   4221 	}
   4222 	else UNREACHABLE(target);
   4223 
   4224 	return EGL_SUCCESS;
   4225 }
   4226 
   4227 egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel)
   4228 {
   4229 	GLenum textureTarget = GL_NONE;
   4230 
   4231 	switch(target)
   4232 	{
   4233 	case EGL_GL_TEXTURE_2D_KHR:                  textureTarget = GL_TEXTURE_2D;                  break;
   4234 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break;
   4235 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break;
   4236 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break;
   4237 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break;
   4238 	case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break;
   4239 	case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break;
   4240 	}
   4241 
   4242 	if(textureTarget != GL_NONE)
   4243 	{
   4244 		es2::Texture *texture = getTexture(name);
   4245 
   4246 		return texture->createSharedImage(textureTarget, textureLevel);
   4247 	}
   4248 	else if(target == EGL_GL_RENDERBUFFER_KHR)
   4249 	{
   4250 		es2::Renderbuffer *renderbuffer = getRenderbuffer(name);
   4251 
   4252 		return renderbuffer->createSharedImage();
   4253 	}
   4254 	else UNREACHABLE(target);
   4255 
   4256 	return 0;
   4257 }
   4258 
   4259 Device *Context::getDevice()
   4260 {
   4261 	return device;
   4262 }
   4263 
   4264 const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const
   4265 {
   4266 	// Keep list sorted in following order:
   4267 	// OES extensions
   4268 	// EXT extensions
   4269 	// Vendor extensions
   4270 	static const GLubyte* extensions[] = {
   4271 		(const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture",
   4272 		(const GLubyte*)"GL_OES_depth24",
   4273 		(const GLubyte*)"GL_OES_depth32",
   4274 		(const GLubyte*)"GL_OES_depth_texture",
   4275 		(const GLubyte*)"GL_OES_depth_texture_cube_map",
   4276 		(const GLubyte*)"GL_OES_EGL_image",
   4277 		(const GLubyte*)"GL_OES_EGL_image_external",
   4278 		(const GLubyte*)"GL_OES_EGL_sync",
   4279 		(const GLubyte*)"GL_OES_element_index_uint",
   4280 		(const GLubyte*)"GL_OES_framebuffer_object",
   4281 		(const GLubyte*)"GL_OES_packed_depth_stencil",
   4282 		(const GLubyte*)"GL_OES_rgb8_rgba8",
   4283 		(const GLubyte*)"GL_OES_standard_derivatives",
   4284 		(const GLubyte*)"GL_OES_texture_float",
   4285 		(const GLubyte*)"GL_OES_texture_float_linear",
   4286 		(const GLubyte*)"GL_OES_texture_half_float",
   4287 		(const GLubyte*)"GL_OES_texture_half_float_linear",
   4288 		(const GLubyte*)"GL_OES_texture_npot",
   4289 		(const GLubyte*)"GL_OES_texture_3D",
   4290 		(const GLubyte*)"GL_EXT_blend_minmax",
   4291 		(const GLubyte*)"GL_EXT_color_buffer_half_float",
   4292 		(const GLubyte*)"GL_EXT_draw_buffers",
   4293 		(const GLubyte*)"GL_EXT_occlusion_query_boolean",
   4294 		(const GLubyte*)"GL_EXT_read_format_bgra",
   4295 #if (S3TC_SUPPORT)
   4296 		(const GLubyte*)"GL_EXT_texture_compression_dxt1",
   4297 #endif
   4298 		(const GLubyte*)"GL_EXT_texture_filter_anisotropic",
   4299 		(const GLubyte*)"GL_EXT_texture_format_BGRA8888",
   4300 		(const GLubyte*)"GL_ANGLE_framebuffer_blit",
   4301 		(const GLubyte*)"GL_NV_framebuffer_blit",
   4302 		(const GLubyte*)"GL_ANGLE_framebuffer_multisample",
   4303 #if (S3TC_SUPPORT)
   4304 		(const GLubyte*)"GL_ANGLE_texture_compression_dxt3",
   4305 		(const GLubyte*)"GL_ANGLE_texture_compression_dxt5",
   4306 #endif
   4307 		(const GLubyte*)"GL_NV_fence",
   4308 		(const GLubyte*)"GL_NV_read_depth",
   4309 		(const GLubyte*)"GL_EXT_instanced_arrays",
   4310 		(const GLubyte*)"GL_ANGLE_instanced_arrays",
   4311 	};
   4312 	static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions);
   4313 
   4314 	if(numExt)
   4315 	{
   4316 		*numExt = numExtensions;
   4317 		return nullptr;
   4318 	}
   4319 
   4320 	if(index == GL_INVALID_INDEX)
   4321 	{
   4322 		static GLubyte* extensionsCat = nullptr;
   4323 		if(!extensionsCat && (numExtensions > 0))
   4324 		{
   4325 			size_t totalLength = numExtensions; // 1 space between each extension name + terminating null
   4326 			for(unsigned int i = 0; i < numExtensions; i++)
   4327 			{
   4328 				totalLength += strlen(reinterpret_cast<const char*>(extensions[i]));
   4329 			}
   4330 			extensionsCat = new GLubyte[totalLength];
   4331 			extensionsCat[0] = '\0';
   4332 			for(unsigned int i = 0; i < numExtensions; i++)
   4333 			{
   4334 				if(i != 0)
   4335 				{
   4336 					strcat(reinterpret_cast<char*>(extensionsCat), " ");
   4337 				}
   4338 				strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i]));
   4339 			}
   4340 		}
   4341 		return extensionsCat;
   4342 	}
   4343 
   4344 	if(index >= numExtensions)
   4345 	{
   4346 		return nullptr;
   4347 	}
   4348 
   4349 	return extensions[index];
   4350 }
   4351 
   4352 }
   4353 
   4354 egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion)
   4355 {
   4356 	ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion);   // Should be checked by eglCreateContext
   4357 	return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion);
   4358 }
   4359