//
// Copyright 2021 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.
//
// trace_fixture.cpp:
//   Common code for the ANGLE trace replays.
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "trace_fixture.h"

#include "angle_trace_gl.h"

#include <filesystem>
#include <string>
#include "common/system_utils.h"
#include "scoped_capture_exclude.h"

namespace
{
void UpdateResourceMap(GLuint *resourceMap, GLuint id, GLsizei readBufferOffset)
{
    GLuint returnedID;
    memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
    resourceMap[id] = returnedID;
}

void UpdateResourceMapPerContext(GLuint **resourceArray,
                                 GLuint contextId,
                                 GLuint id,
                                 GLsizei readBufferOffset)
{
    GLuint returnedID;
    memcpy(&returnedID, &gReadBuffer[readBufferOffset], sizeof(GLuint));
    resourceArray[contextId][id] = returnedID;
}

uint32_t gMaxContexts                  = 1;
angle::TraceCallbacks *gTraceCallbacks = nullptr;
std::vector<std::string> *gRequestedExtensions = nullptr;

EGLClientBuffer GetClientBuffer(EGLenum target, uintptr_t key)
{
    switch (target)
    {
        case EGL_GL_TEXTURE_2D:
        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
        case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
        case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
        case EGL_GL_TEXTURE_3D:
        {
            uintptr_t id = static_cast<uintptr_t>(gTextureMap[key]);
            return reinterpret_cast<EGLClientBuffer>(id);
        }
        case EGL_GL_RENDERBUFFER:
        {
            uintptr_t id = static_cast<uintptr_t>(gRenderbufferMap[key]);
            return reinterpret_cast<EGLClientBuffer>(id);
        }
        default:
        {
            const auto &iData = gClientBufferMap.find(key);
            return iData != gClientBufferMap.end() ? iData->second : nullptr;
        }
    }
}

ValidateSerializedStateCallback gValidateSerializedStateCallback;
std::unordered_map<GLuint, std::vector<GLint>> gInternalUniformLocationsMap;

constexpr size_t kMaxClientArrays = 16;

std::vector<std::string> *LoadRequestedExtensions()
{
    // Read in requested extensions if the file exists
    constexpr const char *REQUESTED_EXTENSIONS_FILENAME = "angle_trace_requested_extensions";

    std::filesystem::path tempDir     = std::filesystem::temp_directory_path();
    std::filesystem::path extFilePath = tempDir / REQUESTED_EXTENSIONS_FILENAME;
    std::ifstream extFile(extFilePath);
    std::vector<std::string> *requestedExtensions = nullptr;

    if (extFile.is_open())
    {
        requestedExtensions = new std::vector<std::string>();
        std::string ext;
        while (std::getline(extFile, ext))
        {
            requestedExtensions->push_back(ext);
        }
        extFile.close();
        // Delete the file to prevent unexpected results in future runs
        std::filesystem::remove(extFilePath);
    }
    return requestedExtensions;
}
}  // namespace

GLint **gUniformLocations;
GLuint gCurrentProgram = 0;
GLuint gCurrentContext = 0;
GLuint *gCurrentProgramPerContext;

// TODO(jmadill): Hide from the traces. http://anglebug.com/42266223
BlockIndexesMap gUniformBlockIndexes;

void UpdateUniformLocation(GLuint program, const char *name, GLint location, GLint count)
{
    // Do not capture the glGetUniformLocation below on retrace
    angle::ScopedCaptureExclude skipRecording;

    std::vector<GLint> &programLocations = gInternalUniformLocationsMap[program];
    if (static_cast<GLint>(programLocations.size()) < location + count)
    {
        programLocations.resize(location + count, 0);
    }
    GLuint mappedProgramID = gShaderProgramMap[program];
    GLint baseUniformLocation = glGetUniformLocation(mappedProgramID, name);
    for (GLint arrayIndex = 0; arrayIndex < count; ++arrayIndex)
    {
        programLocations[location + arrayIndex] = baseUniformLocation + arrayIndex;
    }
    gUniformLocations[program] = programLocations.data();
}

