//
// Copyright 2025 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// FrameCaptureCL.cpp:
//   ANGLE CL Frame capture implementation.
//

#include "common/unsafe_buffers.h"
#include "libANGLE/capture/FrameCapture.h"

#include "common/angle_version_info.h"
#include "common/frame_capture_utils.h"
#include "common/serializer/JsonSerializer.h"
#include "common/string_utils.h"
#include "common/system_utils.h"
#include "libANGLE/CLBuffer.h"
#include "libANGLE/CLCommandQueue.h"
#include "libANGLE/CLContext.h"
#include "libANGLE/CLImage.h"
#include "libANGLE/CLProgram.h"
#include "libANGLE/capture/capture_cl_autogen.h"
#include "libANGLE/capture/serialize.h"
#include "libANGLE/cl_utils.h"
#include "libGLESv2/cl_stubs_autogen.h"

#if !ANGLE_CAPTURE_ENABLED
#    error Frame capture must be enabled to include this file.
#endif  // !ANGLE_CAPTURE_ENABLED

#ifndef ANGLE_ENABLE_CL
#    error OpenCL must be enabled to include this file.
#endif  // !ANGLE_ENABLE_CL

namespace angle
{

// Some replay functions can get quite large. If over a certain size, this method breaks up the
// function into parts to avoid overflowing the stack and causing slow compilation.
void WriteCppReplayFunctionWithPartsCL(ReplayFunc replayFunc,
                                       ReplayWriter &replayWriter,
                                       uint32_t frameIndex,
                                       FrameCaptureBinaryData *binaryData,
                                       const std::vector<CallCapture> &calls,
                                       std::stringstream &header,
                                       std::stringstream &out)
{
    out << "void "
        << FmtFunction(replayFunc, kNoContextId, FuncUsage::Definition, frameIndex, kNoPartId)
        << "\n"
        << "{\n";

    for (const CallCapture &call : calls)
    {
        // Process active calls for Setup and inactive calls for SetupInactive
        if ((call.isActive && replayFunc != ReplayFunc::SetupInactive) ||
            (!call.isActive && replayFunc == ReplayFunc::SetupInactive))
        {
            out << "    ";
            WriteCppReplayForCallCL(call, replayWriter, out, header, binaryData);
            out << ";\n";
        }
    }
    out << "}\n";
}

void WriteCppReplayForCallCL(const CallCapture &call,
                             ReplayWriter &replayWriter,
                             std::ostream &out,
                             std::ostream &header,
                             FrameCaptureBinaryData *binaryData)
{
    if (call.customFunctionName == "Comment")
    {
        // Just write it directly to the file and move on
        WriteComment(out, call);
        return;
    }

    std::ostringstream callOut;
    std::ostringstream postCallAdditions;

    const ParamCapture &returnValue = call.params.getReturnValue();
    switch (returnValue.type)
    {
        case ParamType::Tcl_context:
            callOut << "clContextsMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_contextVal)
                    << "] = ";
            break;
        case ParamType::Tcl_command_queue:
            callOut << "clCommandQueuesMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_command_queueVal)
                    << "] = ";
            break;
        case ParamType::Tcl_mem:
            callOut << "clMemMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_memVal)
                    << "] = ";
            break;
        case ParamType::Tcl_sampler:
            callOut << "clSamplerMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_samplerVal)
                    << "] = ";
            break;
        case ParamType::Tcl_program:
            callOut << "clProgramsMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_programVal)
                    << "] = ";
            break;
        case ParamType::Tcl_kernel:
            callOut << "clKernelsMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_kernelVal)
                    << "] = ";
            break;
        case ParamType::Tcl_event:
            callOut << "clEventsMap["
                    << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                           &returnValue.value.cl_eventVal)
                    << "] = ";
            break;
        case ParamType::TvoidPointer:
            if (cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                    returnValue.value.voidPointerVal) != SIZE_MAX)
            {
                callOut << "clVoidMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                               returnValue.value.voidPointerVal)
                        << "] = ";
            }
            break;
        default:
            break;
    }

    callOut << call.name() << "(";

    bool first = true;
    for (const ParamCapture &param : call.params.getParamCaptures())
    {
        if (!first)
        {
            callOut << ", ";
        }

        if (param.arrayClientPointerIndex != -1 && param.value.voidConstPointerVal != nullptr)
        {
            int clientIndex = (param.arrayClientPointerMergedIndex != -1)
                                  ? param.arrayClientPointerMergedIndex
                                  : param.arrayClientPointerIndex;
            callOut << "gClientArrays[" << clientIndex << "]";
            if (param.arrayClientPointerOffset != 0)
            {
                callOut << " + " << param.arrayClientPointerOffset;
            }
        }
        else if (param.readBufferSizeBytes > 0)
        {
            callOut << "(" << ParamTypeToString(param.type) << ")gReadBuffer";
        }
        else if (param.data.empty())
        {
            if (param.type == ParamType::Tcl_platform_idPointer &&
                param.value.cl_platform_idPointerVal)
            {
                callOut << "clPlatformsMap";
            }
            else if (param.type == ParamType::Tcl_platform_id)
            {
                callOut << "clPlatformsMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_platform_idVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_device_idPointer &&
                     param.value.cl_device_idPointerVal)
            {
                std::vector<size_t> tempDeviceIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);

                cl_uint numDevices = call.params.getParamCaptures()[2].value.cl_uintVal;
                out << "temporaryDevicesList.clear();\n    temporaryDevicesList.resize("
                    << numDevices << ");\n    ";
                callOut << "temporaryDevicesList.data()";
                for (cl_uint i = 0; i < numDevices; ++i)
                {
                    postCallAdditions << ";\n    clDevicesMap[" << tempDeviceIndices[i]
                                      << "] = temporaryDevicesList[" << i << "]";
                }
            }
            else if (param.type == ParamType::Tcl_device_id)
            {
                callOut << "clDevicesMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_device_idVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_context)
            {
                callOut << "clContextsMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_contextVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_command_queue)
            {
                callOut << "clCommandQueuesMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_command_queueVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_mem)
            {
                callOut << "clMemMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_memVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_sampler)
            {
                callOut << "clSamplerMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_samplerVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_program)
            {
                callOut << "clProgramsMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_programVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_kernel)
            {
                callOut << "clKernelsMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_kernelVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_event)
            {
                callOut << "clEventsMap["
                        << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                               &param.value.cl_eventVal)
                        << "]";
            }
            else if (param.type == ParamType::Tcl_eventPointer)
            {
                if (param.value.cl_eventPointerVal)
                {
                    callOut << "&clEventsMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                                   &param.value.cl_eventVal)
                            << "]";
                }
                else
                {
                    callOut << "NULL";
                }
            }
            else if (param.type == ParamType::TvoidConstPointer)
            {
                if (cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                        &param.value.cl_memVal) != SIZE_MAX)
                {
                    callOut << "(const void *)" << "&clMemMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                                   &param.value.cl_memVal)
                            << "]";
                }
                else if (cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                             &param.value.cl_samplerVal) != SIZE_MAX)
                {
                    callOut << "(const void *)" << "&clSamplerMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                                   &param.value.cl_samplerVal)
                            << "]";
                }
                else if (cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                             &param.value.cl_command_queueVal) != SIZE_MAX)
                {
                    callOut << "(const void *)" << "&clCommandQueuesMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                                   &param.value.cl_command_queueVal)
                            << "]";
                }
                else if (cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                             param.value.voidConstPointerVal) != SIZE_MAX)
                {
                    callOut << "clVoidMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                                   param.value.voidConstPointerVal)
                            << "]";
                }
                else
                {
                    WriteParamCaptureReplay(callOut, call, param);
                }
            }
            else if (param.type == ParamType::TvoidPointer)
            {
                if (cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                        param.value.voidPointerVal) != SIZE_MAX)
                {
                    callOut << "clVoidMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getCLVoidIndex(
                                   param.value.voidPointerVal)
                            << "]";
                }
                else
                {
                    WriteParamCaptureReplay(callOut, call, param);
                }
            }
            else if (param.type == ParamType::Tcl_mem_destructor_func_type ||
                     param.type == ParamType::Tcl_callback_func_type ||
                     param.type == ParamType::Tcl_svm_free_callback_func_type ||
                     param.type == ParamType::Tcl_program_func_type ||
                     param.type == ParamType::Tcl_context_destructor_func_type ||
                     param.type == ParamType::Tcl_context_func_type ||
                     param.type == ParamType::Tcl_void_func_type)
            {
                callOut << "NULL";
            }
            else if (param.type == ParamType::Tcl_memConstPointer && cl::Platform::GetDefault()
                                                                         ->getFrameCaptureShared()
                                                                         ->getCLObjVector(&param)
                                                                         .size())
            {
                std::vector<size_t> tempBufferIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                out << "temporaryBuffersList = {";
                for (uint32_t i = 0; i < tempBufferIndices.size(); ++i)
                {
                    out << (i != 0 ? ", " : "") << "clMemMap[" << tempBufferIndices.at(i) << "]";
                }
                out << "};\n    ";
                callOut << "temporaryBuffersList.data()";
            }
            else if (param.type == ParamType::Tcl_eventConstPointer)
            {
                std::vector<size_t> tempEventIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                if (tempEventIndices.empty())
                {
                    callOut << "NULL";
                }
                else
                {
                    out << "temporaryEventsList = {";
                    for (uint32_t i = 0; i < tempEventIndices.size(); ++i)
                    {
                        out << (i != 0 ? ", " : "") << "clEventsMap[" << tempEventIndices.at(i)
                            << "]";
                    }
                    out << "};\n    ";
                    callOut << "temporaryEventsList.data()";
                }
            }
            else if (param.type == ParamType::Tcl_device_idConstPointer)
            {
                std::vector<size_t> tempDeviceIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                if (tempDeviceIndices.empty())
                {
                    callOut << "NULL";
                }
                else
                {
                    out << "temporaryDevicesList = {";
                    for (uint32_t i = 0; i < tempDeviceIndices.size(); ++i)
                    {
                        if (i != 0)
                        {
                            out << ", ";
                        }
                        out << "clDevicesMap[" << tempDeviceIndices.at(i) << "]";
                    }
                    out << "};\n    ";
                    callOut << "temporaryDevicesList.data()";
                }
            }
            else if (param.type == ParamType::Tcl_kernelPointer)
            {
                std::vector<size_t> tempKernelIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                cl_uint numKernels = call.params.getParamCaptures()[1].value.cl_uintVal;
                out << "temporaryKernelsList.clear();\ntemporaryKernelsList.resize(" << numKernels
                    << ");\n    ";
                callOut << "temporaryKernelsList.data()";
                for (cl_uint i = 0; i < numKernels; ++i)
                {
                    postCallAdditions << ";\n    clKernelsMap[" << tempKernelIndices[i]
                                      << "] = temporaryKernelsList[" << i << "]";
                }
            }
            else if (param.type == ParamType::TvoidConstPointerPointer &&
                     cl::Platform::GetDefault()
                         ->getFrameCaptureShared()
                         ->getCLObjVector(&param)
                         .size())
            {
                std::vector<size_t> offsets =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                out << "temporaryVoidPtrList = {";
                for (size_t i = 0; i < offsets.size(); ++i)
                {
                    out << (i != 0 ? ", " : "") << "&((char*)temporaryVoidPtr)[" << offsets.at(i)
                        << "]";
                }
                out << "};\n    ";
                callOut << "temporaryVoidPtrList.data()";
            }
            else if (param.type == ParamType::TvoidPointerPointer ||
                     param.type == ParamType::TvoidConstPointerPointer)
            {
                std::vector<size_t> tempVoidIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                out << "temporaryVoidPtrList = {";
                for (uint32_t i = 0; i < tempVoidIndices.size(); ++i)
                {
                    out << (i != 0 ? ", " : "") << "clVoidMap[" << tempVoidIndices.at(i) << "]";
                }
                out << "};\n    ";
                callOut << "temporaryVoidPtrList.data()";
            }
            else if (param.type == ParamType::Tcl_programConstPointer && param.value.size_tVal)
            {
                std::vector<size_t> tempProgramIndices =
                    cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(&param);
                out << "temporaryProgramsList = {";
                for (uint32_t i = 0; i < tempProgramIndices.size(); ++i)
                {
                    out << (i != 0 ? ", " : "") << "clProgramsMap[" << tempProgramIndices.at(i)
                        << "]";
                }
                out << "};\n    ";
                callOut << "temporaryProgramsList.data()";
            }
            else if (param.type == ParamType::Tcl_context_propertiesConstPointer)
            {
                if (param.value.cl_context_propertiesConstPointerVal)
                {
                    callOut << "temporaryContextProps.data()";
                }
                else
                {
                    WriteParamCaptureReplay(callOut, call, param);
                }
            }
            else
            {
                WriteParamCaptureReplay(callOut, call, param);
            }
        }
        else
        {
            switch (param.type)
            {
                case ParamType::TcharConstPointerPointer:
                    WriteStringPointerParamReplay(replayWriter, callOut, header, call, param);
                    break;
                case ParamType::Tcl_device_idPointer:
                    callOut << "clDevicesMap";
                    break;
                case ParamType::TcharUnsignedConstPointerPointer:
                {
                    std::string tempStructureName = "temporaryCharPointerList";
                    std::string tempStructureType = "(const char *)";
                    if (param.type == ParamType::TcharUnsignedConstPointerPointer)
                    {
                        tempStructureName = "temporaryUnsignedCharPointerList";
                        tempStructureType = "(const unsigned char *)";
                    }
                    const std::vector<uint8_t> *data;
                    out << tempStructureName << " = {";
                    for (size_t i = 0; i < param.data.size(); ++i)
                    {
                        if (i != 0)
                        {
                            out << ", ";
                        }
                        data          = &param.data[i];
                        const size_t offset = binaryData->append(data->data(), data->size());
                        out << tempStructureType << "GetBinaryData[" << offset << "]";
                    }
                    out << "};\n    ";
                    callOut << tempStructureName << ".data()";
                    break;
                }
                case ParamType::Tcl_image_descConstPointer:
                    cl_image_desc tempImageDesc;
                    ANGLE_UNSAFE_TODO(
                        std::memcpy(&tempImageDesc, param.data[0].data(), sizeof(cl_image_desc)));
                    if (tempImageDesc.mem_object)
                    {
                        out << "    std::memcpy(&temporaryImageDesc, ";
                        WriteBinaryParamReplay(replayWriter, out, header, call, param, binaryData);
                        out << ", sizeof(cl_image_desc));\ntemporaryImageDesc.mem_object = "
                               "clMemMap["
                            << cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(
                                   &tempImageDesc.mem_object)
                            << "];\n    ";
                        callOut << "&temporaryImageDesc";
                    }
                    else
                    {
                        WriteBinaryParamReplay(replayWriter, callOut, header, call, param,
                                               binaryData);
                    }
                    break;
                case ParamType::TvoidPointer:
                {
                    // For clEnqueueNativeKernel
                    if (call.entryPoint == EntryPoint::CLEnqueueNativeKernel)
                    {
                        std::vector<size_t> bufferIndices =
                            cl::Platform::GetDefault()->getFrameCaptureShared()->getCLObjVector(
                                &param);
                        size_t totalSize = call.params.getParamCaptures()[3].value.size_tVal;
                        out << "temporaryVoidPtr = (void *)std::malloc(" << totalSize
                            << ");\nstd::memcpy(&temporaryVoidPtr, ";
                        WriteBinaryParamReplay(replayWriter, out, header, call, param, binaryData);
                        out << ", " << totalSize << ");\n    ";
                        callOut << "temporaryVoidPtr";
                    }
                    else
                    {
                        WriteBinaryParamReplay(replayWriter, callOut, header, call, param,
                                               binaryData);
                    }
                    break;
                }
                default:
                    WriteBinaryParamReplay(replayWriter, callOut, header, call, param, binaryData);
                    break;
            }
        }

        first = false;
    }

    callOut << ")";

    out << callOut.str() << postCallAdditions.str();
}

