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