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