void WriteInitReplayCallCL(bool compression,
                           std::ostream &out,
                           const std::string &captureLabel,
                           size_t maxClientArraySize,
                           size_t readBufferSize,
                           const std::map<ParamType, uint32_t> &maxCLParamsSize)
{
    std::string binaryDataFileName = GetBinaryDataFilePath(compression, captureLabel);
    out << "    // binaryDataFileName = " << binaryDataFileName << "\n";
    out << "    // maxClientArraySize = " << maxClientArraySize << "\n";
    out << "    // readBufferSize = " << readBufferSize << "\n";
    out << "    // clPlatformsMapSize = " << maxCLParamsSize.at(ParamType::Tcl_platform_idPointer)
        << "\n";
    out << "    // clDevicesMapSize = " << maxCLParamsSize.at(ParamType::Tcl_device_idPointer)
        << "\n";
    out << "    // clContextsMapSize = " << maxCLParamsSize.at(ParamType::Tcl_context) << "\n";
    out << "    // clCommandQueuesMapSize = " << maxCLParamsSize.at(ParamType::Tcl_command_queue)
        << "\n";
    out << "    // clMemMapSize = " << maxCLParamsSize.at(ParamType::Tcl_mem) << "\n";
    out << "    // clEventsMapSize = " << maxCLParamsSize.at(ParamType::Tcl_eventPointer) << "\n";
    out << "    // clProgramsMapSize = " << maxCLParamsSize.at(ParamType::Tcl_program) << "\n";
    out << "    // clKernelsMapSize = " << maxCLParamsSize.at(ParamType::Tcl_kernel) << "\n";
    out << "    // clSamplerMapSize = " << maxCLParamsSize.at(ParamType::Tcl_sampler) << "\n";
    out << "    // clVoidMapSize = " << maxCLParamsSize.at(ParamType::TvoidPointer) << "\n";
    out << "    InitializeReplayCL2(\"" << binaryDataFileName << "\", " << maxClientArraySize
        << ", " << readBufferSize << ", " << maxCLParamsSize.at(ParamType::Tcl_platform_idPointer)
        << ", " << maxCLParamsSize.at(ParamType::Tcl_device_idPointer) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_context) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_command_queue) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_mem) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_eventPointer) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_program) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_kernel) << ", "
        << maxCLParamsSize.at(ParamType::Tcl_sampler) << ", "
        << maxCLParamsSize.at(ParamType::TvoidPointer) << ");\n";

    // Load binary data
    out << "    InitializeBinaryDataLoader();\n";
}

void FrameCaptureShared::trackCLMemUpdate(const cl_mem *mem, bool referenced)
{
    std::vector<cl_mem> &mCLDirtyMem = mResourceTrackerCL.mCLDirtyMem;
    // retained or created cl mem object
    if (referenced)
    {
        // Potentially mark as dirty
        auto it = std::find(mCLDirtyMem.begin(), mCLDirtyMem.end(), *mem);
        if (it == mCLDirtyMem.end())
        {
            mCLDirtyMem.push_back(*mem);
        }
    }
    else
    {
        std::unordered_map<cl_mem, cl_mem> &mCLSubBufferToParent =
            mResourceTrackerCL.mCLSubBufferToParent;
        if ((*mem)->cast<cl::Memory>().getRefCount() == 1)
        {
            auto it = std::find(mCLDirtyMem.begin(), mCLDirtyMem.end(), *mem);
            if (it != mCLDirtyMem.end())
            {
                mCLDirtyMem.erase(it);
            }

            if (removeUnneededOpenCLCalls)
            {
                removeCLMemOccurrences(mem, &mFrameCalls);
            }
            mCLSubBufferToParent.erase(*mem);
            (*mem)->cast<cl::Memory>().release();
        }
        if (mCLSubBufferToParent.find(*mem) != mCLSubBufferToParent.end())
        {
            trackCLMemUpdate(&mCLSubBufferToParent[*mem], false);
        }
    }
}

void FrameCaptureShared::trackCLProgramUpdate(const cl_program *program,
                                              bool referenced,
                                              cl_uint numLinkedPrograms,
                                              const cl_program *linkedPrograms)
{
    std::unordered_map<cl_program, cl_uint> &mCLProgramLinkCounter =
        mResourceTrackerCL.mCLProgramLinkCounter;
    std::unordered_map<cl_program, std::vector<cl_program>> &mCLLinkedPrograms =
        mResourceTrackerCL.mCLLinkedPrograms;
    // retained or created cl program object
    if (referenced)
    {
        // Increment link count for this program
        if (mCLProgramLinkCounter.find(*program) == mCLProgramLinkCounter.end())
        {
            mCLProgramLinkCounter[*program] = 0;
        }
        ++mCLProgramLinkCounter[*program];

        // Setup the linked programs if this call is from capturing clCompileProgram or
        // clLinkProgram
        if (numLinkedPrograms)
        {
            mCLLinkedPrograms[*program] = std::vector<cl_program>();
            for (cl_uint i = 0; i < numLinkedPrograms; ++i)
            {
                mCLLinkedPrograms[*program].push_back(ANGLE_UNSAFE_TODO(linkedPrograms[i]));
            }
        }

        // Go through the linked programs and increment their link counts
        for (size_t i = 0; mCLLinkedPrograms.find(*program) != mCLLinkedPrograms.end() &&
                           i < mCLLinkedPrograms[*program].size();
             ++i)
        {
            trackCLProgramUpdate(&mCLLinkedPrograms[*program].at(i), true, 0, nullptr);
        }
    }
    else
    {
        // Decrement link count for this program and the linked programs
        --mCLProgramLinkCounter[*program];
        for (size_t i = 0; mCLLinkedPrograms.find(*program) != mCLLinkedPrograms.end() &&
                           i < mCLLinkedPrograms[*program].size();
             ++i)
        {
            trackCLProgramUpdate(&mCLLinkedPrograms[*program].at(i), false, 0, nullptr);
        }

        // Remove the calls containing this object if the link count is 0
        if (mCLProgramLinkCounter[*program] == 0)
        {
            mCLProgramLinkCounter.erase(*program);
            if (mCLLinkedPrograms.find(*program) != mCLLinkedPrograms.end())
            {
                mCLLinkedPrograms.erase(*program);
            }

            if (removeUnneededOpenCLCalls)
            {
                removeCLProgramOccurrences(program, &mFrameCalls);
            }
        }
    }
}

void FrameCaptureShared::injectMemcpy(void *src,
                                      void *dest,
                                      size_t size,
                                      std::vector<CallCapture> *calls)
{
    // Inject memcpy call before unmap

    // Create param buffer
    ParamBuffer paramBuffer;

    // Create dest parameter
    ParamCapture destParam("dest", ParamType::TvoidConstPointer);
    InitParamValue(ParamType::TvoidPointer, dest, &destParam.value);
    paramBuffer.addParam(std::move(destParam));

    // Create src param
    ParamCapture updateMemory("src", ParamType::TvoidConstPointer);
    CaptureMemory(src, size, &updateMemory);
    paramBuffer.addParam(std::move(updateMemory));

    paramBuffer.addValueParam<size_t>("size", ParamType::Tsize_t, size);

    calls->emplace(calls->end() - 1, "std::memcpy", std::move(paramBuffer));
}

void FrameCaptureShared::captureUpdateCLObjs(std::vector<CallCapture> *calls)
{
    std::vector<cl_mem> &mCLDirtyMem         = mResourceTrackerCL.mCLDirtyMem;
    std::vector<void *> &mCLDirtySVM         = mResourceTrackerCL.mCLDirtySVM;
    cl_command_queue &mCLCurrentCommandQueue = mResourceTrackerCL.mCLCurrentCommandQueue;
    for (uint32_t i = 0; i < mCLDirtyMem.size(); ++i)
    {
        cl_mem_object_type memType;
        if (IsError(mCLDirtyMem.at(i)->cast<cl::Memory>().getInfo(
                cl::MemInfo::Type, sizeof(cl_mem_object_type), &memType, nullptr)))
        {
            continue;
        }
        if (memType == CL_MEM_OBJECT_BUFFER)
        {
            void *ptr;

            if (calls->back().entryPoint == EntryPoint::CLEnqueueUnmapMemObject)
            {
                CallCapture *mapCall = &mResourceTrackerCL.mCLMapCall.at(
                    calls->back()
                        .params.getParam("mapped_ptr", ParamType::TvoidPointer, 2)
                        .value.voidPointerVal);
                size_t offset =
                    mapCall->params.getParam("offset", ParamType::Tsize_t, 4).value.size_tVal;
                size_t size =
                    mapCall->params.getParam("size", ParamType::Tsize_t, 5).value.size_tVal;
                ptr = malloc(size);

                // Call clEnqueueReadBuffer to get the current data in the buffer
                EnqueueReadBuffer(mCLCurrentCommandQueue, mCLDirtyMem.at(i), true, offset, size,
                                  ptr, 0, nullptr, nullptr);

                // Inject memcpy call BEFORE unmap
                injectMemcpy(ptr,
                             calls->back()
                                 .params.getParam("mapped_ptr", ParamType::TvoidPointer, 2)
                                 .value.voidPointerVal,
                             size, calls);
            }
            else
            {
                size_t bufferSize = mCLDirtyMem.at(i)->cast<cl::Buffer>().getSize();
                ptr               = malloc(bufferSize);

                // Call clEnqueueReadBuffer to get the current data in the buffer
                EnqueueReadBuffer(mCLCurrentCommandQueue, mCLDirtyMem.at(i), true, 0, bufferSize,
                                  ptr, 0, nullptr, nullptr);

                // Pretend that a "clEnqueueWriteBuffer" was called with the above data retrieved
                calls->push_back(CaptureEnqueueWriteBuffer(true, mCLCurrentCommandQueue,
                                                           mCLDirtyMem.at(i), true, 0, bufferSize,
                                                           ptr, 0, nullptr, nullptr, CL_SUCCESS));

                // Implicit release, so going into the starting frame the buffer has the correct
                // reference count
                mCLDirtyMem.at(i)->cast<cl::Memory>().release();
            }
            free(ptr);
        }
        else if (memType == CL_MEM_OBJECT_PIPE)
        {
            UNIMPLEMENTED();
        }
        else
        {
            cl::Image *clImg = &mCLDirtyMem.at(i)->cast<cl::Image>();
            void *ptr;

            if (calls->back().entryPoint == EntryPoint::CLEnqueueUnmapMemObject)
            {
                CallCapture *mapCall = &mResourceTrackerCL.mCLMapCall.at(
                    calls->back()
                        .params.getParam("mapped_ptr", ParamType::TvoidPointer, 2)
                        .value.voidPointerVal);
                const size_t *origin =
                    ANGLE_UNSAFE_TODO((const size_t *)mapCall->params
                                          .getParam("origin", ParamType::Tsize_tConstPointer, 4)
                                          .data.back()
                                          .data());
                const size_t *region =
                    ANGLE_UNSAFE_TODO((const size_t *)mapCall->params
                                          .getParam("region", ParamType::Tsize_tConstPointer, 5)
                                          .data.back()
                                          .data());

                size_t rowPitch = mapCall->params.getParam("image_row_pitch", ParamType::Tsize_t, 6)
                                      .value.size_tVal;
                size_t slicePitch =
                    mapCall->params.getParam("image_slice_pitch", ParamType::Tsize_t, 7)
                        .value.size_tVal;

                // Get the image size to allocate the size of ptr
                size_t totalSize = (ANGLE_UNSAFE_TODO(region[2]) - 1) * slicePitch +
                                   (ANGLE_UNSAFE_TODO(region[1]) - 1) * rowPitch +
                                   region[0] * clImg->getElementSize();
                ptr = malloc(totalSize);

                // Call clEnqueueReadBuffer to get the current data in the image
                EnqueueReadImage(mCLCurrentCommandQueue, mCLDirtyMem.at(i), true, origin, region,
                                 rowPitch, slicePitch, ptr, 0, nullptr, nullptr);

                // Inject memcpy call BEFORE unmap
                injectMemcpy(ptr,
                             calls->back()
                                 .params.getParam("mapped_ptr", ParamType::TvoidPointer, 2)
                                 .value.voidPointerVal,
                             totalSize, calls);
            }
            else
            {
                ptr              = malloc(clImg->getSize());
                size_t origin[3] = {0, 0, 0};
                size_t region[3] = {clImg->getWidth(), clImg->getHeight(), clImg->getDepth()};

                // Call clEnqueueReadBuffer to get the current data in the image
                EnqueueReadImage(mCLCurrentCommandQueue, mCLDirtyMem.at(i), true, origin, region,
                                 clImg->getRowSize(), clImg->getSliceSize(), ptr, 0, nullptr,
                                 nullptr);

                // Pretend that a "clEnqueueWriteImage" was called with the above data retrieved
                calls->push_back(CaptureEnqueueWriteImage(
                    true, mCLCurrentCommandQueue, mCLDirtyMem.at(i), true, origin, region,
                    clImg->getRowSize(), clImg->getSliceSize(), ptr, 0, nullptr, nullptr,
                    CL_SUCCESS));

                // Implicit release, so going into the starting frame the buffer has the correct
                // reference count
                mCLDirtyMem.at(i)->cast<cl::Memory>().release();
            }

            free(ptr);
        }
    }
    for (uint32_t i = 0; i < mCLDirtySVM.size(); ++i)
    {
        size_t SVMSize = mResourceTrackerCL.SVMToSize[mCLDirtySVM.at(i)];

        // Call clEnqueueSVMMap to get the current data in the SVM pointer
        cl::MemFlags flags;
        flags.set(CL_MAP_READ);
        EnqueueSVMMap(mCLCurrentCommandQueue, true, flags, mCLDirtySVM.at(i), SVMSize, 0, nullptr,
                      nullptr);

        // Pretend that a "clEnqueueSVMMemcpy" was called with the above data retrieved
        calls->push_back(CaptureEnqueueSVMMemcpy(true, mCLCurrentCommandQueue, true,
                                                 mCLDirtySVM.at(i), mCLDirtySVM.at(i), SVMSize, 0,
                                                 nullptr, nullptr, CL_SUCCESS));

        // Call clEnqueueSVMUnmap to get the current data in the SVM pointer
        EnqueueSVMUnmap(mCLCurrentCommandQueue, mResourceTrackerCL.mCLDirtySVM.at(i), 0, nullptr,
                        nullptr);
    }
    mCLDirtyMem.clear();
    mCLDirtySVM.clear();
}

