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