/*
 * Copyright 2015, 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.
 *
 * THIS FILE WAS GENERATED BY apic. DO NOT EDIT.
 */


#include "abort_exception.h"
#include "gles_imports.h"
#include "gles_types.h"

#include "gles_spy.h"

#include <gapic/log.h>
#include <gapic/coder/memory.h>
#include <gapic/coder/atom.h>
#include <gapic/coder/gles.h>

#define __STDC_FORMAT_MACROS
#include <inttypes.h>

#include <stdint.h>

#include <memory>
#include <string>

namespace gapii {

void GlesSpy::glBlendEquationiEXT(DrawBufferIndex buf, uint32_t mode) {
    GAPID_DEBUG("glBlendEquationiEXT(%" PRIu32 ", %u)", buf, mode);

    if (mImports.glBlendEquationiEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glBlendEquationiEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, buf, mode] {
        called = true;
        observeReads();
        mImports.glBlendEquationiEXT(buf, mode);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_buffers_indexed);
            subBlendEquationi(call, buf, mode);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlBlendEquationiEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(buf, mScratch), mode);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glBlendFunciEXT(DrawBufferIndex buf, uint32_t src, uint32_t dst) {
    GAPID_DEBUG("glBlendFunciEXT(%" PRIu32 ", %u, %u)", buf, src, dst);

    if (mImports.glBlendFunciEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glBlendFunciEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, buf, src, dst] {
        called = true;
        observeReads();
        mImports.glBlendFunciEXT(buf, src, dst);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_buffers_indexed);
            subBlendFunci(call, buf, src, dst);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlBlendFunciEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(buf, mScratch), src, dst);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glCopyImageSubDataEXT(GLuint srcName, uint32_t srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, uint32_t dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
    GAPID_DEBUG("glCopyImageSubDataEXT(%" PRIu32 ", %u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRIu32 ", %u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);

    if (mImports.glCopyImageSubDataEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glCopyImageSubDataEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth] {
        called = true;
        observeReads();
        mImports.glCopyImageSubDataEXT(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_copy_image);
            subCopyImageSubData(call, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, srcWidth, srcHeight, srcDepth);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlCopyImageSubDataEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(srcName, mScratch), srcTarget, toEncoder< int32_t >(srcLevel, mScratch), toEncoder< int32_t >(srcX, mScratch), toEncoder< int32_t >(srcY, mScratch), toEncoder< int32_t >(srcZ, mScratch), toEncoder< uint32_t >(dstName, mScratch), dstTarget, toEncoder< int32_t >(dstLevel, mScratch), toEncoder< int32_t >(dstX, mScratch), toEncoder< int32_t >(dstY, mScratch), toEncoder< int32_t >(dstZ, mScratch), toEncoder< int32_t >(srcWidth, mScratch), toEncoder< int32_t >(srcHeight, mScratch), toEncoder< int32_t >(srcDepth, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLuint GlesSpy::glGetDebugMessageLogKHR(GLuint count, GLsizei bufSize, uint32_t* sources, uint32_t* types, GLuint* ids, uint32_t* severities, GLsizei* lengths, GLchar* messageLog) {
    GAPID_DEBUG("glGetDebugMessageLogKHR(%" PRIu32 ", %" PRId32 ", %p, %p, %p, %p, %p, %p)", count, bufSize, sources, types, ids, severities, lengths, messageLog);

    if (mImports.glGetDebugMessageLogKHR == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetDebugMessageLogKHR");
        return 0;
    }

    GLuint result = 0;
    bool called = false;
    auto call = [this, &called, &result, count, bufSize, sources, types, ids, severities, lengths, messageLog] {
        called = true;
        observeReads();
        result = mImports.glGetDebugMessageLogKHR(count, bufSize, sources, types, ids, severities, lengths, messageLog);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_KHR_debug);
            call();
            auto l_l = result;
            subGetDebugMessageLog(call, count, bufSize, sources, types, ids, severities, lengths, messageLog, l_l);
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetDebugMessageLogKHR coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(count, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLenum__P >(sources, mScratch), toEncoder< gapic::coder::gles::GLenum__P >(types, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(ids, mScratch), toEncoder< gapic::coder::gles::GLenum__P >(severities, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(lengths, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(messageLog, mScratch), toEncoder< uint32_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glGetTexParameterIivEXT(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetTexParameterIivEXT(%u, %u, %p)", target, pname, params);

    if (mImports.glGetTexParameterIivEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetTexParameterIivEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexParameterIivEXT(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_texture_border_clamp);
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            call();
            subGetTexParameterIiv(call, target, pname, params);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetTexParameterIivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLint__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLboolean GlesSpy::glIsEnablediEXT(uint32_t target, GLuint index) {
    GAPID_DEBUG("glIsEnablediEXT(%u, %" PRIu32 ")", target, index);

    if (mImports.glIsEnablediEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsEnablediEXT");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, target, index] {
        called = true;
        observeReads();
        result = mImports.glIsEnablediEXT(target, index);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_buffers_indexed);
            uint32_t l_IsEnabledi_55_capability = target;
            GLuint l_IsEnabledi_55_index = index;
            GLboolean l_IsEnabledi_55_result = subGetCapability(call, l_IsEnabledi_55_capability, l_IsEnabledi_55_index);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>(l_IsEnabledi_55_result);
            }
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsEnablediEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glPatchParameteriEXT(uint32_t pname, GLint value) {
    GAPID_DEBUG("glPatchParameteriEXT(%u, %" PRId32 ")", pname, value);

    if (mImports.glPatchParameteriEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glPatchParameteriEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, pname, value] {
        called = true;
        observeReads();
        mImports.glPatchParameteriEXT(pname, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_tessellation_shader);
            subPatchParameteri(call, pname, value);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlPatchParameteriEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< int32_t >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glBeginQuery(uint32_t target, QueryId query) {
    GAPID_DEBUG("glBeginQuery(%u, %" PRIu32 ")", target, query);

    if (mImports.glBeginQuery == nullptr) {
        GAPID_WARNING("Application called unsupported function glBeginQuery");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, query] {
        called = true;
        observeReads();
        mImports.glBeginQuery(target, query);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_ANY_SAMPLES_PASSED: // fall-through...
                case GLenum::GL_ANY_SAMPLES_PASSED_CONSERVATIVE: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: {
                    break;
                }
                case GLenum::GL_PRIMITIVES_GENERATED: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mActiveQueries[target] = query;
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlBeginQuery coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(query, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glEndQuery(uint32_t target) {
    GAPID_DEBUG("glEndQuery(%u)", target);

    if (mImports.glEndQuery == nullptr) {
        GAPID_WARNING("Application called unsupported function glEndQuery");
        return;
    }

    bool called = false;
    auto call = [this, &called, target] {
        called = true;
        observeReads();
        mImports.glEndQuery(target);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_ANY_SAMPLES_PASSED: // fall-through...
                case GLenum::GL_ANY_SAMPLES_PASSED_CONSERVATIVE: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: {
                    break;
                }
                case GLenum::GL_PRIMITIVES_GENERATED: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mActiveQueries.erase(target);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlEndQuery coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetBufferPointerv(uint32_t target, uint32_t pname, void** params) {
    GAPID_DEBUG("glGetBufferPointerv(%u, %u, %p)", target, pname, params);

    if (mImports.glGetBufferPointerv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetBufferPointerv");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetBufferPointerv(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            call();
            subGetBufferPointerv(call, target, pname, params);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetBufferPointerv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::Void__P__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDebugMessageControl(uint32_t source, uint32_t type, uint32_t severity, GLsizei count, GLuint* ids, GLboolean enabled) {
    GAPID_DEBUG("glDebugMessageControl(%u, %u, %u, %" PRId32 ", %p, %" PRIu8 ")", source, type, severity, count, ids, enabled);

    if (mImports.glDebugMessageControl == nullptr) {
        GAPID_WARNING("Application called unsupported function glDebugMessageControl");
        return;
    }

    bool called = false;
    auto call = [this, &called, source, type, severity, count, ids, enabled] {
        called = true;
        observeReads();
        mImports.glDebugMessageControl(source, type, severity, count, ids, enabled);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subDebugMessageControl(call, source, type, severity, count, ids, enabled);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDebugMessageControl coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), source, type, severity, toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLuint__CP >(ids, mScratch), toEncoder< uint8_t >(enabled, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetObjectLabel(uint32_t identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) {
    GAPID_DEBUG("glGetObjectLabel(%u, %" PRIu32 ", %" PRId32 ", %p, %p)", identifier, name, bufSize, length, label);

    if (mImports.glGetObjectLabel == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetObjectLabel");
        return;
    }

    bool called = false;
    auto call = [this, &called, identifier, name, bufSize, length, label] {
        called = true;
        observeReads();
        mImports.glGetObjectLabel(identifier, name, bufSize, length, label);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            call();
            subGetObjectLabel(call, identifier, name, bufSize, length, label);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetObjectLabel coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), identifier, toEncoder< uint32_t >(name, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(label, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glObjectPtrLabel(void* ptr, GLsizei length, GLchar* label) {
    GAPID_DEBUG("glObjectPtrLabel(%p, %" PRId32 ", %p)", ptr, length, label);

    if (mImports.glObjectPtrLabel == nullptr) {
        GAPID_WARNING("Application called unsupported function glObjectPtrLabel");
        return;
    }

    bool called = false;
    auto call = [this, &called, ptr, length, label] {
        called = true;
        observeReads();
        mImports.glObjectPtrLabel(ptr, length, label);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subObjectPtrLabel(call, ptr, length, label);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlObjectPtrLabel coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::Void__CP >(ptr, mScratch), toEncoder< int32_t >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__CP >(label, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDrawElements(uint32_t draw_mode, GLsizei indices_count, uint32_t indices_type, IndicesPointer indices) {
    GAPID_DEBUG("glDrawElements(%u, %" PRId32 ", %u, %p)", draw_mode, indices_count, indices_type, indices);

    if (mImports.glDrawElements == nullptr) {
        GAPID_WARNING("Application called unsupported function glDrawElements");
        return;
    }

    bool called = false;
    auto call = [this, &called, draw_mode, indices_count, indices_type, indices] {
        called = true;
        observeReads();
        mImports.glDrawElements(draw_mode, indices_count, indices_type, indices);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subDrawElements(call, l_ctx, draw_mode, indices_count, indices_type, indices, (GLsizei)(1L), (GLint)(0L));
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDrawElements coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), draw_mode, toEncoder< int32_t >(indices_count, mScratch), indices_type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);
    onPostDrawCall();

}

void GlesSpy::glDrawElementsInstancedBaseVertex(uint32_t draw_mode, GLsizei indices_count, uint32_t indices_type, IndicesPointer indices, GLsizei instance_count, GLint base_vertex) {
    GAPID_DEBUG("glDrawElementsInstancedBaseVertex(%u, %" PRId32 ", %u, %p, %" PRId32 ", %" PRId32 ")", draw_mode, indices_count, indices_type, indices, instance_count, base_vertex);

    if (mImports.glDrawElementsInstancedBaseVertex == nullptr) {
        GAPID_WARNING("Application called unsupported function glDrawElementsInstancedBaseVertex");
        return;
    }

    bool called = false;
    auto call = [this, &called, draw_mode, indices_count, indices_type, indices, instance_count, base_vertex] {
        called = true;
        observeReads();
        mImports.glDrawElementsInstancedBaseVertex(draw_mode, indices_count, indices_type, indices, instance_count, base_vertex);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subDrawElementsInstancedBaseVertex(call, draw_mode, indices_count, indices_type, indices, instance_count, base_vertex);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDrawElementsInstancedBaseVertex coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), draw_mode, toEncoder< int32_t >(indices_count, mScratch), indices_type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch), toEncoder< int32_t >(instance_count, mScratch), toEncoder< int32_t >(base_vertex, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);
    onPostDrawCall();

}

void GlesSpy::glColorMaskiOES(DrawBufferIndex index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
    GAPID_DEBUG("glColorMaskiOES(%" PRIu32 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ")", index, r, g, b, a);

    if (mImports.glColorMaskiOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glColorMaskiOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, index, r, g, b, a] {
        called = true;
        observeReads();
        mImports.glColorMaskiOES(index, r, g, b, a);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_buffers_indexed);
            subColorMaski(call, index, r, g, b, a);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlColorMaskiOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< uint8_t >(r, mScratch), toEncoder< uint8_t >(g, mScratch), toEncoder< uint8_t >(b, mScratch), toEncoder< uint8_t >(a, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glCompressedTexSubImage3DOES(uint32_t target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, uint32_t format, GLsizei image_size, TexturePointer data) {
    GAPID_DEBUG("glCompressedTexSubImage3DOES(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %u, %" PRId32 ", %p)", target, level, xoffset, yoffset, zoffset, width, height, depth, format, image_size, data);

    if (mImports.glCompressedTexSubImage3DOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glCompressedTexSubImage3DOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, level, xoffset, yoffset, zoffset, width, height, depth, format, image_size, data] {
        called = true;
        observeReads();
        mImports.glCompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, image_size, data);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_3D);
            subCompressedTexSubImage3D(call, target, level, xoffset, yoffset, zoffset, width, height, depth, format, image_size, data);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlCompressedTexSubImage3DOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(level, mScratch), toEncoder< int32_t >(xoffset, mScratch), toEncoder< int32_t >(yoffset, mScratch), toEncoder< int32_t >(zoffset, mScratch), toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch), toEncoder< int32_t >(depth, mScratch), format, toEncoder< int32_t >(image_size, mScratch), toEncoder< gapic::coder::gles::TexturePointer >(data, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glCopyTexSubImage3DOES(uint32_t target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glCopyTexSubImage3DOES(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", target, level, xoffset, yoffset, zoffset, x, y, width, height);

    if (mImports.glCopyTexSubImage3DOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glCopyTexSubImage3DOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, level, xoffset, yoffset, zoffset, x, y, width, height] {
        called = true;
        observeReads();
        mImports.glCopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_3D);
            subCopyTexSubImage3D(call, target, level, xoffset, yoffset, zoffset, x, y, width, height);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlCopyTexSubImage3DOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(level, mScratch), toEncoder< int32_t >(xoffset, mScratch), toEncoder< int32_t >(yoffset, mScratch), toEncoder< int32_t >(zoffset, mScratch), toEncoder< int32_t >(x, mScratch), toEncoder< int32_t >(y, mScratch), toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDeleteProgramPipelinesEXT(GLsizei n, PipelineId* pipelines) {
    GAPID_DEBUG("glDeleteProgramPipelinesEXT(%" PRId32 ", %p)", n, pipelines);

    if (mImports.glDeleteProgramPipelinesEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glDeleteProgramPipelinesEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, n, pipelines] {
        called = true;
        observeReads();
        mImports.glDeleteProgramPipelinesEXT(n, pipelines);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDeleteProgramPipelinesEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::PipelineId__CP >(pipelines, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDepthRangeArrayfvNV(GLuint first, GLsizei count, GLfloat* v) {
    GAPID_DEBUG("glDepthRangeArrayfvNV(%" PRIu32 ", %" PRId32 ", %p)", first, count, v);

    if (mImports.glDepthRangeArrayfvNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glDepthRangeArrayfvNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, first, count, v] {
        called = true;
        observeReads();
        mImports.glDepthRangeArrayfvNV(first, count, v);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDepthRangeArrayfvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(first, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(v, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDepthRangeIndexedfNV(GLuint index, GLfloat n, GLfloat f) {
    GAPID_DEBUG("glDepthRangeIndexedfNV(%" PRIu32 ", %f, %f)", index, n, f);

    if (mImports.glDepthRangeIndexedfNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glDepthRangeIndexedfNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, index, n, f] {
        called = true;
        observeReads();
        mImports.glDepthRangeIndexedfNV(index, n, f);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDepthRangeIndexedfNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< float >(n, mScratch), toEncoder< float >(f, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDisableDriverControlQCOM(GLuint driverControl) {
    GAPID_DEBUG("glDisableDriverControlQCOM(%" PRIu32 ")", driverControl);

    if (mImports.glDisableDriverControlQCOM == nullptr) {
        GAPID_WARNING("Application called unsupported function glDisableDriverControlQCOM");
        return;
    }

    bool called = false;
    auto call = [this, &called, driverControl] {
        called = true;
        observeReads();
        mImports.glDisableDriverControlQCOM(driverControl);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_QCOM_driver_control);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDisableDriverControlQCOM coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(driverControl, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glFramebufferSampleLocationsfvNV(uint32_t target, GLuint start, GLsizei count, GLfloat* v) {
    GAPID_DEBUG("glFramebufferSampleLocationsfvNV(%u, %" PRIu32 ", %" PRId32 ", %p)", target, start, count, v);

    if (mImports.glFramebufferSampleLocationsfvNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glFramebufferSampleLocationsfvNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, start, count, v] {
        called = true;
        observeReads();
        mImports.glFramebufferSampleLocationsfvNV(target, start, count, v);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_sample_locations);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlFramebufferSampleLocationsfvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(start, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(v, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetIntegeri_vEXT(uint32_t target, GLuint index, GLint* data) {
    GAPID_DEBUG("glGetIntegeri_vEXT(%u, %" PRIu32 ", %p)", target, index, data);

    if (mImports.glGetIntegeri_vEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetIntegeri_vEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, index, data] {
        called = true;
        observeReads();
        mImports.glGetIntegeri_vEXT(target, index, data);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_multiview_draw_buffers);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetIntegeri_vEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, mScratch), toEncoder< gapic::coder::gles::GLint__P >(data, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLfloat GlesSpy::glGetPathLengthNV(GLuint path, GLsizei startSegment, GLsizei numSegments) {
    GAPID_DEBUG("glGetPathLengthNV(%" PRIu32 ", %" PRId32 ", %" PRId32 ")", path, startSegment, numSegments);

    if (mImports.glGetPathLengthNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetPathLengthNV");
        return 0;
    }

    GLfloat result = 0;
    bool called = false;
    auto call = [this, &called, &result, path, startSegment, numSegments] {
        called = true;
        observeReads();
        result = mImports.glGetPathLengthNV(path, startSegment, numSegments);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_path_rendering);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetPathLengthNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), toEncoder< int32_t >(startSegment, mScratch), toEncoder< int32_t >(numSegments, mScratch), toEncoder< float >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glGetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, GLuint counterNameLength, GLchar* counterName, GLuint counterDescLength, GLchar* counterDesc, GLuint* counterOffset, GLuint* counterDataSize, GLuint* counterTypeEnum, GLuint* counterDataTypeEnum, GLuint64* rawCounterMaxValue) {
    GAPID_DEBUG("glGetPerfCounterInfoINTEL(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %p, %" PRIu32 ", %p, %p, %p, %p, %p, %p)", queryId, counterId, counterNameLength, counterName, counterDescLength, counterDesc, counterOffset, counterDataSize, counterTypeEnum, counterDataTypeEnum, rawCounterMaxValue);

    if (mImports.glGetPerfCounterInfoINTEL == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetPerfCounterInfoINTEL");
        return;
    }

    bool called = false;
    auto call = [this, &called, queryId, counterId, counterNameLength, counterName, counterDescLength, counterDesc, counterOffset, counterDataSize, counterTypeEnum, counterDataTypeEnum, rawCounterMaxValue] {
        called = true;
        observeReads();
        mImports.glGetPerfCounterInfoINTEL(queryId, counterId, counterNameLength, counterName, counterDescLength, counterDesc, counterOffset, counterDataSize, counterTypeEnum, counterDataTypeEnum, rawCounterMaxValue);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_INTEL_performance_query);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetPerfCounterInfoINTEL coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(queryId, mScratch), toEncoder< uint32_t >(counterId, mScratch), toEncoder< uint32_t >(counterNameLength, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(counterName, mScratch), toEncoder< uint32_t >(counterDescLength, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(counterDesc, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(counterOffset, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(counterDataSize, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(counterTypeEnum, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(counterDataTypeEnum, mScratch), toEncoder< gapic::coder::gles::GLuint64__P >(rawCounterMaxValue, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei* length, GLchar* groupString) {
    GAPID_DEBUG("glGetPerfMonitorGroupStringAMD(%" PRIu32 ", %" PRId32 ", %p, %p)", group, bufSize, length, groupString);

    if (mImports.glGetPerfMonitorGroupStringAMD == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetPerfMonitorGroupStringAMD");
        return;
    }

    bool called = false;
    auto call = [this, &called, group, bufSize, length, groupString] {
        called = true;
        observeReads();
        mImports.glGetPerfMonitorGroupStringAMD(group, bufSize, length, groupString);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_AMD_performance_monitor);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetPerfMonitorGroupStringAMD coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(group, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(groupString, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetPerfMonitorGroupsAMD(GLint* numGroups, GLsizei groupsSize, GLuint* groups) {
    GAPID_DEBUG("glGetPerfMonitorGroupsAMD(%p, %" PRId32 ", %p)", numGroups, groupsSize, groups);

    if (mImports.glGetPerfMonitorGroupsAMD == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetPerfMonitorGroupsAMD");
        return;
    }

    bool called = false;
    auto call = [this, &called, numGroups, groupsSize, groups] {
        called = true;
        observeReads();
        mImports.glGetPerfMonitorGroupsAMD(numGroups, groupsSize, groups);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_AMD_performance_monitor);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetPerfMonitorGroupsAMD coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLint__P >(numGroups, mScratch), toEncoder< int32_t >(groupsSize, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(groups, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLuint64 GlesSpy::glGetTextureSamplerHandleNV(TextureId texture, SamplerId sampler) {
    GAPID_DEBUG("glGetTextureSamplerHandleNV(%" PRIu32 ", %" PRIu32 ")", texture, sampler);

    if (mImports.glGetTextureSamplerHandleNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetTextureSamplerHandleNV");
        return 0;
    }

    GLuint64 result = 0;
    bool called = false;
    auto call = [this, &called, &result, texture, sampler] {
        called = true;
        observeReads();
        result = mImports.glGetTextureSamplerHandleNV(texture, sampler);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_bindless_texture);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetTextureSamplerHandleNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(texture, mScratch), toEncoder< uint32_t >(sampler, mScratch), toEncoder< uint64_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

GLboolean GlesSpy::glIsImageHandleResidentNV(GLuint64 handle) {
    GAPID_DEBUG("glIsImageHandleResidentNV(%" PRIu64 ")", handle);

    if (mImports.glIsImageHandleResidentNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsImageHandleResidentNV");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, handle] {
        called = true;
        observeReads();
        result = mImports.glIsImageHandleResidentNV(handle);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_bindless_texture);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsImageHandleResidentNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint64_t >(handle, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

GLboolean GlesSpy::glIsPointInFillPathNV(GLuint path, GLuint mask, GLfloat x, GLfloat y) {
    GAPID_DEBUG("glIsPointInFillPathNV(%" PRIu32 ", %" PRIu32 ", %f, %f)", path, mask, x, y);

    if (mImports.glIsPointInFillPathNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsPointInFillPathNV");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, path, mask, x, y] {
        called = true;
        observeReads();
        result = mImports.glIsPointInFillPathNV(path, mask, x, y);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_path_rendering);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsPointInFillPathNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), toEncoder< uint32_t >(mask, mScratch), toEncoder< float >(x, mScratch), toEncoder< float >(y, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glMakeTextureHandleResidentNV(GLuint64 handle) {
    GAPID_DEBUG("glMakeTextureHandleResidentNV(%" PRIu64 ")", handle);

    if (mImports.glMakeTextureHandleResidentNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glMakeTextureHandleResidentNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, handle] {
        called = true;
        observeReads();
        mImports.glMakeTextureHandleResidentNV(handle);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_bindless_texture);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlMakeTextureHandleResidentNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint64_t >(handle, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glMatrixLoad3x3fNV(uint32_t matrixMode, GLfloat* m) {
    GAPID_DEBUG("glMatrixLoad3x3fNV(%u, %p)", matrixMode, m);

    if (mImports.glMatrixLoad3x3fNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glMatrixLoad3x3fNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, matrixMode, m] {
        called = true;
        observeReads();
        mImports.glMatrixLoad3x3fNV(matrixMode, m);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_path_rendering);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlMatrixLoad3x3fNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), matrixMode, toEncoder< gapic::coder::gles::GLfloat__CP >(m, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

uint32_t GlesSpy::glPathMemoryGlyphIndexArrayNV(GLuint firstPathName, uint32_t fontTarget, GLsizeiptr fontSize, void* fontData, GLsizei faceIndex, GLuint firstGlyphIndex, GLsizei numGlyphs, GLuint pathParameterTemplate, GLfloat emScale) {
    GAPID_DEBUG("glPathMemoryGlyphIndexArrayNV(%" PRIu32 ", %u, %" PRId32 ", %p, %" PRId32 ", %" PRIu32 ", %" PRId32 ", %" PRIu32 ", %f)", firstPathName, fontTarget, fontSize, fontData, faceIndex, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale);

    if (mImports.glPathMemoryGlyphIndexArrayNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glPathMemoryGlyphIndexArrayNV");
        return 0;
    }

    uint32_t result = 0;
    bool called = false;
    auto call = [this, &called, &result, firstPathName, fontTarget, fontSize, fontData, faceIndex, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale] {
        called = true;
        observeReads();
        result = mImports.glPathMemoryGlyphIndexArrayNV(firstPathName, fontTarget, fontSize, fontData, faceIndex, firstGlyphIndex, numGlyphs, pathParameterTemplate, emScale);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_path_rendering);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlPathMemoryGlyphIndexArrayNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(firstPathName, mScratch), fontTarget, toEncoder< int32_t >(fontSize, mScratch), toEncoder< gapic::coder::gles::Void__CP >(fontData, mScratch), toEncoder< int32_t >(faceIndex, mScratch), toEncoder< uint32_t >(firstGlyphIndex, mScratch), toEncoder< int32_t >(numGlyphs, mScratch), toEncoder< uint32_t >(pathParameterTemplate, mScratch), toEncoder< float >(emScale, mScratch), result);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glPrimitiveBoundingBoxOES(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) {
    GAPID_DEBUG("glPrimitiveBoundingBoxOES(%f, %f, %f, %f, %f, %f, %f, %f)", minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);

    if (mImports.glPrimitiveBoundingBoxOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glPrimitiveBoundingBoxOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW] {
        called = true;
        observeReads();
        mImports.glPrimitiveBoundingBoxOES(minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_primitive_bounding_box);
            subPrimitiveBoundingBox(call, minX, minY, minZ, minW, maxX, maxY, maxZ, maxW);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlPrimitiveBoundingBoxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(minX, mScratch), toEncoder< float >(minY, mScratch), toEncoder< float >(minZ, mScratch), toEncoder< float >(minW, mScratch), toEncoder< float >(maxX, mScratch), toEncoder< float >(maxY, mScratch), toEncoder< float >(maxZ, mScratch), toEncoder< float >(maxW, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniformMatrix2x3fvEXT(ProgramId program, UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* value) {
    GAPID_DEBUG("glProgramUniformMatrix2x3fvEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", program, location, count, transpose, value);

    if (mImports.glProgramUniformMatrix2x3fvEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniformMatrix2x3fvEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, count, transpose, value] {
        called = true;
        observeReads();
        mImports.glProgramUniformMatrix2x3fvEXT(program, location, count, transpose, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniformMatrix2x3fv(call, program, location, count, transpose, value);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniformMatrix2x3fvEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< uint8_t >(transpose, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniformMatrix3x2fvEXT(ProgramId program, UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* value) {
    GAPID_DEBUG("glProgramUniformMatrix3x2fvEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", program, location, count, transpose, value);

    if (mImports.glProgramUniformMatrix3x2fvEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniformMatrix3x2fvEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, count, transpose, value] {
        called = true;
        observeReads();
        mImports.glProgramUniformMatrix3x2fvEXT(program, location, count, transpose, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniformMatrix3x2fv(call, program, location, count, transpose, value);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniformMatrix3x2fvEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< uint8_t >(transpose, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glQueryCounterEXT(QueryId query, uint32_t target) {
    GAPID_DEBUG("glQueryCounterEXT(%" PRIu32 ", %u)", query, target);

    if (mImports.glQueryCounterEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glQueryCounterEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, query, target] {
        called = true;
        observeReads();
        mImports.glQueryCounterEXT(query, target);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_disjoint_timer_query);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlQueryCounterEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(query, mScratch), target);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glSamplerParameterIuivOES(SamplerId sampler, uint32_t pname, GLuint* param) {
    GAPID_DEBUG("glSamplerParameterIuivOES(%" PRIu32 ", %u, %p)", sampler, pname, param);

    if (mImports.glSamplerParameterIuivOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glSamplerParameterIuivOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, sampler, pname, param] {
        called = true;
        observeReads();
        mImports.glSamplerParameterIuivOES(sampler, pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_border_clamp);
            subSamplerParameterIuiv(call, sampler, pname, param);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlSamplerParameterIuivOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< gapic::coder::gles::GLuint__CP >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glScissorIndexedvNV(GLuint index, GLint* v) {
    GAPID_DEBUG("glScissorIndexedvNV(%" PRIu32 ", %p)", index, v);

    if (mImports.glScissorIndexedvNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glScissorIndexedvNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, index, v] {
        called = true;
        observeReads();
        mImports.glScissorIndexedvNV(index, v);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlScissorIndexedvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< gapic::coder::gles::GLint__CP >(v, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTextureViewOES(TextureId texture, uint32_t target, GLuint origtexture, uint32_t internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) {
    GAPID_DEBUG("glTextureViewOES(%" PRIu32 ", %u, %" PRIu32 ", %u, %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);

    if (mImports.glTextureViewOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glTextureViewOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers] {
        called = true;
        observeReads();
        mImports.glTextureViewOES(texture, target, origtexture, internalformat, minlevel, numlevels, minlayer, numlayers);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_view);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTextureViewOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(texture, mScratch), target, toEncoder< uint32_t >(origtexture, mScratch), internalformat, toEncoder< uint32_t >(minlevel, mScratch), toEncoder< uint32_t >(numlevels, mScratch), toEncoder< uint32_t >(minlayer, mScratch), toEncoder< uint32_t >(numlayers, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTransformPathNV(GLuint resultPath, GLuint srcPath, uint32_t transformType, GLfloat* transformValues) {
    GAPID_DEBUG("glTransformPathNV(%" PRIu32 ", %" PRIu32 ", %u, %p)", resultPath, srcPath, transformType, transformValues);

    if (mImports.glTransformPathNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glTransformPathNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, resultPath, srcPath, transformType, transformValues] {
        called = true;
        observeReads();
        mImports.glTransformPathNV(resultPath, srcPath, transformType, transformValues);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_path_rendering);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTransformPathNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(resultPath, mScratch), toEncoder< uint32_t >(srcPath, mScratch), transformType, toEncoder< gapic::coder::gles::GLfloat__CP >(transformValues, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glValidateProgramPipelineEXT(PipelineId pipeline) {
    GAPID_DEBUG("glValidateProgramPipelineEXT(%" PRIu32 ")", pipeline);

    if (mImports.glValidateProgramPipelineEXT == nullptr) {
        GAPID_WARNING("Application called unsupported function glValidateProgramPipelineEXT");
        return;
    }

    bool called = false;
    auto call = [this, &called, pipeline] {
        called = true;
        observeReads();
        mImports.glValidateProgramPipelineEXT(pipeline);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlValidateProgramPipelineEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(pipeline, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glViewportIndexedfNV(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
    GAPID_DEBUG("glViewportIndexedfNV(%" PRIu32 ", %f, %f, %f, %f)", index, x, y, w, h);

    if (mImports.glViewportIndexedfNV == nullptr) {
        GAPID_WARNING("Application called unsupported function glViewportIndexedfNV");
        return;
    }

    bool called = false;
    auto call = [this, &called, index, x, y, w, h] {
        called = true;
        observeReads();
        mImports.glViewportIndexedfNV(index, x, y, w, h);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlViewportIndexedfNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< float >(x, mScratch), toEncoder< float >(y, mScratch), toEncoder< float >(w, mScratch), toEncoder< float >(h, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glStencilOp(uint32_t fail, uint32_t zfail, uint32_t zpass) {
    GAPID_DEBUG("glStencilOp(%u, %u, %u)", fail, zfail, zpass);

    if (mImports.glStencilOp == nullptr) {
        GAPID_WARNING("Application called unsupported function glStencilOp");
        return;
    }

    bool called = false;
    auto call = [this, &called, fail, zfail, zpass] {
        called = true;
        observeReads();
        mImports.glStencilOp(fail, zfail, zpass);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subStencilOpSeparate(call, GLenum::GL_FRONT_AND_BACK, fail, zfail, zpass);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlStencilOp coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), fail, zfail, zpass);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glClearBufferfv(uint32_t buffer, GLint drawbuffer, GLfloat* value) {
    GAPID_DEBUG("glClearBufferfv(%u, %" PRId32 ", %p)", buffer, drawbuffer, value);

    if (mImports.glClearBufferfv == nullptr) {
        GAPID_WARNING("Application called unsupported function glClearBufferfv");
        return;
    }

    bool called = false;
    auto call = [this, &called, buffer, drawbuffer, value] {
        called = true;
        observeReads();
        mImports.glClearBufferfv(buffer, drawbuffer, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (buffer) {
                case GLenum::GL_COLOR: {
                    std::shared_ptr<Context> l_ctx = subGetContext(call);
                    subGlErrorInvalidValueIf(call, (drawbuffer) >= (checkNotNull(l_ctx).mConstants.mMaxDrawBuffers));
                    read(slice(value, 0ULL, 4ULL));
                    break;
                }
                case GLenum::GL_DEPTH: {
                    subGlErrorInvalidValueIf(call, (drawbuffer) != ((GLint)(0L)));
                    read(slice(value, 0ULL, 1ULL));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, buffer);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlClearBufferfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), buffer, toEncoder< int32_t >(drawbuffer, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glClearStencil(GLint stencil) {
    GAPID_DEBUG("glClearStencil(%" PRId32 ")", stencil);

    if (mImports.glClearStencil == nullptr) {
        GAPID_WARNING("Application called unsupported function glClearStencil");
        return;
    }

    bool called = false;
    auto call = [this, &called, stencil] {
        called = true;
        observeReads();
        mImports.glClearStencil(stencil);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mFramebuffer.mStencilClearValue = stencil;
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlClearStencil coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(stencil, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
    GAPID_DEBUG("glColorMask(%" PRIu8 ", %" PRIu8 ", %" PRIu8 ", %" PRIu8 ")", red, green, blue, alpha);

    if (mImports.glColorMask == nullptr) {
        GAPID_WARNING("Application called unsupported function glColorMask");
        return;
    }

    bool called = false;
    auto call = [this, &called, red, green, blue, alpha] {
        called = true;
        observeReads();
        mImports.glColorMask(red, green, blue, alpha);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            for (DrawBufferIndex l_i = (DrawBufferIndex)(0UL); l_i < (DrawBufferIndex)(checkNotNull(l_ctx).mConstants.mMaxDrawBuffers); ++l_i) {
                checkNotNull(l_ctx).mFramebuffer.mColorWritemask[l_i] = {red, green, blue, alpha};
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlColorMask coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint8_t >(red, mScratch), toEncoder< uint8_t >(green, mScratch), toEncoder< uint8_t >(blue, mScratch), toEncoder< uint8_t >(alpha, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDeleteFramebuffers(GLsizei count, FramebufferId* framebuffers) {
    GAPID_DEBUG("glDeleteFramebuffers(%" PRId32 ", %p)", count, framebuffers);

    if (mImports.glDeleteFramebuffers == nullptr) {
        GAPID_WARNING("Application called unsupported function glDeleteFramebuffers");
        return;
    }

    bool called = false;
    auto call = [this, &called, count, framebuffers] {
        called = true;
        observeReads();
        mImports.glDeleteFramebuffers(count, framebuffers);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            subGlErrorInvalidValueIf(call, (count) < ((GLsizei)(0L)));
            Slice<FramebufferId> l_f = slice(framebuffers, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                FramebufferId l_id = read(l_f, (uint64_t)(l_i));
                if ((l_id) != ((FramebufferId)(0UL))) {
                    checkNotNull(l_ctx).mInstances.mFramebuffers.erase(l_id);
                    if ((l_id) == (findOrZero(checkNotNull(l_ctx).mBoundFramebuffers, GLenum::GL_READ_FRAMEBUFFER))) {
                        checkNotNull(l_ctx).mBoundFramebuffers[GLenum::GL_READ_FRAMEBUFFER] = (FramebufferId)(0UL);
                    }
                    if ((l_id) == (findOrZero(checkNotNull(l_ctx).mBoundFramebuffers, GLenum::GL_DRAW_FRAMEBUFFER))) {
                        checkNotNull(l_ctx).mBoundFramebuffers[GLenum::GL_DRAW_FRAMEBUFFER] = (FramebufferId)(0UL);
                    }
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDeleteFramebuffers coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::FramebufferId__CP >(framebuffers, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLboolean GlesSpy::glIsFramebuffer(FramebufferId framebuffer) {
    GAPID_DEBUG("glIsFramebuffer(%" PRIu32 ")", framebuffer);

    if (mImports.glIsFramebuffer == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsFramebuffer");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, framebuffer] {
        called = true;
        observeReads();
        result = mImports.glIsFramebuffer(framebuffer);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.mFramebuffers.count(framebuffer) > 0));
            }
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsFramebuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(framebuffer, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glReadnPixels(GLint x, GLint y, GLsizei width, GLsizei height, uint32_t format, uint32_t type, GLsizei bufSize, void* data) {
    GAPID_DEBUG("glReadnPixels(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %u, %u, %" PRId32 ", %p)", x, y, width, height, format, type, bufSize, data);

    if (mImports.glReadnPixels == nullptr) {
        GAPID_WARNING("Application called unsupported function glReadnPixels");
        return;
    }

    bool called = false;
    auto call = [this, &called, x, y, width, height, format, type, bufSize, data] {
        called = true;
        observeReads();
        mImports.glReadnPixels(x, y, width, height, format, type, bufSize, data);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            call();
            subReadnPixels(call, x, y, width, height, format, type, bufSize, data);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlReadnPixels coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(x, mScratch), toEncoder< int32_t >(y, mScratch), toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch), format, type, toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::Void__P >(data, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLint GlesSpy::glGetProgramResourceLocation(ProgramId program, uint32_t programInterface, const char* name) {
    GAPID_DEBUG("glGetProgramResourceLocation(%" PRIu32 ", %u, %s)", program, programInterface, name);

    if (mImports.glGetProgramResourceLocation == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetProgramResourceLocation");
        return 0;
    }

    GLint result = 0;
    bool called = false;
    auto call = [this, &called, &result, program, programInterface, name] {
        called = true;
        observeReads();
        result = mImports.glGetProgramResourceLocation(program, programInterface, name);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (programInterface) {
                case GLenum::GL_PROGRAM_INPUT: // fall-through...
                case GLenum::GL_PROGRAM_OUTPUT: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_BUFFER: // fall-through...
                case GLenum::GL_UNIFORM: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, programInterface);
                }
            }
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetProgramResourceLocation coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), programInterface, toEncoder< const char* >(name, mScratch), toEncoder< int32_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glGetProgramResourceiv(ProgramId program, uint32_t programInterface, GLuint index, GLsizei propCount, uint32_t* props, GLsizei bufSize, GLsizei* length, GLint* params) {
    GAPID_DEBUG("glGetProgramResourceiv(%" PRIu32 ", %u, %" PRIu32 ", %" PRId32 ", %p, %" PRId32 ", %p, %p)", program, programInterface, index, propCount, props, bufSize, length, params);

    if (mImports.glGetProgramResourceiv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetProgramResourceiv");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, programInterface, index, propCount, props, bufSize, length, params] {
        called = true;
        observeReads();
        mImports.glGetProgramResourceiv(program, programInterface, index, propCount, props, bufSize, length, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (programInterface) {
                case GLenum::GL_ATOMIC_COUNTER_BUFFER: // fall-through...
                case GLenum::GL_BUFFER_VARIABLE: // fall-through...
                case GLenum::GL_PROGRAM_INPUT: // fall-through...
                case GLenum::GL_PROGRAM_OUTPUT: // fall-through...
                case GLenum::GL_SHADER_STORAGE_BLOCK: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_BUFFER: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_VARYING: // fall-through...
                case GLenum::GL_UNIFORM: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, programInterface);
                }
            }
            read(slice(props, (uint64_t)((GLsizei)(0L)), (uint64_t)(propCount)));
            call();
            if ((length) != (nullptr)) {
                GLsizei l_l = (GLsizei)(slice(length, 0ULL, 1ULL)[0ULL]);
                write(slice(length, 0ULL, 1ULL), 0ULL, l_l);
                write(slice(params, (uint64_t)((GLsizei)(0L)), (uint64_t)(l_l)));
            } else {
                write(slice(params, (uint64_t)((GLsizei)(0L)), (uint64_t)(bufSize)));
            }
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetProgramResourceiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), programInterface, toEncoder< uint32_t >(index, mScratch), toEncoder< int32_t >(propCount, mScratch), toEncoder< gapic::coder::gles::GLenum__CP >(props, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLint__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

UniformBlockId GlesSpy::glGetUniformBlockIndex(ProgramId program, const char* uniformBlockName) {
    GAPID_DEBUG("glGetUniformBlockIndex(%" PRIu32 ", %s)", program, uniformBlockName);

    if (mImports.glGetUniformBlockIndex == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetUniformBlockIndex");
        return 0;
    }

    UniformBlockId result = 0;
    bool called = false;
    auto call = [this, &called, &result, program, uniformBlockName] {
        called = true;
        observeReads();
        result = mImports.glGetUniformBlockIndex(program, uniformBlockName);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetUniformBlockIndex coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< const char* >(uniformBlockName, mScratch), toEncoder< uint32_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

UniformLocation GlesSpy::glGetUniformLocation(ProgramId program, const char* name) {
    GAPID_DEBUG("glGetUniformLocation(%" PRIu32 ", %s)", program, name);

    if (mImports.glGetUniformLocation == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetUniformLocation");
        return 0;
    }

    UniformLocation result = 0;
    bool called = false;
    auto call = [this, &called, &result, program, name] {
        called = true;
        observeReads();
        result = mImports.glGetUniformLocation(program, name);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckProgram(call, l_ctx, program);
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetUniformLocation coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< const char* >(name, mScratch), toEncoder< int32_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glGetUniformiv(ProgramId program, UniformLocation location, GLint* values) {
    GAPID_DEBUG("glGetUniformiv(%" PRIu32 ", %" PRId32 ", %p)", program, location, values);

    if (mImports.glGetUniformiv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetUniformiv");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, values] {
        called = true;
        observeReads();
        mImports.glGetUniformiv(program, location, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            ProgramId l_GetUniformv_81_program = program;
            UniformLocation l_GetUniformv_81_location = location;
            GLint* l_GetUniformv_81_values = values;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckProgram(call, l_ctx, l_GetUniformv_81_program);
            (void)l_GetUniformv_81_program;
            (void)l_GetUniformv_81_location;
            call();
            write(slice(l_GetUniformv_81_values, 0ULL, 16ULL));
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetUniformiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< gapic::coder::gles::GLint__P >(values, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glMemoryBarrierByRegion(uint32_t barriers) {
    GAPID_DEBUG("glMemoryBarrierByRegion(%u)", barriers);

    if (mImports.glMemoryBarrierByRegion == nullptr) {
        GAPID_WARNING("Application called unsupported function glMemoryBarrierByRegion");
        return;
    }

    bool called = false;
    auto call = [this, &called, barriers] {
        called = true;
        observeReads();
        mImports.glMemoryBarrierByRegion(barriers);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subSupportsBits(call, barriers, (GLbitfield::GL_ALL_BARRIER_BITS) | ((GLbitfield::GL_ATOMIC_COUNTER_BARRIER_BIT) | ((GLbitfield::GL_BUFFER_UPDATE_BARRIER_BIT) | ((GLbitfield::GL_COMMAND_BARRIER_BIT) | ((GLbitfield::GL_ELEMENT_ARRAY_BARRIER_BIT) | ((GLbitfield::GL_FRAMEBUFFER_BARRIER_BIT) | ((GLbitfield::GL_PIXEL_BUFFER_BARRIER_BIT) | ((GLbitfield::GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) | ((GLbitfield::GL_SHADER_STORAGE_BARRIER_BIT) | ((GLbitfield::GL_TEXTURE_FETCH_BARRIER_BIT) | ((GLbitfield::GL_TEXTURE_UPDATE_BARRIER_BIT) | ((GLbitfield::GL_TRANSFORM_FEEDBACK_BARRIER_BIT) | ((GLbitfield::GL_UNIFORM_BARRIER_BIT) | (GLbitfield::GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT))))))))))))));
            if ((barriers & GLbitfield::GL_ALL_BARRIER_BITS) != 0) {
            }
            if ((barriers & GLbitfield::GL_ATOMIC_COUNTER_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_BUFFER_UPDATE_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_COMMAND_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_ELEMENT_ARRAY_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_FRAMEBUFFER_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_PIXEL_BUFFER_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_SHADER_STORAGE_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_TEXTURE_FETCH_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_TEXTURE_UPDATE_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_TRANSFORM_FEEDBACK_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_UNIFORM_BARRIER_BIT) != 0) {
            }
            if ((barriers & GLbitfield::GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) != 0) {
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlMemoryBarrierByRegion coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), barriers);
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniform1f(ProgramId program, UniformLocation location, GLfloat value0) {
    GAPID_DEBUG("glProgramUniform1f(%" PRIu32 ", %" PRId32 ", %f)", program, location, value0);

    if (mImports.glProgramUniform1f == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniform1f");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, value0] {
        called = true;
        observeReads();
        mImports.glProgramUniform1f(program, location, value0);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            call();
            subProgramUniform1f(call, program, location, value0);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniform1f coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< float >(value0, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniform3ui(ProgramId program, UniformLocation location, GLuint value0, GLuint value1, GLuint value2) {
    GAPID_DEBUG("glProgramUniform3ui(%" PRIu32 ", %" PRId32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", program, location, value0, value1, value2);

    if (mImports.glProgramUniform3ui == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniform3ui");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, value0, value1, value2] {
        called = true;
        observeReads();
        mImports.glProgramUniform3ui(program, location, value0, value1, value2);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            call();
            subProgramUniform3ui(call, program, location, value0, value1, value2);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniform3ui coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< uint32_t >(value0, mScratch), toEncoder< uint32_t >(value1, mScratch), toEncoder< uint32_t >(value2, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniform4i(ProgramId program, UniformLocation location, GLint value0, GLint value1, GLint value2, GLint value3) {
    GAPID_DEBUG("glProgramUniform4i(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", program, location, value0, value1, value2, value3);

    if (mImports.glProgramUniform4i == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniform4i");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, value0, value1, value2, value3] {
        called = true;
        observeReads();
        mImports.glProgramUniform4i(program, location, value0, value1, value2, value3);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            call();
            subProgramUniform4i(call, program, location, value0, value1, value2, value3);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniform4i coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(value0, mScratch), toEncoder< int32_t >(value1, mScratch), toEncoder< int32_t >(value2, mScratch), toEncoder< int32_t >(value3, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glProgramUniformMatrix4fv(ProgramId program, UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* values) {
    GAPID_DEBUG("glProgramUniformMatrix4fv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", program, location, count, transpose, values);

    if (mImports.glProgramUniformMatrix4fv == nullptr) {
        GAPID_WARNING("Application called unsupported function glProgramUniformMatrix4fv");
        return;
    }

    bool called = false;
    auto call = [this, &called, program, location, count, transpose, values] {
        called = true;
        observeReads();
        mImports.glProgramUniformMatrix4fv(program, location, count, transpose, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniformMatrix4fv(call, program, location, count, transpose, values);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlProgramUniformMatrix4fv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< uint8_t >(transpose, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(values, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glUniform1fv(UniformLocation location, GLsizei count, GLfloat* values) {
    GAPID_DEBUG("glUniform1fv(%" PRId32 ", %" PRId32 ", %p)", location, count, values);

    if (mImports.glUniform1fv == nullptr) {
        GAPID_WARNING("Application called unsupported function glUniform1fv");
        return;
    }

    bool called = false;
    auto call = [this, &called, location, count, values] {
        called = true;
        observeReads();
        mImports.glUniform1fv(location, count, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<GLfloat> l_v = slice(values, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            UniformLocation l_Uniformv_85_location = location;
            Slice<GLfloat> l_Uniformv_85_values = l_v;
            uint32_t l_Uniformv_85_type = GLenum::GL_FLOAT;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_85_location, l_Uniformv_85_values.as<uint8_t>(), l_Uniformv_85_type);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlUniform1fv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(values, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glUniform3uiv(UniformLocation location, GLsizei count, GLuint* values) {
    GAPID_DEBUG("glUniform3uiv(%" PRId32 ", %" PRId32 ", %p)", location, count, values);

    if (mImports.glUniform3uiv == nullptr) {
        GAPID_WARNING("Application called unsupported function glUniform3uiv");
        return;
    }

    bool called = false;
    auto call = [this, &called, location, count, values] {
        called = true;
        observeReads();
        mImports.glUniform3uiv(location, count, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            Slice<Vec3u> l_v = slice((Vec3u*)(values), (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            UniformLocation l_Uniformv_101_location = location;
            Slice<Vec3u> l_Uniformv_101_values = l_v;
            uint32_t l_Uniformv_101_type = GLenum::GL_UNSIGNED_INT_VEC3;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_101_location, l_Uniformv_101_values.as<uint8_t>(), l_Uniformv_101_type);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlUniform3uiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLuint__CP >(values, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glUniform4iv(UniformLocation location, GLsizei count, GLint* values) {
    GAPID_DEBUG("glUniform4iv(%" PRId32 ", %" PRId32 ", %p)", location, count, values);

    if (mImports.glUniform4iv == nullptr) {
        GAPID_WARNING("Application called unsupported function glUniform4iv");
        return;
    }

    bool called = false;
    auto call = [this, &called, location, count, values] {
        called = true;
        observeReads();
        mImports.glUniform4iv(location, count, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<Vec4i> l_v = slice((Vec4i*)(values), (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            UniformLocation l_Uniformv_105_location = location;
            Slice<Vec4i> l_Uniformv_105_values = l_v;
            uint32_t l_Uniformv_105_type = GLenum::GL_INT_VEC4;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_105_location, l_Uniformv_105_values.as<uint8_t>(), l_Uniformv_105_type);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlUniform4iv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLint__CP >(values, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetMultisamplefv(uint32_t pname, GLuint index, GLfloat* val) {
    GAPID_DEBUG("glGetMultisamplefv(%u, %" PRIu32 ", %p)", pname, index, val);

    if (mImports.glGetMultisamplefv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetMultisamplefv");
        return;
    }

    bool called = false;
    auto call = [this, &called, pname, index, val] {
        called = true;
        observeReads();
        mImports.glGetMultisamplefv(pname, index, val);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (pname) {
                case GLenum::GL_SAMPLE_POSITION: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, pname);
                }
            }
            read(slice(val, 0ULL, 2ULL));
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetMultisamplefv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< uint32_t >(index, mScratch), toEncoder< gapic::coder::gles::GLfloat__P >(val, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLboolean GlesSpy::glIsSync(GLsync sync) {
    GAPID_DEBUG("glIsSync(%p)", sync);

    if (mImports.glIsSync == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsSync");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, sync] {
        called = true;
        observeReads();
        result = mImports.glIsSync(sync);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            GLsync l_IsSync_115_sync = sync;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            GLboolean l_IsSync_115_result = (GLboolean)(checkNotNull(l_ctx).mInstances.mSyncObjects.count(l_IsSync_115_sync) > 0);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>(l_IsSync_115_result);
            }
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsSync coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glDeleteTextures(GLsizei count, TextureId* textures) {
    GAPID_DEBUG("glDeleteTextures(%" PRId32 ", %p)", count, textures);

    if (mImports.glDeleteTextures == nullptr) {
        GAPID_WARNING("Application called unsupported function glDeleteTextures");
        return;
    }

    bool called = false;
    auto call = [this, &called, count, textures] {
        called = true;
        observeReads();
        mImports.glDeleteTextures(count, textures);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subGlErrorInvalidValueIf(call, (count) < ((GLsizei)(0L)));
            Slice<TextureId> l_t = slice(textures, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                TextureId l_id = read(l_t, (uint64_t)(l_i));
                if ((l_id) != ((TextureId)(0UL))) {
                    checkNotNull(l_ctx).mInstances.mTextures.erase(l_id);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDeleteTextures coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::TextureId__CP >(textures, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetSamplerParameterfv(SamplerId sampler, uint32_t pname, GLfloat* params) {
    GAPID_DEBUG("glGetSamplerParameterfv(%" PRIu32 ", %u, %p)", sampler, pname, params);

    if (mImports.glGetSamplerParameterfv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetSamplerParameterfv");
        return;
    }

    bool called = false;
    auto call = [this, &called, sampler, pname, params] {
        called = true;
        observeReads();
        mImports.glGetSamplerParameterfv(sampler, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            SamplerId l_GetSamplerParameterv_116_sampler = sampler;
            uint32_t l_GetSamplerParameterv_116_pname = pname;
            GLfloat* l_GetSamplerParameterv_116_params = params;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            std::shared_ptr<Sampler> l_s = findOrZero(checkNotNull(l_ctx).mInstances.mSamplers, l_GetSamplerParameterv_116_sampler);
            call();
            switch (l_GetSamplerParameterv_116_pname) {
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mCompareFunc));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mCompareMode));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mMinFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mMagFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_s).mMinLod);
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_s).mMaxLod);
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mWrapR));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mWrapS));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    write(slice(l_GetSamplerParameterv_116_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_s).mWrapT));
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    Slice<GLfloat> l_p = slice(l_GetSamplerParameterv_116_params, 0ULL, 4ULL);
                    write(l_p, 0ULL, checkNotNull(l_s).mBorderColor[0ULL]);
                    write(l_p, 1ULL, checkNotNull(l_s).mBorderColor[1ULL]);
                    write(l_p, 2ULL, checkNotNull(l_s).mBorderColor[2ULL]);
                    write(l_p, 3ULL, checkNotNull(l_s).mBorderColor[3ULL]);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetSamplerParameterv_116_pname);
                }
            }
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetSamplerParameterfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< gapic::coder::gles::GLfloat__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLboolean GlesSpy::glIsTexture(TextureId texture) {
    GAPID_DEBUG("glIsTexture(%" PRIu32 ")", texture);

    if (mImports.glIsTexture == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsTexture");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, texture] {
        called = true;
        observeReads();
        result = mImports.glIsTexture(texture);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.mTextures.count(texture) > 0));
            }
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsTexture coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(texture, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glSamplerParameterf(SamplerId sampler, uint32_t pname, GLfloat param) {
    GAPID_DEBUG("glSamplerParameterf(%" PRIu32 ", %u, %f)", sampler, pname, param);

    if (mImports.glSamplerParameterf == nullptr) {
        GAPID_WARNING("Application called unsupported function glSamplerParameterf");
        return;
    }

    bool called = false;
    auto call = [this, &called, sampler, pname, param] {
        called = true;
        observeReads();
        mImports.glSamplerParameterf(sampler, pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            Vec1f l_params = {param};
            SamplerId l_SamplerParameterv_120_sampler = sampler;
            uint32_t l_SamplerParameterv_120_pname = pname;
            Vec1f l_SamplerParameterv_120_params = l_params;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            std::shared_ptr<Sampler> l_s = findOrZero(checkNotNull(l_ctx).mInstances.mSamplers, l_SamplerParameterv_120_sampler);
            switch (l_SamplerParameterv_120_pname) {
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    checkNotNull(l_s).mCompareFunc = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    checkNotNull(l_s).mCompareMode = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    checkNotNull(l_s).mMinFilter = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    checkNotNull(l_s).mMagFilter = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    checkNotNull(l_s).mMinLod = l_SamplerParameterv_120_params[0ULL];
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    checkNotNull(l_s).mMaxLod = l_SamplerParameterv_120_params[0ULL];
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    checkNotNull(l_s).mWrapR = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    checkNotNull(l_s).mWrapS = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    checkNotNull(l_s).mWrapT = (uint32_t)(l_SamplerParameterv_120_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_SamplerParameterv_120_pname);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlSamplerParameterf coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< float >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTexParameteriv(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glTexParameteriv(%u, %u, %p)", target, pname, params);

    if (mImports.glTexParameteriv == nullptr) {
        GAPID_WARNING("Application called unsupported function glTexParameteriv");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexParameteriv(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            uint32_t l_TexParameterv_127_target = target;
            uint32_t l_TexParameterv_127_pname = pname;
            GLint* l_TexParameterv_127_params = params;
            subGlErrorInvalidEnumIf(call, (l_TexParameterv_127_target) == (GLenum::GL_TEXTURE_BUFFER));
            std::shared_ptr<Texture> l_t = subGetBoundTextureOrErrorInvalidEnum(call, l_TexParameterv_127_target);
            switch (l_TexParameterv_127_pname) {
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    uint32_t l_magFilter = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    switch (l_magFilter) {
                        case GLenum::GL_NEAREST: // fall-through...
                        case GLenum::GL_LINEAR: {
                            break;
                        }
                        default: {
                            subGlErrorInvalidEnum(call, l_magFilter);
                        }
                    }
                    checkNotNull(l_t).mMagFilter = l_magFilter;
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    uint32_t l_minFilter = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    switch (l_minFilter) {
                        case GLenum::GL_NEAREST: // fall-through...
                        case GLenum::GL_LINEAR: // fall-through...
                        case GLenum::GL_NEAREST_MIPMAP_NEAREST: // fall-through...
                        case GLenum::GL_LINEAR_MIPMAP_NEAREST: // fall-through...
                        case GLenum::GL_NEAREST_MIPMAP_LINEAR: // fall-through...
                        case GLenum::GL_LINEAR_MIPMAP_LINEAR: {
                            break;
                        }
                        default: {
                            subGlErrorInvalidEnum(call, l_minFilter);
                        }
                    }
                    checkNotNull(l_t).mMinFilter = l_minFilter;
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckWrapParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mWrapS = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckWrapParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mWrapT = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_BASE_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    GLint l_baseLevel = read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL);
                    subGlErrorInvalidValueIf(call, (l_baseLevel) < ((GLint)(0L)));
                    checkNotNull(l_t).mBaseLevel = l_baseLevel;
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    checkNotNull(l_t).mCompareFunc = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    checkNotNull(l_t).mCompareMode = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    GLint l_maxLevel = read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL);
                    subGlErrorInvalidValueIf(call, (l_maxLevel) < ((GLint)(0L)));
                    checkNotNull(l_t).mMaxLevel = l_maxLevel;
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    checkNotNull(l_t).mMaxLod = (GLfloat)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    checkNotNull(l_t).mMinLod = (GLfloat)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_A: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckSwizzleParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mSwizzleA = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_B: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckSwizzleParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mSwizzleB = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_G: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckSwizzleParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mSwizzleG = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckSwizzleParam(call, (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL)));
                    checkNotNull(l_t).mSwizzleR = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    checkNotNull(l_t).mWrapR = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_DEPTH_STENCIL_TEXTURE_MODE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    checkNotNull(l_t).mDepthStencilTextureMode = (uint32_t)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
                    subRequiresExtension(call, ExtensionId::GL_EXT_texture_filter_anisotropic);
                    checkNotNull(l_t).mMaxAnisotropy = (GLfloat)(read(slice(l_TexParameterv_127_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_SRGB_DECODE_EXT: {
                    subRequiresExtension(call, ExtensionId::GL_EXT_texture_sRGB_decode);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_TexParameterv_127_pname);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTexParameteriv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLint__CP >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTexStorage2DMultisample(uint32_t target, GLsizei samples, uint32_t internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) {
    GAPID_DEBUG("glTexStorage2DMultisample(%u, %" PRId32 ", %u, %" PRId32 ", %" PRId32 ", %" PRIu8 ")", target, samples, internalformat, width, height, fixedsamplelocations);

    if (mImports.glTexStorage2DMultisample == nullptr) {
        GAPID_WARNING("Application called unsupported function glTexStorage2DMultisample");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, samples, internalformat, width, height, fixedsamplelocations] {
        called = true;
        observeReads();
        mImports.glTexStorage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (target) {
                case GLenum::GL_TEXTURE_2D_MULTISAMPLE: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            switch (internalformat) {
                case GLenum::GL_DEPTH24_STENCIL8: // fall-through...
                case GLenum::GL_DEPTH32F_STENCIL8: // fall-through...
                case GLenum::GL_DEPTH_COMPONENT16: // fall-through...
                case GLenum::GL_DEPTH_COMPONENT24: // fall-through...
                case GLenum::GL_DEPTH_COMPONENT32F: // fall-through...
                case GLenum::GL_R11F_G11F_B10F: // fall-through...
                case GLenum::GL_R16F: // fall-through...
                case GLenum::GL_R16I: // fall-through...
                case GLenum::GL_R16UI: // fall-through...
                case GLenum::GL_R32F: // fall-through...
                case GLenum::GL_R32I: // fall-through...
                case GLenum::GL_R32UI: // fall-through...
                case GLenum::GL_R8: // fall-through...
                case GLenum::GL_R8I: // fall-through...
                case GLenum::GL_R8UI: // fall-through...
                case GLenum::GL_R8_SNORM: // fall-through...
                case GLenum::GL_RG16F: // fall-through...
                case GLenum::GL_RG16I: // fall-through...
                case GLenum::GL_RG16UI: // fall-through...
                case GLenum::GL_RG32F: // fall-through...
                case GLenum::GL_RG32I: // fall-through...
                case GLenum::GL_RG32UI: // fall-through...
                case GLenum::GL_RG8: // fall-through...
                case GLenum::GL_RG8I: // fall-through...
                case GLenum::GL_RG8UI: // fall-through...
                case GLenum::GL_RG8_SNORM: // fall-through...
                case GLenum::GL_RGB10_A2: // fall-through...
                case GLenum::GL_RGB10_A2UI: // fall-through...
                case GLenum::GL_RGB16F: // fall-through...
                case GLenum::GL_RGB16I: // fall-through...
                case GLenum::GL_RGB16UI: // fall-through...
                case GLenum::GL_RGB32F: // fall-through...
                case GLenum::GL_RGB32I: // fall-through...
                case GLenum::GL_RGB32UI: // fall-through...
                case GLenum::GL_RGB565: // fall-through...
                case GLenum::GL_RGB5_A1: // fall-through...
                case GLenum::GL_RGB8: // fall-through...
                case GLenum::GL_RGB8I: // fall-through...
                case GLenum::GL_RGB8UI: // fall-through...
                case GLenum::GL_RGB8_SNORM: // fall-through...
                case GLenum::GL_RGB9_E5: // fall-through...
                case GLenum::GL_RGBA16F: // fall-through...
                case GLenum::GL_RGBA16I: // fall-through...
                case GLenum::GL_RGBA16UI: // fall-through...
                case GLenum::GL_RGBA32F: // fall-through...
                case GLenum::GL_RGBA32I: // fall-through...
                case GLenum::GL_RGBA32UI: // fall-through...
                case GLenum::GL_RGBA4: // fall-through...
                case GLenum::GL_RGBA8: // fall-through...
                case GLenum::GL_RGBA8I: // fall-through...
                case GLenum::GL_RGBA8UI: // fall-through...
                case GLenum::GL_RGBA8_SNORM: // fall-through...
                case GLenum::GL_SRGB8: // fall-through...
                case GLenum::GL_SRGB8_ALPHA8: {
                    break;
                }
                case GLenum::GL_STENCIL_INDEX8: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, internalformat);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTexStorage2DMultisample coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(samples, mScratch), internalformat, toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch), toEncoder< uint8_t >(fixedsamplelocations, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDeleteTransformFeedbacks(GLsizei n, TransformFeedbackId* ids) {
    GAPID_DEBUG("glDeleteTransformFeedbacks(%" PRId32 ", %p)", n, ids);

    if (mImports.glDeleteTransformFeedbacks == nullptr) {
        GAPID_WARNING("Application called unsupported function glDeleteTransformFeedbacks");
        return;
    }

    bool called = false;
    auto call = [this, &called, n, ids] {
        called = true;
        observeReads();
        mImports.glDeleteTransformFeedbacks(n, ids);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            Slice<TransformFeedbackId> l_tfs = slice(ids, (uint64_t)((GLsizei)(0L)), (uint64_t)(n));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            for (GLsizei l_i = (GLsizei)(0L); l_i < n; ++l_i) {
                TransformFeedbackId l_id = read(l_tfs, (uint64_t)(l_i));
                if ((l_id) != ((TransformFeedbackId)(0UL))) {
                    checkNotNull(l_ctx).mInstances.mTransformFeedbacks[l_id] = std::shared_ptr<TransformFeedback>();
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDeleteTransformFeedbacks coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::TransformFeedbackId__CP >(ids, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

GLboolean GlesSpy::glIsTransformFeedback(TransformFeedbackId id) {
    GAPID_DEBUG("glIsTransformFeedback(%" PRIu32 ")", id);

    if (mImports.glIsTransformFeedback == nullptr) {
        GAPID_WARNING("Application called unsupported function glIsTransformFeedback");
        return 0;
    }

    GLboolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, id] {
        called = true;
        observeReads();
        result = mImports.glIsTransformFeedback(id);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.mTransformFeedbacks.count(id) > 0));
            }
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlIsTransformFeedback coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(id, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::glGetVertexAttribPointerv(AttributeLocation index, uint32_t pname, void** pointer) {
    GAPID_DEBUG("glGetVertexAttribPointerv(%" PRIu32 ", %u, %p)", index, pname, pointer);

    if (mImports.glGetVertexAttribPointerv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetVertexAttribPointerv");
        return;
    }

    bool called = false;
    auto call = [this, &called, index, pname, pointer] {
        called = true;
        observeReads();
        mImports.glGetVertexAttribPointerv(index, pname, pointer);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, (index) >= (checkNotNull(l_ctx).mConstants.mMaxVertexAttribs));
            subGlErrorInvalidEnumIf(call, (pname) != (GLenum::GL_VERTEX_ATTRIB_ARRAY_POINTER));
            std::shared_ptr<VertexArray> l_vao = findOrZero(checkNotNull(l_ctx).mInstances.mVertexArrays, checkNotNull(l_ctx).mBoundVertexArray);
            call();
            write(slice(pointer, 0ULL, 1ULL), 0ULL, (void*)(checkNotNull(findOrZero(checkNotNull(l_vao).mVertexAttributeArrays, index)).mPointer));
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetVertexAttribPointerv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), pname, toEncoder< gapic::coder::gles::Void__P__P >(pointer, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glVertexAttrib3fv(AttributeLocation location, GLfloat* value) {
    GAPID_DEBUG("glVertexAttrib3fv(%" PRIu32 ", %p)", location, value);

    if (mImports.glVertexAttrib3fv == nullptr) {
        GAPID_WARNING("Application called unsupported function glVertexAttrib3fv");
        return;
    }

    bool called = false;
    auto call = [this, &called, location, value] {
        called = true;
        observeReads();
        mImports.glVertexAttrib3fv(location, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<GLfloat> l_v = slice(value, 0ULL, 3ULL);
            Vec4f l_vec = {read(l_v, 0ULL), read(l_v, 1ULL), read(l_v, 2ULL), (GLfloat)(1.f)};
            call();
            subVertexAttribF(call, location, l_vec);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlVertexAttrib3fv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(location, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glVertexAttribPointer(AttributeLocation location, GLint size, uint32_t type, GLboolean normalized, GLsizei stride, VertexPointer data) {
    GAPID_DEBUG("glVertexAttribPointer(%" PRIu32 ", %" PRId32 ", %u, %" PRIu8 ", %" PRId32 ", %p)", location, size, type, normalized, stride, data);

    if (mImports.glVertexAttribPointer == nullptr) {
        GAPID_WARNING("Application called unsupported function glVertexAttribPointer");
        return;
    }

    bool called = false;
    auto call = [this, &called, location, size, type, normalized, stride, data] {
        called = true;
        observeReads();
        mImports.glVertexAttribPointer(location, size, type, normalized, stride, data);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subVertexAttribPointer(call, l_ctx, location, size, type, normalized, stride, data, false);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlVertexAttribPointer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(location, mScratch), toEncoder< int32_t >(size, mScratch), type, toEncoder< uint8_t >(normalized, mScratch), toEncoder< int32_t >(stride, mScratch), toEncoder< gapic::coder::gles::VertexPointer >(data, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

Bool GlesSpy::glXMakeCurrent(void* display, GLXDrawable drawable, GLXContext ctx) {
    GAPID_DEBUG("glXMakeCurrent(%p, %p, %p)", display, drawable, ctx);

    if (mImports.glXMakeCurrent == nullptr) {
        GAPID_WARNING("Application called unsupported function glXMakeCurrent");
        return 0;
    }

    Bool result = 0;
    bool called = false;
    auto call = [this, &called, &result, display, drawable, ctx] {
        called = true;
        observeReads();
        result = mImports.glXMakeCurrent(display, drawable, ctx);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subSetContext(call, findOrZero(this->GLXContexts, ctx));
            call();
            break;
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlXMakeCurrent coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::Void__P >(display, mScratch), toEncoder< gapic::coder::gles::GLXDrawable >(drawable, mScratch), toEncoder< gapic::coder::gles::GLXContext >(ctx, mScratch), toEncoder< int >(result, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);


    return result;
}

void GlesSpy::wglSwapBuffers(HDC hdc) {
    GAPID_DEBUG("wglSwapBuffers(%p)", hdc);

    if (mImports.wglSwapBuffers == nullptr) {
        GAPID_WARNING("Application called unsupported function wglSwapBuffers");
        return;
    }

    bool called = false;
    auto call = [this, &called, hdc] {
        called = true;
        observeReads();
        mImports.wglSwapBuffers(hdc);
    };

    onPreEndOfFrame();

    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::WglSwapBuffers coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::HDC >(hdc, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetQueryObjectui64v(QueryId query, uint32_t parameter, uint64_t* value) {
    GAPID_DEBUG("glGetQueryObjectui64v(%" PRIu32 ", %u, %p)", query, parameter, value);

    if (mImports.glGetQueryObjectui64v == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetQueryObjectui64v");
        return;
    }

    bool called = false;
    auto call = [this, &called, query, parameter, value] {
        called = true;
        observeReads();
        mImports.glGetQueryObjectui64v(query, parameter, value);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            call();
            write(slice(value, 0ULL, 1ULL), 0ULL, slice(value, 0ULL, 1ULL)[0ULL]);
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetQueryObjectui64v coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(query, mScratch), parameter, toEncoder< gapic::coder::gles::U64__P >(value, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glAlphaFuncxOES(uint32_t func, GLfixed ref) {
    GAPID_DEBUG("glAlphaFuncxOES(%u, %" PRId32 ")", func, ref);

    if (mImports.glAlphaFuncxOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glAlphaFuncxOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, func, ref] {
        called = true;
        observeReads();
        mImports.glAlphaFuncxOES(func, ref);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlAlphaFuncxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), func, toEncoder< int32_t >(ref, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glBindFramebufferOES(uint32_t target, GLuint framebuffer) {
    GAPID_DEBUG("glBindFramebufferOES(%u, %" PRIu32 ")", target, framebuffer);

    if (mImports.glBindFramebufferOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glBindFramebufferOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, framebuffer] {
        called = true;
        observeReads();
        mImports.glBindFramebufferOES(target, framebuffer);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_framebuffer_object);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlBindFramebufferOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(framebuffer, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glClearDepthxOES(GLfixed depth) {
    GAPID_DEBUG("glClearDepthxOES(%" PRId32 ")", depth);

    if (mImports.glClearDepthxOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glClearDepthxOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, depth] {
        called = true;
        observeReads();
        mImports.glClearDepthxOES(depth);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlClearDepthxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(depth, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glColor4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) {
    GAPID_DEBUG("glColor4x(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", red, green, blue, alpha);

    if (mImports.glColor4x == nullptr) {
        GAPID_WARNING("Application called unsupported function glColor4x");
        return;
    }

    bool called = false;
    auto call = [this, &called, red, green, blue, alpha] {
        called = true;
        observeReads();
        mImports.glColor4x(red, green, blue, alpha);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlColor4x coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(red, mScratch), toEncoder< int32_t >(green, mScratch), toEncoder< int32_t >(blue, mScratch), toEncoder< int32_t >(alpha, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDepthRangexOES(GLfixed n, GLfixed f) {
    GAPID_DEBUG("glDepthRangexOES(%" PRId32 ", %" PRId32 ")", n, f);

    if (mImports.glDepthRangexOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glDepthRangexOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, n, f] {
        called = true;
        observeReads();
        mImports.glDepthRangexOES(n, f);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDepthRangexOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< int32_t >(f, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glDrawTexsvOES(GLshort* coords) {
    GAPID_DEBUG("glDrawTexsvOES(%p)", coords);

    if (mImports.glDrawTexsvOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glDrawTexsvOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, coords] {
        called = true;
        observeReads();
        mImports.glDrawTexsvOES(coords);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_texture);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDrawTexsvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLshort__CP >(coords, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);
    onPostDrawCall();

}

void GlesSpy::glGenFramebuffersOES(GLsizei n, GLuint* framebuffers) {
    GAPID_DEBUG("glGenFramebuffersOES(%" PRId32 ", %p)", n, framebuffers);

    if (mImports.glGenFramebuffersOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glGenFramebuffersOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, n, framebuffers] {
        called = true;
        observeReads();
        mImports.glGenFramebuffersOES(n, framebuffers);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_framebuffer_object);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGenFramebuffersOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(framebuffers, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetClipPlanefOES(uint32_t plane, GLfloat* equation) {
    GAPID_DEBUG("glGetClipPlanefOES(%u, %p)", plane, equation);

    if (mImports.glGetClipPlanefOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetClipPlanefOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, plane, equation] {
        called = true;
        observeReads();
        mImports.glGetClipPlanefOES(plane, equation);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_single_precision);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetClipPlanefOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), plane, toEncoder< gapic::coder::gles::GLfloat__P >(equation, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetFramebufferAttachmentParameterivOES(uint32_t target, uint32_t attachment, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetFramebufferAttachmentParameterivOES(%u, %u, %u, %p)", target, attachment, pname, params);

    if (mImports.glGetFramebufferAttachmentParameterivOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetFramebufferAttachmentParameterivOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, attachment, pname, params] {
        called = true;
        observeReads();
        mImports.glGetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_framebuffer_object);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetFramebufferAttachmentParameterivOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, attachment, pname, toEncoder< gapic::coder::gles::GLint__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetMaterialxv(uint32_t face, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glGetMaterialxv(%u, %u, %p)", face, pname, params);

    if (mImports.glGetMaterialxv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetMaterialxv");
        return;
    }

    bool called = false;
    auto call = [this, &called, face, pname, params] {
        called = true;
        observeReads();
        mImports.glGetMaterialxv(face, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetMaterialxv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), face, pname, toEncoder< gapic::coder::gles::GLfixed__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetTexEnviv(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetTexEnviv(%u, %u, %p)", target, pname, params);

    if (mImports.glGetTexEnviv == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetTexEnviv");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexEnviv(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetTexEnviv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLint__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetTexEnvxvOES(uint32_t target, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glGetTexEnvxvOES(%u, %u, %p)", target, pname, params);

    if (mImports.glGetTexEnvxvOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetTexEnvxvOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexEnvxvOES(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetTexEnvxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLfixed__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glGetTexGenivOES(uint32_t coord, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetTexGenivOES(%u, %u, %p)", coord, pname, params);

    if (mImports.glGetTexGenivOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glGetTexGenivOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, coord, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexGenivOES(coord, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_cube_map);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetTexGenivOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), coord, pname, toEncoder< gapic::coder::gles::GLint__P >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glLightModelx(uint32_t pname, GLfixed param) {
    GAPID_DEBUG("glLightModelx(%u, %" PRId32 ")", pname, param);

    if (mImports.glLightModelx == nullptr) {
        GAPID_WARNING("Application called unsupported function glLightModelx");
        return;
    }

    bool called = false;
    auto call = [this, &called, pname, param] {
        called = true;
        observeReads();
        mImports.glLightModelx(pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlLightModelx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< int32_t >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glLightxvOES(uint32_t light, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glLightxvOES(%u, %u, %p)", light, pname, params);

    if (mImports.glLightxvOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glLightxvOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, light, pname, params] {
        called = true;
        observeReads();
        mImports.glLightxvOES(light, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlLightxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), light, pname, toEncoder< gapic::coder::gles::GLfixed__CP >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glMaterialx(uint32_t face, uint32_t pname, GLfixed param) {
    GAPID_DEBUG("glMaterialx(%u, %u, %" PRId32 ")", face, pname, param);

    if (mImports.glMaterialx == nullptr) {
        GAPID_WARNING("Application called unsupported function glMaterialx");
        return;
    }

    bool called = false;
    auto call = [this, &called, face, pname, param] {
        called = true;
        observeReads();
        mImports.glMaterialx(face, pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlMaterialx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), face, pname, toEncoder< int32_t >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glOrthoxOES(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) {
    GAPID_DEBUG("glOrthoxOES(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", l, r, b, t, n, f);

    if (mImports.glOrthoxOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glOrthoxOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, l, r, b, t, n, f] {
        called = true;
        observeReads();
        mImports.glOrthoxOES(l, r, b, t, n, f);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlOrthoxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(l, mScratch), toEncoder< int32_t >(r, mScratch), toEncoder< int32_t >(b, mScratch), toEncoder< int32_t >(t, mScratch), toEncoder< int32_t >(n, mScratch), toEncoder< int32_t >(f, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glPointParameterx(uint32_t pname, GLfixed param) {
    GAPID_DEBUG("glPointParameterx(%u, %" PRId32 ")", pname, param);

    if (mImports.glPointParameterx == nullptr) {
        GAPID_WARNING("Application called unsupported function glPointParameterx");
        return;
    }

    bool called = false;
    auto call = [this, &called, pname, param] {
        called = true;
        observeReads();
        mImports.glPointParameterx(pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlPointParameterx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< int32_t >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glPolygonOffsetx(GLfixed factor, GLfixed units) {
    GAPID_DEBUG("glPolygonOffsetx(%" PRId32 ", %" PRId32 ")", factor, units);

    if (mImports.glPolygonOffsetx == nullptr) {
        GAPID_WARNING("Application called unsupported function glPolygonOffsetx");
        return;
    }

    bool called = false;
    auto call = [this, &called, factor, units] {
        called = true;
        observeReads();
        mImports.glPolygonOffsetx(factor, units);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlPolygonOffsetx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(factor, mScratch), toEncoder< int32_t >(units, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) {
    GAPID_DEBUG("glRotatef(%f, %f, %f, %f)", angle, x, y, z);

    if (mImports.glRotatef == nullptr) {
        GAPID_WARNING("Application called unsupported function glRotatef");
        return;
    }

    bool called = false;
    auto call = [this, &called, angle, x, y, z] {
        called = true;
        observeReads();
        mImports.glRotatef(angle, x, y, z);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlRotatef coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(angle, mScratch), toEncoder< float >(x, mScratch), toEncoder< float >(y, mScratch), toEncoder< float >(z, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glScalexOES(GLfixed x, GLfixed y, GLfixed z) {
    GAPID_DEBUG("glScalexOES(%" PRId32 ", %" PRId32 ", %" PRId32 ")", x, y, z);

    if (mImports.glScalexOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glScalexOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, x, y, z] {
        called = true;
        observeReads();
        mImports.glScalexOES(x, y, z);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlScalexOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(x, mScratch), toEncoder< int32_t >(y, mScratch), toEncoder< int32_t >(z, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTexCoordPointer(GLint size, uint32_t type, GLsizei stride, void* pointer) {
    GAPID_DEBUG("glTexCoordPointer(%" PRId32 ", %u, %" PRId32 ", %p)", size, type, stride, pointer);

    if (mImports.glTexCoordPointer == nullptr) {
        GAPID_WARNING("Application called unsupported function glTexCoordPointer");
        return;
    }

    bool called = false;
    auto call = [this, &called, size, type, stride, pointer] {
        called = true;
        observeReads();
        mImports.glTexCoordPointer(size, type, stride, pointer);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTexCoordPointer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(size, mScratch), type, toEncoder< int32_t >(stride, mScratch), toEncoder< gapic::coder::gles::Void__CP >(pointer, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTexEnvi(uint32_t target, uint32_t pname, GLint param) {
    GAPID_DEBUG("glTexEnvi(%u, %u, %" PRId32 ")", target, pname, param);

    if (mImports.glTexEnvi == nullptr) {
        GAPID_WARNING("Application called unsupported function glTexEnvi");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, param] {
        called = true;
        observeReads();
        mImports.glTexEnvi(target, pname, param);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTexEnvi coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< int32_t >(param, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glTexParameterxvOES(uint32_t target, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glTexParameterxvOES(%u, %u, %p)", target, pname, params);

    if (mImports.glTexParameterxvOES == nullptr) {
        GAPID_WARNING("Application called unsupported function glTexParameterxvOES");
        return;
    }

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexParameterxvOES(target, pname, params);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_fixed_point);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlTexParameterxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLfixed__CP >(params, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::glWeightPointerOESBounds(GLint size, uint32_t type, GLsizei stride, void* pointer, GLsizei count) {
    GAPID_DEBUG("glWeightPointerOESBounds(%" PRId32 ", %u, %" PRId32 ", %p, %" PRId32 ")", size, type, stride, pointer, count);

    if (mImports.glWeightPointerOESBounds == nullptr) {
        GAPID_WARNING("Application called unsupported function glWeightPointerOESBounds");
        return;
    }

    bool called = false;
    auto call = [this, &called, size, type, stride, pointer, count] {
        called = true;
        observeReads();
        mImports.glWeightPointerOESBounds(size, type, stride, pointer, count);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_matrix_palette);
            subErrorGLES10notSupported(call);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlWeightPointerOESBounds coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(size, mScratch), type, toEncoder< int32_t >(stride, mScratch), toEncoder< gapic::coder::gles::Void__CP >(pointer, mScratch), toEncoder< int32_t >(count, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}

void GlesSpy::switchThread(ThreadID threadID) {
    GAPID_DEBUG("switchThread(%" PRIu64 ")", threadID);

    bool called = false;
    auto call = [this, &called, threadID] {
        called = true;
        observeReads();
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            this->CurrentThread = threadID;
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::SwitchThread coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint64_t >(threadID, mScratch));
    coder.mextras.append(&mObservations);

    if (counter_at_end > counter_at_begin + 1 ||
    counter_at_begin != mExpectedNextCommandStartCounterValue) {
        coder.mextras.append(&counter_value_encodable);
    }
    mExpectedNextCommandStartCounterValue = counter_at_end + 1;

    addExtras(coder);
    mEncoder->Variant(&coder);

}
} // namespace gapii