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