void DeleteUniformLocations(GLuint program)
{
    // No-op. We leave uniform locations around so deleted current programs can still use them.
}

void UpdateUniformBlockIndex(GLuint program, const char *name, GLuint index)
{
    // Do not capture the glGetUniformBlockIndex below on retrace
    angle::ScopedCaptureExclude skipRecording;

    gUniformBlockIndexes[program][index] = glGetUniformBlockIndex(program, name);
}

void UniformBlockBinding(GLuint program, GLuint uniformblockIndex, GLuint binding)
{
    glUniformBlockBinding(gShaderProgramMap[program],
                          gUniformBlockIndexes[gShaderProgramMap[program]][uniformblockIndex],
                          binding);
}

void UpdateCurrentProgram(GLuint program)
{
    gCurrentProgram = program;
    // gCurrentContext will be zero for legacy traces
    gCurrentProgramPerContext[0] = program;
}

void UpdateCurrentContext(GLuint context)
{
    gCurrentContext = context;
}

void UpdateCurrentProgramPerContext(GLuint program)
{
    gCurrentProgramPerContext[gCurrentContext] = program;
}

uint8_t *gBinaryData;
angle::FrameCaptureBinaryData *gFrameCaptureBinaryData;
uint8_t *gReadBuffer;
uint8_t *gClientArrays[kMaxClientArrays];
GLuint *gResourceIDBuffer;
SyncResourceMap gSyncMap;
ContextMap gContextMap;
GLuint gShareContextId;
GLuint *gBufferMap;
GLuint *gFenceNVMap;
GLuint *gFramebufferMap;
GLuint **gFramebufferMapPerContext;
GLuint *gMemoryObjectMap;
GLuint *gProgramPipelineMap;
GLuint *gQueryMap;
GLuint *gRenderbufferMap;
GLuint *gSamplerMap;
GLuint *gSemaphoreMap;
GLuint *gShaderProgramMap;
GLuint *gTextureMap;
GLuint *gTransformFeedbackMap;
GLuint *gVertexArrayMap;

// TODO(jmadill): Consolidate. http://anglebug.com/42266223
ClientBufferMap gClientBufferMap;
EGLImageMap gEGLImageMap;
SurfaceMap gSurfaceMap;

GLeglImageOES *gEGLImageMap2;
GLuint *gEGLImageMap2Resources;
EGLSurface *gSurfaceMap2;
EGLContext *gContextMap2;
GLsync *gSyncMap2;
EGLSync *gEGLSyncMap;
EGLDisplay gEGLDisplay;

std::string gBinaryDataDir = ".";

angle::ReplayResourceMode gReplayResourceMode = angle::ReplayResourceMode::Active;

template <typename T>
T *AllocateZeroedValues(size_t count)
{
    T *mem = new T[count + 1];
    memset(mem, 0, sizeof(T) * (count + 1));
    return mem;
}

GLuint *AllocateZeroedUints(size_t count)
{
    return AllocateZeroedValues<GLuint>(count);
}

void InitializeReplay5(const char *binaryDataFileName,
                       size_t maxClientArraySize,
                       size_t readBufferSize,
                       size_t resourceIDBufferSize,
                       GLuint contextId,
                       uint32_t maxBuffer,
                       uint32_t maxContext,
                       uint32_t maxFenceNV,
                       uint32_t maxFramebuffer,
                       uint32_t maxImage,
                       uint32_t maxMemoryObject,
                       uint32_t maxProgramPipeline,
                       uint32_t maxQuery,
                       uint32_t maxRenderbuffer,
                       uint32_t maxSampler,
                       uint32_t maxSemaphore,
                       uint32_t maxShaderProgram,
                       uint32_t maxSurface,
                       uint32_t maxSync,
                       uint32_t maxTexture,
                       uint32_t maxTransformFeedback,
                       uint32_t maxVertexArray,
                       GLuint maxEGLSyncID)
{
    gFrameCaptureBinaryData = gTraceCallbacks->ConfigureBinaryDataLoader(binaryDataFileName);

    InitializeReplay4(binaryDataFileName, maxClientArraySize, readBufferSize, resourceIDBufferSize,
                      contextId, maxBuffer, maxContext, maxFenceNV, maxFramebuffer, maxImage,
                      maxMemoryObject, maxProgramPipeline, maxQuery, maxRenderbuffer, maxSampler,
                      maxSemaphore, maxShaderProgram, maxSurface, maxSync, maxTexture,
                      maxTransformFeedback, maxVertexArray, maxEGLSyncID);
}

