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