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