• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
init()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 
GLEScmContext()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 
setActiveTexture(GLenum tex)47 void GLEScmContext::setActiveTexture(GLenum tex) {
48    m_activeTexture = tex - GL_TEXTURE0;
49 }
50 
setClientActiveTexture(GLenum tex)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 
~GLEScmContext()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
setupArr(const GLvoid * arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized,int index)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 
setupArrayPointerHelper(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLenum array_id,GLESpointer * p)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 
setupArraysPointers(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct)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 
drawPointsData(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices_in,bool isElemsDraw)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 
drawPointsArrs(GLESConversionArrays & arrs,GLint first,GLsizei count)205 void  GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
206     drawPointsData(arrs,first,count,0,NULL,false);
207 }
208 
drawPointsElems(GLESConversionArrays & arrs,GLsizei count,GLenum type,const GLvoid * indices_in)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 
needConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)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 
getPointer(GLenum arrType)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 
initExtensionString()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 
getMaxTexUnits()291 int GLEScmContext::getMaxTexUnits() {
292     return getCaps()->maxTexUnits;
293 }
294 
glGetBooleanv(GLenum pname,GLboolean * params)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 
glGetFixedv(GLenum pname,GLfixed * params)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 
glGetFloatv(GLenum pname,GLfloat * params)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 
glGetIntegerv(GLenum pname,GLint * params)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