void InitializeReplay4(const char *binaryDataFileName,
                       size_t maxClientArraySize,
                       size_t readBufferSize,
                       size_t resourceIDBufferSize,
                       GLuint contextId,
                       uint32_t maxBuffer,
                       uint32_t maxContext,
                       uint32_t maxFenceNV,
                       uint32_t maxFramebuffer,
                       uint32_t maxImage,
                       uint32_t maxMemoryObject,
                       uint32_t maxProgramPipeline,
                       uint32_t maxQuery,
                       uint32_t maxRenderbuffer,
                       uint32_t maxSampler,
                       uint32_t maxSemaphore,
                       uint32_t maxShaderProgram,
                       uint32_t maxSurface,
                       uint32_t maxSync,
                       uint32_t maxTexture,
                       uint32_t maxTransformFeedback,
                       uint32_t maxVertexArray,
                       GLuint maxEGLSyncID)
{
    InitializeReplay3(binaryDataFileName, maxClientArraySize, readBufferSize, resourceIDBufferSize,
                      contextId, maxBuffer, maxContext, maxFenceNV, maxFramebuffer, maxImage,
                      maxMemoryObject, maxProgramPipeline, maxQuery, maxRenderbuffer, maxSampler,
                      maxSemaphore, maxShaderProgram, maxSurface, maxSync, maxTexture,
                      maxTransformFeedback, maxVertexArray);
    gEGLSyncMap = AllocateZeroedValues<EGLSync>(maxEGLSyncID);
    gEGLDisplay = eglGetCurrentDisplay();
}

void InitializeReplay3(const char *binaryDataFileName,
                       size_t maxClientArraySize,
                       size_t readBufferSize,
                       size_t resourceIDBufferSize,
                       GLuint contextId,
                       uint32_t maxBuffer,
                       uint32_t maxContext,
                       uint32_t maxFenceNV,
                       uint32_t maxFramebuffer,
                       uint32_t maxImage,
                       uint32_t maxMemoryObject,
                       uint32_t maxProgramPipeline,
                       uint32_t maxQuery,
                       uint32_t maxRenderbuffer,
                       uint32_t maxSampler,
                       uint32_t maxSemaphore,
                       uint32_t maxShaderProgram,
                       uint32_t maxSurface,
                       uint32_t maxSync,
                       uint32_t maxTexture,
                       uint32_t maxTransformFeedback,
                       uint32_t maxVertexArray)
{
    InitializeReplay2(binaryDataFileName, maxClientArraySize, readBufferSize, contextId, maxBuffer,
                      maxContext, maxFenceNV, maxFramebuffer, maxImage, maxMemoryObject,
                      maxProgramPipeline, maxQuery, maxRenderbuffer, maxSampler, maxSemaphore,
                      maxShaderProgram, maxSurface, maxTexture, maxTransformFeedback,
                      maxVertexArray);

    gSyncMap2         = AllocateZeroedValues<GLsync>(maxSync);
    gResourceIDBuffer = AllocateZeroedUints(resourceIDBufferSize);
}

