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