/*
 ** Copyright 2011, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License");
 ** you may not use this file except in compliance with the License.
 ** You may obtain a copy of the License at
 **
 **     http://www.apache.org/licenses/LICENSE-2.0
 **
 ** Unless required by applicable law or agreed to in writing, software
 ** distributed under the License is distributed on an "AS IS" BASIS,
 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
 
// auto generated by generate_api_cpp.py

#include <utils/Debug.h>

#include "src/header.h"
#include "src/api.h"

template<typename T> static int ToInt(const T & t)
{
    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(T) == sizeof(int));
    return (int &)t;
}

void Debug_glActiveTexture(GLenum texture)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum texture;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glActiveTexture(texture);
            return 0;
        }
    } caller;
    caller.texture = texture;

    msg.set_arg0(texture);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glActiveTexture);
}

void Debug_glAttachShader(GLuint program, GLuint shader)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLuint shader;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glAttachShader(program, shader);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.shader = shader;

    msg.set_arg0(program);
    msg.set_arg1(shader);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glAttachShader);
}

void Debug_glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLuint index;
        const GLchar* name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBindAttribLocation(program, index, name);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.index = index;
    caller.name = name;

    msg.set_arg0(program);
    msg.set_arg1(index);
    msg.set_arg2(ToInt(name));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindAttribLocation);
}

void Debug_glBindBuffer(GLenum target, GLuint buffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLuint buffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBindBuffer(target, buffer);
            getDbgContextThreadSpecific()->glBindBuffer(target, buffer);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.buffer = buffer;

    msg.set_arg0(target);
    msg.set_arg1(buffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindBuffer);
}

void Debug_glBindFramebuffer(GLenum target, GLuint framebuffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLuint framebuffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBindFramebuffer(target, framebuffer);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.framebuffer = framebuffer;

    msg.set_arg0(target);
    msg.set_arg1(framebuffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindFramebuffer);
}

void Debug_glBindRenderbuffer(GLenum target, GLuint renderbuffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLuint renderbuffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBindRenderbuffer(target, renderbuffer);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.renderbuffer = renderbuffer;

    msg.set_arg0(target);
    msg.set_arg1(renderbuffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindRenderbuffer);
}

void Debug_glBindTexture(GLenum target, GLuint texture)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLuint texture;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBindTexture(target, texture);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.texture = texture;

    msg.set_arg0(target);
    msg.set_arg1(texture);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBindTexture);
}

void Debug_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLclampf red;
        GLclampf green;
        GLclampf blue;
        GLclampf alpha;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBlendColor(red, green, blue, alpha);
            return 0;
        }
    } caller;
    caller.red = red;
    caller.green = green;
    caller.blue = blue;
    caller.alpha = alpha;

    msg.set_arg0(ToInt(red));
    msg.set_arg1(ToInt(green));
    msg.set_arg2(ToInt(blue));
    msg.set_arg3(ToInt(alpha));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendColor);
}

void Debug_glBlendEquation( GLenum mode )
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum mode;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBlendEquation(mode);
            return 0;
        }
    } caller;
    caller.mode = mode;

    msg.set_arg0(mode);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquation);
}

void Debug_glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum modeRGB;
        GLenum modeAlpha;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBlendEquationSeparate(modeRGB, modeAlpha);
            return 0;
        }
    } caller;
    caller.modeRGB = modeRGB;
    caller.modeAlpha = modeAlpha;

    msg.set_arg0(modeRGB);
    msg.set_arg1(modeAlpha);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendEquationSeparate);
}

void Debug_glBlendFunc(GLenum sfactor, GLenum dfactor)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum sfactor;
        GLenum dfactor;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBlendFunc(sfactor, dfactor);
            return 0;
        }
    } caller;
    caller.sfactor = sfactor;
    caller.dfactor = dfactor;

    msg.set_arg0(sfactor);
    msg.set_arg1(dfactor);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFunc);
}

void Debug_glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum srcRGB;
        GLenum dstRGB;
        GLenum srcAlpha;
        GLenum dstAlpha;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
            return 0;
        }
    } caller;
    caller.srcRGB = srcRGB;
    caller.dstRGB = dstRGB;
    caller.srcAlpha = srcAlpha;
    caller.dstAlpha = dstAlpha;

    msg.set_arg0(srcRGB);
    msg.set_arg1(dstRGB);
    msg.set_arg2(srcAlpha);
    msg.set_arg3(dstAlpha);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBlendFuncSeparate);
}

void Debug_glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLsizeiptr size;
        const GLvoid* data;
        GLenum usage;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBufferData(target, size, data, usage);
            getDbgContextThreadSpecific()->glBufferData(target, size, data, usage);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.size = size;
    caller.data = data;
    caller.usage = usage;

    msg.set_arg0(target);
    msg.set_arg1(size);
    msg.set_arg2(ToInt(data));
    msg.set_arg3(usage);

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferData);
}

void Debug_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLintptr offset;
        GLsizeiptr size;
        const GLvoid* data;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glBufferSubData(target, offset, size, data);
            getDbgContextThreadSpecific()->glBufferSubData(target, offset, size, data);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.offset = offset;
    caller.size = size;
    caller.data = data;

    msg.set_arg0(target);
    msg.set_arg1(offset);
    msg.set_arg2(size);
    msg.set_arg3(ToInt(data));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(data), size * sizeof(char));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glBufferSubData);
}

GLenum Debug_glCheckFramebufferStatus(GLenum target)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glCheckFramebufferStatus(target));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.target = target;

    msg.set_arg0(target);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCheckFramebufferStatus);
    return reinterpret_cast<GLenum>(ret);
}

void Debug_glClear(GLbitfield mask)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLbitfield mask;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glClear(mask);
            return 0;
        }
    } caller;
    caller.mask = mask;

    msg.set_arg0(mask);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClear);
}

void Debug_glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLclampf red;
        GLclampf green;
        GLclampf blue;
        GLclampf alpha;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glClearColor(red, green, blue, alpha);
            return 0;
        }
    } caller;
    caller.red = red;
    caller.green = green;
    caller.blue = blue;
    caller.alpha = alpha;

    msg.set_arg0(ToInt(red));
    msg.set_arg1(ToInt(green));
    msg.set_arg2(ToInt(blue));
    msg.set_arg3(ToInt(alpha));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearColor);
}

void Debug_glClearDepthf(GLclampf depth)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLclampf depth;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glClearDepthf(depth);
            return 0;
        }
    } caller;
    caller.depth = depth;

    msg.set_arg0(ToInt(depth));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearDepthf);
}

void Debug_glClearStencil(GLint s)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint s;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glClearStencil(s);
            return 0;
        }
    } caller;
    caller.s = s;

    msg.set_arg0(s);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glClearStencil);
}

void Debug_glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLboolean red;
        GLboolean green;
        GLboolean blue;
        GLboolean alpha;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glColorMask(red, green, blue, alpha);
            return 0;
        }
    } caller;
    caller.red = red;
    caller.green = green;
    caller.blue = blue;
    caller.alpha = alpha;

    msg.set_arg0(red);
    msg.set_arg1(green);
    msg.set_arg2(blue);
    msg.set_arg3(alpha);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glColorMask);
}

void Debug_glCompileShader(GLuint shader)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCompileShader(shader);
            return 0;
        }
    } caller;
    caller.shader = shader;

    msg.set_arg0(shader);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompileShader);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLenum internalformat;
        GLsizei width;
        GLsizei height;
        GLint border;
        GLsizei imageSize;
        const GLvoid* data;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.internalformat = internalformat;
    caller.width = width;
    caller.height = height;
    caller.border = border;
    caller.imageSize = imageSize;
    caller.data = data;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(internalformat);
    msg.set_arg3(width);
    msg.set_arg4(height);
    msg.set_arg5(border);
    msg.set_arg6(imageSize);
    msg.set_arg7(ToInt(data));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexImage2D);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLint xoffset;
        GLint yoffset;
        GLsizei width;
        GLsizei height;
        GLenum format;
        GLsizei imageSize;
        const GLvoid* data;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.xoffset = xoffset;
    caller.yoffset = yoffset;
    caller.width = width;
    caller.height = height;
    caller.format = format;
    caller.imageSize = imageSize;
    caller.data = data;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(xoffset);
    msg.set_arg3(yoffset);
    msg.set_arg4(width);
    msg.set_arg5(height);
    msg.set_arg6(format);
    msg.set_arg7(imageSize);
    msg.set_arg8(ToInt(data));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCompressedTexSubImage2D);
}

void Debug_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLenum internalformat;
        GLint x;
        GLint y;
        GLsizei width;
        GLsizei height;
        GLint border;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
#ifdef EXTEND_AFTER_CALL_Debug_glCopyTexImage2D
            EXTEND_AFTER_CALL_Debug_glCopyTexImage2D;
#endif
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.internalformat = internalformat;
    caller.x = x;
    caller.y = y;
    caller.width = width;
    caller.height = height;
    caller.border = border;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(internalformat);
    msg.set_arg3(x);
    msg.set_arg4(y);
    msg.set_arg5(width);
    msg.set_arg6(height);
    msg.set_arg7(border);

#ifdef EXTEND_Debug_glCopyTexImage2D
    EXTEND_Debug_glCopyTexImage2D;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexImage2D);
}

void Debug_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLint xoffset;
        GLint yoffset;
        GLint x;
        GLint y;
        GLsizei width;
        GLsizei height;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
#ifdef EXTEND_AFTER_CALL_Debug_glCopyTexSubImage2D
            EXTEND_AFTER_CALL_Debug_glCopyTexSubImage2D;
#endif
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.xoffset = xoffset;
    caller.yoffset = yoffset;
    caller.x = x;
    caller.y = y;
    caller.width = width;
    caller.height = height;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(xoffset);
    msg.set_arg3(yoffset);
    msg.set_arg4(x);
    msg.set_arg5(y);
    msg.set_arg6(width);
    msg.set_arg7(height);

#ifdef EXTEND_Debug_glCopyTexSubImage2D
    EXTEND_Debug_glCopyTexSubImage2D;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCopyTexSubImage2D);
}

GLuint Debug_glCreateProgram(void)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glCreateProgram());
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;


    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateProgram);
    return reinterpret_cast<GLuint>(ret);
}

GLuint Debug_glCreateShader(GLenum type)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum type;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glCreateShader(type));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.type = type;

    msg.set_arg0(type);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCreateShader);
    return reinterpret_cast<GLuint>(ret);
}

void Debug_glCullFace(GLenum mode)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum mode;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glCullFace(mode);
            return 0;
        }
    } caller;
    caller.mode = mode;

    msg.set_arg0(mode);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glCullFace);
}

void Debug_glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        const GLuint* buffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteBuffers(n, buffers);
            getDbgContextThreadSpecific()->glDeleteBuffers(n, buffers);
            return 0;
        }
    } caller;
    caller.n = n;
    caller.buffers = buffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(buffers));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteBuffers);
}

void Debug_glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        const GLuint* framebuffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteFramebuffers(n, framebuffers);
            return 0;
        }
    } caller;
    caller.n = n;
    caller.framebuffers = framebuffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(framebuffers));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteFramebuffers);
}

void Debug_glDeleteProgram(GLuint program)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteProgram(program);
            return 0;
        }
    } caller;
    caller.program = program;

    msg.set_arg0(program);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteProgram);
}

void Debug_glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        const GLuint* renderbuffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteRenderbuffers(n, renderbuffers);
            return 0;
        }
    } caller;
    caller.n = n;
    caller.renderbuffers = renderbuffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(renderbuffers));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteRenderbuffers);
}

void Debug_glDeleteShader(GLuint shader)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteShader(shader);
            return 0;
        }
    } caller;
    caller.shader = shader;

    msg.set_arg0(shader);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteShader);
}

void Debug_glDeleteTextures(GLsizei n, const GLuint* textures)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        const GLuint* textures;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDeleteTextures(n, textures);
            return 0;
        }
    } caller;
    caller.n = n;
    caller.textures = textures;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(textures));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDeleteTextures);
}

void Debug_glDepthFunc(GLenum func)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum func;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDepthFunc(func);
            return 0;
        }
    } caller;
    caller.func = func;

    msg.set_arg0(func);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthFunc);
}

void Debug_glDepthMask(GLboolean flag)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLboolean flag;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDepthMask(flag);
            return 0;
        }
    } caller;
    caller.flag = flag;

    msg.set_arg0(flag);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthMask);
}

void Debug_glDepthRangef(GLclampf zNear, GLclampf zFar)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLclampf zNear;
        GLclampf zFar;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDepthRangef(zNear, zFar);
            return 0;
        }
    } caller;
    caller.zNear = zNear;
    caller.zFar = zFar;

    msg.set_arg0(ToInt(zNear));
    msg.set_arg1(ToInt(zFar));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDepthRangef);
}

void Debug_glDetachShader(GLuint program, GLuint shader)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLuint shader;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDetachShader(program, shader);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.shader = shader;

    msg.set_arg0(program);
    msg.set_arg1(shader);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDetachShader);
}

void Debug_glDisable(GLenum cap)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum cap;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDisable(cap);
            return 0;
        }
    } caller;
    caller.cap = cap;

    msg.set_arg0(cap);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisable);
}

void Debug_glDisableVertexAttribArray(GLuint index)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint index;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glDisableVertexAttribArray(index);
            getDbgContextThreadSpecific()->glDisableVertexAttribArray(index);
            return 0;
        }
    } caller;
    caller.index = index;

    msg.set_arg0(index);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glDisableVertexAttribArray);
}

void Debug_glEnable(GLenum cap)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum cap;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glEnable(cap);
            return 0;
        }
    } caller;
    caller.cap = cap;

    msg.set_arg0(cap);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnable);
}

void Debug_glEnableVertexAttribArray(GLuint index)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint index;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glEnableVertexAttribArray(index);
            getDbgContextThreadSpecific()->glEnableVertexAttribArray(index);
            return 0;
        }
    } caller;
    caller.index = index;

    msg.set_arg0(index);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glEnableVertexAttribArray);
}

void Debug_glFinish(void)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glFinish();
            return 0;
        }
    } caller;


    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFinish);
}

void Debug_glFlush(void)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glFlush();
            return 0;
        }
    } caller;


    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFlush);
}

void Debug_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum attachment;
        GLenum renderbuffertarget;
        GLuint renderbuffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.attachment = attachment;
    caller.renderbuffertarget = renderbuffertarget;
    caller.renderbuffer = renderbuffer;

    msg.set_arg0(target);
    msg.set_arg1(attachment);
    msg.set_arg2(renderbuffertarget);
    msg.set_arg3(renderbuffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferRenderbuffer);
}

void Debug_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum attachment;
        GLenum textarget;
        GLuint texture;
        GLint level;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glFramebufferTexture2D(target, attachment, textarget, texture, level);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.attachment = attachment;
    caller.textarget = textarget;
    caller.texture = texture;
    caller.level = level;

    msg.set_arg0(target);
    msg.set_arg1(attachment);
    msg.set_arg2(textarget);
    msg.set_arg3(texture);
    msg.set_arg4(level);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFramebufferTexture2D);
}

void Debug_glFrontFace(GLenum mode)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum mode;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glFrontFace(mode);
            return 0;
        }
    } caller;
    caller.mode = mode;

    msg.set_arg0(mode);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glFrontFace);
}

void Debug_glGenBuffers(GLsizei n, GLuint* buffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        GLuint* buffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGenBuffers(n, buffers);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(buffers), n * sizeof(GLuint));
            return 0;
        }
    } caller;
    caller.n = n;
    caller.buffers = buffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(buffers));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenBuffers);
}

void Debug_glGenerateMipmap(GLenum target)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGenerateMipmap(target);
            return 0;
        }
    } caller;
    caller.target = target;

    msg.set_arg0(target);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenerateMipmap);
}

void Debug_glGenFramebuffers(GLsizei n, GLuint* framebuffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        GLuint* framebuffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGenFramebuffers(n, framebuffers);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(framebuffers), n * sizeof(GLuint));
            return 0;
        }
    } caller;
    caller.n = n;
    caller.framebuffers = framebuffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(framebuffers));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenFramebuffers);
}

void Debug_glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        GLuint* renderbuffers;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGenRenderbuffers(n, renderbuffers);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(renderbuffers), n * sizeof(GLuint));
            return 0;
        }
    } caller;
    caller.n = n;
    caller.renderbuffers = renderbuffers;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(renderbuffers));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenRenderbuffers);
}

void Debug_glGenTextures(GLsizei n, GLuint* textures)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        GLuint* textures;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGenTextures(n, textures);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(textures), n * sizeof(GLuint));
            return 0;
        }
    } caller;
    caller.n = n;
    caller.textures = textures;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(textures));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGenTextures);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLuint index;
        GLsizei bufsize;
        GLsizei* length;
        GLint* size;
        GLenum* type;
        GLchar* name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetActiveAttrib(program, index, bufsize, length, size, type, name);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.index = index;
    caller.bufsize = bufsize;
    caller.length = length;
    caller.size = size;
    caller.type = type;
    caller.name = name;

    msg.set_arg0(program);
    msg.set_arg1(index);
    msg.set_arg2(bufsize);
    msg.set_arg3(ToInt(length));
    msg.set_arg4(ToInt(size));
    msg.set_arg5(ToInt(type));
    msg.set_arg6(ToInt(name));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveAttrib);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLuint index;
        GLsizei bufsize;
        GLsizei* length;
        GLint* size;
        GLenum* type;
        GLchar* name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetActiveUniform(program, index, bufsize, length, size, type, name);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.index = index;
    caller.bufsize = bufsize;
    caller.length = length;
    caller.size = size;
    caller.type = type;
    caller.name = name;

    msg.set_arg0(program);
    msg.set_arg1(index);
    msg.set_arg2(bufsize);
    msg.set_arg3(ToInt(length));
    msg.set_arg4(ToInt(size));
    msg.set_arg5(ToInt(type));
    msg.set_arg6(ToInt(name));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetActiveUniform);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLsizei maxcount;
        GLsizei* count;
        GLuint* shaders;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetAttachedShaders(program, maxcount, count, shaders);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.maxcount = maxcount;
    caller.count = count;
    caller.shaders = shaders;

    msg.set_arg0(program);
    msg.set_arg1(maxcount);
    msg.set_arg2(ToInt(count));
    msg.set_arg3(ToInt(shaders));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttachedShaders);
}

int Debug_glGetAttribLocation(GLuint program, const GLchar* name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        const GLchar* name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glGetAttribLocation(program, name));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.program = program;
    caller.name = name;

    msg.set_arg0(program);
    msg.set_arg1(ToInt(name));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetAttribLocation);
    return reinterpret_cast<int>(ret);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetBooleanv(GLenum pname, GLboolean* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum pname;
        GLboolean* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetBooleanv(pname, params);
            return 0;
        }
    } caller;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(pname);
    msg.set_arg1(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBooleanv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetBufferParameteriv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetBufferParameteriv);
}

GLenum Debug_glGetError(void)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glGetError());
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;


    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetError);
    return reinterpret_cast<GLenum>(ret);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetFloatv(GLenum pname, GLfloat* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum pname;
        GLfloat* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetFloatv(pname, params);
            return 0;
        }
    } caller;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(pname);
    msg.set_arg1(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFloatv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum attachment;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.attachment = attachment;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(attachment);
    msg.set_arg2(pname);
    msg.set_arg3(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetFramebufferAttachmentParameteriv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetIntegerv(GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetIntegerv(pname, params);
            return 0;
        }
    } caller;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(pname);
    msg.set_arg1(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetIntegerv);
}

void Debug_glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGetProgramiv(program, pname, params);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
            return 0;
        }
    } caller;
    caller.program = program;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(program);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramiv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLsizei bufsize;
        GLsizei* length;
        GLchar* infolog;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGetProgramInfoLog(program, bufsize, length, infolog);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
            return 0;
        }
    } caller;
    caller.program = program;
    caller.bufsize = bufsize;
    caller.length = length;
    caller.infolog = infolog;

    msg.set_arg0(program);
    msg.set_arg1(bufsize);
    msg.set_arg2(ToInt(length));
    msg.set_arg3(ToInt(infolog));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetProgramInfoLog);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetRenderbufferParameteriv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetRenderbufferParameteriv);
}

void Debug_glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGetShaderiv(shader, pname, params);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(params), 1 * sizeof(GLint));
            return 0;
        }
    } caller;
    caller.shader = shader;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(shader);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderiv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;
        GLsizei bufsize;
        GLsizei* length;
        GLchar* infolog;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGetShaderInfoLog(shader, bufsize, length, infolog);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(infolog), strlen(infolog) * sizeof(GLchar));
            return 0;
        }
    } caller;
    caller.shader = shader;
    caller.bufsize = bufsize;
    caller.length = length;
    caller.infolog = infolog;

    msg.set_arg0(shader);
    msg.set_arg1(bufsize);
    msg.set_arg2(ToInt(length));
    msg.set_arg3(ToInt(infolog));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderInfoLog);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum shadertype;
        GLenum precisiontype;
        GLint* range;
        GLint* precision;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
            return 0;
        }
    } caller;
    caller.shadertype = shadertype;
    caller.precisiontype = precisiontype;
    caller.range = range;
    caller.precision = precision;

    msg.set_arg0(shadertype);
    msg.set_arg1(precisiontype);
    msg.set_arg2(ToInt(range));
    msg.set_arg3(ToInt(precision));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderPrecisionFormat);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;
        GLsizei bufsize;
        GLsizei* length;
        GLchar* source;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            nsecs_t c0 = systemTime(timeMode);
            _c->glGetShaderSource(shader, bufsize, length, source);
            msg.set_time((systemTime(timeMode) - c0) * 1e-6f);
            msg.mutable_data()->assign(reinterpret_cast<const char *>(source), strlen(source) * sizeof(GLchar));
            return 0;
        }
    } caller;
    caller.shader = shader;
    caller.bufsize = bufsize;
    caller.length = length;
    caller.source = source;

    msg.set_arg0(shader);
    msg.set_arg1(bufsize);
    msg.set_arg2(ToInt(length));
    msg.set_arg3(ToInt(source));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetShaderSource);
}

// FIXME: this function has pointers, it should be hand written
const GLubyte* Debug_glGetString(GLenum name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glGetString(name));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.name = name;

    msg.set_arg0(name);

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetString);
    return reinterpret_cast<const GLubyte*>(ret);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLfloat* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetTexParameterfv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameterfv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetTexParameteriv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetTexParameteriv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLint location;
        GLfloat* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetUniformfv(program, location, params);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.location = location;
    caller.params = params;

    msg.set_arg0(program);
    msg.set_arg1(location);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformfv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        GLint location;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetUniformiv(program, location, params);
            return 0;
        }
    } caller;
    caller.program = program;
    caller.location = location;
    caller.params = params;

    msg.set_arg0(program);
    msg.set_arg1(location);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformiv);
}

int Debug_glGetUniformLocation(GLuint program, const GLchar* name)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;
        const GLchar* name;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glGetUniformLocation(program, name));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.program = program;
    caller.name = name;

    msg.set_arg0(program);
    msg.set_arg1(ToInt(name));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(name), strlen(name) * sizeof(GLchar));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetUniformLocation);
    return reinterpret_cast<int>(ret);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint index;
        GLenum pname;
        GLfloat* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetVertexAttribfv(index, pname, params);
            return 0;
        }
    } caller;
    caller.index = index;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(index);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribfv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint index;
        GLenum pname;
        GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetVertexAttribiv(index, pname, params);
            return 0;
        }
    } caller;
    caller.index = index;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(index);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribiv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint index;
        GLenum pname;
        GLvoid** pointer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glGetVertexAttribPointerv(index, pname, pointer);
            return 0;
        }
    } caller;
    caller.index = index;
    caller.pname = pname;
    caller.pointer = pointer;

    msg.set_arg0(index);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(pointer));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glGetVertexAttribPointerv);
}

void Debug_glHint(GLenum target, GLenum mode)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum mode;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glHint(target, mode);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.mode = mode;

    msg.set_arg0(target);
    msg.set_arg1(mode);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glHint);
}

GLboolean Debug_glIsBuffer(GLuint buffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint buffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsBuffer(buffer));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.buffer = buffer;

    msg.set_arg0(buffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsBuffer);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsEnabled(GLenum cap)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum cap;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsEnabled(cap));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.cap = cap;

    msg.set_arg0(cap);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsEnabled);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsFramebuffer(GLuint framebuffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint framebuffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsFramebuffer(framebuffer));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.framebuffer = framebuffer;

    msg.set_arg0(framebuffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsFramebuffer);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsProgram(GLuint program)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsProgram(program));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.program = program;

    msg.set_arg0(program);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsProgram);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsRenderbuffer(GLuint renderbuffer)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint renderbuffer;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsRenderbuffer(renderbuffer));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.renderbuffer = renderbuffer;

    msg.set_arg0(renderbuffer);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsRenderbuffer);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsShader(GLuint shader)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsShader(shader));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.shader = shader;

    msg.set_arg0(shader);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsShader);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

GLboolean Debug_glIsTexture(GLuint texture)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint texture;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            const int * ret = reinterpret_cast<const int *>(_c->glIsTexture(texture));
            msg.set_ret(ToInt(ret));
            return ret;
        }
    } caller;
    caller.texture = texture;

    msg.set_arg0(texture);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glIsTexture);
    return static_cast<GLboolean>(reinterpret_cast<int>(ret));
}

void Debug_glLineWidth(GLfloat width)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLfloat width;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glLineWidth(width);
            return 0;
        }
    } caller;
    caller.width = width;

    msg.set_arg0(ToInt(width));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLineWidth);
}

void Debug_glLinkProgram(GLuint program)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glLinkProgram(program);
            return 0;
        }
    } caller;
    caller.program = program;

    msg.set_arg0(program);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glLinkProgram);
}

void Debug_glPixelStorei(GLenum pname, GLint param)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum pname;
        GLint param;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glPixelStorei(pname, param);
            return 0;
        }
    } caller;
    caller.pname = pname;
    caller.param = param;

    msg.set_arg0(pname);
    msg.set_arg1(param);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPixelStorei);
}

void Debug_glPolygonOffset(GLfloat factor, GLfloat units)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLfloat factor;
        GLfloat units;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glPolygonOffset(factor, units);
            return 0;
        }
    } caller;
    caller.factor = factor;
    caller.units = units;

    msg.set_arg0(ToInt(factor));
    msg.set_arg1(ToInt(units));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glPolygonOffset);
}

void Debug_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint x;
        GLint y;
        GLsizei width;
        GLsizei height;
        GLenum format;
        GLenum type;
        GLvoid* pixels;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glReadPixels(x, y, width, height, format, type, pixels);
#ifdef EXTEND_AFTER_CALL_Debug_glReadPixels
            EXTEND_AFTER_CALL_Debug_glReadPixels;
#endif
            return 0;
        }
    } caller;
    caller.x = x;
    caller.y = y;
    caller.width = width;
    caller.height = height;
    caller.format = format;
    caller.type = type;
    caller.pixels = pixels;

    msg.set_arg0(x);
    msg.set_arg1(y);
    msg.set_arg2(width);
    msg.set_arg3(height);
    msg.set_arg4(format);
    msg.set_arg5(type);
    msg.set_arg6(ToInt(pixels));

    // FIXME: check for pointer usage
#ifdef EXTEND_Debug_glReadPixels
    EXTEND_Debug_glReadPixels;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glReadPixels);
}

void Debug_glReleaseShaderCompiler(void)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glReleaseShaderCompiler();
            return 0;
        }
    } caller;


    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glReleaseShaderCompiler);
}

void Debug_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum internalformat;
        GLsizei width;
        GLsizei height;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glRenderbufferStorage(target, internalformat, width, height);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.internalformat = internalformat;
    caller.width = width;
    caller.height = height;

    msg.set_arg0(target);
    msg.set_arg1(internalformat);
    msg.set_arg2(width);
    msg.set_arg3(height);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glRenderbufferStorage);
}

void Debug_glSampleCoverage(GLclampf value, GLboolean invert)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLclampf value;
        GLboolean invert;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glSampleCoverage(value, invert);
            return 0;
        }
    } caller;
    caller.value = value;
    caller.invert = invert;

    msg.set_arg0(ToInt(value));
    msg.set_arg1(invert);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glSampleCoverage);
}

void Debug_glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint x;
        GLint y;
        GLsizei width;
        GLsizei height;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glScissor(x, y, width, height);
            return 0;
        }
    } caller;
    caller.x = x;
    caller.y = y;
    caller.width = width;
    caller.height = height;

    msg.set_arg0(x);
    msg.set_arg1(y);
    msg.set_arg2(width);
    msg.set_arg3(height);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glScissor);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLsizei n;
        const GLuint* shaders;
        GLenum binaryformat;
        const GLvoid* binary;
        GLsizei length;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glShaderBinary(n, shaders, binaryformat, binary, length);
            return 0;
        }
    } caller;
    caller.n = n;
    caller.shaders = shaders;
    caller.binaryformat = binaryformat;
    caller.binary = binary;
    caller.length = length;

    msg.set_arg0(n);
    msg.set_arg1(ToInt(shaders));
    msg.set_arg2(binaryformat);
    msg.set_arg3(ToInt(binary));
    msg.set_arg4(length);

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderBinary);
}

void Debug_glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint shader;
        GLsizei count;
        const GLchar** string;
        const GLint* length;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glShaderSource(shader, count, string, length);
#ifdef EXTEND_AFTER_CALL_Debug_glShaderSource
            EXTEND_AFTER_CALL_Debug_glShaderSource;
#endif
            return 0;
        }
    } caller;
    caller.shader = shader;
    caller.count = count;
    caller.string = string;
    caller.length = length;

    msg.set_arg0(shader);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(string));
    msg.set_arg3(ToInt(length));

    // FIXME: check for pointer usage
#ifdef EXTEND_Debug_glShaderSource
    EXTEND_Debug_glShaderSource;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glShaderSource);
}

void Debug_glStencilFunc(GLenum func, GLint ref, GLuint mask)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum func;
        GLint ref;
        GLuint mask;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilFunc(func, ref, mask);
            return 0;
        }
    } caller;
    caller.func = func;
    caller.ref = ref;
    caller.mask = mask;

    msg.set_arg0(func);
    msg.set_arg1(ref);
    msg.set_arg2(mask);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFunc);
}

void Debug_glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum face;
        GLenum func;
        GLint ref;
        GLuint mask;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilFuncSeparate(face, func, ref, mask);
            return 0;
        }
    } caller;
    caller.face = face;
    caller.func = func;
    caller.ref = ref;
    caller.mask = mask;

    msg.set_arg0(face);
    msg.set_arg1(func);
    msg.set_arg2(ref);
    msg.set_arg3(mask);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilFuncSeparate);
}

void Debug_glStencilMask(GLuint mask)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint mask;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilMask(mask);
            return 0;
        }
    } caller;
    caller.mask = mask;

    msg.set_arg0(mask);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMask);
}

void Debug_glStencilMaskSeparate(GLenum face, GLuint mask)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum face;
        GLuint mask;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilMaskSeparate(face, mask);
            return 0;
        }
    } caller;
    caller.face = face;
    caller.mask = mask;

    msg.set_arg0(face);
    msg.set_arg1(mask);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilMaskSeparate);
}

void Debug_glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum fail;
        GLenum zfail;
        GLenum zpass;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilOp(fail, zfail, zpass);
            return 0;
        }
    } caller;
    caller.fail = fail;
    caller.zfail = zfail;
    caller.zpass = zpass;

    msg.set_arg0(fail);
    msg.set_arg1(zfail);
    msg.set_arg2(zpass);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOp);
}

void Debug_glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum face;
        GLenum fail;
        GLenum zfail;
        GLenum zpass;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glStencilOpSeparate(face, fail, zfail, zpass);
            return 0;
        }
    } caller;
    caller.face = face;
    caller.fail = fail;
    caller.zfail = zfail;
    caller.zpass = zpass;

    msg.set_arg0(face);
    msg.set_arg1(fail);
    msg.set_arg2(zfail);
    msg.set_arg3(zpass);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glStencilOpSeparate);
}

void Debug_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLint internalformat;
        GLsizei width;
        GLsizei height;
        GLint border;
        GLenum format;
        GLenum type;
        const GLvoid* pixels;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
#ifdef EXTEND_AFTER_CALL_Debug_glTexImage2D
            EXTEND_AFTER_CALL_Debug_glTexImage2D;
#endif
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.internalformat = internalformat;
    caller.width = width;
    caller.height = height;
    caller.border = border;
    caller.format = format;
    caller.type = type;
    caller.pixels = pixels;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(internalformat);
    msg.set_arg3(width);
    msg.set_arg4(height);
    msg.set_arg5(border);
    msg.set_arg6(format);
    msg.set_arg7(type);
    msg.set_arg8(ToInt(pixels));

    // FIXME: check for pointer usage
#ifdef EXTEND_Debug_glTexImage2D
    EXTEND_Debug_glTexImage2D;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexImage2D);
}

void Debug_glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLfloat param;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexParameterf(target, pname, param);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.param = param;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(param));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterf);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        const GLfloat* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexParameterfv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameterfv);
}

void Debug_glTexParameteri(GLenum target, GLenum pname, GLint param)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        GLint param;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexParameteri(target, pname, param);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.param = param;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(param);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteri);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLenum pname;
        const GLint* params;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexParameteriv(target, pname, params);
            return 0;
        }
    } caller;
    caller.target = target;
    caller.pname = pname;
    caller.params = params;

    msg.set_arg0(target);
    msg.set_arg1(pname);
    msg.set_arg2(ToInt(params));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexParameteriv);
}

void Debug_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLenum target;
        GLint level;
        GLint xoffset;
        GLint yoffset;
        GLsizei width;
        GLsizei height;
        GLenum format;
        GLenum type;
        const GLvoid* pixels;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
#ifdef EXTEND_AFTER_CALL_Debug_glTexSubImage2D
            EXTEND_AFTER_CALL_Debug_glTexSubImage2D;
#endif
            return 0;
        }
    } caller;
    caller.target = target;
    caller.level = level;
    caller.xoffset = xoffset;
    caller.yoffset = yoffset;
    caller.width = width;
    caller.height = height;
    caller.format = format;
    caller.type = type;
    caller.pixels = pixels;

    msg.set_arg0(target);
    msg.set_arg1(level);
    msg.set_arg2(xoffset);
    msg.set_arg3(yoffset);
    msg.set_arg4(width);
    msg.set_arg5(height);
    msg.set_arg6(format);
    msg.set_arg7(type);
    msg.set_arg8(ToInt(pixels));

    // FIXME: check for pointer usage
#ifdef EXTEND_Debug_glTexSubImage2D
    EXTEND_Debug_glTexSubImage2D;
#endif
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glTexSubImage2D);
}

void Debug_glUniform1f(GLint location, GLfloat x)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLfloat x;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform1f(location, x);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;

    msg.set_arg0(location);
    msg.set_arg1(ToInt(x));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1f);
}

void Debug_glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLfloat* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform1fv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1fv);
}

void Debug_glUniform1i(GLint location, GLint x)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLint x;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform1i(location, x);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;

    msg.set_arg0(location);
    msg.set_arg1(x);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1i);
}

void Debug_glUniform1iv(GLint location, GLsizei count, const GLint* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLint* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform1iv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 1*count * sizeof(GLint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform1iv);
}

void Debug_glUniform2f(GLint location, GLfloat x, GLfloat y)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLfloat x;
        GLfloat y;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform2f(location, x, y);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;

    msg.set_arg0(location);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2f);
}

void Debug_glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLfloat* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform2fv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2fv);
}

void Debug_glUniform2i(GLint location, GLint x, GLint y)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLint x;
        GLint y;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform2i(location, x, y);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;

    msg.set_arg0(location);
    msg.set_arg1(x);
    msg.set_arg2(y);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2i);
}

void Debug_glUniform2iv(GLint location, GLsizei count, const GLint* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLint* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform2iv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 2*count * sizeof(GLint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform2iv);
}

void Debug_glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLfloat x;
        GLfloat y;
        GLfloat z;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform3f(location, x, y, z);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;
    caller.z = z;

    msg.set_arg0(location);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));
    msg.set_arg3(ToInt(z));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3f);
}

void Debug_glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLfloat* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform3fv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3fv);
}

void Debug_glUniform3i(GLint location, GLint x, GLint y, GLint z)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLint x;
        GLint y;
        GLint z;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform3i(location, x, y, z);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;
    caller.z = z;

    msg.set_arg0(location);
    msg.set_arg1(x);
    msg.set_arg2(y);
    msg.set_arg3(z);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3i);
}

void Debug_glUniform3iv(GLint location, GLsizei count, const GLint* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLint* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform3iv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 3*count * sizeof(GLint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform3iv);
}

void Debug_glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform4f(location, x, y, z, w);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;
    caller.z = z;
    caller.w = w;

    msg.set_arg0(location);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));
    msg.set_arg3(ToInt(z));
    msg.set_arg4(ToInt(w));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4f);
}

void Debug_glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLfloat* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform4fv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4fv);
}

void Debug_glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLint x;
        GLint y;
        GLint z;
        GLint w;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform4i(location, x, y, z, w);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.x = x;
    caller.y = y;
    caller.z = z;
    caller.w = w;

    msg.set_arg0(location);
    msg.set_arg1(x);
    msg.set_arg2(y);
    msg.set_arg3(z);
    msg.set_arg4(w);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4i);
}

void Debug_glUniform4iv(GLint location, GLsizei count, const GLint* v)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        const GLint* v;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniform4iv(location, count, v);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.v = v;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(ToInt(v));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(v), 4*count * sizeof(GLint));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniform4iv);
}

void Debug_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        GLboolean transpose;
        const GLfloat* value;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniformMatrix2fv(location, count, transpose, value);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.transpose = transpose;
    caller.value = value;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(transpose);
    msg.set_arg3(ToInt(value));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 4*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix2fv);
}

void Debug_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        GLboolean transpose;
        const GLfloat* value;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniformMatrix3fv(location, count, transpose, value);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.transpose = transpose;
    caller.value = value;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(transpose);
    msg.set_arg3(ToInt(value));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 9*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix3fv);
}

void Debug_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint location;
        GLsizei count;
        GLboolean transpose;
        const GLfloat* value;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUniformMatrix4fv(location, count, transpose, value);
            return 0;
        }
    } caller;
    caller.location = location;
    caller.count = count;
    caller.transpose = transpose;
    caller.value = value;

    msg.set_arg0(location);
    msg.set_arg1(count);
    msg.set_arg2(transpose);
    msg.set_arg3(ToInt(value));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(value), 16*count * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUniformMatrix4fv);
}

void Debug_glUseProgram(GLuint program)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glUseProgram(program);
            getDbgContextThreadSpecific()->glUseProgram(program);
            return 0;
        }
    } caller;
    caller.program = program;

    msg.set_arg0(program);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glUseProgram);
}

void Debug_glValidateProgram(GLuint program)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint program;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glValidateProgram(program);
            return 0;
        }
    } caller;
    caller.program = program;

    msg.set_arg0(program);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glValidateProgram);
}

void Debug_glVertexAttrib1f(GLuint indx, GLfloat x)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        GLfloat x;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib1f(indx, x);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.x = x;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(x));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1f);
}

void Debug_glVertexAttrib1fv(GLuint indx, const GLfloat* values)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        const GLfloat* values;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib1fv(indx, values);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.values = values;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(values));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 1 * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib1fv);
}

void Debug_glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        GLfloat x;
        GLfloat y;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib2f(indx, x, y);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.x = x;
    caller.y = y;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2f);
}

void Debug_glVertexAttrib2fv(GLuint indx, const GLfloat* values)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        const GLfloat* values;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib2fv(indx, values);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.values = values;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(values));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 2 * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib2fv);
}

void Debug_glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        GLfloat x;
        GLfloat y;
        GLfloat z;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib3f(indx, x, y, z);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.x = x;
    caller.y = y;
    caller.z = z;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));
    msg.set_arg3(ToInt(z));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3f);
}

void Debug_glVertexAttrib3fv(GLuint indx, const GLfloat* values)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        const GLfloat* values;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib3fv(indx, values);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.values = values;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(values));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 3 * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib3fv);
}

void Debug_glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib4f(indx, x, y, z, w);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.x = x;
    caller.y = y;
    caller.z = z;
    caller.w = w;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(x));
    msg.set_arg2(ToInt(y));
    msg.set_arg3(ToInt(z));
    msg.set_arg4(ToInt(w));

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4f);
}

void Debug_glVertexAttrib4fv(GLuint indx, const GLfloat* values)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        const GLfloat* values;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttrib4fv(indx, values);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.values = values;

    msg.set_arg0(indx);
    msg.set_arg1(ToInt(values));

    // FIXME: check for pointer usage
    msg.mutable_data()->assign(reinterpret_cast<const char *>(values), 4 * sizeof(GLfloat));
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttrib4fv);
}

// FIXME: this function has pointers, it should be hand written
void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLuint indx;
        GLint size;
        GLenum type;
        GLboolean normalized;
        GLsizei stride;
        const GLvoid* ptr;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
            getDbgContextThreadSpecific()->glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
            return 0;
        }
    } caller;
    caller.indx = indx;
    caller.size = size;
    caller.type = type;
    caller.normalized = normalized;
    caller.stride = stride;
    caller.ptr = ptr;

    msg.set_arg0(indx);
    msg.set_arg1(size);
    msg.set_arg2(type);
    msg.set_arg3(normalized);
    msg.set_arg4(stride);
    msg.set_arg5(ToInt(ptr));

    // FIXME: check for pointer usage
    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glVertexAttribPointer);
}

void Debug_glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
    glesv2debugger::Message msg;
    struct : public FunctionCall {
        GLint x;
        GLint y;
        GLsizei width;
        GLsizei height;

        const int * operator()(gl_hooks_t::gl_t const * const _c, glesv2debugger::Message & msg) {
            _c->glViewport(x, y, width, height);
            return 0;
        }
    } caller;
    caller.x = x;
    caller.y = y;
    caller.width = width;
    caller.height = height;

    msg.set_arg0(x);
    msg.set_arg1(y);
    msg.set_arg2(width);
    msg.set_arg3(height);

    int * ret = MessageLoop(caller, msg, glesv2debugger::Message_Function_glViewport);
}

// FIXME: the following functions should be written by hand
void Debug_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
void Debug_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
void Debug_glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
void Debug_glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
void Debug_glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
void Debug_glGetBooleanv(GLenum pname, GLboolean* params);
void Debug_glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params);
void Debug_glGetFloatv(GLenum pname, GLfloat* params);
void Debug_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params);
void Debug_glGetIntegerv(GLenum pname, GLint* params);
void Debug_glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
void Debug_glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params);
void Debug_glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
void Debug_glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
void Debug_glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
const GLubyte* Debug_glGetString(GLenum name);
void Debug_glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params);
void Debug_glGetTexParameteriv(GLenum target, GLenum pname, GLint* params);
void Debug_glGetUniformfv(GLuint program, GLint location, GLfloat* params);
void Debug_glGetUniformiv(GLuint program, GLint location, GLint* params);
void Debug_glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
void Debug_glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
void Debug_glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer);
void Debug_glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
void Debug_glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params);
void Debug_glTexParameteriv(GLenum target, GLenum pname, const GLint* params);
void Debug_glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
