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