Home | History | Annotate | Download | only in GLES_CM
      1 /*
      2 * Copyright (C) 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 "GLEScmContext.h"
     18 #include "GLEScmUtils.h"
     19 #include <GLcommon/GLutils.h>
     20 #include <GLcommon/GLconversion_macros.h>
     21 #include <string.h>
     22 #include <GLES/gl.h>
     23 #include <GLES/glext.h>
     24 
     25 void GLEScmContext::init() {
     26     android::Mutex::Autolock mutex(s_lock);
     27     if(!m_initialized) {
     28         s_glDispatch.dispatchFuncs(GLES_1_1);
     29         GLEScontext::init();
     30 
     31         m_texCoords = new GLESpointer[s_glSupport.maxTexUnits];
     32         m_map[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_clientActiveTexture];
     33 
     34         buildStrings((const char*)dispatcher().glGetString(GL_VENDOR),
     35                      (const char*)dispatcher().glGetString(GL_RENDERER),
     36                      (const char*)dispatcher().glGetString(GL_VERSION),
     37                      "OpenGL ES-CM 1.1");
     38     }
     39     m_initialized = true;
     40 }
     41 
     42 GLEScmContext::GLEScmContext():GLEScontext(),m_texCoords(NULL),m_pointsIndex(-1), m_clientActiveTexture(0) {
     43 
     44     m_map[GL_COLOR_ARRAY]          = new GLESpointer();
     45     m_map[GL_NORMAL_ARRAY]         = new GLESpointer();
     46     m_map[GL_VERTEX_ARRAY]         = new GLESpointer();
     47     m_map[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer();
     48 }
     49 
     50 
     51 void GLEScmContext::setActiveTexture(GLenum tex) {
     52    m_activeTexture = tex - GL_TEXTURE0;
     53 }
     54 
     55 void GLEScmContext::setClientActiveTexture(GLenum tex) {
     56    m_clientActiveTexture = tex - GL_TEXTURE0;
     57    m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
     58 }
     59 
     60 GLEScmContext::~GLEScmContext(){
     61     if(m_texCoords){
     62         delete[] m_texCoords;
     63         m_texCoords = NULL;
     64     }
     65     m_map[GL_TEXTURE_COORD_ARRAY] = NULL;
     66 }
     67 
     68 
     69 //setting client side arr
     70 void GLEScmContext::setupArr(const GLvoid* arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized, int index){
     71     if( arr == NULL) return;
     72     switch(arrayType) {
     73         case GL_VERTEX_ARRAY:
     74             s_glDispatch.glVertexPointer(size,dataType,stride,arr);
     75             break;
     76         case GL_NORMAL_ARRAY:
     77             s_glDispatch.glNormalPointer(dataType,stride,arr);
     78             break;
     79         case GL_TEXTURE_COORD_ARRAY:
     80             s_glDispatch.glTexCoordPointer(size,dataType,stride,arr);
     81             break;
     82         case GL_COLOR_ARRAY:
     83             s_glDispatch.glColorPointer(size,dataType,stride,arr);
     84             break;
     85         case GL_POINT_SIZE_ARRAY_OES:
     86             m_pointsIndex = index;
     87             break;
     88     }
     89 }
     90 
     91 
     92 void GLEScmContext::setupArrayPointerHelper(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLenum array_id,GLESpointer* p){
     93         unsigned int size = p->getSize();
     94         GLenum dataType = p->getType();
     95 
     96         if(needConvert(cArrs,first,count,type,indices,direct,p,array_id)){
     97             //conversion has occured
     98             ArrayData currentArr = cArrs.getCurrentArray();
     99             setupArr(currentArr.data,array_id,currentArr.type,size,currentArr.stride,GL_FALSE, cArrs.getCurrentIndex());
    100             ++cArrs;
    101         } else {
    102             setupArr(p->getData(),array_id,dataType,size,p->getStride(), GL_FALSE);
    103         }
    104 }
    105 
    106 void GLEScmContext::setupArraysPointers(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct) {
    107     ArraysMap::iterator it;
    108     m_pointsIndex = -1;
    109 
    110     //going over all clients arrays Pointers
    111     for ( it=m_map.begin() ; it != m_map.end(); it++ ) {
    112 
    113         GLenum array_id   = (*it).first;
    114         GLESpointer* p = (*it).second;
    115         if(!isArrEnabled(array_id)) continue;
    116         if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later
    117         setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
    118     }
    119 
    120     unsigned int activeTexture = m_clientActiveTexture + GL_TEXTURE0;
    121 
    122     s_lock.lock();
    123     int maxTexUnits = s_glSupport.maxTexUnits;
    124     s_lock.unlock();
    125 
    126     //converting all texture coords arrays
    127     for(int i=0; i< maxTexUnits;i++) {
    128 
    129         unsigned int tex = GL_TEXTURE0+i;
    130         setClientActiveTexture(tex);
    131         s_glDispatch.glClientActiveTexture(tex);
    132 
    133         GLenum array_id   = GL_TEXTURE_COORD_ARRAY;
    134         GLESpointer* p = m_map[array_id];
    135         if(!isArrEnabled(array_id)) continue;
    136         setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
    137     }
    138 
    139     setClientActiveTexture(activeTexture);
    140     s_glDispatch.glClientActiveTexture(activeTexture);
    141 }
    142 
    143 void  GLEScmContext::drawPointsData(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) {
    144     const char  *pointsArr =  NULL;
    145     int stride = 0;
    146     GLESpointer* p = m_map[GL_POINT_SIZE_ARRAY_OES];
    147 
    148     //choosing the right points sizes array source
    149     if(m_pointsIndex >= 0) { //point size array was converted
    150         pointsArr = (const char*)(cArrs[m_pointsIndex].data);
    151         stride = cArrs[m_pointsIndex].stride;
    152     } else {
    153         pointsArr = static_cast<const char*>(p->getData());
    154         stride = p->getStride();
    155     }
    156 
    157     if(stride == 0){
    158         stride = sizeof(GLfloat);
    159     }
    160 
    161 
    162     if(isElemsDraw) {
    163         int tSize = type == GL_UNSIGNED_SHORT ? 2 : 1;
    164 
    165         int i = 0;
    166         while(i<count)
    167         {
    168             int sStart = i;
    169             int sCount = 1;
    170 
    171 #define INDEX \
    172                 (type == GL_UNSIGNED_SHORT ? \
    173                 static_cast<const GLushort*>(indices_in)[i]: \
    174                 static_cast<const GLubyte*>(indices_in)[i])
    175 
    176             GLfloat pSize = *((GLfloat*)(pointsArr+(INDEX*stride)));
    177             i++;
    178 
    179             while(i < count && pSize == *((GLfloat*)(pointsArr+(INDEX*stride))))
    180             {
    181                 sCount++;
    182                 i++;
    183             }
    184 
    185             s_glDispatch.glPointSize(pSize);
    186             s_glDispatch.glDrawElements(GL_POINTS, sCount, type, (char*)indices_in+sStart*tSize);
    187         }
    188     } else {
    189         int i = 0;
    190         while(i<count)
    191         {
    192             int sStart = i;
    193             int sCount = 1;
    194             GLfloat pSize = *((GLfloat*)(pointsArr+((first+i)*stride)));
    195             i++;
    196 
    197             while(i < count && pSize == *((GLfloat*)(pointsArr+((first+i)*stride))))
    198             {
    199                 sCount++;
    200                 i++;
    201             }
    202 
    203             s_glDispatch.glPointSize(pSize);
    204             s_glDispatch.glDrawArrays(GL_POINTS, first+sStart, sCount);
    205         }
    206     }
    207 }
    208 
    209 void  GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
    210     drawPointsData(arrs,first,count,0,NULL,false);
    211 }
    212 
    213 void GLEScmContext::drawPointsElems(GLESConversionArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) {
    214     drawPointsData(arrs,0,count,type,indices_in,true);
    215 }
    216 
    217 bool GLEScmContext::needConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
    218 
    219     bool usingVBO = p->isVBO();
    220     GLenum arrType = p->getType();
    221     /*
    222      conversion is not necessary in the following cases:
    223       (*) array type is byte but it is not vertex or texture array
    224       (*) array type is not fixed
    225     */
    226     if((arrType != GL_FIXED) && (arrType != GL_BYTE)) return false;
    227     if((arrType == GL_BYTE   && (array_id != GL_VERTEX_ARRAY)) &&
    228        (arrType == GL_BYTE   && (array_id != GL_TEXTURE_COORD_ARRAY)) ) return false;
    229 
    230 
    231     bool byteVBO = (arrType == GL_BYTE) && usingVBO;
    232     if(byteVBO){
    233         p->redirectPointerData();
    234     }
    235 
    236     if(!usingVBO || byteVBO) {
    237         if (direct) {
    238             convertDirect(cArrs,first,count,array_id,p);
    239         } else {
    240             convertIndirect(cArrs,count,type,indices,array_id,p);
    241         }
    242     } else {
    243         if (direct) {
    244             convertDirectVBO(cArrs,first,count,array_id,p) ;
    245         } else {
    246             convertIndirectVBO(cArrs,count,type,indices,array_id,p);
    247         }
    248     }
    249     return true;
    250 }
    251 
    252 const GLESpointer* GLEScmContext::getPointer(GLenum arrType) {
    253     GLenum type =
    254         arrType == GL_VERTEX_ARRAY_POINTER          ? GL_VERTEX_ARRAY :
    255         arrType == GL_NORMAL_ARRAY_POINTER          ? GL_NORMAL_ARRAY :
    256         arrType == GL_TEXTURE_COORD_ARRAY_POINTER   ? GL_TEXTURE_COORD_ARRAY :
    257         arrType == GL_COLOR_ARRAY_POINTER           ? GL_COLOR_ARRAY :
    258         arrType == GL_POINT_SIZE_ARRAY_POINTER_OES  ? GL_POINT_SIZE_ARRAY_OES :
    259         0;
    260     if(type != 0)
    261     {
    262         return GLEScontext::getPointer(type);
    263     }
    264     return NULL;
    265 }
    266 
    267 void GLEScmContext::initExtensionString() {
    268     *s_glExtensions = "GL_OES_blend_func_separate GL_OES_blend_equation_separate GL_OES_blend_subtract "
    269                       "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
    270                       "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
    271                       "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
    272                       "GL_OES_texture_cube_map GL_OES_draw_texture ";
    273     if (s_glSupport.GL_OES_READ_FORMAT)
    274         *s_glExtensions+="GL_OES_read_format ";
    275     if (s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT) {
    276         *s_glExtensions+="GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 GL_OES_fbo_render_mipmap "
    277                          "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 GL_OES_stencil8 ";
    278     }
    279     if (s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL)
    280         *s_glExtensions+="GL_OES_packed_depth_stencil ";
    281     if (s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888)
    282         *s_glExtensions+="GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
    283     if (s_glSupport.GL_ARB_MATRIX_PALETTE && s_glSupport.GL_ARB_VERTEX_BLEND) {
    284         *s_glExtensions+="GL_OES_matrix_palette ";
    285         GLint max_palette_matrices=0;
    286         GLint max_vertex_units=0;
    287         dispatcher().glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES,&max_palette_matrices);
    288         dispatcher().glGetIntegerv(GL_MAX_VERTEX_UNITS_OES,&max_vertex_units);
    289         if (max_palette_matrices>=32 && max_vertex_units>=4)
    290             *s_glExtensions+="GL_OES_extended_matrix_palette ";
    291     }
    292     *s_glExtensions+="GL_OES_compressed_ETC1_RGB8_texture ";
    293 }
    294 
    295 int GLEScmContext::getMaxTexUnits() {
    296     return getCaps()->maxTexUnits;
    297 }
    298 
    299 bool GLEScmContext::glGetBooleanv(GLenum pname, GLboolean *params)
    300 {
    301     GLint iParam;
    302 
    303     if(glGetIntegerv(pname, &iParam))
    304     {
    305         *params = (iParam != 0);
    306         return true;
    307     }
    308 
    309     return false;
    310 }
    311 
    312 bool GLEScmContext::glGetFixedv(GLenum pname, GLfixed *params)
    313 {
    314     GLint iParam;
    315 
    316     if(glGetIntegerv(pname, &iParam))
    317     {
    318         *params = I2X(iParam);
    319         return true;
    320     }
    321 
    322     return false;
    323 }
    324 
    325 bool GLEScmContext::glGetFloatv(GLenum pname, GLfloat *params)
    326 {
    327     GLint iParam;
    328 
    329     if(glGetIntegerv(pname, &iParam))
    330     {
    331         *params = (GLfloat)iParam;
    332         return true;
    333     }
    334 
    335     return false;
    336 }
    337 
    338 bool GLEScmContext::glGetIntegerv(GLenum pname, GLint *params)
    339 {
    340     if(GLEScontext::glGetIntegerv(pname, params))
    341         return true;
    342 
    343     const GLESpointer* ptr = NULL;
    344 
    345     switch(pname){
    346         case GL_VERTEX_ARRAY_BUFFER_BINDING:
    347         case GL_VERTEX_ARRAY_SIZE:
    348         case GL_VERTEX_ARRAY_STRIDE:
    349         case GL_VERTEX_ARRAY_TYPE:
    350             ptr = getPointer(GL_VERTEX_ARRAY_POINTER);
    351             break;
    352 
    353         case GL_NORMAL_ARRAY_BUFFER_BINDING:
    354         case GL_NORMAL_ARRAY_STRIDE:
    355         case GL_NORMAL_ARRAY_TYPE:
    356             ptr = getPointer(GL_NORMAL_ARRAY_POINTER);
    357             break;
    358 
    359         case GL_COLOR_ARRAY_BUFFER_BINDING:
    360         case GL_COLOR_ARRAY_SIZE:
    361         case GL_COLOR_ARRAY_STRIDE:
    362         case GL_COLOR_ARRAY_TYPE:
    363             ptr = getPointer(GL_COLOR_ARRAY_POINTER);
    364             break;
    365 
    366         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
    367         case GL_TEXTURE_COORD_ARRAY_SIZE:
    368         case GL_TEXTURE_COORD_ARRAY_STRIDE:
    369         case GL_TEXTURE_COORD_ARRAY_TYPE:
    370             ptr = getPointer(GL_TEXTURE_COORD_ARRAY_POINTER);
    371             break;
    372 
    373         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
    374         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
    375         case GL_POINT_SIZE_ARRAY_TYPE_OES:
    376             ptr = getPointer(GL_POINT_SIZE_ARRAY_POINTER_OES);
    377             break;
    378 
    379         default:
    380             return false;
    381     }
    382 
    383     switch(pname)
    384     {
    385         case GL_VERTEX_ARRAY_BUFFER_BINDING:
    386         case GL_NORMAL_ARRAY_BUFFER_BINDING:
    387         case GL_COLOR_ARRAY_BUFFER_BINDING:
    388         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
    389         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
    390             *params = ptr ? ptr->getBufferName() : 0;
    391             break;
    392 
    393         case GL_VERTEX_ARRAY_STRIDE:
    394         case GL_NORMAL_ARRAY_STRIDE:
    395         case GL_COLOR_ARRAY_STRIDE:
    396         case GL_TEXTURE_COORD_ARRAY_STRIDE:
    397         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
    398             *params = ptr ? ptr->getStride() : 0;
    399             break;
    400 
    401         case GL_VERTEX_ARRAY_SIZE:
    402         case GL_COLOR_ARRAY_SIZE:
    403         case GL_TEXTURE_COORD_ARRAY_SIZE:
    404             *params = ptr ? ptr->getSize() : 0;
    405             break;
    406 
    407         case GL_VERTEX_ARRAY_TYPE:
    408         case GL_NORMAL_ARRAY_TYPE:
    409         case GL_COLOR_ARRAY_TYPE:
    410         case GL_TEXTURE_COORD_ARRAY_TYPE:
    411         case GL_POINT_SIZE_ARRAY_TYPE_OES:
    412             *params = ptr ? ptr->getType() : 0;
    413             break;
    414     }
    415 
    416     return true;
    417 }
    418