1 /* 2 * Copyright 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <GLcommon/GLEScontext.h> 18 #include <GLcommon/GLconversion_macros.h> 19 #include <GLcommon/GLESmacros.h> 20 #include <GLES/gl.h> 21 #include <GLES/glext.h> 22 #include <GLcommon/GLESvalidate.h> 23 #include <GLcommon/TextureUtils.h> 24 #include <GLcommon/FramebufferData.h> 25 #include <strings.h> 26 27 //decleration 28 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize); 29 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize); 30 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize); 31 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize); 32 33 GLESConversionArrays::~GLESConversionArrays() { 34 for(std::map<GLenum,ArrayData>::iterator it = m_arrays.begin(); it != m_arrays.end();it++) { 35 if((*it).second.allocated){ 36 if((*it).second.type == GL_FLOAT){ 37 GLfloat* p = (GLfloat *)((*it).second.data); 38 if(p) delete[] p; 39 } else if((*it).second.type == GL_SHORT){ 40 GLshort* p = (GLshort *)((*it).second.data); 41 if(p) delete[] p; 42 } 43 } 44 } 45 } 46 47 void GLESConversionArrays::allocArr(unsigned int size,GLenum type){ 48 if(type == GL_FIXED){ 49 m_arrays[m_current].data = new GLfloat[size]; 50 m_arrays[m_current].type = GL_FLOAT; 51 } else if(type == GL_BYTE){ 52 m_arrays[m_current].data = new GLshort[size]; 53 m_arrays[m_current].type = GL_SHORT; 54 } 55 m_arrays[m_current].stride = 0; 56 m_arrays[m_current].allocated = true; 57 } 58 59 void GLESConversionArrays::setArr(void* data,unsigned int stride,GLenum type){ 60 m_arrays[m_current].type = type; 61 m_arrays[m_current].data = data; 62 m_arrays[m_current].stride = stride; 63 m_arrays[m_current].allocated = false; 64 } 65 66 void* GLESConversionArrays::getCurrentData(){ 67 return m_arrays[m_current].data; 68 } 69 70 ArrayData& GLESConversionArrays::getCurrentArray(){ 71 return m_arrays[m_current]; 72 } 73 74 unsigned int GLESConversionArrays::getCurrentIndex(){ 75 return m_current; 76 } 77 78 ArrayData& GLESConversionArrays::operator[](int i){ 79 return m_arrays[i]; 80 } 81 82 void GLESConversionArrays::operator++(){ 83 m_current++; 84 } 85 86 GLDispatch GLEScontext::s_glDispatch; 87 android::Mutex GLEScontext::s_lock; 88 std::string* GLEScontext::s_glExtensions= NULL; 89 std::string GLEScontext::s_glVendor; 90 std::string GLEScontext::s_glRenderer; 91 std::string GLEScontext::s_glVersion; 92 GLSupport GLEScontext::s_glSupport; 93 94 Version::Version():m_major(0), 95 m_minor(0), 96 m_release(0){}; 97 98 Version::Version(int major,int minor,int release):m_major(major), 99 m_minor(minor), 100 m_release(release){}; 101 102 Version::Version(const Version& ver):m_major(ver.m_major), 103 m_minor(ver.m_minor), 104 m_release(ver.m_release){} 105 106 Version::Version(const char* versionString){ 107 m_release = 0; 108 if((!versionString) || 109 ((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) && 110 (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){ 111 m_major = m_minor = 0; // the version is not in the right format 112 } 113 } 114 115 Version& Version::operator=(const Version& ver){ 116 m_major = ver.m_major; 117 m_minor = ver.m_minor; 118 m_release = ver.m_release; 119 return *this; 120 } 121 122 bool Version::operator<(const Version& ver) const{ 123 if(m_major < ver.m_major) return true; 124 if(m_major == ver.m_major){ 125 if(m_minor < ver.m_minor) return true; 126 if(m_minor == ver.m_minor){ 127 return m_release < ver.m_release; 128 } 129 } 130 return false; 131 } 132 133 void GLEScontext::init() { 134 135 if (!s_glExtensions) { 136 initCapsLocked(s_glDispatch.glGetString(GL_EXTENSIONS)); 137 s_glExtensions = new std::string(""); 138 } 139 140 if (!m_initialized) { 141 initExtensionString(); 142 143 int maxTexUnits = getMaxTexUnits(); 144 m_texState = new textureUnitState[maxTexUnits]; 145 for (int i=0;i<maxTexUnits;++i) { 146 for (int j=0;j<NUM_TEXTURE_TARGETS;++j) 147 { 148 m_texState[i][j].texture = 0; 149 m_texState[i][j].enabled = GL_FALSE; 150 } 151 } 152 } 153 } 154 155 GLEScontext::GLEScontext(): 156 m_initialized(false) , 157 m_activeTexture(0) , 158 m_unpackAlignment(4) , 159 m_glError(GL_NO_ERROR) , 160 m_texState(0) , 161 m_arrayBuffer(0) , 162 m_elementBuffer(0), 163 m_renderbuffer(0), 164 m_framebuffer(0) 165 { 166 }; 167 168 GLenum GLEScontext::getGLerror() { 169 return m_glError; 170 } 171 172 void GLEScontext::setGLerror(GLenum err) { 173 m_glError = err; 174 } 175 176 void GLEScontext::setActiveTexture(GLenum tex) { 177 m_activeTexture = tex - GL_TEXTURE0; 178 } 179 180 GLEScontext::~GLEScontext() { 181 for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) { 182 GLESpointer* p = (*it).second; 183 if(p) { 184 delete p; 185 } 186 } 187 delete[] m_texState; 188 m_texState = NULL; 189 } 190 191 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data,bool normalize) { 192 GLuint bufferName = m_arrayBuffer; 193 if(bufferName) { 194 unsigned int offset = ToTargetCompatibleHandle((uintptr_t)data); 195 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 196 m_map[arrType]->setBuffer(size,type,stride,vbo,bufferName,offset,normalize); 197 return static_cast<const unsigned char*>(vbo->getData()) + offset; 198 } 199 m_map[arrType]->setArray(size,type,stride,data,normalize); 200 return data; 201 } 202 203 void GLEScontext::enableArr(GLenum arr,bool enable) { 204 m_map[arr]->enable(enable); 205 } 206 207 bool GLEScontext::isArrEnabled(GLenum arr) { 208 return m_map[arr]->isEnable(); 209 } 210 211 const GLESpointer* GLEScontext::getPointer(GLenum arrType) { 212 if (m_map.find(arrType) != m_map.end()) return m_map[arrType]; 213 return NULL; 214 } 215 216 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) { 217 218 for(unsigned int i = 0; i < nBytes;i+=strideOut) { 219 const GLfixed* fixed_data = (const GLfixed *)dataIn; 220 //filling attrib 221 for(int j=0;j<attribSize;j++) { 222 reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]); 223 } 224 dataIn += strideIn; 225 } 226 } 227 228 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) { 229 for(int i = 0 ;i < count ;i++) { 230 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]: 231 ((GLushort *)indices)[i]; 232 const GLfixed* fixed_data = (GLfixed *)(dataIn + index*strideIn); 233 GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut); 234 235 for(int j=0;j<attribSize;j++) { 236 float_data[j] = X2F(fixed_data[j]); 237 } 238 } 239 } 240 241 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) { 242 243 for(unsigned int i = 0; i < nBytes;i+=strideOut) { 244 const GLbyte* byte_data = (const GLbyte *)dataIn; 245 //filling attrib 246 for(int j=0;j<attribSize;j++) { 247 reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]); 248 } 249 dataIn += strideIn; 250 } 251 } 252 253 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) { 254 for(int i = 0 ;i < count ;i++) { 255 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]: 256 ((GLushort *)indices)[i]; 257 const GLbyte* bytes_data = (GLbyte *)(dataIn + index*strideIn); 258 GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut); 259 260 for(int j=0;j<attribSize;j++) { 261 short_data[j] = B2S(bytes_data[j]); 262 } 263 } 264 } 265 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) { 266 267 int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes 268 int stride = p->getStride()?p->getStride():attribSize; 269 int start = p->getBufferOffset()+first*attribSize; 270 if(!p->getStride()) { 271 list.addRange(Range(start,count*attribSize)); 272 } else { 273 for(int i = 0 ;i < count; i++,start+=stride) { 274 list.addRange(Range(start,attribSize)); 275 } 276 } 277 } 278 279 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) { 280 281 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes 282 int stride = p->getStride()?p->getStride():attribSize; 283 int start = p->getBufferOffset(); 284 for(int i=0 ; i < count; i++) { 285 GLushort index = (indices_type == GL_UNSIGNED_SHORT? 286 static_cast<const GLushort*>(indices)[i]: 287 static_cast<const GLubyte*>(indices)[i]); 288 list.addRange(Range(start+index*stride,attribSize)); 289 290 } 291 } 292 293 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) { 294 295 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes 296 int stride = p->getStride()?p->getStride():attribSize; 297 int offset = p->getBufferOffset(); 298 299 int n = 0; 300 for(int i=0;i<ranges.size();i++) { 301 int startIndex = (ranges[i].getStart() - offset) / stride; 302 int nElements = ranges[i].getSize()/attribSize; 303 for(int j=0;j<nElements;j++) { 304 indices[n++] = startIndex+j; 305 } 306 } 307 return n; 308 } 309 310 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) { 311 312 GLenum type = p->getType(); 313 int attribSize = p->getSize(); 314 unsigned int size = attribSize*count + first; 315 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte); 316 cArrs.allocArr(size,type); 317 int stride = p->getStride()?p->getStride():bytes*attribSize; 318 const char* data = (const char*)p->getArrayData() + (first*stride); 319 320 if(type == GL_FIXED) { 321 convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize); 322 } else if(type == GL_BYTE) { 323 convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize); 324 } 325 } 326 327 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) { 328 329 RangeList ranges; 330 RangeList conversions; 331 GLushort* indices = NULL; 332 GLenum type = p->getType(); 333 int attribSize = p->getSize(); 334 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; 335 unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed); 336 char* data = (char*)p->getBufferData() + (first*stride); 337 338 if(p->bufferNeedConversion()) { 339 directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset 340 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted 341 342 if(conversions.size()) { // there are some elements to convert 343 indices = new GLushort[count]; 344 int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array 345 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize); 346 } 347 } 348 if(indices) delete[] indices; 349 cArrs.setArr(data,p->getStride(),GL_FLOAT); 350 } 351 352 int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) { 353 //finding max index 354 int max = 0; 355 if(type == GL_UNSIGNED_BYTE) { 356 GLubyte* b_indices =(GLubyte *)indices; 357 for(int i=0;i<count;i++) { 358 if(b_indices[i] > max) max = b_indices[i]; 359 } 360 } else { 361 GLushort* us_indices =(GLushort *)indices; 362 for(int i=0;i<count;i++) { 363 if(us_indices[i] > max) max = us_indices[i]; 364 } 365 } 366 return max; 367 } 368 369 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { 370 GLenum type = p->getType(); 371 int maxElements = findMaxIndex(count,type,indices) + 1; 372 373 int attribSize = p->getSize(); 374 int size = attribSize * maxElements; 375 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte); 376 cArrs.allocArr(size,type); 377 int stride = p->getStride()?p->getStride():bytes*attribSize; 378 379 const char* data = (const char*)p->getArrayData(); 380 if(type == GL_FIXED) { 381 convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize); 382 } else if(type == GL_BYTE){ 383 convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize); 384 } 385 } 386 387 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { 388 RangeList ranges; 389 RangeList conversions; 390 GLushort* conversionIndices = NULL; 391 GLenum type = p->getType(); 392 int attribSize = p->getSize(); 393 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; 394 char* data = static_cast<char*>(p->getBufferData()); 395 if(p->bufferNeedConversion()) { 396 indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset 397 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted 398 if(conversions.size()) { // there are some elements to convert 399 conversionIndices = new GLushort[count]; 400 int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array 401 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,conversionIndices,stride,attribSize); 402 } 403 } 404 if(conversionIndices) delete[] conversionIndices; 405 cArrs.setArr(data,p->getStride(),GL_FLOAT); 406 } 407 408 409 410 void GLEScontext::bindBuffer(GLenum target,GLuint buffer) { 411 if(target == GL_ARRAY_BUFFER) { 412 m_arrayBuffer = buffer; 413 } else { 414 m_elementBuffer = buffer; 415 } 416 } 417 418 void GLEScontext::unbindBuffer(GLuint buffer) { 419 if(m_arrayBuffer == buffer) 420 { 421 m_arrayBuffer = 0; 422 } 423 if(m_elementBuffer == buffer) 424 { 425 m_elementBuffer = 0; 426 } 427 } 428 429 //checks if any buffer is binded to target 430 bool GLEScontext::isBindedBuffer(GLenum target) { 431 if(target == GL_ARRAY_BUFFER) { 432 return m_arrayBuffer != 0; 433 } else { 434 return m_elementBuffer != 0; 435 } 436 } 437 438 GLuint GLEScontext::getBuffer(GLenum target) { 439 return target == GL_ARRAY_BUFFER ? m_arrayBuffer:m_elementBuffer; 440 } 441 442 GLvoid* GLEScontext::getBindedBuffer(GLenum target) { 443 GLuint bufferName = getBuffer(target); 444 if(!bufferName) return NULL; 445 446 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 447 return vbo->getData(); 448 } 449 450 void GLEScontext::getBufferSize(GLenum target,GLint* param) { 451 GLuint bufferName = getBuffer(target); 452 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 453 *param = vbo->getSize(); 454 } 455 456 void GLEScontext::getBufferUsage(GLenum target,GLint* param) { 457 GLuint bufferName = getBuffer(target); 458 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 459 *param = vbo->getUsage(); 460 } 461 462 bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) { 463 GLuint bufferName = getBuffer(target); 464 if(!bufferName) return false; 465 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 466 return vbo->setBuffer(size,usage,data); 467 } 468 469 bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) { 470 471 GLuint bufferName = getBuffer(target); 472 if(!bufferName) return false; 473 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 474 return vbo->setSubBuffer(offset,size,data); 475 } 476 477 const char * GLEScontext::getExtensionString() { 478 const char * ret; 479 s_lock.lock(); 480 if (s_glExtensions) 481 ret = s_glExtensions->c_str(); 482 else 483 ret=""; 484 s_lock.unlock(); 485 return ret; 486 } 487 488 const char * GLEScontext::getVendorString() const { 489 return s_glVendor.c_str(); 490 } 491 492 const char * GLEScontext::getRendererString() const { 493 return s_glRenderer.c_str(); 494 } 495 496 const char * GLEScontext::getVersionString() const { 497 return s_glVersion.c_str(); 498 } 499 500 void GLEScontext::getGlobalLock() { 501 s_lock.lock(); 502 } 503 504 void GLEScontext::releaseGlobalLock() { 505 s_lock.unlock(); 506 } 507 508 509 void GLEScontext::initCapsLocked(const GLubyte * extensionString) 510 { 511 const char* cstring = (const char*)extensionString; 512 513 s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs); 514 s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane); 515 s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights); 516 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize); 517 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits); 518 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits); 519 const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION); 520 s_glSupport.glslVersion = Version((const char*)(glslVersion)); 521 522 if (strstr(cstring,"GL_EXT_bgra ")!=NULL) 523 s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true; 524 525 if (strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL) 526 s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true; 527 528 if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL) 529 s_glSupport.GL_ARB_VERTEX_BLEND = true; 530 531 if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL) 532 s_glSupport.GL_ARB_MATRIX_PALETTE = true; 533 534 if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL ) 535 s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true; 536 537 if (strstr(cstring,"GL_OES_read_format ")!=NULL) 538 s_glSupport.GL_OES_READ_FORMAT = true; 539 540 if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL) 541 s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true; 542 543 if (strstr(cstring,"GL_NV_half_float ")!=NULL) 544 s_glSupport.GL_NV_HALF_FLOAT = true; 545 546 if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL) 547 s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true; 548 549 if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL) 550 s_glSupport.GL_SGIS_GENERATE_MIPMAP = true; 551 552 if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL) 553 s_glSupport.GL_ARB_ES2_COMPATIBILITY = true; 554 555 if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL) 556 s_glSupport.GL_OES_STANDARD_DERIVATIVES = true; 557 558 } 559 560 void GLEScontext::buildStrings(const char* baseVendor, 561 const char* baseRenderer, const char* baseVersion, const char* version) 562 { 563 static const char VENDOR[] = {"Google ("}; 564 static const char RENDERER[] = {"Android Emulator OpenGL ES Translator ("}; 565 const size_t VENDOR_LEN = sizeof(VENDOR) - 1; 566 const size_t RENDERER_LEN = sizeof(RENDERER) - 1; 567 568 size_t baseVendorLen = strlen(baseVendor); 569 s_glVendor.clear(); 570 s_glVendor.reserve(baseVendorLen + VENDOR_LEN + 1); 571 s_glVendor.append(VENDOR, VENDOR_LEN); 572 s_glVendor.append(baseVendor, baseVendorLen); 573 s_glVendor.append(")", 1); 574 575 size_t baseRendererLen = strlen(baseRenderer); 576 s_glRenderer.clear(); 577 s_glRenderer.reserve(baseRendererLen + RENDERER_LEN + 1); 578 s_glRenderer.append(RENDERER, RENDERER_LEN); 579 s_glRenderer.append(baseRenderer, baseRendererLen); 580 s_glRenderer.append(")", 1); 581 582 size_t baseVersionLen = strlen(baseVersion); 583 size_t versionLen = strlen(version); 584 s_glVersion.clear(); 585 s_glVersion.reserve(baseVersionLen + versionLen + 3); 586 s_glVersion.append(version, versionLen); 587 s_glVersion.append(" (", 2); 588 s_glVersion.append(baseVersion, baseVersionLen); 589 s_glVersion.append(")", 1); 590 } 591 592 bool GLEScontext::isTextureUnitEnabled(GLenum unit) { 593 for (int i=0;i<NUM_TEXTURE_TARGETS;++i) { 594 if (m_texState[unit-GL_TEXTURE0][i].enabled) 595 return true; 596 } 597 return false; 598 } 599 600 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params) 601 { 602 GLint iParam; 603 604 if(glGetIntegerv(pname, &iParam)) 605 { 606 *params = (iParam != 0); 607 return true; 608 } 609 610 return false; 611 } 612 613 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params) 614 { 615 bool result = false; 616 GLint numParams = 1; 617 618 GLint* iParams = new GLint[numParams]; 619 if (numParams>0 && glGetIntegerv(pname,iParams)) { 620 while(numParams >= 0) 621 { 622 params[numParams] = I2X(iParams[numParams]); 623 numParams--; 624 } 625 result = true; 626 } 627 delete [] iParams; 628 629 return result; 630 } 631 632 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params) 633 { 634 bool result = false; 635 GLint numParams = 1; 636 637 GLint* iParams = new GLint[numParams]; 638 if (numParams>0 && glGetIntegerv(pname,iParams)) { 639 while(numParams >= 0) 640 { 641 params[numParams] = (GLfloat)iParams[numParams]; 642 numParams--; 643 } 644 result = true; 645 } 646 delete [] iParams; 647 648 return result; 649 } 650 651 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params) 652 { 653 switch(pname) 654 { 655 case GL_ARRAY_BUFFER_BINDING: 656 *params = m_arrayBuffer; 657 break; 658 659 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 660 *params = m_elementBuffer; 661 break; 662 663 case GL_TEXTURE_BINDING_CUBE_MAP: 664 *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture; 665 break; 666 667 case GL_TEXTURE_BINDING_2D: 668 *params = m_texState[m_activeTexture][TEXTURE_2D].texture; 669 break; 670 671 case GL_ACTIVE_TEXTURE: 672 *params = m_activeTexture+GL_TEXTURE0; 673 break; 674 675 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 676 *params = GL_UNSIGNED_BYTE; 677 break; 678 679 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 680 *params = GL_RGBA; 681 break; 682 default: 683 return false; 684 } 685 686 return true; 687 } 688 689 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) { 690 TextureTarget value=TEXTURE_2D; 691 switch (target) { 692 case GL_TEXTURE_CUBE_MAP: 693 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 694 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 695 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 696 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 697 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 698 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 699 value = TEXTURE_CUBE_MAP; 700 break; 701 case GL_TEXTURE_2D: 702 value = TEXTURE_2D; 703 break; 704 } 705 return value; 706 } 707 708 unsigned int GLEScontext::getBindedTexture(GLenum target) { 709 TextureTarget pos = GLTextureTargetToLocal(target); 710 return m_texState[m_activeTexture][pos].texture; 711 } 712 713 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) { 714 TextureTarget pos = GLTextureTargetToLocal(target); 715 return m_texState[unit-GL_TEXTURE0][pos].texture; 716 } 717 718 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) { 719 TextureTarget pos = GLTextureTargetToLocal(target); 720 m_texState[m_activeTexture][pos].texture = tex; 721 } 722 723 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) { 724 TextureTarget pos = GLTextureTargetToLocal(target); 725 m_texState[m_activeTexture][pos].enabled = enable; 726 } 727 728 #define INTERNAL_NAME(x) (x +0x100000000ll); 729 730 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) { 731 ObjectLocalName name = 0; 732 switch (GLTextureTargetToLocal(target)) { 733 case TEXTURE_2D: 734 name = INTERNAL_NAME(0); 735 break; 736 case TEXTURE_CUBE_MAP: 737 name = INTERNAL_NAME(1); 738 break; 739 default: 740 name = 0; 741 break; 742 } 743 return name; 744 } 745 746 void GLEScontext::drawValidate(void) 747 { 748 if(m_framebuffer == 0) 749 return; 750 751 ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer); 752 if (fbObj.Ptr() == NULL) 753 return; 754 755 FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); 756 757 fbData->validate(this); 758 } 759