• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include <GLcommon/GLEScontext.h>
18 
19 #include "base/Lock.h"
20 #include "base/Lookup.h"
21 #include "base/StreamSerializing.h"
22 #include "host-common/feature_control.h"
23 #include "host-common/logging.h"
24 
25 #include <GLcommon/GLconversion_macros.h>
26 #include <GLcommon/GLSnapshotSerializers.h>
27 #include <GLcommon/GLESmacros.h>
28 #include <GLcommon/TextureData.h>
29 #include <GLES/gl.h>
30 #include <GLES/glext.h>
31 #include <GLES2/gl2.h>
32 #include <GLES2/gl2ext.h>
33 #include <GLES3/gl3.h>
34 #include <GLES3/gl31.h>
35 #include <GLcommon/GLESvalidate.h>
36 #include <GLcommon/TextureUtils.h>
37 #include <GLcommon/FramebufferData.h>
38 #include <GLcommon/ScopedGLState.h>
39 #ifndef _MSC_VER
40 #include <strings.h>
41 #endif
42 #include <string.h>
43 
44 #include <numeric>
45 #include <map>
46 
47 //decleration
48 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
49 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize);
50 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize);
51 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize);
52 
onLoad(android::base::Stream * stream)53 void BufferBinding::onLoad(android::base::Stream* stream) {
54     buffer = stream->getBe32();
55     offset = stream->getBe32();
56     size = stream->getBe32();
57     stride = stream->getBe32();
58     divisor = stream->getBe32();
59     isBindBase = stream->getByte();
60 }
61 
onSave(android::base::Stream * stream) const62 void BufferBinding::onSave(android::base::Stream* stream) const {
63     stream->putBe32(buffer);
64     stream->putBe32(offset);
65     stream->putBe32(size);
66     stream->putBe32(stride);
67     stream->putBe32(divisor);
68     stream->putByte(isBindBase);
69 }
70 
VAOState(android::base::Stream * stream)71 VAOState::VAOState(android::base::Stream* stream) {
72     element_array_buffer_binding = stream->getBe32();
73 
74     vertexAttribInfo.clear();
75     for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
76         vertexAttribInfo.emplace_back(stream);
77     }
78 
79     uint64_t arraysMapPtr = stream->getBe64();
80 
81     if (arraysMapPtr) {
82         arraysMap.reset(new ArraysMap());
83         size_t mapSize = stream->getBe32();
84         for (size_t i = 0; i < mapSize; i++) {
85             GLuint id = stream->getBe32();
86             arraysMap->emplace(id, new GLESpointer(stream));
87         }
88         legacy = true;
89     } else {
90         arraysMap.reset();
91     }
92 
93     loadContainer(stream, bindingState);
94     bufferBacked = stream->getByte();
95     everBound = stream->getByte();
96 }
97 
onSave(android::base::Stream * stream) const98 void VAOState::onSave(android::base::Stream* stream) const {
99     stream->putBe32(element_array_buffer_binding);
100     for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
101         vertexAttribInfo[i].onSave(stream);
102     }
103 
104     if (arraysMap) {
105         stream->putBe64((uint64_t)(uintptr_t)arraysMap.get());
106     } else {
107         stream->putBe64(0);
108     }
109 
110     if (arraysMap) {
111         stream->putBe32(arraysMap->size());
112         for (const auto& ite : *arraysMap) {
113             stream->putBe32(ite.first);
114             assert(ite.second);
115             ite.second->onSave(stream);
116         }
117     }
118 
119     saveContainer(stream, bindingState);
120     stream->putByte(bufferBacked);
121     stream->putByte(everBound);
122 }
123 
~GLESConversionArrays()124 GLESConversionArrays::~GLESConversionArrays() {
125     for(auto it = m_arrays.begin(); it != m_arrays.end(); ++it) {
126         if((*it).second.allocated){
127             if((*it).second.type == GL_FLOAT){
128                 GLfloat* p = (GLfloat *)((*it).second.data);
129                 if(p) delete[] p;
130             } else if((*it).second.type == GL_SHORT){
131                 GLshort* p = (GLshort *)((*it).second.data);
132                 if(p) delete[] p;
133             }
134         }
135     }
136 }
137 
allocArr(unsigned int size,GLenum type)138 void GLESConversionArrays::allocArr(unsigned int size,GLenum type){
139     if(type == GL_FIXED){
140         m_arrays[m_current].data = new GLfloat[size];
141         m_arrays[m_current].type = GL_FLOAT;
142     } else if(type == GL_BYTE){
143         m_arrays[m_current].data = new GLshort[size];
144         m_arrays[m_current].type = GL_SHORT;
145     }
146     m_arrays[m_current].stride = 0;
147     m_arrays[m_current].allocated = true;
148 }
149 
setArr(void * data,unsigned int stride,GLenum type)150 void GLESConversionArrays::setArr(void* data,unsigned int stride,GLenum type){
151    m_arrays[m_current].type = type;
152    m_arrays[m_current].data = data;
153    m_arrays[m_current].stride = stride;
154    m_arrays[m_current].allocated = false;
155 }
156 
getCurrentData()157 void* GLESConversionArrays::getCurrentData(){
158     return m_arrays[m_current].data;
159 }
160 
getCurrentArray()161 ArrayData& GLESConversionArrays::getCurrentArray(){
162     return m_arrays[m_current];
163 }
164 
getCurrentIndex()165 unsigned int GLESConversionArrays::getCurrentIndex(){
166     return m_current;
167 }
168 
operator [](int i)169 ArrayData& GLESConversionArrays::operator[](int i){
170     return m_arrays[i];
171 }
172 
operator ++()173 void GLESConversionArrays::operator++(){
174     m_current++;
175 }
176 
177 GLDispatch     GLEScontext::s_glDispatch;
178 android::base::Lock   GLEScontext::s_lock;
179 std::string*   GLEScontext::s_glExtensionsGles1 = NULL;
180 bool           GLEScontext::s_glExtensionsGles1Initialized = false;
181 std::string*   GLEScontext::s_glExtensions = NULL;
182 bool           GLEScontext::s_glExtensionsInitialized = false;
183 std::string    GLEScontext::s_glVendorGles1;
184 std::string    GLEScontext::s_glRendererGles1;
185 std::string    GLEScontext::s_glVersionGles1;
186 std::string    GLEScontext::s_glVendor;
187 std::string    GLEScontext::s_glRenderer;
188 std::string    GLEScontext::s_glVersion;
189 GLSupport      GLEScontext::s_glSupport;
190 
Version(int major,int minor,int release)191 Version::Version(int major,int minor,int release):m_major(major),
192                                                   m_minor(minor),
193                                                   m_release(release){};
194 
Version(const Version & ver)195 Version::Version(const Version& ver):m_major(ver.m_major),
196                                      m_minor(ver.m_minor),
197                                      m_release(ver.m_release){}
198 
Version(const char * versionString)199 Version::Version(const char* versionString){
200     m_release = 0;
201     if((!versionString) ||
202       ((!(sscanf(versionString,"%d.%d"   ,&m_major,&m_minor) == 2)) &&
203        (!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){
204         m_major = m_minor = 0; // the version is not in the right format
205     }
206 }
207 
operator =(const Version & ver)208 Version& Version::operator=(const Version& ver){
209     m_major   = ver.m_major;
210     m_minor   = ver.m_minor;
211     m_release = ver.m_release;
212     return *this;
213 }
214 
operator <(const Version & ver) const215 bool Version::operator<(const Version& ver) const{
216     if(m_major < ver.m_major) return true;
217     if(m_major == ver.m_major){
218         if(m_minor < ver.m_minor) return true;
219         if(m_minor == ver.m_minor){
220            return m_release < ver.m_release;
221         }
222     }
223     return false;
224 }
225 
getHostExtensionsString(GLDispatch * dispatch)226 static std::string getHostExtensionsString(GLDispatch* dispatch) {
227     // glGetString(GL_EXTENSIONS) is deprecated in GL 3.0, one has to use
228     // glGetStringi(GL_EXTENSIONS, index) instead to get individual extension
229     // names. Recent desktop drivers implement glGetStringi() but have a
230     // version of glGetString() that returns NULL, so deal with this by
231     // doing the following:
232     //
233     //  - If glGetStringi() is available, and glGetIntegerv(GL_NUM_EXTENSIONS &num_exts)
234     //    gives a nonzero value, use it to build the extensions
235     //    string, using simple spaces to separate the names.
236     //
237     //  - Otherwise, fallback to getGetString(). If it returns NULL, return
238     //    an empty string.
239     //
240 
241     std::string result;
242     int num_exts = 0;
243 
244     if (dispatch->glGetStringi) {
245         dispatch->glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts);
246         GLenum err = dispatch->glGetError();
247         if (err == GL_NO_ERROR) {
248             for (int n = 0; n < num_exts; n++) {
249                 const char* ext = reinterpret_cast<const char*>(
250                         dispatch->glGetStringi(GL_EXTENSIONS, n));
251                 if (ext != NULL) {
252                     if (!result.empty()) {
253                         result += " ";
254                     }
255                     result += ext;
256                 }
257             }
258         }
259     }
260 
261     // If glGetIntegerv does not affect the value,
262     // our system does not actually support
263     // GL 3.0 style extension getting.
264     if (!dispatch->glGetStringi || num_exts == 0) {
265         const char* extensions = reinterpret_cast<const char*>(
266                 dispatch->glGetString(GL_EXTENSIONS));
267         if (extensions) {
268             result = extensions;
269         }
270     }
271 
272     // For the sake of initCapsLocked() add a starting and trailing space.
273     if (!result.empty()) {
274         if (result[0] != ' ') {
275             result.insert(0, 1, ' ');
276         }
277         if (result[result.size() - 1U] != ' ') {
278             result += ' ';
279         }
280     }
281     return result;
282 }
283 
getIndex(GLenum indices_type,const GLvoid * indices,unsigned int i)284 static GLuint getIndex(GLenum indices_type, const GLvoid* indices, unsigned int i) {
285     switch (indices_type) {
286         case GL_UNSIGNED_BYTE:
287             return static_cast<const GLubyte*>(indices)[i];
288         case GL_UNSIGNED_SHORT:
289             return static_cast<const GLushort*>(indices)[i];
290         case GL_UNSIGNED_INT:
291             return static_cast<const GLuint*>(indices)[i];
292         default:
293             ERR("**** ERROR unknown type 0x%x", indices_type);
294             return 0;
295     }
296 }
297 
addVertexArrayObjects(GLsizei n,GLuint * arrays)298 void GLEScontext::addVertexArrayObjects(GLsizei n, GLuint* arrays) {
299     for (int i = 0; i < n; i++) {
300         addVertexArrayObject(arrays[i]);
301     }
302 }
303 
removeVertexArrayObjects(GLsizei n,const GLuint * arrays)304 void GLEScontext::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) {
305     for (int i = 0; i < n; i++) {
306         removeVertexArrayObject(arrays[i]);
307     }
308 }
309 
addVertexArrayObject(GLuint array)310 void GLEScontext::addVertexArrayObject(GLuint array) {
311     ArraysMap* map = new ArraysMap();
312     for (int i = 0; i < s_glSupport.maxVertexAttribs; i++) {
313         map->insert(
314                 ArraysMap::value_type(
315                     i,
316                     new GLESpointer()));
317     }
318     assert(m_vaoStateMap.count(array) == 0);  // Overwriting existing entry, leaking memory
319     m_vaoStateMap[array] = VAOState(0, map, std::max(s_glSupport.maxVertexAttribs, s_glSupport.maxVertexAttribBindings));
320 }
321 
removeVertexArrayObject(GLuint array)322 void GLEScontext::removeVertexArrayObject(GLuint array) {
323     if (array == 0) return;
324     if (m_vaoStateMap.find(array) == m_vaoStateMap.end())
325         return;
326     if (array == m_currVaoState.vaoId()) {
327         setVertexArrayObject(0);
328     }
329 
330     auto& state = m_vaoStateMap[array];
331 
332     if (state.arraysMap) {
333         for (auto elem : *(state.arraysMap)) {
334             delete elem.second;
335         }
336     }
337 
338     m_vaoStateMap.erase(array);
339 }
340 
setVertexArrayObject(GLuint array)341 bool GLEScontext::setVertexArrayObject(GLuint array) {
342     VAOStateMap::iterator it = m_vaoStateMap.find(array);
343     if (it != m_vaoStateMap.end()) {
344         m_currVaoState = VAOStateRef(it);
345         return true;
346     }
347     return false;
348 }
349 
setVAOEverBound()350 void GLEScontext::setVAOEverBound() {
351     m_currVaoState.setEverBound();
352 }
353 
getVertexArrayObject() const354 GLuint GLEScontext::getVertexArrayObject() const {
355     return m_currVaoState.vaoId();
356 }
357 
vertexAttributesBufferBacked()358 bool GLEScontext::vertexAttributesBufferBacked() {
359     const auto& info = m_currVaoState.attribInfo_const();
360     for (uint32_t i = 0; i  < kMaxVertexAttributes; ++i) {
361         const auto& pointerInfo = info[i];
362         if (pointerInfo.isEnable() &&
363             !m_currVaoState.bufferBindings()[pointerInfo.getBindingIndex()].buffer) {
364             return false;
365         }
366     }
367 
368     return true;
369 }
370 
371 static EGLiface*      s_eglIface = nullptr;
372 
373 // static
eglIface()374 EGLiface* GLEScontext::eglIface() {
375     return s_eglIface;
376 }
377 
378 // static
initEglIface(EGLiface * iface)379 void GLEScontext::initEglIface(EGLiface* iface) {
380     if (!s_eglIface) s_eglIface = iface;
381 }
382 
initGlobal(EGLiface * iface)383 void GLEScontext::initGlobal(EGLiface* iface) {
384     initEglIface(iface);
385     s_lock.lock();
386     if (!s_glExtensions) {
387         initCapsLocked(reinterpret_cast<const GLubyte*>(
388                 getHostExtensionsString(&s_glDispatch).c_str()));
389         s_glExtensions = new std::string();
390     }
391     if (!s_glExtensionsGles1) {
392         s_glExtensionsGles1 = new std::string();
393     }
394     s_lock.unlock();
395 }
396 
init()397 void GLEScontext::init() {
398     if (!m_initialized) {
399         initExtensionString();
400 
401         m_maxTexUnits = getMaxCombinedTexUnits();
402         m_texState = new textureUnitState[m_maxTexUnits];
403         for (int i=0;i<m_maxTexUnits;++i) {
404             for (int j=0;j<NUM_TEXTURE_TARGETS;++j)
405             {
406                 m_texState[i][j].texture = 0;
407                 m_texState[i][j].enabled = GL_FALSE;
408             }
409         }
410 
411         m_indexedTransformFeedbackBuffers.resize(getCaps()->maxTransformFeedbackSeparateAttribs);
412         m_indexedUniformBuffers.resize(getCaps()->maxUniformBufferBindings);
413         m_indexedAtomicCounterBuffers.resize(getCaps()->maxAtomicCounterBufferBindings);
414         m_indexedShaderStorageBuffers.resize(getCaps()->maxShaderStorageBufferBindings);
415     }
416 }
417 
restore()418 void GLEScontext::restore() {
419     postLoadRestoreShareGroup();
420     if (m_needRestoreFromSnapshot) {
421         postLoadRestoreCtx();
422         m_needRestoreFromSnapshot = false;
423     }
424 }
425 
needRestore()426 bool GLEScontext::needRestore() {
427     bool ret = m_needRestoreFromSnapshot;
428     if (m_shareGroup) {
429         ret |= m_shareGroup->needRestore();
430     }
431     return ret;
432 }
433 
getGLerror()434 GLenum GLEScontext::getGLerror() {
435     return m_glError;
436 }
437 
setGLerror(GLenum err)438 void GLEScontext::setGLerror(GLenum err) {
439     m_glError = err;
440 }
441 
setActiveTexture(GLenum tex)442 void GLEScontext::setActiveTexture(GLenum tex) {
443    m_activeTexture = tex - GL_TEXTURE0;
444    m_maxUsedTexUnit = std::max(m_activeTexture, m_maxUsedTexUnit);
445 }
446 
GLEScontext()447 GLEScontext::GLEScontext() {}
448 
GLEScontext(GlobalNameSpace * globalNameSpace,android::base::Stream * stream,GlLibrary * glLib)449 GLEScontext::GLEScontext(GlobalNameSpace* globalNameSpace,
450         android::base::Stream* stream, GlLibrary* glLib) {
451     if (stream) {
452         m_initialized = stream->getByte();
453         m_glesMajorVersion = stream->getBe32();
454         m_glesMinorVersion = stream->getBe32();
455         if (m_initialized) {
456             m_activeTexture = (GLuint)stream->getBe32();
457 
458             loadNameMap<VAOStateMap>(stream, m_vaoStateMap);
459             uint32_t vaoId = stream->getBe32();
460             setVertexArrayObject(vaoId);
461 
462             m_copyReadBuffer = static_cast<GLuint>(stream->getBe32());
463             m_copyWriteBuffer = static_cast<GLuint>(stream->getBe32());
464             m_pixelPackBuffer = static_cast<GLuint>(stream->getBe32());
465             m_pixelUnpackBuffer = static_cast<GLuint>(stream->getBe32());
466             m_transformFeedbackBuffer = static_cast<GLuint>(stream->getBe32());
467             m_uniformBuffer = static_cast<GLuint>(stream->getBe32());
468             m_atomicCounterBuffer = static_cast<GLuint>(stream->getBe32());
469             m_dispatchIndirectBuffer = static_cast<GLuint>(stream->getBe32());
470             m_drawIndirectBuffer = static_cast<GLuint>(stream->getBe32());
471             m_shaderStorageBuffer = static_cast<GLuint>(stream->getBe32());
472 
473             loadContainer(stream, m_indexedTransformFeedbackBuffers);
474             loadContainer(stream, m_indexedUniformBuffers);
475             loadContainer(stream, m_indexedAtomicCounterBuffers);
476             loadContainer(stream, m_indexedShaderStorageBuffers);
477 
478             // TODO: handle the case where the loaded size and the supported
479             // side does not match
480 
481             m_isViewport = stream->getByte();
482             m_viewportX = static_cast<GLint>(stream->getBe32());
483             m_viewportY = static_cast<GLint>(stream->getBe32());
484             m_viewportWidth = static_cast<GLsizei>(stream->getBe32());
485             m_viewportHeight = static_cast<GLsizei>(stream->getBe32());
486 
487             m_polygonOffsetFactor = static_cast<GLfloat>(stream->getFloat());
488             m_polygonOffsetUnits = static_cast<GLfloat>(stream->getFloat());
489 
490             m_isScissor = stream->getByte();
491             m_scissorX = static_cast<GLint>(stream->getBe32());
492             m_scissorY = static_cast<GLint>(stream->getBe32());
493             m_scissorWidth = static_cast<GLsizei>(stream->getBe32());
494             m_scissorHeight = static_cast<GLsizei>(stream->getBe32());
495 
496             loadCollection(stream, &m_glEnableList,
497                     [](android::base::Stream* stream) {
498                         GLenum item = stream->getBe32();
499                         bool enabled = stream->getByte();
500                         return std::make_pair(item, enabled);
501             });
502 
503             m_blendEquationRgb = static_cast<GLenum>(stream->getBe32());
504             m_blendEquationAlpha = static_cast<GLenum>(stream->getBe32());
505             m_blendSrcRgb = static_cast<GLenum>(stream->getBe32());
506             m_blendDstRgb = static_cast<GLenum>(stream->getBe32());
507             m_blendSrcAlpha = static_cast<GLenum>(stream->getBe32());
508             m_blendDstAlpha = static_cast<GLenum>(stream->getBe32());
509 
510             loadCollection(stream, &m_glPixelStoreiList,
511                     [](android::base::Stream* stream) {
512                         GLenum item = stream->getBe32();
513                         GLint val = stream->getBe32();
514                         return std::make_pair(item, val);
515             });
516 
517             m_cullFace = static_cast<GLenum>(stream->getBe32());
518             m_frontFace = static_cast<GLenum>(stream->getBe32());
519             m_depthFunc = static_cast<GLenum>(stream->getBe32());
520             m_depthMask = static_cast<GLboolean>(stream->getByte());
521             m_zNear = static_cast<GLclampf>(stream->getFloat());
522             m_zFar = static_cast<GLclampf>(stream->getFloat());
523 
524             m_lineWidth = static_cast<GLclampf>(stream->getFloat());
525 
526             m_sampleCoverageVal = static_cast<GLclampf>(stream->getFloat());
527             m_sampleCoverageInvert = static_cast<GLboolean>(stream->getByte());
528 
529             stream->read(m_stencilStates, sizeof(m_stencilStates));
530 
531             m_colorMaskR = static_cast<GLboolean>(stream->getByte());
532             m_colorMaskG = static_cast<GLboolean>(stream->getByte());
533             m_colorMaskB = static_cast<GLboolean>(stream->getByte());
534             m_colorMaskA = static_cast<GLboolean>(stream->getByte());
535 
536             m_clearColorR = static_cast<GLclampf>(stream->getFloat());
537             m_clearColorG = static_cast<GLclampf>(stream->getFloat());
538             m_clearColorB = static_cast<GLclampf>(stream->getFloat());
539             m_clearColorA = static_cast<GLclampf>(stream->getFloat());
540 
541             m_clearDepth = static_cast<GLclampf>(stream->getFloat());
542             m_clearStencil = static_cast<GLint>(stream->getBe32());
543 
544             // share group is supposed to be loaded by EglContext and reset
545             // when loading EglContext
546             //int sharegroupId = stream->getBe32();
547             m_glError = static_cast<GLenum>(stream->getBe32());
548             m_maxTexUnits = static_cast<int>(stream->getBe32());
549             m_maxUsedTexUnit = static_cast<int>(stream->getBe32());
550             m_texState = new textureUnitState[m_maxTexUnits];
551             stream->read(m_texState, sizeof(textureUnitState) * m_maxTexUnits);
552             m_arrayBuffer = static_cast<unsigned int>(stream->getBe32());
553             m_elementBuffer = static_cast<unsigned int>(stream->getBe32());
554             m_renderbuffer = static_cast<GLuint>(stream->getBe32());
555             m_drawFramebuffer = static_cast<GLuint>(stream->getBe32());
556             m_readFramebuffer = static_cast<GLuint>(stream->getBe32());
557             m_defaultFBODrawBuffer = static_cast<GLenum>(stream->getBe32());
558             m_defaultFBOReadBuffer = static_cast<GLenum>(stream->getBe32());
559 
560             m_needRestoreFromSnapshot = true;
561         }
562     }
563     ObjectData::loadObject_t loader = [this](NamedObjectType type,
564                                              long long unsigned int localName,
565                                              android::base::Stream* stream) {
566         return loadObject(type, localName, stream);
567     };
568     m_fboNameSpace = new NameSpace(NamedObjectType::FRAMEBUFFER,
569                                    globalNameSpace, stream, loader);
570     // do not load m_vaoNameSpace
571     m_vaoNameSpace = new NameSpace(NamedObjectType::VERTEX_ARRAY_OBJECT,
572                                    globalNameSpace, nullptr, loader);
573 }
574 
~GLEScontext()575 GLEScontext::~GLEScontext() {
576     auto& gl = dispatcher();
577 
578     if (m_blitState.program) {
579         gl.glDeleteProgram(m_blitState.program);
580         gl.glDeleteTextures(1, &m_blitState.tex);
581         gl.glDeleteVertexArrays(1, &m_blitState.vao);
582         gl.glDeleteBuffers(1, &m_blitState.vbo);
583         gl.glDeleteFramebuffers(1, &m_blitState.fbo);
584     }
585 
586     if (m_textureEmulationProg) {
587         gl.glDeleteProgram(m_textureEmulationProg);
588         gl.glDeleteTextures(2, m_textureEmulationTextures);
589         gl.glDeleteFramebuffers(1, &m_textureEmulationFBO);
590         gl.glDeleteVertexArrays(1, &m_textureEmulationVAO);
591     }
592 
593     if (m_defaultFBO) {
594         gl.glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
595         gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
596         gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
597         gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
598         gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
599         gl.glDeleteFramebuffers(1, &m_defaultFBO);
600     }
601 
602     if (m_defaultReadFBO && (m_defaultReadFBO != m_defaultFBO)) {
603         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultReadFBO);
604         gl.glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0);
605         gl.glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
606         gl.glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
607         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
608         gl.glDeleteFramebuffers(1, &m_defaultReadFBO);
609     }
610 
611     m_defaultFBO = 0;
612     m_defaultReadFBO = 0;
613 
614     for (auto&& vao : m_vaoStateMap) {
615         if (vao.second.arraysMap) {
616             for (auto elem : *(vao.second.arraysMap)) {
617                 delete elem.second;
618             }
619             vao.second.arraysMap.reset();
620         }
621     }
622 
623     delete[] m_texState;
624     m_texState = nullptr;
625     delete m_fboNameSpace;
626     m_fboNameSpace = nullptr;
627     delete m_vaoNameSpace;
628     m_vaoNameSpace = nullptr;
629 }
630 
postLoad()631 void GLEScontext::postLoad() {
632     m_fboNameSpace->postLoad(
633             [this](NamedObjectType p_type, ObjectLocalName p_localName) {
634                 if (p_type == NamedObjectType::FRAMEBUFFER) {
635                     return this->getFBODataPtr(p_localName);
636                 } else {
637                     return m_shareGroup->getObjectDataPtr(p_type, p_localName);
638                 }
639             });
640 }
641 
onSave(android::base::Stream * stream) const642 void GLEScontext::onSave(android::base::Stream* stream) const {
643     stream->putByte(m_initialized);
644     stream->putBe32(m_glesMajorVersion);
645     stream->putBe32(m_glesMinorVersion);
646     if (m_initialized) {
647         stream->putBe32(m_activeTexture);
648 
649         saveNameMap(stream, m_vaoStateMap);
650         stream->putBe32(getVertexArrayObject());
651 
652         stream->putBe32(m_copyReadBuffer);
653         stream->putBe32(m_copyWriteBuffer);
654         stream->putBe32(m_pixelPackBuffer);
655         stream->putBe32(m_pixelUnpackBuffer);
656         stream->putBe32(m_transformFeedbackBuffer);
657         stream->putBe32(m_uniformBuffer);
658         stream->putBe32(m_atomicCounterBuffer);
659         stream->putBe32(m_dispatchIndirectBuffer);
660         stream->putBe32(m_drawIndirectBuffer);
661         stream->putBe32(m_shaderStorageBuffer);
662 
663         saveContainer(stream, m_indexedTransformFeedbackBuffers);
664         saveContainer(stream, m_indexedUniformBuffers);
665         saveContainer(stream, m_indexedAtomicCounterBuffers);
666         saveContainer(stream, m_indexedShaderStorageBuffers);
667 
668         stream->putByte(m_isViewport);
669         stream->putBe32(m_viewportX);
670         stream->putBe32(m_viewportY);
671         stream->putBe32(m_viewportWidth);
672         stream->putBe32(m_viewportHeight);
673 
674         stream->putFloat(m_polygonOffsetFactor);
675         stream->putFloat(m_polygonOffsetUnits);
676 
677         stream->putByte(m_isScissor);
678         stream->putBe32(m_scissorX);
679         stream->putBe32(m_scissorY);
680         stream->putBe32(m_scissorWidth);
681         stream->putBe32(m_scissorHeight);
682 
683         saveCollection(stream, m_glEnableList, [](android::base::Stream* stream,
684                 const std::pair<const GLenum, bool>& enableItem) {
685                     stream->putBe32(enableItem.first);
686                     stream->putByte(enableItem.second);
687         });
688 
689         stream->putBe32(m_blendEquationRgb);
690         stream->putBe32(m_blendEquationAlpha);
691         stream->putBe32(m_blendSrcRgb);
692         stream->putBe32(m_blendDstRgb);
693         stream->putBe32(m_blendSrcAlpha);
694         stream->putBe32(m_blendDstAlpha);
695 
696         saveCollection(stream, m_glPixelStoreiList, [](android::base::Stream* stream,
697                 const std::pair<const GLenum, GLint>& pixelStore) {
698                     stream->putBe32(pixelStore.first);
699                     stream->putBe32(pixelStore.second);
700         });
701 
702         stream->putBe32(m_cullFace);
703         stream->putBe32(m_frontFace);
704         stream->putBe32(m_depthFunc);
705         stream->putByte(m_depthMask);
706         stream->putFloat(m_zNear);
707         stream->putFloat(m_zFar);
708 
709         stream->putFloat(m_lineWidth);
710 
711         stream->putFloat(m_sampleCoverageVal);
712         stream->putByte(m_sampleCoverageInvert);
713 
714         stream->write(m_stencilStates, sizeof(m_stencilStates));
715 
716         stream->putByte(m_colorMaskR);
717         stream->putByte(m_colorMaskG);
718         stream->putByte(m_colorMaskB);
719         stream->putByte(m_colorMaskA);
720 
721         stream->putFloat(m_clearColorR);
722         stream->putFloat(m_clearColorG);
723         stream->putFloat(m_clearColorB);
724         stream->putFloat(m_clearColorA);
725 
726         stream->putFloat(m_clearDepth);
727         stream->putBe32(m_clearStencil);
728 
729         // share group is supposed to be saved / loaded by EglContext
730         stream->putBe32(m_glError);
731         stream->putBe32(m_maxTexUnits);
732         stream->putBe32(m_maxUsedTexUnit);
733         stream->write(m_texState, sizeof(textureUnitState) * m_maxTexUnits);
734         stream->putBe32(m_arrayBuffer);
735         stream->putBe32(m_elementBuffer);
736         stream->putBe32(m_renderbuffer);
737         stream->putBe32(m_drawFramebuffer);
738         stream->putBe32(m_readFramebuffer);
739         stream->putBe32(m_defaultFBODrawBuffer);
740         stream->putBe32(m_defaultFBOReadBuffer);
741     }
742     m_fboNameSpace->onSave(stream);
743     // do not save m_vaoNameSpace
744 }
745 
postSave(android::base::Stream * stream) const746 void GLEScontext::postSave(android::base::Stream* stream) const {
747     (void)stream;
748     // We need to mark the textures dirty, for those that has been bound to
749     // a potential render target.
750     for (ObjectDataMap::const_iterator it = m_fboNameSpace->objDataMapBegin();
751         it != m_fboNameSpace->objDataMapEnd();
752         it ++) {
753         FramebufferData* fbData = (FramebufferData*)it->second.get();
754         fbData->makeTextureDirty([this](NamedObjectType p_type,
755             ObjectLocalName p_localName) {
756                 if (p_type == NamedObjectType::FRAMEBUFFER) {
757                     return this->getFBODataPtr(p_localName);
758                 } else {
759                     return m_shareGroup->getObjectDataPtr(p_type, p_localName);
760                 }
761             });
762     }
763 }
764 
postLoadRestoreShareGroup()765 void GLEScontext::postLoadRestoreShareGroup() {
766     m_shareGroup->postLoadRestore();
767 }
768 
postLoadRestoreCtx()769 void GLEScontext::postLoadRestoreCtx() {
770     GLDispatch& dispatcher = GLEScontext::dispatcher();
771 
772     assert(!m_shareGroup->needRestore());
773     m_fboNameSpace->postLoadRestore(
774             [this](NamedObjectType p_type, ObjectLocalName p_localName) {
775                 if (p_type == NamedObjectType::FRAMEBUFFER) {
776                     return getFBOGlobalName(p_localName);
777                 } else {
778                     return m_shareGroup->getGlobalName(p_type, p_localName);
779                 }
780             }
781         );
782 
783     // buffer bindings
784     auto bindBuffer = [this](GLenum target, GLuint buffer) {
785         this->dispatcher().glBindBuffer(target,
786                 m_shareGroup->getGlobalName(NamedObjectType::VERTEXBUFFER, buffer));
787     };
788     bindBuffer(GL_ARRAY_BUFFER, m_arrayBuffer);
789     bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_currVaoState.iboId());
790 
791     // framebuffer binding
792     auto bindFrameBuffer = [this](GLenum target, GLuint buffer) {
793         this->dispatcher().glBindFramebuffer(target,
794                 getFBOGlobalName(buffer));
795     };
796     bindFrameBuffer(GL_READ_FRAMEBUFFER, m_readFramebuffer);
797     bindFrameBuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebuffer);
798 
799     for (unsigned int i = 0; i <= m_maxUsedTexUnit; i++) {
800         for (unsigned int j = 0; j < NUM_TEXTURE_TARGETS; j++) {
801             textureTargetState& texState = m_texState[i][j];
802             if (texState.texture || texState.enabled) {
803                 this->dispatcher().glActiveTexture(i + GL_TEXTURE0);
804                 GLenum texTarget = GL_TEXTURE_2D;
805                 switch (j) {
806                     case TEXTURE_2D:
807                         texTarget = GL_TEXTURE_2D;
808                         break;
809                     case TEXTURE_CUBE_MAP:
810                         texTarget = GL_TEXTURE_CUBE_MAP;
811                         break;
812                     case TEXTURE_2D_ARRAY:
813                         texTarget = GL_TEXTURE_2D_ARRAY;
814                         break;
815                     case TEXTURE_3D:
816                         texTarget = GL_TEXTURE_3D;
817                         break;
818                     case TEXTURE_2D_MULTISAMPLE:
819                         texTarget = GL_TEXTURE_2D_MULTISAMPLE;
820                         break;
821                     default:
822                         fprintf(stderr,
823                                 "Warning: unsupported texture target 0x%x.\n",
824                                 j);
825                         break;
826                 }
827                 // TODO: refactor the following line since it is duplicated in
828                 // GLESv2Imp and GLEScmImp as well
829                 ObjectLocalName texName = texState.texture != 0 ?
830                         texState.texture : getDefaultTextureName(texTarget);
831                 this->dispatcher().glBindTexture(
832                         texTarget,
833                         m_shareGroup->getGlobalName(
834                             NamedObjectType::TEXTURE, texName));
835                 if (!isCoreProfile() && texState.enabled) {
836                     dispatcher.glEnable(texTarget);
837                 }
838             }
839         }
840     }
841     dispatcher.glActiveTexture(m_activeTexture + GL_TEXTURE0);
842 
843     // viewport & scissor
844     if (m_isViewport) {
845         dispatcher.glViewport(m_viewportX, m_viewportY,
846                 m_viewportWidth, m_viewportHeight);
847     }
848     if (m_isScissor) {
849         dispatcher.glScissor(m_scissorX, m_scissorY,
850                 m_scissorWidth, m_scissorHeight);
851     }
852     dispatcher.glPolygonOffset(m_polygonOffsetFactor,
853             m_polygonOffsetUnits);
854 
855     for (auto item : m_glEnableList) {
856         if (item.first == GL_TEXTURE_2D
857                 || item.first == GL_TEXTURE_CUBE_MAP_OES) {
858             continue;
859         }
860         std::function<void(GLenum)> enableFunc = item.second ? dispatcher.glEnable :
861                                                    dispatcher.glDisable;
862         if (item.first==GL_TEXTURE_GEN_STR_OES) {
863             enableFunc(GL_TEXTURE_GEN_S);
864             enableFunc(GL_TEXTURE_GEN_T);
865             enableFunc(GL_TEXTURE_GEN_R);
866         } else {
867             enableFunc(item.first);
868         }
869     }
870     dispatcher.glBlendEquationSeparate(m_blendEquationRgb,
871             m_blendEquationAlpha);
872     dispatcher.glBlendFuncSeparate(m_blendSrcRgb, m_blendDstRgb,
873             m_blendSrcAlpha, m_blendDstAlpha);
874     for (const auto& pixelStore : m_glPixelStoreiList) {
875         dispatcher.glPixelStorei(pixelStore.first, pixelStore.second);
876     }
877 
878     dispatcher.glCullFace(m_cullFace);
879     dispatcher.glFrontFace(m_frontFace);
880     dispatcher.glDepthFunc(m_depthFunc);
881     dispatcher.glDepthMask(m_depthMask);
882 
883     dispatcher.glLineWidth(m_lineWidth);
884 
885     dispatcher.glSampleCoverage(m_sampleCoverageVal, m_sampleCoverageInvert);
886 
887     for (int i = 0; i < 2; i++) {
888         GLenum face = i == StencilFront ? GL_FRONT
889                                        : GL_BACK;
890         dispatcher.glStencilFuncSeparate(face, m_stencilStates[i].m_func,
891                 m_stencilStates[i].m_ref, m_stencilStates[i].m_funcMask);
892         dispatcher.glStencilMaskSeparate(face, m_stencilStates[i].m_writeMask);
893         dispatcher.glStencilOpSeparate(face, m_stencilStates[i].m_sfail,
894                 m_stencilStates[i].m_dpfail, m_stencilStates[i].m_dppass);
895     }
896 
897     dispatcher.glClearColor(m_clearColorR, m_clearColorG, m_clearColorB,
898             m_clearColorA);
899     if (isGles2Gles()) {
900         dispatcher.glClearDepthf(m_clearDepth);
901         dispatcher.glDepthRangef(m_zNear, m_zFar);
902     } else {
903         dispatcher.glClearDepth(m_clearDepth);
904         dispatcher.glDepthRange(m_zNear, m_zFar);
905     }
906     dispatcher.glClearStencil(m_clearStencil);
907     dispatcher.glColorMask(m_colorMaskR, m_colorMaskG, m_colorMaskB,
908             m_colorMaskA);
909 
910     // report any GL errors when loading from a snapshot
911     GLenum err = 0;
912     do {
913         err = dispatcher.glGetError();
914 #ifdef _DEBUG
915         if (err) {
916             ERR("warning: get GL error %d while restoring a snapshot", err);
917         }
918 #endif
919     } while (err != 0);
920 }
921 
loadObject(NamedObjectType type,ObjectLocalName localName,android::base::Stream * stream) const922 ObjectDataPtr GLEScontext::loadObject(NamedObjectType type,
923             ObjectLocalName localName, android::base::Stream* stream) const {
924     switch (type) {
925         case NamedObjectType::VERTEXBUFFER:
926             return ObjectDataPtr(new GLESbuffer(stream));
927         case NamedObjectType::TEXTURE:
928             return ObjectDataPtr(new TextureData(stream));
929         case NamedObjectType::FRAMEBUFFER:
930             return ObjectDataPtr(new FramebufferData(stream));
931         case NamedObjectType::RENDERBUFFER:
932             return ObjectDataPtr(new RenderbufferData(stream));
933         default:
934             return {};
935     }
936 }
937 
setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid * data,GLsizei dataSize,bool normalize,bool isInt)938 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data, GLsizei dataSize, bool normalize, bool isInt) {
939     GLuint bufferName = m_arrayBuffer;
940     GLESpointer* glesPointer = nullptr;
941 
942     if (m_currVaoState.it->second.legacy) {
943         auto vertexAttrib = m_currVaoState.find(arrType);
944         if (vertexAttrib == m_currVaoState.end()) {
945             return nullptr;
946         }
947         glesPointer = m_currVaoState[arrType];
948     } else {
949         uint32_t attribIndex = (uint32_t)arrType;
950         if (attribIndex > kMaxVertexAttributes) return nullptr;
951         glesPointer = m_currVaoState.attribInfo().data() + (uint32_t)arrType;
952     }
953 
954     if(bufferName) {
955         unsigned int offset = SafeUIntFromPointer(data);
956         GLESbuffer* vbo = static_cast<GLESbuffer*>(
957                 m_shareGroup
958                         ->getObjectData(NamedObjectType::VERTEXBUFFER,
959                                         bufferName));
960         if(offset >= vbo->getSize() || vbo->getSize() - offset < size) {
961 #ifdef _DEBUG
962             ERR("Warning: Invalid pointer offset %u, arrType %d, type %d", offset, arrType, type);
963 #endif
964             return nullptr;
965         }
966 
967         glesPointer->setBuffer(size,type,stride,vbo,bufferName,offset,normalize, isInt);
968 
969         return  static_cast<const unsigned char*>(vbo->getData()) +  offset;
970     }
971     glesPointer->setArray(size,type,stride,data,dataSize,normalize,isInt);
972     return data;
973 }
974 
enableArr(GLenum arr,bool enable)975 void GLEScontext::enableArr(GLenum arr,bool enable) {
976     auto vertexAttrib = m_currVaoState.find(arr);
977     if (vertexAttrib != m_currVaoState.end()) {
978         vertexAttrib->second->enable(enable);
979     }
980 }
981 
isArrEnabled(GLenum arr)982 bool GLEScontext::isArrEnabled(GLenum arr) {
983     if (m_currVaoState.it->second.legacy) {
984         return m_currVaoState[arr]->isEnable();
985     } else {
986         if ((uint32_t)arr > kMaxVertexAttributes) return false;
987         return m_currVaoState.attribInfo()[(uint32_t)arr].isEnable();
988     }
989 }
990 
getPointer(GLenum arrType)991 const GLESpointer* GLEScontext::getPointer(GLenum arrType) {
992     const auto it = m_currVaoState.find(arrType);
993     return it != m_currVaoState.end() ? it->second : nullptr;
994 }
995 
convertFixedDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)996 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
997 
998     for(unsigned int i = 0; i < nBytes;i+=strideOut) {
999         const GLfixed* fixed_data = (const GLfixed *)dataIn;
1000         //filling attrib
1001         for(int j=0;j<attribSize;j++) {
1002             reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]);
1003         }
1004         dataIn += strideIn;
1005     }
1006 }
1007 
convertFixedIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)1008 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
1009     for(int i = 0 ;i < count ;i++) {
1010         GLuint index = getIndex(indices_type, indices, i);
1011 
1012         const GLfixed* fixed_data = (GLfixed *)(dataIn  + index*strideIn);
1013         GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
1014 
1015         for(int j=0;j<attribSize;j++) {
1016             float_data[j] = X2F(fixed_data[j]);
1017          }
1018     }
1019 }
1020 
convertByteDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)1021 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
1022 
1023     for(unsigned int i = 0; i < nBytes;i+=strideOut) {
1024         const GLbyte* byte_data = (const GLbyte *)dataIn;
1025         //filling attrib
1026         for(int j=0;j<attribSize;j++) {
1027             reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]);
1028         }
1029         dataIn += strideIn;
1030     }
1031 }
1032 
convertByteIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)1033 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
1034     for(int i = 0 ;i < count ;i++) {
1035         GLuint index = getIndex(indices_type, indices, i);
1036         const GLbyte* bytes_data = (GLbyte *)(dataIn  + index*strideIn);
1037         GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
1038 
1039         for(int j=0;j<attribSize;j++) {
1040             short_data[j] = B2S(bytes_data[j]);
1041          }
1042     }
1043 }
directToBytesRanges(GLint first,GLsizei count,GLESpointer * p,RangeList & list)1044 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) {
1045 
1046     int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes
1047     int stride = p->getStride()?p->getStride():attribSize;
1048     int start  = p->getBufferOffset()+first*stride;
1049     if(!p->getStride()) {
1050         list.addRange(Range(start,count*attribSize));
1051     } else {
1052         for(int i = 0 ;i < count; i++,start+=stride) {
1053             list.addRange(Range(start,attribSize));
1054         }
1055     }
1056 }
1057 
indirectToBytesRanges(const GLvoid * indices,GLenum indices_type,GLsizei count,GLESpointer * p,RangeList & list)1058 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) {
1059 
1060     int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
1061     int stride = p->getStride()?p->getStride():attribSize;
1062     int start  = p->getBufferOffset();
1063     for(int i=0 ; i < count; i++) {
1064         GLuint index = getIndex(indices_type, indices, i);
1065         list.addRange(Range(start+index*stride,attribSize));
1066 
1067     }
1068 }
1069 
bytesRangesToIndices(RangeList & ranges,GLESpointer * p,GLuint * indices)1070 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLuint* indices) {
1071 
1072     int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
1073     int stride = p->getStride()?p->getStride():attribSize;
1074     int offset = p->getBufferOffset();
1075 
1076     int n = 0;
1077     for(int i=0;i<ranges.size();i++) {
1078         int startIndex = (ranges[i].getStart() - offset) / stride;
1079         int nElements = ranges[i].getSize()/attribSize;
1080         for(int j=0;j<nElements;j++) {
1081             indices[n++] = startIndex+j;
1082         }
1083     }
1084     return n;
1085 }
1086 
convertDirect(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)1087 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
1088 
1089     GLenum type    = p->getType();
1090     int attribSize = p->getSize();
1091     unsigned int size = attribSize*count + first;
1092     unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
1093     cArrs.allocArr(size,type);
1094     int stride = p->getStride()?p->getStride():bytes*attribSize;
1095     const char* data = (const char*)p->getArrayData() + (first*stride);
1096 
1097     if(type == GL_FIXED) {
1098         convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize);
1099     } else if(type == GL_BYTE) {
1100         convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize);
1101     }
1102 }
1103 
convertDirectVBO(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)1104 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
1105 
1106     RangeList ranges;
1107     RangeList conversions;
1108     GLuint* indices = NULL;
1109     int attribSize = p->getSize();
1110     int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
1111     char* data = (char*)p->getBufferData();
1112 
1113     if(p->bufferNeedConversion()) {
1114         directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset
1115         p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
1116 
1117         if(conversions.size()) { // there are some elements to convert
1118            indices = new GLuint[count];
1119            int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array
1120            convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_INT,indices,stride,attribSize);
1121         }
1122     }
1123     if(indices) delete[] indices;
1124     cArrs.setArr(data,p->getStride(),GL_FLOAT);
1125 }
1126 
findMaxIndex(GLsizei count,GLenum type,const GLvoid * indices)1127 unsigned int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) {
1128     //finding max index
1129     unsigned int max = 0;
1130     if(type == GL_UNSIGNED_BYTE) {
1131         GLubyte*  b_indices  =(GLubyte *)indices;
1132         for(int i=0;i<count;i++) {
1133             if(b_indices[i] > max) max = b_indices[i];
1134         }
1135     } else if (type == GL_UNSIGNED_SHORT) {
1136         GLushort* us_indices =(GLushort *)indices;
1137         for(int i=0;i<count;i++) {
1138             if(us_indices[i] > max) max = us_indices[i];
1139         }
1140     } else { // type == GL_UNSIGNED_INT
1141         GLuint* ui_indices =(GLuint *)indices;
1142         for(int i=0;i<count;i++) {
1143             if(ui_indices[i] > max) max = ui_indices[i];
1144         }
1145     }
1146     return max;
1147 }
1148 
convertIndirect(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)1149 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
1150     GLenum type    = p->getType();
1151     int maxElements = findMaxIndex(count,indices_type,indices) + 1;
1152 
1153     int attribSize = p->getSize();
1154     int size = attribSize * maxElements;
1155     unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
1156     cArrs.allocArr(size,type);
1157     int stride = p->getStride()?p->getStride():bytes*attribSize;
1158 
1159     const char* data = (const char*)p->getArrayData();
1160     if(type == GL_FIXED) {
1161         convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize);
1162     } else if(type == GL_BYTE){
1163         convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize);
1164     }
1165 }
1166 
convertIndirectVBO(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)1167 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
1168     RangeList ranges;
1169     RangeList conversions;
1170     GLuint* conversionIndices = NULL;
1171     int attribSize = p->getSize();
1172     int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
1173     char* data = static_cast<char*>(p->getBufferData());
1174     if(p->bufferNeedConversion()) {
1175         indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset
1176         p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
1177         if(conversions.size()) { // there are some elements to convert
1178             conversionIndices = new GLuint[count];
1179             int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array
1180             convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_INT,conversionIndices,stride,attribSize);
1181         }
1182     }
1183     if(conversionIndices) delete[] conversionIndices;
1184     cArrs.setArr(data,p->getStride(),GL_FLOAT);
1185 }
1186 
bindBuffer(GLenum target,GLuint buffer)1187 GLuint GLEScontext::bindBuffer(GLenum target,GLuint buffer) {
1188     switch(target) {
1189     case GL_ARRAY_BUFFER:
1190         m_arrayBuffer = buffer;
1191         break;
1192     case GL_ELEMENT_ARRAY_BUFFER:
1193         m_currVaoState.iboId() = buffer;
1194         break;
1195     case GL_COPY_READ_BUFFER:
1196         m_copyReadBuffer = buffer;
1197         break;
1198     case GL_COPY_WRITE_BUFFER:
1199         m_copyWriteBuffer = buffer;
1200         break;
1201     case GL_PIXEL_PACK_BUFFER:
1202         m_pixelPackBuffer = buffer;
1203         break;
1204     case GL_PIXEL_UNPACK_BUFFER:
1205         m_pixelUnpackBuffer = buffer;
1206         break;
1207     case GL_TRANSFORM_FEEDBACK_BUFFER:
1208         m_transformFeedbackBuffer = buffer;
1209         break;
1210     case GL_UNIFORM_BUFFER:
1211         m_uniformBuffer = buffer;
1212         break;
1213     case GL_ATOMIC_COUNTER_BUFFER:
1214         m_atomicCounterBuffer = buffer;
1215         break;
1216     case GL_DISPATCH_INDIRECT_BUFFER:
1217         m_dispatchIndirectBuffer = buffer;
1218         break;
1219     case GL_DRAW_INDIRECT_BUFFER:
1220         m_drawIndirectBuffer = buffer;
1221         break;
1222     case GL_SHADER_STORAGE_BUFFER:
1223         m_shaderStorageBuffer = buffer;
1224         break;
1225     default:
1226         m_arrayBuffer = buffer;
1227         break;
1228     }
1229 
1230     if (!buffer) return 0;
1231 
1232     auto sg = m_shareGroup.get();
1233 
1234     if (!sg) return 0;
1235 
1236     return sg->ensureObjectOnBind(NamedObjectType::VERTEXBUFFER, buffer);
1237 }
1238 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,bool isBindBase)1239 void GLEScontext::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer,
1240         GLintptr offset, GLsizeiptr size, GLintptr stride, bool isBindBase) {
1241     VertexAttribBindingVector* bindings = nullptr;
1242     switch (target) {
1243     case GL_UNIFORM_BUFFER:
1244         bindings = &m_indexedUniformBuffers;
1245         break;
1246     case GL_ATOMIC_COUNTER_BUFFER:
1247         bindings = &m_indexedAtomicCounterBuffers;
1248         break;
1249     case GL_SHADER_STORAGE_BUFFER:
1250         bindings = &m_indexedShaderStorageBuffers;
1251         break;
1252     default:
1253         bindings = &m_currVaoState.bufferBindings();
1254         break;
1255     }
1256     if (index >= bindings->size()) {
1257             return;
1258     }
1259     auto& bufferBinding = (*bindings)[index];
1260     bufferBinding.buffer = buffer;
1261     bufferBinding.offset = offset;
1262     bufferBinding.size = size;
1263     bufferBinding.stride = stride;
1264     bufferBinding.isBindBase = isBindBase;
1265 }
1266 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer)1267 void GLEScontext::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer) {
1268     GLint sz;
1269     getBufferSizeById(buffer, &sz);
1270     bindIndexedBuffer(target, index, buffer, 0, sz, 0, true);
1271 }
1272 
sClearIndexedBufferBinding(GLuint id,std::vector<BufferBinding> & bindings)1273 static void sClearIndexedBufferBinding(GLuint id, std::vector<BufferBinding>& bindings) {
1274     for (size_t i = 0; i < bindings.size(); i++) {
1275         if (bindings[i].buffer == id) {
1276             bindings[i].offset = 0;
1277             bindings[i].size = 0;
1278             bindings[i].stride = 0;
1279             bindings[i].buffer = 0;
1280             bindings[i].isBindBase = false;
1281         }
1282     }
1283 }
1284 
unbindBuffer(GLuint buffer)1285 void GLEScontext::unbindBuffer(GLuint buffer) {
1286     if (m_arrayBuffer == buffer)
1287         m_arrayBuffer = 0;
1288     if (m_currVaoState.iboId() == buffer)
1289         m_currVaoState.iboId() = 0;
1290     if (m_copyReadBuffer == buffer)
1291         m_copyReadBuffer = 0;
1292     if (m_copyWriteBuffer == buffer)
1293         m_copyWriteBuffer = 0;
1294     if (m_pixelPackBuffer == buffer)
1295         m_pixelPackBuffer = 0;
1296     if (m_pixelUnpackBuffer == buffer)
1297         m_pixelUnpackBuffer = 0;
1298     if (m_transformFeedbackBuffer == buffer)
1299         m_transformFeedbackBuffer = 0;
1300     if (m_uniformBuffer == buffer)
1301         m_uniformBuffer = 0;
1302     if (m_atomicCounterBuffer == buffer)
1303         m_atomicCounterBuffer = 0;
1304     if (m_dispatchIndirectBuffer == buffer)
1305         m_dispatchIndirectBuffer = 0;
1306     if (m_drawIndirectBuffer == buffer)
1307         m_drawIndirectBuffer = 0;
1308     if (m_shaderStorageBuffer == buffer)
1309         m_shaderStorageBuffer = 0;
1310 
1311     // One might think that indexed buffer bindings for transform feedbacks
1312     // must be cleared as well, but transform feedbacks are
1313     // considered GL objects with attachments, so even if the buffer is
1314     // deleted (unbindBuffer is called), the state query with
1315     // glGetIntegeri_v must still return the deleted name [1].
1316     // sClearIndexedBufferBinding(buffer, m_indexedTransformFeedbackBuffers);
1317     // [1] OpenGL ES 3.0.5 spec Appendix D.1.3
1318     sClearIndexedBufferBinding(buffer, m_indexedUniformBuffers);
1319     sClearIndexedBufferBinding(buffer, m_indexedAtomicCounterBuffers);
1320     sClearIndexedBufferBinding(buffer, m_indexedShaderStorageBuffers);
1321     sClearIndexedBufferBinding(buffer, m_currVaoState.bufferBindings());
1322 }
1323 
1324 //checks if any buffer is binded to target
isBindedBuffer(GLenum target)1325 bool GLEScontext::isBindedBuffer(GLenum target) {
1326     switch(target) {
1327     case GL_ARRAY_BUFFER:
1328         return m_arrayBuffer != 0;
1329     case GL_ELEMENT_ARRAY_BUFFER:
1330         return m_currVaoState.iboId() != 0;
1331     case GL_COPY_READ_BUFFER:
1332         return m_copyReadBuffer != 0;
1333     case GL_COPY_WRITE_BUFFER:
1334         return m_copyWriteBuffer != 0;
1335     case GL_PIXEL_PACK_BUFFER:
1336         return m_pixelPackBuffer != 0;
1337     case GL_PIXEL_UNPACK_BUFFER:
1338         return m_pixelUnpackBuffer != 0;
1339     case GL_TRANSFORM_FEEDBACK_BUFFER:
1340         return m_transformFeedbackBuffer != 0;
1341     case GL_UNIFORM_BUFFER:
1342         return m_uniformBuffer != 0;
1343     case GL_ATOMIC_COUNTER_BUFFER:
1344         return m_atomicCounterBuffer != 0;
1345     case GL_DISPATCH_INDIRECT_BUFFER:
1346         return m_dispatchIndirectBuffer != 0;
1347     case GL_DRAW_INDIRECT_BUFFER:
1348         return m_drawIndirectBuffer != 0;
1349     case GL_SHADER_STORAGE_BUFFER:
1350         return m_shaderStorageBuffer != 0;
1351     default:
1352         return m_arrayBuffer != 0;
1353     }
1354 }
1355 
getBuffer(GLenum target)1356 GLuint GLEScontext::getBuffer(GLenum target) {
1357     switch(target) {
1358     case GL_ARRAY_BUFFER:
1359         return m_arrayBuffer;
1360     case GL_ELEMENT_ARRAY_BUFFER:
1361         return m_currVaoState.iboId();
1362     case GL_COPY_READ_BUFFER:
1363         return m_copyReadBuffer;
1364     case GL_COPY_WRITE_BUFFER:
1365         return m_copyWriteBuffer;
1366     case GL_PIXEL_PACK_BUFFER:
1367         return m_pixelPackBuffer;
1368     case GL_PIXEL_UNPACK_BUFFER:
1369         return m_pixelUnpackBuffer;
1370     case GL_TRANSFORM_FEEDBACK_BUFFER:
1371         return m_transformFeedbackBuffer;
1372     case GL_UNIFORM_BUFFER:
1373         return m_uniformBuffer;
1374     case GL_ATOMIC_COUNTER_BUFFER:
1375         return m_atomicCounterBuffer;
1376     case GL_DISPATCH_INDIRECT_BUFFER:
1377         return m_dispatchIndirectBuffer;
1378     case GL_DRAW_INDIRECT_BUFFER:
1379         return m_drawIndirectBuffer;
1380     case GL_SHADER_STORAGE_BUFFER:
1381         return m_shaderStorageBuffer;
1382     default:
1383         return m_arrayBuffer;
1384     }
1385 }
1386 
getIndexedBuffer(GLenum target,GLuint index)1387 GLuint GLEScontext::getIndexedBuffer(GLenum target, GLuint index) {
1388     switch (target) {
1389     case GL_UNIFORM_BUFFER:
1390         return m_indexedUniformBuffers[index].buffer;
1391     case GL_ATOMIC_COUNTER_BUFFER:
1392         return m_indexedAtomicCounterBuffers[index].buffer;
1393     case GL_SHADER_STORAGE_BUFFER:
1394         return m_indexedShaderStorageBuffers[index].buffer;
1395     default:
1396         return m_currVaoState.bufferBindings()[index].buffer;
1397     }
1398 }
1399 
1400 
getBindedBuffer(GLenum target)1401 GLvoid* GLEScontext::getBindedBuffer(GLenum target) {
1402     GLuint bufferName = getBuffer(target);
1403     if(!bufferName) return NULL;
1404 
1405     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1406             m_shareGroup
1407                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1408     return vbo->getData();
1409 }
1410 
getBufferSize(GLenum target,GLint * param)1411 void GLEScontext::getBufferSize(GLenum target,GLint* param) {
1412     GLuint bufferName = getBuffer(target);
1413     getBufferSizeById(bufferName, param);
1414 }
1415 
getBufferSizeById(GLuint bufferName,GLint * param)1416 void GLEScontext::getBufferSizeById(GLuint bufferName, GLint* param) {
1417     if (!bufferName) { *param = 0; return; }
1418     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1419             m_shareGroup
1420                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1421     *param = vbo->getSize();
1422 }
1423 
getBufferUsage(GLenum target,GLint * param)1424 void GLEScontext::getBufferUsage(GLenum target,GLint* param) {
1425     GLuint bufferName = getBuffer(target);
1426     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1427             m_shareGroup
1428                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1429     *param = vbo->getUsage();
1430 }
1431 
setBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)1432 bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) {
1433     GLuint bufferName = getBuffer(target);
1434     if(!bufferName) return false;
1435     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1436             m_shareGroup
1437                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1438     return vbo->setBuffer(size,usage,data);
1439 }
1440 
setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)1441 bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) {
1442 
1443     GLuint bufferName = getBuffer(target);
1444     if(!bufferName) return false;
1445     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1446             m_shareGroup
1447                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1448     return vbo->setSubBuffer(offset,size,data);
1449 }
1450 
setViewport(GLint x,GLint y,GLsizei width,GLsizei height)1451 void GLEScontext::setViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
1452     m_isViewport = true;
1453     m_viewportX = x;
1454     m_viewportY = y;
1455     m_viewportWidth = width;
1456     m_viewportHeight = height;
1457 }
1458 
getViewport(GLint * params)1459 void GLEScontext::getViewport(GLint* params) {
1460     if (!m_isViewport) {
1461         dispatcher().glGetIntegerv(GL_VIEWPORT, params);
1462     } else {
1463         params[0] = m_viewportX;
1464         params[1] = m_viewportY;
1465         params[2] = m_viewportWidth;
1466         params[3] = m_viewportHeight;
1467     }
1468 }
1469 
setScissor(GLint x,GLint y,GLsizei width,GLsizei height)1470 void GLEScontext::setScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1471     m_isScissor = true;
1472     m_scissorX = x;
1473     m_scissorY = y;
1474     m_scissorWidth = width;
1475     m_scissorHeight = height;
1476 }
1477 
setPolygonOffset(GLfloat factor,GLfloat units)1478 void GLEScontext::setPolygonOffset(GLfloat factor, GLfloat units) {
1479     m_polygonOffsetFactor = factor;
1480     m_polygonOffsetUnits = units;
1481 }
1482 
setEnable(GLenum item,bool isEnable)1483 void GLEScontext::setEnable(GLenum item, bool isEnable) {
1484     switch (item) {
1485         case GL_TEXTURE_2D:
1486         case GL_TEXTURE_CUBE_MAP_OES:
1487         case GL_TEXTURE_3D:
1488         case GL_TEXTURE_2D_ARRAY:
1489         case GL_TEXTURE_2D_MULTISAMPLE:
1490             setTextureEnabled(item,true);
1491             break;
1492         default:
1493             m_glEnableList[item] = isEnable;
1494             break;
1495     }
1496 }
1497 
isEnabled(GLenum item) const1498 bool GLEScontext::isEnabled(GLenum item) const {
1499     switch (item) {
1500         case GL_TEXTURE_2D:
1501         case GL_TEXTURE_CUBE_MAP_OES:
1502         case GL_TEXTURE_3D:
1503         case GL_TEXTURE_2D_ARRAY:
1504         case GL_TEXTURE_2D_MULTISAMPLE:
1505             return m_texState[m_activeTexture][GLTextureTargetToLocal(item)].enabled;
1506         default:
1507             return android::base::findOrDefault(m_glEnableList, item, false);
1508     }
1509 }
1510 
setBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)1511 void GLEScontext::setBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
1512     m_blendEquationRgb = modeRGB;
1513     m_blendEquationAlpha = modeAlpha;
1514 }
1515 
setBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)1516 void GLEScontext::setBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
1517             GLenum srcAlpha, GLenum dstAlpha) {
1518     m_blendSrcRgb = srcRGB;
1519     m_blendDstRgb = dstRGB;
1520     m_blendSrcAlpha = srcAlpha;
1521     m_blendDstAlpha = dstAlpha;
1522 }
1523 
setPixelStorei(GLenum pname,GLint param)1524 void GLEScontext::setPixelStorei(GLenum pname, GLint param) {
1525     m_glPixelStoreiList[pname] = param;
1526 }
1527 
setCullFace(GLenum mode)1528 void GLEScontext::setCullFace(GLenum mode) {
1529     m_cullFace = mode;
1530 }
1531 
setFrontFace(GLenum mode)1532 void GLEScontext::setFrontFace(GLenum mode) {
1533     m_frontFace = mode;
1534 }
1535 
setDepthFunc(GLenum func)1536 void GLEScontext::setDepthFunc(GLenum func) {
1537     m_depthFunc = func;
1538 }
1539 
setDepthMask(GLboolean flag)1540 void GLEScontext::setDepthMask(GLboolean flag) {
1541     m_depthMask = flag;
1542 }
1543 
setDepthRangef(GLclampf zNear,GLclampf zFar)1544 void GLEScontext::setDepthRangef(GLclampf zNear, GLclampf zFar) {
1545     m_zNear = zNear;
1546     m_zFar = zFar;
1547 }
1548 
setLineWidth(GLfloat lineWidth)1549 void GLEScontext::setLineWidth(GLfloat lineWidth) {
1550     m_lineWidth = lineWidth;
1551 }
1552 
setSampleCoverage(GLclampf value,GLboolean invert)1553 void GLEScontext::setSampleCoverage(GLclampf value, GLboolean invert) {
1554     m_sampleCoverageVal = value;
1555     m_sampleCoverageInvert = invert;
1556 }
setStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)1557 void GLEScontext::setStencilFuncSeparate(GLenum face, GLenum func, GLint ref,
1558         GLuint mask) {
1559     if (face == GL_FRONT_AND_BACK) {
1560         setStencilFuncSeparate(GL_FRONT, func, ref, mask);
1561         setStencilFuncSeparate(GL_BACK, func, ref, mask);
1562         return;
1563     }
1564     int idx = 0;
1565     switch (face) {
1566         case GL_FRONT:
1567             idx = StencilFront;
1568             break;
1569         case GL_BACK:
1570             idx = StencilBack;
1571             break;
1572         default:
1573             return;
1574     }
1575     m_stencilStates[idx].m_func = func;
1576     m_stencilStates[idx].m_ref = ref;
1577     m_stencilStates[idx].m_funcMask = mask;
1578 }
1579 
setStencilMaskSeparate(GLenum face,GLuint mask)1580 void GLEScontext::setStencilMaskSeparate(GLenum face, GLuint mask) {
1581     if (face == GL_FRONT_AND_BACK) {
1582         setStencilMaskSeparate(GL_FRONT, mask);
1583         setStencilMaskSeparate(GL_BACK, mask);
1584         return;
1585     }
1586     int idx = 0;
1587     switch (face) {
1588         case GL_FRONT:
1589             idx = StencilFront;
1590             break;
1591         case GL_BACK:
1592             idx = StencilBack;
1593             break;
1594         default:
1595             return;
1596     }
1597     m_stencilStates[idx].m_writeMask = mask;
1598 }
1599 
setStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)1600 void GLEScontext::setStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail,
1601         GLenum zpass) {
1602     if (face == GL_FRONT_AND_BACK) {
1603         setStencilOpSeparate(GL_FRONT, fail, zfail, zpass);
1604         setStencilOpSeparate(GL_BACK, fail, zfail, zpass);
1605         return;
1606     }
1607     int idx = 0;
1608     switch (face) {
1609         case GL_FRONT:
1610             idx = StencilFront;
1611             break;
1612         case GL_BACK:
1613             idx = StencilBack;
1614             break;
1615         default:
1616             return;
1617     }
1618     m_stencilStates[idx].m_sfail = fail;
1619     m_stencilStates[idx].m_dpfail = zfail;
1620     m_stencilStates[idx].m_dppass = zpass;
1621 }
1622 
setColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)1623 void GLEScontext::setColorMask(GLboolean red, GLboolean green, GLboolean blue,
1624         GLboolean alpha) {
1625     m_colorMaskR = red;
1626     m_colorMaskG = green;
1627     m_colorMaskB = blue;
1628     m_colorMaskA = alpha;
1629 }
1630 
setClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)1631 void GLEScontext::setClearColor(GLclampf red, GLclampf green, GLclampf blue,
1632         GLclampf alpha) {
1633     m_clearColorR = red;
1634     m_clearColorG = green;
1635     m_clearColorB = blue;
1636     m_clearColorA = alpha;
1637 }
1638 
setClearDepth(GLclampf depth)1639 void GLEScontext::setClearDepth(GLclampf depth) {
1640     m_clearDepth = depth;
1641 }
1642 
setClearStencil(GLint s)1643 void GLEScontext::setClearStencil(GLint s) {
1644     m_clearStencil = s;
1645 }
1646 
getExtensionString(bool isGles1)1647 const char * GLEScontext::getExtensionString(bool isGles1) {
1648     const char * ret;
1649     s_lock.lock();
1650     if (isGles1) {
1651         if (s_glExtensionsGles1)
1652             ret = s_glExtensionsGles1->c_str();
1653         else
1654             ret="";
1655     } else {
1656         if (s_glExtensions)
1657             ret = s_glExtensions->c_str();
1658         else
1659             ret="";
1660     }
1661     s_lock.unlock();
1662     return ret;
1663 }
1664 
getVendorString(bool isGles1) const1665 const char * GLEScontext::getVendorString(bool isGles1) const {
1666     return isGles1 ? s_glVendorGles1.c_str() : s_glVendor.c_str();
1667 }
1668 
getRendererString(bool isGles1) const1669 const char * GLEScontext::getRendererString(bool isGles1) const {
1670     return isGles1 ? s_glRendererGles1.c_str() : s_glRenderer.c_str();
1671 }
1672 
getVersionString(bool isGles1) const1673 const char * GLEScontext::getVersionString(bool isGles1) const {
1674     return isGles1 ? s_glVersionGles1.c_str() : s_glVersion.c_str();
1675 }
1676 
getGlobalLock()1677 void GLEScontext::getGlobalLock() {
1678     s_lock.lock();
1679 }
1680 
releaseGlobalLock()1681 void GLEScontext::releaseGlobalLock() {
1682     s_lock.unlock();
1683 }
1684 
initCapsLocked(const GLubyte * extensionString)1685 void GLEScontext::initCapsLocked(const GLubyte * extensionString)
1686 {
1687     const char* cstring = (const char*)extensionString;
1688 
1689     s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs);
1690 
1691     if (s_glSupport.maxVertexAttribs > kMaxVertexAttributes) {
1692         s_glSupport.maxVertexAttribs = kMaxVertexAttributes;
1693     }
1694 
1695     s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane);
1696     s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights);
1697     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
1698     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits);
1699     // Core profile lacks a fixed-function pipeline with texture units,
1700     // but we still want glDrawTexOES to work in core profile.
1701     // So, set it to 8.
1702     if ((::isCoreProfile() || isGles2Gles()) &&
1703         !s_glSupport.maxTexUnits) {
1704         s_glSupport.maxTexUnits = 8;
1705     }
1706     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits);
1707     s_glDispatch.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &s_glSupport.maxCombinedTexImageUnits);
1708 
1709     s_glDispatch.glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &s_glSupport.maxTransformFeedbackSeparateAttribs);
1710     s_glDispatch.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &s_glSupport.maxUniformBufferBindings);
1711     s_glDispatch.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &s_glSupport.maxAtomicCounterBufferBindings);
1712     s_glDispatch.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &s_glSupport.maxShaderStorageBufferBindings);
1713     s_glDispatch.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &s_glSupport.maxDrawBuffers);
1714     s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &s_glSupport.maxVertexAttribBindings);
1715 
1716     // Compressed texture format query
1717     if(feature_is_enabled(kFeature_NativeTextureDecompression)) {
1718         bool hasEtc2Support = false;
1719         bool hasAstcSupport = false;
1720         int numCompressedFormats = 0;
1721         s_glDispatch.glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedFormats);
1722         if (numCompressedFormats > 0) {
1723             int numEtc2Formats = 0;
1724             int numAstcFormats = 0;
1725             int numEtc2FormatsSupported = 0;
1726             int numAstcFormatsSupported = 0;
1727 
1728             std::map<GLint, bool> found;
1729             forEachEtc2Format([&numEtc2Formats, &found](GLint format) { ++numEtc2Formats; found[format] = false;});
1730             forEachAstcFormat([&numAstcFormats, &found](GLint format) { ++numAstcFormats; found[format] = false;});
1731 
1732             std::vector<GLint> formats(numCompressedFormats);
1733             s_glDispatch.glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats.data());
1734 
1735             for (int i = 0; i < numCompressedFormats; ++i) {
1736                 GLint format = formats[i];
1737                 if (isEtc2Format(format)) {
1738                     ++numEtc2FormatsSupported;
1739                     found[format] = true;
1740                 } else if (isAstcFormat(format)) {
1741                     ++numAstcFormatsSupported;
1742                     found[format] = true;
1743                 }
1744             }
1745 
1746             if (numEtc2Formats == numEtc2FormatsSupported) {
1747                 hasEtc2Support = true; // Supports ETC2 underneath
1748             } else {
1749                 // It is unusual to support only some. Record what happened.
1750                 ERR("Not supporting etc2: %d vs %d",
1751                     numEtc2FormatsSupported, numEtc2Formats);
1752                 for (auto it : found) {
1753                     if (!it.second) {
1754                         ERR("Not found: 0x%x", it.first);
1755                     }
1756                 }
1757             }
1758 
1759             if (numAstcFormats == numAstcFormatsSupported) {
1760                 hasAstcSupport = true; // Supports ASTC underneath
1761             } else {
1762                 // It is unusual to support only some. Record what happened.
1763                 ERR("Not supporting astc: %d vs %d",
1764                     numAstcFormatsSupported, numAstcFormats);
1765                 for (auto it : found) {
1766                     if (!it.second) {
1767                         ERR("Not found: 0x%x", it.first);
1768                     }
1769                 }
1770             }
1771         }
1772         s_glSupport.hasEtc2Support = hasEtc2Support;
1773         s_glSupport.hasAstcSupport = hasAstcSupport;
1774     }
1775 
1776     // Clear GL error in case these enums not supported.
1777     s_glDispatch.glGetError();
1778 
1779     const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION);
1780     s_glSupport.glslVersion = Version((const  char*)(glslVersion));
1781     const GLubyte* glVersion = s_glDispatch.glGetString(GL_VERSION);
1782 
1783     // fprintf(stderr, "%s: vendor renderer version [%s] [%s] [%s]\n", __func__,
1784     //         s_glDispatch.glGetString(GL_VENDOR),
1785     //         s_glDispatch.glGetString(GL_RENDERER),
1786     //         s_glDispatch.glGetString(GL_VERSION));
1787 
1788     if (strstr(cstring,"GL_EXT_bgra ")!=NULL ||
1789         (isGles2Gles() && strstr(cstring, "GL_EXT_texture_format_BGRA8888")) ||
1790         (!isGles2Gles() && !(Version((const char*)glVersion) < Version("1.2"))))
1791         s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;
1792 
1793     if (::isCoreProfile() ||
1794         strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL)
1795         s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true;
1796 
1797     if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL)
1798         s_glSupport.GL_ARB_VERTEX_BLEND = true;
1799 
1800     if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL)
1801         s_glSupport.GL_ARB_MATRIX_PALETTE = true;
1802 
1803     if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL ||
1804         strstr(cstring,"GL_OES_packed_depth_stencil ")!=NULL)
1805         s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true;
1806 
1807     if (strstr(cstring,"GL_OES_read_format ")!=NULL)
1808         s_glSupport.GL_OES_READ_FORMAT = true;
1809 
1810     if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL ||
1811         strstr(cstring,"GL_OES_texture_half_float ")!=NULL)
1812         s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true;
1813 
1814     if (strstr(cstring,"GL_NV_half_float ")!=NULL)
1815         s_glSupport.GL_NV_HALF_FLOAT = true;
1816 
1817     if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL ||
1818         strstr(cstring,"GL_OES_vertex_half_float ")!=NULL)
1819         s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true;
1820 
1821     if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL)
1822         s_glSupport.GL_SGIS_GENERATE_MIPMAP = true;
1823 
1824     if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL
1825             || isGles2Gles())
1826         s_glSupport.GL_ARB_ES2_COMPATIBILITY = true;
1827 
1828     if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL)
1829         s_glSupport.GL_OES_STANDARD_DERIVATIVES = true;
1830 
1831     if (::isCoreProfile() ||
1832         strstr(cstring,"GL_ARB_texture_non_power_of_two")!=NULL ||
1833         strstr(cstring,"GL_OES_texture_npot")!=NULL)
1834         s_glSupport.GL_OES_TEXTURE_NPOT = true;
1835 
1836     if (::isCoreProfile() ||
1837         strstr(cstring,"GL_ARB_color_buffer_float")!=NULL ||
1838         strstr(cstring,"GL_EXT_color_buffer_float")!=NULL)
1839         s_glSupport.ext_GL_EXT_color_buffer_float = true;
1840 
1841     if (::isCoreProfile() ||
1842         strstr(cstring,"GL_EXT_color_buffer_half_float")!=NULL)
1843         s_glSupport.ext_GL_EXT_color_buffer_half_float = true;
1844 
1845     if (strstr(cstring,"GL_EXT_shader_framebuffer_fetch")!=NULL) {
1846         s_glSupport.ext_GL_EXT_shader_framebuffer_fetch = true;
1847     }
1848 
1849     if (!(Version((const char*)glVersion) < Version("3.0")) || strstr(cstring,"GL_OES_rgb8_rgba8")!=NULL)
1850         s_glSupport.GL_OES_RGB8_RGBA8 = true;
1851 
1852     if (strstr(cstring, "GL_EXT_memory_object") != NULL) {
1853         s_glSupport.ext_GL_EXT_memory_object = true;
1854     }
1855 
1856     if (strstr(cstring, "GL_EXT_semaphore") != NULL) {
1857         s_glSupport.ext_GL_EXT_semaphore = true;
1858     }
1859 
1860     // ASTC
1861     if (strstr(cstring, "GL_KHR_texture_compression_astc_ldr") != NULL) {
1862         s_glSupport.ext_GL_KHR_texture_compression_astc_ldr = true;
1863     }
1864 
1865     // BPTC extension detection
1866     if (feature_is_enabled(kFeature_BptcTextureSupport)) {
1867         if ((strstr(cstring, "GL_EXT_texture_compression_bptc") != NULL) ||
1868             (strstr(cstring, "GL_ARB_texture_compression_bptc") != NULL)) {
1869             s_glSupport.hasBptcSupport = true;
1870         }
1871     }
1872 
1873     if (feature_is_enabled(kFeature_S3tcTextureSupport)) {
1874         if (strstr(cstring, "GL_EXT_texture_compression_s3tc") != NULL) {
1875             s_glSupport.hasS3tcSupport = true;
1876         }
1877     }
1878 
1879     if (feature_is_enabled(kFeature_RgtcTextureSupport)) {
1880         if (strstr(cstring, "GL_EXT_texture_compression_rgtc") != NULL) {
1881             s_glSupport.hasRgtcSupport = true;
1882         }
1883     }
1884 }
1885 
buildStrings(bool isGles1,const char * baseVendor,const char * baseRenderer,const char * baseVersion,const char * version)1886 void GLEScontext::buildStrings(bool isGles1, const char* baseVendor,
1887         const char* baseRenderer, const char* baseVersion, const char* version)
1888 {
1889     static const char VENDOR[]   = {"Google ("};
1890     static const char RENDERER[] = {"Android Emulator OpenGL ES Translator ("};
1891     const size_t VENDOR_LEN   = sizeof(VENDOR) - 1;
1892     const size_t RENDERER_LEN = sizeof(RENDERER) - 1;
1893 
1894     // Sanitize the strings as some OpenGL implementations return NULL
1895     // when asked the basic questions (this happened at least once on a client
1896     // machine)
1897     if (!baseVendor) {
1898         baseVendor = "N/A";
1899     }
1900     if (!baseRenderer) {
1901         baseRenderer = "N/A";
1902     }
1903     if (!baseVersion) {
1904         baseVersion = "N/A";
1905     }
1906     if (!version) {
1907         version = "N/A";
1908     }
1909 
1910     std::string& vendorString = isGles1 ? s_glVendorGles1 : s_glVendor;
1911     std::string& rendererString = isGles1 ? s_glRendererGles1 : s_glRenderer;
1912     std::string& versionString = isGles1 ? s_glVersionGles1 : s_glVersion;
1913 
1914     size_t baseVendorLen = strlen(baseVendor);
1915     vendorString.clear();
1916     vendorString.reserve(baseVendorLen + VENDOR_LEN + 1);
1917     vendorString.append(VENDOR, VENDOR_LEN);
1918     vendorString.append(baseVendor, baseVendorLen);
1919     vendorString.append(")", 1);
1920 
1921     size_t baseRendererLen = strlen(baseRenderer);
1922     rendererString.clear();
1923     rendererString.reserve(baseRendererLen + RENDERER_LEN + 1);
1924     rendererString.append(RENDERER, RENDERER_LEN);
1925     rendererString.append(baseRenderer, baseRendererLen);
1926     rendererString.append(")", 1);
1927 
1928     size_t baseVersionLen = strlen(baseVersion);
1929     size_t versionLen = strlen(version);
1930     versionString.clear();
1931     versionString.reserve(baseVersionLen + versionLen + 3);
1932     versionString.append(version, versionLen);
1933     versionString.append(" (", 2);
1934     versionString.append(baseVersion, baseVersionLen);
1935     versionString.append(")", 1);
1936 }
1937 
isTextureUnitEnabled(GLenum unit)1938 bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
1939     for (int i=0;i<NUM_TEXTURE_TARGETS;++i) {
1940         if (m_texState[unit-GL_TEXTURE0][i].enabled)
1941             return true;
1942     }
1943     return false;
1944 }
1945 
glGetBooleanv(GLenum pname,GLboolean * params)1946 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params)
1947 {
1948     GLint iParam;
1949 
1950     if(glGetIntegerv(pname, &iParam))
1951     {
1952         *params = (iParam != 0);
1953         return true;
1954     }
1955 
1956     return false;
1957 }
1958 
glGetFixedv(GLenum pname,GLfixed * params)1959 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params)
1960 {
1961     bool result = false;
1962     GLint numParams = 1;
1963 
1964     GLint* iParams = new GLint[numParams];
1965     if (numParams>0 && glGetIntegerv(pname,iParams)) {
1966         while(numParams >= 0)
1967         {
1968             params[numParams] = I2X(iParams[numParams]);
1969             numParams--;
1970         }
1971         result = true;
1972     }
1973     delete [] iParams;
1974 
1975     return result;
1976 }
1977 
glGetFloatv(GLenum pname,GLfloat * params)1978 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params)
1979 {
1980     bool result = false;
1981     GLint numParams = 1;
1982 
1983     GLint* iParams = new GLint[numParams];
1984     if (numParams>0 && glGetIntegerv(pname,iParams)) {
1985         while(numParams >= 0)
1986         {
1987             params[numParams] = (GLfloat)iParams[numParams];
1988             numParams--;
1989         }
1990         result = true;
1991     }
1992     delete [] iParams;
1993 
1994     return result;
1995 }
1996 
glGetIntegerv(GLenum pname,GLint * params)1997 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
1998 {
1999     switch(pname)
2000     {
2001         case GL_ARRAY_BUFFER_BINDING:
2002             *params = m_arrayBuffer;
2003             break;
2004 
2005         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2006             *params = m_currVaoState.iboId();
2007             break;
2008 
2009         case GL_TEXTURE_BINDING_CUBE_MAP:
2010             *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture;
2011             break;
2012 
2013         case GL_TEXTURE_BINDING_2D:
2014             *params = m_texState[m_activeTexture][TEXTURE_2D].texture;
2015             break;
2016 
2017         case GL_ACTIVE_TEXTURE:
2018             *params = m_activeTexture+GL_TEXTURE0;
2019             break;
2020 
2021         case GL_MAX_TEXTURE_SIZE:
2022             *params = getMaxTexSize();
2023             break;
2024         default:
2025             return false;
2026     }
2027 
2028     return true;
2029 }
2030 
GLTextureTargetToLocal(GLenum target)2031 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) {
2032     TextureTarget value=TEXTURE_2D;
2033     switch (target) {
2034     case GL_TEXTURE_CUBE_MAP:
2035     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2036     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2037     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2038     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2039     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2040     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2041         value = TEXTURE_CUBE_MAP;
2042         break;
2043     case GL_TEXTURE_2D:
2044         value = TEXTURE_2D;
2045         break;
2046     case GL_TEXTURE_2D_ARRAY:
2047         value = TEXTURE_2D_ARRAY;
2048         break;
2049     case GL_TEXTURE_3D:
2050         value = TEXTURE_3D;
2051         break;
2052     case GL_TEXTURE_2D_MULTISAMPLE:
2053         value = TEXTURE_2D_MULTISAMPLE;
2054         break;
2055     }
2056     return value;
2057 }
2058 
getBindedTexture(GLenum target)2059 unsigned int GLEScontext::getBindedTexture(GLenum target) {
2060     TextureTarget pos = GLTextureTargetToLocal(target);
2061     return m_texState[m_activeTexture][pos].texture;
2062 }
2063 
getBindedTexture(GLenum unit,GLenum target)2064 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) {
2065     TextureTarget pos = GLTextureTargetToLocal(target);
2066     return m_texState[unit-GL_TEXTURE0][pos].texture;
2067 }
2068 
setBindedTexture(GLenum target,unsigned int tex)2069 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) {
2070     TextureTarget pos = GLTextureTargetToLocal(target);
2071     m_texState[m_activeTexture][pos].texture = tex;
2072 }
2073 
setTextureEnabled(GLenum target,GLenum enable)2074 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) {
2075     TextureTarget pos = GLTextureTargetToLocal(target);
2076     m_texState[m_activeTexture][pos].enabled = enable;
2077 }
2078 
2079 #define INTERNAL_NAME(x) (x +0x100000000ll);
2080 
getDefaultTextureName(GLenum target)2081 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
2082     ObjectLocalName name = 0;
2083     switch (GLTextureTargetToLocal(target)) {
2084     case TEXTURE_2D:
2085         name = INTERNAL_NAME(0);
2086         break;
2087     case TEXTURE_CUBE_MAP:
2088         name = INTERNAL_NAME(1);
2089         break;
2090     case TEXTURE_2D_ARRAY:
2091         name = INTERNAL_NAME(2);
2092         break;
2093     case TEXTURE_3D:
2094         name = INTERNAL_NAME(3);
2095         break;
2096     case TEXTURE_2D_MULTISAMPLE:
2097         name = INTERNAL_NAME(4);
2098         break;
2099     default:
2100         name = 0;
2101         break;
2102     }
2103     return name;
2104 }
2105 
getTextureLocalName(GLenum target,unsigned int tex)2106 ObjectLocalName GLEScontext::getTextureLocalName(GLenum target,
2107         unsigned int tex) {
2108     return (tex!=0? tex : getDefaultTextureName(target));
2109 }
2110 
drawValidate(void)2111 void GLEScontext::drawValidate(void)
2112 {
2113     if(m_drawFramebuffer == 0)
2114         return;
2115 
2116     auto fbObj = getFBOData(m_drawFramebuffer);
2117     if (!fbObj)
2118         return;
2119 
2120     fbObj->validate(this);
2121 }
2122 
initEmulatedEGLSurface(GLint width,GLint height,GLint colorFormat,GLint depthstencilFormat,GLint multisamples,GLuint rboColor,GLuint rboDepth)2123 void GLEScontext::initEmulatedEGLSurface(GLint width, GLint height,
2124                              GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
2125                              GLuint rboColor, GLuint rboDepth) {
2126     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, rboColor);
2127     if (multisamples) {
2128         dispatcher().glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisamples, colorFormat, width, height);
2129         GLint err = dispatcher().glGetError();
2130         if (err != GL_NO_ERROR) {
2131             ERR("error setting up multisampled RBO! 0x%x", err);
2132         }
2133     } else {
2134         dispatcher().glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
2135     }
2136 
2137     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);
2138     if (multisamples) {
2139         dispatcher().glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisamples, depthstencilFormat, width, height);
2140         GLint err = dispatcher().glGetError();
2141         if (err != GL_NO_ERROR) {
2142             ERR("error setting up multisampled RBO! 0x%x", err);
2143         }
2144     } else {
2145         dispatcher().glRenderbufferStorage(GL_RENDERBUFFER, depthstencilFormat, width, height);
2146     }
2147 }
2148 
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)2149 void GLEScontext::initDefaultFBO(
2150         GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
2151         GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
2152         GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthStencilFormat, GLint readMultisamples,
2153         GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
2154 
2155     if (!m_defaultFBO) {
2156         dispatcher().glGenFramebuffers(1, &m_defaultFBO);
2157         m_defaultReadFBO = m_defaultFBO;
2158     }
2159 
2160     bool needReallocateRbo = false;
2161     bool separateReadRbo = false;
2162     bool needReallocateReadRbo = false;
2163 
2164     separateReadRbo =
2165         eglReadSurfaceRBColorId !=
2166         eglSurfaceRBColorId;
2167 
2168     if (separateReadRbo && (m_defaultReadFBO == m_defaultFBO)) {
2169         dispatcher().glGenFramebuffers(1, &m_defaultReadFBO);
2170     }
2171 
2172     if (!(*eglSurfaceRBColorId)) {
2173         dispatcher().glGenRenderbuffers(1, eglSurfaceRBColorId);
2174         dispatcher().glGenRenderbuffers(1, eglSurfaceRBDepthId);
2175         needReallocateRbo = true;
2176     }
2177 
2178     if (!(*eglReadSurfaceRBColorId) && separateReadRbo) {
2179         dispatcher().glGenRenderbuffers(1, eglReadSurfaceRBColorId);
2180         dispatcher().glGenRenderbuffers(1, eglReadSurfaceRBDepthId);
2181         needReallocateReadRbo = true;
2182     }
2183 
2184     m_defaultFBOColorFormat = colorFormat;
2185     m_defaultFBOWidth = width;
2186     m_defaultFBOHeight = height;
2187     m_defaultFBOSamples = multisamples;
2188 
2189     GLint prevRbo;
2190     dispatcher().glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRbo);
2191 
2192     // OS X in legacy opengl mode does not actually support GL_RGB565 as a renderbuffer.
2193     // Just replace it with GL_RGB8 for now.
2194     // TODO: Re-enable GL_RGB565 for OS X when we move to core profile.
2195 #ifdef __APPLE__
2196     if (colorFormat == GL_RGB565)
2197         colorFormat = GL_RGB8;
2198     if (readColorFormat == GL_RGB565)
2199         readColorFormat = GL_RGB8;
2200 #endif
2201 
2202     if (needReallocateRbo) {
2203         initEmulatedEGLSurface(width, height, colorFormat, depthstencilFormat, multisamples,
2204                                 *eglSurfaceRBColorId, *eglSurfaceRBDepthId);
2205     }
2206 
2207     if (needReallocateReadRbo) {
2208         initEmulatedEGLSurface(readWidth, readHeight, readColorFormat, readDepthStencilFormat, readMultisamples,
2209                                 *eglReadSurfaceRBColorId, *eglReadSurfaceRBDepthId);
2210     }
2211 
2212     dispatcher().glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2213 
2214     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *eglSurfaceRBColorId);
2215     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *eglSurfaceRBDepthId);
2216     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *eglSurfaceRBDepthId);
2217 
2218     if (m_defaultFBODrawBuffer != GL_COLOR_ATTACHMENT0) {
2219         dispatcher().glDrawBuffers(1, &m_defaultFBODrawBuffer);
2220     }
2221     if (m_defaultFBOReadBuffer != GL_COLOR_ATTACHMENT0) {
2222         dispatcher().glReadBuffer(m_defaultFBOReadBuffer);
2223     }
2224 
2225     if (separateReadRbo) {
2226         dispatcher().glBindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultReadFBO);
2227         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *eglReadSurfaceRBColorId);
2228         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *eglReadSurfaceRBDepthId);
2229         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *eglReadSurfaceRBDepthId);
2230     }
2231 
2232     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, prevRbo);
2233     GLuint prevDrawFBOBinding = getFramebufferBinding(GL_FRAMEBUFFER);
2234     GLuint prevReadFBOBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2235 
2236     if (prevDrawFBOBinding)
2237         dispatcher().glBindFramebuffer(GL_FRAMEBUFFER, getFBOGlobalName(prevDrawFBOBinding));
2238     if (prevReadFBOBinding)
2239         dispatcher().glBindFramebuffer(GL_READ_FRAMEBUFFER, getFBOGlobalName(prevReadFBOBinding));
2240 
2241     // We might be initializing a surfaceless context underneath
2242     // where the viewport is initialized to 0x0 width and height.
2243     // Set to our wanted pbuffer dimensions if this is the first time
2244     // the viewport has been set.
2245     if (!m_isViewport) {
2246         setViewport(0, 0, width, height);
2247         dispatcher().glViewport(0, 0, width, height);
2248     }
2249     // same for the scissor
2250     if (!m_isScissor) {
2251         setScissor(0, 0, width, height);
2252         dispatcher().glScissor(0, 0, width, height);
2253     }
2254 }
2255 
2256 
prepareCoreProfileEmulatedTexture(TextureData * texData,bool is3d,GLenum target,GLenum format,GLenum type,GLint * internalformat_out,GLenum * format_out)2257 void GLEScontext::prepareCoreProfileEmulatedTexture(TextureData* texData, bool is3d, GLenum target,
2258                                                     GLenum format, GLenum type,
2259                                                     GLint* internalformat_out, GLenum* format_out) {
2260     if (format != GL_ALPHA &&
2261         format != GL_LUMINANCE &&
2262         format != GL_LUMINANCE_ALPHA) {
2263         return;
2264     }
2265 
2266     if (isCubeMapFaceTarget(target)) {
2267         target = is3d ? GL_TEXTURE_CUBE_MAP_ARRAY_EXT : GL_TEXTURE_CUBE_MAP;
2268     }
2269 
2270     // Set up the swizzle from the underlying supported
2271     // host format to the emulated format.
2272     // Make sure to re-apply any user-specified custom swizlz
2273     TextureSwizzle userSwz; // initialized to identity map
2274 
2275     if (texData) {
2276         userSwz.toRed = texData->getSwizzle(GL_TEXTURE_SWIZZLE_R);
2277         userSwz.toGreen = texData->getSwizzle(GL_TEXTURE_SWIZZLE_G);
2278         userSwz.toBlue = texData->getSwizzle(GL_TEXTURE_SWIZZLE_B);
2279         userSwz.toAlpha = texData->getSwizzle(GL_TEXTURE_SWIZZLE_A);
2280     }
2281 
2282     TextureSwizzle swz =
2283         concatSwizzles(getSwizzleForEmulatedFormat(format),
2284                        userSwz);
2285 
2286     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, swz.toRed);
2287     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, swz.toGreen);
2288     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, swz.toBlue);
2289     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, swz.toAlpha);
2290 
2291     // Change the format/internalformat communicated to GL.
2292     GLenum emulatedFormat =
2293         getCoreProfileEmulatedFormat(format);
2294     GLint emulatedInternalFormat =
2295         getCoreProfileEmulatedInternalFormat(format, type);
2296 
2297     if (format_out) *format_out = emulatedFormat;
2298     if (internalformat_out) *internalformat_out = emulatedInternalFormat;
2299 }
2300 
isFBO(ObjectLocalName p_localName)2301 bool GLEScontext::isFBO(ObjectLocalName p_localName) {
2302     return m_fboNameSpace->isObject(p_localName);
2303 }
2304 
genFBOName(ObjectLocalName p_localName,bool genLocal)2305 ObjectLocalName GLEScontext::genFBOName(ObjectLocalName p_localName,
2306         bool genLocal) {
2307     return m_fboNameSpace->genName(GenNameInfo(NamedObjectType::FRAMEBUFFER),
2308             p_localName, genLocal);
2309 }
2310 
setFBOData(ObjectLocalName p_localName,ObjectDataPtr data)2311 void GLEScontext::setFBOData(ObjectLocalName p_localName, ObjectDataPtr data) {
2312     m_fboNameSpace->setObjectData(p_localName, data);
2313 }
2314 
deleteFBO(ObjectLocalName p_localName)2315 void GLEScontext::deleteFBO(ObjectLocalName p_localName) {
2316     m_fboNameSpace->deleteName(p_localName);
2317 }
2318 
getFBOData(ObjectLocalName p_localName) const2319 FramebufferData* GLEScontext::getFBOData(ObjectLocalName p_localName) const {
2320     return (FramebufferData*)getFBODataPtr(p_localName).get();
2321 }
2322 
getFBODataPtr(ObjectLocalName p_localName) const2323 ObjectDataPtr GLEScontext::getFBODataPtr(ObjectLocalName p_localName) const {
2324     return m_fboNameSpace->getObjectDataPtr(p_localName);
2325 }
2326 
getFBOGlobalName(ObjectLocalName p_localName) const2327 unsigned int GLEScontext::getFBOGlobalName(ObjectLocalName p_localName) const {
2328     return m_fboNameSpace->getGlobalName(p_localName);
2329 }
2330 
getFBOLocalName(unsigned int p_globalName) const2331 ObjectLocalName GLEScontext::getFBOLocalName(unsigned int p_globalName) const {
2332     return m_fboNameSpace->getLocalName(p_globalName);
2333 }
2334 
queryCurrFboBits(ObjectLocalName localFboName,GLenum pname)2335 int GLEScontext::queryCurrFboBits(ObjectLocalName localFboName, GLenum pname) {
2336     GLint colorInternalFormat = 0;
2337     GLint depthInternalFormat = 0;
2338     GLint stencilInternalFormat = 0;
2339     bool combinedDepthStencil = false;
2340 
2341     if (!localFboName) {
2342         colorInternalFormat = m_defaultFBOColorFormat;
2343         // FBO 0 defaulting to d24s8
2344         depthInternalFormat =
2345             m_defaultFBODepthFormat ? m_defaultFBODepthFormat : GL_DEPTH24_STENCIL8;
2346         stencilInternalFormat =
2347             m_defaultFBOStencilFormat ? m_defaultFBOStencilFormat : GL_DEPTH24_STENCIL8;
2348     } else {
2349         FramebufferData* fbData = getFBOData(localFboName);
2350 
2351         std::vector<GLenum> colorAttachments(getCaps()->maxDrawBuffers);
2352         std::iota(colorAttachments.begin(), colorAttachments.end(), GL_COLOR_ATTACHMENT0);
2353 
2354         bool hasColorAttachment = false;
2355         for (auto attachment : colorAttachments) {
2356             GLint internalFormat =
2357                 fbData->getAttachmentInternalFormat(this, attachment);
2358 
2359             // Only defined if all used color attachments are the same
2360             // internal format.
2361             if (internalFormat) {
2362                 if (hasColorAttachment &&
2363                     colorInternalFormat != internalFormat) {
2364                     colorInternalFormat = 0;
2365                     break;
2366                 }
2367                 colorInternalFormat = internalFormat;
2368                 hasColorAttachment = true;
2369             }
2370         }
2371 
2372         GLint depthStencilFormat =
2373             fbData->getAttachmentInternalFormat(this, GL_DEPTH_STENCIL_ATTACHMENT);
2374 
2375         if (depthStencilFormat) {
2376             combinedDepthStencil = true;
2377             depthInternalFormat = depthStencilFormat;
2378             stencilInternalFormat = depthStencilFormat;
2379         }
2380 
2381         if (!combinedDepthStencil) {
2382             depthInternalFormat =
2383                 fbData->getAttachmentInternalFormat(this, GL_DEPTH_ATTACHMENT);
2384             stencilInternalFormat =
2385                 fbData->getAttachmentInternalFormat(this, GL_STENCIL_ATTACHMENT);
2386         }
2387     }
2388 
2389     FramebufferChannelBits res =
2390         glFormatToChannelBits(colorInternalFormat,
2391                               depthInternalFormat,
2392                               stencilInternalFormat);
2393 
2394     switch (pname) {
2395     case GL_RED_BITS:
2396         return res.red;
2397     case GL_GREEN_BITS:
2398         return res.green;
2399     case GL_BLUE_BITS:
2400         return res.blue;
2401     case GL_ALPHA_BITS:
2402         return res.alpha;
2403     case GL_DEPTH_BITS:
2404         return res.depth;
2405     case GL_STENCIL_BITS:
2406         return res.stencil;
2407     }
2408 
2409     return 0;
2410 }
2411 
2412 static const char kTexImageEmulationVShaderSrc[] = R"(
2413 precision highp float;
2414 out vec2 v_texcoord;
2415 void main() {
2416     const vec2 quad_pos[6] = vec2[6](
2417         vec2(0.0, 0.0),
2418         vec2(0.0, 1.0),
2419         vec2(1.0, 0.0),
2420         vec2(0.0, 1.0),
2421         vec2(1.0, 0.0),
2422         vec2(1.0, 1.0));
2423 
2424     gl_Position = vec4((quad_pos[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);
2425     v_texcoord = quad_pos[gl_VertexID];
2426 })";
2427 
2428 static const char kTexImageEmulationVShaderSrcFlipped[] = R"(
2429 precision highp float;
2430 layout (location = 0) in vec2 a_pos;
2431 out vec2 v_texcoord;
2432 void main() {
2433     gl_Position = vec4((a_pos.xy) * 2.0 - 1.0, 0.0, 1.0);
2434     v_texcoord = a_pos;
2435     v_texcoord.y = 1.0 - v_texcoord.y;
2436 })";
2437 
2438 static const char kTexImageEmulationFShaderSrc[] = R"(
2439 precision highp float;
2440 uniform sampler2D source_tex;
2441 in vec2 v_texcoord;
2442 out vec4 color;
2443 void main() {
2444    color = texture(source_tex, v_texcoord);
2445 })";
2446 
initTexImageEmulation()2447 void GLEScontext::initTexImageEmulation() {
2448     if (m_textureEmulationProg) return;
2449 
2450     auto& gl = dispatcher();
2451 
2452     std::string vshaderSrc = isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2453     vshaderSrc += kTexImageEmulationVShaderSrc;
2454     std::string fshaderSrc = isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2455     fshaderSrc += kTexImageEmulationFShaderSrc;
2456 
2457     GLuint vshader =
2458         compileAndValidateCoreShader(GL_VERTEX_SHADER,
2459                                      vshaderSrc.c_str());
2460     GLuint fshader =
2461         compileAndValidateCoreShader(GL_FRAGMENT_SHADER,
2462                                      fshaderSrc.c_str());
2463     m_textureEmulationProg = linkAndValidateProgram(vshader, fshader);
2464     m_textureEmulationSamplerLoc =
2465         gl.glGetUniformLocation(m_textureEmulationProg, "source_tex");
2466 
2467     gl.glGenFramebuffers(1, &m_textureEmulationFBO);
2468     gl.glGenTextures(2, m_textureEmulationTextures);
2469     gl.glGenVertexArrays(1, &m_textureEmulationVAO);
2470 }
2471 
copyTexImageWithEmulation(TextureData * texData,bool isSubImage,GLenum target,GLint level,GLenum internalformat,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)2472 void GLEScontext::copyTexImageWithEmulation(
2473         TextureData* texData,
2474         bool isSubImage,
2475         GLenum target,
2476         GLint level,
2477         GLenum internalformat,
2478         GLint xoffset, GLint yoffset,
2479         GLint x, GLint y,
2480         GLsizei width, GLsizei height,
2481         GLint border) {
2482 
2483     // Create objects used for emulation if they don't exist already.
2484     initTexImageEmulation();
2485     auto& gl = dispatcher();
2486 
2487     // Save all affected state.
2488     ScopedGLState state;
2489     state.pushForCoreProfileTextureEmulation();
2490 
2491     // render to an intermediate texture with the same format:
2492     // 1. Get the format
2493     FramebufferData* fbData =
2494         getFBOData(getFramebufferBinding(GL_READ_FRAMEBUFFER));
2495     GLint readFbInternalFormat =
2496         fbData ? fbData->getAttachmentInternalFormat(this, GL_COLOR_ATTACHMENT0) :
2497                  m_defaultFBOColorFormat;
2498 
2499     // 2. Create the texture for textures[0] with this format, and initialize
2500     // it to the current FBO read buffer.
2501     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[0]);
2502     gl.glCopyTexImage2D(GL_TEXTURE_2D, 0, readFbInternalFormat,
2503                         x, y, width, height, 0);
2504 
2505     // 3. Set swizzle of textures[0] so they are read in the right way
2506     // when drawing to textures[1].
2507     TextureSwizzle swz = getInverseSwizzleForEmulatedFormat(texData->format);
2508     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swz.toRed);
2509     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swz.toGreen);
2510     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swz.toBlue);
2511     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swz.toAlpha);
2512     // Also, nearest filtering
2513     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2514     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2515 
2516     // 4. Initialize textures[1] with same width/height, and use it to back
2517     // the FBO that holds the swizzled results.
2518     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[1]);
2519     gl.glTexImage2D(GL_TEXTURE_2D, 0, readFbInternalFormat, width, height, 0,
2520                     baseFormatOfInternalFormat(readFbInternalFormat),
2521                     accurateTypeOfInternalFormat(readFbInternalFormat),
2522                     nullptr);
2523     // Also, nearest filtering
2524     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2525     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2526 
2527     gl.glBindFramebuffer(GL_FRAMEBUFFER, m_textureEmulationFBO);
2528     gl.glFramebufferTexture2D(
2529         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
2530         m_textureEmulationTextures[1], 0);
2531 
2532     // 5. Draw textures[0] to our FBO, making sure all state is compatible.
2533     gl.glDisable(GL_BLEND);
2534     gl.glDisable(GL_SCISSOR_TEST);
2535     gl.glDisable(GL_DEPTH_TEST);
2536     gl.glDisable(GL_STENCIL_TEST);
2537     gl.glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2538     gl.glDisable(GL_SAMPLE_COVERAGE);
2539     gl.glDisable(GL_CULL_FACE);
2540     gl.glDisable(GL_POLYGON_OFFSET_FILL);
2541     gl.glDisable(GL_RASTERIZER_DISCARD);
2542 
2543     gl.glViewport(0, 0, width, height);
2544 
2545     if (isGles2Gles()) {
2546         gl.glDepthRangef(0.0f, 1.0f);
2547     } else {
2548         gl.glDepthRange(0.0f, 1.0f);
2549     }
2550 
2551     gl.glColorMask(1, 1, 1, 1);
2552 
2553     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[0]);
2554     GLint texUnit; gl.glGetIntegerv(GL_ACTIVE_TEXTURE, &texUnit);
2555 
2556     gl.glUseProgram(m_textureEmulationProg);
2557     gl.glUniform1i(m_textureEmulationSamplerLoc, texUnit - GL_TEXTURE0);
2558 
2559     gl.glBindVertexArray(m_textureEmulationVAO);
2560 
2561     gl.glDrawArrays(GL_TRIANGLES, 0, 6);
2562 
2563     // now the emulated version has been rendered and written to the read FBO
2564     // with the correct swizzle.
2565     if (isCubeMapFaceTarget(target)) {
2566         gl.glBindTexture(GL_TEXTURE_CUBE_MAP, texData->getGlobalName());
2567     } else {
2568         gl.glBindTexture(target, texData->getGlobalName());
2569     }
2570 
2571     if (isSubImage) {
2572         gl.glCopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0, width, height);
2573     } else {
2574         gl.glCopyTexImage2D(target, level, internalformat, 0, 0, width, height, border);
2575     }
2576 }
2577 
2578 // static
compileAndValidateCoreShader(GLenum shaderType,const char * src)2579 GLuint GLEScontext::compileAndValidateCoreShader(GLenum shaderType, const char* src) {
2580     GLDispatch& gl = dispatcher();
2581 
2582     GLuint shader = gl.glCreateShader(shaderType);
2583     gl.glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
2584     gl.glCompileShader(shader);
2585 
2586     GLint compileStatus;
2587     gl.glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
2588 
2589     if (compileStatus != GL_TRUE) {
2590         GLsizei infoLogLength = 0;
2591         gl.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
2592         std::vector<char> infoLog(infoLogLength + 1, 0);
2593         gl.glGetShaderInfoLog(shader, infoLogLength, nullptr, &infoLog[0]);
2594         ERR("fail to compile. infolog %s", &infoLog[0]);
2595     }
2596 
2597     return shader;
2598 }
2599 
2600 // static
linkAndValidateProgram(GLuint vshader,GLuint fshader)2601 GLuint GLEScontext::linkAndValidateProgram(GLuint vshader, GLuint fshader) {
2602     GLDispatch& gl = dispatcher();
2603 
2604     GLuint program = gl.glCreateProgram();
2605     gl.glAttachShader(program, vshader);
2606     gl.glAttachShader(program, fshader);
2607     gl.glLinkProgram(program);
2608 
2609     GLint linkStatus;
2610     gl.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
2611 
2612     if (linkStatus != GL_TRUE) {
2613         GLsizei infoLogLength = 0;
2614         gl.glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
2615         std::vector<char> infoLog(infoLogLength + 1, 0);
2616         gl.glGetProgramInfoLog(program, infoLogLength, nullptr, &infoLog[0]);
2617         ERR("fail to link program. infolog: %s", &infoLog[0]);
2618     }
2619 
2620     gl.glDeleteShader(vshader);
2621     gl.glDeleteShader(fshader);
2622 
2623     return program;
2624 }
2625 
getReadBufferSamples()2626 int GLEScontext::getReadBufferSamples() {
2627     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2628     bool defaultFboReadBufferBound = readFboBinding == 0;
2629     if (defaultFboReadBufferBound) {
2630         return m_defaultFBOSamples;
2631     } else {
2632         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2633         return fbData ? fbData->getAttachmentSamples(this, fbData->getReadBuffer()) : 0;
2634     }
2635 }
2636 
getReadBufferInternalFormat()2637 int GLEScontext::getReadBufferInternalFormat() {
2638     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2639     bool defaultFboReadBufferBound = readFboBinding == 0;
2640     if (defaultFboReadBufferBound) {
2641         return m_defaultFBOColorFormat;
2642     } else {
2643         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2644         return fbData ? fbData->getAttachmentInternalFormat(this, fbData->getReadBuffer()) : 0;
2645     }
2646 }
2647 
getReadBufferDimensions(GLint * width,GLint * height)2648 void GLEScontext::getReadBufferDimensions(GLint* width, GLint* height) {
2649     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2650     bool defaultFboReadBufferBound = readFboBinding == 0;
2651     if (defaultFboReadBufferBound) {
2652         *width = m_defaultFBOWidth;
2653         *height = m_defaultFBOHeight;
2654     } else {
2655         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2656         if (fbData) {
2657             fbData->getAttachmentDimensions(
2658                 this, fbData->getReadBuffer(), width, height);
2659         }
2660     }
2661 }
2662 
setupImageBlitState()2663 void GLEScontext::setupImageBlitState() {
2664     auto& gl = dispatcher();
2665     m_blitState.prevSamples = m_blitState.samples;
2666     m_blitState.samples = getReadBufferSamples();
2667 
2668     if (m_blitState.program) return;
2669 
2670     std::string vshaderSrc =
2671         isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2672     vshaderSrc += kTexImageEmulationVShaderSrcFlipped;
2673 
2674     std::string fshaderSrc =
2675         isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2676     fshaderSrc += kTexImageEmulationFShaderSrc;
2677 
2678     GLuint vshader =
2679         compileAndValidateCoreShader(GL_VERTEX_SHADER, vshaderSrc.c_str());
2680     GLuint fshader =
2681         compileAndValidateCoreShader(GL_FRAGMENT_SHADER, fshaderSrc.c_str());
2682 
2683     m_blitState.program = linkAndValidateProgram(vshader, fshader);
2684     m_blitState.samplerLoc =
2685         gl.glGetUniformLocation(m_blitState.program, "source_tex");
2686 
2687     gl.glGenFramebuffers(1, &m_blitState.fbo);
2688     gl.glGenFramebuffers(1, &m_blitState.resolveFbo);
2689     gl.glGenTextures(1, &m_blitState.tex);
2690     gl.glGenVertexArrays(1, &m_blitState.vao);
2691 
2692     gl.glGenBuffers(1, &m_blitState.vbo);
2693     float blitVbo[] = {
2694         0.0f, 0.0f,
2695         1.0f, 0.0f,
2696         0.0f, 1.0f,
2697         1.0f, 0.0f,
2698         1.0f, 1.0f,
2699         0.0f, 1.0f,
2700     };
2701 
2702     GLint buf;
2703     gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buf);
2704 
2705     gl.glBindBuffer(GL_ARRAY_BUFFER, m_blitState.vbo);
2706     gl.glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), blitVbo, GL_STATIC_DRAW);
2707 
2708     gl.glBindVertexArray(m_blitState.vao);
2709     gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
2710     gl.glEnableVertexAttribArray(0);
2711 
2712     gl.glBindBuffer(GL_ARRAY_BUFFER, buf);
2713 }
2714 
setupImageBlitForTexture(uint32_t width,uint32_t height,GLint internalFormat)2715 bool GLEScontext::setupImageBlitForTexture(uint32_t width,
2716                                            uint32_t height,
2717                                            GLint internalFormat) {
2718     GLint sizedInternalFormat = GL_RGBA8;
2719     if (internalFormat != GL_RGBA8 &&
2720         internalFormat != GL_RGB8 &&
2721         internalFormat != GL_RGB565) {
2722         switch (internalFormat) {
2723         case GL_RGB:
2724             sizedInternalFormat = GL_RGB8;
2725             break;
2726         case GL_RGBA:
2727             sizedInternalFormat = GL_RGBA8;
2728             break;
2729         default:
2730             break;
2731         }
2732     }
2733 
2734     auto& gl = dispatcher();
2735     gl.glBindTexture(GL_TEXTURE_2D, m_blitState.tex);
2736 
2737     GLint read_iformat = getReadBufferInternalFormat();
2738     GLint read_format = baseFormatOfInternalFormat(read_iformat);
2739 
2740     if (isIntegerInternalFormat(read_iformat) ||
2741         read_iformat == GL_RGB10_A2) {
2742         // Is not a blittable format. Just create the texture for now to
2743         // make image blit state consistent.
2744         gl.glTexImage2D(GL_TEXTURE_2D, 0, sizedInternalFormat, width, height, 0,
2745                 baseFormatOfInternalFormat(internalFormat), GL_UNSIGNED_BYTE, 0);
2746         return false;
2747     }
2748 
2749     if (width != m_blitState.width || height != m_blitState.height ||
2750         internalFormat != m_blitState.internalFormat ||
2751         m_blitState.samples != m_blitState.prevSamples) {
2752 
2753         m_blitState.width = width;
2754         m_blitState.height = height;
2755         m_blitState.internalFormat = internalFormat;
2756 
2757         gl.glTexImage2D(GL_TEXTURE_2D, 0,
2758                         read_iformat, width, height, 0, read_format, GL_UNSIGNED_BYTE, 0);
2759         if (m_blitState.samples > 0) {
2760             gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.resolveFbo);
2761             gl.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2762                     GL_TEXTURE_2D, m_blitState.tex, 0);
2763         }
2764 
2765         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2766         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2767         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2768         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2769     }
2770 
2771     // In eglSwapBuffers, the surface must be bound as the draw surface of
2772     // the current context, which corresponds to m_defaultFBO here.
2773     //
2774     // EGL 1.4 spec:
2775     //
2776     // 3.9.3 Posting Semantics surface must be bound to the draw surface of the
2777     // calling thread’s current context, for the current rendering API. This
2778     // restriction may be lifted in future EGL revisions.
2779     //
2780     const GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2781     if (readFboBinding != 0) {
2782         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultFBO);
2783     }
2784 
2785     if (m_blitState.samples > 0) {
2786         GLint rWidth = width;
2787         GLint rHeight = height;
2788         getReadBufferDimensions(&rWidth, &rHeight);
2789         gl.glBindTexture(GL_TEXTURE_2D, 0);
2790         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.resolveFbo);
2791         gl.glBlitFramebuffer(0, 0, rWidth, rHeight, 0, 0, rWidth, rHeight,
2792                 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2793         gl.glBindTexture(GL_TEXTURE_2D, m_blitState.tex);
2794     } else {
2795         gl.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
2796     }
2797 
2798     return true;
2799 }
2800 
blitFromReadBufferToTextureFlipped(GLuint globalTexObj,GLuint width,GLuint height,GLint internalFormat,GLenum format,GLenum type)2801 void GLEScontext::blitFromReadBufferToTextureFlipped(GLuint globalTexObj,
2802                                                      GLuint width,
2803                                                      GLuint height,
2804                                                      GLint internalFormat,
2805                                                      GLenum format,
2806                                                      GLenum type) {
2807     // TODO: these might also matter
2808     (void)format;
2809     (void)type;
2810 
2811     auto& gl = dispatcher();
2812     GLint prevViewport[4];
2813     getViewport(prevViewport);
2814 
2815     setupImageBlitState();
2816     bool shouldBlit = setupImageBlitForTexture(width, height, internalFormat);
2817 
2818     if (!shouldBlit) return;
2819 
2820     // b/159670873: The texture to blit doesn't necessarily match the display
2821     // size. If it doesn't match, then we might not be using the right mipmap
2822     // level, which can result in a black screen. Set to always use level 0.
2823     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2824     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2825 
2826     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2827     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2828     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2829     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2830 
2831     gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.fbo);
2832     gl.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2833                               GL_TEXTURE_2D, globalTexObj, 0);
2834 
2835     gl.glDisable(GL_BLEND);
2836     gl.glDisable(GL_SCISSOR_TEST);
2837     gl.glDisable(GL_DEPTH_TEST);
2838     gl.glDisable(GL_STENCIL_TEST);
2839     gl.glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2840     gl.glDisable(GL_SAMPLE_COVERAGE);
2841     gl.glDisable(GL_CULL_FACE);
2842     gl.glDisable(GL_POLYGON_OFFSET_FILL);
2843     gl.glDisable(GL_RASTERIZER_DISCARD);
2844 
2845     gl.glViewport(0, 0, width, height);
2846     if (isGles2Gles()) {
2847         gl.glDepthRangef(0.0f, 1.0f);
2848     } else {
2849         gl.glDepthRange(0.0f, 1.0f);
2850     }
2851     gl.glColorMask(1, 1, 1, 1);
2852 
2853     gl.glUseProgram(m_blitState.program);
2854     gl.glUniform1i(m_blitState.samplerLoc, m_activeTexture);
2855 
2856     gl.glBindVertexArray(m_blitState.vao);
2857     gl.glDrawArrays(GL_TRIANGLES, 0, 6);
2858 
2859     // state restore
2860     const GLuint globalProgramName = shareGroup()->getGlobalName(
2861         NamedObjectType::SHADER_OR_PROGRAM, m_useProgram);
2862     gl.glUseProgram(globalProgramName);
2863 
2864     gl.glBindVertexArray(getVAOGlobalName(m_currVaoState.vaoId()));
2865 
2866     gl.glBindTexture(
2867         GL_TEXTURE_2D,
2868         shareGroup()->getGlobalName(
2869             NamedObjectType::TEXTURE,
2870             getTextureLocalName(GL_TEXTURE_2D,
2871                                 getBindedTexture(GL_TEXTURE_2D))));
2872 
2873     GLuint drawFboBinding = getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
2874     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2875 
2876     gl.glBindFramebuffer(
2877         GL_DRAW_FRAMEBUFFER,
2878         drawFboBinding ? getFBOGlobalName(drawFboBinding) : m_defaultFBO);
2879     gl.glBindFramebuffer(
2880         GL_READ_FRAMEBUFFER,
2881         readFboBinding ? getFBOGlobalName(readFboBinding) : m_defaultReadFBO);
2882 
2883     if (isEnabled(GL_BLEND)) gl.glEnable(GL_BLEND);
2884     if (isEnabled(GL_SCISSOR_TEST)) gl.glEnable(GL_SCISSOR_TEST);
2885     if (isEnabled(GL_DEPTH_TEST)) gl.glEnable(GL_DEPTH_TEST);
2886     if (isEnabled(GL_STENCIL_TEST)) gl.glEnable(GL_STENCIL_TEST);
2887     if (isEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)) gl.glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2888     if (isEnabled(GL_SAMPLE_COVERAGE)) gl.glEnable(GL_SAMPLE_COVERAGE);
2889     if (isEnabled(GL_CULL_FACE)) gl.glEnable(GL_CULL_FACE);
2890     if (isEnabled(GL_POLYGON_OFFSET_FILL)) gl.glEnable(GL_POLYGON_OFFSET_FILL);
2891     if (isEnabled(GL_RASTERIZER_DISCARD)) gl.glEnable(GL_RASTERIZER_DISCARD);
2892 
2893     gl.glViewport(prevViewport[0], prevViewport[1],
2894                   prevViewport[2], prevViewport[3]);
2895 
2896     if (isGles2Gles()) {
2897         gl.glDepthRangef(m_zNear, m_zFar);
2898     } else {
2899         gl.glDepthRange(m_zNear, m_zFar);
2900     }
2901 
2902     gl.glColorMask(m_colorMaskR, m_colorMaskG, m_colorMaskB, m_colorMaskA);
2903 
2904     gl.glFlush();
2905 }
2906 
blitFromReadBufferToEGLImage(EGLImage image,GLint internalFormat,int width,int height)2907 void GLEScontext::blitFromReadBufferToEGLImage(EGLImage image, GLint internalFormat, int width, int height) {
2908 
2909     auto& gl = dispatcher();
2910     GLint prevViewport[4];
2911     getViewport(prevViewport);
2912 
2913     setupImageBlitState();
2914     bool shouldBlit = setupImageBlitForTexture(width, height, internalFormat);
2915 
2916     if (!shouldBlit) return;
2917 
2918     // b/159670873: The texture to blit doesn't necessarily match the display
2919     // size. If it doesn't match, then we might not be using the right mipmap
2920     // level, which can result in a black screen. Set to always use level 0.
2921     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2922     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2923 
2924     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2925     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2926     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2927     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2928 
2929     if (!m_blitState.eglImageTex) {
2930         gl.glGenTextures(1, &m_blitState.eglImageTex);
2931     }
2932 
2933     gl.glBindTexture(GL_TEXTURE_2D, m_blitState.eglImageTex);
2934     gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
2935     gl.glBindTexture(GL_TEXTURE_2D, m_blitState.tex);
2936     gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.fbo);
2937     gl.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2938                               GL_TEXTURE_2D, m_blitState.eglImageTex, 0);
2939 
2940     gl.glDisable(GL_BLEND);
2941     gl.glDisable(GL_SCISSOR_TEST);
2942     gl.glDisable(GL_DEPTH_TEST);
2943     gl.glDisable(GL_STENCIL_TEST);
2944     gl.glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2945     gl.glDisable(GL_SAMPLE_COVERAGE);
2946     gl.glDisable(GL_CULL_FACE);
2947     gl.glDisable(GL_POLYGON_OFFSET_FILL);
2948     gl.glDisable(GL_RASTERIZER_DISCARD);
2949 
2950     gl.glViewport(0, 0, width, height);
2951     if (isGles2Gles()) {
2952         gl.glDepthRangef(0.0f, 1.0f);
2953     } else {
2954         gl.glDepthRange(0.0f, 1.0f);
2955     }
2956     gl.glColorMask(1, 1, 1, 1);
2957 
2958     gl.glUseProgram(m_blitState.program);
2959     gl.glUniform1i(m_blitState.samplerLoc, m_activeTexture);
2960 
2961     gl.glBindVertexArray(m_blitState.vao);
2962     gl.glDrawArrays(GL_TRIANGLES, 0, 6);
2963 
2964     // state restore
2965     const GLuint globalProgramName = shareGroup()->getGlobalName(
2966         NamedObjectType::SHADER_OR_PROGRAM, m_useProgram);
2967     gl.glUseProgram(globalProgramName);
2968 
2969     gl.glBindVertexArray(getVAOGlobalName(m_currVaoState.vaoId()));
2970 
2971     gl.glBindTexture(
2972         GL_TEXTURE_2D,
2973         shareGroup()->getGlobalName(
2974             NamedObjectType::TEXTURE,
2975             getTextureLocalName(GL_TEXTURE_2D,
2976                                 getBindedTexture(GL_TEXTURE_2D))));
2977 
2978     GLuint drawFboBinding = getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
2979     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2980 
2981     gl.glBindFramebuffer(
2982         GL_DRAW_FRAMEBUFFER,
2983         drawFboBinding ? getFBOGlobalName(drawFboBinding) : m_defaultFBO);
2984     gl.glBindFramebuffer(
2985         GL_READ_FRAMEBUFFER,
2986         readFboBinding ? getFBOGlobalName(readFboBinding) : m_defaultReadFBO);
2987 
2988     if (isEnabled(GL_BLEND)) gl.glEnable(GL_BLEND);
2989     if (isEnabled(GL_SCISSOR_TEST)) gl.glEnable(GL_SCISSOR_TEST);
2990     if (isEnabled(GL_DEPTH_TEST)) gl.glEnable(GL_DEPTH_TEST);
2991     if (isEnabled(GL_STENCIL_TEST)) gl.glEnable(GL_STENCIL_TEST);
2992     if (isEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)) gl.glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2993     if (isEnabled(GL_SAMPLE_COVERAGE)) gl.glEnable(GL_SAMPLE_COVERAGE);
2994     if (isEnabled(GL_CULL_FACE)) gl.glEnable(GL_CULL_FACE);
2995     if (isEnabled(GL_POLYGON_OFFSET_FILL)) gl.glEnable(GL_POLYGON_OFFSET_FILL);
2996     if (isEnabled(GL_RASTERIZER_DISCARD)) gl.glEnable(GL_RASTERIZER_DISCARD);
2997 
2998     gl.glViewport(prevViewport[0], prevViewport[1],
2999                   prevViewport[2], prevViewport[3]);
3000 
3001     if (isGles2Gles()) {
3002         gl.glDepthRangef(m_zNear, m_zFar);
3003     } else {
3004         gl.glDepthRange(m_zNear, m_zFar);
3005     }
3006 
3007     gl.glColorMask(m_colorMaskR, m_colorMaskG, m_colorMaskB, m_colorMaskA);
3008 
3009     gl.glFlush();
3010 }
3011 
3012 // Primitive restart emulation
3013 #define GL_PRIMITIVE_RESTART              0x8F9D
3014 #define GL_PRIMITIVE_RESTART_INDEX        0x8F9E
3015 
setPrimitiveRestartEnabled(bool enabled)3016 void GLEScontext::setPrimitiveRestartEnabled(bool enabled) {
3017     auto& gl = dispatcher();
3018 
3019     if (enabled) {
3020         gl.glEnable(GL_PRIMITIVE_RESTART);
3021     } else {
3022         gl.glDisable(GL_PRIMITIVE_RESTART);
3023     }
3024 
3025     m_primitiveRestartEnabled = enabled;
3026 }
3027 
updatePrimitiveRestartIndex(GLenum type)3028 void GLEScontext::updatePrimitiveRestartIndex(GLenum type) {
3029     auto& gl = dispatcher();
3030     switch (type) {
3031     case GL_UNSIGNED_BYTE:
3032         gl.glPrimitiveRestartIndex(0xff);
3033         break;
3034     case GL_UNSIGNED_SHORT:
3035         gl.glPrimitiveRestartIndex(0xffff);
3036         break;
3037     case GL_UNSIGNED_INT:
3038         gl.glPrimitiveRestartIndex(0xffffffff);
3039         break;
3040     }
3041 }
3042 
isVAO(ObjectLocalName p_localName)3043 bool GLEScontext::isVAO(ObjectLocalName p_localName) {
3044     VAOStateMap::iterator it = m_vaoStateMap.find(p_localName);
3045     if (it == m_vaoStateMap.end()) return false;
3046     VAOStateRef vao(it);
3047     return vao.isEverBound();
3048 }
3049 
genVAOName(ObjectLocalName p_localName,bool genLocal)3050 ObjectLocalName GLEScontext::genVAOName(ObjectLocalName p_localName,
3051         bool genLocal) {
3052     return m_vaoNameSpace->genName(GenNameInfo(NamedObjectType::VERTEX_ARRAY_OBJECT),
3053             p_localName, genLocal);
3054 }
3055 
deleteVAO(ObjectLocalName p_localName)3056 void GLEScontext::deleteVAO(ObjectLocalName p_localName) {
3057     m_vaoNameSpace->deleteName(p_localName);
3058 }
3059 
getVAOGlobalName(ObjectLocalName p_localName)3060 unsigned int GLEScontext::getVAOGlobalName(ObjectLocalName p_localName) {
3061     return m_vaoNameSpace->getGlobalName(p_localName);
3062 }
3063 
getVAOLocalName(unsigned int p_globalName)3064 ObjectLocalName GLEScontext::getVAOLocalName(unsigned int p_globalName) {
3065     return m_vaoNameSpace->getLocalName(p_globalName);
3066 }
3067 
setDefaultFBODrawBuffer(GLenum buffer)3068 void GLEScontext::setDefaultFBODrawBuffer(GLenum buffer) {
3069     m_defaultFBODrawBuffer = buffer;
3070 }
3071 
setDefaultFBOReadBuffer(GLenum buffer)3072 void GLEScontext::setDefaultFBOReadBuffer(GLenum buffer) {
3073     m_defaultFBOReadBuffer = buffer;
3074 }
3075