void FrameCaptureShared::removeCLMemOccurrences(const cl_mem *mem, std::vector<CallCapture> *calls)
{
    // This function gets called when it captures a clReleaseMemObj prior to the starting frame
    // that sets the reference count to 0, meaning that this cl_mem object isn't necessary for
    // the wanted frames. So, we can remove the calls that use it.

    for (size_t i = 0; i < calls->size(); ++i)
    {
        CallCapture *call = &calls->at(i);
        cl_mem foundMem;
        switch (call->entryPoint)
        {
            case EntryPoint::CLCreateBuffer:
            case EntryPoint::CLCreateBufferWithProperties:
            case EntryPoint::CLCreateImage:
            case EntryPoint::CLCreateImageWithProperties:
            case EntryPoint::CLCreateImage2D:
            case EntryPoint::CLCreateImage3D:
            case EntryPoint::CLCreatePipe:
            {
                foundMem = call->params.getReturnValue().value.cl_memVal;
                break;
            }
            case EntryPoint::CLCreateSubBuffer:
            {
                foundMem = call->params.getReturnValue().value.cl_memVal;
                if (foundMem != *mem)
                {
                    foundMem =
                        call->params.getParam("buffer", ParamType::Tcl_mem, 0).value.cl_memVal;
                }
                break;
            }
            case EntryPoint::CLEnqueueReadBuffer:
            case EntryPoint::CLEnqueueWriteBuffer:
            case EntryPoint::CLEnqueueReadBufferRect:
            case EntryPoint::CLEnqueueWriteBufferRect:
            case EntryPoint::CLEnqueueMapBuffer:
            {
                // Can get rid of these calls because the buffer is no longer needed
                foundMem = call->params.getParam("buffer", ParamType::Tcl_mem, 1).value.cl_memVal;
                break;
            }
            case EntryPoint::CLEnqueueReadImage:
            case EntryPoint::CLEnqueueWriteImage:
            case EntryPoint::CLEnqueueMapImage:
            {
                // Can get rid of these calls because the image is no longer needed
                foundMem = call->params.getParam("image", ParamType::Tcl_mem, 1).value.cl_memVal;
                break;
            }
            case EntryPoint::CLEnqueueCopyBuffer:
            case EntryPoint::CLEnqueueCopyBufferRect:
            case EntryPoint::CLEnqueueCopyImage:
            case EntryPoint::CLEnqueueCopyBufferToImage:
            case EntryPoint::CLEnqueueCopyImageToBuffer:
            {
                // Can get rid of these calls because the obj is no longer needed
                std::string srcType = "src_";
                srcType += ((call->entryPoint == EntryPoint::CLEnqueueCopyImage ||
                             call->entryPoint == EntryPoint::CLEnqueueCopyImageToBuffer)
                                ? "image"
                                : "buffer");
                std::string dstType = "dst_";
                dstType += ((call->entryPoint == EntryPoint::CLEnqueueCopyImage ||
                             call->entryPoint == EntryPoint::CLEnqueueCopyBufferToImage)
                                ? "image"
                                : "buffer");
                foundMem =
                    call->params.getParam(srcType.c_str(), ParamType::Tcl_mem, 1).value.cl_memVal;
                if (foundMem != *mem)
                {
                    foundMem = call->params.getParam(dstType.c_str(), ParamType::Tcl_mem, 2)
                                   .value.cl_memVal;
                }
                break;
            }
            case EntryPoint::CLReleaseMemObject:
            case EntryPoint::CLRetainMemObject:
            case EntryPoint::CLGetMemObjectInfo:
            case EntryPoint::CLSetMemObjectDestructorCallback:
            case EntryPoint::CLEnqueueUnmapMemObject:
            {
                foundMem =
                    call->params
                        .getParam("memobj", ParamType::Tcl_mem,
                                  call->entryPoint == EntryPoint::CLEnqueueUnmapMemObject ? 1 : 0)
                        .value.cl_memVal;
                break;
            }
            case EntryPoint::CLGetImageInfo:
            {
                foundMem = call->params.getParam("image", ParamType::Tcl_mem, 0).value.cl_memVal;
                break;
            }
            case EntryPoint::CLSetKernelArg:
            {
                foundMem = call->params.getParam("arg_value", ParamType::TvoidConstPointer, 3)
                               .value.cl_memVal;
                if (cl::Platform::GetDefault()->getFrameCaptureShared()->getIndex(&foundMem) ==
                    SIZE_MAX)
                {
                    continue;
                }
                break;
            }
            // Leave commented until external memory is upstream
            // case EntryPoint::CLEnqueueAcquireExternalMemObjectsKHR:
            // case EntryPoint::CLEnqueueReleaseExternalMemObjectsKHR:
            case EntryPoint::CLEnqueueMigrateMemObjects:
            {
                const cl_mem *memObjs =
                    call->params.getParam("mem_objects", ParamType::Tcl_memConstPointer, 2)
                        .value.cl_memConstPointerVal;
                cl_uint numMemObjs =
                    call->params.getParam("num_mem_objects", ParamType::Tcl_uint, 1)
                        .value.cl_uintVal;

                std::vector<cl_mem> newMemObjs;
                for (cl_uint memObjIndex = 0; i < numMemObjs; ++i)
                {
                    if (ANGLE_UNSAFE_TODO(memObjs[memObjIndex]) != *mem)
                    {
                        newMemObjs.push_back(ANGLE_UNSAFE_TODO(memObjs[memObjIndex]));
                    }
                }

                // If all the mem objects used in this array are released, I can remove this call
                if (newMemObjs.empty())
                {
                    foundMem = *mem;
                }
                else
                {
                    call->params.setValueParamAtIndex("num_mem_objects", ParamType::Tcl_uint,
                                                      newMemObjs.size(), 1);
                    setCLObjVectorMap(
                        newMemObjs.data(), newMemObjs.size(),
                        &call->params.getParam("mem_objects", ParamType::Tcl_memConstPointer, 2),
                        &angle::FrameCaptureShared::getIndex);
                    continue;
                }
                break;
            }
            default:
                continue;
        }

        if (foundMem == *mem)
        {
            removeCLCall(calls, i);
            --i;
        }
    }
}

void FrameCaptureShared::removeCLKernelOccurrences(const cl_kernel *kernel,
                                                   std::vector<CallCapture> *calls)
{
    // This function gets called when it captures a clReleaseProgram prior to the starting frame
    // that sets the program's reference count to 0. This ensures that the kernels in that program
    // are/should be released as well, meaning that this cl_kernel object isn't necessary for
    // the wanted frames. So, we can remove the calls that use it.
    // We cannot remove cl_kernel occurrences at the time of clReleaseKernel because the kernel may
    // be an input to clCloneKernel and clCreateKernelsInProgram.

    for (size_t i = 0; i < calls->size(); ++i)
    {
        CallCapture *call = &calls->at(i);
        cl_kernel foundKernel;
        switch (call->entryPoint)
        {
            case EntryPoint::CLCreateKernel:
            {
                foundKernel = call->params.getReturnValue().value.cl_kernelVal;
                break;
            }
            case EntryPoint::CLCloneKernel:
            {
                foundKernel = call->params.getReturnValue().value.cl_kernelVal;
                if (foundKernel != *kernel)
                {
                    foundKernel = call->params.getParam("source_kernel", ParamType::Tcl_kernel, 0)
                                      .value.cl_kernelVal;
                }
                break;
            }
            case EntryPoint::CLRetainKernel:
            case EntryPoint::CLReleaseKernel:
            case EntryPoint::CLSetKernelArg:
            case EntryPoint::CLSetKernelArgSVMPointer:
            case EntryPoint::CLSetKernelExecInfo:
            case EntryPoint::CLGetKernelInfo:
            case EntryPoint::CLGetKernelArgInfo:
            case EntryPoint::CLGetKernelWorkGroupInfo:
            case EntryPoint::CLGetKernelSubGroupInfo:
            {
                foundKernel =
                    call->params.getParam("kernel", ParamType::Tcl_kernel, 0).value.cl_kernelVal;
                break;
            }
            case EntryPoint::CLEnqueueNDRangeKernel:
            case EntryPoint::CLEnqueueTask:
            {
                foundKernel =
                    call->params.getParam("kernel", ParamType::Tcl_kernel, 1).value.cl_kernelVal;
                break;
            }

            default:
                continue;
        }

        if (foundKernel == *kernel)
        {
            removeCLCall(calls, i);
            --i;
        }
    }
}

void FrameCaptureShared::removeCLProgramOccurrences(const cl_program *program,
                                                    std::vector<CallCapture> *calls)
{
    // This function gets called when it captures a clReleaseMemObj prior to the starting frame
    // that sets the reference count to 0, and the program is not linked to any other program,
    // meaning that this cl_mem object isn't necessary for the wanted frames. So, we can
    // remove the calls that use it.

    for (size_t i = 0; i < calls->size(); ++i)
    {
        CallCapture *call = &calls->at(i);
        cl_program foundProgram;
        switch (call->entryPoint)
        {
            case EntryPoint::CLCreateProgramWithSource:
            case EntryPoint::CLCreateProgramWithBinary:
            case EntryPoint::CLCreateProgramWithBuiltInKernels:
            case EntryPoint::CLCreateProgramWithIL:
            case EntryPoint::CLLinkProgram:
            {
                foundProgram = call->params.getReturnValue().value.cl_programVal;
                break;
            }
            case EntryPoint::CLRetainProgram:
            case EntryPoint::CLReleaseProgram:
            case EntryPoint::CLBuildProgram:
            case EntryPoint::CLGetProgramInfo:
            case EntryPoint::CLGetProgramBuildInfo:
            case EntryPoint::CLCreateKernel:
            case EntryPoint::CLCreateKernelsInProgram:
            case EntryPoint::CLUnloadPlatformCompiler:
            case EntryPoint::CLCompileProgram:
            {
                uint8_t programIndex = call->entryPoint == EntryPoint::CLCompileProgram ? 1 : 0;
                foundProgram =
                    call->params.getParam("program", ParamType::Tcl_program, programIndex)
                        .value.cl_programVal;
                break;
            }
            default:
                continue;
        }

        if (foundProgram == *program)
        {
            removeCLCall(calls, i);
            --i;
        }
    }

    if (mResourceTrackerCL.mCLProgramToKernels.find(*program) !=
        mResourceTrackerCL.mCLProgramToKernels.end())
    {
        for (size_t i = 0; i < mResourceTrackerCL.mCLProgramToKernels[*program].size(); ++i)
        {
            removeCLKernelOccurrences(&mResourceTrackerCL.mCLProgramToKernels[*program].at(i),
                                      calls);
        }
        mResourceTrackerCL.mCLProgramToKernels.erase(*program);
    }
}

void FrameCaptureShared::removeCLCall(std::vector<CallCapture> *callVector, size_t &callIndex)
{
    CallCapture *call                       = &callVector->at(callIndex);
    const std::vector<ParamCapture> *params = &call->params.getParamCaptures();
    cl_context context                      = nullptr;

    // Checks if there is an event that is implicitly created during the deleted call.
    // If there is, need to inject a clCreateUserEvent call and a clSetUserEventStatus call.
    for (auto &param : *params)
    {
        if (param.type == ParamType::Tcl_context)
        {
            context = param.value.cl_contextVal;
        }
        else if (param.type == ParamType::Tcl_command_queue)
        {
            context =
                param.value.cl_command_queueVal->cast<cl::CommandQueue>().getContext().getNative();
        }
        else if (param.type == ParamType::Tcl_eventPointer && param.value.cl_eventVal != nullptr &&
                 context)
        {
            // Capture the creation of a successful event if the CL call being removed created an
            // event (ex: clEnqueueReadBuffer)
            cl_event event = param.value.cl_eventVal;
            callVector->insert(callVector->begin() + callIndex,
                               CaptureSetUserEventStatus(true, event, CL_COMPLETE, CL_SUCCESS));
            callVector->insert(callVector->begin() + callIndex,
                               CaptureCreateUserEvent(true, context, nullptr, event));
            callIndex += 2;
            break;
        }
    }
    callVector->erase(callVector->begin() + callIndex);
}

