Context.cpp revision 0300e3c7a5ef70b53ad742e348b2cd4d848b42b9
1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// SwiftShader Software Renderer 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright(c) 2005-2013 TransGaming Inc. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// All rights reserved. No part of this software may be copied, distributed, transmitted, 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// transcribed, stored in a retrieval system, translated into any human or computer 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// language by any means, or disclosed to third parties without the explicit written 80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express 90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko// or implied, including but not limited to any patent rights, are granted to you. 10b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Context.cpp: Implements the es2::Context class, managing all GL state and performing 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// rendering operations. It is the GLES2 specific implementation of EGLContext. 1445779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Context.h" 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "main.h" 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "mathutil.h" 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "utilities.h" 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "ResourceManager.h" 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Buffer.h" 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Fence.h" 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Framebuffer.h" 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Program.h" 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Query.h" 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Renderbuffer.h" 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Shader.h" 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Texture.h" 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "VertexDataManager.h" 30b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "IndexDataManager.h" 31b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "libEGL/Display.h" 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "libEGL/Surface.h" 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "Common/Half.hpp" 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include <EGL/eglext.h> 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#undef near 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#undef far 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace es2 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat{ 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratContext::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion) 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : mConfig(config), clientVersion(clientVersion) 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat{ 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat sw::Context *context = new sw::Context(); 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat device = new es2::Device(context); 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mFenceNameSpace.setBaseHandle(0); 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 52b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.depthClearValue = 1.0f; 53b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilClearValue = 0; 54b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 55b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.cullFace = false; 56b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.cullMode = GL_BACK; 57b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.frontFace = GL_CCW; 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.depthTest = false; 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.depthFunc = GL_LESS; 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blend = false; 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.sourceBlendRGB = GL_ONE; 6245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko mState.sourceBlendAlpha = GL_ONE; 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.destBlendRGB = GL_ZERO; 64b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.destBlendAlpha = GL_ZERO; 65b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendEquationRGB = GL_FUNC_ADD; 66b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendEquationAlpha = GL_FUNC_ADD; 67b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendColor.red = 0; 68b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendColor.green = 0; 69b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendColor.blue = 0; 70b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.blendColor.alpha = 0; 71b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilTest = false; 72b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilFunc = GL_ALWAYS; 73b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilRef = 0; 74b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilMask = -1; 75b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilWritemask = -1; 76b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackFunc = GL_ALWAYS; 77b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackRef = 0; 78b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackMask = - 1; 79b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackWritemask = -1; 80b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilFail = GL_KEEP; 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilPassDepthFail = GL_KEEP; 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilPassDepthPass = GL_KEEP; 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackFail = GL_KEEP; 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackPassDepthFail = GL_KEEP; 85b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.stencilBackPassDepthPass = GL_KEEP; 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.polygonOffsetFill = false; 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.polygonOffsetFactor = 0.0f; 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.polygonOffsetUnits = 0.0f; 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.sampleAlphaToCoverage = false; 90b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.sampleCoverage = false; 91b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.sampleCoverageValue = 1.0f; 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.sampleCoverageInvert = false; 93b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.scissorTest = false; 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.dither = true; 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.primitiveRestartFixedIndex = false; 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.rasterizerDiscard = false; 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.generateMipmapHint = GL_DONT_CARE; 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.fragmentShaderDerivativeHint = GL_DONT_CARE; 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 1003a83cddbf6d8fe9c9d70d01e008ff8e86a823cb6Jay Civelli mState.lineWidth = 1.0f; 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.viewportX = 0; 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.viewportY = 0; 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.viewportWidth = config->mDisplayMode.width; 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.viewportHeight = config->mDisplayMode.height; 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.zNear = 0.0f; 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.zFar = 1.0f; 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.scissorX = 0; 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat mState.scissorY = 0; 111 mState.scissorWidth = config->mDisplayMode.width; 112 mState.scissorHeight = config->mDisplayMode.height; 113 114 mState.colorMaskRed = true; 115 mState.colorMaskGreen = true; 116 mState.colorMaskBlue = true; 117 mState.colorMaskAlpha = true; 118 mState.depthMask = true; 119 120 if(shareContext != NULL) 121 { 122 mResourceManager = shareContext->mResourceManager; 123 mResourceManager->addRef(); 124 } 125 else 126 { 127 mResourceManager = new ResourceManager(); 128 } 129 130 // [OpenGL ES 2.0.24] section 3.7 page 83: 131 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 132 // and cube map texture state vectors respectively associated with them. 133 // In order that access to these initial textures not be lost, they are treated as texture 134 // objects all of whose names are 0. 135 136 mTexture2DZero = new Texture2D(0); 137 mTexture3DZero = new Texture3D(0); 138 mTextureCubeMapZero = new TextureCubeMap(0); 139 mTextureExternalZero = new TextureExternal(0); 140 141 mState.activeSampler = 0; 142 bindArrayBuffer(0); 143 bindElementArrayBuffer(0); 144 bindTextureCubeMap(0); 145 bindTexture2D(0); 146 bindReadFramebuffer(0); 147 bindDrawFramebuffer(0); 148 bindRenderbuffer(0); 149 150 mState.currentProgram = 0; 151 152 mState.packAlignment = 4; 153 mState.unpackAlignment = 4; 154 155 mVertexDataManager = NULL; 156 mIndexDataManager = NULL; 157 158 mInvalidEnum = false; 159 mInvalidValue = false; 160 mInvalidOperation = false; 161 mOutOfMemory = false; 162 mInvalidFramebufferOperation = false; 163 164 mHasBeenCurrent = false; 165 166 markAllStateDirty(); 167} 168 169Context::~Context() 170{ 171 if(mState.currentProgram != 0) 172 { 173 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 174 if(programObject) 175 { 176 programObject->release(); 177 } 178 mState.currentProgram = 0; 179 } 180 181 while(!mFramebufferMap.empty()) 182 { 183 deleteFramebuffer(mFramebufferMap.begin()->first); 184 } 185 186 while(!mFenceMap.empty()) 187 { 188 deleteFence(mFenceMap.begin()->first); 189 } 190 191 while(!mQueryMap.empty()) 192 { 193 deleteQuery(mQueryMap.begin()->first); 194 } 195 196 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 197 { 198 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 199 { 200 mState.samplerTexture[type][sampler] = NULL; 201 } 202 } 203 204 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 205 { 206 mState.vertexAttribute[i].mBoundBuffer = NULL; 207 } 208 209 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 210 { 211 mState.activeQuery[i] = NULL; 212 } 213 214 mState.arrayBuffer = NULL; 215 mState.elementArrayBuffer = NULL; 216 mState.renderbuffer = NULL; 217 218 mTexture2DZero = NULL; 219 mTexture3DZero = NULL; 220 mTextureCubeMapZero = NULL; 221 mTextureExternalZero = NULL; 222 223 delete mVertexDataManager; 224 delete mIndexDataManager; 225 226 mResourceManager->release(); 227 delete device; 228} 229 230void Context::makeCurrent(egl::Surface *surface) 231{ 232 if(!mHasBeenCurrent) 233 { 234 mVertexDataManager = new VertexDataManager(this); 235 mIndexDataManager = new IndexDataManager(); 236 237 mState.viewportX = 0; 238 mState.viewportY = 0; 239 mState.viewportWidth = surface->getWidth(); 240 mState.viewportHeight = surface->getHeight(); 241 242 mState.scissorX = 0; 243 mState.scissorY = 0; 244 mState.scissorWidth = surface->getWidth(); 245 mState.scissorHeight = surface->getHeight(); 246 247 mHasBeenCurrent = true; 248 } 249 250 // Wrap the existing resources into GL objects and assign them to the '0' names 251 egl::Image *defaultRenderTarget = surface->getRenderTarget(); 252 egl::Image *depthStencil = surface->getDepthStencil(); 253 254 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 255 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 256 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 257 258 setFramebufferZero(framebufferZero); 259 260 if(defaultRenderTarget) 261 { 262 defaultRenderTarget->release(); 263 } 264 265 if(depthStencil) 266 { 267 depthStencil->release(); 268 } 269 270 markAllStateDirty(); 271} 272 273void Context::destroy() 274{ 275 delete this; 276} 277 278EGLint Context::getClientVersion() 279{ 280 return clientVersion; 281} 282 283// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 284void Context::markAllStateDirty() 285{ 286 mAppliedProgramSerial = 0; 287 288 mDepthStateDirty = true; 289 mMaskStateDirty = true; 290 mBlendStateDirty = true; 291 mStencilStateDirty = true; 292 mPolygonOffsetStateDirty = true; 293 mSampleStateDirty = true; 294 mDitherStateDirty = true; 295 mFrontFaceDirty = true; 296} 297 298void Context::setClearColor(float red, float green, float blue, float alpha) 299{ 300 mState.colorClearValue.red = red; 301 mState.colorClearValue.green = green; 302 mState.colorClearValue.blue = blue; 303 mState.colorClearValue.alpha = alpha; 304} 305 306void Context::setClearDepth(float depth) 307{ 308 mState.depthClearValue = depth; 309} 310 311void Context::setClearStencil(int stencil) 312{ 313 mState.stencilClearValue = stencil; 314} 315 316void Context::setCullFace(bool enabled) 317{ 318 mState.cullFace = enabled; 319} 320 321bool Context::isCullFaceEnabled() const 322{ 323 return mState.cullFace; 324} 325 326void Context::setCullMode(GLenum mode) 327{ 328 mState.cullMode = mode; 329} 330 331void Context::setFrontFace(GLenum front) 332{ 333 if(mState.frontFace != front) 334 { 335 mState.frontFace = front; 336 mFrontFaceDirty = true; 337 } 338} 339 340void Context::setDepthTest(bool enabled) 341{ 342 if(mState.depthTest != enabled) 343 { 344 mState.depthTest = enabled; 345 mDepthStateDirty = true; 346 } 347} 348 349bool Context::isDepthTestEnabled() const 350{ 351 return mState.depthTest; 352} 353 354void Context::setDepthFunc(GLenum depthFunc) 355{ 356 if(mState.depthFunc != depthFunc) 357 { 358 mState.depthFunc = depthFunc; 359 mDepthStateDirty = true; 360 } 361} 362 363void Context::setDepthRange(float zNear, float zFar) 364{ 365 mState.zNear = zNear; 366 mState.zFar = zFar; 367} 368 369void Context::setBlend(bool enabled) 370{ 371 if(mState.blend != enabled) 372 { 373 mState.blend = enabled; 374 mBlendStateDirty = true; 375 } 376} 377 378bool Context::isBlendEnabled() const 379{ 380 return mState.blend; 381} 382 383void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 384{ 385 if(mState.sourceBlendRGB != sourceRGB || 386 mState.sourceBlendAlpha != sourceAlpha || 387 mState.destBlendRGB != destRGB || 388 mState.destBlendAlpha != destAlpha) 389 { 390 mState.sourceBlendRGB = sourceRGB; 391 mState.destBlendRGB = destRGB; 392 mState.sourceBlendAlpha = sourceAlpha; 393 mState.destBlendAlpha = destAlpha; 394 mBlendStateDirty = true; 395 } 396} 397 398void Context::setBlendColor(float red, float green, float blue, float alpha) 399{ 400 if(mState.blendColor.red != red || 401 mState.blendColor.green != green || 402 mState.blendColor.blue != blue || 403 mState.blendColor.alpha != alpha) 404 { 405 mState.blendColor.red = red; 406 mState.blendColor.green = green; 407 mState.blendColor.blue = blue; 408 mState.blendColor.alpha = alpha; 409 mBlendStateDirty = true; 410 } 411} 412 413void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 414{ 415 if(mState.blendEquationRGB != rgbEquation || 416 mState.blendEquationAlpha != alphaEquation) 417 { 418 mState.blendEquationRGB = rgbEquation; 419 mState.blendEquationAlpha = alphaEquation; 420 mBlendStateDirty = true; 421 } 422} 423 424void Context::setStencilTest(bool enabled) 425{ 426 if(mState.stencilTest != enabled) 427 { 428 mState.stencilTest = enabled; 429 mStencilStateDirty = true; 430 } 431} 432 433bool Context::isStencilTestEnabled() const 434{ 435 return mState.stencilTest; 436} 437 438void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 439{ 440 if(mState.stencilFunc != stencilFunc || 441 mState.stencilRef != stencilRef || 442 mState.stencilMask != stencilMask) 443 { 444 mState.stencilFunc = stencilFunc; 445 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 446 mState.stencilMask = stencilMask; 447 mStencilStateDirty = true; 448 } 449} 450 451void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 452{ 453 if(mState.stencilBackFunc != stencilBackFunc || 454 mState.stencilBackRef != stencilBackRef || 455 mState.stencilBackMask != stencilBackMask) 456 { 457 mState.stencilBackFunc = stencilBackFunc; 458 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 459 mState.stencilBackMask = stencilBackMask; 460 mStencilStateDirty = true; 461 } 462} 463 464void Context::setStencilWritemask(GLuint stencilWritemask) 465{ 466 if(mState.stencilWritemask != stencilWritemask) 467 { 468 mState.stencilWritemask = stencilWritemask; 469 mStencilStateDirty = true; 470 } 471} 472 473void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 474{ 475 if(mState.stencilBackWritemask != stencilBackWritemask) 476 { 477 mState.stencilBackWritemask = stencilBackWritemask; 478 mStencilStateDirty = true; 479 } 480} 481 482void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 483{ 484 if(mState.stencilFail != stencilFail || 485 mState.stencilPassDepthFail != stencilPassDepthFail || 486 mState.stencilPassDepthPass != stencilPassDepthPass) 487 { 488 mState.stencilFail = stencilFail; 489 mState.stencilPassDepthFail = stencilPassDepthFail; 490 mState.stencilPassDepthPass = stencilPassDepthPass; 491 mStencilStateDirty = true; 492 } 493} 494 495void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 496{ 497 if(mState.stencilBackFail != stencilBackFail || 498 mState.stencilBackPassDepthFail != stencilBackPassDepthFail || 499 mState.stencilBackPassDepthPass != stencilBackPassDepthPass) 500 { 501 mState.stencilBackFail = stencilBackFail; 502 mState.stencilBackPassDepthFail = stencilBackPassDepthFail; 503 mState.stencilBackPassDepthPass = stencilBackPassDepthPass; 504 mStencilStateDirty = true; 505 } 506} 507 508void Context::setPolygonOffsetFill(bool enabled) 509{ 510 if(mState.polygonOffsetFill != enabled) 511 { 512 mState.polygonOffsetFill = enabled; 513 mPolygonOffsetStateDirty = true; 514 } 515} 516 517bool Context::isPolygonOffsetFillEnabled() const 518{ 519 return mState.polygonOffsetFill; 520} 521 522void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 523{ 524 if(mState.polygonOffsetFactor != factor || 525 mState.polygonOffsetUnits != units) 526 { 527 mState.polygonOffsetFactor = factor; 528 mState.polygonOffsetUnits = units; 529 mPolygonOffsetStateDirty = true; 530 } 531} 532 533void Context::setSampleAlphaToCoverage(bool enabled) 534{ 535 if(mState.sampleAlphaToCoverage != enabled) 536 { 537 mState.sampleAlphaToCoverage = enabled; 538 mSampleStateDirty = true; 539 } 540} 541 542bool Context::isSampleAlphaToCoverageEnabled() const 543{ 544 return mState.sampleAlphaToCoverage; 545} 546 547void Context::setSampleCoverage(bool enabled) 548{ 549 if(mState.sampleCoverage != enabled) 550 { 551 mState.sampleCoverage = enabled; 552 mSampleStateDirty = true; 553 } 554} 555 556bool Context::isSampleCoverageEnabled() const 557{ 558 return mState.sampleCoverage; 559} 560 561void Context::setSampleCoverageParams(GLclampf value, bool invert) 562{ 563 if(mState.sampleCoverageValue != value || 564 mState.sampleCoverageInvert != invert) 565 { 566 mState.sampleCoverageValue = value; 567 mState.sampleCoverageInvert = invert; 568 mSampleStateDirty = true; 569 } 570} 571 572void Context::setScissorTest(bool enabled) 573{ 574 mState.scissorTest = enabled; 575} 576 577bool Context::isScissorTestEnabled() const 578{ 579 return mState.scissorTest; 580} 581 582void Context::setDither(bool enabled) 583{ 584 if(mState.dither != enabled) 585 { 586 mState.dither = enabled; 587 mDitherStateDirty = true; 588 } 589} 590 591bool Context::isDitherEnabled() const 592{ 593 return mState.dither; 594} 595 596void Context::setPrimitiveRestartFixedIndex(bool enabled) 597{ 598 UNIMPLEMENTED(); 599 mState.primitiveRestartFixedIndex = enabled; 600} 601 602bool Context::isPrimitiveRestartFixedIndexEnabled() const 603{ 604 return mState.primitiveRestartFixedIndex; 605} 606 607void Context::setRasterizerDiscard(bool enabled) 608{ 609 UNIMPLEMENTED(); 610 mState.rasterizerDiscard = enabled; 611} 612 613bool Context::isRasterizerDiscardEnabled() const 614{ 615 return mState.rasterizerDiscard; 616} 617 618void Context::setLineWidth(GLfloat width) 619{ 620 mState.lineWidth = width; 621 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX)); 622} 623 624void Context::setGenerateMipmapHint(GLenum hint) 625{ 626 mState.generateMipmapHint = hint; 627} 628 629void Context::setFragmentShaderDerivativeHint(GLenum hint) 630{ 631 mState.fragmentShaderDerivativeHint = hint; 632 // TODO: Propagate the hint to shader translator so we can write 633 // ddx, ddx_coarse, or ddx_fine depending on the hint. 634 // Ignore for now. It is valid for implementations to ignore hint. 635} 636 637void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 638{ 639 mState.viewportX = x; 640 mState.viewportY = y; 641 mState.viewportWidth = width; 642 mState.viewportHeight = height; 643} 644 645void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 646{ 647 mState.scissorX = x; 648 mState.scissorY = y; 649 mState.scissorWidth = width; 650 mState.scissorHeight = height; 651} 652 653void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 654{ 655 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 656 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 657 { 658 mState.colorMaskRed = red; 659 mState.colorMaskGreen = green; 660 mState.colorMaskBlue = blue; 661 mState.colorMaskAlpha = alpha; 662 mMaskStateDirty = true; 663 } 664} 665 666void Context::setDepthMask(bool mask) 667{ 668 if(mState.depthMask != mask) 669 { 670 mState.depthMask = mask; 671 mMaskStateDirty = true; 672 } 673} 674 675void Context::setActiveSampler(unsigned int active) 676{ 677 mState.activeSampler = active; 678} 679 680GLuint Context::getReadFramebufferName() const 681{ 682 return mState.readFramebuffer; 683} 684 685GLuint Context::getDrawFramebufferName() const 686{ 687 return mState.drawFramebuffer; 688} 689 690GLuint Context::getRenderbufferName() const 691{ 692 return mState.renderbuffer.name(); 693} 694 695GLuint Context::getArrayBufferName() const 696{ 697 return mState.arrayBuffer.name(); 698} 699 700GLuint Context::getActiveQuery(GLenum target) const 701{ 702 Query *queryObject = NULL; 703 704 switch(target) 705 { 706 case GL_ANY_SAMPLES_PASSED_EXT: 707 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED]; 708 break; 709 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 710 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE]; 711 break; 712 default: 713 ASSERT(false); 714 } 715 716 if(queryObject) 717 { 718 return queryObject->name; 719 } 720 721 return 0; 722} 723 724void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 725{ 726 mState.vertexAttribute[attribNum].mArrayEnabled = enabled; 727} 728 729const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) 730{ 731 return mState.vertexAttribute[attribNum]; 732} 733 734void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 735 GLsizei stride, const void *pointer) 736{ 737 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer; 738 mState.vertexAttribute[attribNum].mSize = size; 739 mState.vertexAttribute[attribNum].mType = type; 740 mState.vertexAttribute[attribNum].mNormalized = normalized; 741 mState.vertexAttribute[attribNum].mStride = stride; 742 mState.vertexAttribute[attribNum].mPointer = pointer; 743} 744 745const void *Context::getVertexAttribPointer(unsigned int attribNum) const 746{ 747 return mState.vertexAttribute[attribNum].mPointer; 748} 749 750const VertexAttributeArray &Context::getVertexAttributes() 751{ 752 return mState.vertexAttribute; 753} 754 755void Context::setPackAlignment(GLint alignment) 756{ 757 mState.packAlignment = alignment; 758} 759 760GLint Context::getPackAlignment() const 761{ 762 return mState.packAlignment; 763} 764 765void Context::setUnpackAlignment(GLint alignment) 766{ 767 mState.unpackAlignment = alignment; 768} 769 770GLint Context::getUnpackAlignment() const 771{ 772 return mState.unpackAlignment; 773} 774 775GLuint Context::createBuffer() 776{ 777 return mResourceManager->createBuffer(); 778} 779 780GLuint Context::createProgram() 781{ 782 return mResourceManager->createProgram(); 783} 784 785GLuint Context::createShader(GLenum type) 786{ 787 return mResourceManager->createShader(type); 788} 789 790GLuint Context::createTexture() 791{ 792 return mResourceManager->createTexture(); 793} 794 795GLuint Context::createRenderbuffer() 796{ 797 return mResourceManager->createRenderbuffer(); 798} 799 800// Returns an unused framebuffer name 801GLuint Context::createFramebuffer() 802{ 803 GLuint handle = mFramebufferNameSpace.allocate(); 804 805 mFramebufferMap[handle] = NULL; 806 807 return handle; 808} 809 810GLuint Context::createFence() 811{ 812 GLuint handle = mFenceNameSpace.allocate(); 813 814 mFenceMap[handle] = new Fence; 815 816 return handle; 817} 818 819// Returns an unused query name 820GLuint Context::createQuery() 821{ 822 GLuint handle = mQueryNameSpace.allocate(); 823 824 mQueryMap[handle] = NULL; 825 826 return handle; 827} 828 829void Context::deleteBuffer(GLuint buffer) 830{ 831 if(mResourceManager->getBuffer(buffer)) 832 { 833 detachBuffer(buffer); 834 } 835 836 mResourceManager->deleteBuffer(buffer); 837} 838 839void Context::deleteShader(GLuint shader) 840{ 841 mResourceManager->deleteShader(shader); 842} 843 844void Context::deleteProgram(GLuint program) 845{ 846 mResourceManager->deleteProgram(program); 847} 848 849void Context::deleteTexture(GLuint texture) 850{ 851 if(mResourceManager->getTexture(texture)) 852 { 853 detachTexture(texture); 854 } 855 856 mResourceManager->deleteTexture(texture); 857} 858 859void Context::deleteRenderbuffer(GLuint renderbuffer) 860{ 861 if(mResourceManager->getRenderbuffer(renderbuffer)) 862 { 863 detachRenderbuffer(renderbuffer); 864 } 865 866 mResourceManager->deleteRenderbuffer(renderbuffer); 867} 868 869void Context::deleteFramebuffer(GLuint framebuffer) 870{ 871 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 872 873 if(framebufferObject != mFramebufferMap.end()) 874 { 875 detachFramebuffer(framebuffer); 876 877 mFramebufferNameSpace.release(framebufferObject->first); 878 delete framebufferObject->second; 879 mFramebufferMap.erase(framebufferObject); 880 } 881} 882 883void Context::deleteFence(GLuint fence) 884{ 885 FenceMap::iterator fenceObject = mFenceMap.find(fence); 886 887 if(fenceObject != mFenceMap.end()) 888 { 889 mFenceNameSpace.release(fenceObject->first); 890 delete fenceObject->second; 891 mFenceMap.erase(fenceObject); 892 } 893} 894 895void Context::deleteQuery(GLuint query) 896{ 897 QueryMap::iterator queryObject = mQueryMap.find(query); 898 899 if(queryObject != mQueryMap.end()) 900 { 901 mQueryNameSpace.release(queryObject->first); 902 903 if(queryObject->second) 904 { 905 queryObject->second->release(); 906 } 907 908 mQueryMap.erase(queryObject); 909 } 910} 911 912Buffer *Context::getBuffer(GLuint handle) 913{ 914 return mResourceManager->getBuffer(handle); 915} 916 917Shader *Context::getShader(GLuint handle) 918{ 919 return mResourceManager->getShader(handle); 920} 921 922Program *Context::getProgram(GLuint handle) 923{ 924 return mResourceManager->getProgram(handle); 925} 926 927Texture *Context::getTexture(GLuint handle) 928{ 929 return mResourceManager->getTexture(handle); 930} 931 932Renderbuffer *Context::getRenderbuffer(GLuint handle) 933{ 934 return mResourceManager->getRenderbuffer(handle); 935} 936 937Framebuffer *Context::getReadFramebuffer() 938{ 939 return getFramebuffer(mState.readFramebuffer); 940} 941 942Framebuffer *Context::getDrawFramebuffer() 943{ 944 return getFramebuffer(mState.drawFramebuffer); 945} 946 947void Context::bindArrayBuffer(unsigned int buffer) 948{ 949 mResourceManager->checkBufferAllocation(buffer); 950 951 mState.arrayBuffer = getBuffer(buffer); 952} 953 954void Context::bindElementArrayBuffer(unsigned int buffer) 955{ 956 mResourceManager->checkBufferAllocation(buffer); 957 958 mState.elementArrayBuffer = getBuffer(buffer); 959} 960 961void Context::bindTexture2D(GLuint texture) 962{ 963 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 964 965 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture); 966} 967 968void Context::bindTextureCubeMap(GLuint texture) 969{ 970 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 971 972 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture); 973} 974 975void Context::bindTextureExternal(GLuint texture) 976{ 977 mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL); 978 979 mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture); 980} 981 982void Context::bindTexture3D(GLuint texture) 983{ 984 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); 985 986 mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture); 987} 988 989void Context::bindReadFramebuffer(GLuint framebuffer) 990{ 991 if(!getFramebuffer(framebuffer)) 992 { 993 mFramebufferMap[framebuffer] = new Framebuffer(); 994 } 995 996 mState.readFramebuffer = framebuffer; 997} 998 999void Context::bindDrawFramebuffer(GLuint framebuffer) 1000{ 1001 if(!getFramebuffer(framebuffer)) 1002 { 1003 mFramebufferMap[framebuffer] = new Framebuffer(); 1004 } 1005 1006 mState.drawFramebuffer = framebuffer; 1007} 1008 1009void Context::bindRenderbuffer(GLuint renderbuffer) 1010{ 1011 mState.renderbuffer = getRenderbuffer(renderbuffer); 1012} 1013 1014void Context::useProgram(GLuint program) 1015{ 1016 GLuint priorProgram = mState.currentProgram; 1017 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged. 1018 1019 if(priorProgram != program) 1020 { 1021 Program *newProgram = mResourceManager->getProgram(program); 1022 Program *oldProgram = mResourceManager->getProgram(priorProgram); 1023 1024 if(newProgram) 1025 { 1026 newProgram->addRef(); 1027 } 1028 1029 if(oldProgram) 1030 { 1031 oldProgram->release(); 1032 } 1033 } 1034} 1035 1036void Context::beginQuery(GLenum target, GLuint query) 1037{ 1038 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> 1039 // of zero, if the active query object name for <target> is non-zero (for the 1040 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if 1041 // the active query for either target is non-zero), if <id> is the name of an 1042 // existing query object whose type does not match <target>, or if <id> is the 1043 // active query object name for any query type, the error INVALID_OPERATION is 1044 // generated. 1045 1046 // Ensure no other queries are active 1047 // NOTE: If other queries than occlusion are supported, we will need to check 1048 // separately that: 1049 // a) The query ID passed is not the current active query for any target/type 1050 // b) There are no active queries for the requested target (and in the case 1051 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1052 // no query may be active for either if glBeginQuery targets either. 1053 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 1054 { 1055 if(mState.activeQuery[i] != NULL) 1056 { 1057 return error(GL_INVALID_OPERATION); 1058 } 1059 } 1060 1061 QueryType qType; 1062 switch(target) 1063 { 1064 case GL_ANY_SAMPLES_PASSED_EXT: 1065 qType = QUERY_ANY_SAMPLES_PASSED; 1066 break; 1067 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1068 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1069 break; 1070 default: 1071 ASSERT(false); 1072 } 1073 1074 Query *queryObject = getQuery(query, true, target); 1075 1076 // Check that name was obtained with glGenQueries 1077 if(!queryObject) 1078 { 1079 return error(GL_INVALID_OPERATION); 1080 } 1081 1082 // Check for type mismatch 1083 if(queryObject->getType() != target) 1084 { 1085 return error(GL_INVALID_OPERATION); 1086 } 1087 1088 // Set query as active for specified target 1089 mState.activeQuery[qType] = queryObject; 1090 1091 // Begin query 1092 queryObject->begin(); 1093} 1094 1095void Context::endQuery(GLenum target) 1096{ 1097 QueryType qType; 1098 1099 switch(target) 1100 { 1101 case GL_ANY_SAMPLES_PASSED_EXT: 1102 qType = QUERY_ANY_SAMPLES_PASSED; 1103 break; 1104 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1105 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1106 break; 1107 default: 1108 ASSERT(false); 1109 } 1110 1111 Query *queryObject = mState.activeQuery[qType]; 1112 1113 if(queryObject == NULL) 1114 { 1115 return error(GL_INVALID_OPERATION); 1116 } 1117 1118 queryObject->end(); 1119 1120 mState.activeQuery[qType] = NULL; 1121} 1122 1123void Context::setFramebufferZero(Framebuffer *buffer) 1124{ 1125 delete mFramebufferMap[0]; 1126 mFramebufferMap[0] = buffer; 1127} 1128 1129void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 1130{ 1131 Renderbuffer *renderbufferObject = mState.renderbuffer; 1132 renderbufferObject->setStorage(renderbuffer); 1133} 1134 1135Framebuffer *Context::getFramebuffer(unsigned int handle) 1136{ 1137 FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle); 1138 1139 if(framebuffer == mFramebufferMap.end()) 1140 { 1141 return NULL; 1142 } 1143 else 1144 { 1145 return framebuffer->second; 1146 } 1147} 1148 1149Fence *Context::getFence(unsigned int handle) 1150{ 1151 FenceMap::iterator fence = mFenceMap.find(handle); 1152 1153 if(fence == mFenceMap.end()) 1154 { 1155 return NULL; 1156 } 1157 else 1158 { 1159 return fence->second; 1160 } 1161} 1162 1163Query *Context::getQuery(unsigned int handle, bool create, GLenum type) 1164{ 1165 QueryMap::iterator query = mQueryMap.find(handle); 1166 1167 if(query == mQueryMap.end()) 1168 { 1169 return NULL; 1170 } 1171 else 1172 { 1173 if(!query->second && create) 1174 { 1175 query->second = new Query(handle, type); 1176 query->second->addRef(); 1177 } 1178 1179 return query->second; 1180 } 1181} 1182 1183Buffer *Context::getArrayBuffer() 1184{ 1185 return mState.arrayBuffer; 1186} 1187 1188Buffer *Context::getElementArrayBuffer() 1189{ 1190 return mState.elementArrayBuffer; 1191} 1192 1193Program *Context::getCurrentProgram() 1194{ 1195 return mResourceManager->getProgram(mState.currentProgram); 1196} 1197 1198Texture2D *Context::getTexture2D() 1199{ 1200 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1201} 1202 1203Texture3D *Context::getTexture3D() 1204{ 1205 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); 1206} 1207 1208TextureCubeMap *Context::getTextureCubeMap() 1209{ 1210 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1211} 1212 1213TextureExternal *Context::getTextureExternal() 1214{ 1215 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL)); 1216} 1217 1218Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) 1219{ 1220 GLuint texid = mState.samplerTexture[type][sampler].name(); 1221 1222 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 1223 { 1224 switch (type) 1225 { 1226 case TEXTURE_2D: return mTexture2DZero; 1227 case TEXTURE_3D: return mTexture3DZero; 1228 case TEXTURE_CUBE: return mTextureCubeMapZero; 1229 case TEXTURE_EXTERNAL: return mTextureExternalZero; 1230 default: UNREACHABLE(); 1231 } 1232 } 1233 1234 return mState.samplerTexture[type][sampler]; 1235} 1236 1237bool Context::getBooleanv(GLenum pname, GLboolean *params) 1238{ 1239 switch (pname) 1240 { 1241 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 1242 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 1243 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 1244 case GL_COLOR_WRITEMASK: 1245 params[0] = mState.colorMaskRed; 1246 params[1] = mState.colorMaskGreen; 1247 params[2] = mState.colorMaskBlue; 1248 params[3] = mState.colorMaskAlpha; 1249 break; 1250 case GL_CULL_FACE: *params = mState.cullFace; break; 1251 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; 1252 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; 1253 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; 1254 case GL_SCISSOR_TEST: *params = mState.scissorTest; break; 1255 case GL_STENCIL_TEST: *params = mState.stencilTest; break; 1256 case GL_DEPTH_TEST: *params = mState.depthTest; break; 1257 case GL_BLEND: *params = mState.blend; break; 1258 case GL_DITHER: *params = mState.dither; break; 1259 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndex; break; 1260 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscard; break; 1261 default: 1262 return false; 1263 } 1264 1265 return true; 1266} 1267 1268bool Context::getFloatv(GLenum pname, GLfloat *params) 1269{ 1270 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1271 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1272 // GetIntegerv as its native query function. As it would require conversion in any 1273 // case, this should make no difference to the calling application. 1274 switch (pname) 1275 { 1276 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 1277 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 1278 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 1279 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 1280 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 1281 case GL_ALIASED_LINE_WIDTH_RANGE: 1282 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 1283 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 1284 break; 1285 case GL_ALIASED_POINT_SIZE_RANGE: 1286 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 1287 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 1288 break; 1289 case GL_DEPTH_RANGE: 1290 params[0] = mState.zNear; 1291 params[1] = mState.zFar; 1292 break; 1293 case GL_COLOR_CLEAR_VALUE: 1294 params[0] = mState.colorClearValue.red; 1295 params[1] = mState.colorClearValue.green; 1296 params[2] = mState.colorClearValue.blue; 1297 params[3] = mState.colorClearValue.alpha; 1298 break; 1299 case GL_BLEND_COLOR: 1300 params[0] = mState.blendColor.red; 1301 params[1] = mState.blendColor.green; 1302 params[2] = mState.blendColor.blue; 1303 params[3] = mState.blendColor.alpha; 1304 break; 1305 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1306 *params = MAX_TEXTURE_MAX_ANISOTROPY; 1307 break; 1308 default: 1309 return false; 1310 } 1311 1312 return true; 1313} 1314 1315bool Context::getIntegerv(GLenum pname, GLint *params) 1316{ 1317 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1318 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1319 // GetIntegerv as its native query function. As it would require conversion in any 1320 // case, this should make no difference to the calling application. You may find it in 1321 // Context::getFloatv. 1322 switch (pname) 1323 { 1324 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break; 1325 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break; 1326 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break; 1327 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; 1328 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break; 1329 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break; 1330 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break; 1331 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break; 1332 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; 1333 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; 1334 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break; 1335 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break; 1336// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1337 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; 1338 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; 1339 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break; 1340 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; 1341 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 1342 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; 1343 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 1344 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; 1345 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 1346 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 1347 case GL_STENCIL_REF: *params = mState.stencilRef; break; 1348 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 1349 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break; 1350 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; 1351 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break; 1352 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 1353 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 1354 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1355 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break; 1356 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break; 1357 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break; 1358 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1359 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break; 1360 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break; 1361 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break; 1362 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break; 1363 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break; 1364 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break; 1365 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1366 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break; 1367 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1368 case GL_SUBPIXEL_BITS: *params = 4; break; 1369 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1370 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break; 1371 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1372 case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1373 case GL_SAMPLE_BUFFERS: 1374 case GL_SAMPLES: 1375 { 1376 Framebuffer *framebuffer = getDrawFramebuffer(); 1377 int width, height, samples; 1378 1379 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1380 { 1381 switch(pname) 1382 { 1383 case GL_SAMPLE_BUFFERS: 1384 if(samples > 1) 1385 { 1386 *params = 1; 1387 } 1388 else 1389 { 1390 *params = 0; 1391 } 1392 break; 1393 case GL_SAMPLES: 1394 *params = samples & ~1; 1395 break; 1396 } 1397 } 1398 else 1399 { 1400 *params = 0; 1401 } 1402 } 1403 break; 1404 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1405 { 1406 Framebuffer *framebuffer = getReadFramebuffer(); 1407 *params = framebuffer->getImplementationColorReadType(); 1408 } 1409 break; 1410 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1411 { 1412 Framebuffer *framebuffer = getReadFramebuffer(); 1413 *params = framebuffer->getImplementationColorReadFormat(); 1414 } 1415 break; 1416 case GL_MAX_VIEWPORT_DIMS: 1417 { 1418 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1419 params[0] = maxDimension; 1420 params[1] = maxDimension; 1421 } 1422 break; 1423 case GL_COMPRESSED_TEXTURE_FORMATS: 1424 { 1425 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1426 { 1427 params[i] = compressedTextureFormats[i]; 1428 } 1429 } 1430 break; 1431 case GL_VIEWPORT: 1432 params[0] = mState.viewportX; 1433 params[1] = mState.viewportY; 1434 params[2] = mState.viewportWidth; 1435 params[3] = mState.viewportHeight; 1436 break; 1437 case GL_SCISSOR_BOX: 1438 params[0] = mState.scissorX; 1439 params[1] = mState.scissorY; 1440 params[2] = mState.scissorWidth; 1441 params[3] = mState.scissorHeight; 1442 break; 1443 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1444 case GL_FRONT_FACE: *params = mState.frontFace; break; 1445 case GL_RED_BITS: 1446 case GL_GREEN_BITS: 1447 case GL_BLUE_BITS: 1448 case GL_ALPHA_BITS: 1449 { 1450 Framebuffer *framebuffer = getDrawFramebuffer(); 1451 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1452 1453 if(colorbuffer) 1454 { 1455 switch (pname) 1456 { 1457 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1458 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1459 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1460 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1461 } 1462 } 1463 else 1464 { 1465 *params = 0; 1466 } 1467 } 1468 break; 1469 case GL_DEPTH_BITS: 1470 { 1471 Framebuffer *framebuffer = getDrawFramebuffer(); 1472 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1473 1474 if(depthbuffer) 1475 { 1476 *params = depthbuffer->getDepthSize(); 1477 } 1478 else 1479 { 1480 *params = 0; 1481 } 1482 } 1483 break; 1484 case GL_STENCIL_BITS: 1485 { 1486 Framebuffer *framebuffer = getDrawFramebuffer(); 1487 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1488 1489 if(stencilbuffer) 1490 { 1491 *params = stencilbuffer->getStencilSize(); 1492 } 1493 else 1494 { 1495 *params = 0; 1496 } 1497 } 1498 break; 1499 case GL_TEXTURE_BINDING_2D: 1500 { 1501 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1502 { 1503 error(GL_INVALID_OPERATION); 1504 return false; 1505 } 1506 1507 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); 1508 } 1509 break; 1510 case GL_TEXTURE_BINDING_CUBE_MAP: 1511 { 1512 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1513 { 1514 error(GL_INVALID_OPERATION); 1515 return false; 1516 } 1517 1518 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); 1519 } 1520 break; 1521 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1522 { 1523 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1524 { 1525 error(GL_INVALID_OPERATION); 1526 return false; 1527 } 1528 1529 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); 1530 } 1531 break; 1532 case GL_TEXTURE_BINDING_3D_OES: 1533 case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0 1534 { 1535 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1536 { 1537 error(GL_INVALID_OPERATION); 1538 return false; 1539 } 1540 1541 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name(); 1542 } 1543 break; 1544 case GL_COPY_READ_BUFFER_BINDING: // name, initially 0 1545 UNIMPLEMENTED(); 1546 *params = 0; 1547 break; 1548 case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0 1549 UNIMPLEMENTED(); 1550 *params = 0; 1551 break; 1552 case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK 1553 UNIMPLEMENTED(); 1554 *params = GL_BACK; 1555 break; 1556 case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE 1557 case GL_DRAW_BUFFER2: 1558 case GL_DRAW_BUFFER3: 1559 case GL_DRAW_BUFFER4: 1560 case GL_DRAW_BUFFER5: 1561 case GL_DRAW_BUFFER6: 1562 case GL_DRAW_BUFFER7: 1563 case GL_DRAW_BUFFER8: 1564 case GL_DRAW_BUFFER9: 1565 case GL_DRAW_BUFFER10: 1566 case GL_DRAW_BUFFER11: 1567 case GL_DRAW_BUFFER12: 1568 case GL_DRAW_BUFFER13: 1569 case GL_DRAW_BUFFER14: 1570 case GL_DRAW_BUFFER15: 1571 UNIMPLEMENTED(); 1572 *params = GL_NONE; 1573 break; 1574 case GL_MAJOR_VERSION: // integer, at least 3 1575 UNIMPLEMENTED(); 1576 *params = 3; 1577 break; 1578 case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048 1579 UNIMPLEMENTED(); 1580 *params = 2048; 1581 break; 1582 case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048 1583 UNIMPLEMENTED(); 1584 *params = 2048; 1585 break; 1586 case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8 1587 UNIMPLEMENTED(); 1588 *params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; 1589 break; 1590 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1 1591 UNIMPLEMENTED(); 1592 *params = 1; 1593 break; 1594 case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70 1595 UNIMPLEMENTED(); 1596 *params = 70; 1597 break; 1598 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1 1599 UNIMPLEMENTED(); 1600 *params = 1; 1601 break; 1602 case GL_MAX_DRAW_BUFFERS: // integer, at least 8 1603 UNIMPLEMENTED(); 1604 *params = 8; 1605 break; 1606 case GL_MAX_ELEMENT_INDEX: // integer, at least 16777215 1607 UNIMPLEMENTED(); 1608 *params = 16777215; 1609 break; 1610 case GL_MAX_ELEMENTS_INDICES: // integer 1611 UNIMPLEMENTED(); 1612 *params = 0; 1613 break; 1614 case GL_MAX_ELEMENTS_VERTICES: // integer 1615 UNIMPLEMENTED(); 1616 *params = 0; 1617 break; 1618 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128 1619 UNIMPLEMENTED(); 1620 *params = 128; 1621 break; 1622 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12 1623 UNIMPLEMENTED(); 1624 *params = 12; 1625 break; 1626 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1024 1627 UNIMPLEMENTED(); 1628 *params = 1024; 1629 break; 1630 case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7 1631 UNIMPLEMENTED(); 1632 *params = 7; 1633 break; 1634 case GL_MAX_SERVER_WAIT_TIMEOUT: // integer 1635 UNIMPLEMENTED(); 1636 *params = 0; 1637 break; 1638 case GL_MAX_TEXTURE_LOD_BIAS: // integer, at least 2.0 1639 UNIMPLEMENTED(); 1640 *params = 2; 1641 break; 1642 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64 1643 UNIMPLEMENTED(); 1644 *params = 64; 1645 break; 1646 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4 1647 UNIMPLEMENTED(); 1648 *params = 4; 1649 break; 1650 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4 1651 UNIMPLEMENTED(); 1652 *params = 4; 1653 break; 1654 case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384 1655 UNIMPLEMENTED(); 1656 *params = 16384; 1657 break; 1658 case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36 1659 UNIMPLEMENTED(); 1660 *params = 36; 1661 break; 1662 case GL_MAX_VARYING_COMPONENTS: // integer, at least 60 1663 UNIMPLEMENTED(); 1664 *params = 60; 1665 break; 1666 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer, at least 64 1667 UNIMPLEMENTED(); 1668 *params = 64; 1669 break; 1670 case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer, at least 12 1671 UNIMPLEMENTED(); 1672 *params = 12; 1673 break; 1674 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1024 1675 UNIMPLEMENTED(); 1676 *params = 1024; 1677 break; 1678 case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8 1679 UNIMPLEMENTED(); 1680 *params = -8; 1681 break; 1682 case GL_MINOR_VERSION: // integer 1683 UNIMPLEMENTED(); 1684 *params = 0; 1685 break; 1686 case GL_NUM_EXTENSIONS: // integer 1687 UNIMPLEMENTED(); 1688 *params = 0; 1689 break; 1690 case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0 1691 UNIMPLEMENTED(); 1692 *params = 0; 1693 break; 1694 case GL_PACK_ROW_LENGTH: // integer, initially 0 1695 UNIMPLEMENTED(); 1696 *params = 0; 1697 break; 1698 case GL_PACK_SKIP_PIXELS: // integer, initially 0 1699 UNIMPLEMENTED(); 1700 *params = 0; 1701 break; 1702 case GL_PACK_SKIP_ROWS: // integer, initially 0 1703 UNIMPLEMENTED(); 1704 *params = 0; 1705 break; 1706 case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0 1707 UNIMPLEMENTED(); 1708 *params = 0; 1709 break; 1710 case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0 1711 UNIMPLEMENTED(); 1712 *params = 0; 1713 break; 1714 case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS] 1715 UNIMPLEMENTED(); 1716 *params = 0; 1717 break; 1718 case GL_READ_BUFFER: // symbolic constant, initial value is GL_BACK 1719 UNIMPLEMENTED(); 1720 *params = GL_BACK; 1721 break; 1722 case GL_SAMPLER_BINDING: // GLint, default 0 1723 UNIMPLEMENTED(); 1724 *params = 0; 1725 break; 1726 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0 1727 UNIMPLEMENTED(); 1728 *params = 0; 1729 break; 1730 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1 1731 UNIMPLEMENTED(); 1732 *params = 1; 1733 break; 1734 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 1735 UNIMPLEMENTED(); 1736 *params = 0; 1737 break; 1738 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0 1739 UNIMPLEMENTED(); 1740 *params = 0; 1741 break; 1742 case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0 1743 UNIMPLEMENTED(); 1744 *params = 0; 1745 break; 1746 case GL_UNPACK_ROW_LENGTH: // integer, initially 0 1747 UNIMPLEMENTED(); 1748 *params = 0; 1749 break; 1750 case GL_UNPACK_SKIP_IMAGES: // integer, initially 0 1751 UNIMPLEMENTED(); 1752 *params = 0; 1753 break; 1754 case GL_UNPACK_SKIP_PIXELS: // integer, initially 0 1755 UNIMPLEMENTED(); 1756 *params = 0; 1757 break; 1758 case GL_UNPACK_SKIP_ROWS: // integer, initially 0 1759 UNIMPLEMENTED(); 1760 *params = 0; 1761 break; 1762 case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0 1763 UNIMPLEMENTED(); 1764 *params = 0; 1765 break; 1766 default: 1767 return false; 1768 } 1769 1770 return true; 1771} 1772 1773bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param) 1774{ 1775 UNIMPLEMENTED(); 1776 1777 switch(pname) 1778 { 1779 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0 1780 *param = 0; 1781 break; 1782 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE 1783 *param = GL_FALSE; 1784 break; 1785 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0 1786 *param = 0; 1787 break; 1788 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE 1789 *param = GL_FALSE; 1790 break; 1791 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 1792 *param = 0; 1793 break; 1794 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0 1795 *param = 0; 1796 break; 1797 default: 1798 return false; 1799 } 1800 1801 return true; 1802} 1803 1804bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 1805{ 1806 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1807 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1808 // to the fact that it is stored internally as a float, and so would require conversion 1809 // if returned from Context::getIntegerv. Since this conversion is already implemented 1810 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1811 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1812 // application. 1813 switch (pname) 1814 { 1815 case GL_COMPRESSED_TEXTURE_FORMATS: 1816 { 1817 *type = GL_INT; 1818 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 1819 } 1820 break; 1821 case GL_SHADER_BINARY_FORMATS: 1822 { 1823 *type = GL_INT; 1824 *numParams = 0; 1825 } 1826 break; 1827 case GL_MAX_VERTEX_ATTRIBS: 1828 case GL_MAX_VERTEX_UNIFORM_VECTORS: 1829 case GL_MAX_VARYING_VECTORS: 1830 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 1831 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 1832 case GL_MAX_TEXTURE_IMAGE_UNITS: 1833 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 1834 case GL_MAX_RENDERBUFFER_SIZE: 1835 case GL_NUM_SHADER_BINARY_FORMATS: 1836 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1837 case GL_ARRAY_BUFFER_BINDING: 1838 case GL_FRAMEBUFFER_BINDING: 1839 case GL_RENDERBUFFER_BINDING: 1840 case GL_CURRENT_PROGRAM: 1841 case GL_PACK_ALIGNMENT: 1842 case GL_UNPACK_ALIGNMENT: 1843 case GL_GENERATE_MIPMAP_HINT: 1844 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 1845 case GL_RED_BITS: 1846 case GL_GREEN_BITS: 1847 case GL_BLUE_BITS: 1848 case GL_ALPHA_BITS: 1849 case GL_DEPTH_BITS: 1850 case GL_STENCIL_BITS: 1851 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1852 case GL_CULL_FACE_MODE: 1853 case GL_FRONT_FACE: 1854 case GL_ACTIVE_TEXTURE: 1855 case GL_STENCIL_FUNC: 1856 case GL_STENCIL_VALUE_MASK: 1857 case GL_STENCIL_REF: 1858 case GL_STENCIL_FAIL: 1859 case GL_STENCIL_PASS_DEPTH_FAIL: 1860 case GL_STENCIL_PASS_DEPTH_PASS: 1861 case GL_STENCIL_BACK_FUNC: 1862 case GL_STENCIL_BACK_VALUE_MASK: 1863 case GL_STENCIL_BACK_REF: 1864 case GL_STENCIL_BACK_FAIL: 1865 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 1866 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 1867 case GL_DEPTH_FUNC: 1868 case GL_BLEND_SRC_RGB: 1869 case GL_BLEND_SRC_ALPHA: 1870 case GL_BLEND_DST_RGB: 1871 case GL_BLEND_DST_ALPHA: 1872 case GL_BLEND_EQUATION_RGB: 1873 case GL_BLEND_EQUATION_ALPHA: 1874 case GL_STENCIL_WRITEMASK: 1875 case GL_STENCIL_BACK_WRITEMASK: 1876 case GL_STENCIL_CLEAR_VALUE: 1877 case GL_SUBPIXEL_BITS: 1878 case GL_MAX_TEXTURE_SIZE: 1879 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 1880 case GL_SAMPLE_BUFFERS: 1881 case GL_SAMPLES: 1882 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1883 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1884 case GL_TEXTURE_BINDING_2D: 1885 case GL_TEXTURE_BINDING_CUBE_MAP: 1886 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1887 case GL_TEXTURE_BINDING_3D_OES: 1888 case GL_COPY_READ_BUFFER_BINDING: 1889 case GL_COPY_WRITE_BUFFER_BINDING: 1890 case GL_DRAW_BUFFER0: 1891 case GL_DRAW_BUFFER1: 1892 case GL_DRAW_BUFFER2: 1893 case GL_DRAW_BUFFER3: 1894 case GL_DRAW_BUFFER4: 1895 case GL_DRAW_BUFFER5: 1896 case GL_DRAW_BUFFER6: 1897 case GL_DRAW_BUFFER7: 1898 case GL_DRAW_BUFFER8: 1899 case GL_DRAW_BUFFER9: 1900 case GL_DRAW_BUFFER10: 1901 case GL_DRAW_BUFFER11: 1902 case GL_DRAW_BUFFER12: 1903 case GL_DRAW_BUFFER13: 1904 case GL_DRAW_BUFFER14: 1905 case GL_DRAW_BUFFER15: 1906 case GL_MAJOR_VERSION: 1907 case GL_MAX_3D_TEXTURE_SIZE: 1908 case GL_MAX_ARRAY_TEXTURE_LAYERS: 1909 case GL_MAX_COLOR_ATTACHMENTS: 1910 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 1911 case GL_MAX_COMBINED_UNIFORM_BLOCKS: 1912 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 1913 case GL_MAX_DRAW_BUFFERS: 1914 case GL_MAX_ELEMENT_INDEX: 1915 case GL_MAX_ELEMENTS_INDICES: 1916 case GL_MAX_ELEMENTS_VERTICES: 1917 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: 1918 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: 1919 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 1920 case GL_MAX_PROGRAM_TEXEL_OFFSET: 1921 case GL_MAX_SERVER_WAIT_TIMEOUT: 1922 case GL_MAX_TEXTURE_LOD_BIAS: 1923 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 1924 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 1925 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 1926 case GL_MAX_UNIFORM_BLOCK_SIZE: 1927 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 1928 case GL_MAX_VARYING_COMPONENTS: 1929 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: 1930 case GL_MAX_VERTEX_UNIFORM_BLOCKS: 1931 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 1932 case GL_MIN_PROGRAM_TEXEL_OFFSET: 1933 case GL_MINOR_VERSION: 1934 case GL_NUM_EXTENSIONS: 1935 case GL_NUM_PROGRAM_BINARY_FORMATS: 1936 case GL_PACK_ROW_LENGTH: 1937 case GL_PACK_SKIP_PIXELS: 1938 case GL_PACK_SKIP_ROWS: 1939 case GL_PIXEL_PACK_BUFFER_BINDING: 1940 case GL_PIXEL_UNPACK_BUFFER_BINDING: 1941 case GL_PROGRAM_BINARY_FORMATS: 1942 case GL_READ_BUFFER: 1943 case GL_SAMPLER_BINDING: 1944 case GL_TEXTURE_BINDING_2D_ARRAY: 1945 case GL_UNIFORM_BUFFER_BINDING: 1946 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 1947 case GL_UNIFORM_BUFFER_SIZE: 1948 case GL_UNIFORM_BUFFER_START: 1949 case GL_UNPACK_IMAGE_HEIGHT: 1950 case GL_UNPACK_ROW_LENGTH: 1951 case GL_UNPACK_SKIP_IMAGES: 1952 case GL_UNPACK_SKIP_PIXELS: 1953 case GL_UNPACK_SKIP_ROWS: 1954 case GL_VERTEX_ARRAY_BINDING: 1955 { 1956 *type = GL_INT; 1957 *numParams = 1; 1958 } 1959 break; 1960 case GL_MAX_SAMPLES_ANGLE: 1961 { 1962 *type = GL_INT; 1963 *numParams = 1; 1964 } 1965 break; 1966 case GL_MAX_VIEWPORT_DIMS: 1967 { 1968 *type = GL_INT; 1969 *numParams = 2; 1970 } 1971 break; 1972 case GL_VIEWPORT: 1973 case GL_SCISSOR_BOX: 1974 { 1975 *type = GL_INT; 1976 *numParams = 4; 1977 } 1978 break; 1979 case GL_SHADER_COMPILER: 1980 case GL_SAMPLE_COVERAGE_INVERT: 1981 case GL_DEPTH_WRITEMASK: 1982 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1983 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1984 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1985 case GL_SAMPLE_COVERAGE: 1986 case GL_SCISSOR_TEST: 1987 case GL_STENCIL_TEST: 1988 case GL_DEPTH_TEST: 1989 case GL_BLEND: 1990 case GL_DITHER: 1991 case GL_PRIMITIVE_RESTART_FIXED_INDEX: 1992 case GL_RASTERIZER_DISCARD: 1993 { 1994 *type = GL_BOOL; 1995 *numParams = 1; 1996 } 1997 break; 1998 case GL_COLOR_WRITEMASK: 1999 { 2000 *type = GL_BOOL; 2001 *numParams = 4; 2002 } 2003 break; 2004 case GL_POLYGON_OFFSET_FACTOR: 2005 case GL_POLYGON_OFFSET_UNITS: 2006 case GL_SAMPLE_COVERAGE_VALUE: 2007 case GL_DEPTH_CLEAR_VALUE: 2008 case GL_LINE_WIDTH: 2009 { 2010 *type = GL_FLOAT; 2011 *numParams = 1; 2012 } 2013 break; 2014 case GL_ALIASED_LINE_WIDTH_RANGE: 2015 case GL_ALIASED_POINT_SIZE_RANGE: 2016 case GL_DEPTH_RANGE: 2017 { 2018 *type = GL_FLOAT; 2019 *numParams = 2; 2020 } 2021 break; 2022 case GL_COLOR_CLEAR_VALUE: 2023 case GL_BLEND_COLOR: 2024 { 2025 *type = GL_FLOAT; 2026 *numParams = 4; 2027 } 2028 break; 2029 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 2030 *type = GL_FLOAT; 2031 *numParams = 1; 2032 break; 2033 default: 2034 return false; 2035 } 2036 2037 return true; 2038} 2039 2040// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 2041bool Context::applyRenderTarget() 2042{ 2043 Framebuffer *framebuffer = getDrawFramebuffer(); 2044 int width, height, samples; 2045 2046 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 2047 { 2048 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 2049 } 2050 2051 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2052 device->setRenderTarget(renderTarget); 2053 if(renderTarget) renderTarget->release(); 2054 2055 egl::Image *depthStencil = framebuffer->getDepthStencil(); 2056 device->setDepthStencilSurface(depthStencil); 2057 if(depthStencil) depthStencil->release(); 2058 2059 Viewport viewport; 2060 float zNear = clamp01(mState.zNear); 2061 float zFar = clamp01(mState.zFar); 2062 2063 viewport.x0 = mState.viewportX; 2064 viewport.y0 = mState.viewportY; 2065 viewport.width = mState.viewportWidth; 2066 viewport.height = mState.viewportHeight; 2067 viewport.minZ = zNear; 2068 viewport.maxZ = zFar; 2069 2070 device->setViewport(viewport); 2071 2072 if(mState.scissorTest) 2073 { 2074 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 2075 scissor.clip(0, 0, width, height); 2076 2077 device->setScissorRect(scissor); 2078 device->setScissorEnable(true); 2079 } 2080 else 2081 { 2082 device->setScissorEnable(false); 2083 } 2084 2085 Program *program = getCurrentProgram(); 2086 2087 if(program) 2088 { 2089 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 2090 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 2091 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 2092 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 2093 } 2094 2095 return true; 2096} 2097 2098// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 2099void Context::applyState(GLenum drawMode) 2100{ 2101 Framebuffer *framebuffer = getDrawFramebuffer(); 2102 2103 if(mState.cullFace) 2104 { 2105 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 2106 } 2107 else 2108 { 2109 device->setCullMode(sw::CULL_NONE); 2110 } 2111 2112 if(mDepthStateDirty) 2113 { 2114 if(mState.depthTest) 2115 { 2116 device->setDepthBufferEnable(true); 2117 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 2118 } 2119 else 2120 { 2121 device->setDepthBufferEnable(false); 2122 } 2123 2124 mDepthStateDirty = false; 2125 } 2126 2127 if(mBlendStateDirty) 2128 { 2129 if(mState.blend) 2130 { 2131 device->setAlphaBlendEnable(true); 2132 device->setSeparateAlphaBlendEnable(true); 2133 2134 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 2135 2136 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 2137 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 2138 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 2139 2140 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 2141 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 2142 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 2143 } 2144 else 2145 { 2146 device->setAlphaBlendEnable(false); 2147 } 2148 2149 mBlendStateDirty = false; 2150 } 2151 2152 if(mStencilStateDirty || mFrontFaceDirty) 2153 { 2154 if(mState.stencilTest && framebuffer->hasStencil()) 2155 { 2156 device->setStencilEnable(true); 2157 device->setTwoSidedStencil(true); 2158 2159 if(mState.stencilWritemask != mState.stencilBackWritemask || 2160 mState.stencilRef != mState.stencilBackRef || 2161 mState.stencilMask != mState.stencilBackMask) 2162 { 2163 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); 2164 return error(GL_INVALID_OPERATION); 2165 } 2166 2167 // get the maximum size of the stencil ref 2168 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 2169 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 2170 2171 if(mState.frontFace == GL_CCW) 2172 { 2173 device->setStencilWriteMask(mState.stencilWritemask); 2174 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2175 2176 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2177 device->setStencilMask(mState.stencilMask); 2178 2179 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 2180 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2181 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2182 2183 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 2184 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2185 2186 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2187 device->setStencilMaskCCW(mState.stencilBackMask); 2188 2189 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2190 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2191 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2192 } 2193 else 2194 { 2195 device->setStencilWriteMaskCCW(mState.stencilWritemask); 2196 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2197 2198 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2199 device->setStencilMaskCCW(mState.stencilMask); 2200 2201 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 2202 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2203 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2204 2205 device->setStencilWriteMask(mState.stencilBackWritemask); 2206 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2207 2208 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2209 device->setStencilMask(mState.stencilBackMask); 2210 2211 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2212 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2213 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2214 } 2215 } 2216 else 2217 { 2218 device->setStencilEnable(false); 2219 } 2220 2221 mStencilStateDirty = false; 2222 mFrontFaceDirty = false; 2223 } 2224 2225 if(mMaskStateDirty) 2226 { 2227 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 2228 device->setDepthWriteEnable(mState.depthMask); 2229 2230 mMaskStateDirty = false; 2231 } 2232 2233 if(mPolygonOffsetStateDirty) 2234 { 2235 if(mState.polygonOffsetFill) 2236 { 2237 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 2238 if(depthbuffer) 2239 { 2240 device->setSlopeDepthBias(mState.polygonOffsetFactor); 2241 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 2242 device->setDepthBias(depthBias); 2243 } 2244 } 2245 else 2246 { 2247 device->setSlopeDepthBias(0); 2248 device->setDepthBias(0); 2249 } 2250 2251 mPolygonOffsetStateDirty = false; 2252 } 2253 2254 if(mSampleStateDirty) 2255 { 2256 if(mState.sampleAlphaToCoverage) 2257 { 2258 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 2259 } 2260 else 2261 { 2262 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 2263 } 2264 2265 if(mState.sampleCoverage) 2266 { 2267 unsigned int mask = 0; 2268 if(mState.sampleCoverageValue != 0) 2269 { 2270 int width, height, samples; 2271 framebuffer->completeness(width, height, samples); 2272 2273 float threshold = 0.5f; 2274 2275 for(int i = 0; i < samples; i++) 2276 { 2277 mask <<= 1; 2278 2279 if((i + 1) * mState.sampleCoverageValue >= threshold) 2280 { 2281 threshold += 1.0f; 2282 mask |= 1; 2283 } 2284 } 2285 } 2286 2287 if(mState.sampleCoverageInvert) 2288 { 2289 mask = ~mask; 2290 } 2291 2292 device->setMultiSampleMask(mask); 2293 } 2294 else 2295 { 2296 device->setMultiSampleMask(0xFFFFFFFF); 2297 } 2298 2299 mSampleStateDirty = false; 2300 } 2301 2302 if(mDitherStateDirty) 2303 { 2304 // UNIMPLEMENTED(); // FIXME 2305 2306 mDitherStateDirty = false; 2307 } 2308} 2309 2310GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 2311{ 2312 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 2313 2314 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 2315 if(err != GL_NO_ERROR) 2316 { 2317 return err; 2318 } 2319 2320 Program *program = getCurrentProgram(); 2321 2322 device->resetInputStreams(false); 2323 2324 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2325 { 2326 if(program->getAttributeStream(i) == -1) 2327 { 2328 continue; 2329 } 2330 2331 sw::Resource *resource = attributes[i].vertexBuffer; 2332 const void *buffer = (char*)resource->data() + attributes[i].offset; 2333 2334 int stride = attributes[i].stride; 2335 2336 buffer = (char*)buffer + stride * base; 2337 2338 sw::Stream attribute(resource, buffer, stride); 2339 2340 attribute.type = attributes[i].type; 2341 attribute.count = attributes[i].count; 2342 attribute.normalized = attributes[i].normalized; 2343 2344 int stream = program->getAttributeStream(i); 2345 device->setInputStream(stream, attribute); 2346 } 2347 2348 return GL_NO_ERROR; 2349} 2350 2351// Applies the indices and element array bindings 2352GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 2353{ 2354 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo); 2355 2356 if(err == GL_NO_ERROR) 2357 { 2358 device->setIndexBuffer(indexInfo->indexBuffer); 2359 } 2360 2361 return err; 2362} 2363 2364// Applies the shaders and shader constants 2365void Context::applyShaders() 2366{ 2367 Program *programObject = getCurrentProgram(); 2368 sw::VertexShader *vertexShader = programObject->getVertexShader(); 2369 sw::PixelShader *pixelShader = programObject->getPixelShader(); 2370 2371 device->setVertexShader(vertexShader); 2372 device->setPixelShader(pixelShader); 2373 2374 if(programObject->getSerial() != mAppliedProgramSerial) 2375 { 2376 programObject->dirtyAllUniforms(); 2377 mAppliedProgramSerial = programObject->getSerial(); 2378 } 2379 2380 programObject->applyUniforms(); 2381} 2382 2383void Context::applyTextures() 2384{ 2385 applyTextures(sw::SAMPLER_PIXEL); 2386 applyTextures(sw::SAMPLER_VERTEX); 2387} 2388 2389void Context::applyTextures(sw::SamplerType samplerType) 2390{ 2391 Program *programObject = getCurrentProgram(); 2392 2393 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2394 2395 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2396 { 2397 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index 2398 2399 if(textureUnit != -1) 2400 { 2401 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); 2402 2403 Texture *texture = getSamplerTexture(textureUnit, textureType); 2404 2405 if(texture->isSamplerComplete()) 2406 { 2407 GLenum wrapS = texture->getWrapS(); 2408 GLenum wrapT = texture->getWrapT(); 2409 GLenum wrapR = texture->getWrapR(); 2410 GLenum texFilter = texture->getMinFilter(); 2411 GLenum magFilter = texture->getMagFilter(); 2412 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2413 2414 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2415 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2416 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR)); 2417 2418 sw::FilterType minFilter; 2419 sw::MipmapType mipFilter; 2420 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 2421 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 2422 2423 device->setTextureFilter(samplerType, samplerIndex, minFilter); 2424 // device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 2425 device->setMipmapFilter(samplerType, samplerIndex, mipFilter); 2426 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2427 2428 applyTexture(samplerType, samplerIndex, texture); 2429 } 2430 else 2431 { 2432 applyTexture(samplerType, samplerIndex, 0); 2433 } 2434 } 2435 else 2436 { 2437 applyTexture(samplerType, samplerIndex, NULL); 2438 } 2439 } 2440} 2441 2442void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2443{ 2444 Program *program = getCurrentProgram(); 2445 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2446 bool textureUsed = false; 2447 2448 if(type == sw::SAMPLER_PIXEL) 2449 { 2450 textureUsed = program->getPixelShader()->usesSampler(index); 2451 } 2452 else if(type == sw::SAMPLER_VERTEX) 2453 { 2454 textureUsed = program->getVertexShader()->usesSampler(index); 2455 } 2456 else UNREACHABLE(); 2457 2458 sw::Resource *resource = 0; 2459 2460 if(baseTexture && textureUsed) 2461 { 2462 resource = baseTexture->getResource(); 2463 } 2464 2465 device->setTextureResource(sampler, resource); 2466 2467 if(baseTexture && textureUsed) 2468 { 2469 int levelCount = baseTexture->getLevelCount(); 2470 2471 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 2472 { 2473 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2474 2475 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2476 { 2477 int surfaceLevel = mipmapLevel; 2478 2479 if(surfaceLevel < 0) 2480 { 2481 surfaceLevel = 0; 2482 } 2483 else if(surfaceLevel >= levelCount) 2484 { 2485 surfaceLevel = levelCount - 1; 2486 } 2487 2488 egl::Image *surface = texture->getImage(surfaceLevel); 2489 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 2490 } 2491 } 2492 else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES) 2493 { 2494 Texture3D *texture = static_cast<Texture3D*>(baseTexture); 2495 2496 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2497 { 2498 int surfaceLevel = mipmapLevel; 2499 2500 if(surfaceLevel < 0) 2501 { 2502 surfaceLevel = 0; 2503 } 2504 else if(surfaceLevel >= levelCount) 2505 { 2506 surfaceLevel = levelCount - 1; 2507 } 2508 2509 egl::Image *surface = texture->getImage(surfaceLevel); 2510 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D); 2511 } 2512 } 2513 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 2514 { 2515 for(int face = 0; face < 6; face++) 2516 { 2517 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 2518 2519 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2520 { 2521 int surfaceLevel = mipmapLevel; 2522 2523 if(surfaceLevel < 0) 2524 { 2525 surfaceLevel = 0; 2526 } 2527 else if(surfaceLevel >= levelCount) 2528 { 2529 surfaceLevel = levelCount - 1; 2530 } 2531 2532 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel); 2533 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 2534 } 2535 } 2536 } 2537 else UNIMPLEMENTED(); 2538 } 2539 else 2540 { 2541 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 2542 } 2543} 2544 2545void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 2546 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 2547{ 2548 Framebuffer *framebuffer = getReadFramebuffer(); 2549 int framebufferWidth, framebufferHeight, framebufferSamples; 2550 2551 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2552 { 2553 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2554 } 2555 2556 if(getReadFramebufferName() != 0 && framebufferSamples != 0) 2557 { 2558 return error(GL_INVALID_OPERATION); 2559 } 2560 2561 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) 2562 { 2563 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType()) 2564 { 2565 return error(GL_INVALID_OPERATION); 2566 } 2567 } 2568 2569 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 2570 2571 // Sized query sanity check 2572 if(bufSize) 2573 { 2574 int requiredSize = outputPitch * height; 2575 if(requiredSize > *bufSize) 2576 { 2577 return error(GL_INVALID_OPERATION); 2578 } 2579 } 2580 2581 egl::Image *renderTarget = framebuffer->getRenderTarget(); 2582 2583 if(!renderTarget) 2584 { 2585 return error(GL_OUT_OF_MEMORY); 2586 } 2587 2588 sw::Rect rect = {x, y, x + width, y + height}; 2589 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 2590 2591 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 2592 unsigned char *dest = (unsigned char*)pixels; 2593 int inputPitch = (int)renderTarget->getPitch(); 2594 2595 for(int j = 0; j < rect.y1 - rect.y0; j++) 2596 { 2597 unsigned short *dest16 = (unsigned short*)dest; 2598 unsigned int *dest32 = (unsigned int*)dest; 2599 2600 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2601 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2602 { 2603 for(int i = 0; i < rect.x1 - rect.x0; i++) 2604 { 2605 unsigned int argb = *(unsigned int*)(source + 4 * i); 2606 2607 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16); 2608 } 2609 } 2610 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2611 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 2612 { 2613 for(int i = 0; i < rect.x1 - rect.x0; i++) 2614 { 2615 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2616 2617 dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000; 2618 } 2619 } 2620 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 2621 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2622 { 2623 for(int i = 0; i < rect.x1 - rect.x0; i++) 2624 { 2625 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2626 2627 dest32[i] = xrgb | 0xFF000000; 2628 } 2629 } 2630 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2631 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2632 { 2633 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 2634 } 2635 else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F && 2636 format == GL_RGBA && type == GL_HALF_FLOAT_OES) 2637 { 2638 memcpy(dest, source, (rect.x1 - rect.x0) * 8); 2639 } 2640 else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F && 2641 format == GL_RGBA && type == GL_FLOAT) 2642 { 2643 memcpy(dest, source, (rect.x1 - rect.x0) * 16); 2644 } 2645 else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 && 2646 format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) 2647 { 2648 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 2649 } 2650 else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 && 2651 format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT 2652 { 2653 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 2654 } 2655 else 2656 { 2657 for(int i = 0; i < rect.x1 - rect.x0; i++) 2658 { 2659 float r; 2660 float g; 2661 float b; 2662 float a; 2663 2664 switch(renderTarget->getInternalFormat()) 2665 { 2666 case sw::FORMAT_R5G6B5: 2667 { 2668 unsigned short rgb = *(unsigned short*)(source + 2 * i); 2669 2670 a = 1.0f; 2671 b = (rgb & 0x001F) * (1.0f / 0x001F); 2672 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 2673 r = (rgb & 0xF800) * (1.0f / 0xF800); 2674 } 2675 break; 2676 case sw::FORMAT_A1R5G5B5: 2677 { 2678 unsigned short argb = *(unsigned short*)(source + 2 * i); 2679 2680 a = (argb & 0x8000) ? 1.0f : 0.0f; 2681 b = (argb & 0x001F) * (1.0f / 0x001F); 2682 g = (argb & 0x03E0) * (1.0f / 0x03E0); 2683 r = (argb & 0x7C00) * (1.0f / 0x7C00); 2684 } 2685 break; 2686 case sw::FORMAT_A8R8G8B8: 2687 { 2688 unsigned int argb = *(unsigned int*)(source + 4 * i); 2689 2690 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 2691 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 2692 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 2693 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 2694 } 2695 break; 2696 case sw::FORMAT_X8R8G8B8: 2697 { 2698 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 2699 2700 a = 1.0f; 2701 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 2702 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 2703 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 2704 } 2705 break; 2706 case sw::FORMAT_A2R10G10B10: 2707 { 2708 unsigned int argb = *(unsigned int*)(source + 4 * i); 2709 2710 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 2711 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 2712 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 2713 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 2714 } 2715 break; 2716 case sw::FORMAT_A32B32G32R32F: 2717 { 2718 r = *((float*)(source + 16 * i) + 0); 2719 g = *((float*)(source + 16 * i) + 1); 2720 b = *((float*)(source + 16 * i) + 2); 2721 a = *((float*)(source + 16 * i) + 3); 2722 } 2723 break; 2724 case sw::FORMAT_A16B16G16R16F: 2725 { 2726 r = (float)*((sw::half*)(source + 8 * i) + 0); 2727 g = (float)*((sw::half*)(source + 8 * i) + 1); 2728 b = (float)*((sw::half*)(source + 8 * i) + 2); 2729 a = (float)*((sw::half*)(source + 8 * i) + 3); 2730 } 2731 break; 2732 default: 2733 UNIMPLEMENTED(); // FIXME 2734 UNREACHABLE(); 2735 } 2736 2737 switch(format) 2738 { 2739 case GL_RGBA: 2740 switch(type) 2741 { 2742 case GL_UNSIGNED_BYTE: 2743 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f); 2744 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 2745 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f); 2746 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 2747 break; 2748 default: UNREACHABLE(); 2749 } 2750 break; 2751 case GL_BGRA_EXT: 2752 switch(type) 2753 { 2754 case GL_UNSIGNED_BYTE: 2755 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f); 2756 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 2757 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f); 2758 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 2759 break; 2760 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 2761 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2762 // this type is packed as follows: 2763 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2764 // -------------------------------------------------------------------------------- 2765 // | 4th | 3rd | 2nd | 1st component | 2766 // -------------------------------------------------------------------------------- 2767 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2768 dest16[i] = 2769 ((unsigned short)(15 * a + 0.5f) << 12)| 2770 ((unsigned short)(15 * r + 0.5f) << 8) | 2771 ((unsigned short)(15 * g + 0.5f) << 4) | 2772 ((unsigned short)(15 * b + 0.5f) << 0); 2773 break; 2774 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 2775 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2776 // this type is packed as follows: 2777 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2778 // -------------------------------------------------------------------------------- 2779 // | 4th | 3rd | 2nd | 1st component | 2780 // -------------------------------------------------------------------------------- 2781 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2782 dest16[i] = 2783 ((unsigned short)( a + 0.5f) << 15) | 2784 ((unsigned short)(31 * r + 0.5f) << 10) | 2785 ((unsigned short)(31 * g + 0.5f) << 5) | 2786 ((unsigned short)(31 * b + 0.5f) << 0); 2787 break; 2788 default: UNREACHABLE(); 2789 } 2790 break; 2791 case GL_RGB: 2792 switch(type) 2793 { 2794 case GL_UNSIGNED_SHORT_5_6_5: 2795 dest16[i] = 2796 ((unsigned short)(31 * b + 0.5f) << 0) | 2797 ((unsigned short)(63 * g + 0.5f) << 5) | 2798 ((unsigned short)(31 * r + 0.5f) << 11); 2799 break; 2800 default: UNREACHABLE(); 2801 } 2802 break; 2803 default: UNREACHABLE(); 2804 } 2805 } 2806 } 2807 2808 source += inputPitch; 2809 dest += outputPitch; 2810 } 2811 2812 renderTarget->unlock(); 2813 renderTarget->release(); 2814} 2815 2816void Context::clear(GLbitfield mask) 2817{ 2818 Framebuffer *framebuffer = getDrawFramebuffer(); 2819 2820 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 2821 { 2822 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2823 } 2824 2825 if(!applyRenderTarget()) 2826 { 2827 return; 2828 } 2829 2830 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 2831 (unorm<8>(mState.colorClearValue.red) << 16) | 2832 (unorm<8>(mState.colorClearValue.green) << 8) | 2833 (unorm<8>(mState.colorClearValue.blue) << 0); 2834 float depth = clamp01(mState.depthClearValue); 2835 int stencil = mState.stencilClearValue & 0x000000FF; 2836 2837 if(mask & GL_COLOR_BUFFER_BIT) 2838 { 2839 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2840 (mState.colorMaskGreen ? 0x2 : 0) | 2841 (mState.colorMaskBlue ? 0x4 : 0) | 2842 (mState.colorMaskAlpha ? 0x8 : 0); 2843 2844 if(rgbaMask != 0) 2845 { 2846 device->clearColor(color, rgbaMask); 2847 } 2848 } 2849 2850 if(mask & GL_DEPTH_BUFFER_BIT) 2851 { 2852 if(mState.depthMask != 0) 2853 { 2854 device->clearDepth(depth); 2855 } 2856 } 2857 2858 if(mask & GL_STENCIL_BUFFER_BIT) 2859 { 2860 if(mState.stencilWritemask != 0) 2861 { 2862 device->clearStencil(stencil, mState.stencilWritemask); 2863 } 2864 } 2865} 2866 2867void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2868{ 2869 if(!mState.currentProgram) 2870 { 2871 return error(GL_INVALID_OPERATION); 2872 } 2873 2874 PrimitiveType primitiveType; 2875 int primitiveCount; 2876 2877 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2878 return error(GL_INVALID_ENUM); 2879 2880 if(primitiveCount <= 0) 2881 { 2882 return; 2883 } 2884 2885 if(!applyRenderTarget()) 2886 { 2887 return; 2888 } 2889 2890 applyState(mode); 2891 2892 GLenum err = applyVertexBuffer(0, first, count); 2893 if(err != GL_NO_ERROR) 2894 { 2895 return error(err); 2896 } 2897 2898 applyShaders(); 2899 applyTextures(); 2900 2901 if(!getCurrentProgram()->validateSamplers(false)) 2902 { 2903 return error(GL_INVALID_OPERATION); 2904 } 2905 2906 if(!cullSkipsDraw(mode)) 2907 { 2908 device->drawPrimitive(primitiveType, primitiveCount); 2909 } 2910} 2911 2912void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2913{ 2914 if(!mState.currentProgram) 2915 { 2916 return error(GL_INVALID_OPERATION); 2917 } 2918 2919 if(!indices && !mState.elementArrayBuffer) 2920 { 2921 return error(GL_INVALID_OPERATION); 2922 } 2923 2924 PrimitiveType primitiveType; 2925 int primitiveCount; 2926 2927 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2928 return error(GL_INVALID_ENUM); 2929 2930 if(primitiveCount <= 0) 2931 { 2932 return; 2933 } 2934 2935 if(!applyRenderTarget()) 2936 { 2937 return; 2938 } 2939 2940 applyState(mode); 2941 2942 TranslatedIndexData indexInfo; 2943 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2944 if(err != GL_NO_ERROR) 2945 { 2946 return error(err); 2947 } 2948 2949 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2950 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2951 if(err != GL_NO_ERROR) 2952 { 2953 return error(err); 2954 } 2955 2956 applyShaders(); 2957 applyTextures(); 2958 2959 if(!getCurrentProgram()->validateSamplers(false)) 2960 { 2961 return error(GL_INVALID_OPERATION); 2962 } 2963 2964 if(!cullSkipsDraw(mode)) 2965 { 2966 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2967 } 2968} 2969 2970void Context::finish() 2971{ 2972 device->finish(); 2973} 2974 2975void Context::flush() 2976{ 2977 // We don't queue anything without processing it as fast as possible 2978} 2979 2980void Context::recordInvalidEnum() 2981{ 2982 mInvalidEnum = true; 2983} 2984 2985void Context::recordInvalidValue() 2986{ 2987 mInvalidValue = true; 2988} 2989 2990void Context::recordInvalidOperation() 2991{ 2992 mInvalidOperation = true; 2993} 2994 2995void Context::recordOutOfMemory() 2996{ 2997 mOutOfMemory = true; 2998} 2999 3000void Context::recordInvalidFramebufferOperation() 3001{ 3002 mInvalidFramebufferOperation = true; 3003} 3004 3005// Get one of the recorded errors and clear its flag, if any. 3006// [OpenGL ES 2.0.24] section 2.5 page 13. 3007GLenum Context::getError() 3008{ 3009 if(mInvalidEnum) 3010 { 3011 mInvalidEnum = false; 3012 3013 return GL_INVALID_ENUM; 3014 } 3015 3016 if(mInvalidValue) 3017 { 3018 mInvalidValue = false; 3019 3020 return GL_INVALID_VALUE; 3021 } 3022 3023 if(mInvalidOperation) 3024 { 3025 mInvalidOperation = false; 3026 3027 return GL_INVALID_OPERATION; 3028 } 3029 3030 if(mOutOfMemory) 3031 { 3032 mOutOfMemory = false; 3033 3034 return GL_OUT_OF_MEMORY; 3035 } 3036 3037 if(mInvalidFramebufferOperation) 3038 { 3039 mInvalidFramebufferOperation = false; 3040 3041 return GL_INVALID_FRAMEBUFFER_OPERATION; 3042 } 3043 3044 return GL_NO_ERROR; 3045} 3046 3047int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 3048{ 3049 if(requested <= 1) 3050 { 3051 return 1; 3052 } 3053 3054 if(requested == 2) 3055 { 3056 return 2; 3057 } 3058 3059 return 4; 3060} 3061 3062void Context::detachBuffer(GLuint buffer) 3063{ 3064 // [OpenGL ES 2.0.24] section 2.9 page 22: 3065 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 3066 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 3067 3068 if(mState.arrayBuffer.name() == buffer) 3069 { 3070 mState.arrayBuffer = NULL; 3071 } 3072 3073 if(mState.elementArrayBuffer.name() == buffer) 3074 { 3075 mState.elementArrayBuffer = NULL; 3076 } 3077 3078 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 3079 { 3080 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer) 3081 { 3082 mState.vertexAttribute[attribute].mBoundBuffer = NULL; 3083 } 3084 } 3085} 3086 3087void Context::detachTexture(GLuint texture) 3088{ 3089 // [OpenGL ES 2.0.24] section 3.8 page 84: 3090 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 3091 // rebound to texture object zero 3092 3093 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 3094 { 3095 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 3096 { 3097 if(mState.samplerTexture[type][sampler].name() == texture) 3098 { 3099 mState.samplerTexture[type][sampler] = NULL; 3100 } 3101 } 3102 } 3103 3104 // [OpenGL ES 2.0.24] section 4.4 page 112: 3105 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 3106 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 3107 // image was attached in the currently bound framebuffer. 3108 3109 Framebuffer *readFramebuffer = getReadFramebuffer(); 3110 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3111 3112 if(readFramebuffer) 3113 { 3114 readFramebuffer->detachTexture(texture); 3115 } 3116 3117 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3118 { 3119 drawFramebuffer->detachTexture(texture); 3120 } 3121} 3122 3123void Context::detachFramebuffer(GLuint framebuffer) 3124{ 3125 // [OpenGL ES 2.0.24] section 4.4 page 107: 3126 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 3127 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 3128 3129 if(mState.readFramebuffer == framebuffer) 3130 { 3131 bindReadFramebuffer(0); 3132 } 3133 3134 if(mState.drawFramebuffer == framebuffer) 3135 { 3136 bindDrawFramebuffer(0); 3137 } 3138} 3139 3140void Context::detachRenderbuffer(GLuint renderbuffer) 3141{ 3142 // [OpenGL ES 2.0.24] section 4.4 page 109: 3143 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 3144 // had been executed with the target RENDERBUFFER and name of zero. 3145 3146 if(mState.renderbuffer.name() == renderbuffer) 3147 { 3148 bindRenderbuffer(0); 3149 } 3150 3151 // [OpenGL ES 2.0.24] section 4.4 page 111: 3152 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 3153 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 3154 // point to which this image was attached in the currently bound framebuffer. 3155 3156 Framebuffer *readFramebuffer = getReadFramebuffer(); 3157 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3158 3159 if(readFramebuffer) 3160 { 3161 readFramebuffer->detachRenderbuffer(renderbuffer); 3162 } 3163 3164 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3165 { 3166 drawFramebuffer->detachRenderbuffer(renderbuffer); 3167 } 3168} 3169 3170bool Context::cullSkipsDraw(GLenum drawMode) 3171{ 3172 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 3173} 3174 3175bool Context::isTriangleMode(GLenum drawMode) 3176{ 3177 switch (drawMode) 3178 { 3179 case GL_TRIANGLES: 3180 case GL_TRIANGLE_FAN: 3181 case GL_TRIANGLE_STRIP: 3182 return true; 3183 case GL_POINTS: 3184 case GL_LINES: 3185 case GL_LINE_LOOP: 3186 case GL_LINE_STRIP: 3187 return false; 3188 default: UNREACHABLE(); 3189 } 3190 3191 return false; 3192} 3193 3194void Context::setVertexAttrib(GLuint index, const GLfloat *values) 3195{ 3196 ASSERT(index < MAX_VERTEX_ATTRIBS); 3197 3198 mState.vertexAttribute[index].mCurrentValue[0] = values[0]; 3199 mState.vertexAttribute[index].mCurrentValue[1] = values[1]; 3200 mState.vertexAttribute[index].mCurrentValue[2] = values[2]; 3201 mState.vertexAttribute[index].mCurrentValue[3] = values[3]; 3202 3203 mVertexDataManager->dirtyCurrentValue(index); 3204} 3205 3206void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 3207 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 3208 GLbitfield mask) 3209{ 3210 Framebuffer *readFramebuffer = getReadFramebuffer(); 3211 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3212 3213 int readBufferWidth, readBufferHeight, readBufferSamples; 3214 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 3215 3216 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 3217 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 3218 { 3219 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3220 } 3221 3222 if(drawBufferSamples > 1) 3223 { 3224 return error(GL_INVALID_OPERATION); 3225 } 3226 3227 sw::SliceRect sourceRect; 3228 sw::SliceRect destRect; 3229 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1); 3230 bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1); 3231 3232 if(srcX0 < srcX1) 3233 { 3234 sourceRect.x0 = srcX0; 3235 sourceRect.x1 = srcX1; 3236 } 3237 else 3238 { 3239 sourceRect.x0 = srcX1; 3240 sourceRect.x1 = srcX0; 3241 } 3242 3243 if(dstX0 < dstX1) 3244 { 3245 destRect.x0 = dstX0; 3246 destRect.x1 = dstX1; 3247 } 3248 else 3249 { 3250 destRect.x0 = dstX1; 3251 destRect.x1 = dstX0; 3252 } 3253 3254 if(srcY0 < srcY1) 3255 { 3256 sourceRect.y0 = srcY0; 3257 sourceRect.y1 = srcY1; 3258 } 3259 else 3260 { 3261 sourceRect.y0 = srcY1; 3262 sourceRect.y1 = srcY0; 3263 } 3264 3265 if(dstY0 < dstY1) 3266 { 3267 destRect.y0 = dstY0; 3268 destRect.y1 = dstY1; 3269 } 3270 else 3271 { 3272 destRect.y0 = dstY1; 3273 destRect.y1 = dstY0; 3274 } 3275 3276 sw::Rect sourceScissoredRect = sourceRect; 3277 sw::Rect destScissoredRect = destRect; 3278 3279 if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test 3280 { 3281 if(destRect.x0 < mState.scissorX) 3282 { 3283 int xDiff = mState.scissorX - destRect.x0; 3284 destScissoredRect.x0 = mState.scissorX; 3285 sourceScissoredRect.x0 += xDiff; 3286 } 3287 3288 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 3289 { 3290 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 3291 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 3292 sourceScissoredRect.x1 -= xDiff; 3293 } 3294 3295 if(destRect.y0 < mState.scissorY) 3296 { 3297 int yDiff = mState.scissorY - destRect.y0; 3298 destScissoredRect.y0 = mState.scissorY; 3299 sourceScissoredRect.y0 += yDiff; 3300 } 3301 3302 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 3303 { 3304 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 3305 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 3306 sourceScissoredRect.y1 -= yDiff; 3307 } 3308 } 3309 3310 sw::Rect sourceTrimmedRect = sourceScissoredRect; 3311 sw::Rect destTrimmedRect = destScissoredRect; 3312 3313 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 3314 // the actual draw and read surfaces. 3315 if(sourceTrimmedRect.x0 < 0) 3316 { 3317 int xDiff = 0 - sourceTrimmedRect.x0; 3318 sourceTrimmedRect.x0 = 0; 3319 destTrimmedRect.x0 += xDiff; 3320 } 3321 3322 if(sourceTrimmedRect.x1 > readBufferWidth) 3323 { 3324 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 3325 sourceTrimmedRect.x1 = readBufferWidth; 3326 destTrimmedRect.x1 -= xDiff; 3327 } 3328 3329 if(sourceTrimmedRect.y0 < 0) 3330 { 3331 int yDiff = 0 - sourceTrimmedRect.y0; 3332 sourceTrimmedRect.y0 = 0; 3333 destTrimmedRect.y0 += yDiff; 3334 } 3335 3336 if(sourceTrimmedRect.y1 > readBufferHeight) 3337 { 3338 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 3339 sourceTrimmedRect.y1 = readBufferHeight; 3340 destTrimmedRect.y1 -= yDiff; 3341 } 3342 3343 if(destTrimmedRect.x0 < 0) 3344 { 3345 int xDiff = 0 - destTrimmedRect.x0; 3346 destTrimmedRect.x0 = 0; 3347 sourceTrimmedRect.x0 += xDiff; 3348 } 3349 3350 if(destTrimmedRect.x1 > drawBufferWidth) 3351 { 3352 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 3353 destTrimmedRect.x1 = drawBufferWidth; 3354 sourceTrimmedRect.x1 -= xDiff; 3355 } 3356 3357 if(destTrimmedRect.y0 < 0) 3358 { 3359 int yDiff = 0 - destTrimmedRect.y0; 3360 destTrimmedRect.y0 = 0; 3361 sourceTrimmedRect.y0 += yDiff; 3362 } 3363 3364 if(destTrimmedRect.y1 > drawBufferHeight) 3365 { 3366 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 3367 destTrimmedRect.y1 = drawBufferHeight; 3368 sourceTrimmedRect.y1 -= yDiff; 3369 } 3370 3371 bool partialBufferCopy = false; 3372 3373 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 3374 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 3375 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 3376 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 3377 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 3378 { 3379 partialBufferCopy = true; 3380 } 3381 3382 bool blitRenderTarget = false; 3383 bool blitDepthStencil = false; 3384 3385 if(mask & GL_COLOR_BUFFER_BIT) 3386 { 3387 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3388 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3389 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 3390 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 3391 if(!validReadType || !validDrawType) 3392 { 3393 return error(GL_INVALID_OPERATION); 3394 } 3395 3396 if(partialBufferCopy && readBufferSamples > 1) 3397 { 3398 return error(GL_INVALID_OPERATION); 3399 } 3400 3401 blitRenderTarget = true; 3402 } 3403 3404 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 3405 { 3406 Renderbuffer *readDSBuffer = NULL; 3407 Renderbuffer *drawDSBuffer = NULL; 3408 3409 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 3410 // both a depth and stencil buffer, it will be the same buffer. 3411 3412 if(mask & GL_DEPTH_BUFFER_BIT) 3413 { 3414 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 3415 { 3416 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType()) 3417 { 3418 return error(GL_INVALID_OPERATION); 3419 } 3420 3421 blitDepthStencil = true; 3422 readDSBuffer = readFramebuffer->getDepthbuffer(); 3423 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 3424 } 3425 } 3426 3427 if(mask & GL_STENCIL_BUFFER_BIT) 3428 { 3429 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 3430 { 3431 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType()) 3432 { 3433 return error(GL_INVALID_OPERATION); 3434 } 3435 3436 blitDepthStencil = true; 3437 readDSBuffer = readFramebuffer->getStencilbuffer(); 3438 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 3439 } 3440 } 3441 3442 if(partialBufferCopy) 3443 { 3444 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 3445 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 3446 } 3447 3448 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 3449 (readDSBuffer && readDSBuffer->getSamples() > 1)) 3450 { 3451 return error(GL_INVALID_OPERATION); 3452 } 3453 } 3454 3455 if(blitRenderTarget || blitDepthStencil) 3456 { 3457 if(blitRenderTarget) 3458 { 3459 egl::Image *readRenderTarget = readFramebuffer->getRenderTarget(); 3460 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); 3461 3462 if(flipX) 3463 { 3464 swap(destRect.x0, destRect.x1); 3465 } 3466 if(flipy) 3467 { 3468 swap(destRect.y0, destRect.y1); 3469 } 3470 3471 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 3472 3473 readRenderTarget->release(); 3474 drawRenderTarget->release(); 3475 3476 if(!success) 3477 { 3478 ERR("BlitFramebuffer failed."); 3479 return; 3480 } 3481 } 3482 3483 if(blitDepthStencil) 3484 { 3485 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false); 3486 3487 if(!success) 3488 { 3489 ERR("BlitFramebuffer failed."); 3490 return; 3491 } 3492 } 3493 } 3494} 3495 3496void Context::bindTexImage(egl::Surface *surface) 3497{ 3498 es2::Texture2D *textureObject = getTexture2D(); 3499 3500 if(textureObject) 3501 { 3502 textureObject->bindTexImage(surface); 3503 } 3504} 3505 3506EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3507{ 3508 GLenum textureTarget = GL_NONE; 3509 3510 switch(target) 3511 { 3512 case EGL_GL_TEXTURE_2D_KHR: 3513 textureTarget = GL_TEXTURE_2D; 3514 break; 3515 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 3516 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 3517 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 3518 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 3519 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 3520 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 3521 textureTarget = GL_TEXTURE_CUBE_MAP; 3522 break; 3523 case EGL_GL_RENDERBUFFER_KHR: 3524 break; 3525 default: 3526 return EGL_BAD_PARAMETER; 3527 } 3528 3529 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 3530 { 3531 return EGL_BAD_MATCH; 3532 } 3533 3534 if(textureTarget != GL_NONE) 3535 { 3536 es2::Texture *texture = getTexture(name); 3537 3538 if(!texture || texture->getTarget() != textureTarget) 3539 { 3540 return EGL_BAD_PARAMETER; 3541 } 3542 3543 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 3544 { 3545 return EGL_BAD_ACCESS; 3546 } 3547 3548 if(textureLevel != 0 && !texture->isSamplerComplete()) 3549 { 3550 return EGL_BAD_PARAMETER; 3551 } 3552 3553 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 3554 { 3555 return EGL_BAD_PARAMETER; 3556 } 3557 } 3558 else if(target == EGL_GL_RENDERBUFFER_KHR) 3559 { 3560 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3561 3562 if(!renderbuffer) 3563 { 3564 return EGL_BAD_PARAMETER; 3565 } 3566 3567 if(renderbuffer->isShared()) // Already an EGLImage sibling 3568 { 3569 return EGL_BAD_ACCESS; 3570 } 3571 } 3572 else UNREACHABLE(); 3573 3574 return EGL_SUCCESS; 3575} 3576 3577egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 3578{ 3579 GLenum textureTarget = GL_NONE; 3580 3581 switch(target) 3582 { 3583 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break; 3584 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; 3585 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; 3586 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; 3587 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; 3588 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; 3589 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; 3590 } 3591 3592 if(textureTarget != GL_NONE) 3593 { 3594 es2::Texture *texture = getTexture(name); 3595 3596 return texture->createSharedImage(textureTarget, textureLevel); 3597 } 3598 else if(target == EGL_GL_RENDERBUFFER_KHR) 3599 { 3600 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 3601 3602 return renderbuffer->createSharedImage(); 3603 } 3604 else UNREACHABLE(); 3605 3606 return 0; 3607} 3608 3609Device *Context::getDevice() 3610{ 3611 return device; 3612} 3613 3614} 3615 3616// Exported functions for use by EGL 3617extern "C" 3618{ 3619 es2::Context *glCreateContext(const egl::Config *config, const es2::Context *shareContext, int clientVersion) 3620 { 3621 return new es2::Context(config, shareContext, clientVersion); 3622 } 3623} 3624