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