void FrameCaptureShared::maybeCapturePreCallUpdatesCL(CallCapture &call)
{
    switch (call.entryPoint)
    {
        case EntryPoint::CLGetExtensionFunctionAddress:
        case EntryPoint::CLGetExtensionFunctionAddressForPlatform:
        {
            uint32_t index = call.entryPoint == EntryPoint::CLGetExtensionFunctionAddress ? 0 : 1;
            std::string funcName =
                (const char *)call.params.getParam("func_name", ParamType::TcharConstPointer, index)
                    .value.charConstPointerPointerVal;
            call.customFunctionName =
                funcName + " = (" + funcName + "_fn)" + GetEntryPointName(call.entryPoint);

            if (std::find(mExtFuncsAdded.begin(), mExtFuncsAdded.end(), funcName) ==
                mExtFuncsAdded.end())
            {
                mExtFuncsAdded.push_back(funcName);
            }
            break;
        }
        case EntryPoint::CLCreateContext:
        case EntryPoint::CLCreateContextFromType:
        {
            if (call.params.getParam("properties", ParamType::Tcl_context_propertiesConstPointer, 0)
                    .value.cl_context_propertiesConstPointerVal)
            {
                size_t propSize        = 0;
                size_t platformIDIndex = 0;
                const cl_context_properties *propertiesData =
                    ANGLE_UNSAFE_TODO((cl_context_properties *)call.params)
                        .getParam("properties", ParamType::Tcl_context_propertiesConstPointer, 0)
                        .data[0]
                        .data();
                while (ANGLE_UNSAFE_TODO(propertiesData[propSize]) != 0)
                {
                    if (ANGLE_UNSAFE_TODO(propertiesData[propSize]) == CL_CONTEXT_PLATFORM)
                    {
                        // "Each property name is immediately followed by the corresponding desired
                        // value"
                        platformIDIndex = propSize + 1;
                    }
                    ++propSize;
                }
                ++propSize;

                if (platformIDIndex == 0)
                {
                    ParamBuffer params;

                    params.addValueParam("propSize", ParamType::Tsize_t, propSize);

                    ParamCapture propertiesParam("propData",
                                                 ParamType::Tcl_context_propertiesConstPointer);
                    InitParamValue(ParamType::Tcl_context_propertiesConstPointer, propertiesData,
                                   &propertiesParam.value);
                    CaptureMemory(propertiesData, propSize * sizeof(cl_context_properties),
                                  &propertiesParam);
                    params.addParam(std::move(propertiesParam));
                    mFrameCalls.emplace_back(
                        CallCapture("UpdateCLContextPropertiesNoPlatform", std::move(params)));

                    call.params
                        .getParam("properties", ParamType::Tcl_context_propertiesConstPointer, 0)
                        .data.clear();
                    break;
                }

                // Create call to UpdateCLContextProperties
                ParamBuffer params;

                params.addValueParam("propSize", ParamType::Tsize_t, propSize);

                ParamCapture propertiesParam("propData",
                                             ParamType::Tcl_context_propertiesConstPointer);
                InitParamValue(ParamType::Tcl_context_propertiesConstPointer, propertiesData,
                               &propertiesParam.value);
                CaptureMemory(propertiesData, propSize * sizeof(cl_context_properties),
                              &propertiesParam);
                params.addParam(std::move(propertiesParam));

                params.addValueParam("platformIdxInProps", ParamType::Tsize_t, platformIDIndex);
                params.addValueParam("platformIdxInMap", ParamType::Tsize_t,
                                     getIndex((cl_platform_id *)&ANGLE_UNSAFE_TODO(
                                         propertiesData[platformIDIndex])));

                call.params.getParam("properties", ParamType::Tcl_context_propertiesConstPointer, 0)
                    .data.clear();

                mFrameCalls.emplace_back(
                    CallCapture("UpdateCLContextPropertiesWithPlatform", std::move(params)));
            }
            break;
        }
        default:
            break;
    }

    updateReadBufferSize(call.params.getReadBufferSize());
}

void FrameCaptureShared::addCLResetObj(const ParamCapture &param)
{
    mResourceTrackerCL.mCLResetObjs.push_back(angle::ParamCapture("resetObj", param.type));
    auto paramValue =
        &mResourceTrackerCL.mCLResetObjs.at(mResourceTrackerCL.mCLResetObjs.size() - 1).value;
    switch (param.type)
    {
        case ParamType::Tcl_device_id:
            InitParamValue(param.type, param.value.cl_device_idVal, paramValue);
            break;
        case ParamType::Tcl_mem:
            InitParamValue(param.type, param.value.cl_memVal, paramValue);
            break;
        case ParamType::Tcl_kernel:
            InitParamValue(param.type, param.value.cl_kernelVal, paramValue);
            break;
        case ParamType::Tcl_program:
            InitParamValue(param.type, param.value.cl_programVal, paramValue);
            break;
        case ParamType::Tcl_command_queue:
            InitParamValue(param.type, param.value.cl_command_queueVal, paramValue);
            break;
        case ParamType::Tcl_context:
            InitParamValue(param.type, param.value.cl_contextVal, paramValue);
            break;
        case ParamType::Tcl_sampler:
            InitParamValue(param.type, param.value.cl_samplerVal, paramValue);
            break;
        case ParamType::Tcl_event:
            InitParamValue(param.type, param.value.cl_eventVal, paramValue);
            break;
        default:
            break;
    }
}

void FrameCaptureShared::removeCLResetObj(const ParamCapture &param)
{
    std::vector<ParamCapture> &mCLResetObjs = mResourceTrackerCL.mCLResetObjs;
    for (size_t i = 0; i < mCLResetObjs.size(); ++i)
    {
        bool foundCLObj =
            param.type == mCLResetObjs.at(i).type &&
            ((param.type == ParamType::Tcl_device_id &&
              param.value.cl_device_idVal == mCLResetObjs.at(i).value.cl_device_idVal) ||
             (param.type == ParamType::Tcl_mem &&
              param.value.cl_memVal == mCLResetObjs.at(i).value.cl_memVal) ||
             (param.type == ParamType::Tcl_kernel &&
              param.value.cl_kernelVal == mCLResetObjs.at(i).value.cl_kernelVal) ||
             (param.type == ParamType::Tcl_program &&
              param.value.cl_programVal == mCLResetObjs.at(i).value.cl_programVal) ||
             (param.type == ParamType::Tcl_command_queue &&
              param.value.cl_command_queueVal == mCLResetObjs.at(i).value.cl_command_queueVal) ||
             (param.type == ParamType::Tcl_context &&
              param.value.cl_contextVal == mCLResetObjs.at(i).value.cl_contextVal) ||
             (param.type == ParamType::Tcl_sampler &&
              param.value.cl_samplerVal == mCLResetObjs.at(i).value.cl_samplerVal) ||
             (param.type == ParamType::Tcl_event &&
              param.value.cl_eventVal == mCLResetObjs.at(i).value.cl_eventVal));

        if (foundCLObj)
        {
            mCLResetObjs.erase(mCLResetObjs.begin() + i);
            break;
        }
    }
}

void FrameCaptureShared::printCLResetObjs(std::stringstream &stream)
{
    std::vector<ParamCapture> &mCLResetObjs = mResourceTrackerCL.mCLResetObjs;
    for (size_t i = 0; i < mCLResetObjs.size(); ++i)
    {
        stream << "    ";
        switch (mCLResetObjs.at(i).type)
        {
            case ParamType::Tcl_device_id:
                stream << "clReleaseDevice(clDevicesMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_device_idVal))
                       << "]);";
                break;
            case ParamType::Tcl_mem:
                stream << "clReleaseMemObject(clMemMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_memVal)) << "]);";
                break;
            case ParamType::Tcl_kernel:
                stream << "clReleaseKernel(clKernelsMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_kernelVal)) << "]);";
                break;
            case ParamType::Tcl_program:
                stream << "clReleaseProgram(clProgramsMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_programVal))
                       << "]);";
                break;
            case ParamType::Tcl_command_queue:
                stream << "clReleaseCommandQueue(clCommandQueuesMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_command_queueVal))
                       << "]);";
                break;
            case ParamType::Tcl_context:
                stream << "clReleaseContext(clContextsMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_contextVal))
                       << "]);";
                break;
            case ParamType::Tcl_sampler:
                stream << "clReleaseSampler(clSamplersMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_samplerVal))
                       << "]);";
                break;
            case ParamType::Tcl_event:
                stream << "clReleaseEvent(clEventsMap["
                       << std::to_string(getIndex(&mCLResetObjs.at(i).value.cl_eventVal)) << "]);";
                break;
            default:
                break;
        }
        stream << "\n";
    }
}

void FrameCaptureShared::updateResourceCountsFromParamCaptureCL(const ParamCapture &param,
                                                                const CallCapture &call)
{
    switch (param.type)
    {
        case ParamType::Tcl_platform_idPointer:
            if (call.entryPoint == EntryPoint::CLIcdGetPlatformIDsKHR ||
                call.entryPoint == EntryPoint::CLGetPlatformIDs)
            {
                mMaxCLParamsSize[param.type] +=
                    sizeof(cl_platform_id) * ((call.params.getParamCaptures()[0]).value.cl_uintVal);
            }
            break;
        case ParamType::Tcl_device_idPointer:
            if (call.entryPoint == EntryPoint::CLGetDeviceIDs)
            {
                mMaxCLParamsSize[param.type] +=
                    sizeof(cl_device_id) * ((call.params.getParamCaptures()[2]).value.cl_uintVal);
            }
            break;
        case ParamType::Tcl_context:
            if (call.entryPoint == EntryPoint::CLCreateContext ||
                call.entryPoint == EntryPoint::CLCreateContextFromType)
            {
                if ((getIndex(&param.value.cl_contextVal) + 1) * sizeof(cl_context) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_contextVal) + 1) * sizeof(cl_context));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::Tcl_command_queue:
            if (call.entryPoint == EntryPoint::CLCreateCommandQueueWithProperties ||
                call.entryPoint == EntryPoint::CLCreateCommandQueue)
            {
                if ((getIndex(&param.value.cl_command_queueVal) + 1) * sizeof(cl_command_queue) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_command_queueVal) + 1) *
                                   sizeof(cl_command_queue));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::Tcl_mem:
            if (call.entryPoint == EntryPoint::CLCreateBufferWithProperties ||
                call.entryPoint == EntryPoint::CLCreateBuffer ||
                call.entryPoint == EntryPoint::CLCreateSubBuffer ||
                call.entryPoint == EntryPoint::CLCreateImageWithProperties ||
                call.entryPoint == EntryPoint::CLCreateImage ||
                call.entryPoint == EntryPoint::CLCreateImage2D ||
                call.entryPoint == EntryPoint::CLCreateImage3D)
            {
                if ((getIndex(&param.value.cl_memVal) + 1) * sizeof(cl_mem) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_memVal) + 1) * sizeof(cl_mem));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::Tcl_eventPointer:
        {
            if (param.value.cl_eventVal)
            {
                if ((getIndex(&param.value.cl_eventVal) + 1) * sizeof(cl_event) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_eventVal) + 1) * sizeof(cl_event));
                }
                angle::ParamCapture eventParam("event", angle::ParamType::Tcl_event);
                InitParamValue(angle::ParamType::Tcl_event, param.value.cl_eventVal,
                               &eventParam.value);
                addCLResetObj(eventParam);
            }
            break;
        }
        case ParamType::Tcl_program:
            if (call.entryPoint == EntryPoint::CLCreateProgramWithSource ||
                call.entryPoint == EntryPoint::CLCreateProgramWithBinary ||
                call.entryPoint == EntryPoint::CLCreateProgramWithBuiltInKernels ||
                call.entryPoint == EntryPoint::CLLinkProgram ||
                call.entryPoint == EntryPoint::CLCreateProgramWithIL)
            {
                if ((getIndex(&param.value.cl_programVal) + 1) * sizeof(cl_program) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_programVal) + 1) * sizeof(cl_program));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::Tcl_kernel:
            if (call.entryPoint == EntryPoint::CLCreateKernel ||
                call.entryPoint == EntryPoint::CLCloneKernel)
            {
                if ((getIndex(&param.value.cl_kernelVal) + 1) * sizeof(cl_kernel) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_kernelVal) + 1) * sizeof(cl_kernel));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::Tcl_sampler:
            if (call.entryPoint == EntryPoint::CLCreateSampler ||
                call.entryPoint == EntryPoint::CLCreateSamplerWithProperties)
            {
                if ((getIndex(&param.value.cl_samplerVal) + 1) * sizeof(cl_sampler) >
                    mMaxCLParamsSize[param.type])
                {
                    mMaxCLParamsSize[param.type] =
                        (uint32_t)((getIndex(&param.value.cl_samplerVal) + 1) * sizeof(cl_sampler));
                }
                addCLResetObj(param);
            }
            break;
        case ParamType::TvoidPointer:
            if (call.entryPoint == EntryPoint::CLEnqueueMapImage ||
                call.entryPoint == EntryPoint::CLEnqueueMapBuffer)
            {
                mMaxCLParamsSize[param.type] += sizeof(void *);
            }
            break;
        default:
            break;
    }
}

