1 /*
2 * Copyright 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 <GLcommon/GLEScontext.h>
18 #include <GLcommon/GLconversion_macros.h>
19 #include <GLcommon/GLESmacros.h>
20 #include <GLES/gl.h>
21 #include <GLES/glext.h>
22 #include <GLcommon/GLESvalidate.h>
23 #include <GLcommon/TextureUtils.h>
24 #include <GLcommon/FramebufferData.h>
25 #include <strings.h>
26
27 //decleration
28 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
29 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize);
30 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
31 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize);
32
~GLESConversionArrays()33 GLESConversionArrays::~GLESConversionArrays() {
34 for(std::map<GLenum,ArrayData>::iterator it = m_arrays.begin(); it != m_arrays.end();it++) {
35 if((*it).second.allocated){
36 if((*it).second.type == GL_FLOAT){
37 GLfloat* p = (GLfloat *)((*it).second.data);
38 if(p) delete[] p;
39 } else if((*it).second.type == GL_SHORT){
40 GLshort* p = (GLshort *)((*it).second.data);
41 if(p) delete[] p;
42 }
43 }
44 }
45 }
46
allocArr(unsigned int size,GLenum type)47 void GLESConversionArrays::allocArr(unsigned int size,GLenum type){
48 if(type == GL_FIXED){
49 m_arrays[m_current].data = new GLfloat[size];
50 m_arrays[m_current].type = GL_FLOAT;
51 } else if(type == GL_BYTE){
52 m_arrays[m_current].data = new GLshort[size];
53 m_arrays[m_current].type = GL_SHORT;
54 }
55 m_arrays[m_current].stride = 0;
56 m_arrays[m_current].allocated = true;
57 }
58
setArr(void * data,unsigned int stride,GLenum type)59 void GLESConversionArrays::setArr(void* data,unsigned int stride,GLenum type){
60 m_arrays[m_current].type = type;
61 m_arrays[m_current].data = data;
62 m_arrays[m_current].stride = stride;
63 m_arrays[m_current].allocated = false;
64 }
65
getCurrentData()66 void* GLESConversionArrays::getCurrentData(){
67 return m_arrays[m_current].data;
68 }
69
getCurrentArray()70 ArrayData& GLESConversionArrays::getCurrentArray(){
71 return m_arrays[m_current];
72 }
73
getCurrentIndex()74 unsigned int GLESConversionArrays::getCurrentIndex(){
75 return m_current;
76 }
77
operator [](int i)78 ArrayData& GLESConversionArrays::operator[](int i){
79 return m_arrays[i];
80 }
81
operator ++()82 void GLESConversionArrays::operator++(){
83 m_current++;
84 }
85
86 GLDispatch GLEScontext::s_glDispatch;
87 android::Mutex GLEScontext::s_lock;
88 std::string* GLEScontext::s_glExtensions= NULL;
89 std::string GLEScontext::s_glVendor;
90 std::string GLEScontext::s_glRenderer;
91 std::string GLEScontext::s_glVersion;
92 GLSupport GLEScontext::s_glSupport;
93
Version()94 Version::Version():m_major(0),
95 m_minor(0),
96 m_release(0){};
97
Version(int major,int minor,int release)98 Version::Version(int major,int minor,int release):m_major(major),
99 m_minor(minor),
100 m_release(release){};
101
Version(const Version & ver)102 Version::Version(const Version& ver):m_major(ver.m_major),
103 m_minor(ver.m_minor),
104 m_release(ver.m_release){}
105
Version(const char * versionString)106 Version::Version(const char* versionString){
107 m_release = 0;
108 if((!versionString) ||
109 ((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) &&
110 (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){
111 m_major = m_minor = 0; // the version is not in the right format
112 }
113 }
114
operator =(const Version & ver)115 Version& Version::operator=(const Version& ver){
116 m_major = ver.m_major;
117 m_minor = ver.m_minor;
118 m_release = ver.m_release;
119 return *this;
120 }
121
operator <(const Version & ver) const122 bool Version::operator<(const Version& ver) const{
123 if(m_major < ver.m_major) return true;
124 if(m_major == ver.m_major){
125 if(m_minor < ver.m_minor) return true;
126 if(m_minor == ver.m_minor){
127 return m_release < ver.m_release;
128 }
129 }
130 return false;
131 }
132
init()133 void GLEScontext::init() {
134
135 if (!s_glExtensions) {
136 initCapsLocked(s_glDispatch.glGetString(GL_EXTENSIONS));
137 s_glExtensions = new std::string("");
138 }
139
140 if (!m_initialized) {
141 initExtensionString();
142
143 int maxTexUnits = getMaxTexUnits();
144 m_texState = new textureUnitState[maxTexUnits];
145 for (int i=0;i<maxTexUnits;++i) {
146 for (int j=0;j<NUM_TEXTURE_TARGETS;++j)
147 {
148 m_texState[i][j].texture = 0;
149 m_texState[i][j].enabled = GL_FALSE;
150 }
151 }
152 }
153 }
154
GLEScontext()155 GLEScontext::GLEScontext():
156 m_initialized(false) ,
157 m_activeTexture(0) ,
158 m_unpackAlignment(4) ,
159 m_glError(GL_NO_ERROR) ,
160 m_texState(0) ,
161 m_arrayBuffer(0) ,
162 m_elementBuffer(0),
163 m_renderbuffer(0),
164 m_framebuffer(0)
165 {
166 };
167
getGLerror()168 GLenum GLEScontext::getGLerror() {
169 return m_glError;
170 }
171
setGLerror(GLenum err)172 void GLEScontext::setGLerror(GLenum err) {
173 m_glError = err;
174 }
175
setActiveTexture(GLenum tex)176 void GLEScontext::setActiveTexture(GLenum tex) {
177 m_activeTexture = tex - GL_TEXTURE0;
178 }
179
~GLEScontext()180 GLEScontext::~GLEScontext() {
181 for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) {
182 GLESpointer* p = (*it).second;
183 if(p) {
184 delete p;
185 }
186 }
187 delete[] m_texState;
188 m_texState = NULL;
189 }
190
setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid * data,bool normalize)191 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data,bool normalize) {
192 GLuint bufferName = m_arrayBuffer;
193 if(bufferName) {
194 unsigned int offset = ToTargetCompatibleHandle((uintptr_t)data);
195 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
196 m_map[arrType]->setBuffer(size,type,stride,vbo,bufferName,offset,normalize);
197 return static_cast<const unsigned char*>(vbo->getData()) + offset;
198 }
199 m_map[arrType]->setArray(size,type,stride,data,normalize);
200 return data;
201 }
202
enableArr(GLenum arr,bool enable)203 void GLEScontext::enableArr(GLenum arr,bool enable) {
204 m_map[arr]->enable(enable);
205 }
206
isArrEnabled(GLenum arr)207 bool GLEScontext::isArrEnabled(GLenum arr) {
208 return m_map[arr]->isEnable();
209 }
210
getPointer(GLenum arrType)211 const GLESpointer* GLEScontext::getPointer(GLenum arrType) {
212 if (m_map.find(arrType) != m_map.end()) return m_map[arrType];
213 return NULL;
214 }
215
convertFixedDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)216 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
217
218 for(unsigned int i = 0; i < nBytes;i+=strideOut) {
219 const GLfixed* fixed_data = (const GLfixed *)dataIn;
220 //filling attrib
221 for(int j=0;j<attribSize;j++) {
222 reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]);
223 }
224 dataIn += strideIn;
225 }
226 }
227
convertFixedIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)228 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
229 for(int i = 0 ;i < count ;i++) {
230 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]:
231 ((GLushort *)indices)[i];
232 const GLfixed* fixed_data = (GLfixed *)(dataIn + index*strideIn);
233 GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
234
235 for(int j=0;j<attribSize;j++) {
236 float_data[j] = X2F(fixed_data[j]);
237 }
238 }
239 }
240
convertByteDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)241 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
242
243 for(unsigned int i = 0; i < nBytes;i+=strideOut) {
244 const GLbyte* byte_data = (const GLbyte *)dataIn;
245 //filling attrib
246 for(int j=0;j<attribSize;j++) {
247 reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]);
248 }
249 dataIn += strideIn;
250 }
251 }
252
convertByteIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)253 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
254 for(int i = 0 ;i < count ;i++) {
255 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]:
256 ((GLushort *)indices)[i];
257 const GLbyte* bytes_data = (GLbyte *)(dataIn + index*strideIn);
258 GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
259
260 for(int j=0;j<attribSize;j++) {
261 short_data[j] = B2S(bytes_data[j]);
262 }
263 }
264 }
directToBytesRanges(GLint first,GLsizei count,GLESpointer * p,RangeList & list)265 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) {
266
267 int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes
268 int stride = p->getStride()?p->getStride():attribSize;
269 int start = p->getBufferOffset()+first*attribSize;
270 if(!p->getStride()) {
271 list.addRange(Range(start,count*attribSize));
272 } else {
273 for(int i = 0 ;i < count; i++,start+=stride) {
274 list.addRange(Range(start,attribSize));
275 }
276 }
277 }
278
indirectToBytesRanges(const GLvoid * indices,GLenum indices_type,GLsizei count,GLESpointer * p,RangeList & list)279 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) {
280
281 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
282 int stride = p->getStride()?p->getStride():attribSize;
283 int start = p->getBufferOffset();
284 for(int i=0 ; i < count; i++) {
285 GLushort index = (indices_type == GL_UNSIGNED_SHORT?
286 static_cast<const GLushort*>(indices)[i]:
287 static_cast<const GLubyte*>(indices)[i]);
288 list.addRange(Range(start+index*stride,attribSize));
289
290 }
291 }
292
bytesRangesToIndices(RangeList & ranges,GLESpointer * p,GLushort * indices)293 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) {
294
295 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
296 int stride = p->getStride()?p->getStride():attribSize;
297 int offset = p->getBufferOffset();
298
299 int n = 0;
300 for(int i=0;i<ranges.size();i++) {
301 int startIndex = (ranges[i].getStart() - offset) / stride;
302 int nElements = ranges[i].getSize()/attribSize;
303 for(int j=0;j<nElements;j++) {
304 indices[n++] = startIndex+j;
305 }
306 }
307 return n;
308 }
309
convertDirect(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)310 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
311
312 GLenum type = p->getType();
313 int attribSize = p->getSize();
314 unsigned int size = attribSize*count + first;
315 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
316 cArrs.allocArr(size,type);
317 int stride = p->getStride()?p->getStride():bytes*attribSize;
318 const char* data = (const char*)p->getArrayData() + (first*stride);
319
320 if(type == GL_FIXED) {
321 convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize);
322 } else if(type == GL_BYTE) {
323 convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize);
324 }
325 }
326
convertDirectVBO(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)327 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
328
329 RangeList ranges;
330 RangeList conversions;
331 GLushort* indices = NULL;
332 GLenum type = p->getType();
333 int attribSize = p->getSize();
334 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
335 unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed);
336 char* data = (char*)p->getBufferData() + (first*stride);
337
338 if(p->bufferNeedConversion()) {
339 directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset
340 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
341
342 if(conversions.size()) { // there are some elements to convert
343 indices = new GLushort[count];
344 int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array
345 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize);
346 }
347 }
348 if(indices) delete[] indices;
349 cArrs.setArr(data,p->getStride(),GL_FLOAT);
350 }
351
findMaxIndex(GLsizei count,GLenum type,const GLvoid * indices)352 int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) {
353 //finding max index
354 int max = 0;
355 if(type == GL_UNSIGNED_BYTE) {
356 GLubyte* b_indices =(GLubyte *)indices;
357 for(int i=0;i<count;i++) {
358 if(b_indices[i] > max) max = b_indices[i];
359 }
360 } else {
361 GLushort* us_indices =(GLushort *)indices;
362 for(int i=0;i<count;i++) {
363 if(us_indices[i] > max) max = us_indices[i];
364 }
365 }
366 return max;
367 }
368
convertIndirect(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)369 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
370 GLenum type = p->getType();
371 int maxElements = findMaxIndex(count,type,indices) + 1;
372
373 int attribSize = p->getSize();
374 int size = attribSize * maxElements;
375 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
376 cArrs.allocArr(size,type);
377 int stride = p->getStride()?p->getStride():bytes*attribSize;
378
379 const char* data = (const char*)p->getArrayData();
380 if(type == GL_FIXED) {
381 convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize);
382 } else if(type == GL_BYTE){
383 convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize);
384 }
385 }
386
convertIndirectVBO(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)387 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
388 RangeList ranges;
389 RangeList conversions;
390 GLushort* conversionIndices = NULL;
391 GLenum type = p->getType();
392 int attribSize = p->getSize();
393 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
394 char* data = static_cast<char*>(p->getBufferData());
395 if(p->bufferNeedConversion()) {
396 indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset
397 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
398 if(conversions.size()) { // there are some elements to convert
399 conversionIndices = new GLushort[count];
400 int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array
401 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,conversionIndices,stride,attribSize);
402 }
403 }
404 if(conversionIndices) delete[] conversionIndices;
405 cArrs.setArr(data,p->getStride(),GL_FLOAT);
406 }
407
408
409
bindBuffer(GLenum target,GLuint buffer)410 void GLEScontext::bindBuffer(GLenum target,GLuint buffer) {
411 if(target == GL_ARRAY_BUFFER) {
412 m_arrayBuffer = buffer;
413 } else {
414 m_elementBuffer = buffer;
415 }
416 }
417
unbindBuffer(GLuint buffer)418 void GLEScontext::unbindBuffer(GLuint buffer) {
419 if(m_arrayBuffer == buffer)
420 {
421 m_arrayBuffer = 0;
422 }
423 if(m_elementBuffer == buffer)
424 {
425 m_elementBuffer = 0;
426 }
427 }
428
429 //checks if any buffer is binded to target
isBindedBuffer(GLenum target)430 bool GLEScontext::isBindedBuffer(GLenum target) {
431 if(target == GL_ARRAY_BUFFER) {
432 return m_arrayBuffer != 0;
433 } else {
434 return m_elementBuffer != 0;
435 }
436 }
437
getBuffer(GLenum target)438 GLuint GLEScontext::getBuffer(GLenum target) {
439 return target == GL_ARRAY_BUFFER ? m_arrayBuffer:m_elementBuffer;
440 }
441
getBindedBuffer(GLenum target)442 GLvoid* GLEScontext::getBindedBuffer(GLenum target) {
443 GLuint bufferName = getBuffer(target);
444 if(!bufferName) return NULL;
445
446 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
447 return vbo->getData();
448 }
449
getBufferSize(GLenum target,GLint * param)450 void GLEScontext::getBufferSize(GLenum target,GLint* param) {
451 GLuint bufferName = getBuffer(target);
452 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
453 *param = vbo->getSize();
454 }
455
getBufferUsage(GLenum target,GLint * param)456 void GLEScontext::getBufferUsage(GLenum target,GLint* param) {
457 GLuint bufferName = getBuffer(target);
458 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
459 *param = vbo->getUsage();
460 }
461
setBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)462 bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) {
463 GLuint bufferName = getBuffer(target);
464 if(!bufferName) return false;
465 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
466 return vbo->setBuffer(size,usage,data);
467 }
468
setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)469 bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) {
470
471 GLuint bufferName = getBuffer(target);
472 if(!bufferName) return false;
473 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
474 return vbo->setSubBuffer(offset,size,data);
475 }
476
getExtensionString()477 const char * GLEScontext::getExtensionString() {
478 const char * ret;
479 s_lock.lock();
480 if (s_glExtensions)
481 ret = s_glExtensions->c_str();
482 else
483 ret="";
484 s_lock.unlock();
485 return ret;
486 }
487
getVendorString() const488 const char * GLEScontext::getVendorString() const {
489 return s_glVendor.c_str();
490 }
491
getRendererString() const492 const char * GLEScontext::getRendererString() const {
493 return s_glRenderer.c_str();
494 }
495
getVersionString() const496 const char * GLEScontext::getVersionString() const {
497 return s_glVersion.c_str();
498 }
499
getGlobalLock()500 void GLEScontext::getGlobalLock() {
501 s_lock.lock();
502 }
503
releaseGlobalLock()504 void GLEScontext::releaseGlobalLock() {
505 s_lock.unlock();
506 }
507
508
initCapsLocked(const GLubyte * extensionString)509 void GLEScontext::initCapsLocked(const GLubyte * extensionString)
510 {
511 const char* cstring = (const char*)extensionString;
512
513 s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs);
514 s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane);
515 s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights);
516 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
517 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits);
518 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits);
519 const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION);
520 s_glSupport.glslVersion = Version((const char*)(glslVersion));
521
522 if (strstr(cstring,"GL_EXT_bgra ")!=NULL)
523 s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;
524
525 if (strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL)
526 s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true;
527
528 if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL)
529 s_glSupport.GL_ARB_VERTEX_BLEND = true;
530
531 if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL)
532 s_glSupport.GL_ARB_MATRIX_PALETTE = true;
533
534 if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL )
535 s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true;
536
537 if (strstr(cstring,"GL_OES_read_format ")!=NULL)
538 s_glSupport.GL_OES_READ_FORMAT = true;
539
540 if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL)
541 s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true;
542
543 if (strstr(cstring,"GL_NV_half_float ")!=NULL)
544 s_glSupport.GL_NV_HALF_FLOAT = true;
545
546 if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL)
547 s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true;
548
549 if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL)
550 s_glSupport.GL_SGIS_GENERATE_MIPMAP = true;
551
552 if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL)
553 s_glSupport.GL_ARB_ES2_COMPATIBILITY = true;
554
555 if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL)
556 s_glSupport.GL_OES_STANDARD_DERIVATIVES = true;
557
558 }
559
buildStrings(const char * baseVendor,const char * baseRenderer,const char * baseVersion,const char * version)560 void GLEScontext::buildStrings(const char* baseVendor,
561 const char* baseRenderer, const char* baseVersion, const char* version)
562 {
563 static const char VENDOR[] = {"Google ("};
564 static const char RENDERER[] = {"Android Emulator OpenGL ES Translator ("};
565 const size_t VENDOR_LEN = sizeof(VENDOR) - 1;
566 const size_t RENDERER_LEN = sizeof(RENDERER) - 1;
567
568 size_t baseVendorLen = strlen(baseVendor);
569 s_glVendor.clear();
570 s_glVendor.reserve(baseVendorLen + VENDOR_LEN + 1);
571 s_glVendor.append(VENDOR, VENDOR_LEN);
572 s_glVendor.append(baseVendor, baseVendorLen);
573 s_glVendor.append(")", 1);
574
575 size_t baseRendererLen = strlen(baseRenderer);
576 s_glRenderer.clear();
577 s_glRenderer.reserve(baseRendererLen + RENDERER_LEN + 1);
578 s_glRenderer.append(RENDERER, RENDERER_LEN);
579 s_glRenderer.append(baseRenderer, baseRendererLen);
580 s_glRenderer.append(")", 1);
581
582 size_t baseVersionLen = strlen(baseVersion);
583 size_t versionLen = strlen(version);
584 s_glVersion.clear();
585 s_glVersion.reserve(baseVersionLen + versionLen + 3);
586 s_glVersion.append(version, versionLen);
587 s_glVersion.append(" (", 2);
588 s_glVersion.append(baseVersion, baseVersionLen);
589 s_glVersion.append(")", 1);
590 }
591
isTextureUnitEnabled(GLenum unit)592 bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
593 for (int i=0;i<NUM_TEXTURE_TARGETS;++i) {
594 if (m_texState[unit-GL_TEXTURE0][i].enabled)
595 return true;
596 }
597 return false;
598 }
599
glGetBooleanv(GLenum pname,GLboolean * params)600 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params)
601 {
602 GLint iParam;
603
604 if(glGetIntegerv(pname, &iParam))
605 {
606 *params = (iParam != 0);
607 return true;
608 }
609
610 return false;
611 }
612
glGetFixedv(GLenum pname,GLfixed * params)613 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params)
614 {
615 bool result = false;
616 GLint numParams = 1;
617
618 GLint* iParams = new GLint[numParams];
619 if (numParams>0 && glGetIntegerv(pname,iParams)) {
620 while(numParams >= 0)
621 {
622 params[numParams] = I2X(iParams[numParams]);
623 numParams--;
624 }
625 result = true;
626 }
627 delete [] iParams;
628
629 return result;
630 }
631
glGetFloatv(GLenum pname,GLfloat * params)632 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params)
633 {
634 bool result = false;
635 GLint numParams = 1;
636
637 GLint* iParams = new GLint[numParams];
638 if (numParams>0 && glGetIntegerv(pname,iParams)) {
639 while(numParams >= 0)
640 {
641 params[numParams] = (GLfloat)iParams[numParams];
642 numParams--;
643 }
644 result = true;
645 }
646 delete [] iParams;
647
648 return result;
649 }
650
glGetIntegerv(GLenum pname,GLint * params)651 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
652 {
653 switch(pname)
654 {
655 case GL_ARRAY_BUFFER_BINDING:
656 *params = m_arrayBuffer;
657 break;
658
659 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
660 *params = m_elementBuffer;
661 break;
662
663 case GL_TEXTURE_BINDING_CUBE_MAP:
664 *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture;
665 break;
666
667 case GL_TEXTURE_BINDING_2D:
668 *params = m_texState[m_activeTexture][TEXTURE_2D].texture;
669 break;
670
671 case GL_ACTIVE_TEXTURE:
672 *params = m_activeTexture+GL_TEXTURE0;
673 break;
674
675 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
676 *params = GL_UNSIGNED_BYTE;
677 break;
678
679 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
680 *params = GL_RGBA;
681 break;
682 default:
683 return false;
684 }
685
686 return true;
687 }
688
GLTextureTargetToLocal(GLenum target)689 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) {
690 TextureTarget value=TEXTURE_2D;
691 switch (target) {
692 case GL_TEXTURE_CUBE_MAP:
693 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
694 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
695 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
696 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
697 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
698 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
699 value = TEXTURE_CUBE_MAP;
700 break;
701 case GL_TEXTURE_2D:
702 value = TEXTURE_2D;
703 break;
704 }
705 return value;
706 }
707
getBindedTexture(GLenum target)708 unsigned int GLEScontext::getBindedTexture(GLenum target) {
709 TextureTarget pos = GLTextureTargetToLocal(target);
710 return m_texState[m_activeTexture][pos].texture;
711 }
712
getBindedTexture(GLenum unit,GLenum target)713 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) {
714 TextureTarget pos = GLTextureTargetToLocal(target);
715 return m_texState[unit-GL_TEXTURE0][pos].texture;
716 }
717
setBindedTexture(GLenum target,unsigned int tex)718 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) {
719 TextureTarget pos = GLTextureTargetToLocal(target);
720 m_texState[m_activeTexture][pos].texture = tex;
721 }
722
setTextureEnabled(GLenum target,GLenum enable)723 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) {
724 TextureTarget pos = GLTextureTargetToLocal(target);
725 m_texState[m_activeTexture][pos].enabled = enable;
726 }
727
728 #define INTERNAL_NAME(x) (x +0x100000000ll);
729
getDefaultTextureName(GLenum target)730 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
731 ObjectLocalName name = 0;
732 switch (GLTextureTargetToLocal(target)) {
733 case TEXTURE_2D:
734 name = INTERNAL_NAME(0);
735 break;
736 case TEXTURE_CUBE_MAP:
737 name = INTERNAL_NAME(1);
738 break;
739 default:
740 name = 0;
741 break;
742 }
743 return name;
744 }
745
drawValidate(void)746 void GLEScontext::drawValidate(void)
747 {
748 if(m_framebuffer == 0)
749 return;
750
751 ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer);
752 if (fbObj.Ptr() == NULL)
753 return;
754
755 FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
756
757 fbData->validate(this);
758 }
759