void InitializeReplay2(const char *binaryDataFileName,
                       size_t maxClientArraySize,
                       size_t readBufferSize,
                       GLuint contextId,
                       uint32_t maxBuffer,
                       uint32_t maxContext,
                       uint32_t maxFenceNV,
                       uint32_t maxFramebuffer,
                       uint32_t maxImage,
                       uint32_t maxMemoryObject,
                       uint32_t maxProgramPipeline,
                       uint32_t maxQuery,
                       uint32_t maxRenderbuffer,
                       uint32_t maxSampler,
                       uint32_t maxSemaphore,
                       uint32_t maxShaderProgram,
                       uint32_t maxSurface,
                       uint32_t maxTexture,
                       uint32_t maxTransformFeedback,
                       uint32_t maxVertexArray)
{
    gMaxContexts = maxContext + 1;
    InitializeReplay(binaryDataFileName, maxClientArraySize, readBufferSize, maxBuffer, maxFenceNV,
                     maxFramebuffer, maxMemoryObject, maxProgramPipeline, maxQuery, maxRenderbuffer,
                     maxSampler, maxSemaphore, maxShaderProgram, maxTexture, maxTransformFeedback,
                     maxVertexArray);

    gContextMap2           = AllocateZeroedValues<EGLContext>(maxContext);
    gEGLImageMap2          = AllocateZeroedValues<EGLImage>(maxImage);
    gEGLImageMap2Resources = AllocateZeroedValues<GLuint>(maxImage);
    gSurfaceMap2           = AllocateZeroedValues<EGLSurface>(maxSurface);

    gContextMap2[0]         = EGL_NO_CONTEXT;
    gShareContextId         = contextId;
    gContextMap2[contextId] = eglGetCurrentContext();
}

void InitializeReplay(const char *binaryDataFileName,
                      size_t maxClientArraySize,
                      size_t readBufferSize,
                      uint32_t maxBuffer,
                      uint32_t maxFenceNV,
                      uint32_t maxFramebuffer,
                      uint32_t maxMemoryObject,
                      uint32_t maxProgramPipeline,
                      uint32_t maxQuery,
                      uint32_t maxRenderbuffer,
                      uint32_t maxSampler,
                      uint32_t maxSemaphore,
                      uint32_t maxShaderProgram,
                      uint32_t maxTexture,
                      uint32_t maxTransformFeedback,
                      uint32_t maxVertexArray)
{
    if (!gFrameCaptureBinaryData)
    {
        gBinaryData = gTraceCallbacks->LoadBinaryData(binaryDataFileName);
    }

    for (uint8_t *&clientArray : gClientArrays)
    {
        clientArray = new uint8_t[maxClientArraySize];
    }

    gReadBuffer = new uint8_t[readBufferSize];

    gBufferMap            = AllocateZeroedUints(maxBuffer);
    gFenceNVMap           = AllocateZeroedUints(maxFenceNV);
    gFramebufferMap       = AllocateZeroedUints(maxFramebuffer);
    gMemoryObjectMap      = AllocateZeroedUints(maxMemoryObject);
    gProgramPipelineMap   = AllocateZeroedUints(maxProgramPipeline);
    gQueryMap             = AllocateZeroedUints(maxQuery);
    gRenderbufferMap      = AllocateZeroedUints(maxRenderbuffer);
    gSamplerMap           = AllocateZeroedUints(maxSampler);
    gSemaphoreMap         = AllocateZeroedUints(maxSemaphore);
    gShaderProgramMap     = AllocateZeroedUints(maxShaderProgram);
    gTextureMap           = AllocateZeroedUints(maxTexture);
    gTransformFeedbackMap = AllocateZeroedUints(maxTransformFeedback);
    gVertexArrayMap       = AllocateZeroedUints(maxVertexArray);

    gUniformLocations = new GLint *[maxShaderProgram + 1];
    memset(gUniformLocations, 0, sizeof(GLint *) * (maxShaderProgram + 1));

    gContextMap[0] = EGL_NO_CONTEXT;

    gCurrentProgramPerContext = new GLuint[gMaxContexts];
    gFramebufferMapPerContext = new GLuint *[gMaxContexts];
    memset(gFramebufferMapPerContext, 0, sizeof(GLuint *) * (gMaxContexts));
    for (uint8_t i = 0; i < gMaxContexts; i++)
    {
        gFramebufferMapPerContext[i] = AllocateZeroedValues<GLuint>(maxFramebuffer);
    }

    // Pull in requested extension list from file created by ANGLEPerfTest
    gRequestedExtensions = LoadRequestedExtensions();
}