void FrameCaptureShared::updateResourceCountsFromCallCaptureCL(const CallCapture &call)
{
    for (const ParamCapture &param : call.params.getParamCaptures())
    {
        updateResourceCountsFromParamCaptureCL(param, call);
    }

    // Update resource IDs in the return value.
    switch (call.entryPoint)
    {
        case EntryPoint::CLCreateContext:
        case EntryPoint::CLCreateContextFromType:
            setIndex(&call.params.getReturnValue().value.cl_contextVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLCreateBuffer:
        case EntryPoint::CLCreateBufferWithProperties:
        case EntryPoint::CLCreateSubBuffer:
        case EntryPoint::CLCreateImageWithProperties:
        case EntryPoint::CLCreateImage:
        case EntryPoint::CLCreateImage2D:
        case EntryPoint::CLCreateImage3D:
        case EntryPoint::CLCreatePipe:
            setIndex(&call.params.getReturnValue().value.cl_memVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLCreateSampler:
        case EntryPoint::CLCreateSamplerWithProperties:
            setIndex(&call.params.getReturnValue().value.cl_samplerVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLCreateCommandQueue:
        case EntryPoint::CLCreateCommandQueueWithProperties:
            setIndex(&call.params.getReturnValue().value.cl_command_queueVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLCreateProgramWithSource:
        case EntryPoint::CLCreateProgramWithBinary:
        case EntryPoint::CLCreateProgramWithBuiltInKernels:
        case EntryPoint::CLLinkProgram:
        case EntryPoint::CLCreateProgramWithIL:
            setIndex(&call.params.getReturnValue().value.cl_programVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLCreateKernel:
        case EntryPoint::CLCloneKernel:
            setIndex(&call.params.getReturnValue().value.cl_kernelVal);
            updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            break;
        case EntryPoint::CLEnqueueMapBuffer:
        case EntryPoint::CLEnqueueMapImage:
        case EntryPoint::CLSVMAlloc:
            if (call.params.getReturnValue().value.voidPointerVal)
            {
                setCLVoidIndex(call.params.getReturnValue().value.voidPointerVal);
                updateResourceCountsFromParamCaptureCL(call.params.getReturnValue(), call);
            }
            break;
        case EntryPoint::CLCreateUserEvent:
            setIndex(&call.params.getReturnValue().value.cl_eventVal);
            break;
        case EntryPoint::CLReleaseDevice:
        case EntryPoint::CLReleaseCommandQueue:
        case EntryPoint::CLReleaseContext:
        case EntryPoint::CLReleaseEvent:
        case EntryPoint::CLReleaseKernel:
        case EntryPoint::CLReleaseMemObject:
        case EntryPoint::CLReleaseProgram:
        case EntryPoint::CLReleaseSampler:
            removeCLResetObj(call.params.getParamCaptures()[0]);
            break;
        default:
            break;
    }
}

void FrameCaptureShared::captureCLCall(CallCapture &&inCall, bool isCallValid)
{
    if (!mCallCaptured)
    {
        mReplayWriter.captureAPI = CaptureAPI::CL;
        mBinaryData.clear();
        mCallCaptured = true;
        std::atexit(onCLProgramEnd);
    }

    if (checkForCaptureEnd())
    {
        onEndCLCapture();
        mCaptureEndFrame = 0;
        return;
    }

    if (mFrameIndex <= mCaptureEndFrame)
    {
        if ((mFrameIndex == mCaptureStartFrame - 1) ||
            ((mFrameIndex == 1) && (mCaptureStartFrame == 1)))
        {
            std::string fileName = GetBinaryDataFilePath(mCompression, mCaptureLabel);
            mBinaryData.initializeBinaryDataStore(mCompression, mOutDirectory, fileName);
        }

        // Keep track of return values from OpenCL calls
        updateResourceCountsFromCallCaptureCL(inCall);

        // Set to true if the call signifies the end of a frame
        // ex: clEnqueueNDRangeKernel
        bool frameEnd = false;

        // Covers pre call updates, like updating the read buffer size
        maybeCapturePreCallUpdatesCL(inCall);

        // If it's an unnecessary call for replay (ex: clGetDeviceInfo)
        if (mCLOptionalCalls.find(inCall.entryPoint) == mCLOptionalCalls.end())
        {
            if (mCLEndFrameCalls.find(inCall.entryPoint) != mCLEndFrameCalls.end())
            {
                frameEnd = true;
            }

            mFrameCalls.emplace_back(std::move(inCall));
        }
        else
        {
            saveCLGetInfo(inCall);
            return;
        }

        // For kernel argument memory snapshots
        maybeCapturePostCallUpdatesCL();
        if (mFrameIndex >= mCaptureStartFrame ||
            (mFrameIndex + 1 == mCaptureStartFrame && frameEnd))
        {
            // Maybe add clEnqueueWrite* or memcpy for memory snapshots
            captureUpdateCLObjs(&mFrameCalls);
        }

        if (frameEnd && mFrameIndex >= mCaptureStartFrame)
        {
            mActiveFrameIndices.push_back(mFrameIndex);
            writeMainContextCppReplayCL();
            if (mFrameIndex == mCaptureEndFrame)
            {
                writeCppReplayIndexFilesCL();
            }
            reset();
        }

        if (frameEnd)
        {
            if (mFrameIndex == (mCaptureStartFrame == 0 ? 0 : mCaptureStartFrame - 1))
            {
                mCLSetupCalls = std::move(mFrameCalls);
            }
            ++mFrameIndex;
        }
    }
}

void FrameCaptureShared::maybeCapturePostCallUpdatesCL()
{
    CallCapture &lastCall = mFrameCalls.back();
    switch (lastCall.entryPoint)
    {
        case EntryPoint::CLEnqueueMapBuffer:
        {
            // Recreate the map call to store in the mCLMapCall unordered_map
            // so later upon the unmap call, the original map data will be available
            cl_command_queue command_queue =
                lastCall.params.getParam("command_queue", ParamType::Tcl_command_queue, 0)
                    .value.cl_command_queueVal;
            cl_mem buffer =
                lastCall.params.getParam("buffer", ParamType::Tcl_mem, 1).value.cl_memVal;
            cl_bool blocking_map =
                lastCall.params.getParam("blocking_map", ParamType::Tcl_bool, 2).value.cl_boolVal;
            cl::MapFlags map_flags =
                lastCall.params.getParam("map_flagsPacked", ParamType::TMapFlags, 3)
                    .value.MapFlagsVal;
            size_t offset =
                lastCall.params.getParam("offset", ParamType::Tsize_t, 4).value.size_tVal;
            size_t size = lastCall.params.getParam("size", ParamType::Tsize_t, 5).value.size_tVal;

            mResourceTrackerCL.mCLMapCall.emplace(
                lastCall.params.getReturnValue().value.voidPointerVal,
                CaptureEnqueueMapBuffer(true, command_queue, buffer, blocking_map, map_flags,
                                        offset, size, 0, nullptr, nullptr, nullptr, nullptr));
            break;
        }
        case EntryPoint::CLEnqueueMapImage:
        {
            // Recreate the map call to store in the mCLMapCall unordered_map
            // so later upon the unmap call, the original map data will be available
            cl_command_queue command_queue =
                lastCall.params.getParam("command_queue", ParamType::Tcl_command_queue, 0)
                    .value.cl_command_queueVal;
            cl_mem image = lastCall.params.getParam("image", ParamType::Tcl_mem, 1).value.cl_memVal;
            cl_bool blocking_map =
                lastCall.params.getParam("blocking_map", ParamType::Tcl_bool, 2).value.cl_boolVal;
            cl::MapFlags map_flags =
                lastCall.params.getParam("map_flagsPacked", ParamType::TMapFlags, 3)
                    .value.MapFlagsVal;
            const size_t *origin =
                lastCall.params.getParam("origin", ParamType::Tsize_tConstPointer, 4)
                    .value.size_tConstPointerVal;
            const size_t *region =
                lastCall.params.getParam("region", ParamType::Tsize_tConstPointer, 5)
                    .value.size_tConstPointerVal;
            size_t *image_row_pitch =
                lastCall.params.getParam("image_row_pitch", ParamType::Tsize_tPointer, 6)
                    .value.size_tPointerVal;
            size_t *image_slice_pitch =
                lastCall.params.getParam("image_slice_pitch", ParamType::Tsize_tPointer, 7)
                    .value.size_tPointerVal;

            mResourceTrackerCL.mCLMapCall.emplace(
                lastCall.params.getReturnValue().value.voidPointerVal,
                CaptureEnqueueMapImage(true, command_queue, image, blocking_map, map_flags, origin,
                                       region, image_row_pitch, image_slice_pitch, 0, nullptr,
                                       nullptr, nullptr, nullptr));
            mResourceTrackerCL.mCLMapCall.at(lastCall.params.getReturnValue().value.voidPointerVal)
                .params.setValueParamAtIndex("image_row_pitch", ParamType::Tsize_t,
                                             *image_row_pitch, 6);
            mResourceTrackerCL.mCLMapCall.at(lastCall.params.getReturnValue().value.voidPointerVal)
                .params.setValueParamAtIndex("image_slice_pitch", ParamType::Tsize_t,
                                             image_slice_pitch == nullptr ? 0 : *image_slice_pitch,
                                             7);
            break;
        }
        case EntryPoint::CLEnqueueUnmapMemObject:
        {
            if (mFrameIndex >= mCaptureStartFrame)
            {
                // Mark as dirty
                cl_mem *mem =
                    &lastCall.params.getParam("memobj", ParamType::Tcl_mem, 1).value.cl_memVal;
                mResourceTrackerCL.mCLCurrentCommandQueue =
                    lastCall.params.getParam("command_queue", ParamType::Tcl_command_queue, 0)
                        .value.cl_command_queueVal;
                CallCapture *mapCall = &mResourceTrackerCL.mCLMapCall.at(
                    lastCall.params.getParam("mapped_ptr", ParamType::TvoidPointer, 2)
                        .value.voidPointerVal);
                auto it = std::find(mResourceTrackerCL.mCLDirtyMem.begin(),
                                    mResourceTrackerCL.mCLDirtyMem.end(), *mem);
                if (it == mResourceTrackerCL.mCLDirtyMem.end() &&
                    mapCall->params.getParam("map_flagsPacked", ParamType::TMapFlags, 3)
                            .value.MapFlagsVal.mask(CL_MAP_WRITE |
                                                    CL_MAP_WRITE_INVALIDATE_REGION) != 0u)
                {
                    mResourceTrackerCL.mCLDirtyMem.push_back(*mem);
                }
            }
            break;
        }
        case EntryPoint::CLEnqueueSVMUnmap:
        {
            // Mark as dirty
            void *svm = &lastCall.params.getParam("svm_ptr", ParamType::TvoidPointer, 1)
                             .value.voidPointerVal;
            mResourceTrackerCL.mCLCurrentCommandQueue =
                lastCall.params.getParam("command_queue", ParamType::Tcl_command_queue, 0)
                    .value.cl_command_queueVal;
            mResourceTrackerCL.mCLDirtySVM.push_back(svm);
            break;
        }
        default:
            break;
    }

    // OpenCL calls that come before the starting frame
    if (mFrameIndex < mCaptureStartFrame)
    {
        std::unordered_map<cl_program, std::vector<cl_kernel>> &mCLProgramToKernels =
            mResourceTrackerCL.mCLProgramToKernels;
        switch (lastCall.entryPoint)
        {
            // There should be no unnecessary enqueue functions prior to the starting frame.
            // captureUpdateCLObjs accounts for it by dynamically adding
            // CLEnqueueWriteBuffer/CLEnqueueWriteImage to ensure the cl_mem objects
            // have the needed info upon replay
            case EntryPoint::CLEnqueueNDRangeKernel:
            case EntryPoint::CLEnqueueNativeKernel:
            case EntryPoint::CLEnqueueTask:
            case EntryPoint::CLEnqueueReadBuffer:
            case EntryPoint::CLEnqueueWriteBuffer:
            case EntryPoint::CLEnqueueReadBufferRect:
            case EntryPoint::CLEnqueueWriteBufferRect:
            case EntryPoint::CLEnqueueReadImage:
            case EntryPoint::CLEnqueueWriteImage:
            case EntryPoint::CLEnqueueCopyBuffer:
            case EntryPoint::CLEnqueueCopyBufferRect:
            case EntryPoint::CLEnqueueCopyImage:
            case EntryPoint::CLEnqueueCopyBufferToImage:
            case EntryPoint::CLEnqueueCopyImageToBuffer:
            case EntryPoint::CLEnqueueFillBuffer:
            case EntryPoint::CLEnqueueFillImage:
            case EntryPoint::CLEnqueueWaitForEvents:
            case EntryPoint::CLEnqueueMarkerWithWaitList:
            case EntryPoint::CLEnqueueBarrierWithWaitList:
            case EntryPoint::CLEnqueueBarrier:
            case EntryPoint::CLEnqueueMarker:
            case EntryPoint::CLEnqueueMigrateMemObjects:
            case EntryPoint::CLEnqueueSVMMemcpy:
            case EntryPoint::CLEnqueueSVMMemFill:
            case EntryPoint::CLEnqueueSVMMigrateMem:
            {
                size_t index = mFrameCalls.size() - 1;
                removeCLCall(&mFrameCalls, index);
                break;
            }
            case EntryPoint::CLCreateBuffer:
            case EntryPoint::CLCreateBufferWithProperties:
            case EntryPoint::CLCreateImage:
            case EntryPoint::CLCreateImageWithProperties:
            case EntryPoint::CLCreateImage2D:
            case EntryPoint::CLCreateImage3D:
            case EntryPoint::CLCreatePipe:
            case EntryPoint::CLCreateSubBuffer:
            {
                const cl_mem *newBuff = &lastCall.params.getReturnValue().value.cl_memVal;

                // Set the parent
                if (lastCall.entryPoint == EntryPoint::CLCreateSubBuffer)
                {
                    cl_mem parent =
                        lastCall.params.getParam("buffer", ParamType::Tcl_mem, 0).value.cl_memVal;
                    mResourceTrackerCL.mCLSubBufferToParent[*newBuff] = parent;
                }

                // Implicit retain
                (*newBuff)->cast<cl::Memory>().retain();

                // Add buffer as tracked
                trackCLMemUpdate(newBuff, true);
                break;
            }
            case EntryPoint::CLReleaseMemObject:
            {
                // Potentially remove buffer/image (and potentially parents) as tracked
                trackCLMemUpdate(
                    &lastCall.params.getParam("memobj", ParamType::Tcl_mem, 0).value.cl_memVal,
                    false);
                break;
            }
            case EntryPoint::CLCreateCommandQueue:
            case EntryPoint::CLCreateCommandQueueWithProperties:
            {
                mResourceTrackerCL.mCLCurrentCommandQueue =
                    lastCall.params.getReturnValue().value.cl_command_queueVal;
                break;
            }
            case EntryPoint::CLCreateProgramWithSource:
            case EntryPoint::CLCreateProgramWithBinary:
            case EntryPoint::CLCreateProgramWithBuiltInKernels:
            case EntryPoint::CLCreateProgramWithIL:
            {
                mCLProgramToKernels[lastCall.params.getReturnValue().value.cl_programVal] =
                    std::vector<cl_kernel>();
                trackCLProgramUpdate(&lastCall.params.getReturnValue().value.cl_programVal, true, 0,
                                     nullptr);
                break;
            }
            case EntryPoint::CLRetainProgram:
            {
                trackCLProgramUpdate(&lastCall.params.getParam("program", ParamType::Tcl_program, 0)
                                          .value.cl_programVal,
                                     true, 0, nullptr);
                break;
            }
            case EntryPoint::CLCompileProgram:
            {
                const cl_program *program =
                    &lastCall.params.getParam("program", ParamType::Tcl_program, 0)
                         .value.cl_programVal;
                trackCLProgramUpdate(
                    program, true,
                    lastCall.params.getParam("num_input_headers", ParamType::Tcl_uint, 4)
                        .value.cl_uintVal,
                    lastCall.params.getParam("input_headers", ParamType::Tcl_programConstPointer, 5)
                        .value.cl_programConstPointerVal);
                break;
            }
            case EntryPoint::CLLinkProgram:
            {
                const cl_program *program = &lastCall.params.getReturnValue().value.cl_programVal;
                mCLProgramToKernels[*program] = std::vector<cl_kernel>();
                trackCLProgramUpdate(
                    program, true,
                    lastCall.params.getParam("num_input_programs", ParamType::Tcl_uint, 4)
                        .value.cl_uintVal,
                    lastCall.params
                        .getParam("input_programs", ParamType::Tcl_programConstPointer, 5)
                        .value.cl_programConstPointerVal);
                break;
            }
            case EntryPoint::CLReleaseProgram:
            {
                trackCLProgramUpdate(&lastCall.params.getParam("program", ParamType::Tcl_program, 0)
                                          .value.cl_programVal,
                                     false, 0, nullptr);
                break;
            }
            case EntryPoint::CLCreateKernel:
            {
                cl_program *program =
                    &lastCall.params.getParam("program", ParamType::Tcl_program, 0)
                         .value.cl_programVal;
                const cl_kernel *kernel = &lastCall.params.getReturnValue().value.cl_kernelVal;
                mCLProgramToKernels[*program].push_back(*kernel);
                mResourceTrackerCL.mCLKernelToProgram[*kernel] = *program;
                break;
            }
            case EntryPoint::CLCloneKernel:
            {
                cl_program *program =
                    &mResourceTrackerCL.mCLKernelToProgram[lastCall.params
                                                               .getParam("source_kernel",
                                                                         ParamType::Tcl_kernel, 0)
                                                               .value.cl_kernelVal];
                const cl_kernel *kernel = &lastCall.params.getReturnValue().value.cl_kernelVal;
                mCLProgramToKernels[*program].push_back(*kernel);
                mResourceTrackerCL.mCLKernelToProgram[*kernel] = *program;
                break;
            }
            case EntryPoint::CLSVMAlloc:
            {
                void *svm = lastCall.params.getReturnValue().value.voidPointerVal;

                // Potentially mark as dirty
                auto it = std::find(mResourceTrackerCL.mCLDirtySVM.begin(),
                                    mResourceTrackerCL.mCLDirtySVM.end(), svm);
                if (it == mResourceTrackerCL.mCLDirtySVM.end())
                {
                    mResourceTrackerCL.mCLDirtySVM.push_back(svm);
                }
                break;
            }
            case EntryPoint::CLSVMFree:
            {
                void *svm = lastCall.params.getParam("svm_pointer", ParamType::TvoidPointer, 1)
                                .value.voidPointerVal;
                auto it = std::find(mResourceTrackerCL.mCLDirtySVM.begin(),
                                    mResourceTrackerCL.mCLDirtySVM.end(), svm);
                if (it != mResourceTrackerCL.mCLDirtySVM.end())
                {
                    mResourceTrackerCL.mCLDirtySVM.erase(it);
                }
                break;
            }
            case EntryPoint::CLEnqueueSVMFree:
            {
                for (cl_uint svmIndex = 0;
                     svmIndex < lastCall.params.getParam("num_svm_pointers", ParamType::Tcl_uint, 1)
                                    .value.cl_uintVal;
                     ++svmIndex)
                {
                    void *svm =
                        ANGLE_UNSAFE_TODO(lastCall.params.getParam(
                                              "svm_pointers", ParamType::TvoidPointerPointer, 1))
                            .value.voidPointerPointerVal[svmIndex];
                    auto it = std::find(mResourceTrackerCL.mCLDirtySVM.begin(),
                                        mResourceTrackerCL.mCLDirtySVM.end(), svm);
                    if (it != mResourceTrackerCL.mCLDirtySVM.end())
                    {
                        mResourceTrackerCL.mCLDirtySVM.erase(it);
                    }
                }
                break;
            }
            default:
                break;
        }
    }
}

void FrameCaptureShared::onCLProgramEnd()
{
    if (cl::Platform::GetDefault()->getFrameCaptureShared()->onEndCLCapture())
    {
        delete cl::Platform::GetDefault()->getFrameCaptureShared();
    }
}

bool FrameCaptureShared::onEndCLCapture()
{
    if (mFrameIndex >= mCaptureStartFrame && mFrameIndex <= mCaptureEndFrame)
    {
        mActiveFrameIndices.push_back(mFrameIndex);
        mCaptureEndFrame = mFrameIndex;
        writeMainContextCppReplayCL();
        writeCppReplayIndexFilesCL();
        return true;
    }
    return false;
}

ResourceTrackerCL::ResourceTrackerCL() = default;

ResourceTrackerCL::~ResourceTrackerCL() = default;

void FrameCaptureShared::setCLPlatformIndices(cl_platform_id *platforms, size_t numPlatforms)
{
    for (uint32_t i = 0; i < numPlatforms; ++i)
    {
        setIndex(&ANGLE_UNSAFE_TODO(platforms[i]));
    }
}

void FrameCaptureShared::setCLDeviceIndices(cl_device_id *devices, size_t numDevices)
{
    for (uint32_t i = 0; i < numDevices; ++i)
    {
        setIndex(&ANGLE_UNSAFE_TODO(devices[i]));
    }
}

size_t FrameCaptureShared::getCLVoidIndex(const void *v)
{
    if (mResourceTrackerCL.mCLVoidIndices.find(v) == mResourceTrackerCL.mCLVoidIndices.end())
    {
        return SIZE_MAX;
    }
    return mResourceTrackerCL.mCLVoidIndices[v];
}

void FrameCaptureShared::setCLVoidIndex(const void *v)
{
    if (mResourceTrackerCL.mCLVoidIndices.find(v) == mResourceTrackerCL.mCLVoidIndices.end())
    {
        size_t tempSize                      = mResourceTrackerCL.mCLVoidIndices.size();
        mResourceTrackerCL.mCLVoidIndices[v] = tempSize;
    }
}

void FrameCaptureShared::setCLVoidVectorIndex(const void *pointers[],
                                              size_t numPointers,
                                              const angle::ParamCapture *paramCaptureKey)
{
    mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID] = std::vector<size_t>();
    for (size_t i = 0; i < numPointers; ++i)
    {
        mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID].push_back(
            getCLVoidIndex(ANGLE_UNSAFE_TODO(pointers[i])));
    }
}

void FrameCaptureShared::setOffsetsVector(const void *args,
                                          const void **argsLocations,
                                          size_t numLocations,
                                          const angle::ParamCapture *paramCaptureKey)
{
    mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID] = std::vector<size_t>();
    for (size_t i = 0; i < numLocations; ++i)
    {
        mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID].push_back(
            (char *)ANGLE_UNSAFE_TODO(argsLocations[i]) - (char *)args);
    }
}

std::vector<size_t> FrameCaptureShared::getCLObjVector(const angle::ParamCapture *paramCaptureKey)
{
    if (mResourceTrackerCL.mCLParamIDToIndexVector.find(paramCaptureKey->uniqueID) !=
        mResourceTrackerCL.mCLParamIDToIndexVector.end())
    {
        return mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID];
    }
    return std::vector<size_t>();
}

