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