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