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