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