void FinishReplay()
{
    delete[] gReadBuffer;
    for (uint8_t *&clientArray : gClientArrays)
    {
        delete[] clientArray;
    }
    delete[] gResourceIDBuffer;
    delete[] gBufferMap;
    delete[] gContextMap2;
    delete[] gEGLImageMap2;
    delete[] gEGLSyncMap;
    delete[] gRenderbufferMap;
    delete[] gTextureMap;
    delete[] gFramebufferMap;
    delete[] gShaderProgramMap;
    delete[] gFenceNVMap;
    delete[] gMemoryObjectMap;
    delete[] gProgramPipelineMap;
    delete[] gQueryMap;
    delete[] gSamplerMap;
    delete[] gSemaphoreMap;
    delete[] gSurfaceMap2;
    delete[] gSyncMap2;
    delete[] gTransformFeedbackMap;
    delete[] gVertexArrayMap;

    delete gRequestedExtensions;

    for (uint8_t i = 0; i < gMaxContexts; i++)
    {
        delete[] gFramebufferMapPerContext[i];
    }
    delete[] gFramebufferMapPerContext;
    delete[] gCurrentProgramPerContext;

    if (gFrameCaptureBinaryData)
    {
        gFrameCaptureBinaryData->closeBinaryDataLoader();
        delete gFrameCaptureBinaryData;
        gFrameCaptureBinaryData = nullptr;
    }
}

void SetValidateSerializedStateCallback(ValidateSerializedStateCallback callback)
{
    gValidateSerializedStateCallback = callback;
}

angle::TraceInfo gTraceInfo;
std::string gTraceGzPath;

struct TraceFunctionsImpl : angle::TraceFunctions
{
    void SetupReplay() override { ::SetupReplay(); }

    void ReplayFrame(uint32_t frameIndex) override { ::ReplayFrame(frameIndex); }

    void ResetReplay() override { ::ResetReplay(); }

    void SetupFirstFrame() override {}

    void FinishReplay() override { ::FinishReplay(); }

    void SetBinaryDataDir(const char *dataDir) override { gBinaryDataDir = dataDir; }

    void SetReplayResourceMode(const angle::ReplayResourceMode resourceMode) override
    {
        gReplayResourceMode = resourceMode;
    }

    void SetTraceInfo(const angle::TraceInfo &traceInfo) override { gTraceInfo = traceInfo; }

    void SetTraceGzPath(const std::string &traceGzPath) override { gTraceGzPath = traceGzPath; }
};

TraceFunctionsImpl gTraceFunctionsImpl;

void SetupEntryPoints(angle::TraceCallbacks *traceCallbacks, angle::TraceFunctions **traceFunctions)
{
    gTraceCallbacks = traceCallbacks;
    *traceFunctions = &gTraceFunctionsImpl;
}

void UpdateClientArrayPointer(int arrayIndex, const void *data, uint64_t size)
{
    memcpy(gClientArrays[arrayIndex], data, static_cast<size_t>(size));
}

void UpdateClientArrayPointerWithOffset(int arrayIndex,
                                        const void *data,
                                        uint64_t size,
                                        uint64_t offset)
{
    uintptr_t dest =
        reinterpret_cast<uintptr_t>(gClientArrays[arrayIndex]) + static_cast<size_t>(offset);
    memcpy(reinterpret_cast<uint8_t *>(dest), data, static_cast<size_t>(size));
}

BufferHandleMap gMappedBufferData;

void UpdateClientBufferData(GLuint bufferID, const void *source, GLsizei size)
{
    memcpy(gMappedBufferData[gBufferMap[bufferID]], source, size);
}

void UpdateClientBufferDataWithOffset(GLuint bufferID,
                                      const void *source,
                                      GLsizei size,
                                      GLsizei offset)
{
    uintptr_t dest = reinterpret_cast<uintptr_t>(gMappedBufferData[gBufferMap[bufferID]]) + offset;
    memcpy(reinterpret_cast<void *>(dest), source, size);
}

void UpdateResourceIDBuffer(int resourceIndex, GLuint id)
{
    gResourceIDBuffer[resourceIndex] = id;
}

void UpdateBufferID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gBufferMap, id, readBufferOffset);
}

void UpdateFenceNVID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gFenceNVMap, id, readBufferOffset);
}

