/*
 * 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::glGetTexParameterIuivEXT(uint32_t target, uint32_t pname, GLuint* params) {
    GAPID_DEBUG("glGetTexParameterIuivEXT(%u, %u, %p)", target, pname, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

}

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

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlSamplerParameterIivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(sampler, mScratch), pname, toEncoder< gapic::coder::gles::GLint__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);

}

GLboolean GlesSpy::glIsQuery(QueryId query) {
    GAPID_DEBUG("glIsQuery(%" PRIu32 ")", query);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.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::GlIsQuery 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::glGetBufferParameteri64v(uint32_t target, uint32_t parameter, GLint64* value) {
    GAPID_DEBUG("glGetBufferParameteri64v(%u, %u, %p)", target, parameter, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            uint32_t l_GetBufferParameter_56_target = target;
            uint32_t l_GetBufferParameter_56_parameter = parameter;
            GLint64* l_GetBufferParameter_56_value = value;
            std::shared_ptr<Buffer> l_b = subGetBoundBufferOrError(call, l_GetBufferParameter_56_target);
            call();
            switch (l_GetBufferParameter_56_parameter) {
                case GLenum::GL_BUFFER_SIZE: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mSize));
                    break;
                }
                case GLenum::GL_BUFFER_USAGE: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mUsage));
                    break;
                }
                case GLenum::GL_BUFFER_ACCESS_FLAGS: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mAccessFlags));
                    break;
                }
                case GLenum::GL_BUFFER_MAPPED: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mMapped));
                    break;
                }
                case GLenum::GL_BUFFER_MAP_LENGTH: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mMapLength));
                    break;
                }
                case GLenum::GL_BUFFER_MAP_OFFSET: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetBufferParameter_56_value, 0ULL, 1ULL), 0ULL, (GLint64)(checkNotNull(l_b).mMapOffset));
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetBufferParameter_56_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::GlGetBufferParameteri64v coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, parameter, toEncoder< gapic::coder::gles::GLint64__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::glDrawElementsBaseVertex(uint32_t draw_mode, GLsizei indices_count, uint32_t indices_type, IndicesPointer indices, GLint base_vertex) {
    GAPID_DEBUG("glDrawElementsBaseVertex(%u, %" PRId32 ", %u, %p, %" PRId32 ")", draw_mode, indices_count, indices_type, indices, base_vertex);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

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

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subDrawElementsInstanced(call, draw_mode, indices_count, indices_type, indices, instance_count);
            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::GlDrawElementsInstanced coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), draw_mode, toEncoder< int32_t >(indices_count, mScratch), indices_type, toEncoder< gapic::coder::gles::IndicesPointer >(indices, mScratch), toEncoder< int32_t >(instance_count, mScratch));
    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::glActiveShaderProgramEXT(PipelineId pipeline, ProgramId program) {
    GAPID_DEBUG("glActiveShaderProgramEXT(%" PRIu32 ", %" PRIu32 ")", pipeline, program);

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

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


    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::GlActiveShaderProgramEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(pipeline, mScratch), toEncoder< uint32_t >(program, 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::glBlendEquationSeparateiOES(DrawBufferIndex buf, uint32_t modeRGB, uint32_t modeAlpha) {
    GAPID_DEBUG("glBlendEquationSeparateiOES(%" PRIu32 ", %u, %u)", buf, modeRGB, modeAlpha);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_buffers_indexed);
            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::GlBlendEquationSeparateiOES 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::glBlendFuncSeparateiOES(DrawBufferIndex buf, uint32_t srcRGB, uint32_t dstRGB, uint32_t srcAlpha, uint32_t dstAlpha) {
    GAPID_DEBUG("glBlendFuncSeparateiOES(%" PRIu32 ", %u, %u, %u, %u)", buf, srcRGB, dstRGB, srcAlpha, dstAlpha);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_buffers_indexed);
            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::GlBlendFuncSeparateiOES 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::glCoverageModulationTableNV(GLsizei n, GLfloat* v) {
    GAPID_DEBUG("glCoverageModulationTableNV(%" PRId32 ", %p)", n, v);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, 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::GlCoverageModulationTableNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, 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::glDeleteQueriesEXT(GLsizei count, QueryId* queries) {
    GAPID_DEBUG("glDeleteQueriesEXT(%" PRId32 ", %p)", count, queries);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension2(call, ExtensionId::GL_EXT_disjoint_timer_query, ExtensionId::GL_EXT_occlusion_query_boolean);
            Slice<QueryId> l_q = slice(queries, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                QueryId l_id = read(l_q, (uint64_t)(l_i));
                if ((l_id) != ((QueryId)(0UL))) {
                    checkNotNull(l_ctx).mInstances.mQueries.erase(l_id);
                }
            }
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlDeleteQueriesEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::QueryId__CP >(queries, 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::glDeleteSyncAPPLE(GLsync sync) {
    GAPID_DEBUG("glDeleteSyncAPPLE(%p)", sync);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_APPLE_sync);
            subDeleteSync(call, sync);
            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::GlDeleteSyncAPPLE coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, 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::glDeleteVertexArraysOES(GLsizei count, VertexArrayId* arrays) {
    GAPID_DEBUG("glDeleteVertexArraysOES(%" PRId32 ", %p)", count, arrays);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_vertex_array_object);
            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::GlDeleteVertexArraysOES 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::glDisableiOES(uint32_t target, GLuint index) {
    GAPID_DEBUG("glDisableiOES(%u, %" PRIu32 ")", target, index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_draw_buffers_indexed);
            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::GlDisableiOES 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::glDrawArraysInstancedEXT(uint32_t mode, GLint start, GLsizei count, GLsizei primcount) {
    GAPID_DEBUG("glDrawArraysInstancedEXT(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ")", mode, start, count, primcount);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension2(call, ExtensionId::GL_EXT_draw_instanced, ExtensionId::GL_EXT_instanced_arrays);
            subDrawArraysInstanced(call, mode, start, count, 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::GlDrawArraysInstancedEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, toEncoder< int32_t >(start, mScratch), toEncoder< int32_t >(count, 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::glDrawBuffersEXT(GLsizei n, uint32_t* bufs) {
    GAPID_DEBUG("glDrawBuffersEXT(%" PRId32 ", %p)", n, bufs);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_buffers);
            subDrawBuffers(call, n, bufs);
            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::GlDrawBuffersEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::GLenum__CP >(bufs, 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::glDrawRangeElementsBaseVertexEXT(uint32_t mode, GLuint start, GLuint end, GLsizei count, uint32_t type, IndicesPointer indices, GLint basevertex) {
    GAPID_DEBUG("glDrawRangeElementsBaseVertexEXT(%u, %" PRIu32 ", %" PRIu32 ", %" PRId32 ", %u, %p, %" PRId32 ")", mode, start, end, count, type, indices, basevertex);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_draw_elements_base_vertex);
            subDrawRangeElementsBaseVertex(call, mode, start, end, 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::GlDrawRangeElementsBaseVertexEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), mode, toEncoder< uint32_t >(start, mScratch), toEncoder< uint32_t >(end, mScratch), 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::glFinishFenceNV(GLuint fence) {
    GAPID_DEBUG("glFinishFenceNV(%" PRIu32 ")", fence);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_fence);
            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::GlFinishFenceNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(fence, 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::glGenFencesNV(GLsizei n, GLuint* fences) {
    GAPID_DEBUG("glGenFencesNV(%" PRId32 ", %p)", n, fences);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_fence);
            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::GlGenFencesNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(n, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(fences, 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::glGenPerfMonitorsAMD(GLsizei n, GLuint* monitors) {
    GAPID_DEBUG("glGenPerfMonitorsAMD(%" PRId32 ", %p)", n, monitors);

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

    bool called = false;
    auto call = [this, &called, n, monitors] {
        called = true;
        observeReads();
        mImports.glGenPerfMonitorsAMD(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::GlGenPerfMonitorsAMD 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::glGenProgramPipelinesEXT(GLsizei n, PipelineId* pipelines) {
    GAPID_DEBUG("glGenProgramPipelinesEXT(%" PRId32 ", %p)", n, pipelines);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

void GlesSpy::glGetDriverControlsQCOM(GLint* num, GLsizei size, GLuint* driverControls) {
    GAPID_DEBUG("glGetDriverControlsQCOM(%p, %" PRId32 ", %p)", num, size, driverControls);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlGetDriverControlsQCOM coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLint__P >(num, mScratch), toEncoder< int32_t >(size, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(driverControls, 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::glGetFloati_vNV(uint32_t target, GLuint index, GLfloat* data) {
    GAPID_DEBUG("glGetFloati_vNV(%u, %" PRIu32 ", %p)", target, index, data);

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

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


    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::GlGetFloati_vNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, mScratch), toEncoder< gapic::coder::gles::GLfloat__P >(data, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glGetPathSpacingNV(uint32_t pathListMode, GLsizei numPaths, uint32_t pathNameType, void* paths, GLuint pathBase, GLfloat advanceScale, GLfloat kerningScale, uint32_t transformType, GLfloat* returnedSpacing) {
    GAPID_DEBUG("glGetPathSpacingNV(%u, %" PRId32 ", %u, %p, %" PRIu32 ", %f, %f, %u, %p)", pathListMode, numPaths, pathNameType, paths, pathBase, advanceScale, kerningScale, transformType, returnedSpacing);

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

    bool called = false;
    auto call = [this, &called, pathListMode, numPaths, pathNameType, paths, pathBase, advanceScale, kerningScale, transformType, returnedSpacing] {
        called = true;
        observeReads();
        mImports.glGetPathSpacingNV(pathListMode, numPaths, pathNameType, paths, pathBase, advanceScale, kerningScale, transformType, returnedSpacing);
    };


    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::GlGetPathSpacingNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pathListMode, toEncoder< int32_t >(numPaths, mScratch), pathNameType, toEncoder< gapic::coder::gles::Void__CP >(paths, mScratch), toEncoder< uint32_t >(pathBase, mScratch), toEncoder< float >(advanceScale, mScratch), toEncoder< float >(kerningScale, mScratch), transformType, toEncoder< gapic::coder::gles::GLfloat__P >(returnedSpacing, 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::glGetPerfMonitorCountersAMD(GLuint group, GLint* numCounters, GLint* maxActiveCounters, GLsizei counterSize, GLuint* counters) {
    GAPID_DEBUG("glGetPerfMonitorCountersAMD(%" PRIu32 ", %p, %p, %" PRId32 ", %p)", group, numCounters, maxActiveCounters, counterSize, counters);

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

    bool called = false;
    auto call = [this, &called, group, numCounters, maxActiveCounters, counterSize, counters] {
        called = true;
        observeReads();
        mImports.glGetPerfMonitorCountersAMD(group, numCounters, maxActiveCounters, counterSize, counters);
    };


    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::GlGetPerfMonitorCountersAMD coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(group, mScratch), toEncoder< gapic::coder::gles::GLint__P >(numCounters, mScratch), toEncoder< gapic::coder::gles::GLint__P >(maxActiveCounters, mScratch), toEncoder< int32_t >(counterSize, mScratch), toEncoder< gapic::coder::gles::GLuint__P >(counters, 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::glGetProgramResourcefvNV(ProgramId program, uint32_t programInterface, GLuint index, GLsizei propCount, uint32_t* props, GLsizei bufSize, GLsizei* length, GLfloat* params) {
    GAPID_DEBUG("glGetProgramResourcefvNV(%" PRIu32 ", %u, %" PRIu32 ", %" PRId32 ", %p, %" PRId32 ", %p, %p)", program, programInterface, index, propCount, props, bufSize, length, params);

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

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


    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::GlGetProgramResourcefvNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), programInterface, toEncoder< uint32_t >(index, mScratch), toEncoder< int32_t >(propCount, mScratch), toEncoder< gapic::coder::gles::GLenum__CP >(props, mScratch), toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLfloat__P >(params, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glGetSyncivAPPLE(GLsync sync, uint32_t pname, GLsizei bufSize, GLsizei* length, GLint* values) {
    GAPID_DEBUG("glGetSyncivAPPLE(%p, %u, %" PRId32 ", %p, %p)", sync, pname, bufSize, length, values);

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

    bool called = false;
    auto call = [this, &called, sync, pname, bufSize, length, values] {
        called = true;
        observeReads();
        mImports.glGetSyncivAPPLE(sync, pname, bufSize, length, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_APPLE_sync);
            GLsync l_GetSynciv_64_sync = sync;
            uint32_t l_GetSynciv_64_pname = pname;
            GLsizei l_GetSynciv_64_bufSize = bufSize;
            GLsizei* l_GetSynciv_64_length = length;
            GLint* l_GetSynciv_64_values = values;
            (void)l_GetSynciv_64_sync;
            call();
            switch (l_GetSynciv_64_pname) {
                case GLenum::GL_OBJECT_TYPE: // fall-through...
                case GLenum::GL_SYNC_CONDITION: // fall-through...
                case GLenum::GL_SYNC_FLAGS: // fall-through...
                case GLenum::GL_SYNC_STATUS: {
                    if (((l_GetSynciv_64_values) != (nullptr)) && ((l_GetSynciv_64_bufSize) > ((GLsizei)(0L)))) {
                        write(slice(l_GetSynciv_64_values, 0ULL, 1ULL), 0ULL, slice(values, 0ULL, 1ULL)[0ULL]);
                        if ((l_GetSynciv_64_length) != (nullptr)) {
                            write(slice(l_GetSynciv_64_length, 0ULL, 1ULL), 0ULL, (GLsizei)(1L));
                        }
                    }
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetSynciv_64_pname);
                }
            }
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetSyncivAPPLE coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, mScratch), pname, toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLint__P >(values, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glGetnUniformivEXT(ProgramId program, UniformLocation location, GLsizei bufSize, GLint* params) {
    GAPID_DEBUG("glGetnUniformivEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, bufSize, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_robustness);
            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::GlGetnUniformivEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), 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::glGetnUniformivKHR(ProgramId program, UniformLocation location, GLsizei bufSize, GLint* params) {
    GAPID_DEBUG("glGetnUniformivKHR(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, bufSize, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_KHR_robustness);
            call();
            subGetnUniformiv(call, program, location, bufSize, 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::GlGetnUniformivKHR coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), 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::glInsertEventMarkerEXT(GLsizei length, GLchar* marker) {
    GAPID_DEBUG("glInsertEventMarkerEXT(%" PRId32 ", %p)", length, marker);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_debug_marker);
            if ((length) > ((GLsizei)(0L))) {
                read(slice(marker, (uint64_t)((GLsizei)(0L)), (uint64_t)(length)));
            } else {
                (void)string((char*)(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::GlInsertEventMarkerEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__CP >(marker, 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::glIsEnablediNV(uint32_t target, GLuint index) {
    GAPID_DEBUG("glIsEnablediNV(%u, %" PRIu32 ")", target, index);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_NV_viewport_array);
            uint32_t l_IsEnabledi_66_capability = target;
            GLuint l_IsEnabledi_66_index = index;
            GLboolean l_IsEnabledi_66_result = subGetCapability(call, l_IsEnabledi_66_capability, l_IsEnabledi_66_index);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>(l_IsEnabledi_66_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::GlIsEnablediNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< uint32_t >(index, mScratch), toEncoder< uint8_t >(result, mScratch));
    coder.mextras.append(&mObservations);

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

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


    return result;
}

GLboolean GlesSpy::glIsVertexArrayOES(VertexArrayId array) {
    GAPID_DEBUG("glIsVertexArrayOES(%" PRIu32 ")", array);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_vertex_array_object);
            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::GlIsVertexArrayOES 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::glLabelObjectEXT(uint32_t type, GLuint object, GLsizei length, GLchar* label) {
    GAPID_DEBUG("glLabelObjectEXT(%u, %" PRIu32 ", %" PRId32 ", %p)", type, object, length, label);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_debug_label);
            std::string l_str = /* switch((label) != (nullptr)) */
                /* case true: */((((label) != (nullptr)) == (true))) ? (/* switch((length) == ((GLsizei)(0L))) */
                    /* case true: */((((length) == ((GLsizei)(0L))) == (true))) ? (string((char*)(label))) :
                    /* case false: */((((length) == ((GLsizei)(0L))) == (false))) ? (string(slice(label, (uint64_t)((GLsizei)(0L)), (uint64_t)(length)).as<char>())) :
                    /* default: */ "") :
                /* case false: */((((label) != (nullptr)) == (false))) ? ("") :
                /* default: */ "";
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            switch (type) {
                case GLenum::GL_TEXTURE: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mTextures, (TextureId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_FRAMEBUFFER: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mFramebuffers, (FramebufferId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_RENDERBUFFER: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mRenderbuffers, (RenderbufferId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_BUFFER_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mBuffers, (BufferId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_SHADER_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mShaders, (ShaderId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_PROGRAM_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mPrograms, (ProgramId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_VERTEX_ARRAY_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mVertexArrays, (VertexArrayId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_QUERY_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mQueries, (QueryId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_SAMPLER: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mSamplers, (SamplerId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_TRANSFORM_FEEDBACK: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mTransformFeedbacks, (TransformFeedbackId)(object))).mLabel = l_str;
                    break;
                }
                case GLenum::GL_PROGRAM_PIPELINE_OBJECT_EXT: {
                    checkNotNull(findOrZero(checkNotNull(l_ctx).mInstances.mPipelines, (PipelineId)(object))).mLabel = l_str;
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, 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::GlLabelObjectEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), type, toEncoder< uint32_t >(object, 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::glMakeImageHandleNonResidentNV(GLuint64 handle) {
    GAPID_DEBUG("glMakeImageHandleNonResidentNV(%" PRIu64 ")", handle);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

void* GlesSpy::glMapBufferRangeEXT(uint32_t target, GLintptr offset, GLsizeiptr length, uint32_t access) {
    GAPID_DEBUG("glMapBufferRangeEXT(%u, %" PRId32 ", %" PRId32 ", %u)", target, offset, length, access);

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

    void* result = nullptr;
    bool called = false;
    auto call = [this, &called, &result, target, offset, length, access] {
        called = true;
        observeReads();
        result = mImports.glMapBufferRangeEXT(target, offset, length, access);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_map_buffer_range);
            call();
            auto l_ptr = result;
            subMapBufferRange(call, target, offset, length, access, (uint8_t*)(l_ptr));
            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::GlMapBufferRangeEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(offset, mScratch), toEncoder< int32_t >(length, mScratch), access, toEncoder< gapic::coder::gles::Void__P >(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::glMatrixMult3x2fNV(uint32_t matrixMode, GLfloat* m) {
    GAPID_DEBUG("glMatrixMult3x2fNV(%u, %p)", matrixMode, m);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

void GlesSpy::glPathDashArrayNV(GLuint path, GLsizei dashCount, GLfloat* dashArray) {
    GAPID_DEBUG("glPathDashArrayNV(%" PRIu32 ", %" PRId32 ", %p)", path, dashCount, dashArray);

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

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


    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::GlPathDashArrayNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), toEncoder< int32_t >(dashCount, mScratch), toEncoder< gapic::coder::gles::GLfloat__CP >(dashArray, 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::glPathParameterfNV(GLuint path, uint32_t pname, GLfloat value) {
    GAPID_DEBUG("glPathParameterfNV(%" PRIu32 ", %u, %f)", path, pname, value);

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

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


    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::GlPathParameterfNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), pname, 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::glProgramUniform1uiEXT(ProgramId program, UniformLocation location, GLuint v0) {
    GAPID_DEBUG("glProgramUniform1uiEXT(%" PRIu32 ", %" PRId32 ", %" PRIu32 ")", program, location, v0);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniform2iv(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::GlProgramUniform2ivEXT 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::glProgramUniform3fvEXT(ProgramId program, UniformLocation location, GLsizei count, GLfloat* value) {
    GAPID_DEBUG("glProgramUniform3fvEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_separate_shader_objects);
            subProgramUniform3fv(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::GlProgramUniform3fvEXT 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::glProgramUniformHandleui64vNV(ProgramId program, UniformLocation location, GLsizei count, GLuint64* values) {
    GAPID_DEBUG("glProgramUniformHandleui64vNV(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlProgramUniformHandleui64vNV 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::GLuint64__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::glProgramUniformMatrix2fvEXT(ProgramId program, UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* value) {
    GAPID_DEBUG("glProgramUniformMatrix2fvEXT(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", program, location, count, transpose, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

void GlesSpy::glPushGroupMarkerEXT(GLsizei length, GLchar* marker) {
    GAPID_DEBUG("glPushGroupMarkerEXT(%" PRId32 ", %p)", length, marker);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_debug_marker);
            if ((length) > ((GLsizei)(0L))) {
                read(slice(marker, (uint64_t)((GLsizei)(0L)), (uint64_t)(length)));
            } else {
                (void)string((char*)(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::GlPushGroupMarkerEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< int32_t >(length, mScratch), toEncoder< gapic::coder::gles::GLchar__CP >(marker, 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::glStencilStrokePathInstancedNV(GLsizei numPaths, uint32_t pathNameType, void* paths, GLuint pathBase, GLint reference, GLuint mask, uint32_t transformType, GLfloat* transformValues) {
    GAPID_DEBUG("glStencilStrokePathInstancedNV(%" PRId32 ", %u, %p, %" PRIu32 ", %" PRId32 ", %" PRIu32 ", %u, %p)", numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues);

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

    bool called = false;
    auto call = [this, &called, numPaths, pathNameType, paths, pathBase, reference, mask, transformType, transformValues] {
        called = true;
        observeReads();
        mImports.glStencilStrokePathInstancedNV(numPaths, pathNameType, paths, pathBase, reference, 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::GlStencilStrokePathInstancedNV 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), toEncoder< int32_t >(reference, mScratch), 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::glStencilThenCoverFillPathNV(GLuint path, uint32_t fillMode, GLuint mask, uint32_t coverMode) {
    GAPID_DEBUG("glStencilThenCoverFillPathNV(%" PRIu32 ", %u, %" PRIu32 ", %u)", path, fillMode, mask, coverMode);

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

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


    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::GlStencilThenCoverFillPathNV coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(path, mScratch), fillMode, toEncoder< uint32_t >(mask, mScratch), coverMode);
    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::glTexBufferOES(uint32_t target, uint32_t internalformat, BufferId buffer) {
    GAPID_DEBUG("glTexBufferOES(%u, %u, %" PRIu32 ")", target, internalformat, buffer);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_texture_buffer);
            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::GlTexBufferOES 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::glTexStorage3DEXT(uint32_t target, GLsizei levels, uint32_t format, GLsizei width, GLsizei height, GLsizei depth) {
    GAPID_DEBUG("glTexStorage3DEXT(%u, %" PRId32 ", %u, %" PRId32 ", %" PRId32 ", %" PRId32 ")", target, levels, format, width, height, depth);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_texture_storage);
            subTexStorage3D(call, target, levels, format, width, height, depth);
            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::GlTexStorage3DEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(levels, mScratch), format, toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch), toEncoder< int32_t >(depth, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glTextureStorage1DEXT(TextureId texture, uint32_t target, GLsizei levels, uint32_t format, GLsizei width) {
    GAPID_DEBUG("glTextureStorage1DEXT(%" PRIu32 ", %u, %" PRId32 ", %u, %" PRId32 ")", texture, target, levels, format, width);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_EXT_texture_storage);
            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::GlTextureStorage1DEXT coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(texture, mScratch), target, toEncoder< int32_t >(levels, mScratch), format, 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::glBlendEquationSeparate(uint32_t rgb, uint32_t alpha) {
    GAPID_DEBUG("glBlendEquationSeparate(%u, %u)", rgb, alpha);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlBlendEquationSeparate coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), rgb, alpha);
    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::glBlendFuncSeparate(uint32_t src_factor_rgb, uint32_t dst_factor_rgb, uint32_t src_factor_alpha, uint32_t dst_factor_alpha) {
    GAPID_DEBUG("glBlendFuncSeparate(%u, %u, %u, %u)", src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha);

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

    bool called = false;
    auto call = [this, &called, src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha] {
        called = true;
        observeReads();
        mImports.glBlendFuncSeparate(src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subSetBlendFunc(call, (DrawBufferIndex)(0UL), checkNotNull(l_ctx).mConstants.mMaxDrawBuffers, src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha);
            call();
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlBlendFuncSeparate coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), src_factor_rgb, dst_factor_rgb, src_factor_alpha, dst_factor_alpha);
    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::glClearDepthf(GLfloat depth) {
    GAPID_DEBUG("glClearDepthf(%f)", depth);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mFramebuffer.mDepthClearValue = depth;
            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::GlClearDepthf coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(depth, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glFramebufferTexture2D(uint32_t framebuffer_target, uint32_t framebuffer_attachment, uint32_t texture_target, TextureId texture, GLint level) {
    GAPID_DEBUG("glFramebufferTexture2D(%u, %u, %u, %" PRIu32 ", %" PRId32 ")", framebuffer_target, framebuffer_attachment, texture_target, texture, level);

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

    bool called = false;
    auto call = [this, &called, framebuffer_target, framebuffer_attachment, texture_target, texture, level] {
        called = true;
        observeReads();
        mImports.glFramebufferTexture2D(framebuffer_target, framebuffer_attachment, texture_target, texture, level);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            subFramebufferTexture2D(call, framebuffer_target, framebuffer_attachment, texture_target, 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::GlFramebufferTexture2D coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), framebuffer_target, framebuffer_attachment, texture_target, 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::glInvalidateFramebuffer(uint32_t target, GLsizei count, uint32_t* attachments) {
    GAPID_DEBUG("glInvalidateFramebuffer(%u, %" PRId32 ", %p)", target, count, attachments);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subInvalidateFramebuffer(call, target, count, attachments);
            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::GlInvalidateFramebuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLenum__CP >(attachments, 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::glInvalidateSubFramebuffer(uint32_t target, GLsizei numAttachments, uint32_t* attachments, GLint x, GLint y, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glInvalidateSubFramebuffer(%u, %" PRId32 ", %p, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", target, numAttachments, attachments, x, y, width, height);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (target) {
                case GLenum::GL_FRAMEBUFFER: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, target);
                }
            }
            read(slice(attachments, (uint64_t)((GLsizei)(0L)), (uint64_t)(numAttachments)));
            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::GlInvalidateSubFramebuffer coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(numAttachments, mScratch), toEncoder< gapic::coder::gles::GLenum__CP >(attachments, 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::glStencilMask(GLuint mask) {
    GAPID_DEBUG("glStencilMask(%" PRIu32 ")", mask);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mFramebuffer.mStencilWritemask = mask;
            checkNotNull(l_ctx).mFramebuffer.mStencilBackWritemask = 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::GlStencilMask coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), 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::glDisable(uint32_t capability) {
    GAPID_DEBUG("glDisable(%u)", capability);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            subSetCapability(call, capability, false, (GLuint)(0UL), 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::GlDisable 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::glFlushMappedBufferRange(uint32_t target, GLintptr offset, GLsizeiptr length) {
    GAPID_DEBUG("glFlushMappedBufferRange(%u, %" PRId32 ", %" PRId32 ")", target, offset, length);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            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::GlFlushMappedBufferRange 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::glBindAttribLocation(ProgramId program, AttributeLocation location, const char* name) {
    GAPID_DEBUG("glBindAttribLocation(%" PRIu32 ", %" PRIu32 ", %s)", program, location, name);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            Slice<char> l_n = slice(name);
            subGlErrorInvalidOperationIf(call, ((int32_t((l_n.count()))) > (2L)) && ((string(slice(l_n, 0ULL, 3ULL))) == ("gl_")));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckProgram(call, l_ctx, program);
            subGlErrorInvalidValueIf(call, (location) >= (checkNotNull(l_ctx).mConstants.mMaxVertexAttribs));
            std::shared_ptr<Program> l_p = findOrZero(checkNotNull(l_ctx).mInstances.mPrograms, program);
            checkNotNull(l_p).mAttributeBindings[name] = location;
            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::GlBindAttribLocation coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< uint32_t >(location, 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::glGetActiveUniformBlockName(ProgramId program, UniformBlockId uniform_block_index, GLsizei buffer_size, GLsizei* buffer_bytes_written, GLchar* name) {
    GAPID_DEBUG("glGetActiveUniformBlockName(%" PRIu32 ", %" PRIu32 ", %" PRId32 ", %p, %p)", program, uniform_block_index, buffer_size, buffer_bytes_written, name);

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

    bool called = false;
    auto call = [this, &called, program, uniform_block_index, buffer_size, buffer_bytes_written, name] {
        called = true;
        observeReads();
        mImports.glGetActiveUniformBlockName(program, uniform_block_index, buffer_size, buffer_bytes_written, name);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            GLsizei l_writeString_72_buffer_size = buffer_size;
            GLsizei* l_writeString_72_buffer_bytes_written = buffer_bytes_written;
            GLchar* l_writeString_72_buffer = name;
            call();
            if (((l_writeString_72_buffer) != (nullptr)) && ((l_writeString_72_buffer_size) > ((GLsizei)(0L)))) {
                GLsizei l_buffer_size2 = l_writeString_72_buffer_size;
                if ((l_writeString_72_buffer_bytes_written) != (nullptr)) {
                    GLsizei l_length = (GLsizei)(slice(buffer_bytes_written, 0ULL, 1ULL)[0ULL]);
                    write(slice(l_writeString_72_buffer_bytes_written, 0ULL, 1ULL), 0ULL, l_length);
                    write(slice(l_writeString_72_buffer, (uint64_t)((GLsizei)(0L)), (uint64_t)((l_length) + ((GLsizei)(1L)))));
                } else {
                    write(slice(l_writeString_72_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::GlGetActiveUniformBlockName coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< uint32_t >(uniform_block_index, mScratch), toEncoder< int32_t >(buffer_size, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(buffer_bytes_written, 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::glGetActiveUniformBlockiv(ProgramId program, UniformBlockId uniform_block_index, uint32_t parameter_name, GLint* parameters) {
    GAPID_DEBUG("glGetActiveUniformBlockiv(%" PRIu32 ", %" PRIu32 ", %u, %p)", program, uniform_block_index, parameter_name, parameters);

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

    bool called = false;
    auto call = [this, &called, program, uniform_block_index, parameter_name, parameters] {
        called = true;
        observeReads();
        mImports.glGetActiveUniformBlockiv(program, uniform_block_index, parameter_name, parameters);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (parameter_name) {
                case GLenum::GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_BINDING: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_DATA_SIZE: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_NAME_LENGTH: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: // fall-through...
                case GLenum::GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, parameter_name);
                }
            }
            call();
            write(slice(parameters, 0ULL, 1ULL), 0ULL, slice(parameters, 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::GlGetActiveUniformBlockiv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< uint32_t >(uniform_block_index, mScratch), parameter_name, toEncoder< gapic::coder::gles::GLint__P >(parameters, 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::glGetProgramPipelineInfoLog(PipelineId pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) {
    GAPID_DEBUG("glGetProgramPipelineInfoLog(%" PRIu32 ", %" PRId32 ", %p, %p)", pipeline, bufSize, length, infoLog);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            GLsizei l_writeString_76_buffer_size = bufSize;
            GLsizei* l_writeString_76_buffer_bytes_written = length;
            GLchar* l_writeString_76_buffer = infoLog;
            call();
            if (((l_writeString_76_buffer) != (nullptr)) && ((l_writeString_76_buffer_size) > ((GLsizei)(0L)))) {
                GLsizei l_buffer_size2 = l_writeString_76_buffer_size;
                if ((l_writeString_76_buffer_bytes_written) != (nullptr)) {
                    GLsizei l_length = (GLsizei)(slice(length, 0ULL, 1ULL)[0ULL]);
                    write(slice(l_writeString_76_buffer_bytes_written, 0ULL, 1ULL), 0ULL, l_length);
                    write(slice(l_writeString_76_buffer, (uint64_t)((GLsizei)(0L)), (uint64_t)((l_length) + ((GLsizei)(1L)))));
                } else {
                    write(slice(l_writeString_76_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::GlGetProgramPipelineInfoLog 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);

}

GLboolean GlesSpy::glIsProgram(ProgramId program) {
    GAPID_DEBUG("glIsProgram(%" PRIu32 ")", program);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            call();
            if (__builtin_expect(shouldComputeExpectedReturn(), false)) {
                setExpectedReturn<GLboolean>((GLboolean)(checkNotNull(l_ctx).mInstances.mPrograms.count(program) > 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::GlIsProgram coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, 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::glLinkProgram(ProgramId program) {
    GAPID_DEBUG("glLinkProgram(%" PRIu32 ")", program);

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

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


    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);
            std::shared_ptr<Program> l_p = findOrZero(checkNotNull(l_ctx).mInstances.mPrograms, program);
            resolveAttributesAndUniforms(l_p, program);
            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::GlLinkProgram coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, 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::glProgramUniform1iv(ProgramId program, UniformLocation location, GLsizei count, GLint* values) {
    GAPID_DEBUG("glProgramUniform1iv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform1iv(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::GlProgramUniform1iv 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::glProgramUniform2f(ProgramId program, UniformLocation location, GLfloat value0, GLfloat value1) {
    GAPID_DEBUG("glProgramUniform2f(%" PRIu32 ", %" PRId32 ", %f, %f)", program, location, value0, value1);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            call();
            subProgramUniform2f(call, program, location, value0, value1);
        } 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::GlProgramUniform2f coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< float >(value0, mScratch), toEncoder< float >(value1, 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::glProgramUniform2ui(ProgramId program, UniformLocation location, GLuint value0, GLuint value1) {
    GAPID_DEBUG("glProgramUniform2ui(%" PRIu32 ", %" PRId32 ", %" PRIu32 ", %" PRIu32 ")", program, location, value0, value1);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            call();
            subProgramUniform2ui(call, program, location, value0, value1);
        } 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::GlProgramUniform2ui coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< uint32_t >(value0, mScratch), toEncoder< uint32_t >(value1, mScratch));
    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::glProgramUniform3i(ProgramId program, UniformLocation location, GLint value0, GLint value1, GLint value2) {
    GAPID_DEBUG("glProgramUniform3i(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", program, location, value0, value1, value2);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlProgramUniform3i coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(program, mScratch), toEncoder< int32_t >(location, mScratch), toEncoder< int32_t >(value0, mScratch), toEncoder< int32_t >(value1, mScratch), toEncoder< int32_t >(value2, mScratch));
    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::glProgramUniform4fv(ProgramId program, UniformLocation location, GLsizei count, GLfloat* values) {
    GAPID_DEBUG("glProgramUniform4fv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform4fv(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::GlProgramUniform4fv 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::glProgramUniform4uiv(ProgramId program, UniformLocation location, GLsizei count, GLuint* values) {
    GAPID_DEBUG("glProgramUniform4uiv(%" PRIu32 ", %" PRId32 ", %" PRId32 ", %p)", program, location, count, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
            subProgramUniform4uiv(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::GlProgramUniform4uiv 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::glShaderSource(ShaderId shader, GLsizei count, GLchar** source, GLint* length) {
    GAPID_DEBUG("glShaderSource(%" PRIu32 ", %" PRId32 ", %p, %p)", shader, count, source, length);

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

    bool called = false;
    auto call = [this, &called, shader, count, source, length] {
        called = true;
        observeReads();
        mImports.glShaderSource(shader, count, source, length);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
            subGlErrorInvalidValueIf(call, (count) < ((GLsizei)(0L)));
            Slice<GLchar*> l_sources = slice(source, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            subCheckShader(call, l_ctx, shader);
            std::shared_ptr<Shader> l_s = findOrZero(checkNotNull(l_ctx).mInstances.mShaders, shader);
            checkNotNull(l_s).mSource = "";
            if ((length) == (nullptr)) {
                for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                    checkNotNull(l_s).mSource += string((char*)(read(l_sources, (uint64_t)(l_i))));
                }
            } else {
                Slice<GLint> l_lengths = slice(length, (uint64_t)((GLsizei)(0L)), (uint64_t)(count));
                for (GLsizei l_i = (GLsizei)(0L); l_i < count; ++l_i) {
                    std::string l_str = /* switch((read(l_lengths, (uint64_t)(l_i))) < ((GLint)(0L))) */
                        /* case true: */((((read(l_lengths, (uint64_t)(l_i))) < ((GLint)(0L))) == (true))) ? (string((char*)(read(l_sources, (uint64_t)(l_i))))) :
                        /* case false: */((((read(l_lengths, (uint64_t)(l_i))) < ((GLint)(0L))) == (false))) ? (string(slice((char*)(read(l_sources, (uint64_t)(l_i))), (uint64_t)((GLint)(0L)), (uint64_t)(read(l_lengths, (uint64_t)(l_i)))))) :
                        /* default: */ "";
                    checkNotNull(l_s).mSource += l_str;
                }
            }
            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::GlShaderSource coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(shader, mScratch), toEncoder< int32_t >(count, mScratch), toEncoder< gapic::coder::gles::GLchar__CP__CP >(source, mScratch), toEncoder< gapic::coder::gles::GLint__CP >(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::glUniformMatrix2x3fv(UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* values) {
    GAPID_DEBUG("glUniformMatrix2x3fv(%" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", location, count, transpose, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlUniformMatrix2x3fv 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::glUniformMatrix3x2fv(UniformLocation location, GLsizei count, GLboolean transpose, GLfloat* values) {
    GAPID_DEBUG("glUniformMatrix3x2fv(%" PRId32 ", %" PRId32 ", %" PRIu8 ", %p)", location, count, transpose, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlUniformMatrix3x2fv 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::glDepthRangef(GLfloat near, GLfloat far) {
    GAPID_DEBUG("glDepthRangef(%f, %f)", near, far);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            std::shared_ptr<Context> l_ctx = subGetContext(call);
            checkNotNull(l_ctx).mRasterization.mDepthRange = {near, far};
            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::GlDepthRangef coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(near, mScratch), toEncoder< float >(far, 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);

}

GLubyte* GlesSpy::glGetStringi(uint32_t name, GLuint index) {
    GAPID_DEBUG("glGetStringi(%u, %" PRIu32 ")", name, index);

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

    GLubyte* result = nullptr;
    bool called = false;
    auto call = [this, &called, &result, name, index] {
        called = true;
        observeReads();
        result = mImports.glGetStringi(name, index);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            switch (name) {
                case GLenum::GL_EXTENSIONS: {
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, name);
                }
            }
            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::GlGetStringi coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), name, toEncoder< uint32_t >(index, mScratch), toEncoder< gapic::coder::gles::GLubyte__CP >(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::glDeleteSync(GLsync sync) {
    GAPID_DEBUG("glDeleteSync(%p)", sync);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subDeleteSync(call, sync);
            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::GlDeleteSync coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, 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::glGetSynciv(GLsync sync, uint32_t pname, GLsizei bufSize, GLsizei* length, GLint* values) {
    GAPID_DEBUG("glGetSynciv(%p, %u, %" PRId32 ", %p, %p)", sync, pname, bufSize, length, values);

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

    bool called = false;
    auto call = [this, &called, sync, pname, bufSize, length, values] {
        called = true;
        observeReads();
        mImports.glGetSynciv(sync, pname, bufSize, length, values);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            GLsync l_GetSynciv_114_sync = sync;
            uint32_t l_GetSynciv_114_pname = pname;
            GLsizei l_GetSynciv_114_bufSize = bufSize;
            GLsizei* l_GetSynciv_114_length = length;
            GLint* l_GetSynciv_114_values = values;
            (void)l_GetSynciv_114_sync;
            call();
            switch (l_GetSynciv_114_pname) {
                case GLenum::GL_OBJECT_TYPE: // fall-through...
                case GLenum::GL_SYNC_CONDITION: // fall-through...
                case GLenum::GL_SYNC_FLAGS: // fall-through...
                case GLenum::GL_SYNC_STATUS: {
                    if (((l_GetSynciv_114_values) != (nullptr)) && ((l_GetSynciv_114_bufSize) > ((GLsizei)(0L)))) {
                        write(slice(l_GetSynciv_114_values, 0ULL, 1ULL), 0ULL, slice(values, 0ULL, 1ULL)[0ULL]);
                        if ((l_GetSynciv_114_length) != (nullptr)) {
                            write(slice(l_GetSynciv_114_length, 0ULL, 1ULL), 0ULL, (GLsizei)(1L));
                        }
                    }
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetSynciv_114_pname);
                }
            }
        } while(false);
    } catch (gapii::AbortException& e) {
        if (!called) {
            call(); // abort() was called before the fence.
        }
        handleAbort(e);
    }
    uint64_t counter_at_end = mCommandStartEndCounter++;
    gapic::coder::atom::CommandCounter counter_value_encodable(counter_at_begin, counter_at_end);

    observeWrites();

    gapic::coder::gles::GlGetSynciv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLsync >(sync, mScratch), pname, toEncoder< int32_t >(bufSize, mScratch), toEncoder< gapic::coder::gles::GLsizei__P >(length, mScratch), toEncoder< gapic::coder::gles::GLint__P >(values, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glCompressedTexImage3D(uint32_t target, GLint level, uint32_t internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei image_size, TexturePointer data) {
    GAPID_DEBUG("glCompressedTexImage3D(%u, %" PRId32 ", %u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ", %p)", target, level, internalformat, width, height, depth, border, image_size, data);

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

    bool called = false;
    auto call = [this, &called, target, level, internalformat, width, height, depth, border, image_size, data] {
        called = true;
        observeReads();
        mImports.glCompressedTexImage3D(target, level, internalformat, width, height, depth, border, image_size, data);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlCompressedTexImage3D coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(level, mScratch), internalformat, toEncoder< int32_t >(width, mScratch), toEncoder< int32_t >(height, mScratch), toEncoder< int32_t >(depth, mScratch), toEncoder< int32_t >(border, mScratch), 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::glGetTexLevelParameterfv(uint32_t target, GLint level, uint32_t pname, GLfloat* params) {
    GAPID_DEBUG("glGetTexLevelParameterfv(%u, %" PRId32 ", %u, %p)", target, level, pname, params);

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

    bool called = false;
    auto call = [this, &called, target, level, pname, params] {
        called = true;
        observeReads();
        mImports.glGetTexLevelParameterfv(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::GlGetTexLevelParameterfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(level, mScratch), pname, toEncoder< gapic::coder::gles::GLfloat__P >(params, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

void GlesSpy::glGetTexParameterfv(uint32_t target, uint32_t parameter, GLfloat* values) {
    GAPID_DEBUG("glGetTexParameterfv(%u, %u, %p)", target, parameter, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(1L), (GLint)(0L));
            uint32_t l_GetTexParameter_118_target = target;
            uint32_t l_GetTexParameter_118_parameter = parameter;
            GLfloat* l_GetTexParameter_118_params = values;
            switch (l_GetTexParameter_118_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_118_target);
                }
            }
            subGlErrorInvalidEnumIf(call, (l_GetTexParameter_118_target) == (GLenum::GL_TEXTURE_BUFFER));
            std::shared_ptr<Texture> l_t = subGetBoundTextureOrErrorInvalidEnum(call, l_GetTexParameter_118_target);
            call();
            switch (l_GetTexParameter_118_parameter) {
                case GLenum::GL_TEXTURE_MAG_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mMagFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_FILTER: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mMinFilter));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_S: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mWrapS));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_T: {
                    subMinRequiredVersion(call, (GLint)(2L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mWrapT));
                    break;
                }
                case GLenum::GL_TEXTURE_BASE_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mBaseLevel));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_FUNC: {
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mCompareFunc));
                    break;
                }
                case GLenum::GL_TEXTURE_COMPARE_MODE: {
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mCompareMode));
                    break;
                }
                case GLenum::GL_TEXTURE_IMMUTABLE_FORMAT: {
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mImmutableFormat));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LEVEL: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mMaxLevel));
                    break;
                }
                case GLenum::GL_TEXTURE_MAX_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_t).mMaxLod);
                    break;
                }
                case GLenum::GL_TEXTURE_MIN_LOD: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_t).mMinLod);
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_A: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mSwizzleA));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_B: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mSwizzleB));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_G: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mSwizzleG));
                    break;
                }
                case GLenum::GL_TEXTURE_SWIZZLE_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mSwizzleR));
                    break;
                }
                case GLenum::GL_TEXTURE_WRAP_R: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mWrapR));
                    break;
                }
                case GLenum::GL_DEPTH_STENCIL_TEXTURE_MODE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    write(slice(l_GetTexParameter_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mDepthStencilTextureMode));
                    break;
                }
                case GLenum::GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(1L));
                    write(slice(l_GetTexParameter_118_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_118_params, 0ULL, 1ULL), 0ULL, (GLfloat)(checkNotNull(l_t).mImmutableLevels));
                    break;
                }
                case GLenum::GL_TEXTURE_BORDER_COLOR: {
                    subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
                    Slice<GLfloat> l_p = slice(l_GetTexParameter_118_params, 0ULL, 4ULL);
                    write(l_p, 0ULL, checkNotNull(l_t).mBorderColor[0ULL]);
                    write(l_p, 1ULL, checkNotNull(l_t).mBorderColor[1ULL]);
                    write(l_p, 2ULL, checkNotNull(l_t).mBorderColor[2ULL]);
                    write(l_p, 3ULL, 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_118_params, 0ULL, 1ULL), 0ULL, checkNotNull(l_t).mMaxAnisotropy);
                    break;
                }
                default: {
                    subGlErrorInvalidEnum(call, l_GetTexParameter_118_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::GlGetTexParameterfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, parameter, toEncoder< gapic::coder::gles::GLfloat__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::glSamplerParameteriv(SamplerId sampler, uint32_t pname, GLint* param) {
    GAPID_DEBUG("glSamplerParameteriv(%" PRIu32 ", %u, %p)", sampler, pname, param);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            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::GlTexBufferRange 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::glTexParameterIiv(uint32_t target, uint32_t pname, GLint* params) {
    GAPID_DEBUG("glTexParameterIiv(%u, %u, %p)", target, pname, params);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(2L));
            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::GlTexParameterIiv 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::glTexStorage2D(uint32_t target, GLsizei levels, uint32_t internalformat, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glTexStorage2D(%u, %" PRId32 ", %u, %" PRId32 ", %" PRId32 ")", target, levels, internalformat, width, height);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            subTexStorage2D(call, target, levels, internalformat, 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::GlTexStorage2D coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, toEncoder< int32_t >(levels, mScratch), 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::glVertexAttrib2fv(AttributeLocation location, GLfloat* value) {
    GAPID_DEBUG("glVertexAttrib2fv(%" PRIu32 ", %p)", location, value);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

void GlesSpy::glVertexAttrib4f(AttributeLocation location, GLfloat value0, GLfloat value1, GLfloat value2, GLfloat value3) {
    GAPID_DEBUG("glVertexAttrib4f(%" PRIu32 ", %f, %f, %f, %f)", location, value0, value1, value2, value3);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlVertexAttrib4f coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< uint32_t >(location, mScratch), toEncoder< float >(value0, mScratch), toEncoder< float >(value1, mScratch), toEncoder< float >(value2, mScratch), toEncoder< float >(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::glVertexAttribDivisor(AttributeLocation index, GLuint divisor) {
    GAPID_DEBUG("glVertexAttribDivisor(%" PRIu32 ", %" PRIu32 ")", index, divisor);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subMinRequiredVersion(call, (GLint)(3L), (GLint)(0L));
            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::GlVertexAttribDivisor 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::glVertexAttribI4iv(AttributeLocation index, GLint* values) {
    GAPID_DEBUG("glVertexAttribI4iv(%" PRIu32 ", %p)", index, values);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

}

EGLBoolean GlesSpy::eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) {
    GAPID_DEBUG("eglMakeCurrent(%p, %p, %p, %p)", display, draw, read, context);

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

    EGLBoolean result = 0;
    bool called = false;
    auto call = [this, &called, &result, display, draw, read, context] {
        called = true;
        observeReads();
        result = mImports.eglMakeCurrent(display, draw, read, context);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subSetContext(call, findOrZero(this->EGLContexts, context));
            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::EglMakeCurrent coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::EGLDisplay >(display, mScratch), toEncoder< gapic::coder::gles::EGLSurface >(draw, mScratch), toEncoder< gapic::coder::gles::EGLSurface >(read, mScratch), toEncoder< gapic::coder::gles::EGLContext >(context, 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;
}

int GlesSpy::CGLGetSurface(CGLContextObj ctx, CGSConnectionID* cid, CGSWindowID* wid, CGSSurfaceID* sid) {
    GAPID_DEBUG("CGLGetSurface(%p, %p, %p, %p)", ctx, cid, wid, sid);

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

    int result = 0;
    bool called = false;
    auto call = [this, &called, &result, ctx, cid, wid, sid] {
        called = true;
        observeReads();
        result = mImports.CGLGetSurface(ctx, cid, wid, sid);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            call();
            write(slice(cid, 0ULL, 1ULL), 0ULL, slice(cid, 0ULL, 1ULL)[0ULL]);
            write(slice(wid, 0ULL, 1ULL), 0ULL, slice(wid, 0ULL, 1ULL)[0ULL]);
            write(slice(sid, 0ULL, 1ULL), 0ULL, slice(sid, 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::CGLGetSurface coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::CGLContextObj >(ctx, mScratch), toEncoder< gapic::coder::gles::CGSConnectionID__P >(cid, mScratch), toEncoder< gapic::coder::gles::CGSWindowID__P >(wid, mScratch), toEncoder< gapic::coder::gles::CGSSurfaceID__P >(sid, 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::glColorPointer(GLint size, uint32_t type, GLsizei stride, void* pointer) {
    GAPID_DEBUG("glColorPointer(%" PRId32 ", %u, %" PRId32 ", %p)", size, type, stride, pointer);

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

    bool called = false;
    auto call = [this, &called, size, type, stride, pointer] {
        called = true;
        observeReads();
        mImports.glColorPointer(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::GlColorPointer 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::glDisableClientState(uint32_t array) {
    GAPID_DEBUG("glDisableClientState(%u)", array);

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

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


    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::GlDisableClientState coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), array);
    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::glDrawTexfvOES(GLfloat* coords) {
    GAPID_DEBUG("glDrawTexfvOES(%p)", coords);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

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

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

    bool called = false;
    auto call = [this, &called, pname, params] {
        called = true;
        observeReads();
        mImports.glFogfv(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::GlFogfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), pname, toEncoder< gapic::coder::gles::GLfloat__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::glGenerateMipmapOES(uint32_t target) {
    GAPID_DEBUG("glGenerateMipmapOES(%u)", target);

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

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


    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::GlGenerateMipmapOES 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::glGetClipPlanex(uint32_t plane, GLfixed* equation) {
    GAPID_DEBUG("glGetClipPlanex(%u, %p)", plane, equation);

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

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


    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::GlGetClipPlanex coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), plane, toEncoder< gapic::coder::gles::GLfixed__P >(equation, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

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

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

    bool called = false;
    auto call = [this, &called, light, pname, params] {
        called = true;
        observeReads();
        mImports.glGetLightfv(light, 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::GlGetLightfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), light, pname, toEncoder< gapic::coder::gles::GLfloat__P >(params, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

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

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

    bool called = false;
    auto call = [this, &called, pname, param] {
        called = true;
        observeReads();
        mImports.glLightModelxvOES(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::GlLightModelxvOES 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::glLightx(uint32_t light, uint32_t pname, GLfixed param) {
    GAPID_DEBUG("glLightx(%u, %u, %" PRId32 ")", light, pname, param);

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

    bool called = false;
    auto call = [this, &called, light, pname, param] {
        called = true;
        observeReads();
        mImports.glLightx(light, 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::GlLightx coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), light, 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::glLoadMatrixxOES(GLfixed* m) {
    GAPID_DEBUG("glLoadMatrixxOES(%p)", m);

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

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


    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::GlLoadMatrixxOES 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::glMaterialxvOES(uint32_t face, uint32_t pname, GLfixed* param) {
    GAPID_DEBUG("glMaterialxvOES(%u, %u, %p)", face, pname, param);

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

    bool called = false;
    auto call = [this, &called, face, pname, param] {
        called = true;
        observeReads();
        mImports.glMaterialxvOES(face, 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::GlMaterialxvOES 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::glMultiTexCoord4xOES(uint32_t texture, GLfixed v0, GLfixed v1, GLfixed v2, GLfixed v3) {
    GAPID_DEBUG("glMultiTexCoord4xOES(%u, %" PRId32 ", %" PRId32 ", %" PRId32 ", %" PRId32 ")", texture, v0, v1, v2, v3);

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

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


    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::GlMultiTexCoord4xOES 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::glOrthof(GLfloat l, GLfloat r, GLfloat b, GLfloat t, GLfloat n, GLfloat f) {
    GAPID_DEBUG("glOrthof(%f, %f, %f, %f, %f, %f)", l, r, b, t, n, f);

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

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


    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::GlOrthof coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< float >(l, mScratch), toEncoder< float >(r, mScratch), toEncoder< float >(b, mScratch), toEncoder< float >(t, mScratch), toEncoder< float >(n, mScratch), toEncoder< float >(f, mScratch));
    coder.mextras.append(&mObservations);

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

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

}

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

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

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

}

uint32_t GlesSpy::glQueryMatrixxOES(GLfixed* mantissa, GLint* exponent) {
    GAPID_DEBUG("glQueryMatrixxOES(%p, %p)", mantissa, exponent);

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

    uint32_t result = 0;
    bool called = false;
    auto call = [this, &called, &result, mantissa, exponent] {
        called = true;
        observeReads();
        result = mImports.glQueryMatrixxOES(mantissa, exponent);
    };


    uint64_t counter_at_begin = mCommandStartEndCounter++;

    try {
        do {
            subRequiresExtension(call, ExtensionId::GL_OES_query_matrix);
            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::GlQueryMatrixxOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), toEncoder< gapic::coder::gles::GLfixed__P >(mantissa, mScratch), toEncoder< gapic::coder::gles::GLint__P >(exponent, 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::glRenderbufferStorageOES(uint32_t target, uint32_t internalformat, GLsizei width, GLsizei height) {
    GAPID_DEBUG("glRenderbufferStorageOES(%u, %u, %" PRId32 ", %" PRId32 ")", target, internalformat, width, height);

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

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


    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::GlRenderbufferStorageOES 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::glScalef(GLfloat x, GLfloat y, GLfloat z) {
    GAPID_DEBUG("glScalef(%f, %f, %f)", x, y, z);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

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

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

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

}

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

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

    bool called = false;
    auto call = [this, &called, target, pname, params] {
        called = true;
        observeReads();
        mImports.glTexEnvfv(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::GlTexEnvfv coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), target, pname, toEncoder< gapic::coder::gles::GLfloat__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::glTexGenxvOES(uint32_t coord, uint32_t pname, GLfixed* params) {
    GAPID_DEBUG("glTexGenxvOES(%u, %u, %p)", coord, pname, params);

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

    bool called = false;
    auto call = [this, &called, coord, pname, params] {
        called = true;
        observeReads();
        mImports.glTexGenxvOES(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::GlTexGenxvOES coder(mScratch.vector<gapic::Encodable*>(kMaxExtras), coord, 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::glTexParameterx(uint32_t target, uint32_t pname, GLfixed param) {
    GAPID_DEBUG("glTexParameterx(%u, %u, %" PRId32 ")", target, pname, param);

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

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


    uint64_t counter_at_begin = mCommandStartEndCounter++;

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

    observeWrites();

    gapic::coder::gles::GlTexParameterx 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::replayBindRenderer(uint32_t id) {
    GAPID_DEBUG("replayBindRenderer(%" 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::ReplayBindRenderer 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);

}
} // namespace gapii