• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 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 "GLEScmContext.h"
18 #include "GLEScmUtils.h"
19 #include <GLcommon/GLutils.h>
20 #include <GLcommon/GLconversion_macros.h>
21 #include <string.h>
22 #include <GLES/gl.h>
23 #include <GLES/glext.h>
24 
25 #include "base/Lock.h"
26 #include "base/StreamSerializing.h"
27 #include "host-common/crash_reporter.h"
28 #include "GLEScmValidate.h"
29 
30 #include <glm/vec3.hpp>
31 #include <glm/vec4.hpp>
32 #include <glm/gtc/matrix_transform.hpp>
33 #include <glm/gtc/type_ptr.hpp>
34 
35 static GLESVersion s_maxGlesVersion = GLES_1_1;
36 
setMaxGlesVersion(GLESVersion version)37 void GLEScmContext::setMaxGlesVersion(GLESVersion version) {
38     s_maxGlesVersion = version;
39 }
40 
init()41 void GLEScmContext::init() {
42     android::base::AutoLock mutex(s_lock);
43     if(!m_initialized) {
44         GLEScontext::init();
45 
46         addVertexArrayObject(0);
47         setVertexArrayObject(0);
48 
49         m_currVaoState[GL_COLOR_ARRAY]          = new GLESpointer();
50         m_currVaoState[GL_NORMAL_ARRAY]         = new GLESpointer();
51         m_currVaoState[GL_VERTEX_ARRAY]         = new GLESpointer();
52         m_currVaoState[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer();
53 
54         m_texCoords = new GLESpointer[kMaxTextureUnits];
55         m_currVaoState[GL_TEXTURE_COORD_ARRAY]  = &m_texCoords[m_clientActiveTexture];
56 
57         if (isCoreProfile()) {
58             m_coreProfileEngine = new CoreProfileEngine(this);
59         } else if (isGles2Gles()) {
60             m_coreProfileEngine = new CoreProfileEngine(this, true /* gles2gles */);
61         }
62         mColor.type = GL_UNSIGNED_BYTE;
63         mColor.val.ubyteVal[0] = 255;
64         mColor.val.ubyteVal[1] = 255;
65         mColor.val.ubyteVal[2] = 255;
66         mColor.val.ubyteVal[3] = 255;
67         mNormal.type = GL_FLOAT;
68         mNormal.val.floatVal[0] = 0.0f;
69         mNormal.val.floatVal[1] = 0.0f;
70         mNormal.val.floatVal[2] = 1.0f;
71     }
72     m_initialized = true;
73 }
74 
initGlobal(EGLiface * eglIface)75 void GLEScmContext::initGlobal(EGLiface* eglIface) {
76     s_glDispatch.dispatchFuncs(s_maxGlesVersion, eglIface->eglGetGlLibrary(), eglIface->getProcAddress);
77     GLEScontext::initGlobal(eglIface);
78     buildStrings(true /* is gles1 */,
79                  (const char*)dispatcher().glGetString(GL_VENDOR),
80                  (const char*)dispatcher().glGetString(GL_RENDERER),
81                  (const char*)dispatcher().glGetString(GL_VERSION),
82                  "OpenGL ES-CM 1.1");
83 }
84 
initDefaultFBO(GLint width,GLint height,GLint colorFormat,GLint depthstencilFormat,GLint multisamples,GLuint * eglSurfaceRBColorId,GLuint * eglSurfaceRBDepthId,GLuint readWidth,GLint readHeight,GLint readColorFormat,GLint readDepthstencilFormat,GLint readMultisamples,GLuint * eglReadSurfaceRBColorId,GLuint * eglReadSurfaceRBDepthId)85 void GLEScmContext::initDefaultFBO(
86         GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
87         GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
88         GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthstencilFormat, GLint readMultisamples,
89         GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
90     GLEScontext::initDefaultFBO(
91             width, height, colorFormat, depthstencilFormat, multisamples,
92             eglSurfaceRBColorId, eglSurfaceRBDepthId,
93             readWidth, readHeight, readColorFormat, readDepthstencilFormat, readMultisamples,
94             eglReadSurfaceRBColorId, eglReadSurfaceRBDepthId
95             );
96 }
97 
GLEScmContext(int maj,int min,GlobalNameSpace * globalNameSpace,android::base::Stream * stream)98 GLEScmContext::GLEScmContext(int maj, int min,
99         GlobalNameSpace* globalNameSpace, android::base::Stream* stream)
100     : GLEScontext(globalNameSpace, stream, nullptr) {
101     if (stream) {
102         assert(maj == m_glesMajorVersion);
103         assert(min == m_glesMinorVersion);
104         android::base::loadBuffer(stream, &mProjMatrices);
105         android::base::loadBuffer(stream, &mModelviewMatrices);
106         android::base::loadBuffer(stream, &mTextureMatrices,
107                 [](android::base::Stream* stream) {
108                     MatrixStack matrices;
109                     android::base::loadBuffer(stream, &matrices);
110                     return matrices;
111                 });
112         android::base::loadBuffer(stream, &mTexUnitEnvs,
113                 [](android::base::Stream* stream) {
114                     TexEnv texEnv;
115                     android::base::loadCollection(stream, &texEnv,
116                             [] (android::base::Stream* stream) {
117                                 GLenum idx = stream->getBe32();
118                                 GLValTyped val;
119                                 stream->read(&val, sizeof(GLValTyped));
120                                 return std::make_pair(idx, val);
121                             });
122                     return texEnv;
123                 });
124         android::base::loadBuffer(stream, &mTexGens,
125                 [](android::base::Stream* stream) {
126                     TexEnv texEnv;
127                     android::base::loadCollection(stream, &texEnv,
128                             [] (android::base::Stream* stream) {
129                                 GLenum idx = stream->getBe32();
130                                 GLValTyped val;
131                                 stream->read(&val, sizeof(GLValTyped));
132                                 return std::make_pair(idx, val);
133                             });
134                     return texEnv;
135                 });
136         m_clientActiveTexture = stream->getBe32();
137         if (m_initialized) {
138             mShadeModel = stream->getBe32();
139             stream->read((void*)&mColor, sizeof(mColor));
140             stream->read((void*)&mNormal, sizeof(mNormal));
141             uint32_t size = stream->getBe32();
142             m_texCoords = new GLESpointer[size];
143             for (uint32_t i = 0; i < size; i++) {
144                 m_texCoords[i].onLoad(stream);
145             }
146             m_currVaoState[GL_TEXTURE_COORD_ARRAY] =
147                     &m_texCoords[m_clientActiveTexture];
148         }
149 
150         android::base::loadBufferPtr<GLVal>(stream, mMultiTexCoord);
151         android::base::loadBufferPtr<Material>(stream, &mMaterial);
152         android::base::loadBufferPtr<LightModel>(stream, &mLightModel);
153         android::base::loadBufferPtr<Light>(stream, mLights);
154         android::base::loadBufferPtr<Fog>(stream, &mFog);
155 
156     } else {
157         m_glesMajorVersion = maj;
158         m_glesMinorVersion = min;
159 
160         mProjMatrices.resize(1, glm::mat4());
161         mModelviewMatrices.resize(1, glm::mat4());
162         mTextureMatrices.resize(kMaxTextureUnits, { glm::mat4() });
163         mTexUnitEnvs.resize(kMaxTextureUnits, TexEnv());
164         mTexGens.resize(kMaxTextureUnits, TexEnv());
165 
166         for (int i = 0; i < kMaxTextureUnits; i++) {
167             mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].val.intVal[0] = GL_MODULATE;
168             mTexUnitEnvs[i][GL_TEXTURE_ENV_MODE].type = GL_INT;
169             mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[0] = 0.2f;
170             mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[1] = 0.4f;
171             mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[2] = 0.8f;
172             mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].val.floatVal[3] = 0.7f;
173             mTexUnitEnvs[i][GL_TEXTURE_ENV_COLOR].type = GL_FLOAT;
174             mTexUnitEnvs[i][GL_COMBINE_RGB].val.intVal[0] = GL_REPLACE;
175             mTexUnitEnvs[i][GL_COMBINE_RGB].type = GL_INT;
176             mTexUnitEnvs[i][GL_COMBINE_ALPHA].val.intVal[0] = GL_REPLACE;
177             mTexUnitEnvs[i][GL_COMBINE_ALPHA].type = GL_INT;
178         }
179 
180         // GL_LIGHT0 starts off as white
181         mLights[0].diffuse[0] = 1.0f;
182         mLights[0].diffuse[1] = 1.0f;
183         mLights[0].diffuse[2] = 1.0f;
184         mLights[0].diffuse[3] = 1.0f;
185         mLights[0].specular[0] = 1.0f;
186         mLights[0].specular[1] = 1.0f;
187         mLights[0].specular[2] = 1.0f;
188         mLights[0].specular[3] = 1.0f;
189     }
190 }
191 
192 
setActiveTexture(GLenum tex)193 void GLEScmContext::setActiveTexture(GLenum tex) {
194    m_activeTexture = tex - GL_TEXTURE0;
195 }
196 
setClientActiveTexture(GLenum tex)197 void GLEScmContext::setClientActiveTexture(GLenum tex) {
198    m_clientActiveTexture = tex - GL_TEXTURE0;
199    m_currVaoState[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_clientActiveTexture];
200 }
201 
setBindedTexture(GLenum target,unsigned int texture,unsigned int globalTexName)202 void GLEScmContext::setBindedTexture(GLenum target, unsigned int texture, unsigned int globalTexName) {
203     GLEScontext::setBindedTexture(target, texture);
204 }
205 
~GLEScmContext()206 GLEScmContext::~GLEScmContext(){
207     if(m_texCoords){
208         delete[] m_texCoords;
209         m_texCoords = NULL;
210     }
211     if (m_vaoStateMap.size()) {
212         m_currVaoState[GL_TEXTURE_COORD_ARRAY] = NULL;
213     }
214 
215     if (m_coreProfileEngine) {
216         delete m_coreProfileEngine;
217         m_coreProfileEngine = NULL;
218     }
219 }
220 
getMaterialInfo()221 const GLEScmContext::Material& GLEScmContext::getMaterialInfo() {
222     return mMaterial;
223 }
224 
getLightModelInfo()225 const GLEScmContext::LightModel& GLEScmContext::getLightModelInfo() {
226     return mLightModel;
227 }
228 
getLightInfo(uint32_t lightIndex)229 const GLEScmContext::Light& GLEScmContext::getLightInfo(uint32_t lightIndex) {
230     return mLights[lightIndex];
231 }
232 
getFogInfo()233 const GLEScmContext::Fog& GLEScmContext::getFogInfo() {
234     return mFog;
235 }
236 
onSave(android::base::Stream * stream) const237 void GLEScmContext::onSave(android::base::Stream* stream) const {
238     GLEScontext::onSave(stream);
239     android::base::saveBuffer(stream, mProjMatrices);
240     android::base::saveBuffer(stream, mModelviewMatrices);
241     android::base::saveBuffer(stream, mTextureMatrices,
242             [](android::base::Stream* stream, const MatrixStack& matrices) {
243                 android::base::saveBuffer(stream, matrices);
244             });
245     android::base::saveBuffer(stream, mTexUnitEnvs,
246             [](android::base::Stream* stream, const TexEnv& texEnv) {
247                 android::base::saveCollection(stream, texEnv,
248                         [] (android::base::Stream* stream,
249                             const std::pair<GLenum, GLValTyped>& it) {
250                             stream->putBe32(it.first);
251                             stream->write(&it.second, sizeof(GLValTyped));
252                         });
253             });
254     android::base::saveBuffer(stream, mTexGens,
255             [](android::base::Stream* stream, const TexEnv& texEnv) {
256                 android::base::saveCollection(stream, texEnv,
257                         [] (android::base::Stream* stream,
258                             const std::pair<GLenum, GLValTyped>& it) {
259                             stream->putBe32(it.first);
260                             stream->write(&it.second, sizeof(GLValTyped));
261                         });
262             });
263     stream->putBe32(m_clientActiveTexture);
264     if (m_initialized) {
265         stream->putBe32(mShadeModel);
266         stream->write((void*)&mColor, sizeof(mColor));
267         stream->write((void*)&mNormal, sizeof(mNormal));
268         stream->putBe32(kMaxTextureUnits);
269         for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
270             m_texCoords[i].onSave(stream);
271         }
272     }
273 
274     android::base::saveBuffer<GLVal>(stream, mMultiTexCoord, kMaxTextureUnits);
275     android::base::saveBuffer<Material>(stream, &mMaterial, 1);
276     android::base::saveBuffer<LightModel>(stream, &mLightModel, 1);
277     android::base::saveBuffer<Light>(stream, mLights, kMaxLights);
278     android::base::saveBuffer<Fog>(stream, &mFog, 1);
279 }
280 
restoreMatrixStack(const MatrixStack & matrices)281 void GLEScmContext::restoreMatrixStack(const MatrixStack& matrices) {
282     for (size_t i = 0; i < matrices.size(); i++) {
283         if (i > 0) {
284             dispatcher().glPushMatrix();
285         }
286         dispatcher().glLoadMatrixf(&matrices[i][0][0]);
287     }
288 }
289 
postLoadRestoreCtx()290 void GLEScmContext::postLoadRestoreCtx() {
291     if (isInitialized()) {
292         if (isCoreProfile()) {
293             m_coreProfileEngine = new CoreProfileEngine(this);
294         } else if (isGles2Gles()) {
295             m_coreProfileEngine = new CoreProfileEngine(this, true);
296         }
297         if (!m_coreProfileEngine) {
298             GLDispatch& dispatcher = GLEScontext::dispatcher();
299             dispatcher.glMatrixMode(GL_PROJECTION);
300             restoreMatrixStack(mProjMatrices);
301             dispatcher.glMatrixMode(GL_MODELVIEW);
302             restoreMatrixStack(mModelviewMatrices);
303             dispatcher.glMatrixMode(GL_TEXTURE);
304             for (size_t i = 0; i < mTextureMatrices.size(); i++) {
305                 if (mTextureMatrices[i].size() == 0) {
306                     continue;
307                 }
308                 dispatcher.glActiveTexture(GL_TEXTURE0 + i);
309                 restoreMatrixStack(mTextureMatrices[i]);
310             }
311             for (const auto& array : m_currVaoState) {
312                 if (array.first == GL_TEXTURE_COORD_ARRAY) continue;
313                 array.second->restoreBufferObj(getBufferObj);
314             }
315             for (uint32_t i = 0; i < kMaxTextureUnits; i++) {
316                 m_texCoords[i].restoreBufferObj(getBufferObj);
317             }
318             dispatcher.glMatrixMode(mCurrMatrixMode);
319             dispatcher.glActiveTexture(GL_TEXTURE0 + m_activeTexture);
320             for (const auto& it : *m_currVaoState.it->second.arraysMap) {
321                 if (GLEScmValidate::supportedArrays(it.first) &&
322                         it.first != GL_TEXTURE_COORD_ARRAY) {
323                     if (it.second->isEnable()) {
324                         dispatcher.glEnableClientState(it.first);
325                     } else {
326                         dispatcher.glDisableClientState(it.first);
327                     }
328                 }
329             }
330 
331             for (int i = 0; i < kMaxTextureUnits; i++) {
332                 GLESpointer* texcoord = m_texCoords + i;
333                 dispatcher.glClientActiveTexture(i + GL_TEXTURE0);
334                 if (texcoord->isEnable()) {
335                     dispatcher.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
336                 } else {
337                     dispatcher.glDisableClientState(GL_TEXTURE_COORD_ARRAY);
338                 }
339                 dispatcher.glActiveTexture(i + GL_TEXTURE0);
340                 for (const auto& texEnv : mTexUnitEnvs[i]) {
341                     GLenum target = texEnv.first == GL_POINT_SPRITE_OES ?
342                         GL_COORD_REPLACE_OES : GL_TEXTURE_ENV;
343                     if (texEnv.second.type == GL_INT) {
344                         dispatcher.glTexEnviv(target, texEnv.first,
345                                 texEnv.second.val.intVal);
346                     } else {
347                         assert(texEnv.second.type == GL_FLOAT);
348                         dispatcher.glTexEnvfv(target, texEnv.first,
349                                 texEnv.second.val.floatVal);
350                     }
351                 }
352             }
353             dispatcher.glClientActiveTexture(
354                     m_clientActiveTexture + GL_TEXTURE0);
355             dispatcher.glActiveTexture(m_activeTexture + GL_TEXTURE0);
356             dispatcher.glShadeModel(mShadeModel);
357             switch (mColor.type) {
358                 case GL_FLOAT:
359                     dispatcher.glColor4f(mColor.val.floatVal[0],
360                             mColor.val.floatVal[1],
361                             mColor.val.floatVal[2],
362                             mColor.val.floatVal[3]);
363                     break;
364                 case GL_UNSIGNED_BYTE:
365                     dispatcher.glColor4ub(mColor.val.ubyteVal[0],
366                             mColor.val.ubyteVal[1],
367                             mColor.val.ubyteVal[2],
368                             mColor.val.ubyteVal[3]);
369                     break;
370                 default:
371                     fprintf(stderr, "WARNING: glColor with unknown type 0x%x\n",
372                             mColor.type);
373                     break;
374             }
375             switch (mNormal.type) {
376                 case GL_FLOAT:
377                     dispatcher.glNormal3f(mNormal.val.floatVal[0],
378                             mNormal.val.floatVal[1],
379                             mNormal.val.floatVal[2]);
380                     break;
381                 default:
382                     fprintf(stderr, "WARNING: glNormal with unknown type 0x%x\n",
383                             mNormal.type);
384                     break;
385             }
386 
387             dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mMaterial.ambient);
388             dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mMaterial.diffuse);
389             dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mMaterial.specular);
390             dispatcher.glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mMaterial.emissive);
391             dispatcher.glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, mMaterial.specularExponent);
392 
393             dispatcher.glLightModelfv(GL_LIGHT_MODEL_AMBIENT, mLightModel.color);
394             dispatcher.glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, mLightModel.twoSided);
395 
396             for (int i = 0; i < kMaxLights; i++) {
397                 dispatcher.glLightfv(GL_LIGHT0 + i, GL_AMBIENT, mLights[i].ambient);
398                 dispatcher.glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mLights[i].diffuse);
399                 dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPECULAR, mLights[i].specular);
400                 dispatcher.glLightfv(GL_LIGHT0 + i, GL_POSITION, mLights[i].position);
401                 dispatcher.glLightfv(GL_LIGHT0 + i, GL_SPOT_DIRECTION, mLights[i].direction);
402                 dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_EXPONENT, mLights[i].spotlightExponent);
403                 dispatcher.glLightf(GL_LIGHT0 + i, GL_SPOT_CUTOFF, mLights[i].spotlightCutoffAngle);
404                 dispatcher.glLightf(GL_LIGHT0 + i, GL_CONSTANT_ATTENUATION, mLights[i].attenuationConst);
405                 dispatcher.glLightf(GL_LIGHT0 + i, GL_LINEAR_ATTENUATION, mLights[i].attenuationLinear);
406                 dispatcher.glLightf(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, mLights[i].attenuationQuadratic);
407             }
408 
409             dispatcher.glFogf(GL_FOG_MODE, (GLfloat)mFog.mode);
410             dispatcher.glFogf(GL_FOG_DENSITY, mFog.density);
411             dispatcher.glFogf(GL_FOG_START, mFog.start);
412             dispatcher.glFogf(GL_FOG_END, mFog.end);
413             dispatcher.glFogfv(GL_FOG_COLOR, mFog.color);
414         }
415     }
416     GLEScontext::postLoadRestoreCtx();
417 }
418 
419 //setting client side arr
setupArr(const GLvoid * arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized,int index,bool isInt)420 void GLEScmContext::setupArr(const GLvoid* arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized, int index, bool isInt){
421     if( arr == NULL) return;
422     switch(arrayType) {
423         case GL_VERTEX_ARRAY:
424             s_glDispatch.glVertexPointer(size,dataType,stride,arr);
425             break;
426         case GL_NORMAL_ARRAY:
427             s_glDispatch.glNormalPointer(dataType,stride,arr);
428             break;
429         case GL_TEXTURE_COORD_ARRAY:
430             s_glDispatch.glTexCoordPointer(size,dataType,stride,arr);
431             break;
432         case GL_COLOR_ARRAY:
433             s_glDispatch.glColorPointer(size,dataType,stride,arr);
434             break;
435         case GL_POINT_SIZE_ARRAY_OES:
436             m_pointsIndex = index;
437             break;
438     }
439 }
440 
441 
setupArrayPointerHelper(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLenum array_id,GLESpointer * p)442 void GLEScmContext::setupArrayPointerHelper(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLenum array_id,GLESpointer* p){
443         unsigned int size = p->getSize();
444         GLenum dataType = p->getType();
445 
446         if(needConvert(cArrs,first,count,type,indices,direct,p,array_id)){
447             //conversion has occured
448             ArrayData currentArr = cArrs.getCurrentArray();
449             setupArr(currentArr.data,array_id,currentArr.type,size,currentArr.stride,GL_FALSE, cArrs.getCurrentIndex());
450             ++cArrs;
451         } else {
452             setupArr(p->getData(),array_id,dataType,size,p->getStride(), GL_FALSE);
453         }
454 }
455 
setupArraysPointers(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct)456 void GLEScmContext::setupArraysPointers(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct) {
457     ArraysMap::iterator it;
458     m_pointsIndex = -1;
459 
460     //going over all clients arrays Pointers
461     for ( it=m_currVaoState.begin() ; it != m_currVaoState.end(); ++it) {
462 
463         GLenum array_id   = (*it).first;
464         GLESpointer* p = (*it).second;
465         if(!p->isEnable()) continue;
466         if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later
467         setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
468     }
469 
470     unsigned int activeTexture = m_clientActiveTexture + GL_TEXTURE0;
471 
472     //converting all texture coords arrays
473     for(int i=0; i< kMaxTextureUnits;i++) {
474 
475         unsigned int tex = GL_TEXTURE0+i;
476         setClientActiveTexture(tex);
477         s_glDispatch.glClientActiveTexture(tex);
478 
479         GLenum array_id   = GL_TEXTURE_COORD_ARRAY;
480         GLESpointer* p = m_currVaoState[array_id];
481         if(!p->isEnable()) continue;
482         setupArrayPointerHelper(cArrs,first,count,type,indices,direct,array_id,p);
483     }
484 
485     setClientActiveTexture(activeTexture);
486     s_glDispatch.glClientActiveTexture(activeTexture);
487 }
488 
drawPointsData(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices_in,bool isElemsDraw)489 void  GLEScmContext::drawPointsData(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) {
490     const char  *pointsArr =  NULL;
491     int stride = 0;
492     GLESpointer* p = m_currVaoState[GL_POINT_SIZE_ARRAY_OES];
493 
494     //choosing the right points sizes array source
495     if(m_pointsIndex >= 0) { //point size array was converted
496         pointsArr = (const char*)(cArrs[m_pointsIndex].data);
497         stride = cArrs[m_pointsIndex].stride;
498     } else {
499         pointsArr = static_cast<const char*>(p->getData());
500         stride = p->getStride();
501     }
502 
503     if(stride == 0){
504         stride = sizeof(GLfloat);
505     }
506 
507 
508     if(isElemsDraw) {
509         int tSize = 0;
510         switch (type) {
511             case GL_UNSIGNED_BYTE:
512                 tSize = 1;
513                 break;
514             case GL_UNSIGNED_SHORT:
515                 tSize = 2;
516                 break;
517             case GL_UNSIGNED_INT:
518                 tSize = 4;
519                 break;
520         };
521 
522         int i = 0;
523         while(i<count)
524         {
525             int sStart = i;
526             int sCount = 1;
527 
528 #define INDEX \
529                 (type == GL_UNSIGNED_INT ? \
530                 static_cast<const GLuint*>(indices_in)[i]: \
531                 type == GL_UNSIGNED_SHORT ? \
532                 static_cast<const GLushort*>(indices_in)[i]: \
533                 static_cast<const GLubyte*>(indices_in)[i])
534 
535             GLfloat pSize = *((GLfloat*)(pointsArr+(INDEX*stride)));
536             i++;
537 
538             while(i < count && pSize == *((GLfloat*)(pointsArr+(INDEX*stride))))
539             {
540                 sCount++;
541                 i++;
542             }
543 
544             s_glDispatch.glPointSize(pSize);
545             s_glDispatch.glDrawElements(GL_POINTS, sCount, type, (char*)indices_in+sStart*tSize);
546         }
547     } else {
548         int i = 0;
549         while(i<count)
550         {
551             int sStart = i;
552             int sCount = 1;
553             GLfloat pSize = *((GLfloat*)(pointsArr+((first+i)*stride)));
554             i++;
555 
556             while(i < count && pSize == *((GLfloat*)(pointsArr+((first+i)*stride))))
557             {
558                 sCount++;
559                 i++;
560             }
561 
562             s_glDispatch.glPointSize(pSize);
563             s_glDispatch.glDrawArrays(GL_POINTS, first+sStart, sCount);
564         }
565     }
566 }
567 
drawPointsArrs(GLESConversionArrays & arrs,GLint first,GLsizei count)568 void  GLEScmContext::drawPointsArrs(GLESConversionArrays& arrs,GLint first,GLsizei count) {
569     drawPointsData(arrs,first,count,0,NULL,false);
570 }
571 
drawPointsElems(GLESConversionArrays & arrs,GLsizei count,GLenum type,const GLvoid * indices_in)572 void GLEScmContext::drawPointsElems(GLESConversionArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) {
573     drawPointsData(arrs,0,count,type,indices_in,true);
574 }
575 
doConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)576 bool GLEScmContext::doConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
577     return needConvert(cArrs, first, count, type, indices, direct, p, array_id);
578 }
579 
getColor() const580 std::vector<float> GLEScmContext::getColor() const {
581     switch (mColor.type) {
582         case GL_UNSIGNED_BYTE:
583             return
584             { mColor.val.ubyteVal[0] / 255.0f,
585               mColor.val.ubyteVal[1] / 255.0f,
586               mColor.val.ubyteVal[2] / 255.0f,
587               mColor.val.ubyteVal[3] / 255.0f, };
588         default:
589         case GL_FLOAT:
590             return { mColor.val.floatVal[0],
591                      mColor.val.floatVal[1],
592                      mColor.val.floatVal[2],
593                      mColor.val.floatVal[3], };
594     }
595 }
596 
getNormal() const597 std::vector<float> GLEScmContext::getNormal() const {
598     return
599         { mNormal.val.floatVal[0],
600           mNormal.val.floatVal[1],
601           mNormal.val.floatVal[2] };
602 }
603 
getMultiTexCoord(uint32_t index) const604 std::vector<float> GLEScmContext::getMultiTexCoord(uint32_t index) const {
605     return // s, t, r, qcomponents
606         { mMultiTexCoord[index].floatVal[0],
607           mMultiTexCoord[index].floatVal[1],
608           mMultiTexCoord[index].floatVal[2],
609           mMultiTexCoord[index].floatVal[3] };
610 }
611 
getTextureEnvMode()612 GLenum GLEScmContext::getTextureEnvMode() {
613     return mTexUnitEnvs[m_activeTexture][GL_TEXTURE_ENV_MODE].val.intVal[0];
614 }
615 
getTextureGenMode()616 GLenum GLEScmContext::getTextureGenMode() {
617     return mTexGens[m_activeTexture][GL_TEXTURE_GEN_MODE_OES].val.intVal[0];
618 }
619 
getProjMatrix()620 glm::mat4 GLEScmContext::getProjMatrix() {
621     return mProjMatrices.back();
622 }
623 
getModelviewMatrix()624 glm::mat4 GLEScmContext::getModelviewMatrix() {
625     return mModelviewMatrices.back();
626 }
627 
getTextureMatrix()628 glm::mat4 GLEScmContext::getTextureMatrix() {
629     return mTextureMatrices[m_activeTexture].back();
630 }
631 
currMatrix()632 glm::mat4& GLEScmContext::currMatrix() {
633     return currMatrixStack().back();
634 }
635 
currMatrixStack()636 GLEScmContext::MatrixStack& GLEScmContext::currMatrixStack() {
637     switch (mCurrMatrixMode) {
638     case GL_TEXTURE:
639         return mTextureMatrices[m_activeTexture];
640     case GL_PROJECTION:
641         return mProjMatrices;
642     case GL_MODELVIEW:
643         return mModelviewMatrices;
644     default:
645         break;
646         // emugl_crash_reporter("error: matrix mode set to 0x%x!", mCurrMatrixMode);
647     }
648     // Make compiler happy
649     return mModelviewMatrices;
650 }
651 
needConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)652 bool GLEScmContext::needConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
653 
654     bool usingVBO = p->getAttribType() == GLESpointer::BUFFER;
655     GLenum arrType = p->getType();
656     /*
657      conversion is not necessary in the following cases:
658       (*) array type is byte but it is not vertex or texture array
659       (*) array type is not fixed
660     */
661     if((arrType != GL_FIXED) && (arrType != GL_BYTE)) return false;
662     if((arrType == GL_BYTE   && (array_id != GL_VERTEX_ARRAY)) &&
663        (arrType == GL_BYTE   && (array_id != GL_TEXTURE_COORD_ARRAY)) ) return false;
664 
665 
666     bool byteVBO = (arrType == GL_BYTE) && usingVBO;
667     if(byteVBO){
668         p->redirectPointerData();
669     }
670 
671     if(!usingVBO || byteVBO) {
672         if (direct) {
673             convertDirect(cArrs,first,count,array_id,p);
674         } else {
675             convertIndirect(cArrs,count,type,indices,array_id,p);
676         }
677     } else {
678         if (direct) {
679             convertDirectVBO(cArrs,first,count,array_id,p) ;
680         } else {
681             convertIndirectVBO(cArrs,count,type,indices,array_id,p);
682         }
683     }
684     return true;
685 }
686 
getPointer(GLenum arrType)687 const GLESpointer* GLEScmContext::getPointer(GLenum arrType) {
688     GLenum type =
689         arrType == GL_VERTEX_ARRAY_POINTER          ? GL_VERTEX_ARRAY :
690         arrType == GL_NORMAL_ARRAY_POINTER          ? GL_NORMAL_ARRAY :
691         arrType == GL_TEXTURE_COORD_ARRAY_POINTER   ? GL_TEXTURE_COORD_ARRAY :
692         arrType == GL_COLOR_ARRAY_POINTER           ? GL_COLOR_ARRAY :
693         arrType == GL_POINT_SIZE_ARRAY_POINTER_OES  ? GL_POINT_SIZE_ARRAY_OES :
694         0;
695     if(type != 0)
696     {
697         return GLEScontext::getPointer(type);
698     }
699     return NULL;
700 }
701 
initExtensionString()702 void GLEScmContext::initExtensionString() {
703     if (s_glExtensionsGles1Initialized) return;
704 
705     *s_glExtensionsGles1 = "GL_OES_blend_func_separate GL_OES_blend_equation_separate GL_OES_blend_subtract "
706                       "GL_OES_byte_coordinates GL_OES_compressed_paletted_texture GL_OES_point_size_array "
707                       "GL_OES_point_sprite GL_OES_single_precision GL_OES_stencil_wrap GL_OES_texture_env_crossbar "
708                       "GL_OES_texture_mirored_repeat GL_OES_EGL_image GL_OES_element_index_uint GL_OES_draw_texture "
709                       "GL_OES_texture_cube_map GL_OES_draw_texture ";
710     if (s_glSupport.GL_OES_READ_FORMAT)
711         *s_glExtensionsGles1+="GL_OES_read_format ";
712     if (s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT) {
713         *s_glExtensionsGles1+="GL_OES_framebuffer_object GL_OES_depth24 GL_OES_depth32 GL_OES_fbo_render_mipmap "
714                          "GL_OES_rgb8_rgba8 GL_OES_stencil1 GL_OES_stencil4 GL_OES_stencil8 ";
715     }
716     if (s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL)
717         *s_glExtensionsGles1+="GL_OES_packed_depth_stencil ";
718     if (s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888)
719         *s_glExtensionsGles1+="GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
720     if (s_glSupport.GL_ARB_MATRIX_PALETTE && s_glSupport.GL_ARB_VERTEX_BLEND) {
721         *s_glExtensionsGles1+="GL_OES_matrix_palette ";
722         GLint max_palette_matrices=0;
723         GLint max_vertex_units=0;
724         dispatcher().glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES,&max_palette_matrices);
725         dispatcher().glGetIntegerv(GL_MAX_VERTEX_UNITS_OES,&max_vertex_units);
726         if (max_palette_matrices>=32 && max_vertex_units>=4)
727             *s_glExtensionsGles1+="GL_OES_extended_matrix_palette ";
728     }
729     *s_glExtensionsGles1+="GL_OES_compressed_ETC1_RGB8_texture ";
730 
731     s_glExtensionsGles1Initialized = true;
732 }
733 
getMaxTexUnits()734 int GLEScmContext::getMaxTexUnits() {
735     return kMaxTextureUnits;
736 }
737 
glGetBooleanv(GLenum pname,GLboolean * params)738 bool GLEScmContext::glGetBooleanv(GLenum pname, GLboolean *params)
739 {
740     GLint iParam;
741 
742     if(glGetIntegerv(pname, &iParam))
743     {
744         *params = (iParam != 0);
745         return true;
746     }
747 
748     return false;
749 }
750 
glGetFixedv(GLenum pname,GLfixed * params)751 bool GLEScmContext::glGetFixedv(GLenum pname, GLfixed *params)
752 {
753     GLint iParam;
754 
755     if(glGetIntegerv(pname, &iParam))
756     {
757         *params = I2X(iParam);
758         return true;
759     }
760 
761     return false;
762 }
763 
glGetFloatv(GLenum pname,GLfloat * params)764 bool GLEScmContext::glGetFloatv(GLenum pname, GLfloat *params)
765 {
766     GLint iParam;
767 
768     if(glGetIntegerv(pname, &iParam))
769     {
770         *params = (GLfloat)iParam;
771         return true;
772     }
773 
774     return false;
775 }
776 
glGetIntegerv(GLenum pname,GLint * params)777 bool GLEScmContext::glGetIntegerv(GLenum pname, GLint *params)
778 {
779     if(GLEScontext::glGetIntegerv(pname, params))
780         return true;
781 
782     const GLESpointer* ptr = NULL;
783 
784     switch(pname){
785         case GL_VERTEX_ARRAY_BUFFER_BINDING:
786         case GL_VERTEX_ARRAY_SIZE:
787         case GL_VERTEX_ARRAY_STRIDE:
788         case GL_VERTEX_ARRAY_TYPE:
789             ptr = getPointer(GL_VERTEX_ARRAY_POINTER);
790             break;
791 
792         case GL_NORMAL_ARRAY_BUFFER_BINDING:
793         case GL_NORMAL_ARRAY_STRIDE:
794         case GL_NORMAL_ARRAY_TYPE:
795             ptr = getPointer(GL_NORMAL_ARRAY_POINTER);
796             break;
797 
798         case GL_COLOR_ARRAY_BUFFER_BINDING:
799         case GL_COLOR_ARRAY_SIZE:
800         case GL_COLOR_ARRAY_STRIDE:
801         case GL_COLOR_ARRAY_TYPE:
802             ptr = getPointer(GL_COLOR_ARRAY_POINTER);
803             break;
804 
805         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
806         case GL_TEXTURE_COORD_ARRAY_SIZE:
807         case GL_TEXTURE_COORD_ARRAY_STRIDE:
808         case GL_TEXTURE_COORD_ARRAY_TYPE:
809             ptr = getPointer(GL_TEXTURE_COORD_ARRAY_POINTER);
810             break;
811 
812         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
813         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
814         case GL_POINT_SIZE_ARRAY_TYPE_OES:
815             ptr = getPointer(GL_POINT_SIZE_ARRAY_POINTER_OES);
816             break;
817 
818         default:
819             return false;
820     }
821 
822     switch(pname)
823     {
824         case GL_VERTEX_ARRAY_BUFFER_BINDING:
825         case GL_NORMAL_ARRAY_BUFFER_BINDING:
826         case GL_COLOR_ARRAY_BUFFER_BINDING:
827         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
828         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
829             *params = ptr ? ptr->getBufferName() : 0;
830             break;
831 
832         case GL_VERTEX_ARRAY_STRIDE:
833         case GL_NORMAL_ARRAY_STRIDE:
834         case GL_COLOR_ARRAY_STRIDE:
835         case GL_TEXTURE_COORD_ARRAY_STRIDE:
836         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
837             *params = ptr ? ptr->getStride() : 0;
838             break;
839 
840         case GL_VERTEX_ARRAY_SIZE:
841         case GL_COLOR_ARRAY_SIZE:
842         case GL_TEXTURE_COORD_ARRAY_SIZE:
843             *params = ptr ? ptr->getSize() : 0;
844             break;
845 
846         case GL_VERTEX_ARRAY_TYPE:
847         case GL_NORMAL_ARRAY_TYPE:
848         case GL_COLOR_ARRAY_TYPE:
849         case GL_TEXTURE_COORD_ARRAY_TYPE:
850         case GL_POINT_SIZE_ARRAY_TYPE_OES:
851             *params = ptr ? ptr->getType() : 0;
852             break;
853     }
854 
855     return true;
856 }
857 
getErrorCoreProfile()858 GLint GLEScmContext::getErrorCoreProfile() {
859     return core().getAndClearLastError();
860 }
861 
enable(GLenum cap)862 void GLEScmContext::enable(GLenum cap) {
863     setEnable(cap, true);
864 
865     if (m_coreProfileEngine) {
866         core().enable(cap);
867     } else {
868         if (cap==GL_TEXTURE_GEN_STR_OES) {
869             dispatcher().glEnable(GL_TEXTURE_GEN_S);
870             dispatcher().glEnable(GL_TEXTURE_GEN_T);
871             dispatcher().glEnable(GL_TEXTURE_GEN_R);
872         } else {
873             dispatcher().glEnable(cap);
874         }
875     }
876 }
877 
disable(GLenum cap)878 void GLEScmContext::disable(GLenum cap) {
879     setEnable(cap, false);
880 
881     if (m_coreProfileEngine) {
882         core().disable(cap);
883     } else {
884         if (cap==GL_TEXTURE_GEN_STR_OES) {
885             dispatcher().glDisable(GL_TEXTURE_GEN_S);
886             dispatcher().glDisable(GL_TEXTURE_GEN_T);
887             dispatcher().glDisable(GL_TEXTURE_GEN_R);
888         } else {
889             dispatcher().glDisable(cap);
890         }
891     }
892 }
893 
shadeModel(GLenum mode)894 void GLEScmContext::shadeModel(GLenum mode) {
895     mShadeModel = mode;
896 
897     if (m_coreProfileEngine) {
898         core().shadeModel(mode);
899     } else {
900         dispatcher().glShadeModel(mode);
901     }
902 }
903 
matrixMode(GLenum mode)904 void GLEScmContext::matrixMode(GLenum mode) {
905     mCurrMatrixMode = mode;
906 
907     if (m_coreProfileEngine) {
908         core().matrixMode(mode);
909     } else {
910         dispatcher().glMatrixMode(mode);
911     }
912 }
913 
loadIdentity()914 void GLEScmContext::loadIdentity() {
915     currMatrix() = glm::mat4();
916 
917     if (m_coreProfileEngine) {
918         core().loadIdentity();
919     } else {
920         dispatcher().glLoadIdentity();
921     }
922 }
923 
loadMatrixf(const GLfloat * m)924 void GLEScmContext::loadMatrixf(const GLfloat* m) {
925     currMatrix() = glm::make_mat4(m);
926 
927     if (m_coreProfileEngine) {
928         core().loadMatrixf(m);
929     } else {
930         dispatcher().glLoadMatrixf(m);
931     }
932 }
933 
pushMatrix()934 void GLEScmContext::pushMatrix() {
935     if (currMatrixStack().size() >= kMaxMatrixStackSize) {
936         setGLerror(GL_STACK_OVERFLOW);
937         return;
938     }
939     currMatrixStack().emplace_back(currMatrixStack().back());
940 
941     if (m_coreProfileEngine) {
942         core().pushMatrix();
943     } else {
944         dispatcher().glPushMatrix();
945     }
946 }
947 
popMatrix()948 void GLEScmContext::popMatrix() {
949     if (currMatrixStack().size() == 1) {
950         setGLerror(GL_STACK_UNDERFLOW);
951         return;
952     }
953     currMatrixStack().pop_back();
954 
955     if (m_coreProfileEngine) {
956         core().popMatrix();
957     } else {
958         dispatcher().glPopMatrix();
959     }
960 }
961 
multMatrixf(const GLfloat * m)962 void GLEScmContext::multMatrixf(const GLfloat* m) {
963     currMatrix() *= glm::make_mat4(m);
964 
965     if (m_coreProfileEngine) {
966         core().multMatrixf(m);
967     } else {
968         dispatcher().glMultMatrixf(m);
969     }
970 }
971 
orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)972 void GLEScmContext::orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
973     currMatrix() *= glm::ortho(left, right, bottom, top, zNear, zFar);
974 
975     if (m_coreProfileEngine) {
976         core().orthof(left, right, bottom, top, zNear, zFar);
977     } else {
978         dispatcher().glOrtho(left,right,bottom,top,zNear,zFar);
979     }
980 }
981 
frustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)982 void GLEScmContext::frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) {
983     currMatrix() *= glm::frustum(left, right, bottom, top, zNear, zFar);
984 
985     if (m_coreProfileEngine) {
986         core().frustumf(left, right, bottom, top, zNear, zFar);
987     } else {
988         dispatcher().glFrustum(left,right,bottom,top,zNear,zFar);
989     }
990 }
991 
texEnvf(GLenum target,GLenum pname,GLfloat param)992 void GLEScmContext::texEnvf(GLenum target, GLenum pname, GLfloat param) {
993     // Assume |target| is GL_TEXTURE_ENV
994     if (pname == GL_TEXTURE_ENV_MODE) {
995         texEnvi(target, pname, (GLint)param);
996     } else {
997         mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0] = param;
998         mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
999     }
1000 
1001     if (m_coreProfileEngine) {
1002         core().texEnvf(target, pname, param);
1003     } else {
1004         dispatcher().glTexEnvf(target, pname, param);
1005     }
1006 }
1007 
texEnvfv(GLenum target,GLenum pname,const GLfloat * params)1008 void GLEScmContext::texEnvfv(GLenum target, GLenum pname, const GLfloat* params) {
1009     if (pname == GL_TEXTURE_ENV_COLOR) {
1010         for (int i = 0; i < 4; i++) {
1011             mTexUnitEnvs[m_activeTexture][pname].val.floatVal[i] = params[i];
1012             mTexUnitEnvs[m_activeTexture][pname].type = GL_FLOAT;
1013         }
1014     } else {
1015         texEnvf(target, pname, params[0]);
1016     }
1017 
1018     if (m_coreProfileEngine) {
1019         core().texEnvfv(target, pname, params);
1020     } else {
1021         dispatcher().glTexEnvfv(target, pname, params);
1022     }
1023 }
1024 
texEnvi(GLenum target,GLenum pname,GLint param)1025 void GLEScmContext::texEnvi(GLenum target, GLenum pname, GLint param) {
1026     mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = param;
1027     mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1028 
1029     if (m_coreProfileEngine) {
1030         core().texEnvi(target, pname, param);
1031     } else {
1032         dispatcher().glTexEnvi(target, pname, param);
1033     }
1034 }
1035 
texEnviv(GLenum target,GLenum pname,const GLint * params)1036 void GLEScmContext::texEnviv(GLenum target, GLenum pname, const GLint* params) {
1037     mTexUnitEnvs[m_activeTexture][pname].val.intVal[0] = params[0];
1038     mTexUnitEnvs[m_activeTexture][pname].type = GL_INT;
1039 
1040     if (m_coreProfileEngine) {
1041         core().texEnviv(target, pname, params);
1042     } else {
1043         dispatcher().glTexEnviv(target, pname, params);
1044     }
1045 }
1046 
getTexEnvfv(GLenum env,GLenum pname,GLfloat * params)1047 void GLEScmContext::getTexEnvfv(GLenum env, GLenum pname, GLfloat* params) {
1048     *params = mTexUnitEnvs[m_activeTexture][pname].val.floatVal[0];
1049 
1050     if (m_coreProfileEngine) {
1051         core().getTexEnvfv(env, pname, params);
1052     } else {
1053         dispatcher().glGetTexEnvfv(env, pname, params);
1054     }
1055 }
1056 
getTexEnviv(GLenum env,GLenum pname,GLint * params)1057 void GLEScmContext::getTexEnviv(GLenum env, GLenum pname, GLint* params) {
1058     *params = mTexUnitEnvs[m_activeTexture][pname].val.intVal[0];
1059 
1060     if (m_coreProfileEngine) {
1061         core().getTexEnviv(env, pname, params);
1062     } else {
1063         dispatcher().glGetTexEnviv(env, pname, params);
1064     }
1065 }
1066 
texGenf(GLenum coord,GLenum pname,GLfloat param)1067 void GLEScmContext::texGenf(GLenum coord, GLenum pname, GLfloat param) {
1068     mTexGens[m_activeTexture][pname].val.floatVal[0] = param;
1069     mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1070 
1071     if (m_coreProfileEngine) {
1072         core().texGenf(coord, pname, param);
1073     } else {
1074         if (coord == GL_TEXTURE_GEN_STR_OES) {
1075             dispatcher().glTexGenf(GL_S,pname,param);
1076             dispatcher().glTexGenf(GL_T,pname,param);
1077             dispatcher().glTexGenf(GL_R,pname,param);
1078         } else {
1079             dispatcher().glTexGenf(coord,pname,param);
1080         }
1081     }
1082 }
1083 
texGenfv(GLenum coord,GLenum pname,const GLfloat * params)1084 void GLEScmContext::texGenfv(GLenum coord, GLenum pname, const GLfloat* params) {
1085     mTexGens[m_activeTexture][pname].val.floatVal[0] = params[0];
1086     mTexGens[m_activeTexture][pname].type = GL_FLOAT;
1087 
1088     if (m_coreProfileEngine) {
1089         core().texGenfv(coord, pname, params);
1090     } else {
1091         if (coord == GL_TEXTURE_GEN_STR_OES) {
1092             dispatcher().glTexGenfv(GL_S,pname,params);
1093             dispatcher().glTexGenfv(GL_T,pname,params);
1094             dispatcher().glTexGenfv(GL_R,pname,params);
1095         } else {
1096             dispatcher().glTexGenfv(coord,pname,params);
1097         }
1098     }
1099 }
1100 
texGeni(GLenum coord,GLenum pname,GLint param)1101 void GLEScmContext::texGeni(GLenum coord, GLenum pname, GLint param) {
1102     mTexGens[m_activeTexture][pname].val.intVal[0] = param;
1103     mTexGens[m_activeTexture][pname].type = GL_INT;
1104 
1105     if (m_coreProfileEngine) {
1106         core().texGeni(coord, pname, param);
1107     } else {
1108         if (coord == GL_TEXTURE_GEN_STR_OES) {
1109             dispatcher().glTexGeni(GL_S,pname,param);
1110             dispatcher().glTexGeni(GL_T,pname,param);
1111             dispatcher().glTexGeni(GL_R,pname,param);
1112         } else {
1113             dispatcher().glTexGeni(coord,pname,param);
1114         }
1115     }
1116 }
1117 
texGeniv(GLenum coord,GLenum pname,const GLint * params)1118 void GLEScmContext::texGeniv(GLenum coord, GLenum pname, const GLint* params) {
1119     mTexGens[m_activeTexture][pname].val.intVal[0] = params[0];
1120     mTexGens[m_activeTexture][pname].type = GL_INT;
1121 
1122     if (m_coreProfileEngine) {
1123         core().texGeniv(coord, pname, params);
1124     } else {
1125         if (coord == GL_TEXTURE_GEN_STR_OES) {
1126             dispatcher().glTexGeniv(GL_S,pname,params);
1127             dispatcher().glTexGeniv(GL_T,pname,params);
1128             dispatcher().glTexGeniv(GL_R,pname,params);
1129         } else {
1130             dispatcher().glTexGeniv(coord,pname,params);
1131         }
1132     }
1133 }
1134 
getTexGeniv(GLenum coord,GLenum pname,GLint * params)1135 void GLEScmContext::getTexGeniv(GLenum coord, GLenum pname, GLint* params) {
1136     *params = mTexGens[m_activeTexture][pname].val.intVal[0];
1137 
1138     if (m_coreProfileEngine) {
1139         core().getTexGeniv(coord, pname, params);
1140     } else {
1141         if (coord == GL_TEXTURE_GEN_STR_OES) {
1142             GLint state_s = GL_FALSE;
1143             GLint state_t = GL_FALSE;
1144             GLint state_r = GL_FALSE;
1145             dispatcher().glGetTexGeniv(GL_S,pname,&state_s);
1146             dispatcher().glGetTexGeniv(GL_T,pname,&state_t);
1147             dispatcher().glGetTexGeniv(GL_R,pname,&state_r);
1148             *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1149         } else {
1150             dispatcher().glGetTexGeniv(coord,pname,params);
1151         }
1152     }
1153 }
1154 
getTexGenfv(GLenum coord,GLenum pname,GLfloat * params)1155 void GLEScmContext::getTexGenfv(GLenum coord, GLenum pname, GLfloat* params) {
1156     params[0] = mTexGens[m_activeTexture][pname].val.floatVal[0];
1157     params[1] = mTexGens[m_activeTexture][pname].val.floatVal[1];
1158     params[2] = mTexGens[m_activeTexture][pname].val.floatVal[2];
1159     params[3] = mTexGens[m_activeTexture][pname].val.floatVal[3];
1160 
1161     if (m_coreProfileEngine) {
1162         core().getTexGenfv(coord, pname, params);
1163     } else {
1164         if (coord == GL_TEXTURE_GEN_STR_OES) {
1165             GLfloat state_s = GL_FALSE;
1166             GLfloat state_t = GL_FALSE;
1167             GLfloat state_r = GL_FALSE;
1168             dispatcher().glGetTexGenfv(GL_S,pname,&state_s);
1169             dispatcher().glGetTexGenfv(GL_T,pname,&state_t);
1170             dispatcher().glGetTexGenfv(GL_R,pname,&state_r);
1171             *params = state_s && state_t && state_r ? GL_TRUE: GL_FALSE;
1172         } else {
1173             dispatcher().glGetTexGenfv(coord,pname,params);
1174         }
1175     }
1176 }
1177 
materialf(GLenum face,GLenum pname,GLfloat param)1178 void GLEScmContext::materialf(GLenum face, GLenum pname, GLfloat param) {
1179     if (face != GL_FRONT_AND_BACK) {
1180         fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x) "
1181                         "only supports GL_FRONT_AND_BACK for materials.\n");
1182         setGLerror(GL_INVALID_ENUM);
1183         return;
1184     }
1185     switch (pname) {
1186     case GL_AMBIENT:
1187     case GL_DIFFUSE:
1188     case GL_AMBIENT_AND_DIFFUSE:
1189     case GL_SPECULAR:
1190     case GL_EMISSION:
1191         fprintf(stderr, "GL_INVALID_ENUM: glMaterial(f/x) only supports "
1192                         "GL_SHININESS for single parameter setting.\n");
1193         setGLerror(GL_INVALID_ENUM);
1194         return;
1195     case GL_SHININESS:
1196         if (param < 0.0f || param > 128.0f) {
1197             fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1198                             "Only range [0.0, 128.0] supported.\n", param);
1199             setGLerror(GL_INVALID_VALUE);
1200             return;
1201         }
1202         mMaterial.specularExponent = param;
1203         break;
1204     default:
1205         fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)\n", pname);
1206         setGLerror(GL_INVALID_ENUM);
1207         return;
1208     }
1209 
1210     if (!m_coreProfileEngine) {
1211         dispatcher().glMaterialf(face, pname, param);
1212     }
1213 }
1214 
materialfv(GLenum face,GLenum pname,const GLfloat * params)1215 void GLEScmContext::materialfv(GLenum face, GLenum pname, const GLfloat* params) {
1216     if (face != GL_FRONT_AND_BACK) {
1217         fprintf(stderr, "GL_INVALID_ENUM: GLES1's glMaterial(f/x)v "
1218                         "only supports GL_FRONT_AND_BACK for materials.\n");
1219         setGLerror(GL_INVALID_ENUM);
1220         return;
1221     }
1222 
1223     switch (pname) {
1224     case GL_AMBIENT:
1225         memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1226         break;
1227     case GL_DIFFUSE:
1228         memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1229         break;
1230     case GL_AMBIENT_AND_DIFFUSE:
1231         memcpy(&mMaterial.ambient, params, 4 * sizeof(GLfloat));
1232         memcpy(&mMaterial.diffuse, params, 4 * sizeof(GLfloat));
1233         break;
1234     case GL_SPECULAR:
1235         memcpy(&mMaterial.specular, params, 4 * sizeof(GLfloat));
1236         break;
1237     case GL_EMISSION:
1238         memcpy(&mMaterial.emissive, params, 4 * sizeof(GLfloat));
1239         break;
1240     case GL_SHININESS:
1241         if (*params < 0.0f || *params > 128.0f) {
1242             fprintf(stderr, "GL_INVALID_VALUE: Invalid specular exponent value %f. "
1243                             "Only range [0.0, 128.0] supported.\n", *params);
1244             setGLerror(GL_INVALID_VALUE);
1245             return;
1246         }
1247         mMaterial.specularExponent = *params;
1248         break;
1249     default:
1250         fprintf(stderr, "Unknown parameter name 0x%x for glMaterial(f/x)v.\n", pname);
1251         setGLerror(GL_INVALID_ENUM);
1252         return;
1253     }
1254 
1255     if (!m_coreProfileEngine) {
1256         dispatcher().glMaterialfv(face, pname, params);
1257     }
1258 }
1259 
getMaterialfv(GLenum face,GLenum pname,GLfloat * params)1260 void GLEScmContext::getMaterialfv(GLenum face, GLenum pname, GLfloat* params) {
1261     if (face != GL_FRONT && face != GL_BACK) {
1262         fprintf(stderr, "GL_INVALID_ENUM: glGetMaterial(f/x)v "
1263                         "must take GL_FRONT or GL_BACK as face argument\n");
1264         setGLerror(GL_INVALID_ENUM);
1265         return;
1266     }
1267 
1268     switch (pname) {
1269     case GL_AMBIENT:
1270         memcpy(params, &mMaterial.ambient, 4 * sizeof(GLfloat));
1271         break;
1272     case GL_DIFFUSE:
1273         memcpy(params, &mMaterial.diffuse, 4 * sizeof(GLfloat));
1274         break;
1275     case GL_SPECULAR:
1276         memcpy(params, &mMaterial.specular, 4 * sizeof(GLfloat));
1277         break;
1278     case GL_EMISSION:
1279         memcpy(params, &mMaterial.emissive, 4 * sizeof(GLfloat));
1280         break;
1281     case GL_SHININESS:
1282         *params = mMaterial.specularExponent;
1283         break;
1284     default:
1285         fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glGetMaterial(f/x)v.\n", pname);
1286         setGLerror(GL_INVALID_ENUM);
1287         return;
1288     }
1289 
1290     if (!m_coreProfileEngine) {
1291         dispatcher().glGetMaterialfv(face, pname, params);
1292     }
1293 }
1294 
lightModelf(GLenum pname,GLfloat param)1295 void GLEScmContext::lightModelf(GLenum pname, GLfloat param) {
1296     switch (pname) {
1297         case GL_LIGHT_MODEL_AMBIENT:
1298             fprintf(stderr, "GL_INVALID_ENUM: glLightModelf only supports GL_LIGHT_MODEL_TWO_SIDE.\n");
1299             setGLerror(GL_INVALID_ENUM);
1300             return;
1301         case GL_LIGHT_MODEL_TWO_SIDE:
1302             if (param != 1.0f && param != 0.0f) {
1303                 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1304                                 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", param);
1305                 setGLerror(GL_INVALID_VALUE);
1306             }
1307             mLightModel.twoSided = param == 1.0f ? true : false;
1308             break;
1309         default:
1310             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1311             setGLerror(GL_INVALID_ENUM);
1312             return;
1313     }
1314 
1315     if (!m_coreProfileEngine) {
1316         dispatcher().glLightModelf(pname, param);
1317     }
1318 }
1319 
lightModelfv(GLenum pname,const GLfloat * params)1320 void GLEScmContext::lightModelfv(GLenum pname, const GLfloat* params) {
1321     switch (pname) {
1322         case GL_LIGHT_MODEL_AMBIENT:
1323             memcpy(&mLightModel.color, params, 4 * sizeof(GLfloat));
1324             break;
1325         case GL_LIGHT_MODEL_TWO_SIDE:
1326             if (*params != 1.0f && *params != 0.0f) {
1327                 fprintf(stderr, "GL_INVALID_VALUE: glLightModelf only takes 0 or 1 "
1328                                 "for GL_LIGHT_MODEL_TWO_SIDE, but got %f\n", *params);
1329                 setGLerror(GL_INVALID_VALUE);
1330             }
1331             mLightModel.twoSided = *params == 1.0f ? true : false;
1332             break;
1333         default:
1334             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x for glLightModel(f/x)v.\n", pname);
1335             setGLerror(GL_INVALID_ENUM);
1336             return;
1337     }
1338 
1339     if (!m_coreProfileEngine) {
1340         dispatcher().glLightModelfv(pname, params);
1341     }
1342 }
1343 
lightf(GLenum light,GLenum pname,GLfloat param)1344 void GLEScmContext::lightf(GLenum light, GLenum pname, GLfloat param) {
1345     uint32_t lightIndex = light - GL_LIGHT0;
1346 
1347     if (lightIndex >= kMaxLights) {
1348         fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for glLight(f/x) (wanted %u)\n",
1349                 lightIndex);
1350         setGLerror(GL_INVALID_ENUM);
1351         return;
1352     }
1353 
1354     switch (pname) {
1355         case GL_AMBIENT:
1356         case GL_DIFFUSE:
1357         case GL_SPECULAR:
1358         case GL_POSITION:
1359         case GL_SPOT_DIRECTION:
1360             fprintf(stderr, "GL_INVALID_ENUM: Invalid parameter name 0x%x "
1361                             "for glLight(f/x). Needs glLight(f/x)v.\n", pname);
1362             setGLerror(GL_INVALID_ENUM);
1363             return;
1364         case GL_SPOT_EXPONENT:
1365             mLights[lightIndex].spotlightExponent = param;
1366             break;
1367         case GL_SPOT_CUTOFF:
1368             mLights[lightIndex].spotlightCutoffAngle = param;
1369             break;
1370         case GL_CONSTANT_ATTENUATION:
1371             mLights[lightIndex].attenuationConst = param;
1372             break;
1373         case GL_LINEAR_ATTENUATION:
1374             mLights[lightIndex].attenuationLinear = param;
1375             break;
1376         case GL_QUADRATIC_ATTENUATION:
1377             mLights[lightIndex].attenuationQuadratic = param;
1378             break;
1379         default:
1380             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1381                             "for glLight(f/x).\n", pname);
1382             setGLerror(GL_INVALID_ENUM);
1383             return;
1384     }
1385 
1386     if (!m_coreProfileEngine) {
1387         dispatcher().glLightf(light, pname, param);
1388     }
1389 }
1390 
lightfv(GLenum light,GLenum pname,const GLfloat * params)1391 void GLEScmContext::lightfv(GLenum light, GLenum pname, const GLfloat* params) {
1392     uint32_t lightIndex = light - GL_LIGHT0;
1393 
1394     if (lightIndex >= kMaxLights) {
1395         fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1396                         "glLight(f/x)v (wanted %u)\n",
1397                 lightIndex);
1398         setGLerror(GL_INVALID_ENUM);
1399         return;
1400     }
1401 
1402     switch (pname) {
1403         case GL_AMBIENT:
1404             memcpy(&mLights[lightIndex].ambient, params, 4 * sizeof(GLfloat));
1405             break;
1406         case GL_DIFFUSE:
1407             memcpy(&mLights[lightIndex].diffuse, params, 4 * sizeof(GLfloat));
1408             break;
1409         case GL_SPECULAR:
1410             memcpy(&mLights[lightIndex].specular, params, 4 * sizeof(GLfloat));
1411             break;
1412         case GL_POSITION:
1413             memcpy(&mLights[lightIndex].position, params, 4 * sizeof(GLfloat));
1414             break;
1415         case GL_SPOT_DIRECTION:
1416             memcpy(&mLights[lightIndex].direction, params, 3 * sizeof(GLfloat));
1417             break;
1418         case GL_SPOT_EXPONENT:
1419             mLights[lightIndex].spotlightExponent = *params;
1420             break;
1421         case GL_SPOT_CUTOFF:
1422             mLights[lightIndex].spotlightCutoffAngle = *params;
1423             break;
1424         case GL_CONSTANT_ATTENUATION:
1425             mLights[lightIndex].attenuationConst = *params;
1426             break;
1427         case GL_LINEAR_ATTENUATION:
1428             mLights[lightIndex].attenuationLinear = *params;
1429             break;
1430         case GL_QUADRATIC_ATTENUATION:
1431             mLights[lightIndex].attenuationQuadratic = *params;
1432             break;
1433         default:
1434             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1435                             "for glLight(f/x).\n", pname);
1436             setGLerror(GL_INVALID_ENUM);
1437             return;
1438     }
1439 
1440     if (!m_coreProfileEngine) {
1441         dispatcher().glLightfv(light, pname, params);
1442     }
1443 }
1444 
getLightfv(GLenum light,GLenum pname,GLfloat * params)1445 void GLEScmContext::getLightfv(GLenum light, GLenum pname, GLfloat* params) {
1446     uint32_t lightIndex = light - GL_LIGHT0;
1447 
1448     if (lightIndex >= kMaxLights) {
1449         fprintf(stderr, "GL_INVALID_ENUM: Exceeded max lights for "
1450                         "glGetLight(f/x)v (wanted %u)\n",
1451                 lightIndex);
1452         setGLerror(GL_INVALID_ENUM);
1453         return;
1454     }
1455 
1456     switch (pname) {
1457         case GL_AMBIENT:
1458             memcpy(params, &mLights[lightIndex].ambient, 4 * sizeof(GLfloat));
1459             break;
1460         case GL_DIFFUSE:
1461             memcpy(params, &mLights[lightIndex].diffuse, 4 * sizeof(GLfloat));
1462             break;
1463         case GL_SPECULAR:
1464             memcpy(params, &mLights[lightIndex].specular, 4 * sizeof(GLfloat));
1465             break;
1466         case GL_POSITION:
1467             memcpy(params, &mLights[lightIndex].position, 4 * sizeof(GLfloat));
1468             break;
1469         case GL_SPOT_DIRECTION:
1470             memcpy(params, &mLights[lightIndex].direction, 3 * sizeof(GLfloat));
1471             break;
1472         case GL_SPOT_EXPONENT:
1473             *params = mLights[lightIndex].spotlightExponent;
1474             break;
1475         case GL_SPOT_CUTOFF:
1476             *params = mLights[lightIndex].spotlightCutoffAngle;
1477             break;
1478         case GL_CONSTANT_ATTENUATION:
1479             *params = mLights[lightIndex].attenuationConst;
1480             break;
1481         case GL_LINEAR_ATTENUATION:
1482             *params = mLights[lightIndex].attenuationLinear;
1483             break;
1484         case GL_QUADRATIC_ATTENUATION:
1485             *params = mLights[lightIndex].attenuationQuadratic;
1486             break;
1487         default:
1488             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1489                             "for glGetLight(f/x).\n", pname);
1490             setGLerror(GL_INVALID_ENUM);
1491             return;
1492     }
1493 
1494     if (!m_coreProfileEngine) {
1495         dispatcher().glGetLightfv(light, pname, params);
1496     }
1497 }
1498 
multiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)1499 void GLEScmContext::multiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) {
1500 
1501     mMultiTexCoord[target - GL_TEXTURE0].floatVal[0] = s;
1502     mMultiTexCoord[target - GL_TEXTURE0].floatVal[1] = t;
1503     mMultiTexCoord[target - GL_TEXTURE0].floatVal[2] = q;
1504     mMultiTexCoord[target - GL_TEXTURE0].floatVal[3] = r;
1505 
1506     if (!m_coreProfileEngine) {
1507         dispatcher().glMultiTexCoord4f(target, s, t, r, q);
1508     }
1509 }
1510 
normal3f(GLfloat nx,GLfloat ny,GLfloat nz)1511 void GLEScmContext::normal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
1512     mNormal.type = GL_FLOAT;
1513     mNormal.val.floatVal[0] = nx;
1514     mNormal.val.floatVal[1] = ny;
1515     mNormal.val.floatVal[2] = nz;
1516 
1517     if (!m_coreProfileEngine) {
1518         dispatcher().glNormal3f(nx, ny, nz);
1519     }
1520 }
1521 
fogf(GLenum pname,GLfloat param)1522 void GLEScmContext::fogf(GLenum pname, GLfloat param) {
1523     switch (pname) {
1524         case GL_FOG_MODE: {
1525             GLenum mode = (GLenum)param;
1526             switch (mode) {
1527                 case GL_EXP:
1528                 case GL_EXP2:
1529                 case GL_LINEAR:
1530                     mFog.mode = mode;
1531                     break;
1532                 default:
1533                     fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1534                                     "for glFog(f/x).\n", mode);
1535                     setGLerror(GL_INVALID_ENUM);
1536                     break;
1537             }
1538             break;
1539         }
1540         case GL_FOG_DENSITY:
1541             if (param < 0.0f) {
1542                 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x): GL_FOG_DENSITY "
1543                                 "needs to be nonnegative, but got %f\n", param);
1544                 setGLerror(GL_INVALID_VALUE);
1545                 return;
1546             }
1547             mFog.density = param;
1548             break;
1549         case GL_FOG_START:
1550             mFog.start = param;
1551             break;
1552         case GL_FOG_END:
1553             mFog.end = param;
1554             break;
1555         case GL_FOG_COLOR:
1556             fprintf(stderr, "GL_INVALID_ENUM: GL_FOG_COLOR not allowed for glFog(f/x).\n");
1557             setGLerror(GL_INVALID_ENUM);
1558             break;
1559         default:
1560             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1561                             "for glFog(f/x).\n", pname);
1562             setGLerror(GL_INVALID_ENUM);
1563             return;
1564     }
1565 
1566     if (!m_coreProfileEngine) {
1567         dispatcher().glFogf(pname, param);
1568     }
1569 }
1570 
fogfv(GLenum pname,const GLfloat * params)1571 void GLEScmContext::fogfv(GLenum pname, const GLfloat* params) {
1572     switch (pname) {
1573         case GL_FOG_MODE: {
1574             GLenum mode = (GLenum)params[0];
1575             switch (mode) {
1576                 case GL_EXP:
1577                 case GL_EXP2:
1578                 case GL_LINEAR:
1579                     mFog.mode = mode;
1580                     break;
1581                 default:
1582                     fprintf(stderr, "GL_INVALID_ENUM: Unknown GL_FOG_MODE 0x%x "
1583                                     "for glFog(f/x)v.\n", mode);
1584                     setGLerror(GL_INVALID_ENUM);
1585                     break;
1586             }
1587             break;
1588         }
1589         case GL_FOG_DENSITY:
1590             if (params[0] < 0.0f) {
1591                 fprintf(stderr, "GL_INVALID_VALUE: glFog(f/x)v: GL_FOG_DENSITY "
1592                                 "needs to be nonnegative, but got %f\n", params[0]);
1593                 setGLerror(GL_INVALID_VALUE);
1594                 return;
1595             }
1596             mFog.density = params[0];
1597             break;
1598         case GL_FOG_START:
1599             mFog.start = params[0];
1600             break;
1601         case GL_FOG_END:
1602             mFog.end = params[0];
1603             break;
1604         case GL_FOG_COLOR:
1605             memcpy(&mFog.color, params, 4 * sizeof(GLfloat));
1606             break;
1607         default:
1608             fprintf(stderr, "GL_INVALID_ENUM: Unknown parameter name 0x%x "
1609                             "for glFog(f/x)v.\n", pname);
1610             setGLerror(GL_INVALID_ENUM);
1611             return;
1612     }
1613 
1614     if (!m_coreProfileEngine) {
1615         dispatcher().glFogfv(pname, params);
1616     }
1617 }
1618 
enableClientState(GLenum clientState)1619 void GLEScmContext::enableClientState(GLenum clientState) {
1620     if (m_coreProfileEngine) {
1621         core().enableClientState(clientState);
1622     } else {
1623         dispatcher().glEnableClientState(clientState);
1624     }
1625 }
1626 
disableClientState(GLenum clientState)1627 void GLEScmContext::disableClientState(GLenum clientState) {
1628     if (m_coreProfileEngine) {
1629         core().disableClientState(clientState);
1630     } else {
1631         dispatcher().glDisableClientState(clientState);
1632     }
1633 }
1634 
drawTexOES(float x,float y,float z,float width,float height)1635 void GLEScmContext::drawTexOES(float x, float y, float z, float width, float height) {
1636     if (m_coreProfileEngine) {
1637         core().drawTexOES(x, y, z, width, height);
1638     } else {
1639         auto& gl = dispatcher();
1640 
1641         int numClipPlanes;
1642 
1643         GLint viewport[4] = {};
1644         z = (z>1 ? 1 : (z<0 ?  0 : z));
1645 
1646         float vertices[4*3] = {
1647             x , y, z,
1648             x , static_cast<float>(y+height), z,
1649             static_cast<float>(x+width), static_cast<float>(y+height), z,
1650             static_cast<float>(x+width), y, z
1651         };
1652         GLfloat texels[getMaxTexUnits()][4*2];
1653         memset((void*)texels, 0, getMaxTexUnits()*4*2*sizeof(GLfloat));
1654 
1655         gl.glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
1656         gl.glPushAttrib(GL_TRANSFORM_BIT);
1657 
1658         //setup projection matrix to draw in viewport aligned coordinates
1659         gl.glMatrixMode(GL_PROJECTION);
1660         gl.glPushMatrix();
1661         gl.glLoadIdentity();
1662         gl.glGetIntegerv(GL_VIEWPORT,viewport);
1663         gl.glOrtho(viewport[0],viewport[0] + viewport[2],viewport[1],viewport[1]+viewport[3],0,-1);
1664         //setup texture matrix
1665         gl.glMatrixMode(GL_TEXTURE);
1666         gl.glPushMatrix();
1667         gl.glLoadIdentity();
1668         //setup modelview matrix
1669         gl.glMatrixMode(GL_MODELVIEW);
1670         gl.glPushMatrix();
1671         gl.glLoadIdentity();
1672         //backup vbo's
1673         int array_buffer,element_array_buffer;
1674         gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING,&array_buffer);
1675         gl.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,&element_array_buffer);
1676         gl.glBindBuffer(GL_ARRAY_BUFFER,0);
1677         gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
1678 
1679         //disable clip planes
1680         gl.glGetIntegerv(GL_MAX_CLIP_PLANES,&numClipPlanes);
1681         for (int i=0;i<numClipPlanes;++i)
1682             gl.glDisable(GL_CLIP_PLANE0+i);
1683 
1684         int nTexPtrs = 0;
1685         for (int i=0;i<getMaxTexUnits();++i) {
1686             if (isTextureUnitEnabled(GL_TEXTURE0+i)) {
1687                 TextureData * texData = NULL;
1688                 unsigned int texname = getBindedTexture(GL_TEXTURE0+i,GL_TEXTURE_2D);
1689                 ObjectLocalName tex = getTextureLocalName(GL_TEXTURE_2D,texname);
1690                 gl.glClientActiveTexture(GL_TEXTURE0+i);
1691                 auto objData = shareGroup()->getObjectData(
1692                         NamedObjectType::TEXTURE, tex);
1693                 if (objData) {
1694                     texData = (TextureData*)objData;
1695                     //calculate texels
1696                     texels[i][0] = (float)(texData->crop_rect[0])/(float)(texData->width);
1697                     texels[i][1] = (float)(texData->crop_rect[1])/(float)(texData->height);
1698 
1699                     texels[i][2] = (float)(texData->crop_rect[0])/(float)(texData->width);
1700                     texels[i][3] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1701 
1702                     texels[i][4] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1703                     texels[i][5] = (float)(texData->crop_rect[3]+texData->crop_rect[1])/(float)(texData->height);
1704 
1705                     texels[i][6] = (float)(texData->crop_rect[2]+texData->crop_rect[0])/(float)(texData->width);
1706                     texels[i][7] = (float)(texData->crop_rect[1])/(float)(texData->height);
1707 
1708                     gl.glTexCoordPointer(2,GL_FLOAT,0,texels[i]);
1709                     nTexPtrs++;
1710                 }
1711             }
1712         }
1713 
1714         if (nTexPtrs>0) {
1715             //draw rectangle - only if we have some textures enabled & ready
1716             gl.glEnableClientState(GL_VERTEX_ARRAY);
1717             gl.glVertexPointer(3,GL_FLOAT,0,vertices);
1718             gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1719             gl.glDrawArrays(GL_TRIANGLE_FAN,0,4);
1720         }
1721 
1722         //restore vbo's
1723         gl.glBindBuffer(GL_ARRAY_BUFFER,array_buffer);
1724         gl.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,element_array_buffer);
1725 
1726         //restore matrix state
1727 
1728         gl.glMatrixMode(GL_MODELVIEW);
1729         gl.glPopMatrix();
1730         gl.glMatrixMode(GL_TEXTURE);
1731         gl.glPopMatrix();
1732         gl.glMatrixMode(GL_PROJECTION);
1733         gl.glPopMatrix();
1734 
1735         gl.glPopAttrib();
1736         gl.glPopClientAttrib();
1737     }
1738 }
1739 
rotatef(float angle,float x,float y,float z)1740 void GLEScmContext::rotatef(float angle, float x, float y, float z) {
1741     glm::mat4 rot = glm::rotate(glm::mat4(), 3.14159265358979f / 180.0f * angle, glm::vec3(x, y, z));
1742     currMatrix() *= rot;
1743 
1744     if (m_coreProfileEngine) {
1745         core().rotatef(angle, x, y, z);
1746     } else {
1747         dispatcher().glRotatef(angle, x, y, z);
1748     }
1749 }
1750 
scalef(float x,float y,float z)1751 void GLEScmContext::scalef(float x, float y, float z) {
1752     glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(x, y, z));
1753     currMatrix() *= scale;
1754 
1755     if (m_coreProfileEngine) {
1756         core().scalef(x, y, z);
1757     } else {
1758         dispatcher().glScalef(x, y, z);
1759     }
1760 }
1761 
translatef(float x,float y,float z)1762 void GLEScmContext::translatef(float x, float y, float z) {
1763     glm::mat4 tr = glm::translate(glm::mat4(), glm::vec3(x, y, z));
1764     currMatrix() *= tr;
1765 
1766     if (m_coreProfileEngine) {
1767         core().translatef(x, y, z);
1768     } else {
1769         dispatcher().glTranslatef(x, y, z);
1770     }
1771 }
1772 
color4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)1773 void GLEScmContext::color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
1774 
1775     mColor.type = GL_FLOAT;
1776     mColor.val.floatVal[0] = red;
1777     mColor.val.floatVal[1] = green;
1778     mColor.val.floatVal[2] = blue;
1779     mColor.val.floatVal[3] = alpha;
1780 
1781     if (m_coreProfileEngine) {
1782         core().color4f(red,green,blue,alpha);
1783     } else{
1784         dispatcher().glColor4f(red,green,blue,alpha);
1785     }
1786 }
1787 
color4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)1788 void GLEScmContext::color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
1789 
1790     mColor.type = GL_UNSIGNED_BYTE;
1791     mColor.val.ubyteVal[0] = red;
1792     mColor.val.ubyteVal[1] = green;
1793     mColor.val.ubyteVal[2] = blue;
1794     mColor.val.ubyteVal[3] = alpha;
1795 
1796     if (m_coreProfileEngine) {
1797         core().color4ub(red,green,blue,alpha);
1798     } else{
1799         dispatcher().glColor4ub(red,green,blue,alpha);
1800     }
1801 }
1802 
drawArrays(GLenum mode,GLint first,GLsizei count)1803 void GLEScmContext::drawArrays(GLenum mode, GLint first, GLsizei count) {
1804     if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1805 
1806     drawValidate();
1807 
1808     GLuint prev_vbo;
1809     GLuint prev_ibo;
1810     dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1811             (GLint*)&prev_vbo);
1812     dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1813             (GLint*)&prev_ibo);
1814     dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1815     dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1816 
1817     if (m_coreProfileEngine) {
1818         ArraysMap::iterator it;
1819         m_pointsIndex = -1;
1820 
1821         // going over all clients arrays Pointers
1822         for (it = m_currVaoState.begin();
1823              it != m_currVaoState.end(); ++it) {
1824             GLenum array_id = (*it).first;
1825             GLESpointer* p  = (*it).second;
1826             if (array_id == GL_VERTEX_ARRAY ||
1827                 array_id == GL_NORMAL_ARRAY ||
1828                 array_id == GL_COLOR_ARRAY ||
1829                 array_id == GL_POINT_SIZE_ARRAY_OES ||
1830                 array_id == GL_TEXTURE_COORD_ARRAY) {
1831                 core().setupArrayForDraw(array_id, p, first, count, false, 0, nullptr);
1832             }
1833         }
1834 
1835         GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1836         setClientActiveTexture(activeTexture);
1837         core().clientActiveTexture(activeTexture);
1838         core().drawArrays(mode, first, count);
1839     } else {
1840         GLESConversionArrays tmpArrs;
1841 
1842         setupArraysPointers(tmpArrs,first,count,0,NULL,true);
1843 
1844         if (mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1845             drawPointsArrs(tmpArrs,first,count);
1846         } else {
1847             dispatcher().glDrawArrays(mode,first,count);
1848         }
1849     }
1850     dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1851     dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1852 }
1853 
drawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1854 void GLEScmContext::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
1855     if (!isArrEnabled(GL_VERTEX_ARRAY)) return;
1856 
1857     drawValidate();
1858 
1859     if(isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo
1860         const unsigned char* buf = static_cast<unsigned char *>(getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER));
1861         indices = buf + SafeUIntFromPointer(indices);
1862     }
1863 
1864     GLuint prev_vbo;
1865     GLuint prev_ibo;
1866     dispatcher().glGetIntegerv(GL_ARRAY_BUFFER_BINDING,
1867             (GLint*)&prev_vbo);
1868     dispatcher().glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING,
1869             (GLint*)&prev_ibo);
1870     dispatcher().glBindBuffer(GL_ARRAY_BUFFER, 0);
1871     dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
1872 
1873     if (m_coreProfileEngine) {
1874         ArraysMap::iterator it;
1875         m_pointsIndex = -1;
1876 
1877         // going over all clients arrays Pointers
1878         for (it = m_currVaoState.begin();
1879              it != m_currVaoState.end(); ++it) {
1880             GLenum array_id = (*it).first;
1881             GLESpointer* p  = (*it).second;
1882             if (array_id == GL_VERTEX_ARRAY ||
1883                 array_id == GL_NORMAL_ARRAY ||
1884                 array_id == GL_COLOR_ARRAY ||
1885                 array_id == GL_POINT_SIZE_ARRAY_OES ||
1886                 array_id == GL_TEXTURE_COORD_ARRAY) {
1887                 core().setupArrayForDraw(array_id, p, 0, count, true, type, indices);
1888             }
1889         }
1890 
1891         GLenum activeTexture = m_clientActiveTexture + GL_TEXTURE0;
1892         setClientActiveTexture(activeTexture);
1893         core().clientActiveTexture(activeTexture);
1894         core().drawElements(mode, count, type, indices);
1895     } else {
1896         GLESConversionArrays tmpArrs;
1897 
1898         setupArraysPointers(tmpArrs,0,count,type,indices,false);
1899         if(mode == GL_POINTS && isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){
1900             drawPointsElems(tmpArrs,count,type,indices);
1901         }
1902         else{
1903             dispatcher().glDrawElements(mode,count,type,indices);
1904         }
1905     }
1906     dispatcher().glBindBuffer(GL_ARRAY_BUFFER, prev_vbo);
1907     dispatcher().glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_ibo);
1908 }
1909 
clientActiveTexture(GLenum texture)1910 void GLEScmContext::clientActiveTexture(GLenum texture) {
1911     if (m_coreProfileEngine) {
1912         core().clientActiveTexture(texture);
1913     } else {
1914         dispatcher().glClientActiveTexture(texture);
1915     }
1916 }
1917