template <typename T>
std::unordered_map<T, size_t> &FrameCaptureShared::getMap()
{
    ASSERT(false);
    return std::unordered_map<T, size_t>();
}
template <>
std::unordered_map<cl_platform_id, size_t> &FrameCaptureShared::getMap<cl_platform_id>()
{
    return mResourceTrackerCL.mCLPlatformIDIndices;
}
template <>
std::unordered_map<cl_device_id, size_t> &FrameCaptureShared::getMap<cl_device_id>()
{
    return mResourceTrackerCL.mCLDeviceIDIndices;
}
template <>
std::unordered_map<cl_context, size_t> &FrameCaptureShared::getMap<cl_context>()
{
    return mResourceTrackerCL.mCLContextIndices;
}
template <>
std::unordered_map<cl_event, size_t> &FrameCaptureShared::getMap<cl_event>()
{
    return mResourceTrackerCL.mCLEventsIndices;
}
template <>
std::unordered_map<cl_command_queue, size_t> &FrameCaptureShared::getMap<cl_command_queue>()
{
    return mResourceTrackerCL.mCLCommandQueueIndices;
}
template <>
std::unordered_map<cl_mem, size_t> &FrameCaptureShared::getMap<cl_mem>()
{
    return mResourceTrackerCL.mCLMemIndices;
}
template <>
std::unordered_map<cl_sampler, size_t> &FrameCaptureShared::getMap<cl_sampler>()
{
    return mResourceTrackerCL.mCLSamplerIndices;
}
template <>
std::unordered_map<cl_program, size_t> &FrameCaptureShared::getMap<cl_program>()
{
    return mResourceTrackerCL.mCLProgramIndices;
}
template <>
std::unordered_map<cl_kernel, size_t> &FrameCaptureShared::getMap<cl_kernel>()
{
    return mResourceTrackerCL.mCLKernelIndices;
}

void FrameCaptureShared::writeJSONCL()
{

    JsonSerializer json;
    json.startGroup("TraceMetadata");
    json.addBool("IsBinaryDataCompressed", mCompression);
    json.addScalar("CaptureRevision", GetANGLERevision());
    json.addScalar("FrameStart", mCaptureStartFrame);
    json.addScalar("FrameEnd", mFrameIndex);
    json.addBool("IsOpenCL", true);
    json.endGroup();

    json.startGroup("BinaryMetadata");
    json.addScalar("Version", mIndexInfo.version);
    json.addScalar("BlockCount", mIndexInfo.blockCount);
    // These values are handled as strings to avoid json-related underflows
    std::stringstream blockSizeString;
    blockSizeString << mIndexInfo.blockSize;
    json.addString("BlockSize", blockSizeString.str());
    std::stringstream resSizeString;
    resSizeString << mIndexInfo.residentSize;
    json.addString("ResidentSize", resSizeString.str());
    std::stringstream offsetString;
    offsetString << mIndexInfo.indexOffset;
    json.addString("IndexOffset", offsetString.str());
    json.endGroup();

    {
        const std::vector<std::string> &traceFiles = mReplayWriter.getAndResetWrittenFiles();
        json.addVectorOfStrings("TraceFiles", traceFiles);
    }

    {
        std::stringstream jsonFileNameStream;
        jsonFileNameStream << mOutDirectory << FmtCapturePrefix(kNoContextId, mCaptureLabel)
                           << ".json";
        std::string jsonFileName = jsonFileNameStream.str();

        SaveFileHelper saveData(jsonFileName);
        saveData.write(reinterpret_cast<const uint8_t *>(json.data()), json.length());
    }
}

