• 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 "ErrorLog.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 (%s,%d)\n", indices_type, __FUNCTION__,__LINE__);
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             fprintf(stderr,
917                     "warning: get GL error %d while restoring a snapshot\n",
918                     err);
919         }
920 #endif
921     } while (err != 0);
922 }
923 
loadObject(NamedObjectType type,ObjectLocalName localName,android::base::Stream * stream) const924 ObjectDataPtr GLEScontext::loadObject(NamedObjectType type,
925             ObjectLocalName localName, android::base::Stream* stream) const {
926     switch (type) {
927         case NamedObjectType::VERTEXBUFFER:
928             return ObjectDataPtr(new GLESbuffer(stream));
929         case NamedObjectType::TEXTURE:
930             return ObjectDataPtr(new TextureData(stream));
931         case NamedObjectType::FRAMEBUFFER:
932             return ObjectDataPtr(new FramebufferData(stream));
933         case NamedObjectType::RENDERBUFFER:
934             return ObjectDataPtr(new RenderbufferData(stream));
935         default:
936             return {};
937     }
938 }
939 
setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid * data,GLsizei dataSize,bool normalize,bool isInt)940 const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data, GLsizei dataSize, bool normalize, bool isInt) {
941     GLuint bufferName = m_arrayBuffer;
942     GLESpointer* glesPointer = nullptr;
943 
944     if (m_currVaoState.it->second.legacy) {
945         auto vertexAttrib = m_currVaoState.find(arrType);
946         if (vertexAttrib == m_currVaoState.end()) {
947             return nullptr;
948         }
949         glesPointer = m_currVaoState[arrType];
950     } else {
951         uint32_t attribIndex = (uint32_t)arrType;
952         if (attribIndex > kMaxVertexAttributes) return nullptr;
953         glesPointer = m_currVaoState.attribInfo().data() + (uint32_t)arrType;
954     }
955 
956     if(bufferName) {
957         unsigned int offset = SafeUIntFromPointer(data);
958         GLESbuffer* vbo = static_cast<GLESbuffer*>(
959                 m_shareGroup
960                         ->getObjectData(NamedObjectType::VERTEXBUFFER,
961                                         bufferName));
962         if(offset >= vbo->getSize() || vbo->getSize() - offset < size) {
963 #ifdef _DEBUG
964             fprintf(stderr, "Warning: Invalid pointer offset %u, arrType %d, type %d\n", offset, arrType, type);
965 #endif
966             return nullptr;
967         }
968 
969         glesPointer->setBuffer(size,type,stride,vbo,bufferName,offset,normalize, isInt);
970 
971         return  static_cast<const unsigned char*>(vbo->getData()) +  offset;
972     }
973     glesPointer->setArray(size,type,stride,data,dataSize,normalize,isInt);
974     return data;
975 }
976 
getUnpackAlignment()977 GLint GLEScontext::getUnpackAlignment() {
978     return android::base::findOrDefault(m_glPixelStoreiList,
979             GL_UNPACK_ALIGNMENT, 4);
980 }
981 
enableArr(GLenum arr,bool enable)982 void GLEScontext::enableArr(GLenum arr,bool enable) {
983     auto vertexAttrib = m_currVaoState.find(arr);
984     if (vertexAttrib != m_currVaoState.end()) {
985         vertexAttrib->second->enable(enable);
986     }
987 }
988 
isArrEnabled(GLenum arr)989 bool GLEScontext::isArrEnabled(GLenum arr) {
990     if (m_currVaoState.it->second.legacy) {
991         return m_currVaoState[arr]->isEnable();
992     } else {
993         if ((uint32_t)arr > kMaxVertexAttributes) return false;
994         return m_currVaoState.attribInfo()[(uint32_t)arr].isEnable();
995     }
996 }
997 
getPointer(GLenum arrType)998 const GLESpointer* GLEScontext::getPointer(GLenum arrType) {
999     const auto it = m_currVaoState.find(arrType);
1000     return it != m_currVaoState.end() ? it->second : nullptr;
1001 }
1002 
convertFixedDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)1003 static void convertFixedDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
1004 
1005     for(unsigned int i = 0; i < nBytes;i+=strideOut) {
1006         const GLfixed* fixed_data = (const GLfixed *)dataIn;
1007         //filling attrib
1008         for(int j=0;j<attribSize;j++) {
1009             reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(dataOut)[i])[j] = X2F(fixed_data[j]);
1010         }
1011         dataIn += strideIn;
1012     }
1013 }
1014 
convertFixedIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)1015 static void convertFixedIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
1016     for(int i = 0 ;i < count ;i++) {
1017         GLuint index = getIndex(indices_type, indices, i);
1018 
1019         const GLfixed* fixed_data = (GLfixed *)(dataIn  + index*strideIn);
1020         GLfloat* float_data = reinterpret_cast<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
1021 
1022         for(int j=0;j<attribSize;j++) {
1023             float_data[j] = X2F(fixed_data[j]);
1024          }
1025     }
1026 }
1027 
convertByteDirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize)1028 static void convertByteDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) {
1029 
1030     for(unsigned int i = 0; i < nBytes;i+=strideOut) {
1031         const GLbyte* byte_data = (const GLbyte *)dataIn;
1032         //filling attrib
1033         for(int j=0;j<attribSize;j++) {
1034             reinterpret_cast<GLshort*>(&static_cast<unsigned char*>(dataOut)[i])[j] = B2S(byte_data[j]);
1035         }
1036         dataIn += strideIn;
1037     }
1038 }
1039 
convertByteIndirectLoop(const char * dataIn,unsigned int strideIn,void * dataOut,GLsizei count,GLenum indices_type,const GLvoid * indices,unsigned int strideOut,int attribSize)1040 static void convertByteIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) {
1041     for(int i = 0 ;i < count ;i++) {
1042         GLuint index = getIndex(indices_type, indices, i);
1043         const GLbyte* bytes_data = (GLbyte *)(dataIn  + index*strideIn);
1044         GLshort* short_data = reinterpret_cast<GLshort*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
1045 
1046         for(int j=0;j<attribSize;j++) {
1047             short_data[j] = B2S(bytes_data[j]);
1048          }
1049     }
1050 }
directToBytesRanges(GLint first,GLsizei count,GLESpointer * p,RangeList & list)1051 static void directToBytesRanges(GLint first,GLsizei count,GLESpointer* p,RangeList& list) {
1052 
1053     int attribSize = p->getSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes
1054     int stride = p->getStride()?p->getStride():attribSize;
1055     int start  = p->getBufferOffset()+first*stride;
1056     if(!p->getStride()) {
1057         list.addRange(Range(start,count*attribSize));
1058     } else {
1059         for(int i = 0 ;i < count; i++,start+=stride) {
1060             list.addRange(Range(start,attribSize));
1061         }
1062     }
1063 }
1064 
indirectToBytesRanges(const GLvoid * indices,GLenum indices_type,GLsizei count,GLESpointer * p,RangeList & list)1065 static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) {
1066 
1067     int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
1068     int stride = p->getStride()?p->getStride():attribSize;
1069     int start  = p->getBufferOffset();
1070     for(int i=0 ; i < count; i++) {
1071         GLuint index = getIndex(indices_type, indices, i);
1072         list.addRange(Range(start+index*stride,attribSize));
1073 
1074     }
1075 }
1076 
bytesRangesToIndices(RangeList & ranges,GLESpointer * p,GLuint * indices)1077 int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLuint* indices) {
1078 
1079     int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes
1080     int stride = p->getStride()?p->getStride():attribSize;
1081     int offset = p->getBufferOffset();
1082 
1083     int n = 0;
1084     for(int i=0;i<ranges.size();i++) {
1085         int startIndex = (ranges[i].getStart() - offset) / stride;
1086         int nElements = ranges[i].getSize()/attribSize;
1087         for(int j=0;j<nElements;j++) {
1088             indices[n++] = startIndex+j;
1089         }
1090     }
1091     return n;
1092 }
1093 
convertDirect(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)1094 void GLEScontext::convertDirect(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
1095 
1096     GLenum type    = p->getType();
1097     int attribSize = p->getSize();
1098     unsigned int size = attribSize*count + first;
1099     unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
1100     cArrs.allocArr(size,type);
1101     int stride = p->getStride()?p->getStride():bytes*attribSize;
1102     const char* data = (const char*)p->getArrayData() + (first*stride);
1103 
1104     if(type == GL_FIXED) {
1105         convertFixedDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize);
1106     } else if(type == GL_BYTE) {
1107         convertByteDirectLoop(data,stride,cArrs.getCurrentData(),size*sizeof(GLshort),attribSize*sizeof(GLshort),attribSize);
1108     }
1109 }
1110 
convertDirectVBO(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer * p)1111 void GLEScontext::convertDirectVBO(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p) {
1112 
1113     RangeList ranges;
1114     RangeList conversions;
1115     GLuint* indices = NULL;
1116     int attribSize = p->getSize();
1117     int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
1118     char* data = (char*)p->getBufferData();
1119 
1120     if(p->bufferNeedConversion()) {
1121         directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset
1122         p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
1123 
1124         if(conversions.size()) { // there are some elements to convert
1125            indices = new GLuint[count];
1126            int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array
1127            convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_INT,indices,stride,attribSize);
1128         }
1129     }
1130     if(indices) delete[] indices;
1131     cArrs.setArr(data,p->getStride(),GL_FLOAT);
1132 }
1133 
findMaxIndex(GLsizei count,GLenum type,const GLvoid * indices)1134 unsigned int GLEScontext::findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) {
1135     //finding max index
1136     unsigned int max = 0;
1137     if(type == GL_UNSIGNED_BYTE) {
1138         GLubyte*  b_indices  =(GLubyte *)indices;
1139         for(int i=0;i<count;i++) {
1140             if(b_indices[i] > max) max = b_indices[i];
1141         }
1142     } else if (type == GL_UNSIGNED_SHORT) {
1143         GLushort* us_indices =(GLushort *)indices;
1144         for(int i=0;i<count;i++) {
1145             if(us_indices[i] > max) max = us_indices[i];
1146         }
1147     } else { // type == GL_UNSIGNED_INT
1148         GLuint* ui_indices =(GLuint *)indices;
1149         for(int i=0;i<count;i++) {
1150             if(ui_indices[i] > max) max = ui_indices[i];
1151         }
1152     }
1153     return max;
1154 }
1155 
convertIndirect(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)1156 void GLEScontext::convertIndirect(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
1157     GLenum type    = p->getType();
1158     int maxElements = findMaxIndex(count,indices_type,indices) + 1;
1159 
1160     int attribSize = p->getSize();
1161     int size = attribSize * maxElements;
1162     unsigned int bytes = type == GL_FIXED ? sizeof(GLfixed):sizeof(GLbyte);
1163     cArrs.allocArr(size,type);
1164     int stride = p->getStride()?p->getStride():bytes*attribSize;
1165 
1166     const char* data = (const char*)p->getArrayData();
1167     if(type == GL_FIXED) {
1168         convertFixedIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize);
1169     } else if(type == GL_BYTE){
1170         convertByteIndirectLoop(data,stride,cArrs.getCurrentData(),count,indices_type,indices,attribSize*sizeof(GLshort),attribSize);
1171     }
1172 }
1173 
convertIndirectVBO(GLESConversionArrays & cArrs,GLsizei count,GLenum indices_type,const GLvoid * indices,GLenum array_id,GLESpointer * p)1174 void GLEScontext::convertIndirectVBO(GLESConversionArrays& cArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) {
1175     RangeList ranges;
1176     RangeList conversions;
1177     GLuint* conversionIndices = NULL;
1178     int attribSize = p->getSize();
1179     int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize;
1180     char* data = static_cast<char*>(p->getBufferData());
1181     if(p->bufferNeedConversion()) {
1182         indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset
1183         p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted
1184         if(conversions.size()) { // there are some elements to convert
1185             conversionIndices = new GLuint[count];
1186             int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array
1187             convertFixedIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_INT,conversionIndices,stride,attribSize);
1188         }
1189     }
1190     if(conversionIndices) delete[] conversionIndices;
1191     cArrs.setArr(data,p->getStride(),GL_FLOAT);
1192 }
1193 
bindBuffer(GLenum target,GLuint buffer)1194 GLuint GLEScontext::bindBuffer(GLenum target,GLuint buffer) {
1195     switch(target) {
1196     case GL_ARRAY_BUFFER:
1197         m_arrayBuffer = buffer;
1198         break;
1199     case GL_ELEMENT_ARRAY_BUFFER:
1200         m_currVaoState.iboId() = buffer;
1201         break;
1202     case GL_COPY_READ_BUFFER:
1203         m_copyReadBuffer = buffer;
1204         break;
1205     case GL_COPY_WRITE_BUFFER:
1206         m_copyWriteBuffer = buffer;
1207         break;
1208     case GL_PIXEL_PACK_BUFFER:
1209         m_pixelPackBuffer = buffer;
1210         break;
1211     case GL_PIXEL_UNPACK_BUFFER:
1212         m_pixelUnpackBuffer = buffer;
1213         break;
1214     case GL_TRANSFORM_FEEDBACK_BUFFER:
1215         m_transformFeedbackBuffer = buffer;
1216         break;
1217     case GL_UNIFORM_BUFFER:
1218         m_uniformBuffer = buffer;
1219         break;
1220     case GL_ATOMIC_COUNTER_BUFFER:
1221         m_atomicCounterBuffer = buffer;
1222         break;
1223     case GL_DISPATCH_INDIRECT_BUFFER:
1224         m_dispatchIndirectBuffer = buffer;
1225         break;
1226     case GL_DRAW_INDIRECT_BUFFER:
1227         m_drawIndirectBuffer = buffer;
1228         break;
1229     case GL_SHADER_STORAGE_BUFFER:
1230         m_shaderStorageBuffer = buffer;
1231         break;
1232     default:
1233         m_arrayBuffer = buffer;
1234         break;
1235     }
1236 
1237     if (!buffer) return 0;
1238 
1239     auto sg = m_shareGroup.get();
1240 
1241     if (!sg) return 0;
1242 
1243     return sg->ensureObjectOnBind(NamedObjectType::VERTEXBUFFER, buffer);
1244 }
1245 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,bool isBindBase)1246 void GLEScontext::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer,
1247         GLintptr offset, GLsizeiptr size, GLintptr stride, bool isBindBase) {
1248     VertexAttribBindingVector* bindings = nullptr;
1249     switch (target) {
1250     case GL_UNIFORM_BUFFER:
1251         bindings = &m_indexedUniformBuffers;
1252         break;
1253     case GL_ATOMIC_COUNTER_BUFFER:
1254         bindings = &m_indexedAtomicCounterBuffers;
1255         break;
1256     case GL_SHADER_STORAGE_BUFFER:
1257         bindings = &m_indexedShaderStorageBuffers;
1258         break;
1259     default:
1260         bindings = &m_currVaoState.bufferBindings();
1261         break;
1262     }
1263     if (index >= bindings->size()) {
1264             return;
1265     }
1266     auto& bufferBinding = (*bindings)[index];
1267     bufferBinding.buffer = buffer;
1268     bufferBinding.offset = offset;
1269     bufferBinding.size = size;
1270     bufferBinding.stride = stride;
1271     bufferBinding.isBindBase = isBindBase;
1272 }
1273 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer)1274 void GLEScontext::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer) {
1275     GLint sz;
1276     getBufferSizeById(buffer, &sz);
1277     bindIndexedBuffer(target, index, buffer, 0, sz, 0, true);
1278 }
1279 
sClearIndexedBufferBinding(GLuint id,std::vector<BufferBinding> & bindings)1280 static void sClearIndexedBufferBinding(GLuint id, std::vector<BufferBinding>& bindings) {
1281     for (size_t i = 0; i < bindings.size(); i++) {
1282         if (bindings[i].buffer == id) {
1283             bindings[i].offset = 0;
1284             bindings[i].size = 0;
1285             bindings[i].stride = 0;
1286             bindings[i].buffer = 0;
1287             bindings[i].isBindBase = false;
1288         }
1289     }
1290 }
1291 
unbindBuffer(GLuint buffer)1292 void GLEScontext::unbindBuffer(GLuint buffer) {
1293     if (m_arrayBuffer == buffer)
1294         m_arrayBuffer = 0;
1295     if (m_currVaoState.iboId() == buffer)
1296         m_currVaoState.iboId() = 0;
1297     if (m_copyReadBuffer == buffer)
1298         m_copyReadBuffer = 0;
1299     if (m_copyWriteBuffer == buffer)
1300         m_copyWriteBuffer = 0;
1301     if (m_pixelPackBuffer == buffer)
1302         m_pixelPackBuffer = 0;
1303     if (m_pixelUnpackBuffer == buffer)
1304         m_pixelUnpackBuffer = 0;
1305     if (m_transformFeedbackBuffer == buffer)
1306         m_transformFeedbackBuffer = 0;
1307     if (m_uniformBuffer == buffer)
1308         m_uniformBuffer = 0;
1309     if (m_atomicCounterBuffer == buffer)
1310         m_atomicCounterBuffer = 0;
1311     if (m_dispatchIndirectBuffer == buffer)
1312         m_dispatchIndirectBuffer = 0;
1313     if (m_drawIndirectBuffer == buffer)
1314         m_drawIndirectBuffer = 0;
1315     if (m_shaderStorageBuffer == buffer)
1316         m_shaderStorageBuffer = 0;
1317 
1318     // One might think that indexed buffer bindings for transform feedbacks
1319     // must be cleared as well, but transform feedbacks are
1320     // considered GL objects with attachments, so even if the buffer is
1321     // deleted (unbindBuffer is called), the state query with
1322     // glGetIntegeri_v must still return the deleted name [1].
1323     // sClearIndexedBufferBinding(buffer, m_indexedTransformFeedbackBuffers);
1324     // [1] OpenGL ES 3.0.5 spec Appendix D.1.3
1325     sClearIndexedBufferBinding(buffer, m_indexedUniformBuffers);
1326     sClearIndexedBufferBinding(buffer, m_indexedAtomicCounterBuffers);
1327     sClearIndexedBufferBinding(buffer, m_indexedShaderStorageBuffers);
1328     sClearIndexedBufferBinding(buffer, m_currVaoState.bufferBindings());
1329 }
1330 
1331 //checks if any buffer is binded to target
isBindedBuffer(GLenum target)1332 bool GLEScontext::isBindedBuffer(GLenum target) {
1333     switch(target) {
1334     case GL_ARRAY_BUFFER:
1335         return m_arrayBuffer != 0;
1336     case GL_ELEMENT_ARRAY_BUFFER:
1337         return m_currVaoState.iboId() != 0;
1338     case GL_COPY_READ_BUFFER:
1339         return m_copyReadBuffer != 0;
1340     case GL_COPY_WRITE_BUFFER:
1341         return m_copyWriteBuffer != 0;
1342     case GL_PIXEL_PACK_BUFFER:
1343         return m_pixelPackBuffer != 0;
1344     case GL_PIXEL_UNPACK_BUFFER:
1345         return m_pixelUnpackBuffer != 0;
1346     case GL_TRANSFORM_FEEDBACK_BUFFER:
1347         return m_transformFeedbackBuffer != 0;
1348     case GL_UNIFORM_BUFFER:
1349         return m_uniformBuffer != 0;
1350     case GL_ATOMIC_COUNTER_BUFFER:
1351         return m_atomicCounterBuffer != 0;
1352     case GL_DISPATCH_INDIRECT_BUFFER:
1353         return m_dispatchIndirectBuffer != 0;
1354     case GL_DRAW_INDIRECT_BUFFER:
1355         return m_drawIndirectBuffer != 0;
1356     case GL_SHADER_STORAGE_BUFFER:
1357         return m_shaderStorageBuffer != 0;
1358     default:
1359         return m_arrayBuffer != 0;
1360     }
1361 }
1362 
getBuffer(GLenum target)1363 GLuint GLEScontext::getBuffer(GLenum target) {
1364     switch(target) {
1365     case GL_ARRAY_BUFFER:
1366         return m_arrayBuffer;
1367     case GL_ELEMENT_ARRAY_BUFFER:
1368         return m_currVaoState.iboId();
1369     case GL_COPY_READ_BUFFER:
1370         return m_copyReadBuffer;
1371     case GL_COPY_WRITE_BUFFER:
1372         return m_copyWriteBuffer;
1373     case GL_PIXEL_PACK_BUFFER:
1374         return m_pixelPackBuffer;
1375     case GL_PIXEL_UNPACK_BUFFER:
1376         return m_pixelUnpackBuffer;
1377     case GL_TRANSFORM_FEEDBACK_BUFFER:
1378         return m_transformFeedbackBuffer;
1379     case GL_UNIFORM_BUFFER:
1380         return m_uniformBuffer;
1381     case GL_ATOMIC_COUNTER_BUFFER:
1382         return m_atomicCounterBuffer;
1383     case GL_DISPATCH_INDIRECT_BUFFER:
1384         return m_dispatchIndirectBuffer;
1385     case GL_DRAW_INDIRECT_BUFFER:
1386         return m_drawIndirectBuffer;
1387     case GL_SHADER_STORAGE_BUFFER:
1388         return m_shaderStorageBuffer;
1389     default:
1390         return m_arrayBuffer;
1391     }
1392 }
1393 
getIndexedBuffer(GLenum target,GLuint index)1394 GLuint GLEScontext::getIndexedBuffer(GLenum target, GLuint index) {
1395     switch (target) {
1396     case GL_UNIFORM_BUFFER:
1397         return m_indexedUniformBuffers[index].buffer;
1398     case GL_ATOMIC_COUNTER_BUFFER:
1399         return m_indexedAtomicCounterBuffers[index].buffer;
1400     case GL_SHADER_STORAGE_BUFFER:
1401         return m_indexedShaderStorageBuffers[index].buffer;
1402     default:
1403         return m_currVaoState.bufferBindings()[index].buffer;
1404     }
1405 }
1406 
1407 
getBindedBuffer(GLenum target)1408 GLvoid* GLEScontext::getBindedBuffer(GLenum target) {
1409     GLuint bufferName = getBuffer(target);
1410     if(!bufferName) return NULL;
1411 
1412     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1413             m_shareGroup
1414                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1415     return vbo->getData();
1416 }
1417 
getBufferSize(GLenum target,GLint * param)1418 void GLEScontext::getBufferSize(GLenum target,GLint* param) {
1419     GLuint bufferName = getBuffer(target);
1420     getBufferSizeById(bufferName, param);
1421 }
1422 
getBufferSizeById(GLuint bufferName,GLint * param)1423 void GLEScontext::getBufferSizeById(GLuint bufferName, GLint* param) {
1424     if (!bufferName) { *param = 0; return; }
1425     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1426             m_shareGroup
1427                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1428     *param = vbo->getSize();
1429 }
1430 
getBufferUsage(GLenum target,GLint * param)1431 void GLEScontext::getBufferUsage(GLenum target,GLint* param) {
1432     GLuint bufferName = getBuffer(target);
1433     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1434             m_shareGroup
1435                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1436     *param = vbo->getUsage();
1437 }
1438 
setBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)1439 bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) {
1440     GLuint bufferName = getBuffer(target);
1441     if(!bufferName) return false;
1442     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1443             m_shareGroup
1444                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1445     return vbo->setBuffer(size,usage,data);
1446 }
1447 
setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)1448 bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) {
1449 
1450     GLuint bufferName = getBuffer(target);
1451     if(!bufferName) return false;
1452     GLESbuffer* vbo = static_cast<GLESbuffer*>(
1453             m_shareGroup
1454                     ->getObjectData(NamedObjectType::VERTEXBUFFER, bufferName));
1455     return vbo->setSubBuffer(offset,size,data);
1456 }
1457 
setViewport(GLint x,GLint y,GLsizei width,GLsizei height)1458 void GLEScontext::setViewport(GLint x, GLint y, GLsizei width, GLsizei height) {
1459     m_isViewport = true;
1460     m_viewportX = x;
1461     m_viewportY = y;
1462     m_viewportWidth = width;
1463     m_viewportHeight = height;
1464 }
1465 
getViewport(GLint * params)1466 void GLEScontext::getViewport(GLint* params) {
1467     if (!m_isViewport) {
1468         dispatcher().glGetIntegerv(GL_VIEWPORT, params);
1469     } else {
1470         params[0] = m_viewportX;
1471         params[1] = m_viewportY;
1472         params[2] = m_viewportWidth;
1473         params[3] = m_viewportHeight;
1474     }
1475 }
1476 
setScissor(GLint x,GLint y,GLsizei width,GLsizei height)1477 void GLEScontext::setScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
1478     m_isScissor = true;
1479     m_scissorX = x;
1480     m_scissorY = y;
1481     m_scissorWidth = width;
1482     m_scissorHeight = height;
1483 }
1484 
setPolygonOffset(GLfloat factor,GLfloat units)1485 void GLEScontext::setPolygonOffset(GLfloat factor, GLfloat units) {
1486     m_polygonOffsetFactor = factor;
1487     m_polygonOffsetUnits = units;
1488 }
1489 
setEnable(GLenum item,bool isEnable)1490 void GLEScontext::setEnable(GLenum item, bool isEnable) {
1491     switch (item) {
1492         case GL_TEXTURE_2D:
1493         case GL_TEXTURE_CUBE_MAP_OES:
1494         case GL_TEXTURE_3D:
1495         case GL_TEXTURE_2D_ARRAY:
1496         case GL_TEXTURE_2D_MULTISAMPLE:
1497             setTextureEnabled(item,true);
1498             break;
1499         default:
1500             m_glEnableList[item] = isEnable;
1501             break;
1502     }
1503 }
1504 
isEnabled(GLenum item) const1505 bool GLEScontext::isEnabled(GLenum item) const {
1506     switch (item) {
1507         case GL_TEXTURE_2D:
1508         case GL_TEXTURE_CUBE_MAP_OES:
1509         case GL_TEXTURE_3D:
1510         case GL_TEXTURE_2D_ARRAY:
1511         case GL_TEXTURE_2D_MULTISAMPLE:
1512             return m_texState[m_activeTexture][GLTextureTargetToLocal(item)].enabled;
1513         default:
1514             return android::base::findOrDefault(m_glEnableList, item, false);
1515     }
1516 }
1517 
setBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)1518 void GLEScontext::setBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
1519     m_blendEquationRgb = modeRGB;
1520     m_blendEquationAlpha = modeAlpha;
1521 }
1522 
setBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)1523 void GLEScontext::setBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB,
1524             GLenum srcAlpha, GLenum dstAlpha) {
1525     m_blendSrcRgb = srcRGB;
1526     m_blendDstRgb = dstRGB;
1527     m_blendSrcAlpha = srcAlpha;
1528     m_blendDstAlpha = dstAlpha;
1529 }
1530 
setPixelStorei(GLenum pname,GLint param)1531 void GLEScontext::setPixelStorei(GLenum pname, GLint param) {
1532     m_glPixelStoreiList[pname] = param;
1533 }
1534 
setCullFace(GLenum mode)1535 void GLEScontext::setCullFace(GLenum mode) {
1536     m_cullFace = mode;
1537 }
1538 
setFrontFace(GLenum mode)1539 void GLEScontext::setFrontFace(GLenum mode) {
1540     m_frontFace = mode;
1541 }
1542 
setDepthFunc(GLenum func)1543 void GLEScontext::setDepthFunc(GLenum func) {
1544     m_depthFunc = func;
1545 }
1546 
setDepthMask(GLboolean flag)1547 void GLEScontext::setDepthMask(GLboolean flag) {
1548     m_depthMask = flag;
1549 }
1550 
setDepthRangef(GLclampf zNear,GLclampf zFar)1551 void GLEScontext::setDepthRangef(GLclampf zNear, GLclampf zFar) {
1552     m_zNear = zNear;
1553     m_zFar = zFar;
1554 }
1555 
setLineWidth(GLfloat lineWidth)1556 void GLEScontext::setLineWidth(GLfloat lineWidth) {
1557     m_lineWidth = lineWidth;
1558 }
1559 
setSampleCoverage(GLclampf value,GLboolean invert)1560 void GLEScontext::setSampleCoverage(GLclampf value, GLboolean invert) {
1561     m_sampleCoverageVal = value;
1562     m_sampleCoverageInvert = invert;
1563 }
setStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)1564 void GLEScontext::setStencilFuncSeparate(GLenum face, GLenum func, GLint ref,
1565         GLuint mask) {
1566     if (face == GL_FRONT_AND_BACK) {
1567         setStencilFuncSeparate(GL_FRONT, func, ref, mask);
1568         setStencilFuncSeparate(GL_BACK, func, ref, mask);
1569         return;
1570     }
1571     int idx = 0;
1572     switch (face) {
1573         case GL_FRONT:
1574             idx = StencilFront;
1575             break;
1576         case GL_BACK:
1577             idx = StencilBack;
1578             break;
1579         default:
1580             return;
1581     }
1582     m_stencilStates[idx].m_func = func;
1583     m_stencilStates[idx].m_ref = ref;
1584     m_stencilStates[idx].m_funcMask = mask;
1585 }
1586 
setStencilMaskSeparate(GLenum face,GLuint mask)1587 void GLEScontext::setStencilMaskSeparate(GLenum face, GLuint mask) {
1588     if (face == GL_FRONT_AND_BACK) {
1589         setStencilMaskSeparate(GL_FRONT, mask);
1590         setStencilMaskSeparate(GL_BACK, mask);
1591         return;
1592     }
1593     int idx = 0;
1594     switch (face) {
1595         case GL_FRONT:
1596             idx = StencilFront;
1597             break;
1598         case GL_BACK:
1599             idx = StencilBack;
1600             break;
1601         default:
1602             return;
1603     }
1604     m_stencilStates[idx].m_writeMask = mask;
1605 }
1606 
setStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)1607 void GLEScontext::setStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail,
1608         GLenum zpass) {
1609     if (face == GL_FRONT_AND_BACK) {
1610         setStencilOpSeparate(GL_FRONT, fail, zfail, zpass);
1611         setStencilOpSeparate(GL_BACK, fail, zfail, zpass);
1612         return;
1613     }
1614     int idx = 0;
1615     switch (face) {
1616         case GL_FRONT:
1617             idx = StencilFront;
1618             break;
1619         case GL_BACK:
1620             idx = StencilBack;
1621             break;
1622         default:
1623             return;
1624     }
1625     m_stencilStates[idx].m_sfail = fail;
1626     m_stencilStates[idx].m_dpfail = zfail;
1627     m_stencilStates[idx].m_dppass = zpass;
1628 }
1629 
setColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)1630 void GLEScontext::setColorMask(GLboolean red, GLboolean green, GLboolean blue,
1631         GLboolean alpha) {
1632     m_colorMaskR = red;
1633     m_colorMaskG = green;
1634     m_colorMaskB = blue;
1635     m_colorMaskA = alpha;
1636 }
1637 
setClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)1638 void GLEScontext::setClearColor(GLclampf red, GLclampf green, GLclampf blue,
1639         GLclampf alpha) {
1640     m_clearColorR = red;
1641     m_clearColorG = green;
1642     m_clearColorB = blue;
1643     m_clearColorA = alpha;
1644 }
1645 
setClearDepth(GLclampf depth)1646 void GLEScontext::setClearDepth(GLclampf depth) {
1647     m_clearDepth = depth;
1648 }
1649 
setClearStencil(GLint s)1650 void GLEScontext::setClearStencil(GLint s) {
1651     m_clearStencil = s;
1652 }
1653 
getExtensionString(bool isGles1)1654 const char * GLEScontext::getExtensionString(bool isGles1) {
1655     const char * ret;
1656     s_lock.lock();
1657     if (isGles1) {
1658         if (s_glExtensionsGles1)
1659             ret = s_glExtensionsGles1->c_str();
1660         else
1661             ret="";
1662     } else {
1663         if (s_glExtensions)
1664             ret = s_glExtensions->c_str();
1665         else
1666             ret="";
1667     }
1668     s_lock.unlock();
1669     return ret;
1670 }
1671 
getVendorString(bool isGles1) const1672 const char * GLEScontext::getVendorString(bool isGles1) const {
1673     return isGles1 ? s_glVendorGles1.c_str() : s_glVendor.c_str();
1674 }
1675 
getRendererString(bool isGles1) const1676 const char * GLEScontext::getRendererString(bool isGles1) const {
1677     return isGles1 ? s_glRendererGles1.c_str() : s_glRenderer.c_str();
1678 }
1679 
getVersionString(bool isGles1) const1680 const char * GLEScontext::getVersionString(bool isGles1) const {
1681     return isGles1 ? s_glVersionGles1.c_str() : s_glVersion.c_str();
1682 }
1683 
getGlobalLock()1684 void GLEScontext::getGlobalLock() {
1685     s_lock.lock();
1686 }
1687 
releaseGlobalLock()1688 void GLEScontext::releaseGlobalLock() {
1689     s_lock.unlock();
1690 }
1691 
initCapsLocked(const GLubyte * extensionString)1692 void GLEScontext::initCapsLocked(const GLubyte * extensionString)
1693 {
1694     const char* cstring = (const char*)extensionString;
1695 
1696     s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIBS,&s_glSupport.maxVertexAttribs);
1697 
1698     if (s_glSupport.maxVertexAttribs > kMaxVertexAttributes) {
1699         s_glSupport.maxVertexAttribs = kMaxVertexAttributes;
1700     }
1701 
1702     s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane);
1703     s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights);
1704     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
1705     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&s_glSupport.maxTexUnits);
1706     // Core profile lacks a fixed-function pipeline with texture units,
1707     // but we still want glDrawTexOES to work in core profile.
1708     // So, set it to 8.
1709     if ((::isCoreProfile() || isGles2Gles()) &&
1710         !s_glSupport.maxTexUnits) {
1711         s_glSupport.maxTexUnits = 8;
1712     }
1713     s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&s_glSupport.maxTexImageUnits);
1714     s_glDispatch.glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &s_glSupport.maxCombinedTexImageUnits);
1715 
1716     s_glDispatch.glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &s_glSupport.maxTransformFeedbackSeparateAttribs);
1717     s_glDispatch.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &s_glSupport.maxUniformBufferBindings);
1718     s_glDispatch.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &s_glSupport.maxAtomicCounterBufferBindings);
1719     s_glDispatch.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &s_glSupport.maxShaderStorageBufferBindings);
1720     s_glDispatch.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &s_glSupport.maxDrawBuffers);
1721     s_glDispatch.glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &s_glSupport.maxVertexAttribBindings);
1722 
1723     // Compressed texture format query
1724     if(feature_is_enabled(kFeature_NativeTextureDecompression)) {
1725         bool hasEtc2Support = false;
1726         bool hasAstcSupport = false;
1727         int numCompressedFormats = 0;
1728         s_glDispatch.glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numCompressedFormats);
1729         if (numCompressedFormats > 0) {
1730             int numEtc2Formats = 0;
1731             int numAstcFormats = 0;
1732             int numEtc2FormatsSupported = 0;
1733             int numAstcFormatsSupported = 0;
1734 
1735             std::map<GLint, bool> found;
1736             forEachEtc2Format([&numEtc2Formats, &found](GLint format) { ++numEtc2Formats; found[format] = false;});
1737             forEachAstcFormat([&numAstcFormats, &found](GLint format) { ++numAstcFormats; found[format] = false;});
1738 
1739             std::vector<GLint> formats(numCompressedFormats);
1740             s_glDispatch.glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats.data());
1741 
1742             for (int i = 0; i < numCompressedFormats; ++i) {
1743                 GLint format = formats[i];
1744                 if (isEtc2Format(format)) {
1745                     ++numEtc2FormatsSupported;
1746                     found[format] = true;
1747                 } else if (isAstcFormat(format)) {
1748                     ++numAstcFormatsSupported;
1749                     found[format] = true;
1750                 }
1751             }
1752 
1753             if (numEtc2Formats == numEtc2FormatsSupported) {
1754                 hasEtc2Support = true; // Supports ETC2 underneath
1755             } else {
1756                 // It is unusual to support only some. Record what happened.
1757                 fprintf(stderr, "%s: Not supporting etc2: %d vs %d\n", __func__,
1758                         numEtc2FormatsSupported, numEtc2Formats);
1759                 for (auto it : found) {
1760                     if (!it.second) {
1761                         fprintf(stderr, "%s: Not found: 0x%x\n", __func__, it.first);
1762                     }
1763                 }
1764             }
1765 
1766             if (numAstcFormats == numAstcFormatsSupported) {
1767                 hasAstcSupport = true; // Supports ASTC underneath
1768             } else {
1769                 // It is unusual to support only some. Record what happened.
1770                 fprintf(stderr, "%s: Not supporting astc: %d vs %d\n", __func__,
1771                         numAstcFormatsSupported, numAstcFormats);
1772                 for (auto it : found) {
1773                     if (!it.second) {
1774                         fprintf(stderr, "%s: Not found: 0x%x\n", __func__, it.first);
1775                     }
1776                 }
1777             }
1778         }
1779         s_glSupport.hasEtc2Support = hasEtc2Support;
1780         s_glSupport.hasAstcSupport = hasAstcSupport;
1781     }
1782 
1783     // Clear GL error in case these enums not supported.
1784     s_glDispatch.glGetError();
1785 
1786     const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION);
1787     s_glSupport.glslVersion = Version((const  char*)(glslVersion));
1788     const GLubyte* glVersion = s_glDispatch.glGetString(GL_VERSION);
1789 
1790     // fprintf(stderr, "%s: vendor renderer version [%s] [%s] [%s]\n", __func__,
1791     //         s_glDispatch.glGetString(GL_VENDOR),
1792     //         s_glDispatch.glGetString(GL_RENDERER),
1793     //         s_glDispatch.glGetString(GL_VERSION));
1794 
1795     if (strstr(cstring,"GL_EXT_bgra ")!=NULL ||
1796         (isGles2Gles() && strstr(cstring, "GL_EXT_texture_format_BGRA8888")) ||
1797         (!isGles2Gles() && !(Version((const char*)glVersion) < Version("1.2"))))
1798         s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;
1799 
1800     if (::isCoreProfile() ||
1801         strstr(cstring,"GL_EXT_framebuffer_object ")!=NULL)
1802         s_glSupport.GL_EXT_FRAMEBUFFER_OBJECT = true;
1803 
1804     if (strstr(cstring,"GL_ARB_vertex_blend ")!=NULL)
1805         s_glSupport.GL_ARB_VERTEX_BLEND = true;
1806 
1807     if (strstr(cstring,"GL_ARB_matrix_palette ")!=NULL)
1808         s_glSupport.GL_ARB_MATRIX_PALETTE = true;
1809 
1810     if (strstr(cstring,"GL_EXT_packed_depth_stencil ")!=NULL ||
1811         strstr(cstring,"GL_OES_packed_depth_stencil ")!=NULL)
1812         s_glSupport.GL_EXT_PACKED_DEPTH_STENCIL = true;
1813 
1814     if (strstr(cstring,"GL_OES_read_format ")!=NULL)
1815         s_glSupport.GL_OES_READ_FORMAT = true;
1816 
1817     if (strstr(cstring,"GL_ARB_half_float_pixel ")!=NULL ||
1818         strstr(cstring,"GL_OES_texture_half_float ")!=NULL)
1819         s_glSupport.GL_ARB_HALF_FLOAT_PIXEL = true;
1820 
1821     if (strstr(cstring,"GL_NV_half_float ")!=NULL)
1822         s_glSupport.GL_NV_HALF_FLOAT = true;
1823 
1824     if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL ||
1825         strstr(cstring,"GL_OES_vertex_half_float ")!=NULL)
1826         s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true;
1827 
1828     if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL)
1829         s_glSupport.GL_SGIS_GENERATE_MIPMAP = true;
1830 
1831     if (strstr(cstring,"GL_ARB_ES2_compatibility ")!=NULL
1832             || isGles2Gles())
1833         s_glSupport.GL_ARB_ES2_COMPATIBILITY = true;
1834 
1835     if (strstr(cstring,"GL_OES_standard_derivatives ")!=NULL)
1836         s_glSupport.GL_OES_STANDARD_DERIVATIVES = true;
1837 
1838     if (::isCoreProfile() ||
1839         strstr(cstring,"GL_ARB_texture_non_power_of_two")!=NULL ||
1840         strstr(cstring,"GL_OES_texture_npot")!=NULL)
1841         s_glSupport.GL_OES_TEXTURE_NPOT = true;
1842 
1843     if (::isCoreProfile() ||
1844         strstr(cstring,"GL_ARB_color_buffer_float")!=NULL ||
1845         strstr(cstring,"GL_EXT_color_buffer_float")!=NULL)
1846         s_glSupport.ext_GL_EXT_color_buffer_float = true;
1847 
1848     if (::isCoreProfile() ||
1849         strstr(cstring,"GL_EXT_color_buffer_half_float")!=NULL)
1850         s_glSupport.ext_GL_EXT_color_buffer_half_float = true;
1851 
1852     if (strstr(cstring,"GL_EXT_shader_framebuffer_fetch")!=NULL) {
1853         s_glSupport.ext_GL_EXT_shader_framebuffer_fetch = true;
1854     }
1855 
1856     if (!(Version((const char*)glVersion) < Version("3.0")) || strstr(cstring,"GL_OES_rgb8_rgba8")!=NULL)
1857         s_glSupport.GL_OES_RGB8_RGBA8 = true;
1858 
1859     if (strstr(cstring, "GL_EXT_memory_object") != NULL) {
1860         s_glSupport.ext_GL_EXT_memory_object = true;
1861     }
1862 
1863     if (strstr(cstring, "GL_EXT_semaphore") != NULL) {
1864         s_glSupport.ext_GL_EXT_semaphore = true;
1865     }
1866 
1867     // ASTC
1868     if (strstr(cstring, "GL_KHR_texture_compression_astc_ldr") != NULL) {
1869         s_glSupport.ext_GL_KHR_texture_compression_astc_ldr = true;
1870     }
1871 
1872     // BPTC extension detection
1873     if (feature_is_enabled(kFeature_BptcTextureSupport)) {
1874         if ((strstr(cstring, "GL_EXT_texture_compression_bptc") != NULL) ||
1875             (strstr(cstring, "GL_ARB_texture_compression_bptc") != NULL)) {
1876             s_glSupport.hasBptcSupport = true;
1877         }
1878     }
1879 
1880     if (feature_is_enabled(kFeature_S3tcTextureSupport)) {
1881         if (strstr(cstring, "GL_EXT_texture_compression_s3tc") != NULL) {
1882             s_glSupport.hasS3tcSupport = true;
1883         }
1884     }
1885 }
1886 
buildStrings(bool isGles1,const char * baseVendor,const char * baseRenderer,const char * baseVersion,const char * version)1887 void GLEScontext::buildStrings(bool isGles1, const char* baseVendor,
1888         const char* baseRenderer, const char* baseVersion, const char* version)
1889 {
1890     static const char VENDOR[]   = {"Google ("};
1891     static const char RENDERER[] = {"Android Emulator OpenGL ES Translator ("};
1892     const size_t VENDOR_LEN   = sizeof(VENDOR) - 1;
1893     const size_t RENDERER_LEN = sizeof(RENDERER) - 1;
1894 
1895     // Sanitize the strings as some OpenGL implementations return NULL
1896     // when asked the basic questions (this happened at least once on a client
1897     // machine)
1898     if (!baseVendor) {
1899         baseVendor = "N/A";
1900     }
1901     if (!baseRenderer) {
1902         baseRenderer = "N/A";
1903     }
1904     if (!baseVersion) {
1905         baseVersion = "N/A";
1906     }
1907     if (!version) {
1908         version = "N/A";
1909     }
1910 
1911     std::string& vendorString = isGles1 ? s_glVendorGles1 : s_glVendor;
1912     std::string& rendererString = isGles1 ? s_glRendererGles1 : s_glRenderer;
1913     std::string& versionString = isGles1 ? s_glVersionGles1 : s_glVersion;
1914 
1915     size_t baseVendorLen = strlen(baseVendor);
1916     vendorString.clear();
1917     vendorString.reserve(baseVendorLen + VENDOR_LEN + 1);
1918     vendorString.append(VENDOR, VENDOR_LEN);
1919     vendorString.append(baseVendor, baseVendorLen);
1920     vendorString.append(")", 1);
1921 
1922     size_t baseRendererLen = strlen(baseRenderer);
1923     rendererString.clear();
1924     rendererString.reserve(baseRendererLen + RENDERER_LEN + 1);
1925     rendererString.append(RENDERER, RENDERER_LEN);
1926     rendererString.append(baseRenderer, baseRendererLen);
1927     rendererString.append(")", 1);
1928 
1929     size_t baseVersionLen = strlen(baseVersion);
1930     size_t versionLen = strlen(version);
1931     versionString.clear();
1932     versionString.reserve(baseVersionLen + versionLen + 3);
1933     versionString.append(version, versionLen);
1934     versionString.append(" (", 2);
1935     versionString.append(baseVersion, baseVersionLen);
1936     versionString.append(")", 1);
1937 }
1938 
isTextureUnitEnabled(GLenum unit)1939 bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
1940     for (int i=0;i<NUM_TEXTURE_TARGETS;++i) {
1941         if (m_texState[unit-GL_TEXTURE0][i].enabled)
1942             return true;
1943     }
1944     return false;
1945 }
1946 
glGetBooleanv(GLenum pname,GLboolean * params)1947 bool GLEScontext::glGetBooleanv(GLenum pname, GLboolean *params)
1948 {
1949     GLint iParam;
1950 
1951     if(glGetIntegerv(pname, &iParam))
1952     {
1953         *params = (iParam != 0);
1954         return true;
1955     }
1956 
1957     return false;
1958 }
1959 
glGetFixedv(GLenum pname,GLfixed * params)1960 bool GLEScontext::glGetFixedv(GLenum pname, GLfixed *params)
1961 {
1962     bool result = false;
1963     GLint numParams = 1;
1964 
1965     GLint* iParams = new GLint[numParams];
1966     if (numParams>0 && glGetIntegerv(pname,iParams)) {
1967         while(numParams >= 0)
1968         {
1969             params[numParams] = I2X(iParams[numParams]);
1970             numParams--;
1971         }
1972         result = true;
1973     }
1974     delete [] iParams;
1975 
1976     return result;
1977 }
1978 
glGetFloatv(GLenum pname,GLfloat * params)1979 bool GLEScontext::glGetFloatv(GLenum pname, GLfloat *params)
1980 {
1981     bool result = false;
1982     GLint numParams = 1;
1983 
1984     GLint* iParams = new GLint[numParams];
1985     if (numParams>0 && glGetIntegerv(pname,iParams)) {
1986         while(numParams >= 0)
1987         {
1988             params[numParams] = (GLfloat)iParams[numParams];
1989             numParams--;
1990         }
1991         result = true;
1992     }
1993     delete [] iParams;
1994 
1995     return result;
1996 }
1997 
glGetIntegerv(GLenum pname,GLint * params)1998 bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
1999 {
2000     switch(pname)
2001     {
2002         case GL_ARRAY_BUFFER_BINDING:
2003             *params = m_arrayBuffer;
2004             break;
2005 
2006         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2007             *params = m_currVaoState.iboId();
2008             break;
2009 
2010         case GL_TEXTURE_BINDING_CUBE_MAP:
2011             *params = m_texState[m_activeTexture][TEXTURE_CUBE_MAP].texture;
2012             break;
2013 
2014         case GL_TEXTURE_BINDING_2D:
2015             *params = m_texState[m_activeTexture][TEXTURE_2D].texture;
2016             break;
2017 
2018         case GL_ACTIVE_TEXTURE:
2019             *params = m_activeTexture+GL_TEXTURE0;
2020             break;
2021 
2022         case GL_MAX_TEXTURE_SIZE:
2023             *params = getMaxTexSize();
2024             break;
2025         default:
2026             return false;
2027     }
2028 
2029     return true;
2030 }
2031 
GLTextureTargetToLocal(GLenum target)2032 TextureTarget GLEScontext::GLTextureTargetToLocal(GLenum target) {
2033     TextureTarget value=TEXTURE_2D;
2034     switch (target) {
2035     case GL_TEXTURE_CUBE_MAP:
2036     case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2037     case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2038     case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2039     case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2040     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2041     case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2042         value = TEXTURE_CUBE_MAP;
2043         break;
2044     case GL_TEXTURE_2D:
2045         value = TEXTURE_2D;
2046         break;
2047     case GL_TEXTURE_2D_ARRAY:
2048         value = TEXTURE_2D_ARRAY;
2049         break;
2050     case GL_TEXTURE_3D:
2051         value = TEXTURE_3D;
2052         break;
2053     case GL_TEXTURE_2D_MULTISAMPLE:
2054         value = TEXTURE_2D_MULTISAMPLE;
2055         break;
2056     }
2057     return value;
2058 }
2059 
getBindedTexture(GLenum target)2060 unsigned int GLEScontext::getBindedTexture(GLenum target) {
2061     TextureTarget pos = GLTextureTargetToLocal(target);
2062     return m_texState[m_activeTexture][pos].texture;
2063 }
2064 
getBindedTexture(GLenum unit,GLenum target)2065 unsigned int GLEScontext::getBindedTexture(GLenum unit, GLenum target) {
2066     TextureTarget pos = GLTextureTargetToLocal(target);
2067     return m_texState[unit-GL_TEXTURE0][pos].texture;
2068 }
2069 
setBindedTexture(GLenum target,unsigned int tex)2070 void GLEScontext::setBindedTexture(GLenum target, unsigned int tex) {
2071     TextureTarget pos = GLTextureTargetToLocal(target);
2072     m_texState[m_activeTexture][pos].texture = tex;
2073 }
2074 
setTextureEnabled(GLenum target,GLenum enable)2075 void GLEScontext::setTextureEnabled(GLenum target, GLenum enable) {
2076     TextureTarget pos = GLTextureTargetToLocal(target);
2077     m_texState[m_activeTexture][pos].enabled = enable;
2078 }
2079 
2080 #define INTERNAL_NAME(x) (x +0x100000000ll);
2081 
getDefaultTextureName(GLenum target)2082 ObjectLocalName GLEScontext::getDefaultTextureName(GLenum target) {
2083     ObjectLocalName name = 0;
2084     switch (GLTextureTargetToLocal(target)) {
2085     case TEXTURE_2D:
2086         name = INTERNAL_NAME(0);
2087         break;
2088     case TEXTURE_CUBE_MAP:
2089         name = INTERNAL_NAME(1);
2090         break;
2091     case TEXTURE_2D_ARRAY:
2092         name = INTERNAL_NAME(2);
2093         break;
2094     case TEXTURE_3D:
2095         name = INTERNAL_NAME(3);
2096         break;
2097     case TEXTURE_2D_MULTISAMPLE:
2098         name = INTERNAL_NAME(4);
2099         break;
2100     default:
2101         name = 0;
2102         break;
2103     }
2104     return name;
2105 }
2106 
getTextureLocalName(GLenum target,unsigned int tex)2107 ObjectLocalName GLEScontext::getTextureLocalName(GLenum target,
2108         unsigned int tex) {
2109     return (tex!=0? tex : getDefaultTextureName(target));
2110 }
2111 
drawValidate(void)2112 void GLEScontext::drawValidate(void)
2113 {
2114     if(m_drawFramebuffer == 0)
2115         return;
2116 
2117     auto fbObj = getFBOData(m_drawFramebuffer);
2118     if (!fbObj)
2119         return;
2120 
2121     fbObj->validate(this);
2122 }
2123 
initEmulatedEGLSurface(GLint width,GLint height,GLint colorFormat,GLint depthstencilFormat,GLint multisamples,GLuint rboColor,GLuint rboDepth)2124 void GLEScontext::initEmulatedEGLSurface(GLint width, GLint height,
2125                              GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
2126                              GLuint rboColor, GLuint rboDepth) {
2127     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, rboColor);
2128     if (multisamples) {
2129         dispatcher().glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisamples, colorFormat, width, height);
2130         GLint err = dispatcher().glGetError();
2131         if (err != GL_NO_ERROR) {
2132             fprintf(stderr, "%s: error setting up multisampled RBO! 0x%x\n", __func__, err);
2133         }
2134     } else {
2135         dispatcher().glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
2136     }
2137 
2138     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, rboDepth);
2139     if (multisamples) {
2140         dispatcher().glRenderbufferStorageMultisample(GL_RENDERBUFFER, multisamples, depthstencilFormat, width, height);
2141         GLint err = dispatcher().glGetError();
2142         if (err != GL_NO_ERROR) {
2143             fprintf(stderr, "%s: error setting up multisampled RBO! 0x%x\n", __func__, err);
2144         }
2145     } else {
2146         dispatcher().glRenderbufferStorage(GL_RENDERBUFFER, depthstencilFormat, width, height);
2147     }
2148 }
2149 
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)2150 void GLEScontext::initDefaultFBO(
2151         GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
2152         GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
2153         GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthStencilFormat, GLint readMultisamples,
2154         GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
2155 
2156     if (!m_defaultFBO) {
2157         dispatcher().glGenFramebuffers(1, &m_defaultFBO);
2158         m_defaultReadFBO = m_defaultFBO;
2159     }
2160 
2161     bool needReallocateRbo = false;
2162     bool separateReadRbo = false;
2163     bool needReallocateReadRbo = false;
2164 
2165     separateReadRbo =
2166         eglReadSurfaceRBColorId !=
2167         eglSurfaceRBColorId;
2168 
2169     if (separateReadRbo && (m_defaultReadFBO == m_defaultFBO)) {
2170         dispatcher().glGenFramebuffers(1, &m_defaultReadFBO);
2171     }
2172 
2173     if (!(*eglSurfaceRBColorId)) {
2174         dispatcher().glGenRenderbuffers(1, eglSurfaceRBColorId);
2175         dispatcher().glGenRenderbuffers(1, eglSurfaceRBDepthId);
2176         needReallocateRbo = true;
2177     }
2178 
2179     if (!(*eglReadSurfaceRBColorId) && separateReadRbo) {
2180         dispatcher().glGenRenderbuffers(1, eglReadSurfaceRBColorId);
2181         dispatcher().glGenRenderbuffers(1, eglReadSurfaceRBDepthId);
2182         needReallocateReadRbo = true;
2183     }
2184 
2185     m_defaultFBOColorFormat = colorFormat;
2186     m_defaultFBOWidth = width;
2187     m_defaultFBOHeight = height;
2188     m_defaultFBOSamples = multisamples;
2189 
2190     GLint prevRbo;
2191     dispatcher().glGetIntegerv(GL_RENDERBUFFER_BINDING, &prevRbo);
2192 
2193     // OS X in legacy opengl mode does not actually support GL_RGB565 as a renderbuffer.
2194     // Just replace it with GL_RGB8 for now.
2195     // TODO: Re-enable GL_RGB565 for OS X when we move to core profile.
2196 #ifdef __APPLE__
2197     if (colorFormat == GL_RGB565)
2198         colorFormat = GL_RGB8;
2199     if (readColorFormat == GL_RGB565)
2200         readColorFormat = GL_RGB8;
2201 #endif
2202 
2203     if (needReallocateRbo) {
2204         initEmulatedEGLSurface(width, height, colorFormat, depthstencilFormat, multisamples,
2205                                 *eglSurfaceRBColorId, *eglSurfaceRBDepthId);
2206     }
2207 
2208     if (needReallocateReadRbo) {
2209         initEmulatedEGLSurface(readWidth, readHeight, readColorFormat, readDepthStencilFormat, readMultisamples,
2210                                 *eglReadSurfaceRBColorId, *eglReadSurfaceRBDepthId);
2211     }
2212 
2213     dispatcher().glBindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2214 
2215     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *eglSurfaceRBColorId);
2216     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *eglSurfaceRBDepthId);
2217     dispatcher().glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *eglSurfaceRBDepthId);
2218 
2219     if (m_defaultFBODrawBuffer != GL_COLOR_ATTACHMENT0) {
2220         dispatcher().glDrawBuffers(1, &m_defaultFBODrawBuffer);
2221     }
2222     if (m_defaultFBOReadBuffer != GL_COLOR_ATTACHMENT0) {
2223         dispatcher().glReadBuffer(m_defaultFBOReadBuffer);
2224     }
2225 
2226     if (separateReadRbo) {
2227         dispatcher().glBindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultReadFBO);
2228         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *eglReadSurfaceRBColorId);
2229         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, *eglReadSurfaceRBDepthId);
2230         dispatcher().glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, *eglReadSurfaceRBDepthId);
2231     }
2232 
2233     dispatcher().glBindRenderbuffer(GL_RENDERBUFFER, prevRbo);
2234     GLuint prevDrawFBOBinding = getFramebufferBinding(GL_FRAMEBUFFER);
2235     GLuint prevReadFBOBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2236 
2237     if (prevDrawFBOBinding)
2238         dispatcher().glBindFramebuffer(GL_FRAMEBUFFER, getFBOGlobalName(prevDrawFBOBinding));
2239     if (prevReadFBOBinding)
2240         dispatcher().glBindFramebuffer(GL_READ_FRAMEBUFFER, getFBOGlobalName(prevReadFBOBinding));
2241 
2242     // We might be initializing a surfaceless context underneath
2243     // where the viewport is initialized to 0x0 width and height.
2244     // Set to our wanted pbuffer dimensions if this is the first time
2245     // the viewport has been set.
2246     if (!m_isViewport) {
2247         setViewport(0, 0, width, height);
2248         dispatcher().glViewport(0, 0, width, height);
2249     }
2250     // same for the scissor
2251     if (!m_isScissor) {
2252         setScissor(0, 0, width, height);
2253         dispatcher().glScissor(0, 0, width, height);
2254     }
2255 }
2256 
2257 
prepareCoreProfileEmulatedTexture(TextureData * texData,bool is3d,GLenum target,GLenum format,GLenum type,GLint * internalformat_out,GLenum * format_out)2258 void GLEScontext::prepareCoreProfileEmulatedTexture(TextureData* texData, bool is3d, GLenum target,
2259                                                     GLenum format, GLenum type,
2260                                                     GLint* internalformat_out, GLenum* format_out) {
2261     if (format != GL_ALPHA &&
2262         format != GL_LUMINANCE &&
2263         format != GL_LUMINANCE_ALPHA) {
2264         return;
2265     }
2266 
2267     if (isCubeMapFaceTarget(target)) {
2268         target = is3d ? GL_TEXTURE_CUBE_MAP_ARRAY_EXT : GL_TEXTURE_CUBE_MAP;
2269     }
2270 
2271     // Set up the swizzle from the underlying supported
2272     // host format to the emulated format.
2273     // Make sure to re-apply any user-specified custom swizlz
2274     TextureSwizzle userSwz; // initialized to identity map
2275 
2276     if (texData) {
2277         userSwz.toRed = texData->getSwizzle(GL_TEXTURE_SWIZZLE_R);
2278         userSwz.toGreen = texData->getSwizzle(GL_TEXTURE_SWIZZLE_G);
2279         userSwz.toBlue = texData->getSwizzle(GL_TEXTURE_SWIZZLE_B);
2280         userSwz.toAlpha = texData->getSwizzle(GL_TEXTURE_SWIZZLE_A);
2281     }
2282 
2283     TextureSwizzle swz =
2284         concatSwizzles(getSwizzleForEmulatedFormat(format),
2285                        userSwz);
2286 
2287     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, swz.toRed);
2288     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, swz.toGreen);
2289     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, swz.toBlue);
2290     dispatcher().glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, swz.toAlpha);
2291 
2292     // Change the format/internalformat communicated to GL.
2293     GLenum emulatedFormat =
2294         getCoreProfileEmulatedFormat(format);
2295     GLint emulatedInternalFormat =
2296         getCoreProfileEmulatedInternalFormat(format, type);
2297 
2298     if (format_out) *format_out = emulatedFormat;
2299     if (internalformat_out) *internalformat_out = emulatedInternalFormat;
2300 }
2301 
isFBO(ObjectLocalName p_localName)2302 bool GLEScontext::isFBO(ObjectLocalName p_localName) {
2303     return m_fboNameSpace->isObject(p_localName);
2304 }
2305 
genFBOName(ObjectLocalName p_localName,bool genLocal)2306 ObjectLocalName GLEScontext::genFBOName(ObjectLocalName p_localName,
2307         bool genLocal) {
2308     return m_fboNameSpace->genName(GenNameInfo(NamedObjectType::FRAMEBUFFER),
2309             p_localName, genLocal);
2310 }
2311 
setFBOData(ObjectLocalName p_localName,ObjectDataPtr data)2312 void GLEScontext::setFBOData(ObjectLocalName p_localName, ObjectDataPtr data) {
2313     m_fboNameSpace->setObjectData(p_localName, data);
2314 }
2315 
deleteFBO(ObjectLocalName p_localName)2316 void GLEScontext::deleteFBO(ObjectLocalName p_localName) {
2317     m_fboNameSpace->deleteName(p_localName);
2318 }
2319 
getFBOData(ObjectLocalName p_localName) const2320 FramebufferData* GLEScontext::getFBOData(ObjectLocalName p_localName) const {
2321     return (FramebufferData*)getFBODataPtr(p_localName).get();
2322 }
2323 
getFBODataPtr(ObjectLocalName p_localName) const2324 ObjectDataPtr GLEScontext::getFBODataPtr(ObjectLocalName p_localName) const {
2325     return m_fboNameSpace->getObjectDataPtr(p_localName);
2326 }
2327 
getFBOGlobalName(ObjectLocalName p_localName) const2328 unsigned int GLEScontext::getFBOGlobalName(ObjectLocalName p_localName) const {
2329     return m_fboNameSpace->getGlobalName(p_localName);
2330 }
2331 
getFBOLocalName(unsigned int p_globalName) const2332 ObjectLocalName GLEScontext::getFBOLocalName(unsigned int p_globalName) const {
2333     return m_fboNameSpace->getLocalName(p_globalName);
2334 }
2335 
queryCurrFboBits(ObjectLocalName localFboName,GLenum pname)2336 int GLEScontext::queryCurrFboBits(ObjectLocalName localFboName, GLenum pname) {
2337     GLint colorInternalFormat = 0;
2338     GLint depthInternalFormat = 0;
2339     GLint stencilInternalFormat = 0;
2340     bool combinedDepthStencil = false;
2341 
2342     if (!localFboName) {
2343         colorInternalFormat = m_defaultFBOColorFormat;
2344         // FBO 0 defaulting to d24s8
2345         depthInternalFormat =
2346             m_defaultFBODepthFormat ? m_defaultFBODepthFormat : GL_DEPTH24_STENCIL8;
2347         stencilInternalFormat =
2348             m_defaultFBOStencilFormat ? m_defaultFBOStencilFormat : GL_DEPTH24_STENCIL8;
2349     } else {
2350         FramebufferData* fbData = getFBOData(localFboName);
2351 
2352         std::vector<GLenum> colorAttachments(getCaps()->maxDrawBuffers);
2353         std::iota(colorAttachments.begin(), colorAttachments.end(), GL_COLOR_ATTACHMENT0);
2354 
2355         bool hasColorAttachment = false;
2356         for (auto attachment : colorAttachments) {
2357             GLint internalFormat =
2358                 fbData->getAttachmentInternalFormat(this, attachment);
2359 
2360             // Only defined if all used color attachments are the same
2361             // internal format.
2362             if (internalFormat) {
2363                 if (hasColorAttachment &&
2364                     colorInternalFormat != internalFormat) {
2365                     colorInternalFormat = 0;
2366                     break;
2367                 }
2368                 colorInternalFormat = internalFormat;
2369                 hasColorAttachment = true;
2370             }
2371         }
2372 
2373         GLint depthStencilFormat =
2374             fbData->getAttachmentInternalFormat(this, GL_DEPTH_STENCIL_ATTACHMENT);
2375 
2376         if (depthStencilFormat) {
2377             combinedDepthStencil = true;
2378             depthInternalFormat = depthStencilFormat;
2379             stencilInternalFormat = depthStencilFormat;
2380         }
2381 
2382         if (!combinedDepthStencil) {
2383             depthInternalFormat =
2384                 fbData->getAttachmentInternalFormat(this, GL_DEPTH_ATTACHMENT);
2385             stencilInternalFormat =
2386                 fbData->getAttachmentInternalFormat(this, GL_STENCIL_ATTACHMENT);
2387         }
2388     }
2389 
2390     FramebufferChannelBits res =
2391         glFormatToChannelBits(colorInternalFormat,
2392                               depthInternalFormat,
2393                               stencilInternalFormat);
2394 
2395     switch (pname) {
2396     case GL_RED_BITS:
2397         return res.red;
2398     case GL_GREEN_BITS:
2399         return res.green;
2400     case GL_BLUE_BITS:
2401         return res.blue;
2402     case GL_ALPHA_BITS:
2403         return res.alpha;
2404     case GL_DEPTH_BITS:
2405         return res.depth;
2406     case GL_STENCIL_BITS:
2407         return res.stencil;
2408     }
2409 
2410     return 0;
2411 }
2412 
2413 static const char kTexImageEmulationVShaderSrc[] = R"(
2414 precision highp float;
2415 out vec2 v_texcoord;
2416 void main() {
2417     const vec2 quad_pos[6] = vec2[6](
2418         vec2(0.0, 0.0),
2419         vec2(0.0, 1.0),
2420         vec2(1.0, 0.0),
2421         vec2(0.0, 1.0),
2422         vec2(1.0, 0.0),
2423         vec2(1.0, 1.0));
2424 
2425     gl_Position = vec4((quad_pos[gl_VertexID] * 2.0) - 1.0, 0.0, 1.0);
2426     v_texcoord = quad_pos[gl_VertexID];
2427 })";
2428 
2429 static const char kTexImageEmulationVShaderSrcFlipped[] = R"(
2430 precision highp float;
2431 layout (location = 0) in vec2 a_pos;
2432 out vec2 v_texcoord;
2433 void main() {
2434     gl_Position = vec4((a_pos.xy) * 2.0 - 1.0, 0.0, 1.0);
2435     v_texcoord = a_pos;
2436     v_texcoord.y = 1.0 - v_texcoord.y;
2437 })";
2438 
2439 static const char kTexImageEmulationFShaderSrc[] = R"(
2440 precision highp float;
2441 uniform sampler2D source_tex;
2442 in vec2 v_texcoord;
2443 out vec4 color;
2444 void main() {
2445    color = texture(source_tex, v_texcoord);
2446 })";
2447 
initTexImageEmulation()2448 void GLEScontext::initTexImageEmulation() {
2449     if (m_textureEmulationProg) return;
2450 
2451     auto& gl = dispatcher();
2452 
2453     std::string vshaderSrc = isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2454     vshaderSrc += kTexImageEmulationVShaderSrc;
2455     std::string fshaderSrc = isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2456     fshaderSrc += kTexImageEmulationFShaderSrc;
2457 
2458     GLuint vshader =
2459         compileAndValidateCoreShader(GL_VERTEX_SHADER,
2460                                      vshaderSrc.c_str());
2461     GLuint fshader =
2462         compileAndValidateCoreShader(GL_FRAGMENT_SHADER,
2463                                      fshaderSrc.c_str());
2464     m_textureEmulationProg = linkAndValidateProgram(vshader, fshader);
2465     m_textureEmulationSamplerLoc =
2466         gl.glGetUniformLocation(m_textureEmulationProg, "source_tex");
2467 
2468     gl.glGenFramebuffers(1, &m_textureEmulationFBO);
2469     gl.glGenTextures(2, m_textureEmulationTextures);
2470     gl.glGenVertexArrays(1, &m_textureEmulationVAO);
2471 }
2472 
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)2473 void GLEScontext::copyTexImageWithEmulation(
2474         TextureData* texData,
2475         bool isSubImage,
2476         GLenum target,
2477         GLint level,
2478         GLenum internalformat,
2479         GLint xoffset, GLint yoffset,
2480         GLint x, GLint y,
2481         GLsizei width, GLsizei height,
2482         GLint border) {
2483 
2484     // Create objects used for emulation if they don't exist already.
2485     initTexImageEmulation();
2486     auto& gl = dispatcher();
2487 
2488     // Save all affected state.
2489     ScopedGLState state;
2490     state.pushForCoreProfileTextureEmulation();
2491 
2492     // render to an intermediate texture with the same format:
2493     // 1. Get the format
2494     FramebufferData* fbData =
2495         getFBOData(getFramebufferBinding(GL_READ_FRAMEBUFFER));
2496     GLint readFbInternalFormat =
2497         fbData ? fbData->getAttachmentInternalFormat(this, GL_COLOR_ATTACHMENT0) :
2498                  m_defaultFBOColorFormat;
2499 
2500     // 2. Create the texture for textures[0] with this format, and initialize
2501     // it to the current FBO read buffer.
2502     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[0]);
2503     gl.glCopyTexImage2D(GL_TEXTURE_2D, 0, readFbInternalFormat,
2504                         x, y, width, height, 0);
2505 
2506     // 3. Set swizzle of textures[0] so they are read in the right way
2507     // when drawing to textures[1].
2508     TextureSwizzle swz = getInverseSwizzleForEmulatedFormat(texData->format);
2509     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, swz.toRed);
2510     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, swz.toGreen);
2511     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, swz.toBlue);
2512     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, swz.toAlpha);
2513     // Also, nearest filtering
2514     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2515     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2516 
2517     // 4. Initialize textures[1] with same width/height, and use it to back
2518     // the FBO that holds the swizzled results.
2519     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[1]);
2520     gl.glTexImage2D(GL_TEXTURE_2D, 0, readFbInternalFormat, width, height, 0,
2521                     baseFormatOfInternalFormat(readFbInternalFormat),
2522                     accurateTypeOfInternalFormat(readFbInternalFormat),
2523                     nullptr);
2524     // Also, nearest filtering
2525     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2526     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2527 
2528     gl.glBindFramebuffer(GL_FRAMEBUFFER, m_textureEmulationFBO);
2529     gl.glFramebufferTexture2D(
2530         GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
2531         m_textureEmulationTextures[1], 0);
2532 
2533     // 5. Draw textures[0] to our FBO, making sure all state is compatible.
2534     gl.glDisable(GL_BLEND);
2535     gl.glDisable(GL_SCISSOR_TEST);
2536     gl.glDisable(GL_DEPTH_TEST);
2537     gl.glDisable(GL_STENCIL_TEST);
2538     gl.glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2539     gl.glDisable(GL_SAMPLE_COVERAGE);
2540     gl.glDisable(GL_CULL_FACE);
2541     gl.glDisable(GL_POLYGON_OFFSET_FILL);
2542     gl.glDisable(GL_RASTERIZER_DISCARD);
2543 
2544     gl.glViewport(0, 0, width, height);
2545 
2546     if (isGles2Gles()) {
2547         gl.glDepthRangef(0.0f, 1.0f);
2548     } else {
2549         gl.glDepthRange(0.0f, 1.0f);
2550     }
2551 
2552     gl.glColorMask(1, 1, 1, 1);
2553 
2554     gl.glBindTexture(GL_TEXTURE_2D, m_textureEmulationTextures[0]);
2555     GLint texUnit; gl.glGetIntegerv(GL_ACTIVE_TEXTURE, &texUnit);
2556 
2557     gl.glUseProgram(m_textureEmulationProg);
2558     gl.glUniform1i(m_textureEmulationSamplerLoc, texUnit - GL_TEXTURE0);
2559 
2560     gl.glBindVertexArray(m_textureEmulationVAO);
2561 
2562     gl.glDrawArrays(GL_TRIANGLES, 0, 6);
2563 
2564     // now the emulated version has been rendered and written to the read FBO
2565     // with the correct swizzle.
2566     if (isCubeMapFaceTarget(target)) {
2567         gl.glBindTexture(GL_TEXTURE_CUBE_MAP, texData->getGlobalName());
2568     } else {
2569         gl.glBindTexture(target, texData->getGlobalName());
2570     }
2571 
2572     if (isSubImage) {
2573         gl.glCopyTexSubImage2D(target, level, xoffset, yoffset, 0, 0, width, height);
2574     } else {
2575         gl.glCopyTexImage2D(target, level, internalformat, 0, 0, width, height, border);
2576     }
2577 }
2578 
2579 // static
compileAndValidateCoreShader(GLenum shaderType,const char * src)2580 GLuint GLEScontext::compileAndValidateCoreShader(GLenum shaderType, const char* src) {
2581     GLDispatch& gl = dispatcher();
2582 
2583     GLuint shader = gl.glCreateShader(shaderType);
2584     gl.glShaderSource(shader, 1, (const GLchar* const*)&src, nullptr);
2585     gl.glCompileShader(shader);
2586 
2587     GLint compileStatus;
2588     gl.glGetShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
2589 
2590     if (compileStatus != GL_TRUE) {
2591         GLsizei infoLogLength = 0;
2592         gl.glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
2593         std::vector<char> infoLog(infoLogLength + 1, 0);
2594         gl.glGetShaderInfoLog(shader, infoLogLength, nullptr, &infoLog[0]);
2595         fprintf(stderr, "%s: fail to compile. infolog %s\n", __func__, &infoLog[0]);
2596     }
2597 
2598     return shader;
2599 }
2600 
2601 // static
linkAndValidateProgram(GLuint vshader,GLuint fshader)2602 GLuint GLEScontext::linkAndValidateProgram(GLuint vshader, GLuint fshader) {
2603     GLDispatch& gl = dispatcher();
2604 
2605     GLuint program = gl.glCreateProgram();
2606     gl.glAttachShader(program, vshader);
2607     gl.glAttachShader(program, fshader);
2608     gl.glLinkProgram(program);
2609 
2610     GLint linkStatus;
2611     gl.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
2612 
2613     if (linkStatus != GL_TRUE) {
2614         GLsizei infoLogLength = 0;
2615         gl.glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
2616         std::vector<char> infoLog(infoLogLength + 1, 0);
2617         gl.glGetProgramInfoLog(program, infoLogLength, nullptr, &infoLog[0]);
2618 
2619         fprintf(stderr, "%s: fail to link program. infolog: %s\n", __func__,
2620                 &infoLog[0]);
2621     }
2622 
2623     gl.glDeleteShader(vshader);
2624     gl.glDeleteShader(fshader);
2625 
2626     return program;
2627 }
2628 
getReadBufferSamples()2629 int GLEScontext::getReadBufferSamples() {
2630     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2631     bool defaultFboReadBufferBound = readFboBinding == 0;
2632     if (defaultFboReadBufferBound) {
2633         return m_defaultFBOSamples;
2634     } else {
2635         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2636         return fbData ? fbData->getAttachmentSamples(this, fbData->getReadBuffer()) : 0;
2637     }
2638 }
2639 
getReadBufferInternalFormat()2640 int GLEScontext::getReadBufferInternalFormat() {
2641     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2642     bool defaultFboReadBufferBound = readFboBinding == 0;
2643     if (defaultFboReadBufferBound) {
2644         return m_defaultFBOColorFormat;
2645     } else {
2646         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2647         return fbData ? fbData->getAttachmentInternalFormat(this, fbData->getReadBuffer()) : 0;
2648     }
2649 }
2650 
getReadBufferDimensions(GLint * width,GLint * height)2651 void GLEScontext::getReadBufferDimensions(GLint* width, GLint* height) {
2652     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2653     bool defaultFboReadBufferBound = readFboBinding == 0;
2654     if (defaultFboReadBufferBound) {
2655         *width = m_defaultFBOWidth;
2656         *height = m_defaultFBOHeight;
2657     } else {
2658         FramebufferData* fbData = (FramebufferData*)(getFBODataPtr(readFboBinding).get());
2659         if (fbData) {
2660             fbData->getAttachmentDimensions(
2661                 this, fbData->getReadBuffer(), width, height);
2662         }
2663     }
2664 }
2665 
setupImageBlitState()2666 void GLEScontext::setupImageBlitState() {
2667     auto& gl = dispatcher();
2668     m_blitState.prevSamples = m_blitState.samples;
2669     m_blitState.samples = getReadBufferSamples();
2670 
2671     if (m_blitState.program) return;
2672 
2673     std::string vshaderSrc =
2674         isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2675     vshaderSrc += kTexImageEmulationVShaderSrcFlipped;
2676 
2677     std::string fshaderSrc =
2678         isCoreProfile() ? "#version 330 core\n" : "#version 300 es\n";
2679     fshaderSrc += kTexImageEmulationFShaderSrc;
2680 
2681     GLuint vshader =
2682         compileAndValidateCoreShader(GL_VERTEX_SHADER, vshaderSrc.c_str());
2683     GLuint fshader =
2684         compileAndValidateCoreShader(GL_FRAGMENT_SHADER, fshaderSrc.c_str());
2685 
2686     m_blitState.program = linkAndValidateProgram(vshader, fshader);
2687     m_blitState.samplerLoc =
2688         gl.glGetUniformLocation(m_blitState.program, "source_tex");
2689 
2690     gl.glGenFramebuffers(1, &m_blitState.fbo);
2691     gl.glGenFramebuffers(1, &m_blitState.resolveFbo);
2692     gl.glGenTextures(1, &m_blitState.tex);
2693     gl.glGenVertexArrays(1, &m_blitState.vao);
2694 
2695     gl.glGenBuffers(1, &m_blitState.vbo);
2696     float blitVbo[] = {
2697         0.0f, 0.0f,
2698         1.0f, 0.0f,
2699         0.0f, 1.0f,
2700         1.0f, 0.0f,
2701         1.0f, 1.0f,
2702         0.0f, 1.0f,
2703     };
2704 
2705     GLint buf;
2706     gl.glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buf);
2707 
2708     gl.glBindBuffer(GL_ARRAY_BUFFER, m_blitState.vbo);
2709     gl.glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(float), blitVbo, GL_STATIC_DRAW);
2710 
2711     gl.glBindVertexArray(m_blitState.vao);
2712     gl.glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
2713     gl.glEnableVertexAttribArray(0);
2714 
2715     gl.glBindBuffer(GL_ARRAY_BUFFER, buf);
2716 }
2717 
setupImageBlitForTexture(uint32_t width,uint32_t height,GLint internalFormat)2718 bool GLEScontext::setupImageBlitForTexture(uint32_t width,
2719                                            uint32_t height,
2720                                            GLint internalFormat) {
2721     GLint sizedInternalFormat = GL_RGBA8;
2722     if (internalFormat != GL_RGBA8 &&
2723         internalFormat != GL_RGB8 &&
2724         internalFormat != GL_RGB565) {
2725         switch (internalFormat) {
2726         case GL_RGB:
2727             sizedInternalFormat = GL_RGB8;
2728             break;
2729         case GL_RGBA:
2730             sizedInternalFormat = GL_RGBA8;
2731             break;
2732         default:
2733             break;
2734         }
2735     }
2736 
2737     auto& gl = dispatcher();
2738     gl.glBindTexture(GL_TEXTURE_2D, m_blitState.tex);
2739 
2740     GLint read_iformat = getReadBufferInternalFormat();
2741     GLint read_format = baseFormatOfInternalFormat(read_iformat);
2742 
2743     if (isIntegerInternalFormat(read_iformat) ||
2744         read_iformat == GL_RGB10_A2) {
2745         // Is not a blittable format. Just create the texture for now to
2746         // make image blit state consistent.
2747         gl.glTexImage2D(GL_TEXTURE_2D, 0, sizedInternalFormat, width, height, 0,
2748                 baseFormatOfInternalFormat(internalFormat), GL_UNSIGNED_BYTE, 0);
2749         return false;
2750     }
2751 
2752     if (width != m_blitState.width || height != m_blitState.height ||
2753         internalFormat != m_blitState.internalFormat ||
2754         m_blitState.samples != m_blitState.prevSamples) {
2755 
2756         m_blitState.width = width;
2757         m_blitState.height = height;
2758         m_blitState.internalFormat = internalFormat;
2759 
2760         gl.glTexImage2D(GL_TEXTURE_2D, 0,
2761                         read_iformat, width, height, 0, read_format, GL_UNSIGNED_BYTE, 0);
2762         if (m_blitState.samples > 0) {
2763             gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.resolveFbo);
2764             gl.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2765                     GL_TEXTURE_2D, m_blitState.tex, 0);
2766         }
2767 
2768         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2769         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2770         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2771         gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2772     }
2773 
2774     // In eglSwapBuffers, the surface must be bound as the draw surface of
2775     // the current context, which corresponds to m_defaultFBO here.
2776     //
2777     // EGL 1.4 spec:
2778     //
2779     // 3.9.3 Posting Semantics surface must be bound to the draw surface of the
2780     // calling thread’s current context, for the current rendering API. This
2781     // restriction may be lifted in future EGL revisions.
2782     //
2783     const GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2784     if (readFboBinding != 0) {
2785         gl.glBindFramebuffer(GL_READ_FRAMEBUFFER, m_defaultFBO);
2786     }
2787 
2788     if (m_blitState.samples > 0) {
2789         GLint rWidth = width;
2790         GLint rHeight = height;
2791         getReadBufferDimensions(&rWidth, &rHeight);
2792         gl.glBindTexture(GL_TEXTURE_2D, 0);
2793         gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.resolveFbo);
2794         gl.glBlitFramebuffer(0, 0, rWidth, rHeight, 0, 0, rWidth, rHeight,
2795                 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2796         gl.glBindTexture(GL_TEXTURE_2D, m_blitState.tex);
2797     } else {
2798         gl.glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height);
2799     }
2800 
2801     return true;
2802 }
2803 
blitFromReadBufferToTextureFlipped(GLuint globalTexObj,GLuint width,GLuint height,GLint internalFormat,GLenum format,GLenum type)2804 void GLEScontext::blitFromReadBufferToTextureFlipped(GLuint globalTexObj,
2805                                                      GLuint width,
2806                                                      GLuint height,
2807                                                      GLint internalFormat,
2808                                                      GLenum format,
2809                                                      GLenum type) {
2810     // TODO: these might also matter
2811     (void)format;
2812     (void)type;
2813 
2814     auto& gl = dispatcher();
2815     GLint prevViewport[4];
2816     getViewport(prevViewport);
2817 
2818     setupImageBlitState();
2819     bool shouldBlit = setupImageBlitForTexture(width, height, internalFormat);
2820 
2821     if (!shouldBlit) return;
2822 
2823     // b/159670873: The texture to blit doesn't necessarily match the display
2824     // size. If it doesn't match, then we might not be using the right mipmap
2825     // level, which can result in a black screen. Set to always use level 0.
2826     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
2827     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
2828 
2829     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2830     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2831     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
2832     gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
2833 
2834     gl.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_blitState.fbo);
2835     gl.glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
2836                               GL_TEXTURE_2D, globalTexObj, 0);
2837 
2838     gl.glDisable(GL_BLEND);
2839     gl.glDisable(GL_SCISSOR_TEST);
2840     gl.glDisable(GL_DEPTH_TEST);
2841     gl.glDisable(GL_STENCIL_TEST);
2842     gl.glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2843     gl.glDisable(GL_SAMPLE_COVERAGE);
2844     gl.glDisable(GL_CULL_FACE);
2845     gl.glDisable(GL_POLYGON_OFFSET_FILL);
2846     gl.glDisable(GL_RASTERIZER_DISCARD);
2847 
2848     gl.glViewport(0, 0, width, height);
2849     if (isGles2Gles()) {
2850         gl.glDepthRangef(0.0f, 1.0f);
2851     } else {
2852         gl.glDepthRange(0.0f, 1.0f);
2853     }
2854     gl.glColorMask(1, 1, 1, 1);
2855 
2856     gl.glUseProgram(m_blitState.program);
2857     gl.glUniform1i(m_blitState.samplerLoc, m_activeTexture);
2858 
2859     gl.glBindVertexArray(m_blitState.vao);
2860     gl.glDrawArrays(GL_TRIANGLES, 0, 6);
2861 
2862     // state restore
2863     const GLuint globalProgramName = shareGroup()->getGlobalName(
2864         NamedObjectType::SHADER_OR_PROGRAM, m_useProgram);
2865     gl.glUseProgram(globalProgramName);
2866 
2867     gl.glBindVertexArray(getVAOGlobalName(m_currVaoState.vaoId()));
2868 
2869     gl.glBindTexture(
2870         GL_TEXTURE_2D,
2871         shareGroup()->getGlobalName(
2872             NamedObjectType::TEXTURE,
2873             getTextureLocalName(GL_TEXTURE_2D,
2874                                 getBindedTexture(GL_TEXTURE_2D))));
2875 
2876     GLuint drawFboBinding = getFramebufferBinding(GL_DRAW_FRAMEBUFFER);
2877     GLuint readFboBinding = getFramebufferBinding(GL_READ_FRAMEBUFFER);
2878 
2879     gl.glBindFramebuffer(
2880         GL_DRAW_FRAMEBUFFER,
2881         drawFboBinding ? getFBOGlobalName(drawFboBinding) : m_defaultFBO);
2882     gl.glBindFramebuffer(
2883         GL_READ_FRAMEBUFFER,
2884         readFboBinding ? getFBOGlobalName(readFboBinding) : m_defaultReadFBO);
2885 
2886     if (isEnabled(GL_BLEND)) gl.glEnable(GL_BLEND);
2887     if (isEnabled(GL_SCISSOR_TEST)) gl.glEnable(GL_SCISSOR_TEST);
2888     if (isEnabled(GL_DEPTH_TEST)) gl.glEnable(GL_DEPTH_TEST);
2889     if (isEnabled(GL_STENCIL_TEST)) gl.glEnable(GL_STENCIL_TEST);
2890     if (isEnabled(GL_SAMPLE_ALPHA_TO_COVERAGE)) gl.glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
2891     if (isEnabled(GL_SAMPLE_COVERAGE)) gl.glEnable(GL_SAMPLE_COVERAGE);
2892     if (isEnabled(GL_CULL_FACE)) gl.glEnable(GL_CULL_FACE);
2893     if (isEnabled(GL_POLYGON_OFFSET_FILL)) gl.glEnable(GL_POLYGON_OFFSET_FILL);
2894     if (isEnabled(GL_RASTERIZER_DISCARD)) gl.glEnable(GL_RASTERIZER_DISCARD);
2895 
2896     gl.glViewport(prevViewport[0], prevViewport[1],
2897                   prevViewport[2], prevViewport[3]);
2898 
2899     if (isGles2Gles()) {
2900         gl.glDepthRangef(m_zNear, m_zFar);
2901     } else {
2902         gl.glDepthRange(m_zNear, m_zFar);
2903     }
2904 
2905     gl.glColorMask(m_colorMaskR, m_colorMaskG, m_colorMaskB, m_colorMaskA);
2906 
2907     gl.glFlush();
2908 }
2909 
2910 // Primitive restart emulation
2911 #define GL_PRIMITIVE_RESTART              0x8F9D
2912 #define GL_PRIMITIVE_RESTART_INDEX        0x8F9E
2913 
setPrimitiveRestartEnabled(bool enabled)2914 void GLEScontext::setPrimitiveRestartEnabled(bool enabled) {
2915     auto& gl = dispatcher();
2916 
2917     if (enabled) {
2918         gl.glEnable(GL_PRIMITIVE_RESTART);
2919     } else {
2920         gl.glDisable(GL_PRIMITIVE_RESTART);
2921     }
2922 
2923     m_primitiveRestartEnabled = enabled;
2924 }
2925 
updatePrimitiveRestartIndex(GLenum type)2926 void GLEScontext::updatePrimitiveRestartIndex(GLenum type) {
2927     auto& gl = dispatcher();
2928     switch (type) {
2929     case GL_UNSIGNED_BYTE:
2930         gl.glPrimitiveRestartIndex(0xff);
2931         break;
2932     case GL_UNSIGNED_SHORT:
2933         gl.glPrimitiveRestartIndex(0xffff);
2934         break;
2935     case GL_UNSIGNED_INT:
2936         gl.glPrimitiveRestartIndex(0xffffffff);
2937         break;
2938     }
2939 }
2940 
isVAO(ObjectLocalName p_localName)2941 bool GLEScontext::isVAO(ObjectLocalName p_localName) {
2942     VAOStateMap::iterator it = m_vaoStateMap.find(p_localName);
2943     if (it == m_vaoStateMap.end()) return false;
2944     VAOStateRef vao(it);
2945     return vao.isEverBound();
2946 }
2947 
genVAOName(ObjectLocalName p_localName,bool genLocal)2948 ObjectLocalName GLEScontext::genVAOName(ObjectLocalName p_localName,
2949         bool genLocal) {
2950     return m_vaoNameSpace->genName(GenNameInfo(NamedObjectType::VERTEX_ARRAY_OBJECT),
2951             p_localName, genLocal);
2952 }
2953 
deleteVAO(ObjectLocalName p_localName)2954 void GLEScontext::deleteVAO(ObjectLocalName p_localName) {
2955     m_vaoNameSpace->deleteName(p_localName);
2956 }
2957 
getVAOGlobalName(ObjectLocalName p_localName)2958 unsigned int GLEScontext::getVAOGlobalName(ObjectLocalName p_localName) {
2959     return m_vaoNameSpace->getGlobalName(p_localName);
2960 }
2961 
getVAOLocalName(unsigned int p_globalName)2962 ObjectLocalName GLEScontext::getVAOLocalName(unsigned int p_globalName) {
2963     return m_vaoNameSpace->getLocalName(p_globalName);
2964 }
2965 
setDefaultFBODrawBuffer(GLenum buffer)2966 void GLEScontext::setDefaultFBODrawBuffer(GLenum buffer) {
2967     m_defaultFBODrawBuffer = buffer;
2968 }
2969 
setDefaultFBOReadBuffer(GLenum buffer)2970 void GLEScontext::setDefaultFBOReadBuffer(GLenum buffer) {
2971     m_defaultFBOReadBuffer = buffer;
2972 }
2973