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