• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include "GLESv2Decoder.h"
18 #include "OpenGLESDispatch/GLESv2Dispatch.h"
19 
20 #include "aemu/base/synchronization/Lock.h"
21 
22 #include "host-common/emugl_vm_operations.h"
23 #include "host-common/vm_operations.h"
24 #include "host-common/dma_device.h"
25 
26 #include <EGL/egl.h>
27 #include <GLES2/gl2.h>
28 #include <GLES2/gl2ext.h>
29 #include <GLES3/gl3.h>
30 #include <GLES3/gl31.h>
31 
32 #include <string>
33 #include <vector>
34 
35 #include <string.h>
36 
37 namespace gfxstream {
38 namespace gl {
39 
40 using android::base::AutoLock;
41 using android::base::StaticLock;
42 
SafePointerFromUInt(GLuint value)43 static inline void* SafePointerFromUInt(GLuint value) {
44   return (void*)(uintptr_t)value;
45 }
46 
initDispatch(GLESv2Decoder::get_proc_func_t getProc,void * userData)47 int gles2_decoder_extended_context::initDispatch(
48         GLESv2Decoder::get_proc_func_t getProc, void *userData) {
49     gles2_server_context_t::initDispatchByName(getProc, userData);
50     glVertexAttribPointerWithDataSize =
51             (glVertexAttribPointerWithDataSize_server_proc_t)
52             getProc("glVertexAttribPointerWithDataSize", userData);
53     glVertexAttribIPointerWithDataSize =
54             (glVertexAttribIPointerWithDataSize_server_proc_t)
55             getProc("glVertexAttribIPointerWithDataSize", userData);
56     return 0;
57 }
58 
59 static StaticLock sLock;
60 static GLESv2Decoder::get_proc_func_t sGetProcFunc;
61 static void* sGetProcFuncData;
62 
63 namespace {
64 
65 struct ContextTemplateLoader {
ContextTemplateLoadergfxstream::gl::__anonf43de79c0111::ContextTemplateLoader66     ContextTemplateLoader() {
67         context.initDispatch(sGetProcFunc, sGetProcFuncData);
68     }
69     gles2_decoder_extended_context context;
70 };
71 
72 }  // namespace
73 
sContextTemplate()74 static ContextTemplateLoader* sContextTemplate() {
75     static ContextTemplateLoader* c = new ContextTemplateLoader;
76     return c;
77 }
78 
GLESv2Decoder()79 GLESv2Decoder::GLESv2Decoder()
80 {
81     m_contextData = NULL;
82     m_GL2library = NULL;
83     m_snapshot = NULL;
84 }
85 
~GLESv2Decoder()86 GLESv2Decoder::~GLESv2Decoder()
87 {
88 }
89 
s_getProc(const char * name,void * userData)90 void *GLESv2Decoder::s_getProc(const char *name, void *userData)
91 {
92     GLESv2Decoder *ctx = (GLESv2Decoder *) userData;
93 
94     if (ctx == NULL || ctx->m_GL2library == NULL) {
95         return NULL;
96     }
97 
98     void *func = NULL;
99 #ifdef USE_EGL_GETPROCADDRESS
100     func = (void *) eglGetProcAddress(name);
101 #endif
102     if (func == NULL) {
103         func = (void *) ctx->m_GL2library->findSymbol(name);
104     }
105     return func;
106 }
107 
108 #define OVERRIDE_DEC(func) func##_dec = s_##func;
109 
initGL(get_proc_func_t getProcFunc,void * getProcFuncData)110 int GLESv2Decoder::initGL(get_proc_func_t getProcFunc, void *getProcFuncData)
111 {
112     AutoLock lock(sLock);
113     sGetProcFunc = getProcFunc;
114     sGetProcFuncData = getProcFuncData;
115     static_cast<gles2_decoder_extended_context&>(*this) = sContextTemplate()->context;
116 
117     glGetCompressedTextureFormats = s_glGetCompressedTextureFormats;
118     glVertexAttribPointerData = s_glVertexAttribPointerData;
119     glVertexAttribPointerOffset = s_glVertexAttribPointerOffset;
120     glShaderString = s_glShaderString;
121 
122     glDrawElementsOffset = s_glDrawElementsOffset;
123     glDrawElementsData = s_glDrawElementsData;
124     glDrawElementsOffsetNullAEMU = s_glDrawElementsOffsetNullAEMU;
125     glDrawElementsDataNullAEMU = s_glDrawElementsDataNullAEMU;
126     glFinishRoundTrip = s_glFinishRoundTrip;
127     glMapBufferRangeAEMU = s_glMapBufferRangeAEMU;
128     glUnmapBufferAEMU = s_glUnmapBufferAEMU;
129     glMapBufferRangeDMA = s_glMapBufferRangeDMA;
130     glUnmapBufferDMA = s_glUnmapBufferDMA;
131     glFlushMappedBufferRangeAEMU = s_glFlushMappedBufferRangeAEMU;
132     glMapBufferRangeDirect = s_glMapBufferRangeDirect;
133     glUnmapBufferDirect = s_glUnmapBufferDirect;
134     glFlushMappedBufferRangeDirect = s_glFlushMappedBufferRangeDirect;
135     glCompressedTexImage2DOffsetAEMU = s_glCompressedTexImage2DOffsetAEMU;
136     glCompressedTexSubImage2DOffsetAEMU = s_glCompressedTexSubImage2DOffsetAEMU;
137     glTexImage2DOffsetAEMU = s_glTexImage2DOffsetAEMU;
138     glTexSubImage2DOffsetAEMU = s_glTexSubImage2DOffsetAEMU;
139     glGetUniformIndicesAEMU = s_glGetUniformIndicesAEMU;
140     glVertexAttribIPointerDataAEMU = s_glVertexAttribIPointerDataAEMU;
141     glVertexAttribIPointerOffsetAEMU = s_glVertexAttribIPointerOffsetAEMU;
142     glTransformFeedbackVaryingsAEMU = s_glTransformFeedbackVaryingsAEMU;
143     glTexImage3DOffsetAEMU = s_glTexImage3DOffsetAEMU;
144     glTexSubImage3DOffsetAEMU = s_glTexSubImage3DOffsetAEMU;
145     glCompressedTexImage3DOffsetAEMU = s_glCompressedTexImage3DOffsetAEMU;
146     glCompressedTexSubImage3DOffsetAEMU = s_glCompressedTexSubImage3DOffsetAEMU;
147     glDrawElementsInstancedOffsetAEMU = s_glDrawElementsInstancedOffsetAEMU;
148     glDrawElementsInstancedDataAEMU = s_glDrawElementsInstancedDataAEMU;
149     glReadPixelsOffsetAEMU = s_glReadPixelsOffsetAEMU;
150 
151     glCreateShaderProgramvAEMU = s_glCreateShaderProgramvAEMU;
152 
153     glDrawArraysIndirectDataAEMU = s_glDrawArraysIndirectDataAEMU;
154     glDrawArraysIndirectOffsetAEMU = s_glDrawArraysIndirectOffsetAEMU;
155 
156     glDrawElementsIndirectDataAEMU = s_glDrawElementsIndirectDataAEMU;
157     glDrawElementsIndirectOffsetAEMU = s_glDrawElementsIndirectOffsetAEMU;
158 
159     glFenceSyncAEMU = s_glFenceSyncAEMU;
160     glClientWaitSyncAEMU = s_glClientWaitSyncAEMU;
161     glWaitSyncAEMU = s_glWaitSyncAEMU;
162     glIsSyncAEMU = s_glIsSyncAEMU;
163     glGetSyncivAEMU = s_glGetSyncivAEMU;
164     glDeleteSyncAEMU = s_glDeleteSyncAEMU;
165 
166     glBufferDataSyncAEMU = s_glBufferDataSyncAEMU;
167 
168     OVERRIDE_DEC(glCreateShader)
169     OVERRIDE_DEC(glCreateProgram)
170 
171     OVERRIDE_DEC(glGenBuffers)
172 
173     OVERRIDE_DEC(glGenFramebuffers)
174     OVERRIDE_DEC(glGenRenderbuffers)
175     OVERRIDE_DEC(glGenTextures)
176 
177     OVERRIDE_DEC(glGenVertexArraysOES)
178     OVERRIDE_DEC(glGenVertexArrays)
179 
180     OVERRIDE_DEC(glGenTransformFeedbacks)
181     OVERRIDE_DEC(glGenSamplers)
182     OVERRIDE_DEC(glGenQueries)
183     OVERRIDE_DEC(glGenProgramPipelines)
184 
185     OVERRIDE_DEC(glDeleteShader)
186     OVERRIDE_DEC(glDeleteProgram)
187 
188     OVERRIDE_DEC(glDeleteBuffers)
189     OVERRIDE_DEC(glDeleteFramebuffers)
190     OVERRIDE_DEC(glDeleteRenderbuffers)
191     OVERRIDE_DEC(glDeleteTextures)
192 
193     OVERRIDE_DEC(glDeleteVertexArraysOES)
194     OVERRIDE_DEC(glDeleteVertexArrays)
195 
196     OVERRIDE_DEC(glDeleteTransformFeedbacks)
197     OVERRIDE_DEC(glDeleteSamplers)
198     OVERRIDE_DEC(glDeleteQueries)
199     OVERRIDE_DEC(glDeleteProgramPipelines)
200 
201     // Shaders and programs
202     OVERRIDE_DEC(glCompileShader)
203     OVERRIDE_DEC(glAttachShader)
204     OVERRIDE_DEC(glDetachShader)
205     OVERRIDE_DEC(glLinkProgram)
206     OVERRIDE_DEC(glUseProgram)
207     OVERRIDE_DEC(glValidateProgram)
208     OVERRIDE_DEC(glIsShader)
209     OVERRIDE_DEC(glIsProgram)
210     OVERRIDE_DEC(glGetShaderiv)
211     OVERRIDE_DEC(glGetProgramiv)
212     OVERRIDE_DEC(glGetShaderInfoLog)
213     OVERRIDE_DEC(glGetProgramInfoLog)
214     OVERRIDE_DEC(glGetShaderSource)
215     OVERRIDE_DEC(glBindAttribLocation)
216     OVERRIDE_DEC(glGetActiveAttrib)
217     OVERRIDE_DEC(glGetActiveUniform)
218     OVERRIDE_DEC(glGetAttachedShaders)
219     OVERRIDE_DEC(glGetAttribLocation)
220     OVERRIDE_DEC(glGetUniformfv)
221     OVERRIDE_DEC(glGetUniformiv)
222     OVERRIDE_DEC(glGetUniformLocation)
223     OVERRIDE_DEC(glGetProgramBinaryOES)
224     OVERRIDE_DEC(glProgramBinaryOES)
225     OVERRIDE_DEC(glUniformBlockBinding)
226     OVERRIDE_DEC(glGetUniformBlockIndex)
227     OVERRIDE_DEC(glGetActiveUniformBlockiv)
228     OVERRIDE_DEC(glGetActiveUniformBlockName)
229     OVERRIDE_DEC(glGetUniformuiv)
230     OVERRIDE_DEC(glGetActiveUniformsiv)
231     OVERRIDE_DEC(glTransformFeedbackVaryings)
232     OVERRIDE_DEC(glGetTransformFeedbackVarying)
233     OVERRIDE_DEC(glProgramParameteri)
234     OVERRIDE_DEC(glProgramBinary)
235     OVERRIDE_DEC(glGetProgramBinary)
236     OVERRIDE_DEC(glGetFragDataLocation)
237     OVERRIDE_DEC(glUseProgramStages)
238     OVERRIDE_DEC(glActiveShaderProgram)
239     OVERRIDE_DEC(glProgramUniform1f)
240     OVERRIDE_DEC(glProgramUniform2f)
241     OVERRIDE_DEC(glProgramUniform3f)
242     OVERRIDE_DEC(glProgramUniform4f)
243     OVERRIDE_DEC(glProgramUniform1i)
244     OVERRIDE_DEC(glProgramUniform2i)
245     OVERRIDE_DEC(glProgramUniform3i)
246     OVERRIDE_DEC(glProgramUniform4i)
247     OVERRIDE_DEC(glProgramUniform1ui)
248     OVERRIDE_DEC(glProgramUniform2ui)
249     OVERRIDE_DEC(glProgramUniform3ui)
250     OVERRIDE_DEC(glProgramUniform4ui)
251     OVERRIDE_DEC(glProgramUniform1fv)
252     OVERRIDE_DEC(glProgramUniform2fv)
253     OVERRIDE_DEC(glProgramUniform3fv)
254     OVERRIDE_DEC(glProgramUniform4fv)
255     OVERRIDE_DEC(glProgramUniform1iv)
256     OVERRIDE_DEC(glProgramUniform2iv)
257     OVERRIDE_DEC(glProgramUniform3iv)
258     OVERRIDE_DEC(glProgramUniform4iv)
259     OVERRIDE_DEC(glProgramUniform1uiv)
260     OVERRIDE_DEC(glProgramUniform2uiv)
261     OVERRIDE_DEC(glProgramUniform3uiv)
262     OVERRIDE_DEC(glProgramUniform4uiv)
263     OVERRIDE_DEC(glProgramUniformMatrix2fv)
264     OVERRIDE_DEC(glProgramUniformMatrix3fv)
265     OVERRIDE_DEC(glProgramUniformMatrix4fv)
266     OVERRIDE_DEC(glProgramUniformMatrix2x3fv)
267     OVERRIDE_DEC(glProgramUniformMatrix3x2fv)
268     OVERRIDE_DEC(glProgramUniformMatrix2x4fv)
269     OVERRIDE_DEC(glProgramUniformMatrix4x2fv)
270     OVERRIDE_DEC(glProgramUniformMatrix3x4fv)
271     OVERRIDE_DEC(glProgramUniformMatrix4x3fv)
272     OVERRIDE_DEC(glGetProgramInterfaceiv)
273     OVERRIDE_DEC(glGetProgramResourceiv)
274     OVERRIDE_DEC(glGetProgramResourceIndex)
275     OVERRIDE_DEC(glGetProgramResourceLocation)
276     OVERRIDE_DEC(glGetProgramResourceName)
277     OVERRIDE_DEC(glTexBufferOES)
278     OVERRIDE_DEC(glTexBufferRangeOES)
279     OVERRIDE_DEC(glTexBufferEXT)
280     OVERRIDE_DEC(glTexBufferRangeEXT)
281     OVERRIDE_DEC(glEnableiEXT);
282     OVERRIDE_DEC(glDisableiEXT);
283     OVERRIDE_DEC(glBlendEquationiEXT);
284     OVERRIDE_DEC(glBlendEquationSeparateiEXT);
285     OVERRIDE_DEC(glBlendFunciEXT);
286     OVERRIDE_DEC(glBlendFuncSeparateiEXT);
287     OVERRIDE_DEC(glColorMaskiEXT);
288     OVERRIDE_DEC(glIsEnablediEXT);
289 
290     return 0;
291 
292 }
293 
s_glFinishRoundTrip(void * self)294 int GLESv2Decoder::s_glFinishRoundTrip(void *self)
295 {
296     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
297     ctx->glFinish();
298     return 0;
299 }
300 
s_glGetCompressedTextureFormats(void * self,int count,GLint * formats)301 void GLESv2Decoder::s_glGetCompressedTextureFormats(void *self, int count, GLint *formats)
302 {
303     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
304 
305     int nFormats;
306     ctx->glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &nFormats);
307     if (nFormats > count) {
308         fprintf(stderr, "%s: GetCompressedTextureFormats: The requested number of formats does not match the number that is reported by OpenGL\n", __FUNCTION__);
309     } else {
310         ctx->glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
311     }
312 }
313 
s_glVertexAttribPointerData(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,void * data,GLuint datalen)314 void GLESv2Decoder::s_glVertexAttribPointerData(void *self, GLuint indx, GLint size, GLenum type,
315                                              GLboolean normalized, GLsizei stride,  void * data, GLuint datalen)
316 {
317     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
318     if (ctx->m_contextData != NULL) {
319         ctx->m_contextData->storePointerData(indx, data, datalen);
320         // note - the stride of the data is always zero when it comes out of the codec.
321         // See gl2.attrib for the packing function call.
322         if ((void*)ctx->glVertexAttribPointerWithDataSize != gles2_unimplemented) {
323             ctx->glVertexAttribPointerWithDataSize(indx, size, type, normalized,
324                     0, ctx->m_contextData->pointerData(indx), datalen);
325         } else {
326             ctx->glVertexAttribPointer(indx, size, type, normalized, 0,
327                     ctx->m_contextData->pointerData(indx));
328         }
329     }
330 }
331 
s_glVertexAttribPointerOffset(void * self,GLuint indx,GLint size,GLenum type,GLboolean normalized,GLsizei stride,GLuint data)332 void GLESv2Decoder::s_glVertexAttribPointerOffset(void *self, GLuint indx, GLint size, GLenum type,
333                                                GLboolean normalized, GLsizei stride,  GLuint data)
334 {
335     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
336     ctx->glVertexAttribPointer(indx, size, type, normalized, stride, SafePointerFromUInt(data));
337 }
338 
339 
s_glDrawElementsData(void * self,GLenum mode,GLsizei count,GLenum type,void * data,GLuint datalen)340 void GLESv2Decoder::s_glDrawElementsData(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen)
341 {
342     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
343     ctx->glDrawElements(mode, count, type, data);
344 }
345 
346 
s_glDrawElementsOffset(void * self,GLenum mode,GLsizei count,GLenum type,GLuint offset)347 void GLESv2Decoder::s_glDrawElementsOffset(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset)
348 {
349     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
350     ctx->glDrawElements(mode, count, type, SafePointerFromUInt(offset));
351 }
352 
s_glDrawElementsDataNullAEMU(void * self,GLenum mode,GLsizei count,GLenum type,void * data,GLuint datalen)353 void GLESv2Decoder::s_glDrawElementsDataNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, void * data, GLuint datalen)
354 {
355     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
356     ctx->glDrawElementsNullAEMU(mode, count, type, data);
357 }
358 
359 
s_glDrawElementsOffsetNullAEMU(void * self,GLenum mode,GLsizei count,GLenum type,GLuint offset)360 void GLESv2Decoder::s_glDrawElementsOffsetNullAEMU(void *self, GLenum mode, GLsizei count, GLenum type, GLuint offset)
361 {
362     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
363     ctx->glDrawElementsNullAEMU(mode, count, type, SafePointerFromUInt(offset));
364 }
365 
s_glMapBufferRangeAEMU(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * mapped)366 void GLESv2Decoder::s_glMapBufferRangeAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* mapped)
367 {
368     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
369     if ((access & GL_MAP_READ_BIT) ||
370         ((access & GL_MAP_WRITE_BIT) &&
371          (!(access & GL_MAP_INVALIDATE_RANGE_BIT) &&
372           !(access & GL_MAP_INVALIDATE_BUFFER_BIT)))) {
373         void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
374 
375         // map failed, no need to copy or unmap
376         if (!gpu_ptr) {
377             fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__);
378             return;
379         }
380 
381         memcpy(mapped, gpu_ptr, length);
382         ctx->glUnmapBuffer(target);
383     } else {
384         // if writing while not wanting to preserve previous contents,
385         // let |mapped| stay as garbage.
386     }
387 }
388 
s_glUnmapBufferAEMU(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * guest_buffer,GLboolean * out_res)389 void GLESv2Decoder::s_glUnmapBufferAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer, GLboolean* out_res)
390 {
391     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
392     *out_res = GL_TRUE;
393 
394     if (access & GL_MAP_WRITE_BIT) {
395         if (!guest_buffer) {
396             // guest can flush 0 in some cases
397             return;
398         }
399         void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
400         if (!gpu_ptr) {
401             fprintf(stderr, "%s: could not get host gpu pointer!\n", __FUNCTION__);
402             return;
403         }
404         memcpy(gpu_ptr, guest_buffer, length);
405         *out_res = ctx->glUnmapBuffer(target);
406     }
407 }
408 
s_glMapBufferRangeDMA(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,uint64_t paddr)409 void GLESv2Decoder::s_glMapBufferRangeDMA(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
410 {
411     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
412     // Check if this is a read or write request and not an invalidate one.
413     if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) &&
414         !(access & (GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT))) {
415         void* guest_buffer = emugl::g_emugl_dma_get_host_addr(paddr);
416         void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
417 
418         // map failed, no need to copy or unmap
419         if (!gpu_ptr) {
420             fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__);
421             return;
422         }
423 
424         memcpy(guest_buffer, gpu_ptr, length);
425         ctx->glUnmapBuffer(target);
426     } else {
427         // if writing while not wanting to preserve previous contents,
428         // let |mapped| stay as garbage.
429     }
430 }
431 
s_glUnmapBufferDMA(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,uint64_t paddr,GLboolean * out_res)432 void GLESv2Decoder::s_glUnmapBufferDMA(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, GLboolean* out_res)
433 {
434     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
435     *out_res = GL_TRUE;
436 
437     if (access & GL_MAP_WRITE_BIT) {
438         if (!paddr) {
439             // guest can flush 0 in some cases
440             return;
441         }
442         void* guest_buffer = emugl::g_emugl_dma_get_host_addr(paddr);
443         void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
444         if (!gpu_ptr) {
445             fprintf(stderr, "%s: could not get host gpu pointer!\n", __FUNCTION__);
446             return;
447         }
448         memcpy(gpu_ptr, guest_buffer, length);
449         *out_res = ctx->glUnmapBuffer(target);
450     }
451 }
452 
align_pointer_size(void * ptr,GLsizeiptr length)453 static std::pair<void*, GLsizeiptr> align_pointer_size(void* ptr, GLsizeiptr length)
454 {
455     constexpr size_t kPageBits = 12;
456     constexpr size_t kPageSize = 1u << kPageBits;
457     constexpr size_t kPageOffsetMask = kPageSize - 1;
458 
459     uintptr_t addr = reinterpret_cast<uintptr_t>(ptr);
460     uintptr_t page_offset = addr & kPageOffsetMask;
461 
462     return { reinterpret_cast<void*>(addr - page_offset),
463              ((length + page_offset + kPageSize - 1) >> kPageBits) << kPageBits
464            };
465 }
466 
s_glMapBufferRangeDirect(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,uint64_t paddr)467 uint64_t GLESv2Decoder::s_glMapBufferRangeDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr)
468 {
469     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
470     // Check if this is a read or write request and not an invalidate one.
471     if (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
472         void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
473 
474         if (gpu_ptr) {
475             std::pair<void*, GLsizeiptr> aligned = align_pointer_size(gpu_ptr, length);
476             get_emugl_vm_operations().mapUserBackedRam(paddr, aligned.first, aligned.second);
477             return reinterpret_cast<uint64_t>(gpu_ptr);
478         } else {
479             fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__);
480             return 0;
481         }
482     } else {
483         // if writing while not wanting to preserve previous contents,
484         // let |mapped| stay as garbage.
485         return 0;
486     }
487 }
488 
s_glUnmapBufferDirect(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,uint64_t paddr,uint64_t gpu_ptr,GLboolean * out_res)489 void GLESv2Decoder::s_glUnmapBufferDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, uint64_t paddr, uint64_t gpu_ptr, GLboolean* out_res)
490 {
491     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
492     GLboolean res = GL_TRUE;
493 
494     if (access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) {
495         get_emugl_vm_operations().unmapUserBackedRam(paddr, align_pointer_size(reinterpret_cast<void*>(gpu_ptr), length).second);
496         res = ctx->glUnmapBuffer(target);
497     }
498 
499     *out_res = res;
500 }
501 
s_glFlushMappedBufferRangeAEMU(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access,void * guest_buffer)502 void GLESv2Decoder::s_glFlushMappedBufferRangeAEMU(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access, void* guest_buffer) {
503     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
504     if (!guest_buffer) {
505         // guest can end up flushing 0 bytes in a lot of cases
506         return;
507     }
508     void* gpu_ptr = ctx->glMapBufferRange(target, offset, length, access);
509 
510     // map failed, no need to copy or unmap
511     if (!gpu_ptr) {
512         fprintf(stderr, "%s: error: could not map host gpu buffer\n", __func__);
513         return;
514     }
515 
516     memcpy(gpu_ptr, guest_buffer, length);
517     // |offset| was the absolute offset into the mapping, so just flush offset 0.
518     ctx->glFlushMappedBufferRange(target, 0, length);
519     ctx->glUnmapBuffer(target);
520 }
521 
s_glFlushMappedBufferRangeDirect(void * self,GLenum target,GLintptr offset,GLsizeiptr length,GLbitfield access)522 void GLESv2Decoder::s_glFlushMappedBufferRangeDirect(void* self, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) {
523     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
524     ctx->glFlushMappedBufferRange(target, offset, length);
525 }
526 
s_glCompressedTexImage2DOffsetAEMU(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,GLuint offset)527 void GLESv2Decoder::s_glCompressedTexImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLuint offset) {
528     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
529 	ctx->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, SafePointerFromUInt(offset));
530 }
s_glCompressedTexSubImage2DOffsetAEMU(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,GLuint offset)531 void GLESv2Decoder::s_glCompressedTexSubImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLuint offset) {
532     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
533 	ctx->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, SafePointerFromUInt(offset));
534 }
s_glTexImage2DOffsetAEMU(void * self,GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLuint offset)535 void GLESv2Decoder::s_glTexImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLuint offset) {
536     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
537 	ctx->glTexImage2D(target, level, internalformat, width, height, border, format, type, SafePointerFromUInt(offset));
538 }
s_glTexSubImage2DOffsetAEMU(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLuint offset)539 void GLESv2Decoder::s_glTexSubImage2DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint offset) {
540     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
541 	ctx->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, SafePointerFromUInt(offset));
542 }
543 
544 static const char* const kNameDelimiter = ";";
545 
sUnpackVarNames(GLsizei count,const char * packedNames)546 static std::vector<std::string> sUnpackVarNames(GLsizei count, const char* packedNames) {
547     std::vector<std::string> unpacked;
548     GLsizei current = 0;
549 
550     while (current < count) {
551         const char* delimPos = strstr(packedNames, kNameDelimiter);
552         size_t nameLen = delimPos - packedNames;
553         std::string next;
554         next.resize(nameLen);
555         memcpy(&next[0], packedNames, nameLen);
556         unpacked.push_back(next);
557         packedNames = delimPos + 1;
558         current++;
559     }
560 
561     return unpacked;
562 }
563 
s_glGetUniformIndicesAEMU(void * self,GLuint program,GLsizei uniformCount,const GLchar * packedNames,GLsizei packedLen,GLuint * uniformIndices)564 void GLESv2Decoder::s_glGetUniformIndicesAEMU(void* self, GLuint program, GLsizei uniformCount, const GLchar* packedNames, GLsizei packedLen, GLuint* uniformIndices) {
565     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
566 
567     std::vector<std::string> unpacked = sUnpackVarNames(uniformCount, packedNames);
568 
569     GLchar** unpackedArray = new GLchar*[unpacked.size()];
570     GLsizei i = 0;
571     for (auto& elt : unpacked) {
572         unpackedArray[i] = (GLchar*)&elt[0];
573         i++;
574     }
575 
576     ctx->glGetUniformIndices(program, uniformCount, (const GLchar**)unpackedArray, uniformIndices);
577 
578     delete [] unpackedArray;
579 }
580 
s_glVertexAttribIPointerDataAEMU(void * self,GLuint indx,GLint size,GLenum type,GLsizei stride,void * data,GLuint datalen)581 void GLESv2Decoder::s_glVertexAttribIPointerDataAEMU(void *self, GLuint indx, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen)
582 {
583     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
584     if (ctx->m_contextData != NULL) {
585         ctx->m_contextData->storePointerData(indx, data, datalen);
586         // note - the stride of the data is always zero when it comes out of the codec.
587         // See gl2.attrib for the packing function call.
588         if ((void*)ctx->glVertexAttribIPointerWithDataSize != gles2_unimplemented) {
589             ctx->glVertexAttribIPointerWithDataSize(indx, size, type, 0,
590                 ctx->m_contextData->pointerData(indx), datalen);
591         } else {
592             ctx->glVertexAttribIPointer(indx, size, type, 0,
593                 ctx->m_contextData->pointerData(indx));
594         }
595     }
596 }
597 
s_glVertexAttribIPointerOffsetAEMU(void * self,GLuint indx,GLint size,GLenum type,GLsizei stride,GLuint data)598 void GLESv2Decoder::s_glVertexAttribIPointerOffsetAEMU(void *self, GLuint indx, GLint size, GLenum type, GLsizei stride, GLuint data)
599 {
600     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
601     ctx->glVertexAttribIPointer(indx, size, type, stride, SafePointerFromUInt(data));
602 }
603 
s_glTransformFeedbackVaryingsAEMU(void * self,GLuint program,GLsizei count,const char * packedVaryings,GLuint packedVaryingsLen,GLenum bufferMode)604 void GLESv2Decoder::s_glTransformFeedbackVaryingsAEMU(void* self, GLuint program, GLsizei count, const char* packedVaryings, GLuint packedVaryingsLen, GLenum bufferMode) {
605 
606     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
607 
608     std::vector<std::string> unpacked = sUnpackVarNames(count, packedVaryings);
609 
610     char** unpackedArray = new char*[unpacked.size()];
611     GLsizei i = 0;
612     for (auto& elt : unpacked) {
613         unpackedArray[i] = &elt[0];
614         i++;
615     }
616 
617     ctx->glTransformFeedbackVaryings(program, count, (const char**)unpackedArray, bufferMode);
618 
619     delete [] unpackedArray;
620 }
621 
s_glTexImage3DOffsetAEMU(void * self,GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLuint offset)622 void GLESv2Decoder::s_glTexImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLuint offset) {
623     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
624 	ctx->glTexImage3D(target, level, internalFormat, width, height, depth, border, format, type, SafePointerFromUInt(offset));
625 }
s_glTexSubImage3DOffsetAEMU(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLuint offset)626 void GLESv2Decoder::s_glTexSubImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLuint offset) {
627     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
628 	ctx->glTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, SafePointerFromUInt(offset));
629 }
s_glCompressedTexImage3DOffsetAEMU(void * self,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,GLuint offset)630 void GLESv2Decoder::s_glCompressedTexImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLuint offset) {
631     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
632 	ctx->glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, SafePointerFromUInt(offset));
633 }
s_glCompressedTexSubImage3DOffsetAEMU(void * self,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,GLuint offset)634 void GLESv2Decoder::s_glCompressedTexSubImage3DOffsetAEMU(void* self, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLuint offset) {
635     GLESv2Decoder *ctx = (GLESv2Decoder *) self;
636 	ctx->glCompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, SafePointerFromUInt(offset));
637 }
638 
s_glDrawElementsInstancedOffsetAEMU(void * self,GLenum mode,GLsizei count,GLenum type,GLuint offset,GLsizei primcount)639 void GLESv2Decoder::s_glDrawElementsInstancedOffsetAEMU(void* self, GLenum mode, GLsizei count, GLenum type, GLuint offset, GLsizei primcount) {
640     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
641     ctx->glDrawElementsInstanced(mode, count, type, SafePointerFromUInt(offset), primcount);
642 }
643 
s_glDrawElementsInstancedDataAEMU(void * self,GLenum mode,GLsizei count,GLenum type,const void * indices,GLsizei primcount,GLsizei datalen)644 void GLESv2Decoder::s_glDrawElementsInstancedDataAEMU(void* self, GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount, GLsizei datalen) {
645     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
646     ctx->glDrawElementsInstanced(mode, count, type, indices, primcount);
647 }
648 
s_glReadPixelsOffsetAEMU(void * self,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLuint offset)649 void GLESv2Decoder::s_glReadPixelsOffsetAEMU(void* self, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLuint offset) {
650     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
651     ctx->glReadPixels(x, y, width, height, format, type, SafePointerFromUInt(offset));
652 }
653 
s_glCreateShaderProgramvAEMU(void * self,GLenum type,GLsizei count,const char * packedStrings,GLuint packedLen)654 GLuint GLESv2Decoder::s_glCreateShaderProgramvAEMU(void* self, GLenum type, GLsizei count, const char* packedStrings, GLuint packedLen) {
655     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
656     return ctx->glCreateShaderProgramv(type, 1, &packedStrings);
657     // TODO: Snapshot names
658 }
659 
s_glDrawArraysIndirectDataAEMU(void * self,GLenum mode,const void * indirect,GLuint datalen)660 void GLESv2Decoder::s_glDrawArraysIndirectDataAEMU(void* self, GLenum mode, const void* indirect, GLuint datalen) {
661     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
662     ctx->glDrawArraysIndirect(mode, indirect);
663 }
664 
s_glDrawArraysIndirectOffsetAEMU(void * self,GLenum mode,GLuint offset)665 void GLESv2Decoder::s_glDrawArraysIndirectOffsetAEMU(void* self, GLenum mode, GLuint offset) {
666     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
667     ctx->glDrawArraysIndirect(mode, SafePointerFromUInt(offset));
668 }
669 
s_glDrawElementsIndirectDataAEMU(void * self,GLenum mode,GLenum type,const void * indirect,GLuint datalen)670 void GLESv2Decoder::s_glDrawElementsIndirectDataAEMU(void* self, GLenum mode, GLenum type, const void* indirect, GLuint datalen) {
671     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
672     ctx->glDrawElementsIndirect(mode, type, indirect);
673 }
674 
s_glDrawElementsIndirectOffsetAEMU(void * self,GLenum mode,GLenum type,GLuint offset)675 void GLESv2Decoder::s_glDrawElementsIndirectOffsetAEMU(void* self, GLenum mode, GLenum type, GLuint offset) {
676     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
677     ctx->glDrawElementsIndirect(mode, type, SafePointerFromUInt(offset));
678 }
679 
s_glFenceSyncAEMU(void * self,GLenum condition,GLbitfield flags)680 uint64_t GLESv2Decoder::s_glFenceSyncAEMU(void* self, GLenum condition, GLbitfield flags) {
681     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
682     return (uint64_t)(uintptr_t)ctx->glFenceSync(condition, flags);
683 }
684 
s_glClientWaitSyncAEMU(void * self,uint64_t wait_on,GLbitfield flags,GLuint64 timeout)685 GLenum GLESv2Decoder::s_glClientWaitSyncAEMU(void* self, uint64_t wait_on, GLbitfield flags, GLuint64 timeout) {
686     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
687     return ctx->glClientWaitSync((GLsync)(uintptr_t)wait_on, flags, timeout);
688 }
689 
s_glWaitSyncAEMU(void * self,uint64_t wait_on,GLbitfield flags,GLuint64 timeout)690 void GLESv2Decoder::s_glWaitSyncAEMU(void* self, uint64_t wait_on, GLbitfield flags, GLuint64 timeout) {
691     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
692     ctx->glWaitSync((GLsync)(uintptr_t)wait_on, flags, timeout);
693 }
694 
s_glDeleteSyncAEMU(void * self,uint64_t to_delete)695 void GLESv2Decoder::s_glDeleteSyncAEMU(void* self, uint64_t to_delete) {
696     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
697     ctx->glDeleteSync((GLsync)(uintptr_t)to_delete);
698 }
699 
s_glIsSyncAEMU(void * self,uint64_t sync)700 GLboolean GLESv2Decoder::s_glIsSyncAEMU(void* self, uint64_t sync) {
701     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
702     return ctx->glIsSync((GLsync)(uintptr_t)sync);
703 }
704 
s_glGetSyncivAEMU(void * self,uint64_t sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)705 void GLESv2Decoder::s_glGetSyncivAEMU(void* self, uint64_t sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values) {
706     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
707     ctx->glGetSynciv((GLsync)(uintptr_t)sync, pname, bufSize, length, values);
708 }
709 
s_glBufferDataSyncAEMU(void * self,GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)710 GLboolean GLESv2Decoder::s_glBufferDataSyncAEMU(void* self, GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
711     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
712     ctx->glBufferData(target, size, data, usage);
713     return GL_TRUE;
714 }
715 
s_glCreateShader(void * self,GLenum shaderType)716 GLuint GLESv2Decoder::s_glCreateShader(void* self, GLenum shaderType) {
717     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
718     GLuint shader = ctx->glCreateShader(shaderType);
719 
720     if (ctx->m_snapshot) {
721         GLuint emuName = ctx->m_snapshot->createShader(shader, shaderType);
722         return emuName;
723     }
724 
725     return shader;
726 }
727 
s_glCreateProgram(void * self)728 GLuint GLESv2Decoder::s_glCreateProgram(void* self) {
729     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
730     return ctx->glCreateProgram();
731 }
732 
s_glGenBuffers(void * self,GLsizei n,GLuint * buffers)733 void GLESv2Decoder::s_glGenBuffers(void* self, GLsizei n, GLuint* buffers) {
734     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
735     ctx->glGenBuffers(n, buffers);
736 
737     if (ctx->m_snapshot) {
738         ctx->m_snapshot->genBuffers(n, buffers);
739     }
740 }
741 
s_glGenFramebuffers(void * self,GLsizei n,GLuint * framebuffers)742 void GLESv2Decoder::s_glGenFramebuffers(void* self, GLsizei n, GLuint* framebuffers) {
743     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
744     ctx->glGenFramebuffers(n, framebuffers);
745     // TODO: Snapshot names
746 }
747 
s_glGenRenderbuffers(void * self,GLsizei n,GLuint * renderbuffers)748 void GLESv2Decoder::s_glGenRenderbuffers(void* self, GLsizei n, GLuint* renderbuffers) {
749     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
750     ctx->glGenRenderbuffers(n, renderbuffers);
751     // TODO: Snapshot names
752 }
753 
s_glGenTextures(void * self,GLsizei n,GLuint * textures)754 void GLESv2Decoder::s_glGenTextures(void* self, GLsizei n, GLuint* textures) {
755     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
756     ctx->glGenTextures(n, textures);
757     // TODO: Snapshot names
758 }
759 
s_glGenVertexArraysOES(void * self,GLsizei n,GLuint * arrays)760 void GLESv2Decoder::s_glGenVertexArraysOES(void* self, GLsizei n, GLuint* arrays) {
761     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
762     ctx->glGenVertexArraysOES(n, arrays);
763     // TODO: Snapshot names
764 }
765 
s_glGenVertexArrays(void * self,GLsizei n,GLuint * arrays)766 void GLESv2Decoder::s_glGenVertexArrays(void* self, GLsizei n, GLuint* arrays) {
767     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
768     ctx->glGenVertexArrays(n, arrays);
769     // TODO: Snapshot names
770 }
771 
s_glGenTransformFeedbacks(void * self,GLsizei n,GLuint * transformFeedbacks)772 void GLESv2Decoder::s_glGenTransformFeedbacks(void* self, GLsizei n, GLuint* transformFeedbacks) {
773     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
774     ctx->glGenTransformFeedbacks(n, transformFeedbacks);
775     // TODO: Snapshot names
776 }
777 
s_glGenSamplers(void * self,GLsizei n,GLuint * samplers)778 void GLESv2Decoder::s_glGenSamplers(void* self, GLsizei n, GLuint* samplers) {
779     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
780     ctx->glGenSamplers(n, samplers);
781     // TODO: Snapshot names
782 
783 }
784 
s_glGenQueries(void * self,GLsizei n,GLuint * queries)785 void GLESv2Decoder::s_glGenQueries(void* self, GLsizei n, GLuint* queries) {
786     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
787     ctx->glGenQueries(n, queries);
788     // TODO: Snapshot names
789 
790 }
791 
s_glGenProgramPipelines(void * self,GLsizei n,GLuint * pipelines)792 void GLESv2Decoder::s_glGenProgramPipelines(void* self, GLsizei n, GLuint* pipelines) {
793     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
794     ctx->glGenProgramPipelines(n, pipelines);
795     // TODO: Snapshot names
796 }
797 
s_glDeleteShader(void * self,GLuint shader)798 void GLESv2Decoder::s_glDeleteShader(void* self, GLuint shader) {
799     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
800     ctx->glDeleteShader(shader);
801     // TODO: Snapshot names
802 }
803 
s_glDeleteProgram(void * self,GLuint program)804 void GLESv2Decoder::s_glDeleteProgram(void* self, GLuint program) {
805     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
806     ctx->glDeleteProgram(program);
807     // TODO: Snapshot names
808 }
809 
s_glDeleteBuffers(void * self,GLsizei n,const GLuint * buffers)810 void GLESv2Decoder::s_glDeleteBuffers(void* self, GLsizei n, const GLuint *buffers) {
811     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
812     ctx->glDeleteBuffers(n, buffers);
813     // TODO: Snapshot names
814 }
815 
s_glDeleteFramebuffers(void * self,GLsizei n,const GLuint * framebuffers)816 void GLESv2Decoder::s_glDeleteFramebuffers(void* self, GLsizei n, const GLuint *framebuffers) {
817     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
818     ctx->glDeleteFramebuffers(n, framebuffers);
819     // TODO: Snapshot names
820 }
821 
s_glDeleteRenderbuffers(void * self,GLsizei n,const GLuint * renderbuffers)822 void GLESv2Decoder::s_glDeleteRenderbuffers(void* self, GLsizei n, const GLuint *renderbuffers) {
823     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
824     ctx->glDeleteRenderbuffers(n, renderbuffers);
825     // TODO: Snapshot names
826 }
827 
s_glDeleteTextures(void * self,GLsizei n,const GLuint * textures)828 void GLESv2Decoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint *textures) {
829     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
830     ctx->glDeleteTextures(n, textures);
831     // TODO: Snapshot names
832 }
833 
834 
s_glDeleteVertexArraysOES(void * self,GLsizei n,const GLuint * arrays)835 void GLESv2Decoder::s_glDeleteVertexArraysOES(void* self, GLsizei n, const GLuint *arrays) {
836     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
837     ctx->glDeleteVertexArraysOES(n, arrays);
838     // TODO: Snapshot names
839 }
840 
s_glDeleteVertexArrays(void * self,GLsizei n,const GLuint * arrays)841 void GLESv2Decoder::s_glDeleteVertexArrays(void* self, GLsizei n, const GLuint *arrays) {
842     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
843     ctx->glDeleteVertexArrays(n, arrays);
844     // TODO: Snapshot names
845 }
846 
847 
s_glDeleteTransformFeedbacks(void * self,GLsizei n,const GLuint * transformFeedbacks)848 void GLESv2Decoder::s_glDeleteTransformFeedbacks(void* self, GLsizei n, const GLuint *transformFeedbacks) {
849     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
850     ctx->glDeleteTransformFeedbacks(n, transformFeedbacks);
851     // TODO: Snapshot names
852 }
853 
s_glDeleteSamplers(void * self,GLsizei n,const GLuint * samplers)854 void GLESv2Decoder::s_glDeleteSamplers(void* self, GLsizei n, const GLuint *samplers) {
855     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
856     ctx->glDeleteSamplers(n, samplers);
857     // TODO: Snapshot names
858 }
859 
s_glDeleteQueries(void * self,GLsizei n,const GLuint * queries)860 void GLESv2Decoder::s_glDeleteQueries(void* self, GLsizei n, const GLuint *queries) {
861     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
862     ctx->glDeleteQueries(n, queries);
863     // TODO: Snapshot names
864 }
865 
s_glDeleteProgramPipelines(void * self,GLsizei n,const GLuint * pipelines)866 void GLESv2Decoder::s_glDeleteProgramPipelines(void* self, GLsizei n, const GLuint *pipelines) {
867     GLESv2Decoder *ctx = (GLESv2Decoder *)self;
868     ctx->glDeleteProgramPipelines(n, pipelines);
869     // TODO: Snapshot names
870 }
871 
872 #define SNAPSHOT_PROGRAM_NAME(x) \
873     GLESv2Decoder *ctx = (GLESv2Decoder *)self; \
874     if (ctx->m_snapshot) { x = ctx->m_snapshot->getProgramName(x); } \
875 
876 #define SNAPSHOT_PROGRAM_NAME2(x,y) \
877     GLESv2Decoder *ctx = (GLESv2Decoder *)self; \
878     if (ctx->m_snapshot) { \
879         x = ctx->m_snapshot->getProgramName(x); \
880         y = ctx->m_snapshot->getProgramName(y); \
881     } \
882 
883 #define SNAPSHOT_SHADER_CALL(funcname,argtypes,args) \
884 void GLESv2Decoder::s_##funcname argtypes { \
885     SNAPSHOT_PROGRAM_NAME(shader) \
886     ctx-> funcname args ; \
887 } \
888 
889 #define SNAPSHOT_PROGRAM_CALL(funcname,argtypes,args) \
890 void GLESv2Decoder::s_##funcname argtypes  { \
891     SNAPSHOT_PROGRAM_NAME(program) \
892     ctx-> funcname args ; \
893 } \
894 
895 #define SNAPSHOT_PROGRAM_CALL_RET(rettype, funcname, argtypes, args) \
896 rettype GLESv2Decoder::s_##funcname argtypes  { \
897     SNAPSHOT_PROGRAM_NAME(program) \
898     return ctx-> funcname args; \
899 } \
900 
901 
s_glShaderString(void * self,GLuint shader,const GLchar * string,GLsizei len)902 void GLESv2Decoder::s_glShaderString(void *self, GLuint shader, const GLchar* string, GLsizei len)
903 {
904     SNAPSHOT_PROGRAM_NAME(shader);
905 
906     ctx->glShaderSource(shader, 1, &string, NULL);
907 
908     if (ctx->m_snapshot) {
909         ctx->m_snapshot->shaderString(shader, string);
910     }
911 }
912 
s_glAttachShader(void * self,GLuint program,GLuint shader)913 void GLESv2Decoder::s_glAttachShader(void* self, GLuint program, GLuint shader) {
914     SNAPSHOT_PROGRAM_NAME2(program, shader)
915     ctx->glAttachShader(program, shader);
916 }
917 
s_glTexBufferOES(void * self,GLenum target,GLenum internalformat,GLuint buffer)918 void GLESv2Decoder::s_glTexBufferOES(void* self, GLenum target, GLenum internalformat, GLuint buffer) {
919     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
920     ctx->glTexBufferOES(target, internalformat, buffer);
921 }
922 
s_glTexBufferEXT(void * self,GLenum target,GLenum internalformat,GLuint buffer)923 void GLESv2Decoder::s_glTexBufferEXT(void* self, GLenum target, GLenum internalformat,
924                                      GLuint buffer) {
925     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
926     ctx->glTexBufferEXT(target, internalformat, buffer);
927 }
928 
s_glTexBufferRangeOES(void * self,GLenum target,GLenum internalformat,GLuint buffer,GLintptr offset,GLsizeiptr size)929 void GLESv2Decoder::s_glTexBufferRangeOES(void* self, GLenum target, GLenum internalformat,
930                                           GLuint buffer,
931                                           GLintptr offset, GLsizeiptr size) {
932     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
933     ctx->glTexBufferRangeOES(target, internalformat, buffer, offset, size);
934 }
935 
s_glTexBufferRangeEXT(void * self,GLenum target,GLenum internalformat,GLuint buffer,GLintptr offset,GLsizeiptr size)936 void GLESv2Decoder::s_glTexBufferRangeEXT(void* self, GLenum target, GLenum internalformat,
937                                           GLuint buffer, GLintptr offset, GLsizeiptr size) {
938     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
939     ctx->glTexBufferRangeEXT(target, internalformat, buffer, offset, size);
940 }
941 
s_glEnableiEXT(void * self,GLenum cap,GLuint index)942 void GLESv2Decoder::s_glEnableiEXT(void* self, GLenum cap, GLuint index) {
943     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
944     ctx->glEnableiEXT(cap, index);
945 }
946 
s_glDisableiEXT(void * self,GLenum cap,GLuint index)947 void GLESv2Decoder::s_glDisableiEXT(void* self, GLenum cap, GLuint index) {
948     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
949     ctx->glDisableiEXT(cap, index);
950 }
951 
s_glBlendEquationiEXT(void * self,GLuint buf,GLenum mode)952 void GLESv2Decoder::s_glBlendEquationiEXT(void* self, GLuint buf, GLenum mode) {
953     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
954     ctx->glBlendEquationiEXT(buf, mode);
955 }
956 
s_glBlendEquationSeparateiEXT(void * self,GLuint buf,GLenum modeRGB,GLenum modeAlpha)957 void GLESv2Decoder::s_glBlendEquationSeparateiEXT(void* self, GLuint buf, GLenum modeRGB,
958                                                GLenum modeAlpha) {
959     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
960     ctx->glBlendEquationSeparateiEXT(buf, modeRGB, modeAlpha);
961 }
962 
s_glBlendFunciEXT(void * self,GLuint buf,GLenum sfactor,GLenum dfactor)963 void GLESv2Decoder::s_glBlendFunciEXT(void* self, GLuint buf, GLenum sfactor, GLenum dfactor) {
964     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
965     ctx->glBlendFunciEXT(buf, sfactor, dfactor);
966 }
967 
s_glBlendFuncSeparateiEXT(void * self,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)968 void GLESv2Decoder::s_glBlendFuncSeparateiEXT(void* self, GLuint buf, GLenum srcRGB, GLenum dstRGB,
969                                            GLenum srcAlpha, GLenum dstAlpha) {
970     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
971     ctx->glBlendFuncSeparateiEXT(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
972 }
973 
s_glColorMaskiEXT(void * self,GLuint buf,GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)974 void GLESv2Decoder::s_glColorMaskiEXT(void* self, GLuint buf, GLboolean red, GLboolean green,
975                                    GLboolean blue, GLboolean alpha) {
976     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
977     ctx->glColorMaskiEXT(buf, red, green, blue, alpha);
978 }
979 
s_glIsEnablediEXT(void * self,GLenum cap,GLuint index)980 GLboolean GLESv2Decoder::s_glIsEnablediEXT(void* self, GLenum cap, GLuint index) {
981     GLESv2Decoder* ctx = (GLESv2Decoder*)self;
982     return ctx->glIsEnablediEXT(cap, index);
983 }
984 
s_glDetachShader(void * self,GLuint program,GLuint shader)985 void GLESv2Decoder::s_glDetachShader(void* self, GLuint program, GLuint shader) {
986     SNAPSHOT_PROGRAM_NAME2(program, shader)
987     ctx->glDetachShader(program, shader);
988 }
989 
s_glIsShader(void * self,GLuint shader)990 GLboolean GLESv2Decoder::s_glIsShader(void* self, GLuint shader) {
991     SNAPSHOT_PROGRAM_NAME(shader);
992     return ctx->glIsShader(shader);
993 }
994 
s_glIsProgram(void * self,GLuint program)995 GLboolean GLESv2Decoder::s_glIsProgram(void* self, GLuint program) {
996     SNAPSHOT_PROGRAM_NAME(program);
997     return ctx->glIsProgram(program);
998 }
999 
1000 SNAPSHOT_SHADER_CALL(glCompileShader, (void* self,  GLuint shader), (shader))
1001 SNAPSHOT_SHADER_CALL(glGetShaderiv, (void* self,  GLuint shader, GLenum pname, GLint* params), (shader, pname, params))
1002 SNAPSHOT_SHADER_CALL(glGetShaderInfoLog, (void* self,  GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog))
1003 SNAPSHOT_SHADER_CALL(glGetShaderSource, (void* self,  GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source), (shader, bufsize, length, source))
1004 SNAPSHOT_PROGRAM_CALL(glLinkProgram, (void* self,  GLuint program), (program))
1005 SNAPSHOT_PROGRAM_CALL(glUseProgram, (void* self,  GLuint program), (program))
1006 SNAPSHOT_PROGRAM_CALL(glValidateProgram, (void* self,  GLuint program), (program))
1007 SNAPSHOT_PROGRAM_CALL(glGetProgramiv, (void* self,  GLuint program, GLenum pname, GLint* params), (program, pname, params))
1008 SNAPSHOT_PROGRAM_CALL(glGetProgramInfoLog, (void* self,  GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog))
1009 SNAPSHOT_PROGRAM_CALL(glBindAttribLocation, (void* self,  GLuint program, GLuint index, const GLchar* name), (program, index, name))
1010 SNAPSHOT_PROGRAM_CALL(glGetActiveAttrib, (void* self,  GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name))
1011 SNAPSHOT_PROGRAM_CALL(glGetActiveUniform, (void* self,  GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name))
1012 SNAPSHOT_PROGRAM_CALL(glGetAttachedShaders, (void* self,  GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders), (program, maxcount, count, shaders))
1013 SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetAttribLocation, (void* self,  GLuint program, const GLchar* name), (program, name))
1014 SNAPSHOT_PROGRAM_CALL(glGetUniformfv, (void* self,  GLuint program, GLint location, GLfloat* params), (program, location, params))
1015 SNAPSHOT_PROGRAM_CALL(glGetUniformiv, (void* self,  GLuint program, GLint location, GLint* params), (program, location, params))
1016 SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetUniformLocation, (void* self,  GLuint program, const GLchar* name), (program, name))
1017 SNAPSHOT_PROGRAM_CALL(glGetProgramBinaryOES, (void* self,  GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary), (program, bufSize, length, binaryFormat, binary))
1018 SNAPSHOT_PROGRAM_CALL(glProgramBinaryOES, (void* self,  GLuint program, GLenum binaryFormat, const GLvoid* binary, GLint length), (program, binaryFormat, binary, length))
1019 SNAPSHOT_PROGRAM_CALL(glUniformBlockBinding, (void* self,  GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding), (program, uniformBlockIndex, uniformBlockBinding))
1020 SNAPSHOT_PROGRAM_CALL_RET(GLuint, glGetUniformBlockIndex, (void* self,  GLuint program, const GLchar* uniformBlockName), (program, uniformBlockName))
1021 SNAPSHOT_PROGRAM_CALL(glGetActiveUniformBlockiv, (void* self,  GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params), (program, uniformBlockIndex, pname, params))
1022 SNAPSHOT_PROGRAM_CALL(glGetActiveUniformBlockName, (void* self,  GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName), (program, uniformBlockIndex, bufSize, length, uniformBlockName))
1023 SNAPSHOT_PROGRAM_CALL(glGetUniformuiv, (void* self,  GLuint program, GLint location, GLuint* params), (program, location, params))
1024 SNAPSHOT_PROGRAM_CALL(glGetActiveUniformsiv, (void* self,  GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params), (program, uniformCount, uniformIndices, pname, params))
1025 SNAPSHOT_PROGRAM_CALL(glTransformFeedbackVaryings, (void* self,  GLuint program, GLsizei count, const char** varyings, GLenum bufferMode), (program, count, varyings, bufferMode))
1026 SNAPSHOT_PROGRAM_CALL(glGetTransformFeedbackVarying, (void* self,  GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, char* name), (program, index, bufSize, length, size, type, name))
1027 SNAPSHOT_PROGRAM_CALL(glProgramParameteri, (void* self,  GLuint program, GLenum pname, GLint value), (program, pname, value))
1028 SNAPSHOT_PROGRAM_CALL(glProgramBinary, (void* self,  GLuint program, GLenum binaryFormat, const void* binary, GLsizei length), (program, binaryFormat, binary, length))
1029 SNAPSHOT_PROGRAM_CALL(glGetProgramBinary, (void* self,  GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary), (program, bufSize, length, binaryFormat, binary))
1030 SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetFragDataLocation, (void* self,  GLuint program, const char* name), (program, name))
1031 SNAPSHOT_PROGRAM_CALL(glUseProgramStages, (void* self,  GLuint pipeline, GLbitfield stages, GLuint program), (pipeline, stages, program))
1032 SNAPSHOT_PROGRAM_CALL(glActiveShaderProgram, (void* self,  GLuint pipeline, GLuint program), (pipeline, program))
1033 SNAPSHOT_PROGRAM_CALL(glProgramUniform1f, (void* self,  GLuint program, GLint location, GLfloat v0), (program, location, v0))
1034 SNAPSHOT_PROGRAM_CALL(glProgramUniform2f, (void* self,  GLuint program, GLint location, GLfloat v0, GLfloat v1), (program, location, v0, v1))
1035 SNAPSHOT_PROGRAM_CALL(glProgramUniform3f, (void* self,  GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2), (program, location, v0, v1, v2))
1036 SNAPSHOT_PROGRAM_CALL(glProgramUniform4f, (void* self,  GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3), (program, location, v0, v1, v2, v3))
1037 SNAPSHOT_PROGRAM_CALL(glProgramUniform1i, (void* self,  GLuint program, GLint location, GLint v0), (program, location, v0))
1038 SNAPSHOT_PROGRAM_CALL(glProgramUniform2i, (void* self,  GLuint program, GLint location, GLint v0, GLint v1), (program, location, v0, v1))
1039 SNAPSHOT_PROGRAM_CALL(glProgramUniform3i, (void* self,  GLuint program, GLint location, GLint v0, GLint v1, GLint v2), (program, location, v0, v1, v2))
1040 SNAPSHOT_PROGRAM_CALL(glProgramUniform4i, (void* self,  GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3), (program, location, v0, v1, v2, v3))
1041 SNAPSHOT_PROGRAM_CALL(glProgramUniform1ui, (void* self,  GLuint program, GLint location, GLuint v0), (program, location, v0))
1042 SNAPSHOT_PROGRAM_CALL(glProgramUniform2ui, (void* self,  GLuint program, GLint location, GLint v0, GLuint v1), (program, location, v0, v1))
1043 SNAPSHOT_PROGRAM_CALL(glProgramUniform3ui, (void* self,  GLuint program, GLint location, GLint v0, GLint v1, GLuint v2), (program, location, v0, v1, v2))
1044 SNAPSHOT_PROGRAM_CALL(glProgramUniform4ui, (void* self,  GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLuint v3), (program, location, v0, v1, v2, v3))
1045 SNAPSHOT_PROGRAM_CALL(glProgramUniform1fv, (void* self,  GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value))
1046 SNAPSHOT_PROGRAM_CALL(glProgramUniform2fv, (void* self,  GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value))
1047 SNAPSHOT_PROGRAM_CALL(glProgramUniform3fv, (void* self,  GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value))
1048 SNAPSHOT_PROGRAM_CALL(glProgramUniform4fv, (void* self,  GLuint program, GLint location, GLsizei count, const GLfloat* value), (program, location, count, value))
1049 SNAPSHOT_PROGRAM_CALL(glProgramUniform1iv, (void* self,  GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value))
1050 SNAPSHOT_PROGRAM_CALL(glProgramUniform2iv, (void* self,  GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value))
1051 SNAPSHOT_PROGRAM_CALL(glProgramUniform3iv, (void* self,  GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value))
1052 SNAPSHOT_PROGRAM_CALL(glProgramUniform4iv, (void* self,  GLuint program, GLint location, GLsizei count, const GLint* value), (program, location, count, value))
1053 SNAPSHOT_PROGRAM_CALL(glProgramUniform1uiv, (void* self,  GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value))
1054 SNAPSHOT_PROGRAM_CALL(glProgramUniform2uiv, (void* self,  GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value))
1055 SNAPSHOT_PROGRAM_CALL(glProgramUniform3uiv, (void* self,  GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value))
1056 SNAPSHOT_PROGRAM_CALL(glProgramUniform4uiv, (void* self,  GLuint program, GLint location, GLsizei count, const GLuint* value), (program, location, count, value))
1057 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1058 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1059 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1060 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2x3fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1061 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3x2fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1062 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix2x4fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1063 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4x2fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1064 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix3x4fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1065 SNAPSHOT_PROGRAM_CALL(glProgramUniformMatrix4x3fv, (void* self,  GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (program, location, count, transpose, value))
1066 SNAPSHOT_PROGRAM_CALL(glGetProgramInterfaceiv, (void* self,  GLuint program, GLenum programInterface, GLenum pname, GLint* params), (program, programInterface, pname, params))
1067 SNAPSHOT_PROGRAM_CALL(glGetProgramResourceiv, (void* self,  GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei bufSize, GLsizei* length, GLint* params), (program, programInterface, index, propCount, props, bufSize, length, params))
1068 SNAPSHOT_PROGRAM_CALL_RET(GLuint, glGetProgramResourceIndex, (void* self, GLuint program, GLenum programInterface, const char * name), (program, programInterface, name))
1069 SNAPSHOT_PROGRAM_CALL_RET(GLint, glGetProgramResourceLocation, (void* self, GLuint program, GLenum programInterface, const char * name), (program, programInterface, name))
1070 SNAPSHOT_PROGRAM_CALL(glGetProgramResourceName, (void* self,  GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, char* name), (program, programInterface, index, bufSize, length, name))
1071 
1072 }  // namespace gl
1073 }  // namespace gfxstream