/*
 * 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::glTexBufferRangeEXT(uint32_t target, uint32_t internalformat, BufferId buffer, GLintptr offset, GLsizeiptr size) {
    GAPID_DEBUG("glTexBufferRangeEXT(%u, %u, %" PRIu32 ", %" PRId32 ", %" PRId32 ")", target, internalformat, buffer, offset, size);

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

    bool called = false;
    auto call = [this, &called, target, internalformat, buffer, offset, size] {
        called = true;
        observeReads();
        mImports.glTexBufferRangeEXT(target, internalformat, buffer, offset, size);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_texture_buffer);
            subTexBufferRange(call, target, internalformat, buffer, offset, size);
            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::GlTexBufferRangeEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, internalformat, toEncoder< uint32_t >(buffer, mScratch), toEncoder< int32_t >(offset, mScratch), toEncoder< int32_t >(size, 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::glTexParameterIivEXT(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glTexParameterIivEXT(%u, %u, %p)", target, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexParameterIivEXT(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));
            subTexParameterIiv(call, target, pname, params);
            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::GlTexParameterIivEXT 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::glGetQueryiv(uint32_t target, uint32_t parameter, GLint* value) {
    GAPID_DEBUG("glGetQueryiv(%u, %u, %p)", target, parameter, value);

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

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


    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);
                }
            }
            call();
            switch (parameter) {
                case GLenum::GL_CURRENT_QUERY: {
                    std::shared_ptr<Context> l_ctx = subGetContext(call);
                    if (checkNotNull(l_ctx).mActiveQueries.count(target) > 0) {
                        write(slice(value, 0ULL, 1ULL), 0ULL, (GLint)(findOrZero(checkNotNull(l_ctx).mActiveQueries, target)));
                    } else {
                        write(slice(value, 0ULL, 1ULL), 0ULL, (GLint)(0L));
                    }
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, parameter);
                }
            }
        } 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::GlGetQueryiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, parameter, toEncoder< gapic::coder::gles::GLint__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::glCopyBufferSubData(uint32_t readTarget, uint32_t writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
    GAPID_DEBUG("glCopyBufferSubData(%u, %u, %" PRId32 ", %" PRId32 ", %" PRId32 ")", readTarget, writeTarget, readOffset, writeOffset, size);

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

    bool called = false;
    auto call = [this, &called, readTarget, writeTarget, readOffset, writeOffset, size] {
        called = true;
        observeReads();
        mImports.glCopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subCopyBufferSubData(call, readTarget, writeTarget, readOffset, writeOffset, size);
            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::GlCopyBufferSubData coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), readTarget, writeTarget, toEncoder< int32_t >(readOffset, mScratch), toEncoder< int32_t >(writeOffset, mScratch), toEncoder< int32_t >(size, 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::glDebugMessageInsert(uint32_t source, uint32_t type, GLuint id, uint32_t severity, GLsizei length, GLchar* message) {
    GAPID_DEBUG("glDebugMessageInsert(%u, %u, %" PRIu32 ", %u, %" PRId32 ", %p)", source, type, id, severity, length, message);

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

    bool called = false;
    auto call = [this, &called, source, type, id, severity, length, message] {
        called = true;
        observeReads();
        mImports.glDebugMessageInsert(source, type, id, severity, length, message);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subDebugMessageInsert(call, source, type, id, severity, length, message);
            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::GlDebugMessageInsert coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), source, type, toEncoder< uint32_t >(id, mScratch), severity, toEncoder< int32_t >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__CP >(message, 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::glGetObjectPtrLabel(void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) {
    GAPID_DEBUG("glGetObjectPtrLabel(%p, %" PRId32 ", %p, %p)", ptr, bufSize, length, label);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            call();
            subGetObjectPtrLabel(call, ptr, 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::GlGetObjectPtrLabel coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::Void__CP >(ptr, 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::glObjectLabel(uint32_t identifier, GLuint name, GLsizei length, GLchar* label) {
    GAPID_DEBUG("glObjectLabel(%u, %" PRIu32 ", %" PRId32 ", %p)", identifier, name, length, label);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subObjectLabel(call, identifier, name, 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::GlObjectLabel coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), identifier, toEncoder< uint32_t >(name, 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::glBeginConditionalRenderNV(GLuint id, uint32_t mode) {
    GAPID_DEBUG("glBeginConditionalRenderNV(%" PRIu32 ", %u)", id, mode);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_conditional_render);
            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::GlBeginConditionalRenderNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(id, 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::glBindFragDataLocationEXT(ProgramId program, GLuint color, const char* name) {
    GAPID_DEBUG("glBindFragDataLocationEXT(%" PRIu32 ", %" PRIu32 ", %s)", program, color, name);

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

    bool called = false;
    auto call = [this, &called, program, color, name] {
        called = true;
        observeReads();
        mImports.glBindFragDataLocationEXT(program, color, name);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_blend_func_extended);
            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::GlBindFragDataLocationEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< uint32_t >(color, mScratch), toEncoder< const char* >(name, 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::glBindVertexArrayOES(VertexArrayId array) {
    GAPID_DEBUG("glBindVertexArrayOES(%" PRIu32 ")", array);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_vertex_array_object);
            subBindVertexArray(call, 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::GlBindVertexArrayOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(array, 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::glClientWaitSyncAPPLE(GLsync sync, uint32_t flag, GLuint64 timeout) {
    GAPID_DEBUG("glClientWaitSyncAPPLE(%p, %u, %" PRIu64 ")", sync, flag, timeout);

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

    uint32_t result = 0;
    bool called = false;
    auto call = [this, &called, &result, sync, flag, timeout] {
        called = true;
        observeReads();
        result = mImports.glClientWaitSyncAPPLE(sync, flag, timeout);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_APPLE_sync);
            GLsync l_ClientWaitSync_58_sync = sync;
            uint32_t l_ClientWaitSync_58_syncFlags = flag;
            GLuint64 l_ClientWaitSync_58_timeout = timeout;
            subSupportsBits(call, l_ClientWaitSync_58_syncFlags, GLbitfield::GL_SYNC_FLUSH_COMMANDS_BIT);
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, !(checkNotNull(l_ctx).mInstances.mSyncObjects.count(l_ClientWaitSync_58_sync) > 0));
            if ((l_ClientWaitSync_58_syncFlags & GLbitfield::GL_SYNC_FLUSH_COMMANDS_BIT) != 0) {
            }
            (void)l_ClientWaitSync_58_timeout;
            call();
            uint32_t l_ClientWaitSync_58_result = 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::GlClientWaitSyncAPPLE coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, mScratch), flag, toEncoder< uint64_t >(timeout, 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::glCopyBufferSubDataNV(uint32_t readTarget, uint32_t writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) {
    GAPID_DEBUG("glCopyBufferSubDataNV(%u, %u, %" PRId32 ", %" PRId32 ", %" PRId32 ")", readTarget, writeTarget, readOffset, writeOffset, size);

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

    bool called = false;
    auto call = [this, &called, readTarget, writeTarget, readOffset, writeOffset, size] {
        called = true;
        observeReads();
        mImports.glCopyBufferSubDataNV(readTarget, writeTarget, readOffset, writeOffset, size);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_copy_buffer);
            subCopyBufferSubData(call, readTarget, writeTarget, readOffset, writeOffset, size);
            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::GlCopyBufferSubDataNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), readTarget, writeTarget, toEncoder< int32_t >(readOffset, mScratch), toEncoder< int32_t >(writeOffset, mScratch), toEncoder< int32_t >(size, 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::glCoverageOperationNV(uint32_t operation) {
    GAPID_DEBUG("glCoverageOperationNV(%u)", operation);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_coverage_sample);
            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::GlCoverageOperationNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), operation);
    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::glCreatePerfQueryINTEL(GLuint queryId, GLuint* queryHandle) {
    GAPID_DEBUG("glCreatePerfQueryINTEL(%" PRIu32 ", %p)", queryId, queryHandle);

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

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


    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::GlCreatePerfQueryINTEL coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(queryId, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(queryHandle, 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::glDeletePerfMonitorsAMD(GLsizei n, GLuint* monitors) {
    GAPID_DEBUG("glDeletePerfMonitorsAMD(%" PRId32 ", %p)", n, monitors);

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

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


    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::GlDeletePerfMonitorsAMD coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(monitors, 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::glDisableiNV(uint32_t target, GLuint index) {
    GAPID_DEBUG("glDisableiNV(%u, %" PRIu32 ")", target, index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            subDisablei(call, target, index);
            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::GlDisableiNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, 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::glDrawElementsBaseVertexEXT(uint32_t mode, GLsizei count, uint32_t type, IndicesPointer indices, GLint basevertex) {
    GAPID_DEBUG("glDrawElementsBaseVertexEXT(%u, %" PRId32 ", %u, %p, %" PRId32 ")", mode, count, type, indices, basevertex);

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

    bool called = false;
    auto call = [this, &called, mode, count, type, indices, basevertex] {
        called = true;
        observeReads();
        mImports.glDrawElementsBaseVertexEXT(mode, count, type, indices, basevertex);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_elements_base_vertex);
            subDrawElementsBaseVertex(call, mode, count, type, indices, basevertex);
            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::GlDrawElementsBaseVertexEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, toEncoder< int32_t >(count, mScratch), type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch), toEncoder< int32_t >(basevertex, 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::glDrawElementsInstancedANGLE(uint32_t mode, GLsizei count, uint32_t type, IndicesPointer indices, GLsizei primcount) {
    GAPID_DEBUG("glDrawElementsInstancedANGLE(%u, %" PRId32 ", %u, %p, %" PRId32 ")", mode, count, type, indices, primcount);

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

    bool called = false;
    auto call = [this, &called, mode, count, type, indices, primcount] {
        called = true;
        observeReads();
        mImports.glDrawElementsInstancedANGLE(mode, count, type, indices, primcount);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_ANGLE_instanced_arrays);
            subDrawElementsInstanced(call, mode, count, type, indices, primcount);
            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::GlDrawElementsInstancedANGLE coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, toEncoder< int32_t >(count, mScratch), type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch), toEncoder< int32_t >(primcount, 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::glDrawElementsInstancedEXT(uint32_t mode, GLsizei count, uint32_t type, IndicesPointer indices, GLsizei primcount) {
    GAPID_DEBUG("glDrawElementsInstancedEXT(%u, %" PRId32 ", %u, %p, %" PRId32 ")", mode, count, type, indices, primcount);

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

    bool called = false;
    auto call = [this, &called, mode, count, type, indices, primcount] {
        called = true;
        observeReads();
        mImports.glDrawElementsInstancedEXT(mode, count, type, indices, primcount);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension2(call, ExtensionId::GL_EXT_draw_instanced, ExtensionId::GL_EXT_instanced_arrays);
            subDrawElementsInstanced(call, mode, count, type, indices, primcount);
            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::GlDrawElementsInstancedEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, toEncoder< int32_t >(count, mScratch), type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch), toEncoder< int32_t >(primcount, 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::glEnableiOES(uint32_t target, GLuint index) {
    GAPID_DEBUG("glEnableiOES(%u, %" PRIu32 ")", target, index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_buffers_indexed);
            subEnablei(call, target, index);
            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::GlEnableiOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, 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::glEndConditionalRenderNV() {
    GAPID_DEBUG("glEndConditionalRenderNV()");

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_conditional_render);
            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::GlEndConditionalRenderNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras));
    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::glExtGetProgramBinarySourceQCOM(ProgramId program, uint32_t shadertype, GLchar* source, GLint* length) {
    GAPID_DEBUG("glExtGetProgramBinarySourceQCOM(%" PRIu32 ", %u, %p, %p)", program, shadertype, source, length);

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

    bool called = false;
    auto call = [this, &called, program, shadertype, source, length] {
        called = true;
        observeReads();
        mImports.glExtGetProgramBinarySourceQCOM(program, shadertype, source, length);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_QCOM_extended_get2);
            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::GlExtGetProgramBinarySourceQCOM coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), shadertype, toEncoder< gapic::coder::gles::GLchar__P >(source, mScratch), toEncoder< gapic::coder::gles::GLint__P >(length, 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::glExtTexObjectStateOverrideiQCOM(uint32_t target, uint32_t pname, GLint param) {
    GAPID_DEBUG("glExtTexObjectStateOverrideiQCOM(%u, %u, %" PRId32 ")", target, pname, param);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_QCOM_extended_get);
            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::GlExtTexObjectStateOverrideiQCOM 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::glFlushMappedBufferRangeEXT(uint32_t target, GLintptr offset, GLsizeiptr length) {
    GAPID_DEBUG("glFlushMappedBufferRangeEXT(%u, %" PRId32 ", %" PRId32 ")", target, offset, length);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_map_buffer_range);
            subFlushMappedBufferRange(call, target, offset, length);
            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::GlFlushMappedBufferRangeEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(offset, mScratch), toEncoder< int32_t >(length, 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::glFramebufferTextureMultiviewOVR(uint32_t target, uint32_t attachment, TextureId texture, GLint level, GLint baseViewIndex, GLsizei numViews) {
    GAPID_DEBUG("glFramebufferTextureMultiviewOVR(%u, %u, %" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", target, attachment, texture, level, baseViewIndex, numViews);

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

    bool called = false;
    auto call = [this, &called, target, attachment, texture, level, baseViewIndex, numViews] {
        called = true;
        observeReads();
        mImports.glFramebufferTextureMultiviewOVR(target, attachment, texture, level, baseViewIndex, numViews);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OVR_multiview);
            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::GlFramebufferTextureMultiviewOVR coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, attachment, toEncoder< uint32_t >(texture, mScratch), toEncoder< int32_t >(level, mScratch), toEncoder< int32_t >(baseViewIndex, mScratch), toEncoder< int32_t >(numViews, 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::glFramebufferTextureOES(uint32_t target, uint32_t attachment, TextureId texture, GLint level) {
    GAPID_DEBUG("glFramebufferTextureOES(%u, %u, %" PRIu32 ", %" PRId32 ")", target, attachment, texture, level);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_geometry_shader);
            subFramebufferTexture(call, target, attachment, texture, level);
            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::GlFramebufferTextureOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, attachment, toEncoder< uint32_t >(texture, mScratch), toEncoder< int32_t >(level, 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::glGenVertexArraysOES(GLsizei count, VertexArrayId* arrays) {
    GAPID_DEBUG("glGenVertexArraysOES(%" PRId32 ", %p)", count, arrays);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_vertex_array_object);
            GLsizei l_GenVertexArrays_60_count = count;
            VertexArrayId* l_GenVertexArrays_60_arrays = arrays;
            subGlErrorInvalidValueIf(call, (l_GenVertexArrays_60_count) < ((GLsizei)(0L)));
            Slice<VertexArrayId> l_a = slice(l_GenVertexArrays_60_arrays, (uint64_t)((GLsizei)(0L)), (uint64_t)(l_GenVertexArrays_60_count));
            call();
            for (GLsizei l_i = (GLsizei)(0L); l_i < l_GenVertexArrays_60_count; ++l_i) {
                VertexArrayId l_id = (VertexArrayId)(slice(arrays, (uint64_t)((GLsizei)(0L)), (uint64_t)(l_GenVertexArrays_60_count))[(uint64_t)(l_i)]);
                write(l_a, (uint64_t)(l_i), l_id);
            }
        } 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::GlGenVertexArraysOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::VertexArrayId__P >(arrays, 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::glGetFragDataIndexEXT(ProgramId program, const char* name) {
    GAPID_DEBUG("glGetFragDataIndexEXT(%" PRIu32 ", %s)", program, name);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_blend_func_extended);
            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::GlGetFragDataIndexEXT 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;
}

GLuint64 GlesSpy::glGetImageHandleNV(TextureId texture, GLint level, GLboolean layered, GLint layer, uint32_t format) {
    GAPID_DEBUG("glGetImageHandleNV(%" PRIu32 ", %" PRId32 ", %" PRIu8 ", %" PRId32 ", %u)", texture, level, layered, layer, format);

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

    GLuint64 result = 0;
    bool called = false;
    auto call = [this, &called, &result, texture, level, layered, layer, format] {
        called = true;
        observeReads();
        result = mImports.glGetImageHandleNV(texture, level, layered, layer, format);
    };


    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::GlGetImageHandleNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(texture, mScratch), toEncoder< int32_t >(level, mScratch), toEncoder< uint8_t >(layered, mScratch), toEncoder< int32_t >(layer, mScratch), format, 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;
}

void GlesSpy::glGetInternalformatSampleivNV(uint32_t target, uint32_t internalformat, GLsizei samples, uint32_t pname, GLsizei bufSize, GLint* params) {
    GAPID_DEBUG("glGetInternalformatSampleivNV(%u, %u, %" PRId32 ", %u, %" PRId32 ", %p)", target, internalformat, samples, pname, bufSize, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_internalformat_sample_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::GlGetInternalformatSampleivNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, internalformat, toEncoder< int32_t >(samples, mScratch), pname, toEncoder< int32_t >(bufSize, 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);

}

void GlesSpy::glGetPerfQueryDataINTEL(GLuint queryHandle, GLuint flag, GLsizei dataSize, GLvoid* data, GLuint* bytesWritten) {
    GAPID_DEBUG("glGetPerfQueryDataINTEL(%" PRIu32 ", %" PRIu32 ", %" PRId32 ", %p, %p)", queryHandle, flag, dataSize, data, bytesWritten);

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

    bool called = false;
    auto call = [this, &called, queryHandle, flag, dataSize, data, bytesWritten] {
        called = true;
        observeReads();
        mImports.glGetPerfQueryDataINTEL(queryHandle, flag, dataSize, data, bytesWritten);
    };


    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::GlGetPerfQueryDataINTEL coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(queryHandle, mScratch), toEncoder< uint32_t >(flag, mScratch), toEncoder< int32_t >(dataSize, mScratch), toEncoder< gapic::coder::gles::GLvoid__P >(data, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(bytesWritten, 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::glGetPerfQueryInfoINTEL(GLuint queryId, GLuint queryNameLength, GLchar* queryName, GLuint* dataSize, GLuint* noCounters, GLuint* noInstances, GLuint* capsMask) {
    GAPID_DEBUG("glGetPerfQueryInfoINTEL(%" PRIu32 ", %" PRIu32 ", %p, %p, %p, %p, %p)", queryId, queryNameLength, queryName, dataSize, noCounters, noInstances, capsMask);

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

    bool called = false;
    auto call = [this, &called, queryId, queryNameLength, queryName, dataSize, noCounters, noInstances, capsMask] {
        called = true;
        observeReads();
        mImports.glGetPerfQueryInfoINTEL(queryId, queryNameLength, queryName, dataSize, noCounters, noInstances, capsMask);
    };


    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::GlGetPerfQueryInfoINTEL coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(queryId, mScratch), toEncoder< uint32_t >(queryNameLength, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(queryName, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(dataSize, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(noCounters, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(noInstances, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(capsMask, 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::glGetProgramPipelineInfoLogEXT(PipelineId pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
    GAPID_DEBUG("glGetProgramPipelineInfoLogEXT(%" PRIu32 ", %" PRId32 ", %p, %p)", pipeline, bufSize, length, infoLog);

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

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


    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::GlGetProgramPipelineInfoLogEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(pipeline, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(infoLog, 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::glGetQueryObjectivEXT(QueryId query, uint32_t parameter, GLint* value) {
    GAPID_DEBUG("glGetQueryObjectivEXT(%" PRIu32 ", %u, %p)", query, parameter, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_disjoint_timer_query);
            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::GlGetQueryObjectivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(query, mScratch), parameter, toEncoder< gapic::coder::gles::GLint__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::glGetSamplerParameterIuivOES(SamplerId sampler, uint32_t pname, GLuint* params) {
    GAPID_DEBUG("glGetSamplerParameterIuivOES(%" PRIu32 ", %u, %p)", sampler, pname, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_border_clamp);
            call();
            subGetSamplerParameterIuiv(call, sampler, 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::GlGetSamplerParameterIuivOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< gapic::coder::gles::GLuint__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::glIsPathNV(GLuint path) {
    GAPID_DEBUG("glIsPathNV(%" PRIu32 ")", path);

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

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


    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::GlIsPathNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, 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::glIsQueryEXT(QueryId query) {
    GAPID_DEBUG("glIsQueryEXT(%" PRIu32 ")", query);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension2(call, ExtensionId::GL_EXT_disjoint_timer_query, ExtensionId::GL_EXT_occlusion_query_boolean);
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.mQueries.count(query) > 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::GlIsQueryEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(query, 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::glMultiDrawElementsIndirectEXT(uint32_t mode, uint32_t type, void* indirect, GLsizei drawcount, GLsizei stride) {
    GAPID_DEBUG("glMultiDrawElementsIndirectEXT(%u, %u, %p, %" PRId32 ", %" PRId32 ")", mode, type, indirect, drawcount, stride);

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

    bool called = false;
    auto call = [this, &called, mode, type, indirect, drawcount, stride] {
        called = true;
        observeReads();
        mImports.glMultiDrawElementsIndirectEXT(mode, type, indirect, drawcount, stride);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_multi_draw_indirect);
            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::GlMultiDrawElementsIndirectEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, type, toEncoder< gapic::coder::gles::Void__CP >(indirect, mScratch), toEncoder< int32_t >(drawcount, mScratch), toEncoder< int32_t >(stride, 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::glPathStencilFuncNV(uint32_t func, GLint ref, GLuint mask) {
    GAPID_DEBUG("glPathStencilFuncNV(%u, %" PRId32 ", %" PRIu32 ")", func, ref, mask);

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

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


    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::GlPathStencilFuncNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), func, toEncoder< int32_t >(ref, mScratch), toEncoder< uint32_t >(mask, 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::glPopGroupMarkerEXT() {
    GAPID_DEBUG("glPopGroupMarkerEXT()");

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_debug_marker);
            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::GlPopGroupMarkerEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras));
    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::glProgramUniform1ivEXT(ProgramId program, UniformLocation location, GLsizei count, GLint* value) {
    GAPID_DEBUG("glProgramUniform1ivEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniform1iv(call, program, location, count, 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::GlProgramUniform1ivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLint__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::glProgramUniform2fEXT(ProgramId program, UniformLocation location, GLfloat v0, GLfloat v1) {
    GAPID_DEBUG("glProgramUniform2fEXT(%" PRIu32 ", %" PRId32 ", %f, %f)", program, location, v0, v1);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            call();
            subProgramUniform2f(call, program, location, v0, v1);
        } 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::GlProgramUniform2fEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< float >(v0, mScratch), toEncoder< float >(v1, 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::glProgramUniform2uiEXT(ProgramId program, UniformLocation location, GLuint v0, GLuint v1) {
    GAPID_DEBUG("glProgramUniform2uiEXT(%" PRIu32 ", %" PRId32 ", %" PRIu32 ", %" PRIu32 ")", program, location, v0, v1);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            call();
            subProgramUniform2ui(call, program, location, v0, v1);
        } 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::GlProgramUniform2uiEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< uint32_t >(v0, mScratch), toEncoder< uint32_t >(v1, 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::glProgramUniform3iEXT(ProgramId program, UniformLocation location, GLint v0, GLint v1, GLint v2) {
    GAPID_DEBUG("glProgramUniform3iEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", program, location, v0, v1, v2);

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

    bool called = false;
    auto call = [this, &called, program, location, v0, v1, v2] {
        called = true;
        observeReads();
        mImports.glProgramUniform3iEXT(program, location, v0, v1, v2);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            call();
            subProgramUniform3i(call, program, location, v0, v1, v2);
        } 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::GlProgramUniform3iEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(v0, mScratch), toEncoder< int32_t >(v1, mScratch), toEncoder< int32_t >(v2, 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::glProgramUniform4fvEXT(ProgramId program, UniformLocation location, GLsizei count, GLfloat* value) {
    GAPID_DEBUG("glProgramUniform4fvEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniform4fv(call, program, location, count, 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::GlProgramUniform4fvEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, 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::glProgramUniform4uivEXT(ProgramId program, UniformLocation location, GLsizei count, GLuint* value) {
    GAPID_DEBUG("glProgramUniform4uivEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniform4uiv(call, program, location, count, 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::GlProgramUniform4uivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLuint__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::glRasterSamplesEXT(GLuint samples, GLboolean fixedsamplelocations) {
    GAPID_DEBUG("glRasterSamplesEXT(%" PRIu32 ", %" PRIu8 ")", samples, fixedsamplelocations);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension3(call, ExtensionId::GL_EXT_raster_multisample, ExtensionId::GL_EXT_texture_filter_minmax, ExtensionId::GL_NV_framebuffer_mixed_samples);
            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::GlRasterSamplesEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(samples, 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::glResolveDepthValuesNV() {
    GAPID_DEBUG("glResolveDepthValuesNV()");

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

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


    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::GlResolveDepthValuesNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras));
    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::glScissorArrayvNV(GLuint first, GLsizei count, GLint* v) {
    GAPID_DEBUG("glScissorArrayvNV(%" PRIu32 ", %" PRId32 ", %p)", first, count, v);

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

    bool called = false;
    auto call = [this, &called, first, count, v] {
        called = true;
        observeReads();
        mImports.glScissorArrayvNV(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::GlScissorArrayvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(first, mScratch), toEncoder< int32_t >(count, 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::glScissorIndexedNV(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glScissorIndexedNV(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", index, left, bottom, width, height);

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

    bool called = false;
    auto call = [this, &called, index, left, bottom, width, height] {
        called = true;
        observeReads();
        mImports.glScissorIndexedNV(index, left, bottom, width, height);
    };


    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::GlScissorIndexedNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< int32_t >(left, mScratch), toEncoder< int32_t >(bottom, 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::glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, uint32_t preserveMask) {
    GAPID_DEBUG("glStartTilingQCOM(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %u)", x, y, width, height, preserveMask);

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

    bool called = false;
    auto call = [this, &called, x, y, width, height, preserveMask] {
        called = true;
        observeReads();
        mImports.glStartTilingQCOM(x, y, width, height, preserveMask);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_QCOM_tiled_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::GlStartTilingQCOM coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(x, mScratch), toEncoder< uint32_t >(y, mScratch), toEncoder< uint32_t >(width, mScratch), toEncoder< uint32_t >(height, mScratch), preserveMask);
    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::glStencilFillPathInstancedNV(GLsizei numPaths, uint32_t pathNameType, void* paths, GLuint pathBase, uint32_t fillMode, GLuint mask, uint32_t transformType, GLfloat* transformValues) {
    GAPID_DEBUG("glStencilFillPathInstancedNV(%" PRId32 ", %u, %p, %" PRIu32 ", %u, %" PRIu32 ", %u, %p)", numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues);

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

    bool called = false;
    auto call = [this, &called, numPaths, pathNameType, paths, pathBase, fillMode, mask, transformType, transformValues] {
        called = true;
        observeReads();
        mImports.glStencilFillPathInstancedNV(numPaths, pathNameType, paths, pathBase, fillMode, mask, 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::GlStencilFillPathInstancedNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(numPaths, mScratch), pathNameType, toEncoder< gapic::coder::gles::Void__CP >(paths, mScratch), toEncoder< uint32_t >(pathBase, mScratch), fillMode, toEncoder< uint32_t >(mask, 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::glStencilStrokePathNV(GLuint path, GLint reference, GLuint mask) {
    GAPID_DEBUG("glStencilStrokePathNV(%" PRIu32 ", %" PRId32 ", %" PRIu32 ")", path, reference, mask);

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

    bool called = false;
    auto call = [this, &called, path, reference, mask] {
        called = true;
        observeReads();
        mImports.glStencilStrokePathNV(path, reference, mask);
    };


    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::GlStencilStrokePathNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), toEncoder< int32_t >(reference, mScratch), toEncoder< uint32_t >(mask, 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::glSubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits) {
    GAPID_DEBUG("glSubpixelPrecisionBiasNV(%" PRIu32 ", %" PRIu32 ")", xbits, ybits);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_conservative_raster);
            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::GlSubpixelPrecisionBiasNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(xbits, mScratch), toEncoder< uint32_t >(ybits, 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::glTexStorage2DEXT(uint32_t target, GLsizei levels, uint32_t format, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glTexStorage2DEXT(%u, %" PRId32 ", %u, %" PRId32 ", %" PRId32 ")", target, levels, format, width, height);

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

    bool called = false;
    auto call = [this, &called, target, levels, format, width, height] {
        called = true;
        observeReads();
        mImports.glTexStorage2DEXT(target, levels, format, width, height);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_texture_storage);
            subTexStorage2D(call, target, levels, format, 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::GlTexStorage2DEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(levels, mScratch), format, 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::glVertexAttribDivisorANGLE(AttributeLocation index, GLuint divisor) {
    GAPID_DEBUG("glVertexAttribDivisorANGLE(%" PRIu32 ", %" PRIu32 ")", index, divisor);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_ANGLE_instanced_arrays);
            subVertexAttribDivisor(call, index, divisor);
            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::GlVertexAttribDivisorANGLE coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< uint32_t >(divisor, 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::glVertexAttribDivisorEXT(AttributeLocation index, GLuint divisor) {
    GAPID_DEBUG("glVertexAttribDivisorEXT(%" PRIu32 ", %" PRIu32 ")", index, divisor);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_instanced_arrays);
            subVertexAttribDivisor(call, index, divisor);
            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::GlVertexAttribDivisorEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< uint32_t >(divisor, 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::glViewportArrayvNV(GLuint first, GLsizei count, GLfloat* v) {
    GAPID_DEBUG("glViewportArrayvNV(%" PRIu32 ", %" PRId32 ", %p)", first, count, v);

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

    bool called = false;
    auto call = [this, &called, first, count, v] {
        called = true;
        observeReads();
        mImports.glViewportArrayvNV(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::GlViewportArrayvNV 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::glViewportIndexedfvNV(GLuint index, GLfloat* v) {
    GAPID_DEBUG("glViewportIndexedfvNV(%" PRIu32 ", %p)", index, v);

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

    bool called = false;
    auto call = [this, &called, index, v] {
        called = true;
        observeReads();
        mImports.glViewportIndexedfvNV(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::GlViewportIndexedfvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, 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::glBlendEquationSeparatei(DrawBufferIndex buf, uint32_t modeRGB, uint32_t modeAlpha) {
    GAPID_DEBUG("glBlendEquationSeparatei(%" PRIu32 ", %u, %u)", buf, modeRGB, modeAlpha);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subBlendEquationSeparatei(call, buf, modeRGB, modeAlpha);
            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::GlBlendEquationSeparatei coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(buf, mScratch), modeRGB, modeAlpha);
    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::glBlendFuncSeparatei(DrawBufferIndex buf, uint32_t srcRGB, uint32_t dstRGB, uint32_t srcAlpha, uint32_t dstAlpha) {
    GAPID_DEBUG("glBlendFuncSeparatei(%" PRIu32 ", %u, %u, %u, %u)", buf, srcRGB, dstRGB, srcAlpha, dstAlpha);

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

    bool called = false;
    auto call = [this, &called, buf, srcRGB, dstRGB, srcAlpha, dstAlpha] {
        called = true;
        observeReads();
        mImports.glBlendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subBlendFuncSeparatei(call, buf, srcRGB, dstRGB, srcAlpha, dstAlpha);
            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::GlBlendFuncSeparatei coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(buf, mScratch), srcRGB, dstRGB, srcAlpha, dstAlpha);
    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::glDepthFunc(uint32_t function) {
    GAPID_DEBUG("glDepthFunc(%u)", function);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            switch (function) {
                case GLenum::GL_ALWAYS: // fall-through...
                case GLenum::GL_EQUAL: // fall-through...
                case GLenum::GL_GEQUAL: // fall-through...
                case GLenum::GL_GREATER: // fall-through...
                case GLenum::GL_LEQUAL: // fall-through...
                case GLenum::GL_LESS: // fall-through...
                case GLenum::GL_NEVER: // fall-through...
                case GLenum::GL_NOTEQUAL: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, function);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mFragmentOperations.mDepth.mFunc = function;
            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::GlDepthFunc coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), function);
    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::glStencilFuncSeparate(uint32_t face, uint32_t function, GLint reference_value, GLuint mask) {
    GAPID_DEBUG("glStencilFuncSeparate(%u, %u, %" PRId32 ", %" PRIu32 ")", face, function, reference_value, mask);

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

    bool called = false;
    auto call = [this, &called, face, function, reference_value, mask] {
        called = true;
        observeReads();
        mImports.glStencilFuncSeparate(face, function, reference_value, mask);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            subStencilFuncSeparate(call, face, function, reference_value, mask);
            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::GlStencilFuncSeparate coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), face, function, toEncoder< int32_t >(reference_value, mScratch), toEncoder< uint32_t >(mask, 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::glFramebufferTextureLayer(uint32_t target, uint32_t attachment, TextureId texture, GLint level, GLint layer) {
    GAPID_DEBUG("glFramebufferTextureLayer(%u, %u, %" PRIu32 ", %" PRId32 ", %" PRId32 ")", target, attachment, texture, level, layer);

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

    bool called = false;
    auto call = [this, &called, target, attachment, texture, level, layer] {
        called = true;
        observeReads();
        mImports.glFramebufferTextureLayer(target, attachment, texture, level, layer);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (attachment) {
                case GLenum::GL_COLOR_ATTACHMENT0: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT1: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT10: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT11: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT12: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT13: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT14: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT15: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT2: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT3: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT4: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT5: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT6: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT7: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT8: // fall-through...
                case GLenum::GL_COLOR_ATTACHMENT9: // fall-through...
                case GLenum::GL_DEPTH_ATTACHMENT: // fall-through...
                case GLenum::GL_DEPTH_STENCIL_ATTACHMENT: // fall-through...
                case GLenum::GL_STENCIL_ATTACHMENT: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, attachment);
                }
            }
            FramebufferAttachment l_attachment_info = FramebufferAttachment(GLenum::GL_NONE, (GLuint)(0UL), (GLint)(0L), GLenum::GL_NONE, (GLint)(0L), GLbooleanLabels::GL_FALSE);
            if ((texture) != ((TextureId)(0UL))) {
                l_attachment_info.mObjectType = GLenum::GL_TEXTURE;
                l_attachment_info.mObjectName = (GLuint)(texture);
                l_attachment_info.mTextureLevel = level;
                l_attachment_info.mTextureLayer = layer;
            }
            subSetFramebufferAttachment(call, target, attachment, l_attachment_info);
            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::GlFramebufferTextureLayer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, attachment, toEncoder< uint32_t >(texture, mScratch), toEncoder< int32_t >(level, mScratch), toEncoder< int32_t >(layer, 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::glRenderbufferStorage(uint32_t target, uint32_t internalformat, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glRenderbufferStorage(%u, %u, %" PRId32 ", %" PRId32 ")", target, internalformat, width, height);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_RENDERBUFFER: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            switch (internalformat) {
                case GLenum::GL_DEPTH_COMPONENT16: // fall-through...
                case GLenum::GL_RGB565: // fall-through...
                case GLenum::GL_RGB5_A1: // fall-through...
                case GLenum::GL_RGBA4: // fall-through...
                case GLenum::GL_STENCIL_INDEX8: {
                    break;
                }
                case GLenum::GL_DEPTH24_STENCIL8: // fall-through...
                case GLenum::GL_DEPTH32F_STENCIL8: // fall-through...
                case GLenum::GL_DEPTH_COMPONENT24: // fall-through...
                case GLenum::GL_DEPTH_COMPONENT32F: // fall-through...
                case GLenum::GL_R16I: // fall-through...
                case GLenum::GL_R16UI: // 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_RG16I: // fall-through...
                case GLenum::GL_RG16UI: // 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_RGB10_A2: // fall-through...
                case GLenum::GL_RGB10_A2UI: // fall-through...
                case GLenum::GL_RGB8: // fall-through...
                case GLenum::GL_RGBA16I: // fall-through...
                case GLenum::GL_RGBA16UI: // fall-through...
                case GLenum::GL_RGBA32I: // fall-through...
                case GLenum::GL_RGBA32UI: // fall-through...
                case GLenum::GL_RGBA8: // fall-through...
                case GLenum::GL_RGBA8I: // fall-through...
                case GLenum::GL_RGBA8UI: // fall-through...
                case GLenum::GL_SRGB8_ALPHA8: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_R16: // fall-through...
                case GLenum::GL_RG16: // fall-through...
                case GLenum::GL_RGBA16: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    subRequiresExtension(call, ExtensionId::GL_EXT_texture_norm16);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, internalformat);
                }
            }
            subGlErrorInvalidValueIf(call, ((width) < ((GLsizei)(0L))) || ((height) < ((GLsizei)(0L))));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, ((width) > ((GLsizei)(checkNotNull(l_ctx).mConstants.mMaxRenderbufferSize))) || ((height) > ((GLsizei)(checkNotNull(l_ctx).mConstants.mMaxRenderbufferSize))));
            RenderbufferId l_id = findOrZero(checkNotNull(l_ctx).mBoundRenderbuffers, target);
            subGlErrorInvalidOperationIf(call, (l_id) == ((RenderbufferId)(0UL)));
            std::shared_ptr<Renderbuffer> l_rb = findOrZero(checkNotNull(l_ctx).mInstances.mRenderbuffers, l_id);
            checkNotNull(l_rb).mTexelFormat = internalformat;
            checkNotNull(l_rb).mWidth = width;
            checkNotNull(l_rb).mHeight = 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::GlRenderbufferStorage coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, internalformat, 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::glDisablei(uint32_t capability, GLuint index) {
    GAPID_DEBUG("glDisablei(%u, %" PRIu32 ")", capability, index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subDisablei(call, capability, index);
            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::GlDisablei coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), capability, toEncoder< uint32_t >(index, 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::glEnable(uint32_t capability) {
    GAPID_DEBUG("glEnable(%u)", capability);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subSetCapability(call, capability, false, (GLuint)(0UL), GLbooleanLabels::GL_TRUE);
            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::GlEnable coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), capability);
    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::glFinish() {
    GAPID_DEBUG("glFinish()");

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(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::GlFinish coder(mScratch.vector<gapic::Encodable*>(kMaxExtras));
    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::glBindProgramPipeline(PipelineId pipeline) {
    GAPID_DEBUG("glBindProgramPipeline(%" PRIu32 ")", pipeline);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            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::GlBindProgramPipeline 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);

}

ProgramId GlesSpy::glCreateShaderProgramv(uint32_t type, GLsizei count, GLchar** strings) {
    GAPID_DEBUG("glCreateShaderProgramv(%u, %" PRId32 ", %p)", type, count, strings);

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

    ProgramId result = 0;
    bool called = false;
    auto call = [this, &called, &result, type, count, strings] {
        called = true;
        observeReads();
        result = mImports.glCreateShaderProgramv(type, count, strings);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (type) {
                case GLenum::GL_COMPUTE_SHADER: // fall-through...
                case GLenum::GL_FRAGMENT_SHADER: // fall-through...
                case GLenum::GL_VERTEX_SHADER: {
                    break;
                }
                case GLenum::GL_GEOMETRY_SHADER: // fall-through...
                case GLenum::GL_TESS_CONTROL_SHADER: // fall-through...
                case GLenum::GL_TESS_EVALUATION_SHADER: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, type);
                }
            }
            Slice<GLchar*> l_sources = slice(strings, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                (void)string((char*)(read(l_sources, (uint64_t)(l_i))));
            }
            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::GlCreateShaderProgramv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), type, toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLchar__CP__CP >(strings, 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::glDispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) {
    GAPID_DEBUG("glDispatchCompute(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", num_groups_x, num_groups_y, num_groups_z);

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

    bool called = false;
    auto call = [this, &called, num_groups_x, num_groups_y, num_groups_z] {
        called = true;
        observeReads();
        mImports.glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            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::GlDispatchCompute coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(num_groups_x, mScratch), toEncoder< uint32_t >(num_groups_y, mScratch), toEncoder< uint32_t >(num_groups_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);

}

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

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

    GLint result = 0;
    bool called = false;
    auto call = [this, &called, &result, program, name] {
        called = true;
        observeReads();
        result = mImports.glGetAttribLocation(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::GlGetAttribLocation 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;
}

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

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (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::GlGetFragDataLocation 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::glGetProgramResourceName(ProgramId program, uint32_t programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) {
    GAPID_DEBUG("glGetProgramResourceName(%" PRIu32 ", %u, %" PRIu32 ", %" PRId32 ", %p, %p)", program, programInterface, index, bufSize, length, name);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (programInterface) {
                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_VARYING: // fall-through...
                case GLenum::GL_UNIFORM: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, programInterface);
                }
            }
            GLsizei l_writeString_77_buffer_size = bufSize;
            GLsizei* l_writeString_77_buffer_bytes_written = length;
            GLchar* l_writeString_77_buffer = name;
            call();
            if (((l_writeString_77_buffer) != (nullptr)) && ((l_writeString_77_buffer_size) > ((GLsizei)(0L)))) {
                GLsizei l_buffer_size2 = l_writeString_77_buffer_size;
                if ((l_writeString_77_buffer_bytes_written) != (nullptr)) {
                    GLsizei l_length = (GLsizei)(slice(length, 0ULL, 1ULL)[0ULL]);
                    write(slice(l_writeString_77_buffer_bytes_written, 0ULL, 1ULL), 0ULL, l_length);
                    write(slice(l_writeString_77_buffer, (uint64_t)((GLsizei)(0L)), (uint64_t)((l_length) + ((GLsizei)(1L)))));
                } else {
                    write(slice(l_writeString_77_buffer, (uint64_t)((GLsizei)(0L)), (uint64_t)(l_buffer_size2)));
                }
            }
        } 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::GlGetProgramResourceName coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), programInterface, toEncoder< uint32_t >(index, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__P >(name, 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::glGetProgramiv(ProgramId program, uint32_t parameter, GLint* value) {
    GAPID_DEBUG("glGetProgramiv(%" PRIu32 ", %u, %p)", program, parameter, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            switch (parameter) {
                case GLenum::GL_ACTIVE_ATTRIBUTES: // fall-through...
                case GLenum::GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: // fall-through...
                case GLenum::GL_ACTIVE_UNIFORMS: // fall-through...
                case GLenum::GL_ACTIVE_UNIFORM_MAX_LENGTH: // fall-through...
                case GLenum::GL_ATTACHED_SHADERS: // fall-through...
                case GLenum::GL_DELETE_STATUS: // fall-through...
                case GLenum::GL_INFO_LOG_LENGTH: // fall-through...
                case GLenum::GL_LINK_STATUS: // fall-through...
                case GLenum::GL_VALIDATE_STATUS: {
                    break;
                }
                case GLenum::GL_ACTIVE_UNIFORM_BLOCKS: // fall-through...
                case GLenum::GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: // fall-through...
                case GLenum::GL_PROGRAM_BINARY_RETRIEVABLE_HINT: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_BUFFER_MODE: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_VARYINGS: // fall-through...
                case GLenum::GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_PROGRAM_BINARY_LENGTH: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_ACTIVE_ATOMIC_COUNTER_BUFFERS: // fall-through...
                case GLenum::GL_COMPUTE_WORK_GROUP_SIZE: // fall-through...
                case GLenum::GL_PROGRAM_SEPARABLE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    break;
                }
                case GLenum::GL_GEOMETRY_INPUT_TYPE: // fall-through...
                case GLenum::GL_GEOMETRY_OUTPUT_TYPE: // fall-through...
                case GLenum::GL_GEOMETRY_VERTICES_OUT: // fall-through...
                case GLenum::GL_GEOMETRY_SHADER_INVOCATIONS: // fall-through...
                case GLenum::GL_TESS_CONTROL_OUTPUT_VERTICES: // fall-through...
                case GLenum::GL_TESS_GEN_MODE: // fall-through...
                case GLenum::GL_TESS_GEN_POINT_MODE: // fall-through...
                case GLenum::GL_TESS_GEN_SPACING: // fall-through...
                case GLenum::GL_TESS_GEN_VERTEX_ORDER: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, parameter);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckProgram(call, l_ctx, program);
            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::GlGetProgramiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), parameter, toEncoder< gapic::coder::gles::GLint__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::glProgramUniform1fv(ProgramId program, UniformLocation location, GLsizei count, GLfloat* values) {
    GAPID_DEBUG("glProgramUniform1fv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform1fv(call, program, location, count, 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::GlProgramUniform1fv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), 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::glProgramUniform3uiv(ProgramId program, UniformLocation location, GLsizei count, GLuint* values) {
    GAPID_DEBUG("glProgramUniform3uiv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform3uiv(call, program, location, count, 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::GlProgramUniform3uiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), 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::glProgramUniform4iv(ProgramId program, UniformLocation location, GLsizei count, GLint* values) {
    GAPID_DEBUG("glProgramUniform4iv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform4iv(call, program, location, count, 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::GlProgramUniform4iv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), 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::glUniform1f(UniformLocation location, GLfloat value) {
    GAPID_DEBUG("glUniform1f(%" PRId32 ", %f)", location, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<GLfloat> l_v = make<GLfloat>(1ULL);
            call();
            write(l_v, 0ULL, value);
            UniformLocation l_Uniformv_84_location = location;
            Slice<GLfloat> l_Uniformv_84_values = l_v;
            uint32_t l_Uniformv_84_type = GLenum::GL_FLOAT;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_84_location, l_Uniformv_84_values.as<uint8_t>(), l_Uniformv_84_type);
        } 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::GlUniform1f coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(location, mScratch), toEncoder< float >(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::glUniform3ui(UniformLocation location, GLuint value0, GLuint value1, GLuint value2) {
    GAPID_DEBUG("glUniform3ui(%" PRId32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ")", location, value0, value1, value2);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            Slice<Vec3u> l_v = make<Vec3u>(1ULL);
            call();
            write(l_v, 0ULL, {value0, value1, value2});
            UniformLocation l_Uniformv_100_location = location;
            Slice<Vec3u> l_Uniformv_100_values = l_v;
            uint32_t l_Uniformv_100_type = GLenum::GL_UNSIGNED_INT_VEC3;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_100_location, l_Uniformv_100_values.as<uint8_t>(), l_Uniformv_100_type);
        } 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::GlUniform3ui coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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::glUniform4i(UniformLocation location, GLint value0, GLint value1, GLint value2, GLint value3) {
    GAPID_DEBUG("glUniform4i(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", location, value0, value1, value2, value3);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<Vec4i> l_v = make<Vec4i>(1ULL);
            call();
            write(l_v, 0ULL, {value0, value1, value2, value3});
            UniformLocation l_Uniformv_104_location = location;
            Slice<Vec4i> l_Uniformv_104_values = l_v;
            uint32_t l_Uniformv_104_type = GLenum::GL_INT_VEC4;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_Uniformv_104_location, l_Uniformv_104_values.as<uint8_t>(), l_Uniformv_104_type);
        } 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::GlUniform4i coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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::glUniformMatrix4fv(UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* values) {
    GAPID_DEBUG("glUniformMatrix4fv(%" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", location, count, transpose, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<Mat4f> l_v = slice((Mat4f*)(values), (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            UniformLocation l_UniformMatrixv_110_location = location;
            GLboolean l_UniformMatrixv_110_transpose = transpose;
            Slice<Mat4f> l_UniformMatrixv_110_values = l_v;
            uint32_t l_UniformMatrixv_110_type = GLenum::GL_FLOAT_MAT4;
            (void)l_UniformMatrixv_110_transpose;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetProgramUniform(call, checkNotNull(l_ctx).mBoundProgram, l_UniformMatrixv_110_location, l_UniformMatrixv_110_values.as<uint8_t>(), l_UniformMatrixv_110_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::GlUniformMatrix4fv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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::glBindImageTexture(GLuint unit, TextureId texture, GLint level, GLboolean layered, GLint layer, uint32_t access, uint32_t format) {
    GAPID_DEBUG("glBindImageTexture(%" PRIu32 ", %" PRIu32 ", %" PRId32 ", %" PRIu8 ", %" PRId32 ", %u, %u)", unit, texture, level, layered, layer, access, format);

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

    bool called = false;
    auto call = [this, &called, unit, texture, level, layered, layer, access, format] {
        called = true;
        observeReads();
        mImports.glBindImageTexture(unit, texture, level, layered, layer, access, format);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (access) {
                case GLenum::GL_READ_ONLY: // fall-through...
                case GLenum::GL_READ_WRITE: // fall-through...
                case GLenum::GL_WRITE_ONLY: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, access);
                }
            }
            switch (format) {
                case GLenum::GL_R32F: // fall-through...
                case GLenum::GL_R32I: // fall-through...
                case GLenum::GL_R32UI: // 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_RGBA8: // fall-through...
                case GLenum::GL_RGBA8I: // fall-through...
                case GLenum::GL_RGBA8UI: // fall-through...
                case GLenum::GL_RGBA8_SNORM: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, format);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mImageUnits[unit] = ImageUnit(texture, level, layered, layer, access, format);
            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::GlBindImageTexture coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(unit, mScratch), toEncoder< uint32_t >(texture, mScratch), toEncoder< int32_t >(level, mScratch), toEncoder< uint8_t >(layered, mScratch), toEncoder< int32_t >(layer, mScratch), access, format);
    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::glCompressedTexSubImage2D(uint32_t target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, uint32_t format, GLsizei image_size, TexturePointer data) {
    GAPID_DEBUG("glCompressedTexSubImage2D(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %u, %" PRId32 ", %p)", target, level, xoffset, yoffset, width, height, format, image_size, data);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_TEXTURE_2D: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Z: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            switch (format) {
                case GLenum::GL_COMPRESSED_R11_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_RG11_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_RGB8_ETC2: // fall-through...
                case GLenum::GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA8_ETC2_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_SIGNED_R11_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_SIGNED_RG11_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ETC2: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_COMPRESSED_RGBA_ASTC_10x10: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_10x5: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_10x6: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_10x8: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_12x10: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_12x12: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_4x4: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_5x4: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_5x5: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_6x5: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_6x6: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_8x5: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_8x6: // fall-through...
                case GLenum::GL_COMPRESSED_RGBA_ASTC_8x8: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6: // fall-through...
                case GLenum::GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                case GLenum::GL_ETC1_RGB8_OES: {
                    subRequiresExtension(call, ExtensionId::GL_OES_compressed_ETC1_RGB8_texture);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, format);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            if (((findOrZero(checkNotNull(l_ctx).mBoundBuffers, GLenum::GL_PIXEL_UNPACK_BUFFER)) == ((BufferId)(0UL))) && ((data) != (nullptr))) {
                read(slice((uint8_t*)(data), (uint64_t)((GLsizei)(0L)), (uint64_t)(image_size)));
            }
            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::GlCompressedTexSubImage2D 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 >(width, mScratch), toEncoder< int32_t >(height, 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::glCopyTexSubImage2D(uint32_t target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glCopyTexSubImage2D(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", target, level, xoffset, yoffset, x, y, width, height);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_TEXTURE_2D: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Z: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckMaxTextureSize(call, l_ctx, target, level, width, height);
            subGlErrorInvalidValueIf(call, ((xoffset) < ((GLint)(0L))) || ((yoffset) < ((GLint)(0L))));
            std::shared_ptr<Texture> l_t = subGetBoundTextureOrErrorInvalidEnum(call, target);
            subGlErrorInvalidValueIf(call, !(checkNotNull(l_t).mTexture2D.count(level) > 0));
            Image l_l = findOrZero(checkNotNull(l_t).mTexture2D, level);
            subGlErrorInvalidValueIf(call, ((((GLsizei)(xoffset)) + (width)) > (l_l.mWidth)) || ((((GLsizei)(yoffset)) + (height)) > (l_l.mHeight)));
            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::GlCopyTexSubImage2D 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 >(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::glGenSamplers(GLsizei count, SamplerId* samplers) {
    GAPID_DEBUG("glGenSamplers(%" PRId32 ", %p)", count, samplers);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            Slice<SamplerId> l_s = slice(samplers, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                SamplerId l_id = (SamplerId)(slice(samplers, (uint64_t)((GLsizei)(0L)), (uint64_t)(count))[(uint64_t)(l_i)]);
                checkNotNull(l_ctx).mInstances.mSamplers[l_id] = std::shared_ptr<Sampler>(new Sampler(std::move(Vec4f{(GLfloat)(0.f), (GLfloat)(0.f), (GLfloat)(0.f), (GLfloat)(0.f)}), GLenum::GL_NEAREST_MIPMAP_LINEAR, GLenum::GL_LINEAR, GLenum::GL_REPEAT, GLenum::GL_REPEAT, GLenum::GL_REPEAT, (GLfloat)(-1000.f), (GLfloat)(1000.f), GLenum::GL_NONE, GLenum::GL_LEQUAL, ""));
                write(l_s, (uint64_t)(l_i), l_id);
            }
        } 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::GlGenSamplers coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::SamplerId__P >(samplers, 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::glGenerateMipmap(uint32_t target) {
    GAPID_DEBUG("glGenerateMipmap(%u)", target);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_TEXTURE_2D: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP: {
                    break;
                }
                case GLenum::GL_TEXTURE_2D_ARRAY: // fall-through...
                case GLenum::GL_TEXTURE_3D: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_TEXTURE_CUBE_MAP_ARRAY: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, 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::GlGenerateMipmap 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::glGetTexLevelParameteriv(uint32_t target, GLint level, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetTexLevelParameteriv(%u, %" PRId32 ", %u, %p)", target, level, pname, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            switch (target) {
                case GLenum::GL_TEXTURE_2D: // fall-through...
                case GLenum::GL_TEXTURE_2D_ARRAY: // fall-through...
                case GLenum::GL_TEXTURE_2D_MULTISAMPLE: // fall-through...
                case GLenum::GL_TEXTURE_3D: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_X: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Y: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_POSITIVE_Z: {
                    break;
                }
                case GLenum::GL_TEXTURE_2D_MULTISAMPLE_ARRAY: // fall-through...
                case GLenum::GL_TEXTURE_BUFFER: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_ARRAY: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            switch (pname) {
                case GLenum::GL_TEXTURE_ALPHA_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_ALPHA_TYPE: // fall-through...
                case GLenum::GL_TEXTURE_BLUE_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_BLUE_TYPE: // fall-through...
                case GLenum::GL_TEXTURE_COMPRESSED: // fall-through...
                case GLenum::GL_TEXTURE_DEPTH: // fall-through...
                case GLenum::GL_TEXTURE_DEPTH_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_DEPTH_TYPE: // fall-through...
                case GLenum::GL_TEXTURE_FIXED_SAMPLE_LOCATIONS: // fall-through...
                case GLenum::GL_TEXTURE_GREEN_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_GREEN_TYPE: // fall-through...
                case GLenum::GL_TEXTURE_HEIGHT: // fall-through...
                case GLenum::GL_TEXTURE_INTERNAL_FORMAT: // fall-through...
                case GLenum::GL_TEXTURE_RED_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_RED_TYPE: // fall-through...
                case GLenum::GL_TEXTURE_SAMPLES: // fall-through...
                case GLenum::GL_TEXTURE_SHARED_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_STENCIL_SIZE: // fall-through...
                case GLenum::GL_TEXTURE_WIDTH: {
                    break;
                }
                case GLenum::GL_TEXTURE_BUFFER_DATA_STORE_BINDING: // fall-through...
                case GLenum::GL_TEXTURE_BUFFER_OFFSET: // fall-through...
                case GLenum::GL_TEXTURE_BUFFER_SIZE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, pname);
                }
            }
            call();
            write(slice(params, 0ULL, 1ULL), 0ULL, slice(params, 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::GlGetTexLevelParameteriv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(level, mScratch), 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::glGetTexParameteriv(uint32_t target, uint32_t parameter, GLint* values) {
    GAPID_DEBUG("glGetTexParameteriv(%u, %u, %p)", target, parameter, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            uint32_t l_GetTexParameter_119_target = target;
            uint32_t l_GetTexParameter_119_parameter = parameter;
            GLint* l_GetTexParameter_119_params = values;
            switch (l_GetTexParameter_119_target) {
                case GLenum::GL_TEXTURE_2D: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP: {
                    break;
                }
                case GLenum::GL_TEXTURE_2D_ARRAY: // fall-through...
                case GLenum::GL_TEXTURE_3D: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    break;
                }
                case GLenum::GL_TEXTURE_2D_MULTISAMPLE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    break;
                }
                case GLenum::GL_TEXTURE_2D_MULTISAMPLE_ARRAY: // fall-through...
                case GLenum::GL_TEXTURE_CUBE_MAP_ARRAY: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetTexParameter_119_target);
                }
            }
            subGlErrorInvalidEnumIf(call, (l_GetTexParameter_119_target) == (GLenum::GL_TEXTURE_BUFFER));
            std::shared_ptr<Texture> l_t = subGetBoundTextureOrErrorInvalidEnum(call, l_GetTexParameter_119_target);
            call();
            switch (l_GetTexParameter_119_parameter) {
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mMagFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mMinFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mWrapS));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mWrapT));
                    break;
                }
                case GLenum::GL_TEXTURE_BASE_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_t).mBaseLevel);
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mCompareFunc));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mCompareMode));
                    break;
                }
                case GLenum::GL_TEXTURE_IMMUTABLE_FORMAT: {
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mImmutableFormat));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_t).mMaxLevel);
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mMaxLod));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mMinLod));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_A: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mSwizzleA));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_B: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mSwizzleB));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_G: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mSwizzleG));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mSwizzleR));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mWrapR));
                    break;
                }
                case GLenum::GL_DEPTH_STENCIL_TEXTURE_MODE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mDepthStencilTextureMode));
                    break;
                }
                case GLenum::GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, slice(values, 0ULL, 1ULL)[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_IMMUTABLE_LEVELS: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mImmutableLevels));
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    Slice<GLint> l_p = slice(l_GetTexParameter_119_params, 0ULL, 4ULL);
                    write(l_p, 0ULL, (GLint)(checkNotNull(l_t).mBorderColor[0ULL]));
                    write(l_p, 1ULL, (GLint)(checkNotNull(l_t).mBorderColor[1ULL]));
                    write(l_p, 2ULL, (GLint)(checkNotNull(l_t).mBorderColor[2ULL]));
                    write(l_p, 3ULL, (GLint)(checkNotNull(l_t).mBorderColor[3ULL]));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_ANISOTROPY_EXT: {
                    subRequiresExtension(call, ExtensionId::GL_EXT_texture_filter_anisotropic);
                    write(slice(l_GetTexParameter_119_params, 0ULL, 1ULL), 0ULL, (GLint)(checkNotNull(l_t).mMaxAnisotropy));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetTexParameter_119_parameter);
                }
            }
        } 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::GlGetTexParameteriv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, parameter, 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::glSamplerParameterfv(SamplerId sampler, uint32_t pname, GLfloat* param) {
    GAPID_DEBUG("glSamplerParameterfv(%" PRIu32 ", %u, %p)", sampler, pname, param);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            SamplerId l_SamplerParameterv_121_sampler = sampler;
            uint32_t l_SamplerParameterv_121_pname = pname;
            GLfloat* l_SamplerParameterv_121_params = param;
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            std::shared_ptr<Sampler> l_s = findOrZero(checkNotNull(l_ctx).mInstances.mSamplers, l_SamplerParameterv_121_sampler);
            switch (l_SamplerParameterv_121_pname) {
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    checkNotNull(l_s).mCompareFunc = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    checkNotNull(l_s).mCompareMode = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    checkNotNull(l_s).mMinFilter = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    checkNotNull(l_s).mMagFilter = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    checkNotNull(l_s).mMinLod = read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL);
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    checkNotNull(l_s).mMaxLod = read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL);
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    checkNotNull(l_s).mWrapR = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    checkNotNull(l_s).mWrapS = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    checkNotNull(l_s).mWrapT = (uint32_t)(read(slice(l_SamplerParameterv_121_params, 0ULL, 1ULL), 0ULL));
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_SamplerParameterv_121_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::GlSamplerParameterfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< gapic::coder::gles::GLfloat__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::glTexBuffer(uint32_t target, uint32_t internalformat, BufferId buffer) {
    GAPID_DEBUG("glTexBuffer(%u, %u, %" PRIu32 ")", target, internalformat, buffer);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            subTexBuffer(call, target, internalformat, 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::GlTexBuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, internalformat, toEncoder< uint32_t >(buffer, 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::glTexParameteri(uint32_t target, uint32_t parameter, GLint value) {
    GAPID_DEBUG("glTexParameteri(%u, %u, %" PRId32 ")", target, parameter, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subGlErrorInvalidEnumIf(call, (parameter) == (GLenum::GL_TEXTURE_BORDER_COLOR));
            Vec1i l_params = {value};
            uint32_t l_TexParameterv_126_target = target;
            uint32_t l_TexParameterv_126_pname = parameter;
            Vec1i l_TexParameterv_126_params = l_params;
            subGlErrorInvalidEnumIf(call, (l_TexParameterv_126_target) == (GLenum::GL_TEXTURE_BUFFER));
            std::shared_ptr<Texture> l_t = subGetBoundTextureOrErrorInvalidEnum(call, l_TexParameterv_126_target);
            switch (l_TexParameterv_126_pname) {
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    uint32_t l_magFilter = (uint32_t)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[0ULL]));
                    checkNotNull(l_t).mWrapT = l__res_0;
                    break;
                }
                case GLenum::GL_TEXTURE_BASE_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    GLint l_baseLevel = l_TexParameterv_126_params[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)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    checkNotNull(l_t).mCompareMode = (uint32_t)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    GLint l_maxLevel = l_TexParameterv_126_params[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)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    checkNotNull(l_t).mMinLod = (GLfloat)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_A: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    uint32_t l__res_0 = subCheckSwizzleParam(call, (uint32_t)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_DEPTH_STENCIL_TEXTURE_MODE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    checkNotNull(l_t).mDepthStencilTextureMode = (uint32_t)(l_TexParameterv_126_params[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)(l_TexParameterv_126_params[0ULL]);
                    break;
                }
                case GLenum::GL_TEXTURE_SRGB_DECODE_EXT: {
                    subRequiresExtension(call, ExtensionId::GL_EXT_texture_sRGB_decode);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_TexParameterv_126_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::GlTexParameteri coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, parameter, 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::glBindVertexBuffer(VertexBufferBindingIndex binding_index, BufferId buffer, GLintptr offset, GLsizei stride) {
    GAPID_DEBUG("glBindVertexBuffer(%" PRIu32 ", %" PRIu32 ", %" PRId32 ", %" PRId32 ")", binding_index, buffer, offset, stride);

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

    bool called = false;
    auto call = [this, &called, binding_index, buffer, offset, stride] {
        called = true;
        observeReads();
        mImports.glBindVertexBuffer(binding_index, buffer, offset, stride);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidOperationIf(call, (checkNotNull(l_ctx).mBoundVertexArray) == ((VertexArrayId)(0UL)));
            subBindVertexBuffer(call, l_ctx, binding_index, buffer, offset, stride);
            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::GlBindVertexBuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(binding_index, mScratch), toEncoder< uint32_t >(buffer, mScratch), toEncoder< int32_t >(offset, mScratch), toEncoder< int32_t >(stride, 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::glDeleteVertexArrays(GLsizei count, VertexArrayId* arrays) {
    GAPID_DEBUG("glDeleteVertexArrays(%" PRId32 ", %p)", count, arrays);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subDeleteVertexArrays(call, count, arrays);
            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::GlDeleteVertexArrays coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::VertexArrayId__CP >(arrays, 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::glDisableVertexAttribArray(AttributeLocation location) {
    GAPID_DEBUG("glDisableVertexAttribArray(%" PRIu32 ")", location);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, (location) >= (checkNotNull(l_ctx).mConstants.mMaxVertexAttribs));
            std::shared_ptr<VertexArray> l_vao = findOrZero(checkNotNull(l_ctx).mInstances.mVertexArrays, checkNotNull(l_ctx).mBoundVertexArray);
            checkNotNull(findOrZero(checkNotNull(l_vao).mVertexAttributeArrays, location)).mEnabled = GLbooleanLabels::GL_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::GlDisableVertexAttribArray coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(location, 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::glGetVertexAttribIuiv(AttributeLocation index, uint32_t pname, GLuint* params) {
    GAPID_DEBUG("glGetVertexAttribIuiv(%" PRIu32 ", %u, %p)", index, pname, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, (index) >= (checkNotNull(l_ctx).mConstants.mMaxVertexAttribs));
            call();
            if ((pname) == (GLenum::GL_CURRENT_VERTEX_ATTRIB)) {
                write(slice(params, 0ULL, 4ULL));
            } else {
                uint64_t l__res_0 = subGetVertexAttrib(call, l_ctx, index, pname);
                write(slice(params, 0ULL, 1ULL), 0ULL, (GLuint)(l__res_0));
            }
        } 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::GlGetVertexAttribIuiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), pname, toEncoder< gapic::coder::gles::GLuint__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::glIsVertexArray(VertexArrayId array) {
    GAPID_DEBUG("glIsVertexArray(%" PRIu32 ")", array);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            GLboolean l__res_0 = subIsVertexArray(call, array);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>(l__res_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::GlIsVertexArray coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(array, 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::glVertexAttrib3f(AttributeLocation location, GLfloat value0, GLfloat value1, GLfloat value2) {
    GAPID_DEBUG("glVertexAttrib3f(%" PRIu32 ", %f, %f, %f)", location, value0, value1, value2);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            call();
            subVertexAttribF(call, location, std::move(Vec4f{value0, value1, value2, (GLfloat)(1.f)}));
        } 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::GlVertexAttrib3f coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(location, mScratch), toEncoder< float >(value0, mScratch), toEncoder< float >(value1, mScratch), toEncoder< float >(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::glVertexAttribBinding(AttributeLocation index, VertexBufferBindingIndex binding_index) {
    GAPID_DEBUG("glVertexAttribBinding(%" PRIu32 ", %" PRIu32 ")", index, binding_index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidOperationIf(call, (checkNotNull(l_ctx).mBoundVertexArray) == ((VertexArrayId)(0UL)));
            subVertexAttribBinding(call, l_ctx, index, binding_index);
            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::GlVertexAttribBinding coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(index, mScratch), toEncoder< uint32_t >(binding_index, 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::glVertexBindingDivisor(VertexBufferBindingIndex binding_index, GLuint divisor) {
    GAPID_DEBUG("glVertexBindingDivisor(%" PRIu32 ", %" PRIu32 ")", binding_index, divisor);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subGlErrorInvalidValueIf(call, (binding_index) >= (checkNotNull(l_ctx).mConstants.mMaxVertexAttribBindings));
            subGlErrorInvalidOperationIf(call, (checkNotNull(l_ctx).mBoundVertexArray) == ((VertexArrayId)(0UL)));
            std::shared_ptr<VertexArray> l_vao = findOrZero(checkNotNull(l_ctx).mInstances.mVertexArrays, checkNotNull(l_ctx).mBoundVertexArray);
            checkNotNull(findOrZero(checkNotNull(l_vao).mVertexBufferBindings, binding_index)).mDivisor = divisor;
            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::GlVertexBindingDivisor coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(binding_index, mScratch), toEncoder< uint32_t >(divisor, 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);

}

EGLBoolean GlesSpy::eglInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) {
    GAPID_DEBUG("eglInitialize(%p, %p, %p)", dpy, major, minor);

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

    EGLBoolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, dpy, major, minor] {
        called = true;
        observeReads();
        result = mImports.eglInitialize(dpy, major, minor);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            call();
            if ((major) != (nullptr)) {
                write(slice(major, 0ULL, 1ULL), 0ULL, slice(major, 0ULL, 1ULL)[0ULL]);
            }
            if ((major) != (nullptr)) {
                write(slice(minor, 0ULL, 1ULL), 0ULL, slice(minor, 0ULL, 1ULL)[0ULL]);
            }
            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::EglInitialize coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::EGLDisplay >(dpy, mScratch), toEncoder< gapic::coder::gles::EGLint__P >(major, mScratch), toEncoder< gapic::coder::gles::EGLint__P >(minor, 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;
}

EGLBoolean GlesSpy::eglSwapBuffersWithDamageKHR(EGLDisplay dpy, EGLSurface surface, EGLint* rects, EGLint n_rects) {
    GAPID_DEBUG("eglSwapBuffersWithDamageKHR(%p, %p, %p, %d)", dpy, surface, rects, n_rects);

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

    EGLBoolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, dpy, surface, rects, n_rects] {
        called = true;
        observeReads();
        result = mImports.eglSwapBuffersWithDamageKHR(dpy, surface, rects, n_rects);
    };

    onPreEndOfFrame();

    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            read(slice(rects, (uint64_t)(0L), (uint64_t)((n_rects) * ((EGLint)(4L)))));
            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::EglSwapBuffersWithDamageKHR coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::EGLDisplay >(dpy, mScratch), toEncoder< gapic::coder::gles::EGLSurface >(surface, mScratch), toEncoder< gapic::coder::gles::EGLint__P >(rects, mScratch), toEncoder< int >(n_rects, 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;
}

GLXContext GlesSpy::glXCreateContext(void* dpy, void* vis, GLXContext shareList, bool direct) {
    GAPID_DEBUG("glXCreateContext(%p, %p, %p, %d)", dpy, vis, shareList, direct);

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

    GLXContext result = nullptr;
    bool called = false;
    auto call = [this, &called, &result, dpy, vis, shareList, direct] {
        called = true;
        observeReads();
        result = mImports.glXCreateContext(dpy, vis, shareList, direct);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            call();
            auto l_context = result;
            std::shared_ptr<Context> l__res_0 = subCreateContext(call);
            this->GLXContexts[l_context] = l__res_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::GlXCreateContext coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::Void__P >(dpy, mScratch), toEncoder< gapic::coder::gles::Void__P >(vis, mScratch), toEncoder< gapic::coder::gles::GLXContext >(shareList, mScratch), direct, toEncoder< gapic::coder::gles::GLXContext >(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::glClipPlanefOES(uint32_t plane, GLfloat* equation) {
    GAPID_DEBUG("glClipPlanefOES(%u, %p)", plane, equation);

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

    bool called = false;
    auto call = [this, &called, plane, equation] {
        called = true;
        observeReads();
        mImports.glClipPlanefOES(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::GlClipPlanefOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), plane, toEncoder< gapic::coder::gles::GLfloat__CP >(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::glClipPlanexIMG(uint32_t p, GLfixed* eqn) {
    GAPID_DEBUG("glClipPlanexIMG(%u, %p)", p, eqn);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_IMG_user_clip_plane);
            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::GlClipPlanexIMG coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), p, toEncoder< gapic::coder::gles::GLfixed__CP >(eqn, 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::glDeleteRenderbuffersOES(GLsizei n, GLuint* renderbuffers) {
    GAPID_DEBUG("glDeleteRenderbuffersOES(%" PRId32 ", %p)", n, renderbuffers);

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

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


    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::GlDeleteRenderbuffersOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::GLuint__CP >(renderbuffers, 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::glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) {
    GAPID_DEBUG("glDrawTexiOES(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", x, y, z, width, height);

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

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


    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::GlDrawTexiOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(x, mScratch), toEncoder< int32_t >(y, mScratch), toEncoder< int32_t >(z, 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);
    onPostDrawCall();

}

void GlesSpy::glFogxvOES(uint32_t pname, GLfixed* param) {
    GAPID_DEBUG("glFogxvOES(%u, %p)", pname, param);

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

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


    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::GlFogxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< gapic::coder::gles::GLfixed__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::glFrustumxOES(GLfixed l, GLfixed r, GLfixed b, GLfixed t, GLfixed n, GLfixed f) {
    GAPID_DEBUG("glFrustumxOES(%" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", l, r, b, t, n, f);

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

    bool called = false;
    auto call = [this, &called, l, r, b, t, n, f] {
        called = true;
        observeReads();
        mImports.glFrustumxOES(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::GlFrustumxOES 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::glGetLightxvOES(uint32_t light, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glGetLightxvOES(%u, %u, %p)", light, pname, params);

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

    bool called = false;
    auto call = [this, &called, light, pname, params] {
        called = true;
        observeReads();
        mImports.glGetLightxvOES(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::GlGetLightxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), light, 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::glGetRenderbufferParameterivOES(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glGetRenderbufferParameterivOES(%u, %u, %p)", target, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetRenderbufferParameterivOES(target, 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::GlGetRenderbufferParameterivOES 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::glGetTexParameterxvOES(uint32_t target, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glGetTexParameterxvOES(%u, %u, %p)", target, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexParameterxvOES(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::GlGetTexParameterxvOES 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);

}

GLboolean GlesSpy::glIsRenderbufferOES(GLuint renderbuffer) {
    GAPID_DEBUG("glIsRenderbufferOES(%" PRIu32 ")", renderbuffer);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_framebuffer_object);
            subErrorGLES10notSupported(call);
            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::GlIsRenderbufferOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(renderbuffer, 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::glLightModelxv(uint32_t pname, GLfixed* param) {
    GAPID_DEBUG("glLightModelxv(%u, %p)", pname, param);

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

    bool called = false;
    auto call = [this, &called, pname, param] {
        called = true;
        observeReads();
        mImports.glLightModelxv(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::GlLightModelxv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< gapic::coder::gles::GLfixed__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::glLineWidthxOES(GLfixed width) {
    GAPID_DEBUG("glLineWidthxOES(%" PRId32 ")", width);

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

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


    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::GlLineWidthxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(width, 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::glLoadMatrixx(GLfixed* m) {
    GAPID_DEBUG("glLoadMatrixx(%p)", m);

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

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


    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::GlLoadMatrixx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLfixed__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);

}

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

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

    bool called = false;
    auto call = [this, &called, face, pname, param] {
        called = true;
        observeReads();
        mImports.glMaterialxv(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::GlMaterialxv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), face, pname, toEncoder< gapic::coder::gles::GLfixed__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::glMultMatrixf(GLfloat* m) {
    GAPID_DEBUG("glMultMatrixf(%p)", m);

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

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


    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::GlMultMatrixf coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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);

}

void GlesSpy::glMultiTexCoord4x(uint32_t texture, GLfixed v0, GLfixed v1, GLfixed v2, GLfixed v3) {
    GAPID_DEBUG("glMultiTexCoord4x(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", texture, v0, v1, v2, v3);

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

    bool called = false;
    auto call = [this, &called, texture, v0, v1, v2, v3] {
        called = true;
        observeReads();
        mImports.glMultiTexCoord4x(texture, v0, v1, v2, v3);
    };


    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::GlMultiTexCoord4x coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), texture, toEncoder< int32_t >(v0, mScratch), toEncoder< int32_t >(v1, mScratch), toEncoder< int32_t >(v2, mScratch), toEncoder< int32_t >(v3, 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::glPointParameterxv(uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glPointParameterxv(%u, %p)", pname, params);

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

    bool called = false;
    auto call = [this, &called, pname, params] {
        called = true;
        observeReads();
        mImports.glPointParameterxv(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::GlPointParameterxv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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::glPointSize(GLfloat size) {
    GAPID_DEBUG("glPointSize(%f)", size);

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

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


    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::GlPointSize coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(size, 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::glTexEnviv(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glTexEnviv(%u, %u, %p)", target, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexEnviv(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::GlTexEnviv 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::glTexEnvxvOES(uint32_t target, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glTexEnvxvOES(%u, %u, %p)", target, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexEnvxvOES(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::GlTexEnvxvOES 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::glTexGenivOES(uint32_t coord, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glTexGenivOES(%u, %u, %p)", coord, pname, params);

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

    bool called = false;
    auto call = [this, &called, coord, pname, params] {
        called = true;
        observeReads();
        mImports.glTexGenivOES(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::GlTexGenivOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), coord, 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::glTranslatexOES(GLfixed x, GLfixed y, GLfixed z) {
    GAPID_DEBUG("glTranslatexOES(%" PRId32 ", %" PRId32 ", %" PRId32 ")", x, y, z);

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

    bool called = false;
    auto call = [this, &called, x, y, z] {
        called = true;
        observeReads();
        mImports.glTranslatexOES(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::GlTranslatexOES 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::glVertexPointer(GLint size, uint32_t type, GLsizei stride, void* pointer) {
    GAPID_DEBUG("glVertexPointer(%" PRId32 ", %u, %" PRId32 ", %p)", size, type, stride, pointer);

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

    bool called = false;
    auto call = [this, &called, size, type, stride, pointer] {
        called = true;
        observeReads();
        mImports.glVertexPointer(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::GlVertexPointer 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::replayCreateRenderer(uint32_t id) {
    GAPID_DEBUG("replayCreateRenderer(%" PRIu32 ")", id);

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


    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::ReplayCreateRenderer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), id);
    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::flushPostBuffer() {
    GAPID_DEBUG("flushPostBuffer()");

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


    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::FlushPostBuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras));
    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