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