Home | History | Annotate | Download | only in GLcommon
      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