void UpdateFramebufferID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gFramebufferMap, id, readBufferOffset);
}

void UpdateFramebufferID2(GLuint contextId, GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMapPerContext(gFramebufferMapPerContext, contextId, id, readBufferOffset);
}

void UpdateMemoryObjectID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gMemoryObjectMap, id, readBufferOffset);
}

void UpdateProgramPipelineID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gProgramPipelineMap, id, readBufferOffset);
}

void UpdateQueryID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gQueryMap, id, readBufferOffset);
}

void UpdateRenderbufferID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gRenderbufferMap, id, readBufferOffset);
}

void UpdateSamplerID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gSamplerMap, id, readBufferOffset);
}

void UpdateSemaphoreID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gSemaphoreMap, id, readBufferOffset);
}

void UpdateShaderProgramID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gShaderProgramMap, id, readBufferOffset);
}

void UpdateTextureID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gTextureMap, id, readBufferOffset);
}

void UpdateTransformFeedbackID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gTransformFeedbackMap, id, readBufferOffset);
}

void UpdateVertexArrayID(GLuint id, GLsizei readBufferOffset)
{
    UpdateResourceMap(gVertexArrayMap, id, readBufferOffset);
}

void SetFramebufferID(GLuint id)
{
    glGenFramebuffers(1, &gFramebufferMap[id]);
}

void SetFramebufferID2(GLuint contextID, GLuint id)
{
    glGenFramebuffers(1, &gFramebufferMapPerContext[contextID][id]);
}

void SetBufferID(GLuint id)
{
    glGenBuffers(1, &gBufferMap[id]);
}

void SetRenderbufferID(GLuint id)
{
    glGenRenderbuffers(1, &gRenderbufferMap[id]);
}

void SetTextureID(GLuint id)
{
    glGenTextures(1, &gTextureMap[id]);
}

void ValidateSerializedState(const char *serializedState, const char *fileName, uint32_t line)
{
    if (gValidateSerializedStateCallback)
    {
        gValidateSerializedStateCallback(serializedState, fileName, line);
    }
}

void MapBufferRange(GLenum target,
                    GLintptr offset,
                    GLsizeiptr length,
                    GLbitfield access,
                    GLuint buffer)
{
    gMappedBufferData[gBufferMap[buffer]] = glMapBufferRange(target, offset, length, access);
}

void MapBufferRangeEXT(GLenum target,
                       GLintptr offset,
                       GLsizeiptr length,
                       GLbitfield access,
                       GLuint buffer)
{
    gMappedBufferData[gBufferMap[buffer]] = glMapBufferRangeEXT(target, offset, length, access);
}

void MapBufferOES(GLenum target, GLbitfield access, GLuint buffer)
{
    gMappedBufferData[gBufferMap[buffer]] = glMapBufferOES(target, access);
}

void CreateShader(GLenum shaderType, GLuint shaderProgram)
{
    gShaderProgramMap[shaderProgram] = glCreateShader(shaderType);
}

void CreateProgram(GLuint shaderProgram)
{
    gShaderProgramMap[shaderProgram] = glCreateProgram();
}

void CreateShaderProgramv(GLenum type,
                          GLsizei count,
                          const GLchar *const *strings,
                          GLuint shaderProgram)
{
    gShaderProgramMap[shaderProgram] = glCreateShaderProgramv(type, count, strings);
}

void FenceSync(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
{
    gSyncMap[fenceSync] = glFenceSync(condition, flags);
}

void FenceSync2(GLenum condition, GLbitfield flags, uintptr_t fenceSync)
{
    gSyncMap2[fenceSync] = glFenceSync(condition, flags);
}

GLenum ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout, GLenum capturedReturnValue)
{
    if (capturedReturnValue == GL_ALREADY_SIGNALED || capturedReturnValue == GL_CONDITION_SATISFIED)
    {
        GLenum result        = GL_TIMEOUT_EXPIRED;
        GLuint64 waitTimeout = 100000000;  // 100ms
        int attempts         = 0;
        while (result != GL_ALREADY_SIGNALED && result != GL_CONDITION_SATISFIED)
        {
            result = glClientWaitSync(sync, flags, waitTimeout);
            attempts++;
            if (attempts > 100)
            {
                printf(
                    "ClientWaitSync: Waiting for sync object %p to be signaled is taking too long "
                    "(attempts: %d)\n",
                    (void *)sync, attempts);
                attempts = 0;
            }
            if (result == GL_WAIT_FAILED)
            {
                printf(
                    "ClientWaitSync: glClientWaitSync returned GL_WAIT_FAILED for sync object %p\n",
                    (void *)sync);
                break;
            }
        }
        return result;
    }
    else
    {
        return glClientWaitSync(sync, flags, timeout);
    }
}

