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