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_glRenderer;
90 GLSupport GLEScontext::s_glSupport;
91
Version()92 Version::Version():m_major(0),
93 m_minor(0),
94 m_release(0){};
95
Version(int major,int minor,int release)96 Version::Version(int major,int minor,int release):m_major(major),
97 m_minor(minor),
98 m_release(release){};
99
Version(const Version & ver)100 Version::Version(const Version& ver):m_major(ver.m_major),
101 m_minor(ver.m_minor),
102 m_release(ver.m_release){}
103
Version(const char * versionString)104 Version::Version(const char* versionString){
105 m_release = 0;
106 if((!versionString) ||
107 ((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) &&
108 (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){
109 m_major = m_minor = 0; // the version is not in the right format
110 }
111 }
112
operator =(const Version & ver)113 Version& Version::operator=(const Version& ver){
114 m_major = ver.m_major;
115 m_minor = ver.m_minor;
116 m_release = ver.m_release;
117 return *this;
118 }
119
operator <(const Version & ver) const120 bool Version::operator<(const Version& ver) const{
121 if(m_major < ver.m_major) return true;
122 if(m_major == ver.m_major){
123 if(m_minor < ver.m_minor) return true;
124 if(m_minor == ver.m_minor){
125 return m_release < ver.m_release;
126 }
127 }
128 return false;
129 }
130
init()131 void GLEScontext::init() {
132
133 if (!s_glExtensions) {
134 initCapsLocked(s_glDispatch.glGetString(GL_EXTENSIONS));
135 s_glExtensions = new std::string("");
136 }
137
138 if (!m_initialized) {
139 initExtensionString();
140
141 int maxTexUnits = getMaxTexUnits();
142 m_texState = new textureUnitState[maxTexUnits];
143 for (int i=0;i<maxTexUnits;++i) {
144 for (int j=0;j<NUM_TEXTURE_TARGETS;++j)
145 {
146 m_texState[i][j].texture = 0;
147 m_texState[i][j].enabled = GL_FALSE;
148 }
149 }
150 }
151 }
152
GLEScontext()153 GLEScontext::GLEScontext():
154 m_initialized(false) ,
155 m_activeTexture(0) ,
156 m_unpackAlignment(4) ,
157 m_glError(GL_NO_ERROR) ,
158 m_texState(0) ,
159 m_arrayBuffer(0) ,
160 m_elementBuffer(0),
161 m_renderbuffer(0),
162 m_framebuffer(0)
163 {
164 };
165
getGLerror()166 GLenum GLEScontext::getGLerror() {
167 return m_glError;
168 }
169
setGLerror(GLenum err)170 void GLEScontext::setGLerror(GLenum err) {
171 m_glError = err;
172 }
173
setActiveTexture(GLenum tex)174 void GLEScontext::setActiveTexture(GLenum tex) {
175 m_activeTexture = tex - GL_TEXTURE0;
176 }
177
~GLEScontext()178 GLEScontext::~GLEScontext() {
179 for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) {
180 GLESpointer* p = (*it).second;
181 if(p) {
182 delete p;
183 }
184 }
185 delete[] m_texState;
186 m_texState = NULL;
187 }
188
setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid * data,bool normalize)189 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data,bool normalize) {
190 GLuint bufferName = m_arrayBuffer;
191 if(bufferName) {
192 unsigned int offset = ToTargetCompatibleHandle((uintptr_t)data);
193 GLESbuffer* vbo = static_cast<GLESbuffer*>(m_shareGroup->getObjectData(VERTEXBUFFER,bufferName).Ptr());
194 m_map[arrType]->setBuffer(size,type,stride,vbo,bufferName,offset,normalize);
195 return static_cast<const unsigned char*>(vbo->getData()) + offset;
196 }
197 m_map[arrType]->setArray(size,type,stride,data,normalize);
198 return data;
199 }
200
enableArr(GLenum arr,bool enable)201 void GLEScontext::enableArr(GLenum arr,bool enable) {
202 m_map[arr]->enable(enable);
203 }
204
isArrEnabled(GLenum arr)205 bool GLEScontext::isArrEnabled(GLenum arr) {
206 return m_map[arr]->isEnable();
207 }
208
getPointer(GLenum arrType)209 const GLESpointer* GLEScontext::getPointer(GLenum arrType) {
210 if (m_map.find(arrType) != m_map.end()) return m_map[arrType];
211 return NULL;
212 }
213
convertFixedDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)214 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
215
216 for(unsigned int i = 0; i < nBytes;i+=strideOut) {
217 const GLfixed* fixed_data = (const GLfixed *)dataIn;
218 //filling attrib
219 for(int j=0;j<attribSize;j++) {
220 reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]);
221 }
222 dataIn += strideIn;
223 }
224 }
225
convertFixedIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)226 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
227 for(int i = 0 ;i < count ;i++) {
228 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]:
229 ((GLushort *)indices)[i];
230 const GLfixed* fixed_data = (GLfixed *)(dataIn + index*strideIn);
231 GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
232
233 for(int j=0;j<attribSize;j++) {
234 float_data[j] = X2F(fixed_data[j]);
235 }
236 }
237 }
238
convertByteDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)239 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
240
241 for(unsigned int i = 0; i < nBytes;i+=strideOut) {
242 const GLbyte* byte_data = (const GLbyte *)dataIn;
243 //filling attrib
244 for(int j=0;j<attribSize;j++) {
245 reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]);
246 }
247 dataIn += strideIn;
248 }
249 }
250
convertByteIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)251 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
252 for(int i = 0 ;i < count ;i++) {
253 unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]:
254 ((GLushort *)indices)[i];
255 const GLbyte* bytes_data = (GLbyte *)(dataIn + index*strideIn);
256 GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
257
258 for(int j=0;j<attribSize;j++) {
259 short_data[j] = B2S(bytes_data[j]);
260 }
261 }
262 }
directToBytesRanges(GLint first,GLsizei count,GLESpointer * p,RangeList & list)263 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) {
264
265 int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes
266 int stride = p->getStride()?p->getStride():attribSize;
267 int start = p->getBufferOffset()+first*attribSize;
268 if(!p->getStride()) {
269 list.addRange(Range(start,count*attribSize));
270 } else {
271 for(int i = 0 ;i < count; i++,start+=stride) {
272 list.addRange(Range(start,attribSize));
273 }
274 }
275 }
276
indirectToBytesRanges(const GLvoid * indices,GLenum indices_type,GLsizei count,GLESpointer * p,RangeList & list)277 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) {
278
279 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
280 int stride = p->getStride()?p->getStride():attribSize;
281 int start = p->getBufferOffset();
282 for(int i=0 ; i < count; i++) {
283 GLushort index = (indices_type == GL_UNSIGNED_SHORT?
284 static_cast<const GLushort*>(indices)[i]:
285 static_cast<const GLubyte*>(indices)[i]);
286 list.addRange(Range(start+index*stride,attribSize));
287
288 }
289 }
290
bytesRangesToIndices(RangeList & ranges,GLESpointer * p,GLushort * indices)291 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) {
292
293 int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
294 int stride = p->getStride()?p->getStride():attribSize;
295 int offset = p->getBufferOffset();
296
297 int n = 0;
298 for(int i=0;i<ranges.size();i++) {
299 int startIndex = (ranges[i].getStart() - offset) / stride;
300 int nElements = ranges[i].getSize()/attribSize;
301 for(int j=0;j<nElements;j++) {
302 indices[n++] = startIndex+j;
303 }
304 }
305 return n;
306 }
307
convertDirect(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)308 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
309
310 GLenum type = p->getType();
311 int attribSize = p->getSize();
312 unsigned int size = attribSize*count + first;
313 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
314 cArrs.allocArr(size,type);
315 int stride = p->getStride()?p->getStride():bytes*attribSize;
316 const char* data = (const char*)p->getArrayData() + (first*stride);
317
318 if(type == GL_FIXED) {
319 convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize);
320 } else if(type == GL_BYTE) {
321 convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize);
322 }
323 }
324
convertDirectVBO(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)325 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
326
327 RangeList ranges;
328 RangeList conversions;
329 GLushort* indices = NULL;
330 GLenum type = p->getType();
331 int attribSize = p->getSize();
332 int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
333 unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed);
334 char* data = (char*)p->getBufferData() + (first*stride);
335
336 if(p->bufferNeedConversion()) {
337 directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset
338 p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
339
340 if(conversions.size()) { // there are some elements to convert
341 indices = new GLushort[count];
342 int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array
343 convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize);
344 }
345 }
346 if(indices) delete[] indices;
347 cArrs.setArr(data,p->getStride(),GL_FLOAT);
348 }
349
findMaxIndex(GLsizei count,GLenum type,const GLvoid * indices)350 int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) {
351 //finding max index
352 int max = 0;
353 if(type == GL_UNSIGNED_BYTE) {
354 GLubyte* b_indices =(GLubyte *)indices;
355 for(int i=0;i<count;i++) {
356 if(b_indices[i] > max) max = b_indices[i];
357 }
358 } else {
359 GLushort* us_indices =(GLushort *)indices;
360 for(int i=0;i<count;i++) {
361 if(us_indices[i] > max) max = us_indices[i];
362 }
363 }
364 return max;
365 }
366
convertIndirect(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)367 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
368 GLenum type = p->getType();
369 int maxElements = findMaxIndex(count,type,indices) + 1;
370
371 int attribSize = p->getSize();
372 int size = attribSize * maxElements;
373 unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
374 cArrs.allocArr(size,type);
375 int stride = p->getStride()?p->getStride():bytes*attribSize;
376
377 const char* data = (const char*)p->getArrayData();
378 if(type == GL_FIXED) {
379 convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize);
380 } else if(type == GL_BYTE){
381 convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize);
382 }
383 }
384
convertIndirectVBO(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)385 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
386 RangeList ranges;
387 RangeList conversions;
388 GLushort* conversionIndices = NULL;
389 GLenum type = p->getType();
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
getRendererString() const486 const char * GLEScontext::getRendererString() const {
487 return s_glRenderer.c_str();
488 }
489
getGlobalLock()490 void GLEScontext::getGlobalLock() {
491 s_lock.lock();
492 }
493
releaseGlobalLock()494 void GLEScontext::releaseGlobalLock() {
495 s_lock.unlock();
496 }
497
498
initCapsLocked(const GLubyte * extensionString)499 void GLEScontext::initCapsLocked(const GLubyte * extensionString)
500 {
501 const char* cstring = (const char*)extensionString;
502
503 s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs);
504 s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane);
505 s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights);
506 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
507 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits);
508 s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits);
509 const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION);
510 s_glSupport.glslVersion = Version((const char*)(glslVersion));
511
512 if (strstr(cstring,"GL_EXT_bgra ")!=NULL)
513 s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;
514
515 if (strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL)
516 s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true;
517
518 if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL)
519 s_glSupport.GL_ARB_VERTEX_BLEND = true;
520
521 if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL)
522 s_glSupport.GL_ARB_MATRIX_PALETTE = true;
523
524 if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL )
525 s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true;
526
527 if (strstr(cstring,"GL_OES_read_format ")!=NULL)
528 s_glSupport.GL_OES_READ_FORMAT = true;
529
530 if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL)
531 s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true;
532
533 if (strstr(cstring,"GL_NV_half_float ")!=NULL)
534 s_glSupport.GL_NV_HALF_FLOAT = true;
535
536 if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL)
537 s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true;
538
539 if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL)
540 s_glSupport.GL_SGIS_GENERATE_MIPMAP = true;
541
542 if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL)
543 s_glSupport.GL_ARB_ES2_COMPATIBILITY = true;
544
545 if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL)
546 s_glSupport.GL_OES_STANDARD_DERIVATIVES = true;
547
548 }
549
isTextureUnitEnabled(GLenum unit)550 bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
551 for (int i=0;i<NUM_TEXTURE_TARGETS;++i) {
552 if (m_texState[unit-GL_TEXTURE0][i].enabled)
553 return true;
554 }
555 return false;
556 }
557
glGetBooleanv(GLenum pname,GLboolean * params)558 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params)
559 {
560 GLint iParam;
561
562 if(glGetIntegerv(pname, &iParam))
563 {
564 *params = (iParam != 0);
565 return true;
566 }
567
568 return false;
569 }
570
glGetFixedv(GLenum pname,GLfixed * params)571 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params)
572 {
573 bool result = false;
574 GLint numParams = 1;
575
576 GLint* iParams = new GLint[numParams];
577 if (numParams>0 && glGetIntegerv(pname,iParams)) {
578 while(numParams >= 0)
579 {
580 params[numParams] = I2X(iParams[numParams]);
581 numParams--;
582 }
583 result = true;
584 }
585 delete [] iParams;
586
587 return result;
588 }
589
glGetFloatv(GLenum pname,GLfloat * params)590 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params)
591 {
592 bool result = false;
593 GLint numParams = 1;
594
595 GLint* iParams = new GLint[numParams];
596 if (numParams>0 && glGetIntegerv(pname,iParams)) {
597 while(numParams >= 0)
598 {
599 params[numParams] = (GLfloat)iParams[numParams];
600 numParams--;
601 }
602 result = true;
603 }
604 delete [] iParams;
605
606 return result;
607 }
608
glGetIntegerv(GLenum pname,GLint * params)609 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
610 {
611 switch(pname)
612 {
613 case GL_ARRAY_BUFFER_BINDING:
614 *params = m_arrayBuffer;
615 break;
616
617 case GL_ELEMENT_ARRAY_BUFFER_BINDING:
618 *params = m_elementBuffer;
619 break;
620
621 case GL_TEXTURE_BINDING_CUBE_MAP:
622 *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture;
623 break;
624
625 case GL_TEXTURE_BINDING_2D:
626 *params = m_texState[m_activeTexture][TEXTURE_2D].texture;
627 break;
628
629 case GL_ACTIVE_TEXTURE:
630 *params = m_activeTexture+GL_TEXTURE0;
631 break;
632
633 case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
634 *params = GL_UNSIGNED_BYTE;
635 break;
636
637 case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
638 *params = GL_RGBA;
639 break;
640 default:
641 return false;
642 }
643
644 return true;
645 }
646
GLTextureTargetToLocal(GLenum target)647 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) {
648 TextureTarget value=TEXTURE_2D;
649 switch (target) {
650 case GL_TEXTURE_CUBE_MAP:
651 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
652 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
653 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
654 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
655 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
656 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
657 value = TEXTURE_CUBE_MAP;
658 break;
659 case GL_TEXTURE_2D:
660 value = TEXTURE_2D;
661 break;
662 }
663 return value;
664 }
665
getBindedTexture(GLenum target)666 unsigned int GLEScontext::getBindedTexture(GLenum target) {
667 TextureTarget pos = GLTextureTargetToLocal(target);
668 return m_texState[m_activeTexture][pos].texture;
669 }
670
getBindedTexture(GLenum unit,GLenum target)671 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) {
672 TextureTarget pos = GLTextureTargetToLocal(target);
673 return m_texState[unit-GL_TEXTURE0][pos].texture;
674 }
675
setBindedTexture(GLenum target,unsigned int tex)676 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) {
677 TextureTarget pos = GLTextureTargetToLocal(target);
678 m_texState[m_activeTexture][pos].texture = tex;
679 }
680
setTextureEnabled(GLenum target,GLenum enable)681 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) {
682 TextureTarget pos = GLTextureTargetToLocal(target);
683 m_texState[m_activeTexture][pos].enabled = enable;
684 }
685
686 #define INTERNAL_NAME(x) (x +0x100000000ll);
687
getDefaultTextureName(GLenum target)688 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
689 ObjectLocalName name = 0;
690 switch (GLTextureTargetToLocal(target)) {
691 case TEXTURE_2D:
692 name = INTERNAL_NAME(0);
693 break;
694 case TEXTURE_CUBE_MAP:
695 name = INTERNAL_NAME(1);
696 break;
697 default:
698 name = 0;
699 break;
700 }
701 return name;
702 }
703
drawValidate(void)704 void GLEScontext::drawValidate(void)
705 {
706 if(m_framebuffer == 0)
707 return;
708
709 ObjectDataPtr fbObj = m_shareGroup->getObjectData(FRAMEBUFFER,m_framebuffer);
710 if (fbObj.Ptr() == NULL)
711 return;
712
713 FramebufferData *fbData = (FramebufferData *)fbObj.Ptr();
714
715 fbData->validate(this);
716 }
717