GLuint CreateEGLImageResource(GLsizei width, GLsizei height)
{
    GLint previousTexId;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &previousTexId);
    GLint previousAlignment;
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &previousAlignment);

    // Create a texture and fill with a placeholder green value
    GLuint stagingTexId;
    glGenTextures(1, &stagingTexId);
    glBindTexture(GL_TEXTURE_2D, stagingTexId);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    std::vector<GLubyte> pixels;
    pixels.reserve(width * height * 4);
    for (int i = 0; i < width * height; i++)
    {
        pixels.push_back(61);
        pixels.push_back(220);
        pixels.push_back(132);
        pixels.push_back(255);
    }
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 pixels.data());

    glPixelStorei(GL_UNPACK_ALIGNMENT, previousAlignment);
    glBindTexture(GL_TEXTURE_2D, previousTexId);
    return stagingTexId;
}

void UpdateEGLImageData(GLuint imageID, GLsizei width, GLsizei height, const void *imageData)
{
    GLint restoreTexture;
    GLint restoreAlignment;
    glGetIntegerv(GL_TEXTURE_BINDING_2D, &restoreTexture);
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &restoreAlignment);

    if (gEGLImageMap2[imageID] != nullptr)
    {
        // EGLImage already exists, update backing texture if there is imageData
        GLuint textureID = gEGLImageMap2Resources[imageID];
        if ((textureID != 0) && (imageData != nullptr))
        {
            glBindTexture(GL_TEXTURE_2D, textureID);
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE,
                            imageData);
        }
    }
    else
    {
        // First eglImage binding, create eglImage and a staging texture for it
        GLuint stagingTexture;
        if (imageData != nullptr)
        {
            glGenTextures(1, &stagingTexture);
            glBindTexture(GL_TEXTURE_2D, stagingTexture);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                         imageData);
        }
        else
        {
            // Fallback is to use a static, solid green placeholder texture
            stagingTexture = CreateEGLImageResource(width, height);
        }

        gEGLImageMap2Resources[imageID] = stagingTexture;
        gEGLImageMap2[imageID] =
            eglCreateImageKHR(gEGLDisplay, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
                              reinterpret_cast<EGLClientBuffer>(stagingTexture), nullptr);
    }

    glPixelStorei(GL_UNPACK_ALIGNMENT, restoreAlignment);
    glBindTexture(GL_TEXTURE_2D, restoreTexture);
}

