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