1 /*
2 * Copyright (C) 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 "GLESv2Context.h"
18 
19 #include "ProgramData.h"
20 #include "SamplerData.h"
21 #include "ShaderParser.h"
22 #include "TransformFeedbackData.h"
23 #include "aemu/base/synchronization/Lock.h"
24 #include "aemu/base/files/StreamSerializing.h"
25 
26 #include "host-common/crash_reporter.h"
27 
28 #include <string.h>
29 
30 static const char kGLES20StringPart[] = "OpenGL ES 2.0";
31 static const char kGLES30StringPart[] = "OpenGL ES 3.0";
32 static const char kGLES31StringPart[] = "OpenGL ES 3.1";
33 static const char kGLES32StringPart[] = "OpenGL ES 3.2";
34 
35 static GLESVersion s_maxGlesVersion = GLES_2_0;
36 
sPickVersionStringPart(int maj,int min)37 static const char* sPickVersionStringPart(int maj, int min) {
38     switch (maj) {
39         case 2:
40             return kGLES20StringPart;
41         case 3:
42             switch (min) {
43                 case 0:
44                     return kGLES30StringPart;
45                 case 1:
46                     return kGLES31StringPart;
47                 case 2:
48                     return kGLES32StringPart;
49                 default:
50                     return nullptr;
51             }
52         default:
53             return nullptr;
54     }
55     return nullptr;
56 }
57 
setMaxGlesVersion(GLESVersion version)58 void GLESv2Context::setMaxGlesVersion(GLESVersion version) {
59     s_maxGlesVersion = version;
60 }
61 
initGlobal(EGLiface * iface)62 void GLESv2Context::initGlobal(EGLiface* iface) {
63     s_glDispatch.dispatchFuncs(s_maxGlesVersion, iface->eglGetGlLibrary(), iface->getProcAddress);
64     GLEScontext::initGlobal(iface);
65 }
66 
init(bool nativeTextureDecompressionEnabled)67 void GLESv2Context::init(bool nativeTextureDecompressionEnabled) {
68     android::base::AutoLock mutex(s_lock);
69     if(!m_initialized) {
70         GLEScontext::init(nativeTextureDecompressionEnabled);
71         addVertexArrayObject(0);
72         setVertexArrayObject(0);
73         setAttribute0value(0.0, 0.0, 0.0, 1.0);
74 
75         buildStrings(m_glesMajorVersion,
76                      m_glesMinorVersion,
77                      (const char*)dispatcher().glGetString(GL_VENDOR),
78                      (const char*)dispatcher().glGetString(GL_RENDERER),
79                      (const char*)dispatcher().glGetString(GL_VERSION),
80                      sPickVersionStringPart(m_glesMajorVersion, m_glesMinorVersion));
81         if (m_glesMajorVersion > 2 && !isGles2Gles()) {
82             // OpenGL ES assumes that colors computed by / given to shaders will be converted to / from SRGB automatically
83             // by the underlying implementation.
84             // Desktop OpenGL makes no such assumption, and requires glEnable(GL_FRAMEBUFFER_SRGB) for the automatic conversion
85             // to work.
86             // This should work in most cases: just glEnable(GL_FRAMEBUFFER_SRGB) for every context.
87             // But, that's not the whole story:
88             // TODO: For dEQP tests standalone, we can just glEnable GL_FRAMEBUFFER_SRGB from the beginning and
89             // pass all the framebuffer blit tests. However with CTS dEQP, EGL gets failures in color clear
90             // and some dEQP-GLES3 framebuffer blit tests fail.
91             // So we need to start out each context with GL_FRAMEBUFFER_SRGB disabled, and then enable it depending on
92             // whether or not the current draw or read framebuffer has a SRGB texture color attachment.
93             dispatcher().glDisable(GL_FRAMEBUFFER_SRGB);
94             // Desktop OpenGL allows one to make cube maps seamless _or not_, but
95             // OpenGL ES assumes seamless cubemaps are activated 100% of the time.
96             // Many dEQP cube map tests fail without this enable.
97             dispatcher().glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
98         }
99 
100         initEmulatedVAO();
101         initEmulatedBuffers();
102         // init emulated transform feedback
103         if (m_glesMajorVersion >= 3) {
104             m_transformFeedbackNameSpace->genName(
105                     GenNameInfo(NamedObjectType::TRANSFORM_FEEDBACK), 0, false);
106             TransformFeedbackData* tf = new TransformFeedbackData();
107             tf->setMaxSize(getCaps()->maxTransformFeedbackSeparateAttribs);
108             m_transformFeedbackNameSpace->setObjectData(0, ObjectDataPtr(tf));
109         }
110     }
111     m_initialized = true;
112 }
113 
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)114 void GLESv2Context::initDefaultFBO(
115         GLint width, GLint height, GLint colorFormat, GLint depthstencilFormat, GLint multisamples,
116         GLuint* eglSurfaceRBColorId, GLuint* eglSurfaceRBDepthId,
117         GLuint readWidth, GLint readHeight, GLint readColorFormat, GLint readDepthstencilFormat, GLint readMultisamples,
118         GLuint* eglReadSurfaceRBColorId, GLuint* eglReadSurfaceRBDepthId) {
119     GLEScontext::initDefaultFBO(
120             width, height, colorFormat, depthstencilFormat, multisamples,
121             eglSurfaceRBColorId, eglSurfaceRBDepthId,
122             readWidth, readHeight, readColorFormat, readDepthstencilFormat, readMultisamples,
123             eglReadSurfaceRBColorId, eglReadSurfaceRBDepthId
124             );
125 }
126 
127 
initEmulatedVAO()128 void GLESv2Context::initEmulatedVAO() {
129     if (!isCoreProfile()) return;
130 
131     // Create emulated default VAO
132     genVAOName(0, false);
133     dispatcher().glBindVertexArray(getVAOGlobalName(0));
134 }
135 
initEmulatedBuffers()136 void GLESv2Context::initEmulatedBuffers() {
137     if (m_emulatedClientVBOs.empty()) {
138         // Create emulated client VBOs
139         GLint neededClientVBOs = 0;
140         dispatcher().glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &neededClientVBOs);
141 
142         // Spec minimum: 16 attribs. Some drivers won't report the right values.
143         neededClientVBOs = std::max(neededClientVBOs, 16);
144 
145         m_emulatedClientVBOs.resize(neededClientVBOs, 0);
146         dispatcher().glGenBuffers(neededClientVBOs, &m_emulatedClientVBOs[0]);
147     }
148 
149     if (!m_emulatedClientIBO) {
150         // Create emulated IBO
151         dispatcher().glGenBuffers(1, &m_emulatedClientIBO);
152     }
153 }
154 
GLESv2Context(int maj,int min,GlobalNameSpace * globalNameSpace,android::base::Stream * stream,GlLibrary * glLib)155 GLESv2Context::GLESv2Context(int maj, int min, GlobalNameSpace* globalNameSpace,
156         android::base::Stream* stream, GlLibrary* glLib)
157         : GLEScontext(globalNameSpace, stream, glLib) {
158     if (stream) {
159         assert(maj == m_glesMajorVersion);
160         assert(min == m_glesMinorVersion);
161         stream->read(m_attribute0value, sizeof(m_attribute0value));
162         m_attribute0valueChanged = stream->getByte();
163         m_att0ArrayLength = stream->getBe32();
164         if (m_att0ArrayLength != 0) {
165             m_att0Array.reset(new GLfloat[4 * m_att0ArrayLength]);
166             stream->read(m_att0Array.get(), sizeof(GLfloat) * 4 * m_att0ArrayLength);
167         }
168         m_att0NeedsDisable = stream->getByte();
169         m_useProgram = stream->getBe32();
170         android::base::loadCollection(stream, &m_bindSampler,
171                 [](android::base::Stream* stream) {
172                     GLuint idx = stream->getBe32();
173                     GLuint val = stream->getBe32();
174                     return std::make_pair(idx, val);
175                 });
176     } else {
177         m_glesMajorVersion = maj;
178         m_glesMinorVersion = min;
179     }
180     ObjectData::loadObject_t loader = [this](NamedObjectType type,
181                                              long long unsigned int localName,
182                                              android::base::Stream* stream) {
183         return loadObject(type, localName, stream);
184     };
185     m_transformFeedbackNameSpace =
186             new NameSpace(NamedObjectType::TRANSFORM_FEEDBACK, globalNameSpace,
187                           stream, loader);
188 }
189 
~GLESv2Context()190 GLESv2Context::~GLESv2Context() {
191     if (m_emulatedClientIBO) {
192         s_glDispatch.glDeleteBuffers(1, &m_emulatedClientIBO);
193     }
194 
195     if (!m_emulatedClientVBOs.empty()) {
196         s_glDispatch.glDeleteBuffers(
197             m_emulatedClientVBOs.size(),
198             &m_emulatedClientVBOs[0]);
199     }
200 
201     deleteVAO(0);
202     delete m_transformFeedbackNameSpace;
203 }
204 
onSave(android::base::Stream * stream) const205 void GLESv2Context::onSave(android::base::Stream* stream) const {
206     GLEScontext::onSave(stream);
207     stream->write(m_attribute0value, sizeof(m_attribute0value));
208     stream->putByte(m_attribute0valueChanged);
209     stream->putBe32(m_att0ArrayLength);
210     stream->write(m_att0Array.get(), sizeof(GLfloat) * 4 * m_att0ArrayLength);
211     stream->putByte(m_att0NeedsDisable);
212     stream->putBe32(m_useProgram);
213     android::base::saveCollection(stream, m_bindSampler,
214             [](android::base::Stream* stream,
215                 const std::pair<const GLenum, GLuint>& item) {
216                 stream->putBe32(item.first);
217                 stream->putBe32(item.second);
218             });
219     m_transformFeedbackNameSpace->onSave(stream);
220 }
221 
addVertexArrayObject(GLuint array)222 void GLESv2Context::addVertexArrayObject(GLuint array) {
223     m_vaoStateMap[array] = VAOState(0, nullptr, kMaxVertexAttributes);
224 }
225 
enableArr(GLenum arrType,bool enable)226 void GLESv2Context::enableArr(GLenum arrType, bool enable) {
227     uint32_t index = (uint32_t)arrType;
228     if (index > kMaxVertexAttributes) return;
229     m_currVaoState.attribInfo()[index].enable(enable);
230 }
231 
getPointer(GLenum arrType)232 const GLESpointer* GLESv2Context::getPointer(GLenum arrType) {
233     uint32_t index = (uint32_t)arrType;
234     if (index > kMaxVertexAttributes) return nullptr;
235     return m_currVaoState.attribInfo().data() + index;
236 }
237 
postLoadRestoreCtx()238 void GLESv2Context::postLoadRestoreCtx() {
239     initExtensionString();
240     GLDispatch& dispatcher = GLEScontext::dispatcher();
241     m_useProgramData = shareGroup()->getObjectDataPtr(
242             NamedObjectType::SHADER_OR_PROGRAM, m_useProgram);
243     const GLuint globalProgramName = shareGroup()->getGlobalName(
244             NamedObjectType::SHADER_OR_PROGRAM, m_useProgram);
245     dispatcher.glUseProgram(globalProgramName);
246 
247     initEmulatedBuffers();
248     initEmulatedVAO();
249 
250     // vertex attribute pointers
251     for (const auto& vaoIte : m_vaoStateMap) {
252         if (vaoIte.first != 0) {
253             genVAOName(vaoIte.first, false);
254         }
255         dispatcher.glBindVertexArray(getVAOGlobalName(vaoIte.first));
256         for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
257             GLESpointer* glesPointer =
258                 (GLESpointer*)(vaoIte.second.vertexAttribInfo.data() + i);
259 
260             // don't skip enabling if the guest assumes it was enabled.
261             if (glesPointer->isEnable()) {
262                 dispatcher.glEnableVertexAttribArray(i);
263             }
264 
265             // attribute 0 are bound right before draw, no need to bind it here
266             if (glesPointer->getAttribType() == GLESpointer::VALUE
267                     && i == 0) {
268                 continue;
269             }
270             switch (glesPointer->getAttribType()) {
271                 case GLESpointer::BUFFER: {
272                     const GLuint globalBufferName = shareGroup()
273                             ->getGlobalName(NamedObjectType::VERTEXBUFFER,
274                                             glesPointer->getBufferName());
275                     if (!globalBufferName) {
276                         continue;
277                     }
278                     glesPointer->restoreBufferObj(getBufferObj);
279                     dispatcher.glBindBuffer(GL_ARRAY_BUFFER,
280                             globalBufferName);
281                     if (glesPointer->isIntPointer()) {
282                         dispatcher.glVertexAttribIPointer(i,
283                                 glesPointer->getSize(),
284                                 glesPointer->getType(),
285                                 glesPointer->getStride(),
286                                 (GLvoid*)(size_t)glesPointer->getBufferOffset());
287                     } else {
288                         dispatcher.glVertexAttribPointer(i,
289                                 glesPointer->getSize(),
290                                 glesPointer->getType(), glesPointer->isNormalize(),
291                                 glesPointer->getStride(),
292                                 (GLvoid*)(size_t)glesPointer->getBufferOffset());
293                     }
294                     break;
295                 }
296                 case GLESpointer::VALUE:
297                     switch (glesPointer->getValueCount()) {
298                         case 1:
299                             dispatcher.glVertexAttrib1fv(i,
300                                     glesPointer->getValues());
301                             break;
302                         case 2:
303                             dispatcher.glVertexAttrib2fv(i,
304                                     glesPointer->getValues());
305                             break;
306                         case 3:
307                             dispatcher.glVertexAttrib3fv(i,
308                                     glesPointer->getValues());
309                             break;
310                         case 4:
311                             dispatcher.glVertexAttrib4fv(i,
312                                     glesPointer->getValues());
313                             break;
314                     }
315                     break;
316                 case GLESpointer::ARRAY:
317                     // client arrays are set up right before draw calls
318                     // so we do nothing here
319                     break;
320             }
321         }
322         for (size_t i = 0; i < vaoIte.second.bindingState.size(); i++) {
323             const BufferBinding& bufferBinding = vaoIte.second.bindingState[i];
324             if (bufferBinding.divisor) {
325                 dispatcher.glVertexAttribDivisor(i, bufferBinding.divisor);
326             }
327         }
328     }
329     dispatcher.glBindVertexArray(getVAOGlobalName(m_currVaoState.vaoId()));
330     if (m_glesMajorVersion >= 3) {
331         auto bindBufferRangeFunc =
332                 [this](GLenum target,
333                     const std::vector<BufferBinding>& bufferBindings) {
334                     for (unsigned int i = 0; i < bufferBindings.size(); i++) {
335                         const BufferBinding& bd = bufferBindings[i];
336                         GLuint globalName = this->shareGroup()->getGlobalName(
337                                 NamedObjectType::VERTEXBUFFER,
338                                 bd.buffer);
339                         assert(bd.buffer == 0 || globalName != 0);
340                         if (bd.isBindBase || bd.buffer == 0) {
341                             this->dispatcher().glBindBufferBase(target,
342                                     i, globalName);
343                         } else {
344                             this->dispatcher().glBindBufferRange(target,
345                                     i, globalName, bd.offset, bd.size);
346                         }
347                     }
348                 };
349         bindBufferRangeFunc(GL_TRANSFORM_FEEDBACK_BUFFER,
350                 m_indexedTransformFeedbackBuffers);
351         bindBufferRangeFunc(GL_UNIFORM_BUFFER,
352                 m_indexedUniformBuffers);
353 
354         if (m_glesMinorVersion >= 1) {
355             bindBufferRangeFunc(GL_ATOMIC_COUNTER_BUFFER,
356                     m_indexedAtomicCounterBuffers);
357             bindBufferRangeFunc(GL_SHADER_STORAGE_BUFFER,
358                     m_indexedShaderStorageBuffers);
359         }
360 
361         // buffer bindings
362         auto bindBuffer = [this](GLenum target, GLuint buffer) {
363             this->dispatcher().glBindBuffer(target,
364                     m_shareGroup->getGlobalName(NamedObjectType::VERTEXBUFFER, buffer));
365         };
366         bindBuffer(GL_COPY_READ_BUFFER, m_copyReadBuffer);
367         bindBuffer(GL_COPY_WRITE_BUFFER, m_copyWriteBuffer);
368         bindBuffer(GL_PIXEL_PACK_BUFFER, m_pixelPackBuffer);
369         bindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixelUnpackBuffer);
370         bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_transformFeedbackBuffer);
371         bindBuffer(GL_UNIFORM_BUFFER, m_uniformBuffer);
372 
373         if (m_glesMinorVersion >= 1) {
374             bindBuffer(GL_ATOMIC_COUNTER_BUFFER, m_atomicCounterBuffer);
375             bindBuffer(GL_DISPATCH_INDIRECT_BUFFER, m_dispatchIndirectBuffer);
376             bindBuffer(GL_DRAW_INDIRECT_BUFFER, m_drawIndirectBuffer);
377             bindBuffer(GL_SHADER_STORAGE_BUFFER, m_shaderStorageBuffer);
378             if (getCaps()->textureBufferAny()) {
379                 bindBuffer(GL_TEXTURE_BUFFER, m_textureBuffer);
380             }
381         }
382         for (const auto& bindSampler : m_bindSampler) {
383             dispatcher.glBindSampler(bindSampler.first,
384                     shareGroup()->getGlobalName(NamedObjectType::SAMPLER,
385                         bindSampler.second));
386         }
387         m_transformFeedbackNameSpace->postLoadRestore(
388                 [this](NamedObjectType p_type, ObjectLocalName p_localName) {
389                     switch (p_type) {
390                         case NamedObjectType::FRAMEBUFFER:
391                             return getFBOGlobalName(p_localName);
392                         case NamedObjectType::TRANSFORM_FEEDBACK:
393                             return getTransformFeedbackGlobalName(p_localName);
394                         default:
395                             return m_shareGroup->getGlobalName(p_type,
396                                                                p_localName);
397                     }
398                 });
399         dispatcher.glBindTransformFeedback(
400                 GL_TRANSFORM_FEEDBACK,
401                 getTransformFeedbackGlobalName(m_transformFeedbackBuffer));
402     }
403 
404     GLEScontext::postLoadRestoreCtx();
405 }
406 
loadObject(NamedObjectType type,ObjectLocalName localName,android::base::Stream * stream) const407 ObjectDataPtr GLESv2Context::loadObject(NamedObjectType type,
408             ObjectLocalName localName, android::base::Stream* stream) const {
409     switch (type) {
410         case NamedObjectType::VERTEXBUFFER:
411         case NamedObjectType::TEXTURE:
412         case NamedObjectType::FRAMEBUFFER:
413         case NamedObjectType::RENDERBUFFER:
414             return GLEScontext::loadObject(type, localName, stream);
415         case NamedObjectType::SAMPLER:
416             return ObjectDataPtr(new SamplerData(stream));
417         case NamedObjectType::SHADER_OR_PROGRAM:
418             // load the first bit to see if it is a program or shader
419             switch (stream->getByte()) {
420                 case LOAD_PROGRAM:
421                     return ObjectDataPtr(new ProgramData(stream));
422                 case LOAD_SHADER:
423                     return ObjectDataPtr(new ShaderParser(stream));
424                 default:
425                     fprintf(stderr, "corrupted snapshot\n");
426                     assert(false);
427                     return nullptr;
428             }
429         case NamedObjectType::TRANSFORM_FEEDBACK:
430             return ObjectDataPtr(new TransformFeedbackData(stream));
431         default:
432             return nullptr;
433     }
434 }
435 
setAttribValue(int idx,unsigned int count,const GLfloat * val)436 void GLESv2Context::setAttribValue(int idx, unsigned int count,
437         const GLfloat* val) {
438     m_currVaoState.attribInfo()[idx].setValue(count, val);
439 }
440 
setAttribute0value(float x,float y,float z,float w)441 void GLESv2Context::setAttribute0value(float x, float y, float z, float w)
442 {
443     m_attribute0valueChanged |=
444             x != m_attribute0value[0] || y != m_attribute0value[1] ||
445             z != m_attribute0value[2] || w != m_attribute0value[3];
446     m_attribute0value[0] = x;
447     m_attribute0value[1] = y;
448     m_attribute0value[2] = z;
449     m_attribute0value[3] = w;
450 }
451 
needAtt0PreDrawValidation()452 bool GLESv2Context::needAtt0PreDrawValidation()
453 {
454     m_att0NeedsDisable = false;
455 
456     // We could go into the driver here and call
457     //      s_glDispatch.glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled)
458     // ... but it's too much for a simple check that runs on almost every draw
459     // call.
460     return !isArrEnabled(0);
461 }
462 
validateAtt0PreDraw(unsigned int count)463 void GLESv2Context::validateAtt0PreDraw(unsigned int count)
464 {
465     if (count == 0) {
466         return;
467     }
468 
469     if (count > m_att0ArrayLength) {
470         const unsigned newLen = std::max(count, 2 * m_att0ArrayLength);
471         m_att0Array.reset(new GLfloat[4 * newLen]);
472         m_att0ArrayLength = newLen;
473         m_attribute0valueChanged = true;
474     }
475     if (m_attribute0valueChanged) {
476         for(unsigned int i = 0; i<m_att0ArrayLength; i++) {
477             memcpy(m_att0Array.get()+i*4, m_attribute0value,
478                     sizeof(m_attribute0value));
479         }
480         m_attribute0valueChanged = false;
481     }
482 
483     GLuint prevArrayBuffer;
484     s_glDispatch.glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&prevArrayBuffer);
485 
486     s_glDispatch.glBindBuffer(GL_ARRAY_BUFFER, m_emulatedClientVBOs[0]);
487     s_glDispatch.glBufferData(GL_ARRAY_BUFFER, m_att0ArrayLength * sizeof(GLfloat), m_att0Array.get(), GL_STREAM_DRAW);
488 
489     s_glDispatch.glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
490     s_glDispatch.glEnableVertexAttribArray(0);
491 
492     s_glDispatch.glBindBuffer(GL_ARRAY_BUFFER, prevArrayBuffer);
493 
494     m_att0NeedsDisable = true;
495 }
496 
validateAtt0PostDraw(void)497 void GLESv2Context::validateAtt0PostDraw(void)
498 {
499     if (m_att0NeedsDisable) {
500         s_glDispatch.glDisableVertexAttribArray(0);
501         m_att0NeedsDisable = false;
502     }
503 }
504 
drawWithEmulations(DrawCallCmd cmd,GLenum mode,GLint first,GLsizei count,GLenum type,const GLvoid * indices,GLsizei primcount,GLuint start,GLuint end)505 void GLESv2Context::drawWithEmulations(
506     DrawCallCmd cmd,
507     GLenum mode,
508     GLint first,
509     GLsizei count,
510     GLenum type,
511     const GLvoid* indices,
512     GLsizei primcount,
513     GLuint start,
514     GLuint end) {
515 
516     if (getMajorVersion() < 3) {
517         drawValidate();
518     }
519 
520     bool needClientVBOSetup = !vertexAttributesBufferBacked();
521 
522     bool needClientIBOSetup =
523         (cmd != DrawCallCmd::Arrays &&
524          cmd != DrawCallCmd::ArraysInstanced) &&
525         !isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER);
526     bool needPointEmulation = mode == GL_POINTS && !isGles2Gles();
527 
528 #ifdef __APPLE__
529     if (!isGles2Gles() && primitiveRestartEnabled() && type) {
530         updatePrimitiveRestartIndex(type);
531     }
532 #endif
533 
534     if (needPointEmulation) {
535         s_glDispatch.glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
536         if (!isCoreProfile()) {
537             // Enable texture generation for GL_POINTS and gl_PointSize shader variable
538             // GLES2 assumes this is enabled by default, we need to set this state for GL
539             s_glDispatch.glEnable(GL_POINT_SPRITE);
540         }
541     }
542 
543     bool needEnablingPostDraw[kMaxVertexAttributes];
544     memset(needEnablingPostDraw, 0, sizeof(needEnablingPostDraw));
545 
546     if (needClientVBOSetup) {
547         GLESConversionArrays tmpArrs;
548         bool needPauseTransformFeedback = boundTransformFeedback()
549                 && boundTransformFeedback()->mIsActive
550                 && !boundTransformFeedback()->mIsPaused;
551         if (needPauseTransformFeedback) {
552             s_glDispatch.glPauseTransformFeedback();
553         }
554         setupArraysPointers(tmpArrs, 0, count, type, indices, false, needEnablingPostDraw);
555         if (needPauseTransformFeedback) {
556             s_glDispatch.glResumeTransformFeedback();
557         }
558         if (needAtt0PreDrawValidation()) {
559             if (indices) {
560                 validateAtt0PreDraw(findMaxIndex(count, type, indices));
561             } else {
562                 validateAtt0PreDraw(count);
563             }
564         }
565     }
566 
567     GLuint prevIBO;
568     if (needClientIBOSetup) {
569         int bpv = 2;
570         switch (type) {
571             case GL_UNSIGNED_BYTE:
572                 bpv = 1;
573                 break;
574             case GL_UNSIGNED_SHORT:
575                 bpv = 2;
576                 break;
577             case GL_UNSIGNED_INT:
578                 bpv = 4;
579                 break;
580         }
581 
582         size_t dataSize = bpv * count;
583 
584         s_glDispatch.glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&prevIBO);
585         s_glDispatch.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_emulatedClientIBO);
586         s_glDispatch.glBufferData(GL_ELEMENT_ARRAY_BUFFER, dataSize, indices, GL_STREAM_DRAW);
587     }
588 
589     const GLvoid* indicesOrOffset =
590         needClientIBOSetup ? nullptr : indices;
591 
592     switch (cmd) {
593         case DrawCallCmd::Elements:
594             s_glDispatch.glDrawElements(mode, count, type, indicesOrOffset);
595             break;
596         case DrawCallCmd::ElementsInstanced:
597             s_glDispatch.glDrawElementsInstanced(mode, count, type,
598                                                  indicesOrOffset,
599                                                  primcount);
600             break;
601         case DrawCallCmd::RangeElements:
602             s_glDispatch.glDrawRangeElements(mode, start, end, count, type,
603                                              indicesOrOffset);
604             break;
605         case DrawCallCmd::Arrays:
606             s_glDispatch.glDrawArrays(mode, first, count);
607             break;
608         case DrawCallCmd::ArraysInstanced:
609             s_glDispatch.glDrawArraysInstanced(mode, first, count, primcount);
610             break;
611         default:
612             emugl::emugl_crash_reporter(
613                 "drawWithEmulations has corrupt call parameters!");
614     }
615 
616     if (needClientIBOSetup) {
617         s_glDispatch.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prevIBO);
618     }
619 
620     if (needClientVBOSetup) {
621         validateAtt0PostDraw();
622     }
623 
624     if (needPointEmulation) {
625         s_glDispatch.glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
626         if (!isCoreProfile()) {
627             s_glDispatch.glDisable(GL_POINT_SPRITE);
628         }
629     }
630 
631     for (int i = 0; i < kMaxVertexAttributes; ++i) {
632         if (needEnablingPostDraw[i]) {
633             s_glDispatch.glEnableVertexAttribArray(i);
634         }
635     }
636 }
637 
setupArraysPointers(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,bool * needEnablingPostDraw)638 void GLESv2Context::setupArraysPointers(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct, bool* needEnablingPostDraw) {
639     //going over all clients arrays Pointers
640     for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
641         GLESpointer* p = m_currVaoState.attribInfo().data() + i;
642         if (!p->isEnable() || p->getAttribType() == GLESpointer::VALUE) {
643             continue;
644         }
645 
646         setupArrWithDataSize(
647             p->getDataSize(),
648             p->getArrayData(),
649             i,
650             p->getType(),
651             p->getSize(),
652             p->getStride(),
653             p->getNormalized(),
654             -1,
655             p->isIntPointer(),
656             p->getBufferName(),
657             needEnablingPostDraw);
658     }
659 }
660 
661 //setting client side arr
setupArrWithDataSize(GLsizei datasize,const GLvoid * arr,GLenum arrayType,GLenum dataType,GLint size,GLsizei stride,GLboolean normalized,int index,bool isInt,GLuint ptrBufferName,bool * needEnablingPostDraw)662 void GLESv2Context::setupArrWithDataSize(GLsizei datasize, const GLvoid* arr,
663                                          GLenum arrayType, GLenum dataType,
664                                          GLint size, GLsizei stride, GLboolean normalized, int index, bool isInt, GLuint ptrBufferName, bool* needEnablingPostDraw){
665     // is not really a client side arr.
666     if (arr == NULL) {
667         GLint isEnabled;
668         s_glDispatch.glGetVertexAttribiv((int)arrayType, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &isEnabled);
669         if (isEnabled && !ptrBufferName) {
670             s_glDispatch.glDisableVertexAttribArray(arrayType);
671             if (needEnablingPostDraw)
672                 needEnablingPostDraw[arrayType] = true;
673         }
674 
675         return;
676     }
677 
678     GLuint prevArrayBuffer;
679     s_glDispatch.glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&prevArrayBuffer);
680 
681     if (arrayType < m_emulatedClientVBOs.size()) {
682         s_glDispatch.glBindBuffer(GL_ARRAY_BUFFER, m_emulatedClientVBOs[arrayType]);
683     } else {
684         fprintf(stderr, "%s: invalid attribute index: %d\n", __func__, (int)arrayType);
685     }
686 
687     s_glDispatch.glBufferData(GL_ARRAY_BUFFER, datasize, arr, GL_STREAM_DRAW);
688 
689     if (isInt) {
690         s_glDispatch.glVertexAttribIPointer(arrayType, size, dataType, stride, 0);
691     } else {
692         s_glDispatch.glVertexAttribPointer(arrayType, size, dataType, normalized, stride, 0);
693     }
694 
695     s_glDispatch.glBindBuffer(GL_ARRAY_BUFFER, prevArrayBuffer);
696 }
697 
setVertexAttribDivisor(GLuint bindingindex,GLuint divisor)698 void GLESv2Context::setVertexAttribDivisor(GLuint bindingindex, GLuint divisor) {
699     if (bindingindex >= m_currVaoState.bufferBindings().size()) {
700         return;
701     }
702     m_currVaoState.bufferBindings()[bindingindex].divisor = divisor;
703 }
704 
setVertexAttribBindingIndex(GLuint attribindex,GLuint bindingindex)705 void GLESv2Context::setVertexAttribBindingIndex(GLuint attribindex, GLuint bindingindex) {
706     if (attribindex > kMaxVertexAttributes) return;
707 
708     m_currVaoState.attribInfo()[attribindex].setBindingIndex(bindingindex);
709 }
710 
setVertexAttribFormat(GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint reloffset,bool isInt)711 void GLESv2Context::setVertexAttribFormat(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
712     if (attribindex > kMaxVertexAttributes) return;
713     m_currVaoState.attribInfo()[attribindex].setFormat(size, type, normalized == GL_TRUE, reloffset, isInt);
714 }
715 
setBindSampler(GLuint unit,GLuint sampler)716 void GLESv2Context::setBindSampler(GLuint unit, GLuint sampler) {
717     m_bindSampler[unit] = sampler;
718 }
719 
needConvert(GLESConversionArrays & cArrs,GLint first,GLsizei count,GLenum type,const GLvoid * indices,bool direct,GLESpointer * p,GLenum array_id)720 bool GLESv2Context::needConvert(GLESConversionArrays& cArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id) {
721 
722     bool usingVBO = p->getAttribType() == GLESpointer::BUFFER;
723     GLenum arrType = p->getType();
724 
725     /*
726      conversion is not necessary in the following cases:
727       (*) array type is not fixed
728     */
729     if(arrType != GL_FIXED) return false;
730 
731     if(!usingVBO) {
732         if (direct) {
733             convertDirect(cArrs,first,count,array_id,p);
734         } else {
735             convertIndirect(cArrs,count,type,indices,array_id,p);
736         }
737     } else {
738         if (direct) {
739             convertDirectVBO(cArrs,first,count,array_id,p);
740         } else {
741             convertIndirectVBO(cArrs,count,type,indices,array_id,p);
742         }
743     }
744     return true;
745 }
746 
setUseProgram(GLuint program,const ObjectDataPtr & programData)747 void GLESv2Context::setUseProgram(GLuint program,
748         const ObjectDataPtr& programData) {
749     m_useProgram = program;
750     assert(!programData ||
751             programData->getDataType() == ObjectDataType::PROGRAM_DATA);
752     m_useProgramData = programData;
753 }
754 
getCurrentProgram() const755 GLuint GLESv2Context::getCurrentProgram() const {
756     return m_useProgram;
757 }
758 
getUseProgram()759 ProgramData* GLESv2Context::getUseProgram() {
760     return (ProgramData*)m_useProgramData.get();
761 }
762 
763 
InitExtensionString(GLSupport & glSupport,std::string & ext)764 void InitExtensionString(GLSupport& glSupport, std::string& ext) {
765     ext =
766         "GL_OES_EGL_sync GL_OES_EGL_image GL_OES_EGL_image_external GL_OES_depth24 GL_OES_depth32 "
767         "GL_OES_element_index_uint "
768         "GL_OES_texture_float GL_OES_texture_float_linear "
769         "GL_OES_compressed_paletted_texture GL_OES_compressed_ETC1_RGB8_texture "
770         "GL_OES_depth_texture ";
771     if (glSupport.GL_ARB_HALF_FLOAT_PIXEL || glSupport.GL_NV_HALF_FLOAT)
772         ext += "GL_OES_texture_half_float GL_OES_texture_half_float_linear ";
773     if (glSupport.GL_EXT_PACKED_DEPTH_STENCIL) ext += "GL_OES_packed_depth_stencil ";
774     if (glSupport.GL_ARB_HALF_FLOAT_VERTEX) ext += "GL_OES_vertex_half_float ";
775     if (glSupport.GL_OES_STANDARD_DERIVATIVES) ext += "GL_OES_standard_derivatives ";
776     if (glSupport.GL_OES_TEXTURE_NPOT) ext += "GL_OES_texture_npot ";
777     if (glSupport.GL_OES_RGB8_RGBA8) ext += "GL_OES_rgb8_rgba8 ";
778     if (glSupport.ext_GL_OVR_multiview2) ext += "GL_OVR_multiview2 ";
779     if (glSupport.ext_GL_EXT_multiview_texture_multisample) ext += "GL_EXT_multiview_texture_multisample ";
780     if (glSupport.ext_GL_EXT_color_buffer_float) ext += "GL_EXT_color_buffer_float ";
781     if (glSupport.ext_GL_EXT_color_buffer_half_float) ext += "GL_EXT_color_buffer_half_float ";
782     // b/203446380
783     // Does not really work on hardware GPUs
784     if (glSupport.ext_GL_EXT_shader_framebuffer_fetch && isGles2Gles()) ext += "GL_EXT_shader_framebuffer_fetch ";
785     if (glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888) {
786         ext += "GL_EXT_texture_format_BGRA8888 GL_APPLE_texture_format_BGRA8888 ";
787     }
788     if (glSupport.ext_GL_EXT_texture_buffer) {
789         ext += "GL_EXT_texture_buffer ";
790     }
791     if (glSupport.ext_GL_OES_texture_buffer) {
792         ext += "GL_OES_texture_buffer ";
793     }
794     if (glSupport.ext_GL_EXT_draw_buffers_indexed) {
795         ext += "GL_EXT_draw_buffers_indexed ";
796     }
797     if (glSupport.ext_GL_EXT_clip_cull_distance) {
798         ext += "GL_EXT_clip_cull_distance ";
799     }
800 }
801 
initExtensionString()802 void GLESv2Context::initExtensionString() {
803     if (m_glesMajorVersion == 3 && m_glesMinorVersion == 1) {
804         if (s_glExtensionsGles31Initialized) return;
805         initCapsLocked((const GLubyte*)getHostExtensionsString(&s_glDispatch).c_str(),
806                        m_nativeTextureDecompressionEnabled, s_glSupportGles31);
807         InitExtensionString(s_glSupportGles31, *s_glExtensionsGles31);
808         s_glExtensionsGles31Initialized = true;
809     } else {
810         if (s_glExtensionsInitialized) return;
811         initCapsLocked((const GLubyte*)getHostExtensionsString(&s_glDispatch).c_str(),
812                        m_nativeTextureDecompressionEnabled, s_glSupport);
813         InitExtensionString(s_glSupport, *s_glExtensions);
814         s_glExtensionsInitialized = true;
815     }
816 }
817 
getMaxTexUnits()818 int GLESv2Context::getMaxTexUnits() {
819     return getCaps()->maxTexImageUnits;
820 }
821 
getMaxCombinedTexUnits()822 int GLESv2Context::getMaxCombinedTexUnits() {
823     return getCaps()->maxCombinedTexImageUnits;
824 }
825 
getTransformFeedbackGlobalName(ObjectLocalName p_localName)826 unsigned int GLESv2Context::getTransformFeedbackGlobalName(
827         ObjectLocalName p_localName) {
828     return m_transformFeedbackNameSpace->getGlobalName(p_localName);
829 }
830 
hasBoundTransformFeedback(ObjectLocalName transformFeedback)831 bool GLESv2Context::hasBoundTransformFeedback(
832         ObjectLocalName transformFeedback) {
833     return transformFeedback &&
834            m_transformFeedbackNameSpace->getObjectDataPtr(transformFeedback)
835                    .get();
836 }
837 
genTransformFeedbackName(ObjectLocalName p_localName,bool genLocal)838 ObjectLocalName GLESv2Context::genTransformFeedbackName(
839         ObjectLocalName p_localName,
840         bool genLocal) {
841     return m_transformFeedbackNameSpace->genName(
842             GenNameInfo(NamedObjectType::TRANSFORM_FEEDBACK), p_localName,
843             genLocal);
844 }
845 
bindTransformFeedback(ObjectLocalName p_localName)846 void GLESv2Context::bindTransformFeedback(ObjectLocalName p_localName) {
847     if (m_transformFeedbackDeletePending &&
848         m_bindTransformFeedback != p_localName) {
849         m_transformFeedbackNameSpace->deleteName(m_bindTransformFeedback);
850         m_transformFeedbackDeletePending = false;
851     }
852     m_bindTransformFeedback = p_localName;
853     if (p_localName &&
854         !m_transformFeedbackNameSpace->getGlobalName(p_localName)) {
855         genTransformFeedbackName(p_localName, false);
856     }
857     if (p_localName &&
858         !m_transformFeedbackNameSpace->getObjectDataPtr(p_localName).get()) {
859         TransformFeedbackData* tf = new TransformFeedbackData();
860         tf->setMaxSize(getCaps()->maxTransformFeedbackSeparateAttribs);
861         m_transformFeedbackNameSpace->setObjectData(p_localName,
862                                                     ObjectDataPtr(tf));
863     }
864 }
865 
getTransformFeedbackBinding()866 ObjectLocalName GLESv2Context::getTransformFeedbackBinding() {
867     return m_bindTransformFeedback;
868 }
869 
deleteTransformFeedback(ObjectLocalName p_localName)870 void GLESv2Context::deleteTransformFeedback(ObjectLocalName p_localName) {
871     // Note: GLES3.0 says it should be pending for delete if it is active
872     // GLES3.2 says report error in this situation
873     if (m_bindTransformFeedback == p_localName) {
874         m_transformFeedbackDeletePending = true;
875         return;
876     }
877     m_transformFeedbackNameSpace->deleteName(p_localName);
878 }
879 
boundTransformFeedback()880 TransformFeedbackData* GLESv2Context::boundTransformFeedback() {
881     return (TransformFeedbackData*)m_transformFeedbackNameSpace
882             ->getObjectDataPtr(m_bindTransformFeedback)
883             .get();
884 }
885 
getIndexedBuffer(GLenum target,GLuint index)886 GLuint GLESv2Context::getIndexedBuffer(GLenum target, GLuint index) {
887     switch (target) {
888         case GL_TRANSFORM_FEEDBACK_BUFFER:
889             return boundTransformFeedback()->getIndexedBuffer(index);
890         default:
891             return GLEScontext::getIndexedBuffer(target, index);
892     }
893 }
894 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer,GLintptr offset,GLsizeiptr size,GLintptr stride,bool isBindBase)895 void GLESv2Context::bindIndexedBuffer(GLenum target,
896                                       GLuint index,
897                                       GLuint buffer,
898                                       GLintptr offset,
899                                       GLsizeiptr size,
900                                       GLintptr stride,
901                                       bool isBindBase) {
902     switch (target) {
903         case GL_TRANSFORM_FEEDBACK_BUFFER: {
904             TransformFeedbackData* tf = boundTransformFeedback();
905             tf->bindIndexedBuffer(index, buffer, offset, size, stride,
906                                   isBindBase);
907             break;
908         }
909         default:
910             GLEScontext::bindIndexedBuffer(target, index, buffer, offset, size,
911                                            stride, isBindBase);
912     }
913 }
914 
bindIndexedBuffer(GLenum target,GLuint index,GLuint buffer)915 void GLESv2Context::bindIndexedBuffer(GLenum target,
916                                       GLuint index,
917                                       GLuint buffer) {
918     GLEScontext::bindIndexedBuffer(target, index, buffer);
919 }
920 
unbindBuffer(GLuint buffer)921 void GLESv2Context::unbindBuffer(GLuint buffer) {
922     if (m_glesMajorVersion >= 3) {
923         boundTransformFeedback()->unbindBuffer(buffer);
924     }
925     GLEScontext::unbindBuffer(buffer);
926 }
927