void CreateEGLImage(EGLDisplay dpy,
                    EGLContext ctx,
                    EGLenum target,
                    uintptr_t buffer,
                    const EGLAttrib *attrib_list,
                    GLsizei width,
                    GLsizei height,
                    GLuint imageID)
{
    if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
    {
        // If image was created from an AHB or the backing resource wasn't captured, create a new
        // texture to use instead, which will be filled in an UpdateEGLImageData call we insert just
        // before the bind call. Substituting a regular texture for the AHB allows the trace to run
        // on non-Android systems.
        gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
        gEGLImageMap2[imageID]          = eglCreateImage(
            dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
            reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
    }
    else
    {
        EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
        gEGLImageMap2[imageID]       = eglCreateImage(dpy, ctx, target, clientBuffer, attrib_list);
    }
}

void CreateEGLImageKHR(EGLDisplay dpy,
                       EGLContext ctx,
                       EGLenum target,
                       uintptr_t buffer,
                       const EGLint *attrib_list,
                       GLsizei width,
                       GLsizei height,
                       GLuint imageID)
{
    // This function is nearly identical to CreateEGLImage() above, but remains separated
    // because of a unique function signature. See comments above.
    if (target == EGL_NATIVE_BUFFER_ANDROID || buffer == 0)
    {
        gEGLImageMap2Resources[imageID] = CreateEGLImageResource(width, height);
        gEGLImageMap2[imageID]          = eglCreateImageKHR(
            dpy, eglGetCurrentContext(), EGL_GL_TEXTURE_2D,
            reinterpret_cast<EGLClientBuffer>(gEGLImageMap2Resources[imageID]), attrib_list);
    }
    else
    {
        EGLClientBuffer clientBuffer = GetClientBuffer(target, buffer);
        gEGLImageMap2[imageID] = eglCreateImageKHR(dpy, ctx, target, clientBuffer, attrib_list);
    }
}

void DestroyEGLImage(EGLDisplay dpy, EGLImage image, GLuint imageID)
{
    if (gEGLImageMap2Resources[imageID])
    {
        glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
        gEGLImageMap2Resources[imageID] = 0;
    }
    eglDestroyImage(dpy, image);
}

void DestroyEGLImageKHR(EGLDisplay dpy, EGLImageKHR image, GLuint imageID)
{
    if (gEGLImageMap2Resources[imageID])
    {
        glDeleteTextures(1, &gEGLImageMap2Resources[imageID]);
        gEGLImageMap2Resources[imageID] = 0;
    }
    eglDestroyImageKHR(dpy, image);
}

void CreateEGLSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list, GLuint syncID)
{
    gEGLSyncMap[syncID] = eglCreateSyncKHR(dpy, type, attrib_list);
}

void CreateEGLSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list, GLuint syncID)
{
    gEGLSyncMap[syncID] = eglCreateSync(dpy, type, attrib_list);
}

void CreatePbufferSurface(EGLDisplay dpy,
                          EGLConfig config,
                          const EGLint *attrib_list,
                          GLuint surfaceID)
{
    gSurfaceMap2[surfaceID] = eglCreatePbufferSurface(dpy, config, attrib_list);
}

void CreateNativeClientBufferANDROID(const EGLint *attrib_list, uintptr_t clientBuffer)
{
    gClientBufferMap[clientBuffer] = eglCreateNativeClientBufferANDROID(attrib_list);
}

// The test harness can set specific extensions, but only for the main context
// so enable the same set of extensions for each side-context.
void EnableSideContextExtensions(GLuint contextID)
{
    if (gRequestedExtensions)
    {
        // Change to newly-created side-context
        eglMakeCurrent(NULL, NULL, NULL, gContextMap2[contextID]);
        for (auto &ext : *gRequestedExtensions)
        {
            glRequestExtensionANGLE(ext.c_str());
        }
        // Switch back to main context
        eglMakeCurrent(NULL, NULL, NULL, gContextMap2[gShareContextId]);
    }
}

void CreateContext(GLuint contextID)
{
    EGLContext shareContext = gContextMap2[gShareContextId];
    EGLContext context      = eglCreateContext(nullptr, nullptr, shareContext, nullptr);
    gContextMap2[contextID] = context;

    // Extensions set using --request-extensions must be propagated to side-contexts
    if (gRequestedExtensions)
    {
        EnableSideContextExtensions(contextID);
    }
}

void SetCurrentContextID(GLuint id)
{
    gContextMap2[id] = eglGetCurrentContext();
}

const uint8_t *GetBinaryData(const size_t offset)
{
    return gFrameCaptureBinaryData->getData(offset);
}

void InitializeBinaryDataLoader()
{
    gFrameCaptureBinaryData->initializeBinaryDataLoader();
}

ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEPROC r_eglCreateImage;
ANGLE_REPLAY_EXPORT PFNEGLCREATEIMAGEKHRPROC r_eglCreateImageKHR;
ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEPROC r_eglDestroyImage;
ANGLE_REPLAY_EXPORT PFNEGLDESTROYIMAGEKHRPROC r_eglDestroyImageKHR;
