• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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