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