• 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         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 
GLEScmContext()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 
setActiveTexture(GLenum tex)51 void GLEScmContext::setActiveTexture(GLenum tex) {
52    m_activeTexture = tex - GL_TEXTURE0;
53 }
54 
setClientActiveTexture(GLenum tex)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 
~GLEScmContext()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
setupArr(const GLvoid * arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized,int index)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 
setupArrayPointerHelper(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLenum array_id,GLESpointer * p)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 
setupArraysPointers(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct)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 
drawPointsData(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices_in,bool isElemsDraw)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 
drawPointsArrs(GLESConversionArrays & arrs,GLint first,GLsizei count)209 void  GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
210     drawPointsData(arrs,first,count,0,NULL,false);
211 }
212 
drawPointsElems(GLESConversionArrays & arrs,GLsizei count,GLenum type,const GLvoid * indices_in)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 
needConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)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 
getPointer(GLenum arrType)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 
initExtensionString()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 
getMaxTexUnits()295 int GLEScmContext::getMaxTexUnits() {
296     return getCaps()->maxTexUnits;
297 }
298 
glGetBooleanv(GLenum pname,GLboolean * params)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 
glGetFixedv(GLenum pname,GLfixed * params)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 
glGetFloatv(GLenum pname,GLfloat * params)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 
glGetIntegerv(GLenum pname,GLint * params)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