void FrameCaptureShared::saveCLGetInfo(const CallCapture &call)
{
    std::string prevCall = "";
    size_t size;
    std::ostringstream objectStream;
    std::string clObject;
    JsonSerializer json;

    json.startGroup(call.name());

    // Below ONLY for clGetSupportedImageFormats
    if (call.entryPoint == EntryPoint::CLGetSupportedImageFormats)
    {
        const cl_image_format *data =
            call.params.getParam("image_formats", ParamType::Tcl_image_formatPointer, 4)
                .value.cl_image_formatPointerVal;
        if (!data)
        {
            return;
        }
        size_t *sizePointer =
            call.params.getParam("num_image_formats", ParamType::Tcl_uintPointer, 5)
                .value.size_tPointerVal;
        if (!sizePointer)
        {
            size = call.params.getParam("num_entries", ParamType::Tcl_uint, 3).value.cl_uintVal;
        }
        else
        {
            size = *sizePointer;
        }

        cl_context context = call.params.getParamCaptures()[0].value.cl_contextVal;
        objectStream << static_cast<void *>(context);
        clObject = objectStream.str();
        json.addString("context", clObject);
        json.addScalar("flags", call.params.getParamCaptures()[1].value.MemFlagsVal.get());

        cl::MemObjectType imageType =
            call.params.getParam("image_typePacked", ParamType::TMemObjectType, 2)
                .value.MemObjectTypeVal;
        std::ostringstream oss;
        oss << imageType;
        std::string infoString = oss.str();
        json.startGroup(infoString);
        for (size_t j = 0; j < size; ++j)
        {
            std::ostringstream temp;
            temp << (j + 1);
            json.addScalar("image_channel_order" + temp.str(),
                           ANGLE_UNSAFE_TODO(data[j]).image_channel_order);
            json.addScalar("image_channel_data_type" + temp.str(),
                           ANGLE_UNSAFE_TODO(data[j]).image_channel_data_type);
        }

        json.endGroup();
        json.endGroup();
        return;
    }

    // Get the param_value and size
    bool offsetData = 0;
    switch (call.entryPoint)
    {
        case EntryPoint::CLGetProgramBuildInfo:
        case EntryPoint::CLGetKernelArgInfo:
        case EntryPoint::CLGetKernelWorkGroupInfo:
        {
            offsetData = 1;
            break;
        }
        default:
            break;
    }

    const void *data = call.params.getParam("param_value", ParamType::TvoidPointer, 3 + offsetData)
                           .value.voidPointerVal;
    if (!data)
    {
        return;
    }
    size_t *sizePointer =
        call.params.getParam("param_value_size_ret", ParamType::Tsize_tPointer, 4 + offsetData)
            .value.size_tPointerVal;
    if (!sizePointer)
    {
        size = call.params.getParam("param_value_size", ParamType::Tsize_t, 2 + offsetData)
                   .value.size_tVal;
    }
    else
    {
        size = *sizePointer;
    }

    // Get string representation of OpenCL object specified
    switch (call.entryPoint)
    {
        case EntryPoint::CLGetPlatformInfo:
        {
            cl_platform_id platform = call.params.getParamCaptures()[0].value.cl_platform_idVal;
            objectStream << static_cast<void *>(platform);
            break;
        }
        case EntryPoint::CLGetDeviceInfo:
        {
            cl_device_id device = call.params.getParamCaptures()[0].value.cl_device_idVal;
            objectStream << static_cast<void *>(device);
            break;
        }
        case EntryPoint::CLGetContextInfo:
        {
            cl_context context = call.params.getParamCaptures()[0].value.cl_contextVal;
            objectStream << static_cast<void *>(context);
            break;
        }
        case EntryPoint::CLGetCommandQueueInfo:
        {
            cl_command_queue commandQueue =
                call.params.getParamCaptures()[0].value.cl_command_queueVal;
            objectStream << static_cast<void *>(commandQueue);
            break;
        }
        case EntryPoint::CLGetProgramInfo:
        case EntryPoint::CLGetProgramBuildInfo:
        {
            cl_program program = call.params.getParamCaptures()[0].value.cl_programVal;
            objectStream << static_cast<void *>(program);
            break;
        }
        case EntryPoint::CLGetKernelInfo:
        case EntryPoint::CLGetKernelArgInfo:
        case EntryPoint::CLGetKernelWorkGroupInfo:
        {
            cl_kernel kernel = call.params.getParamCaptures()[0].value.cl_kernelVal;
            objectStream << static_cast<void *>(kernel);
            break;
        }
        case EntryPoint::CLGetEventInfo:
        case EntryPoint::CLGetEventProfilingInfo:
        {
            cl_event event = call.params.getParamCaptures()[0].value.cl_eventVal;
            objectStream << static_cast<void *>(event);
            break;
        }
        case EntryPoint::CLGetMemObjectInfo:
        case EntryPoint::CLGetImageInfo:
        {
            cl_mem mem = call.params.getParamCaptures()[0].value.cl_memVal;
            objectStream << static_cast<void *>(mem);
            break;
        }
        case EntryPoint::CLGetSamplerInfo:
        {
            cl_sampler sampler = call.params.getParamCaptures()[0].value.cl_samplerVal;
            objectStream << static_cast<void *>(sampler);
            break;
        }
        default:
            break;
    }
    clObject = objectStream.str();

    // Go through the param_name options
    switch (call.entryPoint)
    {
        case EntryPoint::CLGetPlatformInfo:
        {
            cl::PlatformInfo info = call.params.getParamCaptures()[1].value.PlatformInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();
            json.addString("platform", clObject);

            switch (ToCLenum(info))
            {
                case CL_PLATFORM_PROFILE:
                case CL_PLATFORM_VERSION:
                case CL_PLATFORM_NAME:
                case CL_PLATFORM_VENDOR:
                case CL_PLATFORM_EXTENSIONS:
                case CL_PLATFORM_ICD_SUFFIX_KHR:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_PLATFORM_EXTENSIONS_WITH_VERSION:
                {
                    const cl_name_version *nameVersion = static_cast<const cl_name_version *>(data);
                    json.startGroup(infoString);
                    for (size_t j = 0; j < size / sizeof(cl_name_version); ++j)
                    {
                        json.addScalar(ANGLE_UNSAFE_TODO(nameVersion[j]).name,
                                       ANGLE_UNSAFE_TODO(nameVersion[j]).version);
                    }
                    json.endGroup();
                    break;
                }
                case CL_PLATFORM_NUMERIC_VERSION:
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                case CL_PLATFORM_HOST_TIMER_RESOLUTION:
#ifdef CL_ENABLE_BETA_EXTENSIONS
                case CL_PLATFORM_COMMAND_BUFFER_CAPABILITIES_KHR:
#endif
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                case CL_PLATFORM_EXTERNAL_MEMORY_IMPORT_HANDLE_TYPES_KHR:
                case CL_PLATFORM_SEMAPHORE_TYPES_KHR:
                case CL_PLATFORM_SEMAPHORE_IMPORT_HANDLE_TYPES_KHR:
                case CL_PLATFORM_SEMAPHORE_EXPORT_HANDLE_TYPES_KHR:
                    json.addVector(infoString,
                                   std::vector<cl_uint>((cl_uint *)data,
                                                        ANGLE_UNSAFE_TODO((cl_uint *)data +
                                                                          size / sizeof(cl_uint))));
                    break;
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }

            break;
        }
        case EntryPoint::CLGetDeviceInfo:
        {
            cl::DeviceInfo info = call.params.getParamCaptures()[1].value.DeviceInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();
            json.addString("device", clObject);
            switch (ToCLenum(info))
            {
                case CL_DEVICE_IL_VERSION:
                case CL_DEVICE_LATEST_CONFORMANCE_VERSION_PASSED:
                case CL_DEVICE_OPENCL_C_VERSION:
                case CL_DEVICE_EXTENSIONS:
                case CL_DEVICE_VERSION:
                case CL_DEVICE_PROFILE:
                case CL_DRIVER_VERSION:
                case CL_DEVICE_VENDOR:
                case CL_DEVICE_NAME:
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                case CL_DEVICE_TYPE:
                case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
                case CL_DEVICE_LOCAL_MEM_SIZE:
                case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
                case CL_DEVICE_GLOBAL_MEM_SIZE:
                case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE:
                case CL_DEVICE_HALF_FP_CONFIG:
                case CL_DEVICE_SINGLE_FP_CONFIG:
                case CL_DEVICE_DEVICE_ENQUEUE_CAPABILITIES:
                case CL_DEVICE_ATOMIC_FENCE_CAPABILITIES:
                case CL_DEVICE_ATOMIC_MEMORY_CAPABILITIES:
                case CL_DEVICE_SVM_CAPABILITIES:
                case CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES:
                case CL_DEVICE_PARTITION_AFFINITY_DOMAIN:
                case CL_DEVICE_DOUBLE_FP_CONFIG:
                case CL_DEVICE_QUEUE_ON_HOST_PROPERTIES:
                case CL_DEVICE_EXECUTION_CAPABILITIES:
                    // cl_ulong and cl_bitfield
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                case CL_DEVICE_VENDOR_ID:
                case CL_DEVICE_MAX_COMPUTE_UNITS:
                case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
                case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE:
                case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF:
                case CL_DEVICE_MAX_CLOCK_FREQUENCY:
                case CL_DEVICE_ADDRESS_BITS:
                case CL_DEVICE_IMAGE_SUPPORT:
                case CL_DEVICE_MAX_READ_IMAGE_ARGS:
                case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
                case CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS:
                case CL_DEVICE_PIPE_SUPPORT:
                case CL_DEVICE_GENERIC_ADDRESS_SPACE_SUPPORT:
                case CL_DEVICE_WORK_GROUP_COLLECTIVE_FUNCTIONS_SUPPORT:
                case CL_DEVICE_NON_UNIFORM_WORK_GROUP_SUPPORT:
                case CL_DEVICE_NUMERIC_VERSION:
                case CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS:
                case CL_DEVICE_MAX_NUM_SUB_GROUPS:
                case CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT:
                case CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT:
                case CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT:
                case CL_DEVICE_PIPE_MAX_PACKET_SIZE:
                case CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS:
                case CL_DEVICE_MAX_PIPE_ARGS:
                case CL_DEVICE_MAX_ON_DEVICE_EVENTS:
                case CL_DEVICE_MAX_ON_DEVICE_QUEUES:
                case CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE:
                case CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE:
                case CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT:
                case CL_DEVICE_IMAGE_PITCH_ALIGNMENT:
                case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC:
                case CL_DEVICE_REFERENCE_COUNT:
                case CL_DEVICE_PARTITION_MAX_SUB_DEVICES:
                case CL_DEVICE_LINKER_AVAILABLE:
                case CL_DEVICE_HOST_UNIFIED_MEMORY:
                case CL_DEVICE_COMPILER_AVAILABLE:
                case CL_DEVICE_AVAILABLE:
                case CL_DEVICE_ENDIAN_LITTLE:
                case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
                case CL_DEVICE_LOCAL_MEM_TYPE:
                case CL_DEVICE_MAX_CONSTANT_ARGS:
                case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE:
                case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE:
                case CL_DEVICE_MEM_BASE_ADDR_ALIGN:
                case CL_DEVICE_MAX_SAMPLERS:
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                case CL_DEVICE_MAX_WORK_GROUP_SIZE:
                case CL_DEVICE_IMAGE2D_MAX_WIDTH:
                case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
                case CL_DEVICE_IMAGE3D_MAX_WIDTH:
                case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
                case CL_DEVICE_IMAGE3D_MAX_DEPTH:
                case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE:
                case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE:
                case CL_DEVICE_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:
                case CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE:
                case CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE:
                case CL_DEVICE_PRINTF_BUFFER_SIZE:
                case CL_DEVICE_PROFILING_TIMER_RESOLUTION:
                case CL_DEVICE_MAX_PARAMETER_SIZE:
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                case CL_DEVICE_MAX_WORK_ITEM_SIZES:
                    json.addVector(infoString,
                                   std::vector<size_t>(
                                       (size_t *)data,
                                       ANGLE_UNSAFE_TODO((size_t *)data + size / sizeof(size_t))));
                    break;
                case CL_DEVICE_PARTITION_TYPE:
                case CL_DEVICE_PARTITION_PROPERTIES:
                    json.addVector(infoString, std::vector<cl_ulong>(
                                                   (cl_ulong *)data,
                                                   ANGLE_UNSAFE_TODO((cl_ulong *)data +
                                                                     size / sizeof(cl_ulong))));
                    break;
                case CL_DEVICE_PARENT_DEVICE:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_device_id *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_DEVICE_PLATFORM:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_platform_id *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_DEVICE_ILS_WITH_VERSION:
                case CL_DEVICE_OPENCL_C_FEATURES:
                case CL_DEVICE_OPENCL_C_ALL_VERSIONS:
                case CL_DEVICE_BUILT_IN_KERNELS_WITH_VERSION:
                case CL_DEVICE_EXTENSIONS_WITH_VERSION:
                {
                    const cl_name_version *nameVersion = static_cast<const cl_name_version *>(data);
                    json.startGroup(infoString);
                    for (size_t j = 0; j < size / sizeof(cl_name_version); ++j)
                    {
                        json.addScalar(ANGLE_UNSAFE_TODO(nameVersion[j]).name,
                                       ANGLE_UNSAFE_TODO(nameVersion[j]).version);
                    }
                    json.endGroup();
                    break;
                }

                default:
                    // Not supported or cannot add to JSON file
                    break;
            }

            break;
        }
        case EntryPoint::CLGetContextInfo:
        {
            cl::ContextInfo info = call.params.getParamCaptures()[1].value.ContextInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("context", clObject);
            switch (ToCLenum(info))
            {
                case CL_PLATFORM_PROFILE:
                case CL_PLATFORM_VERSION:
                case CL_PLATFORM_NAME:
                case CL_PLATFORM_VENDOR:
                case CL_PLATFORM_EXTENSIONS:
                case CL_PLATFORM_ICD_SUFFIX_KHR:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_CONTEXT_REFERENCE_COUNT:
                case CL_CONTEXT_NUM_DEVICES:
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                case CL_CONTEXT_PROPERTIES:
                    json.addVector(infoString, std::vector<cl_ulong>(
                                                   (cl_ulong *)data,
                                                   ANGLE_UNSAFE_TODO((cl_ulong *)data +
                                                                     size / sizeof(cl_ulong))));
                    break;
                case CL_CONTEXT_DEVICES:
                {
                    const cl_device_id *devices = static_cast<const cl_device_id *>(data);
                    std::vector<std::string> devicesStrings;
                    for (size_t j = 0; j < size / sizeof(cl_device_id); ++j)
                    {
                        std::ostringstream voidStream;
                        voidStream << static_cast<void *>(ANGLE_UNSAFE_TODO(devices[j]));
                        devicesStrings.push_back(voidStream.str());
                    }
                    json.addVectorOfStrings(infoString, devicesStrings);
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }

            break;
        }
        case EntryPoint::CLGetCommandQueueInfo:
        {
            cl::CommandQueueInfo info = call.params.getParamCaptures()[1].value.CommandQueueInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("command_queue", clObject);
            switch (ToCLenum(info))
            {
                case CL_QUEUE_DEVICE_DEFAULT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_command_queue *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_QUEUE_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_QUEUE_DEVICE:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_device_id *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_QUEUE_REFERENCE_COUNT:
                case CL_QUEUE_SIZE:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_QUEUE_PROPERTIES:
                {
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                }
                case CL_QUEUE_PROPERTIES_ARRAY:
                {
                    json.addVector(infoString, std::vector<cl_ulong>(
                                                   (cl_ulong *)data,
                                                   ANGLE_UNSAFE_TODO((cl_ulong *)data +
                                                                     size / sizeof(cl_ulong))));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }

            break;
        }
        case EntryPoint::CLGetProgramInfo:
        {
            cl::ProgramInfo info = call.params.getParamCaptures()[1].value.ProgramInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("program", clObject);
            switch (ToCLenum(info))
            {
                case CL_PROGRAM_SOURCE:
                case CL_PROGRAM_IL:
                case CL_PROGRAM_KERNEL_NAMES:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_PROGRAM_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_PROGRAM_REFERENCE_COUNT:
                case CL_PROGRAM_NUM_DEVICES:
                case CL_PROGRAM_SCOPE_GLOBAL_CTORS_PRESENT:
                case CL_PROGRAM_SCOPE_GLOBAL_DTORS_PRESENT:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_PROGRAM_DEVICES:
                {
                    const cl_device_id *devices = static_cast<const cl_device_id *>(data);
                    std::vector<std::string> devicesStrings;
                    for (size_t j = 0; j < size / sizeof(cl_device_id); ++j)
                    {
                        std::ostringstream voidStream;
                        voidStream << static_cast<void *>(ANGLE_UNSAFE_TODO(devices[j]));
                        devicesStrings.push_back(voidStream.str());
                    }
                    json.addVectorOfStrings(infoString, devicesStrings);
                    break;
                }
                case CL_PROGRAM_NUM_KERNELS:
                {
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                }
                case CL_PROGRAM_BINARY_SIZES:
                    json.addVector(infoString,
                                   std::vector<size_t>(
                                       (size_t *)data,
                                       ANGLE_UNSAFE_TODO((size_t *)data + size / sizeof(size_t))));
                    break;
                case CL_PROGRAM_BINARIES:
                    json.addVector(infoString,
                                   std::vector<unsigned char>(
                                       (unsigned char *)data,
                                       ANGLE_UNSAFE_TODO((unsigned char *)data +
                                                         size / sizeof(unsigned char))));
                    break;
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }

            break;
        }
        case EntryPoint::CLGetProgramBuildInfo:
        {
            cl::ProgramBuildInfo info = call.params.getParamCaptures()[2].value.ProgramBuildInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("program", clObject);
            cl_device_id device = call.params.getParamCaptures()[1].value.cl_device_idVal;
            std::ostringstream objectStream2;
            objectStream2 << static_cast<void *>(device);
            clObject = objectStream2.str();
            json.addString("device", clObject);
            switch (ToCLenum(info))
            {
                case CL_PROGRAM_BUILD_OPTIONS:
                case CL_PROGRAM_BUILD_LOG:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_PROGRAM_BINARY_TYPE:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_PROGRAM_BUILD_STATUS:
                {
                    json.addScalar(infoString, *static_cast<const cl_int *>(data));
                    break;
                }
                case CL_PROGRAM_BUILD_GLOBAL_VARIABLE_TOTAL_SIZE:
                {
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetKernelInfo:
        {
            cl::KernelInfo info = call.params.getParamCaptures()[1].value.KernelInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("kernel", clObject);
            switch (ToCLenum(info))
            {
                case CL_KERNEL_FUNCTION_NAME:
                case CL_KERNEL_ATTRIBUTES:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_KERNEL_NUM_ARGS:
                case CL_KERNEL_REFERENCE_COUNT:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_KERNEL_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_KERNEL_PROGRAM:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_program *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetKernelArgInfo:
        {
            cl::KernelArgInfo info = call.params.getParamCaptures()[2].value.KernelArgInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("kernel", clObject);
            cl_uint index = call.params.getParamCaptures()[1].value.cl_uintVal;
            json.addScalar("arg_index", index);
            switch (ToCLenum(info))
            {
                case CL_KERNEL_ARG_TYPE_NAME:
                case CL_KERNEL_ARG_NAME:
                {
                    json.addCString(infoString, static_cast<const char *>(data));
                    break;
                }
                case CL_KERNEL_ARG_ADDRESS_QUALIFIER:
                case CL_KERNEL_ARG_ACCESS_QUALIFIER:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_KERNEL_ARG_TYPE_QUALIFIER:
                {
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetKernelWorkGroupInfo:
        {
            cl::KernelWorkGroupInfo info =
                call.params.getParamCaptures()[2].value.KernelWorkGroupInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("kernel", clObject);
            cl_device_id device = call.params.getParamCaptures()[1].value.cl_device_idVal;
            std::ostringstream objectStream2;
            objectStream2 << static_cast<void *>(device);
            clObject = objectStream2.str();
            json.addString("device", clObject);
            switch (ToCLenum(info))
            {
                case CL_KERNEL_LOCAL_MEM_SIZE:
                case CL_KERNEL_PRIVATE_MEM_SIZE:
                {
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                }
                case CL_KERNEL_WORK_GROUP_SIZE:
                case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE:
                {
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                }
                case CL_KERNEL_GLOBAL_WORK_SIZE:
                case CL_KERNEL_COMPILE_WORK_GROUP_SIZE:
                {
                    json.addVector(
                        infoString,
                        std::vector<size_t>((size_t *)data, ANGLE_UNSAFE_TODO((size_t *)data + 3)));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetEventInfo:
        {
            cl::EventInfo info = call.params.getParamCaptures()[1].value.EventInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("event", clObject);
            switch (ToCLenum(info))
            {
                case CL_EVENT_REFERENCE_COUNT:
                case CL_EVENT_COMMAND_TYPE:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_EVENT_COMMAND_EXECUTION_STATUS:
                {
                    json.addScalar(infoString, *static_cast<const cl_int *>(data));
                    break;
                }
                case CL_EVENT_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_EVENT_COMMAND_QUEUE:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_command_queue *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetEventProfilingInfo:
        {
            cl::ProfilingInfo info = call.params.getParamCaptures()[1].value.ProfilingInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("event", clObject);
            switch (ToCLenum(info))
            {
                case CL_PROFILING_COMMAND_QUEUED:
                case CL_PROFILING_COMMAND_SUBMIT:
                case CL_PROFILING_COMMAND_START:
                case CL_PROFILING_COMMAND_END:
                case CL_PROFILING_COMMAND_COMPLETE:
                {
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetMemObjectInfo:
        {
            cl::MemInfo info = call.params.getParamCaptures()[1].value.MemInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("memObj", clObject);
            switch (ToCLenum(info))
            {
                case CL_MEM_TYPE:
                case CL_MEM_MAP_COUNT:
                case CL_MEM_REFERENCE_COUNT:
                case CL_MEM_USES_SVM_POINTER:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_MEM_FLAGS:
                {
                    json.addScalar(infoString, *static_cast<const cl_ulong *>(data));
                    break;
                }
                case CL_MEM_SIZE:
                case CL_MEM_OFFSET:
                {
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                }
                case CL_MEM_HOST_PTR:
                {
                    std::ostringstream voidStream;
                    voidStream << data;
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_MEM_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_MEM_ASSOCIATED_MEMOBJECT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_mem *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                case CL_MEM_PROPERTIES:
                {
                    json.addVector(infoString,
                                   std::vector<cl_mem_properties>(
                                       (cl_mem_properties *)data,
                                       ANGLE_UNSAFE_TODO((cl_mem_properties *)data +
                                                         size / sizeof(cl_mem_properties))));
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetImageInfo:
        {
            cl::ImageInfo info = call.params.getParamCaptures()[1].value.ImageInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("image", clObject);
            switch (ToCLenum(info))
            {
                case CL_IMAGE_FORMAT:
                {
                    json.startGroup(infoString);
                    json.addScalar("image_channel_order",
                                   static_cast<const cl_image_format *>(data)->image_channel_order);
                    json.addScalar(
                        "image_channel_data_type",
                        static_cast<const cl_image_format *>(data)->image_channel_data_type);
                    json.endGroup();
                    break;
                }
                case CL_IMAGE_NUM_MIP_LEVELS:
                case CL_IMAGE_NUM_SAMPLES:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_IMAGE_ELEMENT_SIZE:
                case CL_IMAGE_ROW_PITCH:
                case CL_IMAGE_SLICE_PITCH:
                case CL_IMAGE_WIDTH:
                case CL_IMAGE_HEIGHT:
                case CL_IMAGE_DEPTH:
                case CL_IMAGE_ARRAY_SIZE:
                {
                    json.addScalar(infoString, *static_cast<const size_t *>(data));
                    break;
                }
                case CL_IMAGE_BUFFER:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_mem *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        case EntryPoint::CLGetSamplerInfo:
        {
            cl::SamplerInfo info = call.params.getParamCaptures()[1].value.SamplerInfoVal;
            std::ostringstream oss;
            oss << info;
            std::string infoString = oss.str();

            json.addString("image", clObject);
            switch (ToCLenum(info))
            {
                case CL_SAMPLER_REFERENCE_COUNT:
                case CL_SAMPLER_NORMALIZED_COORDS:
                case CL_SAMPLER_ADDRESSING_MODE:
                case CL_SAMPLER_FILTER_MODE:
                {
                    json.addScalar(infoString, *static_cast<const cl_uint *>(data));
                    break;
                }
                case CL_SAMPLER_PROPERTIES:
                {
                    json.addVector(infoString,
                                   std::vector<cl_sampler_properties>(
                                       (cl_sampler_properties *)data,
                                       ANGLE_UNSAFE_TODO((cl_sampler_properties *)data +
                                                         size / sizeof(cl_sampler_properties))));
                    break;
                }
                case CL_SAMPLER_CONTEXT:
                {
                    std::ostringstream voidStream;
                    voidStream << static_cast<void *>(*(cl_context *)data);
                    std::string memLoc = voidStream.str();
                    json.addCString(infoString, memLoc.c_str());
                    break;
                }
                default:
                    // Not supported or cannot add to JSON file
                    break;
            }
            break;
        }
        default:
            break;
    }

    json.endGroup();

    mCLInfoJson += std::string(json.data()) + ",\n";
}

void FrameCaptureShared::writeJSONCLGetInfo()
{
    std::stringstream jsonFileNameStream;
    jsonFileNameStream << mOutDirectory << FmtCapturePrefix(kNoContextId, mCaptureLabel)
                       << "_OpenCL_info.json";
    std::string jsonFileName = jsonFileNameStream.str();

    SaveFileHelper saveData(jsonFileName);

    saveData.write(reinterpret_cast<const uint8_t *>(mCLInfoJson.c_str()), mCLInfoJson.length());
}

void FrameCaptureShared::writeCppReplayIndexFilesCL()
{
    // Ensure the last frame is written. This will no-op if the frame is already written.
    mReplayWriter.saveFrame();

    {
        std::stringstream header;

        header << "#pragma once\n";
        header << "\n";
        header << "#define CL_NO_EXTENSION_PROTOTYPES\n";
        header << "#define CL_ENABLE_BETA_EXTENSIONS\n";
        header << "#include <angle_cl.h>\n";
        header << "#include <stdint.h>\n";
        header << "#include \"trace_fixture_cl.h\"\n";

        std::string includes = header.str();
        mReplayWriter.setHeaderPrologue(includes);
    }

    {
        std::stringstream source;

        source << "#include \"" << FmtCapturePrefix(kNoContextId, mCaptureLabel) << ".h\"\n";
        source << "#include \"trace_fixture_cl.h\"\n";

        std::string sourcePrologue = source.str();
        mReplayWriter.setSourcePrologue(sourcePrologue);
    }

    {
        std::string proto = "void InitReplay(void)";

        std::stringstream source;
        source << proto << "\n";
        source << "{\n";
        WriteInitReplayCallCL(mCompression, source, mCaptureLabel, 0, mReadBufferSize,
                              mMaxCLParamsSize);
        source << "}\n";

        mReplayWriter.addPrivateFunction(proto, std::stringstream(), source);
    }

    {
        std::string proto = "void ReplayFrame(uint32_t frameIndex)";

        std::stringstream source;

        source << proto << "\n";
        source << "{\n";
        source << "    switch (frameIndex)\n";
        source << "    {\n";
        for (uint32_t frameIndex : mActiveFrameIndices)
        {
            source << "        case " << frameIndex << ":\n";
            source << "            " << FmtReplayFunction(kNoContextId, FuncUsage::Call, frameIndex)
                   << ";\n";
            source << "            break;\n";
        }
        source << "        default:\n";
        source << "            break;\n";
        source << "    }\n";
        source << "}\n";

        mReplayWriter.addPublicFunction(proto, std::stringstream(), source);
    }

    for (auto extFuncName : mExtFuncsAdded)
    {
        mReplayWriter.addStaticVariable(extFuncName + "_fn", extFuncName);
    }

    std::stringstream protoSetupStream;
    protoSetupStream << "void SetupFirstFrame(void)";
    std::string protoSetup = protoSetupStream.str();
    std::stringstream headerStreamSetup;
    std::stringstream bodyStreamSetup;
    WriteCppReplayFunctionWithPartsCL(ReplayFunc::SetupFirstFrame, mReplayWriter,
                                      mCaptureStartFrame, &mBinaryData, mCLSetupCalls,
                                      headerStreamSetup, bodyStreamSetup);
    mReplayWriter.addPublicFunction(protoSetup, headerStreamSetup, bodyStreamSetup);

    {
        std::string proto = "void ResetReplay(void)";
        std::stringstream source;
        source << proto << "\n" << "{\n";
        printCLResetObjs(source);
        source << "}\n";
        mReplayWriter.addPublicFunction(proto, std::stringstream(), source);
    }

    {
        std::stringstream fnameStream;
        fnameStream << mOutDirectory << FmtCapturePrefix(kNoContextId, mCaptureLabel);
        std::string fnamePattern = fnameStream.str();

        mReplayWriter.setFilenamePattern(fnamePattern);
    }

    mReplayWriter.saveIndexFilesAndHeader();

    // Finalize binary data file
    mIndexInfo = mBinaryData.closeBinaryDataStore();
    writeJSONCL();
    writeJSONCLGetInfo();
}

void FrameCaptureShared::writeMainContextCppReplayCL()
{
    {
        std::stringstream header;

        header << "#include \"" << FmtCapturePrefix(kNoContextId, mCaptureLabel) << ".h\"\n";
        header << "#include \"trace_fixture_cl.h\"\n";

        std::string headerString = header.str();
        mReplayWriter.setSourcePrologue(headerString);
    }

    uint32_t frameIndex = getReplayFrameIndex();

    if (frameIndex == 1)
    {
        {
            std::string proto = "void SetupReplay(void)";

            std::stringstream out;

            out << proto << "\n";
            out << "{\n";

            // Setup all of the shared objects.
            out << "    InitReplay();\n";

            out << "}\n";

            mReplayWriter.addPublicFunction(proto, std::stringstream(), out);
        }
    }

    if (!mFrameCalls.empty())
    {
        std::stringstream protoStream;
        protoStream << "void "
                    << FmtReplayFunction(kNoContextId, FuncUsage::Prototype, mFrameIndex);
        std::string proto = protoStream.str();
        std::stringstream headerStream;
        std::stringstream bodyStream;

        WriteCppReplayFunctionWithPartsCL(ReplayFunc::Replay, mReplayWriter, mFrameIndex,
                                          &mBinaryData, mFrameCalls, headerStream, bodyStream);

        mReplayWriter.addPrivateFunction(proto, headerStream, bodyStream);
    }

    {
        std::stringstream fnamePatternStream;
        fnamePatternStream << mOutDirectory << FmtCapturePrefix(kNoContextId, mCaptureLabel);
        std::string fnamePattern = fnamePatternStream.str();

        mReplayWriter.setFilenamePattern(fnamePattern);
    }

    if (mFrameIndex == mCaptureEndFrame)
    {
        mReplayWriter.saveFrame();
    }
}

}  // namespace angle
