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_glRenderer; 90 GLSupport GLEScontext::s_glSupport; 91 92 Version::Version():m_major(0), 93 m_minor(0), 94 m_release(0){}; 95 96 Version::Version(int major,int minor,int release):m_major(major), 97 m_minor(minor), 98 m_release(release){}; 99 100 Version::Version(const Version& ver):m_major(ver.m_major), 101 m_minor(ver.m_minor), 102 m_release(ver.m_release){} 103 104 Version::Version(const char* versionString){ 105 m_release = 0; 106 if((!versionString) || 107 ((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) && 108 (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){ 109 m_major = m_minor = 0; // the version is not in the right format 110 } 111 } 112 113 Version& Version::operator=(const Version& ver){ 114 m_major = ver.m_major; 115 m_minor = ver.m_minor; 116 m_release = ver.m_release; 117 return *this; 118 } 119 120 bool Version::operator<(const Version& ver) const{ 121 if(m_major < ver.m_major) return true; 122 if(m_major == ver.m_major){ 123 if(m_minor < ver.m_minor) return true; 124 if(m_minor == ver.m_minor){ 125 return m_release < ver.m_release; 126 } 127 } 128 return false; 129 } 130 131 void GLEScontext::init() { 132 133 if (!s_glExtensions) { 134 initCapsLocked(s_glDispatch.glGetString(GL_EXTENSIONS)); 135 s_glExtensions = new std::string(""); 136 } 137 138 if (!m_initialized) { 139 initExtensionString(); 140 141 int maxTexUnits = getMaxTexUnits(); 142 m_texState = new textureUnitState[maxTexUnits]; 143 for (int i=0;i<maxTexUnits;++i) { 144 for (int j=0;j<NUM_TEXTURE_TARGETS;++j) 145 { 146 m_texState[i][j].texture = 0; 147 m_texState[i][j].enabled = GL_FALSE; 148 } 149 } 150 } 151 } 152 153 GLEScontext::GLEScontext(): 154 m_initialized(false) , 155 m_activeTexture(0) , 156 m_unpackAlignment(4) , 157 m_glError(GL_NO_ERROR) , 158 m_texState(0) , 159 m_arrayBuffer(0) , 160 m_elementBuffer(0), 161 m_renderbuffer(0), 162 m_framebuffer(0) 163 { 164 }; 165 166 GLenum GLEScontext::getGLerror() { 167 return m_glError; 168 } 169 170 void GLEScontext::setGLerror(GLenum err) { 171 m_glError = err; 172 } 173 174 void GLEScontext::setActiveTexture(GLenum tex) { 175 m_activeTexture = tex - GL_TEXTURE0; 176 } 177 178 GLEScontext::~GLEScontext() { 179 for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) { 180 GLESpointer* p = (*it).second; 181 if(p) { 182 delete p; 183 } 184 } 185 delete[] m_texState; 186 m_texState = NULL; 187 } 188 189 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data,bool normalize) { 190 GLuint bufferName = m_arrayBuffer; 191 if(bufferName) { 192 unsigned int offset = ToTargetCompatibleHandle((uintptr_t)data); 193 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr()); 194 m_map[arrType]->setBuffer(size,type,stride,vbo,bufferName,offset,normalize); 195 return static_cast<const unsigned char*>(vbo->getData()) + offset; 196 } 197 m_map[arrType]->setArray(size,type,stride,data,normalize); 198 return data; 199 } 200 201 void GLEScontext::enableArr(GLenum arr,bool enable) { 202 m_map[arr]->enable(enable); 203 } 204 205 bool GLEScontext::isArrEnabled(GLenum arr) { 206 return m_map[arr]->isEnable(); 207 } 208 209 const GLESpointer* GLEScontext::getPointer(GLenum arrType) { 210 if (m_map.find(arrType) != m_map.end()) return m_map[arrType]; 211 return NULL; 212 } 213 214 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) { 215 216 for(unsigned int i = 0; i < nBytes;i+=strideOut) { 217 const GLfixed* fixed_data = (const GLfixed *)dataIn; 218 //filling attrib 219 for(int j=0;j<attribSize;j++) { 220 reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]); 221 } 222 dataIn += strideIn; 223 } 224 } 225 226 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) { 227 for(int i = 0 ;i < count ;i++) { 228 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]: 229 ((GLushort *)indices)[i]; 230 const GLfixed* fixed_data = (GLfixed *)(dataIn + index*strideIn); 231 GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut); 232 233 for(int j=0;j<attribSize;j++) { 234 float_data[j] = X2F(fixed_data[j]); 235 } 236 } 237 } 238 239 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) { 240 241 for(unsigned int i = 0; i < nBytes;i+=strideOut) { 242 const GLbyte* byte_data = (const GLbyte *)dataIn; 243 //filling attrib 244 for(int j=0;j<attribSize;j++) { 245 reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]); 246 } 247 dataIn += strideIn; 248 } 249 } 250 251 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) { 252 for(int i = 0 ;i < count ;i++) { 253 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]: 254 ((GLushort *)indices)[i]; 255 const GLbyte* bytes_data = (GLbyte *)(dataIn + index*strideIn); 256 GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut); 257 258 for(int j=0;j<attribSize;j++) { 259 short_data[j] = B2S(bytes_data[j]); 260 } 261 } 262 } 263 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) { 264 265 int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes 266 int stride = p->getStride()?p->getStride():attribSize; 267 int start = p->getBufferOffset()+first*attribSize; 268 if(!p->getStride()) { 269 list.addRange(Range(start,count*attribSize)); 270 } else { 271 for(int i = 0 ;i < count; i++,start+=stride) { 272 list.addRange(Range(start,attribSize)); 273 } 274 } 275 } 276 277 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) { 278 279 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes 280 int stride = p->getStride()?p->getStride():attribSize; 281 int start = p->getBufferOffset(); 282 for(int i=0 ; i < count; i++) { 283 GLushort index = (indices_type == GL_UNSIGNED_SHORT? 284 static_cast<const GLushort*>(indices)[i]: 285 static_cast<const GLubyte*>(indices)[i]); 286 list.addRange(Range(start+index*stride,attribSize)); 287 288 } 289 } 290 291 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) { 292 293 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes 294 int stride = p->getStride()?p->getStride():attribSize; 295 int offset = p->getBufferOffset(); 296 297 int n = 0; 298 for(int i=0;i<ranges.size();i++) { 299 int startIndex = (ranges[i].getStart() - offset) / stride; 300 int nElements = ranges[i].getSize()/attribSize; 301 for(int j=0;j<nElements;j++) { 302 indices[n++] = startIndex+j; 303 } 304 } 305 return n; 306 } 307 308 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) { 309 310 GLenum type = p->getType(); 311 int attribSize = p->getSize(); 312 unsigned int size = attribSize*count + first; 313 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte); 314 cArrs.allocArr(size,type); 315 int stride = p->getStride()?p->getStride():bytes*attribSize; 316 const char* data = (const char*)p->getArrayData() + (first*stride); 317 318 if(type == GL_FIXED) { 319 convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize); 320 } else if(type == GL_BYTE) { 321 convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize); 322 } 323 } 324 325 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) { 326 327 RangeList ranges; 328 RangeList conversions; 329 GLushort* indices = NULL; 330 GLenum type = p->getType(); 331 int attribSize = p->getSize(); 332 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; 333 unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed); 334 char* data = (char*)p->getBufferData() + (first*stride); 335 336 if(p->bufferNeedConversion()) { 337 directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset 338 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted 339 340 if(conversions.size()) { // there are some elements to convert 341 indices = new GLushort[count]; 342 int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array 343 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize); 344 } 345 } 346 if(indices) delete[] indices; 347 cArrs.setArr(data,p->getStride(),GL_FLOAT); 348 } 349 350 int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) { 351 //finding max index 352 int max = 0; 353 if(type == GL_UNSIGNED_BYTE) { 354 GLubyte* b_indices =(GLubyte *)indices; 355 for(int i=0;i<count;i++) { 356 if(b_indices[i] > max) max = b_indices[i]; 357 } 358 } else { 359 GLushort* us_indices =(GLushort *)indices; 360 for(int i=0;i<count;i++) { 361 if(us_indices[i] > max) max = us_indices[i]; 362 } 363 } 364 return max; 365 } 366 367 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { 368 GLenum type = p->getType(); 369 int maxElements = findMaxIndex(count,type,indices) + 1; 370 371 int attribSize = p->getSize(); 372 int size = attribSize * maxElements; 373 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte); 374 cArrs.allocArr(size,type); 375 int stride = p->getStride()?p->getStride():bytes*attribSize; 376 377 const char* data = (const char*)p->getArrayData(); 378 if(type == GL_FIXED) { 379 convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize); 380 } else if(type == GL_BYTE){ 381 convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize); 382 } 383 } 384 385 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { 386 RangeList ranges; 387 RangeList conversions; 388 GLushort* conversionIndices = NULL; 389 GLenum type = p->getType(); 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::getRendererString() const { 487 return s_glRenderer.c_str(); 488 } 489 490 void GLEScontext::getGlobalLock() { 491 s_lock.lock(); 492 } 493 494 void GLEScontext::releaseGlobalLock() { 495 s_lock.unlock(); 496 } 497 498 499 void GLEScontext::initCapsLocked(const GLubyte * extensionString) 500 { 501 const char* cstring = (const char*)extensionString; 502 503 s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs); 504 s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane); 505 s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights); 506 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize); 507 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits); 508 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits); 509 const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION); 510 s_glSupport.glslVersion = Version((const char*)(glslVersion)); 511 512 if (strstr(cstring,"GL_EXT_bgra ")!=NULL) 513 s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true; 514 515 if (strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL) 516 s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true; 517 518 if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL) 519 s_glSupport.GL_ARB_VERTEX_BLEND = true; 520 521 if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL) 522 s_glSupport.GL_ARB_MATRIX_PALETTE = true; 523 524 if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL ) 525 s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true; 526 527 if (strstr(cstring,"GL_OES_read_format ")!=NULL) 528 s_glSupport.GL_OES_READ_FORMAT = true; 529 530 if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL) 531 s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true; 532 533 if (strstr(cstring,"GL_NV_half_float ")!=NULL) 534 s_glSupport.GL_NV_HALF_FLOAT = true; 535 536 if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL) 537 s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true; 538 539 if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL) 540 s_glSupport.GL_SGIS_GENERATE_MIPMAP = true; 541 542 if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL) 543 s_glSupport.GL_ARB_ES2_COMPATIBILITY = true; 544 545 if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL) 546 s_glSupport.GL_OES_STANDARD_DERIVATIVES = true; 547 548 } 549 550 bool GLEScontext::isTextureUnitEnabled(GLenum unit) { 551 for (int i=0;i<NUM_TEXTURE_TARGETS;++i) { 552 if (m_texState[unit-GL_TEXTURE0][i].enabled) 553 return true; 554 } 555 return false; 556 } 557 558 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params) 559 { 560 GLint iParam; 561 562 if(glGetIntegerv(pname, &iParam)) 563 { 564 *params = (iParam != 0); 565 return true; 566 } 567 568 return false; 569 } 570 571 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params) 572 { 573 bool result = false; 574 GLint numParams = 1; 575 576 GLint* iParams = new GLint[numParams]; 577 if (numParams>0 && glGetIntegerv(pname,iParams)) { 578 while(numParams >= 0) 579 { 580 params[numParams] = I2X(iParams[numParams]); 581 numParams--; 582 } 583 result = true; 584 } 585 delete [] iParams; 586 587 return result; 588 } 589 590 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params) 591 { 592 bool result = false; 593 GLint numParams = 1; 594 595 GLint* iParams = new GLint[numParams]; 596 if (numParams>0 && glGetIntegerv(pname,iParams)) { 597 while(numParams >= 0) 598 { 599 params[numParams] = (GLfloat)iParams[numParams]; 600 numParams--; 601 } 602 result = true; 603 } 604 delete [] iParams; 605 606 return result; 607 } 608 609 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params) 610 { 611 switch(pname) 612 { 613 case GL_ARRAY_BUFFER_BINDING: 614 *params = m_arrayBuffer; 615 break; 616 617 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 618 *params = m_elementBuffer; 619 break; 620 621 case GL_TEXTURE_BINDING_CUBE_MAP: 622 *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture; 623 break; 624 625 case GL_TEXTURE_BINDING_2D: 626 *params = m_texState[m_activeTexture][TEXTURE_2D].texture; 627 break; 628 629 case GL_ACTIVE_TEXTURE: 630 *params = m_activeTexture+GL_TEXTURE0; 631 break; 632 633 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 634 *params = GL_UNSIGNED_BYTE; 635 break; 636 637 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 638 *params = GL_RGBA; 639 break; 640 default: 641 return false; 642 } 643 644 return true; 645 } 646 647 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) { 648 TextureTarget value=TEXTURE_2D; 649 switch (target) { 650 case GL_TEXTURE_CUBE_MAP: 651 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 652 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 653 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 654 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 655 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 656 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 657 value = TEXTURE_CUBE_MAP; 658 break; 659 case GL_TEXTURE_2D: 660 value = TEXTURE_2D; 661 break; 662 } 663 return value; 664 } 665 666 unsigned int GLEScontext::getBindedTexture(GLenum target) { 667 TextureTarget pos = GLTextureTargetToLocal(target); 668 return m_texState[m_activeTexture][pos].texture; 669 } 670 671 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) { 672 TextureTarget pos = GLTextureTargetToLocal(target); 673 return m_texState[unit-GL_TEXTURE0][pos].texture; 674 } 675 676 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) { 677 TextureTarget pos = GLTextureTargetToLocal(target); 678 m_texState[m_activeTexture][pos].texture = tex; 679 } 680 681 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) { 682 TextureTarget pos = GLTextureTargetToLocal(target); 683 m_texState[m_activeTexture][pos].enabled = enable; 684 } 685 686 #define INTERNAL_NAME(x) (x +0x100000000ll); 687 688 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) { 689 ObjectLocalName name = 0; 690 switch (GLTextureTargetToLocal(target)) { 691 case TEXTURE_2D: 692 name = INTERNAL_NAME(0); 693 break; 694 case TEXTURE_CUBE_MAP: 695 name = INTERNAL_NAME(1); 696 break; 697 default: 698 name = 0; 699 break; 700 } 701 return name; 702 } 703 704 void GLEScontext::drawValidate(void) 705 { 706 if(m_framebuffer == 0) 707 return; 708 709 ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer); 710 if (fbObj.Ptr() == NULL) 711 return; 712 713 FramebufferData *fbData = (FramebufferData *)fbObj.Ptr(); 714 715 fbData->validate(this); 716 } 717