//
// Copyright 2019 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.
//
// FrameCapture.h:
//   ANGLE Frame capture interface.
//

#ifndef LIBANGLE_FRAME_CAPTURE_H_
#define LIBANGLE_FRAME_CAPTURE_H_

#include <fstream>
#include "common/unsafe_buffers.h"
#include "sys/stat.h"

#include "common/PackedEnums.h"
#include "common/SimpleMutex.h"
#include "common/frame_capture_binary_data.h"
#include "common/frame_capture_utils.h"
#include "common/string_utils.h"
#include "common/system_utils.h"
#include "libANGLE/Context.h"
#include "libANGLE/ShareGroup.h"
#include "libANGLE/Thread.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/entry_points_utils.h"

#ifdef ANGLE_ENABLE_CL
#    include "libANGLE/CLPlatform.h"
#endif

namespace gl
{
enum class GLESEnum;
}  // namespace gl

namespace angle
{
// Helper to use unique IDs for each local data variable.
class DataCounters final : angle::NonCopyable
{
  public:
    DataCounters();
    ~DataCounters();

    int getAndIncrement(EntryPoint entryPoint, const std::string &paramName);
    void reset() { mData.clear(); }

  private:
    // <CallName, ParamName>
    using Counter = std::pair<EntryPoint, std::string>;
    std::map<Counter, int> mData;
};

constexpr int kStringsNotFound = -1;
class StringCounters final : angle::NonCopyable
{
  public:
    StringCounters();
    ~StringCounters();

    int getStringCounter(const std::vector<std::string> &str);
    void setStringCounter(const std::vector<std::string> &str, int &counter);
    void reset() { mStringCounterMap.clear(); }

  private:
    std::map<std::vector<std::string>, int> mStringCounterMap;
};

class DataTracker final : angle::NonCopyable
{
  public:
    DataTracker();
    ~DataTracker();

    DataCounters &getCounters() { return mCounters; }
    StringCounters &getStringCounters() { return mStringCounters; }

    void reset()
    {
        mCounters.reset();
        mStringCounters.reset();
    }

  private:
    DataCounters mCounters;
    StringCounters mStringCounters;
};

enum class CaptureAPI : uint8_t
{
    GL = 0,
    CL = 1,

    InvalidEnum = 2,
    EnumCount   = 2,
};

class ReplayWriter final : angle::NonCopyable
{
  public:
    ReplayWriter();
    ~ReplayWriter();

    void setSourceFileExtension(const char *ext);
    void setSourceFileSizeThreshold(size_t sourceFileSizeThreshold);
    void setFilenamePattern(const std::string &pattern);
    void setSourcePrologue(const std::string &prologue);
    void setHeaderPrologue(const std::string &prologue);

    void addPublicFunction(const std::string &functionProto,
                           const std::stringstream &headerStream,
                           const std::stringstream &bodyStream);
    void addPrivateFunction(const std::string &functionProto,
                            const std::stringstream &headerStream,
                            const std::stringstream &bodyStream);
    std::string getInlineVariableName(EntryPoint entryPoint, const std::string &paramName);

    std::string getInlineStringSetVariableName(EntryPoint entryPoint,
                                               const std::string &paramName,
                                               const std::vector<std::string> &strings,
                                               bool *isNewEntryOut);

    void addStaticVariable(const std::string &customVarType, const std::string &customVarName);

    void saveFrame();
    void saveFrameIfFull();
    void saveIndexFilesAndHeader();
    void saveSetupFile();

    std::vector<std::string> getAndResetWrittenFiles();

    void reset()
    {
        mDataTracker.reset();
        mFrameIndex = 1;  // This is really the FileIndex
    }

    CaptureAPI captureAPI = CaptureAPI::GL;

  private:
    static std::string GetVarName(EntryPoint entryPoint, const std::string &paramName, int counter);

    void saveHeader();
    void writeReplaySource(const std::string &filename);
    void addWrittenFile(const std::string &filename);
    size_t getStoredReplaySourceSize() const;

    std::string mSourceFileExtension;
    size_t mSourceFileSizeThreshold;
    size_t mFrameIndex;

    DataTracker mDataTracker;
    std::string mFilenamePattern;
    std::string mSourcePrologue;
    std::string mHeaderPrologue;

    std::vector<std::string> mReplayHeaders;
    std::vector<std::string> mGlobalVariableDeclarations;
    std::vector<std::string> mStaticVariableDeclarations;

    std::vector<std::string> mPublicFunctionPrototypes;
    std::vector<std::string> mPublicFunctions;

    std::vector<std::string> mPrivateFunctionPrototypes;
    std::vector<std::string> mPrivateFunctions;

    std::vector<std::string> mWrittenFiles;
};

using BufferCalls = std::map<GLuint, std::vector<CallCapture>>;

// true means mapped, false means unmapped
using BufferMapStatusMap = std::map<GLuint, bool>;

using FenceSyncSet   = std::set<gl::SyncID>;
using FenceSyncCalls = std::map<gl::SyncID, std::vector<CallCapture>>;

// For default uniforms, we need to track which ones are dirty, and the series of calls to reset.
// Each program has unique default uniforms, and each uniform has one or more locations in the
// default buffer. For reset efficiency, we track only the uniforms dirty by location, per program.

// A set of all default uniforms (per program) that were modified during the run
using DefaultUniformLocationsSet = std::set<gl::UniformLocation>;
using DefaultUniformLocationsPerProgramMap =
    std::map<gl::ShaderProgramID, DefaultUniformLocationsSet>;

// A map of programs which maps to locations and their reset calls
using DefaultUniformCallsPerLocationMap = std::map<gl::UniformLocation, std::vector<CallCapture>>;
using DefaultUniformCallsPerProgramMap =
    std::map<gl::ShaderProgramID, DefaultUniformCallsPerLocationMap>;

using DefaultUniformBaseLocationMap =
    std::map<std::pair<gl::ShaderProgramID, gl::UniformLocation>, gl::UniformLocation>;

using ResourceSet   = std::set<GLuint>;
using ResourceCalls = std::map<GLuint, std::vector<CallCapture>>;

class TrackedResource final : angle::NonCopyable
{
  public:
    TrackedResource();
    ~TrackedResource();

    const ResourceSet &getStartingResources() const { return mStartingResources; }
    ResourceSet &getStartingResources() { return mStartingResources; }
    const ResourceSet &getNewResources() const { return mNewResources; }
    ResourceSet &getNewResources() { return mNewResources; }
    const ResourceSet &getResourcesToDelete() const { return mResourcesToDelete; }
    ResourceSet &getResourcesToDelete() { return mResourcesToDelete; }
    const ResourceSet &getResourcesToRegen() const { return mResourcesToRegen; }
    ResourceSet &getResourcesToRegen() { return mResourcesToRegen; }
    const ResourceSet &getResourcesToRestore() const { return mResourcesToRestore; }
    ResourceSet &getResourcesToRestore() { return mResourcesToRestore; }

    void setGennedResource(GLuint id);
    void setDeletedResource(GLuint id);
    void setModifiedResource(GLuint id);
    bool resourceIsGenerated(GLuint id);

    ResourceCalls &getResourceRegenCalls() { return mResourceRegenCalls; }
    ResourceCalls &getResourceRestoreCalls() { return mResourceRestoreCalls; }

    void reset()
    {
        mResourceRegenCalls.clear();
        mResourceRestoreCalls.clear();
        mStartingResources.clear();
        mNewResources.clear();
        mResourcesToDelete.clear();
        mResourcesToRegen.clear();
        mResourcesToRestore.clear();
    }

  private:
    // Resource regen calls will gen a resource
    ResourceCalls mResourceRegenCalls;
    // Resource restore calls will restore the contents of a resource
    ResourceCalls mResourceRestoreCalls;

    // Resources created during startup
    ResourceSet mStartingResources;

    // Resources created during the run that need to be deleted
    ResourceSet mNewResources;
    // Resources recreated during the run that need to be deleted
    ResourceSet mResourcesToDelete;
    // Resources deleted during the run that need to be recreated
    ResourceSet mResourcesToRegen;
    // Resources modified during the run that need to be restored
    ResourceSet mResourcesToRestore;
};

using TrackedResourceArray =
    std::array<TrackedResource, static_cast<uint32_t>(ResourceIDType::EnumCount)>;

enum class ShaderProgramType
{
    ShaderType,
    ProgramType
};

// Helper to track resource changes during the capture
class ResourceTracker final : angle::NonCopyable
{
  public:
    ResourceTracker();
    ~ResourceTracker();

    BufferCalls &getBufferMapCalls() { return mBufferMapCalls; }
    BufferCalls &getBufferUnmapCalls() { return mBufferUnmapCalls; }

    std::vector<CallCapture> &getBufferBindingCalls() { return mBufferBindingCalls; }

    void setBufferMapped(gl::ContextID contextID, GLuint id);
    void setBufferUnmapped(gl::ContextID contextID, GLuint id);

    bool getStartingBuffersMappedCurrent(GLuint id) const;
    bool getStartingBuffersMappedInitial(GLuint id) const;

    void setStartingBufferMapped(GLuint id, bool mapped)
    {
        // Track the current state (which will change throughout the trace)
        mStartingBuffersMappedCurrent[id] = mapped;

        // And the initial state, to compare during frame loop reset
        mStartingBuffersMappedInitial[id] = mapped;
    }

    void onShaderProgramAccess(gl::ShaderProgramID shaderProgramID);
    uint32_t getMaxShaderPrograms() const { return mMaxShaderPrograms; }

    FenceSyncSet &getStartingFenceSyncs() { return mStartingFenceSyncs; }
    FenceSyncCalls &getFenceSyncRegenCalls() { return mFenceSyncRegenCalls; }
    FenceSyncSet &getFenceSyncsToRegen() { return mFenceSyncsToRegen; }
    void setDeletedFenceSync(gl::SyncID sync);

    DefaultUniformLocationsPerProgramMap &getDefaultUniformsToReset()
    {
        return mDefaultUniformsToReset;
    }
    DefaultUniformCallsPerLocationMap &getDefaultUniformResetCalls(gl::ShaderProgramID id)
    {
        return mDefaultUniformResetCalls[id];
    }
    void setModifiedDefaultUniform(gl::ShaderProgramID programID, gl::UniformLocation location);
    void setDefaultUniformBaseLocation(gl::ShaderProgramID programID,
                                       gl::UniformLocation location,
                                       gl::UniformLocation baseLocation);
    gl::UniformLocation getDefaultUniformBaseLocation(gl::ShaderProgramID programID,
                                                      gl::UniformLocation location)
    {
        ASSERT(mDefaultUniformBaseLocations.find({programID, location}) !=
               mDefaultUniformBaseLocations.end());
        return mDefaultUniformBaseLocations[{programID, location}];
    }

    TrackedResource &getTrackedResource(gl::ContextID contextID, ResourceIDType type);

    void getContextIDs(std::set<gl::ContextID> &idsOut);

    std::map<EGLImage, egl::AttributeMap> &getImageToAttribTable() { return mMatchImageToAttribs; }

    std::map<GLuint, egl::ImageID> &getTextureIDToImageTable() { return mMatchTextureIDToImage; }

    std::map<egl::ImageID, std::vector<uint8_t>> &getImageDataMap() { return mImageDataMap; }

    std::map<gl::ContextID, std::set<GLuint>> &getExternalImageBindingsToRestore()
    {
        return mExternalImageBindingsToRestore;
    }

    void setShaderProgramType(gl::ShaderProgramID id, angle::ShaderProgramType type)
    {
        mShaderProgramType[id] = type;
    }
    ShaderProgramType getShaderProgramType(gl::ShaderProgramID id)
    {
        ASSERT(mShaderProgramType.find(id) != mShaderProgramType.end());
        return mShaderProgramType[id];
    }

    void resetTrackedResourceArray(TrackedResourceArray &trackedResourceArray)
    {
        for (auto &trackedResource : trackedResourceArray)
        {
            trackedResource.reset();
        }
    }

    // Some data in FrameCaptureShared tracks resources across all captures while
    // other data is tracked per-capture. This function is responsible for
    // resetting the per-capture tracking data in this class.
    void resetResourceTracking()
    {
        resetTrackedResourceArray(mTrackedResourcesShared);
        for (auto &pair : mTrackedResourcesPerContext)
        {
            resetTrackedResourceArray(pair.second);
        }

        mBufferMapCalls.clear();
        mBufferUnmapCalls.clear();
        mBufferBindingCalls.clear();
        mStartingBuffersMappedInitial.clear();
        mStartingBuffersMappedCurrent.clear();
        mStartingFenceSyncs.clear();
        mFenceSyncRegenCalls.clear();
        mFenceSyncsToRegen.clear();
        mDefaultUniformsToReset.clear();
        mDefaultUniformResetCalls.clear();
        mDefaultUniformBaseLocations.clear();
        mImageDataMap.clear();
        mExternalImageBindingsToRestore.clear();
    }

  private:
    // These data structures are per-capture and must be reset before beginning a new
    // capture in the resetResourceTracking() function above

    // Buffer map calls will map a buffer with correct offset, length, and access flags
    BufferCalls mBufferMapCalls;
    // Buffer unmap calls will bind and unmap a given buffer
    BufferCalls mBufferUnmapCalls;
    // Buffer binding calls to restore bindings recorded during MEC
    std::vector<CallCapture> mBufferBindingCalls;
    // Whether a given buffer was mapped at the start of the trace
    BufferMapStatusMap mStartingBuffersMappedInitial;
    // The status of buffer mapping throughout the trace, modified with each Map/Unmap call
    BufferMapStatusMap mStartingBuffersMappedCurrent;
    // Maximum accessed shader program ID.
    uint32_t mMaxShaderPrograms = 0;
    // Fence sync objects created during MEC setup
    FenceSyncSet mStartingFenceSyncs;
    // Fence sync regen calls will create a fence sync objects
    FenceSyncCalls mFenceSyncRegenCalls;
    // Fence syncs to regen are a list of starting fence sync objects that were deleted and need to
    // be regen'ed.
    FenceSyncSet mFenceSyncsToRegen;
    // Default uniforms that were modified during the run
    DefaultUniformLocationsPerProgramMap mDefaultUniformsToReset;
    // Calls per default uniform to return to original state
    DefaultUniformCallsPerProgramMap mDefaultUniformResetCalls;
    // Base location of arrayed uniforms
    DefaultUniformBaseLocationMap mDefaultUniformBaseLocations;

    // These data structures must be preserved across all captures

    // Tracked resources per context
    TrackedResourceArray mTrackedResourcesShared;
    std::map<gl::ContextID, TrackedResourceArray> mTrackedResourcesPerContext;
    std::map<EGLImage, egl::AttributeMap> mMatchImageToAttribs;
    std::map<GLuint, egl::ImageID> mMatchTextureIDToImage;
    std::map<egl::ImageID, std::vector<uint8_t>> mImageDataMap;
    std::map<gl::ContextID, std::set<GLuint>> mExternalImageBindingsToRestore;
    std::map<gl::ShaderProgramID, ShaderProgramType> mShaderProgramType;
};

// CL specific resource tracker to track resource changes during the capture
#ifdef ANGLE_ENABLE_CL
struct ResourceTrackerCL final : angle::NonCopyable
{
    ResourceTrackerCL();
    ~ResourceTrackerCL();

    // To obtain indices of CL arguments in replay
    std::unordered_map<cl_platform_id, size_t> mCLPlatformIDIndices;
    std::unordered_map<cl_device_id, size_t> mCLDeviceIDIndices;
    std::unordered_map<cl_context, size_t> mCLContextIndices;
    std::unordered_map<cl_event, size_t> mCLEventsIndices;
    std::unordered_map<cl_command_queue, size_t> mCLCommandQueueIndices;
    std::unordered_map<cl_mem, size_t> mCLMemIndices;
    std::unordered_map<cl_sampler, size_t> mCLSamplerIndices;
    std::unordered_map<cl_program, size_t> mCLProgramIndices;
    std::unordered_map<cl_kernel, size_t> mCLKernelIndices;

    std::unordered_map<const void *, size_t> mCLVoidIndices;

    std::unordered_map<uint32_t, std::vector<size_t>> mCLParamIDToIndexVector;

    // To account for cl mem or SVM pointers that are potentially dirty
    // coming into the starting frame or from mapping and unmapping.
    std::vector<cl_mem> mCLDirtyMem;
    std::vector<void *> mCLDirtySVM;

    // Keeps track of the # of times the program is linked, including it's own creation
    std::unordered_map<cl_program, cl_uint> mCLProgramLinkCounter;

    // To keep track of the sub buffer and parent replationship
    std::unordered_map<cl_mem, cl_mem> mCLSubBufferToParent;

    // To keep track of the linked programs
    std::unordered_map<cl_program, std::vector<cl_program>> mCLLinkedPrograms;

    // Program to all the kernels in the program
    // So that when a program is released, it can also remove all the kernels.
    std::unordered_map<cl_program, std::vector<cl_kernel>> mCLProgramToKernels;

    // Kernel to program, to keep track of the program that a cloned kernel
    // belongs to. Can't use ANGLE's getProgram() because the kernel object
    // may be deleted by the time it's needed for capture.
    std::unordered_map<cl_kernel, cl_program> mCLKernelToProgram;

    // Mapped pointer to the map call
    std::unordered_map<const void *, CallCapture> mCLMapCall;

    // Gets the size of the SVM memory
    std::unordered_map<const void *, size_t> SVMToSize;

    cl_command_queue mCLCurrentCommandQueue;

    std::vector<ParamCapture> mCLResetObjs;
};
#endif

// Used by the CPP replay to filter out unnecessary code.
using HasResourceTypeMap = angle::PackedEnumBitSet<ResourceIDType>;

// Map of ResourceType to IDs and range of setup calls
using ResourceIDToSetupCallsMap =
    PackedEnumMap<ResourceIDType, std::map<GLuint, gl::Range<size_t>>>;

// Map of buffer ID to offset and size used when mapped
using BufferDataMap = std::map<gl::BufferID, std::pair<GLintptr, GLsizeiptr>>;

// A dictionary of sources indexed by shader type.
using ProgramSources = gl::ShaderMap<std::string>;

// Maps from IDs to sources.
using ShaderSourceMap  = std::map<gl::ShaderProgramID, std::string>;
using ProgramSourceMap = std::map<gl::ShaderProgramID, ProgramSources>;

// Map from textureID to level and data
using TextureLevels       = std::map<GLint, std::vector<uint8_t>>;
using TextureLevelDataMap = std::map<gl::TextureID, TextureLevels>;

struct SurfaceParams
{
    gl::Extents extents;
    egl::ColorSpace colorSpace;
};

// Map from ContextID to SurfaceParams
using SurfaceParamsMap = std::map<gl::ContextID, SurfaceParams>;

using CallVector = std::vector<std::vector<CallCapture> *>;

// A map from API entry point to calls
using CallResetMap = std::map<angle::EntryPoint, std::vector<CallCapture>>;

using TextureBinding  = std::pair<size_t, gl::TextureType>;
using TextureResetMap = std::map<TextureBinding, gl::TextureID>;

using BufferBindingPair = std::pair<gl::BufferBinding, gl::BufferID>;

// StateResetHelper provides a simple way to track whether an entry point has been called during the
// trace, along with the reset calls to get it back to starting state.  This is useful for things
// that are one dimensional, like context bindings or context state.
class StateResetHelper final : angle::NonCopyable
{
  public:
    StateResetHelper();
    ~StateResetHelper();

    const std::set<angle::EntryPoint> &getDirtyEntryPoints() const { return mDirtyEntryPoints; }
    void setEntryPointDirty(EntryPoint entryPoint) { mDirtyEntryPoints.insert(entryPoint); }

    CallResetMap &getResetCalls() { return mResetCalls; }
    const CallResetMap &getResetCalls() const { return mResetCalls; }

    void setDefaultResetCalls(const gl::Context *context, angle::EntryPoint);

    const std::set<TextureBinding> &getDirtyTextureBindings() const
    {
        return mDirtyTextureBindings;
    }
    void setTextureBindingDirty(size_t unit, gl::TextureType target)
    {
        mDirtyTextureBindings.emplace(unit, target);
    }

    TextureResetMap &getResetTextureBindings() { return mResetTextureBindings; }

    void setResetActiveTexture(size_t textureID) { mResetActiveTexture = textureID; }
    size_t getResetActiveTexture() { return mResetActiveTexture; }

    const std::set<gl::BufferBinding> &getDirtyBufferBindings() const
    {
        return mDirtyBufferBindings;
    }
    void setBufferBindingDirty(gl::BufferBinding binding) { mDirtyBufferBindings.insert(binding); }

    const std::set<BufferBindingPair> &getStartingBufferBindings() const
    {
        return mStartingBufferBindings;
    }
    void setStartingBufferBinding(gl::BufferBinding binding, gl::BufferID bufferID)
    {
        mStartingBufferBindings.insert({binding, bufferID});
    }

    void reset()
    {
        mDirtyEntryPoints.clear();
        mResetCalls.clear();
        mDirtyTextureBindings.clear();
        mResetTextureBindings.clear();
        mResetActiveTexture = 0;
        mStartingBufferBindings.clear();
        mDirtyBufferBindings.clear();
    }

  private:
    // Dirty state per entry point
    std::set<angle::EntryPoint> mDirtyEntryPoints;

    // Reset calls per API entry point
    CallResetMap mResetCalls;

    // Dirty state per texture binding
    std::set<TextureBinding> mDirtyTextureBindings;

    // Texture bindings and active texture to restore
    TextureResetMap mResetTextureBindings;
    size_t mResetActiveTexture = 0;

    // Starting and dirty buffer bindings
    std::set<BufferBindingPair> mStartingBufferBindings;
    std::set<gl::BufferBinding> mDirtyBufferBindings;
};

class FrameCapture final : angle::NonCopyable
{
  public:
    FrameCapture();
    ~FrameCapture();

    std::vector<CallCapture> &getSetupCalls() { return mSetupCalls; }
    void clearSetupCalls() { mSetupCalls.clear(); }

    StateResetHelper &getStateResetHelper() { return mStateResetHelper; }

    void reset();

  private:
    std::vector<CallCapture> mSetupCalls;

    StateResetHelper mStateResetHelper;
};

// Page range inside a coherent buffer
struct PageRange
{
    PageRange(size_t start, size_t end);
    ~PageRange();

    // Relative start page
    size_t start;

    // First page after the relative end
    size_t end;
};

// Memory address range defined by start and size
struct AddressRange
{
    AddressRange();
    AddressRange(uintptr_t start, size_t size);
    ~AddressRange();

    uintptr_t end();

    uintptr_t start;
    size_t size;
};

// Used to handle protection of buffers that overlap in pages.
enum class PageSharingType
{
    NoneShared,
    FirstShared,
    LastShared,
    FirstAndLastShared
};

class CoherentBuffer
{
  public:
    CoherentBuffer(uintptr_t start, size_t size, size_t pageSize, bool useShadowMemory);
    ~CoherentBuffer();

    // Sets the a range in the buffer clean and protects a selected range
    void protectPageRange(const PageRange &pageRange);

    // Sets all pages to clean and enables protection
    void protectAll();

    // Sets a page dirty state and sets it's protection
    void setDirty(size_t relativePage, bool dirty);

    // Shadow memory synchronization
    void updateBufferMemory();
    void updateShadowMemory();

    // Removes protection
    void removeProtection(PageSharingType sharingType);

    bool contains(size_t page, size_t *relativePage);
    bool isDirty();

    // Returns dirty page ranges
    std::vector<PageRange> getDirtyPageRanges();

    // Calculates address range from page range
    AddressRange getDirtyAddressRange(const PageRange &dirtyPageRange);
    AddressRange getRange();

    void markShadowDirty() { mShadowDirty = true; }
    bool isShadowDirty() { return mShadowDirty; }

  private:
    // Actual buffer start and size
    AddressRange mRange;

    // Start and size of page aligned protected area
    AddressRange mProtectionRange;

    // Start and end of protection in relative pages, calculated from mProtectionRange.
    size_t mProtectionStartPage;
    size_t mProtectionEndPage;

    size_t mPageCount;
    size_t mPageSize;

    // Clean pages are protected
    std::vector<bool> mDirtyPages;

    // shadow memory releated fields
    bool mShadowMemoryEnabled;
    uintptr_t mBufferStart;
    void *mShadowMemory;
    bool mShadowDirty;
};

class CoherentBufferTracker final : angle::NonCopyable
{
  public:
    CoherentBufferTracker();
    ~CoherentBufferTracker();

    bool isDirty(gl::BufferID id);
    uintptr_t addBuffer(gl::BufferID id, uintptr_t start, size_t size);
    void removeBuffer(gl::BufferID id);
    void disable();
    void enable();
    void onEndFrame();
    bool haveBuffer(gl::BufferID id);
    bool isShadowMemoryEnabled() { return mShadowMemoryEnabled; }
    void enableShadowMemory() { mShadowMemoryEnabled = true; }
    void maybeUpdateShadowMemory();
    void markAllShadowDirty();
    // Determine whether memory protection can be used directly on graphics memory
    bool canProtectDirectly(gl::Context *context);

  private:
    // Detect overlapping pages when removing protection
    PageSharingType doesBufferSharePage(gl::BufferID id);

    // Returns a map to found buffers and the corresponding pages for a given address.
    // For addresses that are in a page shared by 2 buffers, 2 results are returned.
    HashMap<std::shared_ptr<CoherentBuffer>, size_t> getBufferPagesForAddress(uintptr_t address);
    PageFaultHandlerRangeType handleWrite(uintptr_t address);

  public:
    angle::SimpleMutex mMutex;
    HashMap<GLuint, std::shared_ptr<CoherentBuffer>> mBuffers;
    bool hasBeenReset() { return mHasBeenReset; }

  private:
    bool mEnabled;
    bool mHasBeenReset;
    std::unique_ptr<PageFaultHandler> mPageFaultHandler;
    size_t mPageSize;

    bool mShadowMemoryEnabled;
};

// Shared class for any items that need to be tracked by FrameCapture across shared contexts
class FrameCaptureShared final : angle::NonCopyable
{
  public:
    FrameCaptureShared();
    ~FrameCaptureShared();

    void captureCall(gl::Context *context, CallCapture &&call, bool isCallValid);
    void checkForCaptureTrigger();
    bool checkForCaptureEnd();
    void onEndFrame(gl::Context *context);
    void onDestroyContext(const gl::Context *context);
    bool onEndCLCapture();
    void onMakeCurrent(const gl::Context *context,
                       const egl::Surface *drawSurface,
                       EGLint surfaceWidth,
                       EGLint surfaceHeight);
    bool enabled() const { return mEnabled; }

    bool isCapturing() const;
    uint32_t getFrameCount() const;

    // Returns a frame index starting from "1" as the first frame.
    uint32_t getReplayFrameIndex() const;

#ifdef ANGLE_ENABLE_CL
    void captureCLCall(CallCapture &&call, bool isCallValid);
    static void onCLProgramEnd();

    template <typename T>
    size_t getIndex(const T *object)
    {
        if (getMap<T>().find(*object) == getMap<T>().end())
        {
            return SIZE_MAX;
        }
        return getMap<T>()[*object];
    }
    size_t getCLVoidIndex(const void *v);
    std::vector<size_t> getCLObjVector(const angle::ParamCapture *paramCaptureKey);

    template <typename T>
    void setIndex(const T *object)
    {
        if (getMap<T>().find(*object) == getMap<T>().end())
        {
            size_t tempSize      = getMap<T>().size();
            getMap<T>()[*object] = tempSize;
        }
    }
    void setCLPlatformIndices(cl_platform_id *platforms, size_t numPlatforms);
    void setCLDeviceIndices(cl_device_id *devices, size_t numDevices);
    void setCLVoidIndex(const void *v);
    void setOffsetsVector(const void *args,
                          const void **argsLocations,
                          size_t numLocations,
                          const angle::ParamCapture *paramCaptureKey);
    void setCLVoidVectorIndex(const void *pointers[],
                              size_t numPointers,
                              const angle::ParamCapture *paramCaptureKey);

    template <typename T>
    using MemberFuncPtr = size_t (FrameCaptureShared::*)(const T *);

    template <typename T>
    void setCLObjVectorMap(const T *objs,
                           size_t numObjs,
                           const angle::ParamCapture *paramCaptureKey,
                           MemberFuncPtr<const T> getCLObjIndexFunc)
    {
        mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID] =
            std::vector<size_t>();
        for (size_t i = 0; i < numObjs; ++i)
        {
            mResourceTrackerCL.mCLParamIDToIndexVector[paramCaptureKey->uniqueID].push_back(
                (this->*getCLObjIndexFunc)(&ANGLE_UNSAFE_TODO(objs[i])));
        }
    }

    template <typename T>
    std::unordered_map<T, size_t> &getMap();

    void addCLResetObj(const angle::ParamCapture &param);
    void removeCLResetObj(const ParamCapture &param);
    void printCLResetObjs(std::stringstream &stream);

    void trackCLMemUpdate(const cl_mem *mem, bool created);
    void trackCLProgramUpdate(const cl_program *program,
                              bool referenced,
                              cl_uint numLinkedPrograms,
                              const cl_program *linkedPrograms);
    void trackCLEvents(const cl_event *event, bool created);
    void injectMemcpy(void *src, void *dest, size_t size, std::vector<CallCapture> *calls);
    void captureUpdateCLObjs(std::vector<CallCapture> *calls);
    void removeCLMemOccurrences(const cl_mem *mem, std::vector<CallCapture> *calls);
    void removeCLKernelOccurrences(const cl_kernel *kernel, std::vector<CallCapture> *calls);
    void removeCLProgramOccurrences(const cl_program *program, std::vector<CallCapture> *calls);
    void removeCLCall(std::vector<CallCapture> *callVector, size_t &callIndex);
#endif

    void trackBufferMapping(const gl::Context *context,
                            CallCapture *call,
                            gl::BufferID id,
                            gl::Buffer *buffer,
                            GLintptr offset,
                            GLsizeiptr length,
                            bool writable,
                            bool coherent,
                            bool persistent);

    void trackTextureUpdate(const gl::Context *context, const CallCapture &call);
    void trackFramebufferAttachmentUpdate(const gl::Context *context, const CallCapture &call);
    void trackImageUpdate(const gl::Context *context, const CallCapture &call);
    void trackDefaultUniformUpdate(const gl::Context *context, const CallCapture &call);
    void trackVertexArrayUpdate(const gl::Context *context, const CallCapture &call);

    const std::string &getShaderSource(gl::ShaderProgramID id) const;
    void setShaderSource(gl::ShaderProgramID id, std::string sources);

    const ProgramSources &getProgramSources(gl::ShaderProgramID id) const;
    void setProgramSources(gl::ShaderProgramID id, ProgramSources sources);

    // Load data from a previously stored texture level
    const std::vector<uint8_t> &retrieveCachedTextureLevel(gl::TextureID id,
                                                           gl::TextureTarget target,
                                                           GLint level);

    // Create new texture level data and copy the source into it
    void copyCachedTextureLevel(const gl::Context *context,
                                gl::TextureID srcID,
                                GLint srcLevel,
                                gl::TextureID dstID,
                                GLint dstLevel,
                                const CallCapture &call);

    // Create the location that should be used to cache texture level data
    std::vector<uint8_t> &getCachedTextureLevelData(gl::Texture *texture,
                                                    gl::TextureTarget target,
                                                    GLint level,
                                                    EntryPoint entryPoint);

    // Capture coherent buffer storages
    void captureCoherentBufferSnapshot(const gl::Context *context, gl::BufferID bufferID);

    // Remove any cached texture levels on deletion
    void deleteCachedTextureLevelData(gl::TextureID id);

    void eraseBufferDataMapEntry(const gl::BufferID bufferId)
    {
        const auto &bufferDataInfo = mBufferDataMap.find(bufferId);
        if (bufferDataInfo != mBufferDataMap.end())
        {
            mBufferDataMap.erase(bufferDataInfo);
        }
    }

    bool hasBufferData(gl::BufferID bufferID)
    {
        const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
        if (bufferDataInfo != mBufferDataMap.end())
        {
            return true;
        }
        return false;
    }

    std::pair<GLintptr, GLsizeiptr> getBufferDataOffsetAndLength(gl::BufferID bufferID)
    {
        const auto &bufferDataInfo = mBufferDataMap.find(bufferID);
        ASSERT(bufferDataInfo != mBufferDataMap.end());
        return bufferDataInfo->second;
    }

    void setCaptureActive() { mCaptureActive = true; }
    void setCaptureInactive() { mCaptureActive = false; }
    bool isCaptureActive() { return mCaptureActive; }
    bool usesMidExecutionCapture() { return mCaptureStartFrame > 1; }

    gl::ContextID getWindowSurfaceContextID() const { return mWindowSurfaceContextID; }

    void markResourceSetupCallsInactive(std::vector<CallCapture> *setupCalls,
                                        ResourceIDType type,
                                        GLuint id,
                                        gl::Range<size_t> range);

    void getOutputDirectory();
    void updateReadBufferSize(size_t readBufferSize)
    {
        mReadBufferSize = std::max(mReadBufferSize, readBufferSize);
    }

    template <typename ResourceType>
    void handleGennedResource(const gl::Context *context, ResourceType resourceID)
    {
        if (isCaptureActive())
        {
            ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
            TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
            tracker.setGennedResource(resourceID.value);
        }
    }

    template <typename ResourceType>
    bool resourceIsGenerated(const gl::Context *context, ResourceType resourceID)
    {
        ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
        TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
        return tracker.resourceIsGenerated(resourceID.value);
    }

    template <typename ResourceType>
    void handleDeletedResource(const gl::Context *context, ResourceType resourceID)
    {
        if (isCaptureActive())
        {
            ResourceIDType idType    = GetResourceIDTypeFromType<ResourceType>::IDType;
            TrackedResource &tracker = mResourceTracker.getTrackedResource(context->id(), idType);
            tracker.setDeletedResource(resourceID.value);
        }
    }

    void *maybeGetShadowMemoryPointer(gl::Buffer *buffer, GLsizeiptr length, GLbitfield access);
    void determineMemoryProtectionSupport(gl::Context *context);

    angle::SimpleMutex &getFrameCaptureMutex() { return mFrameCaptureMutex; }

    void markGLSyncEmitted(gl::SyncID syncID) { mEmittedGLSyncIDs.insert(syncID.value); }
    void markEGLSyncEmitted(egl::SyncID syncID) { mEmittedEGLSyncIDs.insert(syncID.value); }
    bool isGLSyncEmitted(gl::SyncID syncID) const
    {
        return mEmittedGLSyncIDs.find(syncID.value) != mEmittedGLSyncIDs.end();
    }
    bool isEGLSyncEmitted(egl::SyncID syncID) const
    {
        return mEmittedEGLSyncIDs.find(syncID.value) != mEmittedEGLSyncIDs.end();
    }

    void setDeferredLinkProgram(gl::ShaderProgramID programID)
    {
        mDeferredLinkPrograms.emplace(programID);
    }
    bool isDeferredLinkProgram(gl::ShaderProgramID programID)
    {
        return (mDeferredLinkPrograms.find(programID) != mDeferredLinkPrograms.end());
    }

    static bool isRuntimeEnabled();

    void resetCaptureStartEndFrames()
    {
        // If the trigger has been populated the frame range variables will be calculated
        // based on the trigger value, so for now reset them to unreasonable values.
        mCaptureStartFrame = mCaptureEndFrame = std::numeric_limits<uint32_t>::max();
        INFO() << "Capture trigger detected, resetting capture start/end frame.";
    }

    void initalizeTraceStorage();

  private:
    void writeJSON(const gl::Context *context);
    void writeJSONCL();
    void writeJSONCLGetInfo();
    void saveCLGetInfo(const CallCapture &call);
    void writeCppReplayIndexFiles(const gl::Context *context, bool writeResetContextCall);
    void writeCppReplayIndexFilesCL();
    void writeMainContextCppReplay(const gl::Context *context,
                                   const std::vector<CallCapture> &setupCalls,
                                   StateResetHelper &StateResetHelper);
    void writeMainContextCppReplayCL();

    void captureClientArraySnapshot(const gl::Context *context,
                                    size_t vertexCount,
                                    size_t instanceCount);
    void captureMappedBufferSnapshot(const gl::Context *context, const CallCapture &call);

    void copyCompressedTextureData(const gl::Context *context, const CallCapture &call);
    void captureCompressedTextureData(const gl::Context *context, const CallCapture &call);

    void reset();
    void resetMidExecutionCapture(gl::Context *context);
    void maybeSetSyncPoint(CallCapture &inCall);
    void maybeOverrideEntryPoint(const gl::Context *context,
                                 CallCapture &call,
                                 std::vector<CallCapture> &newCalls);
    void maybeCapturePreCallUpdates(const gl::Context *context,
                                    CallCapture &call,
                                    std::vector<CallCapture> *shareGroupSetupCalls,
                                    ResourceIDToSetupCallsMap *resourceIDToSetupCalls);
    void maybeCapturePreCallUpdatesCL(CallCapture &call);
    template <typename ParamValueType>
    void maybeGenResourceOnBind(const gl::Context *context, CallCapture &call);
    void maybeCapturePostCallUpdates(const gl::Context *context);
    void maybeCapturePostCallUpdatesCL();
    void maybeCaptureDrawArraysClientData(const gl::Context *context,
                                          CallCapture &call,
                                          size_t instanceCount);
    void maybeCaptureDrawElementsClientData(const gl::Context *context,
                                            CallCapture &call,
                                            size_t instanceCount);
    void maybeCaptureCoherentBuffers(const gl::Context *context);
    void captureCustomMapBufferFromContext(const gl::Context *context,
                                           const char *entryPointName,
                                           CallCapture &call,
                                           std::vector<CallCapture> &callsOut);
    void updateCopyImageSubData(CallCapture &call);
    void overrideProgramBinary(const gl::Context *context,
                               CallCapture &call,
                               std::vector<CallCapture> &outCalls);
    void updateResourceCountsFromParamCapture(const ParamCapture &param, ResourceIDType idType);
    void updateResourceCountsFromParamCaptureCL(const ParamCapture &param, const CallCapture &call);
    void updateResourceCountsFromCallCapture(const CallCapture &call);
    void updateResourceCountsFromCallCaptureCL(const CallCapture &call);

    void runMidExecutionCapture(gl::Context *context);

    void scanSetupCalls(std::vector<CallCapture> &setupCalls);

    std::vector<CallCapture> mFrameCalls;
    std::vector<size_t> mClientVertexArrayCallIndices;
    gl::AttributesMask mClientVertexArrayDirtyAttribMask;

    // We save one large buffer of binary data for the whole CPP replay.
    // This simplifies a lot of file management.
    FrameCaptureBinaryData mBinaryData;
    BinaryFileIndexInfo mIndexInfo;

    bool mEnabled;
    static bool mRuntimeEnabled;
    static bool mRuntimeInitialized;
    bool mSerializeStateEnabled;
    std::string mOutDirectory;
    std::string mCaptureLabel;
    bool mCompression;
    gl::AttribArray<const void *> mClientVertexArrayData;
    uint32_t mFrameIndex;
    uint32_t mCaptureStartFrame;
    uint32_t mCaptureEndFrame;
    bool mIsFirstFrame   = true;
    bool mWroteIndexFile = false;
    SurfaceParamsMap mDrawSurfaceParams;
    gl::AttribArray<size_t> mClientArraySizes;
    size_t mReadBufferSize;
    size_t mResourceIDBufferSize;
    HasResourceTypeMap mHasResourceType;
    ResourceIDToSetupCallsMap mResourceIDToSetupCalls;
    BufferDataMap mBufferDataMap;
    bool mValidateSerializedState = false;
    std::string mValidationExpression;
    PackedEnumMap<ResourceIDType, uint32_t> mMaxAccessedResourceIDs;
    std::map<ParamType, uint32_t> mMaxCLParamsSize;
    CoherentBufferTracker mCoherentBufferTracker;
    angle::SimpleMutex mFrameCaptureMutex;
    bool mCallCaptured           = false;
    bool mStartFrameCallCaptured = false;

    // Track Sync IDs emitted in the trace to allow skipping of external sync objects
    // to prevent corrupttion of Sync state tracking
    std::unordered_set<GLuint> mEmittedGLSyncIDs;
    std::unordered_set<GLuint> mEmittedEGLSyncIDs;

    // When true, it removes unnecessary calls going into
    // replay files that occur before mCaptureStartFrame
    bool removeUnneededOpenCLCalls = false;

#ifdef ANGLE_ENABLE_CL
    // OpenCL calls considered as "frames"
    std::unordered_set<EntryPoint> mCLEndFrameCalls = {EntryPoint::CLEnqueueNDRangeKernel,
                                                       EntryPoint::CLEnqueueNativeKernel,
                                                       EntryPoint::CLEnqueueTask};

    // "Optional" OpenCL calls not important for Capture/Replay
    std::unordered_set<EntryPoint> mCLOptionalCalls = {EntryPoint::CLGetPlatformInfo,
                                                       EntryPoint::CLGetDeviceInfo,
                                                       EntryPoint::CLGetContextInfo,
                                                       EntryPoint::CLGetCommandQueueInfo,
                                                       EntryPoint::CLGetProgramInfo,
                                                       EntryPoint::CLGetProgramBuildInfo,
                                                       EntryPoint::CLGetKernelInfo,
                                                       EntryPoint::CLGetKernelArgInfo,
                                                       EntryPoint::CLGetKernelWorkGroupInfo,
                                                       EntryPoint::CLGetEventInfo,
                                                       EntryPoint::CLGetEventProfilingInfo,
                                                       EntryPoint::CLGetMemObjectInfo,
                                                       EntryPoint::CLGetImageInfo,
                                                       EntryPoint::CLGetSamplerInfo,
                                                       EntryPoint::CLGetSupportedImageFormats};
    std::string mCLInfoJson;
    std::vector<std::string> mExtFuncsAdded;

    std::vector<CallCapture> mCLSetupCalls;

    ResourceTrackerCL mResourceTrackerCL;
#endif

    ResourceTracker mResourceTracker;
    ReplayWriter mReplayWriter;

    // If you don't know which frame you want to start capturing at, use the capture trigger.
    // Initialize it to the number of frames you want to capture, and then clear the value to 0 when
    // you reach the content you want to capture. Currently only available on Android.
    uint32_t mCaptureTrigger;

    // If you want to finish capture early, use the end_capture utility.
    uint32_t mEndCapture;

    bool mCaptureActive;
    std::vector<uint32_t> mActiveFrameIndices;

    // Cache most recently compiled and linked sources.
    ShaderSourceMap mCachedShaderSource;
    ProgramSourceMap mCachedProgramSources;

    // Set of programs which were created but not linked before capture was started
    std::set<gl::ShaderProgramID> mDeferredLinkPrograms;

    gl::ContextID mWindowSurfaceContextID;

    std::vector<CallCapture> mShareGroupSetupCalls;
    // Track which Contexts were created and made current at least once before MEC,
    // requiring setup for replay
    std::unordered_set<GLuint> mActiveContexts;

    // Invalid call counts per entry point while capture is active and inactive.
    std::unordered_map<EntryPoint, size_t> mInvalidCallCountsActive;
    std::unordered_map<EntryPoint, size_t> mInvalidCallCountsInactive;
};

template <typename CaptureFuncT, typename... ArgsT>
void CaptureGLCallToFrameCapture(CaptureFuncT captureFunc,
                                 bool isCallValid,
                                 gl::Context *context,
                                 ArgsT... captureParams)
{
    if (!FrameCaptureShared::isRuntimeEnabled())
    {
        // Return immediately to reduce overhead of compile-time flag
        return;
    }
    FrameCaptureShared *frameCaptureShared = context->getShareGroup()->getFrameCaptureShared();

    // EGL calls are protected by the global context mutex but only a subset of GL calls
    // are so protected. Ensure FrameCaptureShared access thread safety by using a
    // frame-capture only mutex.
    std::lock_guard<angle::SimpleMutex> lock(frameCaptureShared->getFrameCaptureMutex());

    if (!frameCaptureShared->isCapturing())
    {
        return;
    }

    CallCapture call = captureFunc(context->getState(), isCallValid, captureParams...);
    frameCaptureShared->captureCall(context, std::move(call), isCallValid);
}

template <typename FirstT, typename... OthersT>
egl::Display *GetEGLDisplayArg(FirstT display, OthersT... others)
{
    if constexpr (std::is_same<egl::Display *, FirstT>::value)
    {
        return display;
    }
    return nullptr;
}

template <typename CaptureFuncT, typename... ArgsT>
void CaptureEGLCallToFrameCapture(CaptureFuncT captureFunc,
                                  bool isCallValid,
                                  egl::Thread *thread,
                                  ArgsT... captureParams)
{
    if (!FrameCaptureShared::isRuntimeEnabled())
    {
        // Return immediately to reduce overhead of compile-time flag
        return;
    }
    gl::Context *context = thread->getContext();
    if (!context)
    {
        // Get a valid context from the display argument if no context is associated with this
        // thread
        egl::Display *display = GetEGLDisplayArg(captureParams...);
        if (display)
        {
            for (const auto &contextIter : display->getState().contextMap)
            {
                context = contextIter.second;
                break;
            }
        }
        if (!context)
        {
            return;
        }
    }
    std::lock_guard<egl::ContextMutex> lock(context->getContextMutex());

    angle::FrameCaptureShared *frameCaptureShared =
        context->getShareGroup()->getFrameCaptureShared();
    if (!frameCaptureShared->isCapturing())
    {
        return;
    }

    angle::CallCapture call = captureFunc(thread, isCallValid, captureParams...);
    frameCaptureShared->captureCall(context, std::move(call), true);
}

#ifdef ANGLE_ENABLE_CL
template <typename CaptureFuncT, typename... ArgsT>
void CaptureCLCallToFrameCapture(CaptureFuncT captureFunc, bool isCallValid, ArgsT... captureParams)
{
    if (!FrameCaptureShared::isRuntimeEnabled())
    {
        // Return immediately to reduce overhead of compile-time flag
        return;
    }
    angle::FrameCaptureShared *frameCaptureShared =
        cl::Platform::GetDefault()->getFrameCaptureShared();
    std::lock_guard<angle::SimpleMutex> lock(frameCaptureShared->getFrameCaptureMutex());
    if (!frameCaptureShared || !frameCaptureShared->isCapturing())
    {
        return;
    }
    angle::CallCapture call = captureFunc(isCallValid, captureParams...);
    frameCaptureShared->captureCLCall(std::move(call), isCallValid);
}
#endif

// Pointer capture helpers.
void CaptureMemory(const void *source, size_t size, ParamCapture *paramCapture);
void CaptureString(const GLchar *str, ParamCapture *paramCapture);
void CaptureStringLimit(const GLchar *str, uint32_t limit, ParamCapture *paramCapture);
void CaptureVertexPointerGLES1(const gl::State &glState,
                               gl::ClientVertexArrayType type,
                               const void *pointer,
                               ParamCapture *paramCapture);

gl::Program *GetProgramForCapture(const gl::State &glState, gl::ShaderProgramID handle);

// For GetIntegerv, GetFloatv, etc.
void CaptureGetParameter(const gl::State &glState,
                         GLenum pname,
                         size_t typeSize,
                         ParamCapture *paramCapture);

void CaptureGetActiveUniformBlockivParameters(const gl::State &glState,
                                              gl::ShaderProgramID programPacked,
                                              gl::UniformBlockIndex uniformBlockIndexPacked,
                                              gl::UniformBlockParameter pnamePacked,
                                              ParamCapture *paramCapture);

template <typename T>
void CaptureClearBufferValue(GLenum buffer, const T *value, ParamCapture *paramCapture)
{
    // Per the spec, color buffers have a vec4, the rest a single value
    uint32_t valueSize = (buffer == GL_COLOR) ? 4 : 1;
    CaptureMemory(value, valueSize * sizeof(T), paramCapture);
}

void CaptureGenHandlesImpl(GLsizei n, GLuint *handles, ParamCapture *paramCapture);

template <typename T>
void CaptureGenHandles(GLsizei n, T *handles, ParamCapture *paramCapture)
{
    paramCapture->dataNElements = n;
    CaptureGenHandlesImpl(n, reinterpret_cast<GLuint *>(handles), paramCapture);
}

template <typename T>
void CaptureArray(T *elements, GLsizei n, ParamCapture *paramCapture)
{
    paramCapture->dataNElements = n;
    CaptureMemory(elements, n * sizeof(T), paramCapture);
}

void CaptureShaderStrings(GLsizei count,
                          const GLchar *const *strings,
                          const GLint *length,
                          ParamCapture *paramCapture);

bool IsTrackedPerContext(ResourceIDType type);

// Function declarations & data types for both
// capturing OpenGL and OpenCL

std::string EscapeString(const std::string &string);

// Used to indicate that "shared" should be used to identify the files.
constexpr gl::ContextID kSharedContextId = {0};
// Used to indicate no context ID should be output.
constexpr gl::ContextID kNoContextId = {std::numeric_limits<uint32_t>::max()};

constexpr uint32_t kNoPartId = std::numeric_limits<uint32_t>::max();

std::ostream &operator<<(std::ostream &os, gl::ContextID contextId);

struct FmtCapturePrefix
{
    FmtCapturePrefix(gl::ContextID contextIdIn, const std::string &captureLabelIn)
        : contextId(contextIdIn), captureLabel(captureLabelIn)
    {}
    gl::ContextID contextId;
    const std::string &captureLabel;
};

std::ostream &operator<<(std::ostream &os, const FmtCapturePrefix &fmt);

// In C, when you declare or define a function that takes no parameters, you must explicitly say the
// function takes "void" parameters. When you're calling the function you omit this void. It's
// therefore necessary to know how we're using a function to know if we should emi the "void".
enum FuncUsage
{
    Prototype,
    Definition,
    Call,
};

std::ostream &operator<<(std::ostream &os, FuncUsage usage);

struct FmtReplayFunction
{
    FmtReplayFunction(gl::ContextID contextIdIn,
                      FuncUsage usageIn,
                      uint32_t frameIndexIn,
                      uint32_t partIdIn = kNoPartId)
        : contextId(contextIdIn), usage(usageIn), frameIndex(frameIndexIn), partId(partIdIn)
    {}
    gl::ContextID contextId;
    FuncUsage usage;
    uint32_t frameIndex;
    uint32_t partId;
};

std::ostream &operator<<(std::ostream &os, const FmtReplayFunction &fmt);

enum class ReplayFunc
{
    Replay,
    Setup,
    SetupInactive,
    Reset,
    SetupFirstFrame,
};

struct FmtFunction
{
    FmtFunction(ReplayFunc funcTypeIn,
                gl::ContextID contextIdIn,
                FuncUsage usageIn,
                uint32_t frameIndexIn,
                uint32_t partIdIn)
        : funcType(funcTypeIn),
          contextId(contextIdIn),
          usage(usageIn),
          frameIndex(frameIndexIn),
          partId(partIdIn)
    {}

    ReplayFunc funcType;
    gl::ContextID contextId;
    FuncUsage usage;
    uint32_t frameIndex;
    uint32_t partId;
};

std::ostream &operator<<(std::ostream &os, gl::ContextID contextId);

std::ostream &operator<<(std::ostream &os, const FmtFunction &fmt);

struct FmtSetupFunction
{
    FmtSetupFunction(uint32_t partIdIn, gl::ContextID contextIdIn, FuncUsage usageIn)
        : partId(partIdIn), contextId(contextIdIn), usage(usageIn)
    {}

    uint32_t partId;
    gl::ContextID contextId;
    FuncUsage usage;
};

std::ostream &operator<<(std::ostream &os, const FmtSetupFunction &fmt);

struct FmtSetupFirstFrameFunction
{
    FmtSetupFirstFrameFunction(uint32_t partIdIn = kNoPartId) : partId(partIdIn) {}

    uint32_t partId;
};

std::ostream &operator<<(std::ostream &os, const FmtSetupFirstFrameFunction &fmt);

struct FmtSetupInactiveFunction
{
    FmtSetupInactiveFunction(uint32_t partIdIn, gl::ContextID contextIdIn, FuncUsage usageIn)
        : partId(partIdIn), contextId(contextIdIn), usage(usageIn)
    {}

    uint32_t partId;
    gl::ContextID contextId;
    FuncUsage usage;
};

std::ostream &operator<<(std::ostream &os, const FmtSetupInactiveFunction &fmt);

struct FmtResetFunction
{
    FmtResetFunction(uint32_t partIdIn, gl::ContextID contextIdIn, FuncUsage usageIn)
        : partId(partIdIn), contextId(contextIdIn), usage(usageIn)
    {}

    uint32_t partId;
    gl::ContextID contextId;
    FuncUsage usage;
};

std::ostream &operator<<(std::ostream &os, const FmtResetFunction &fmt);

// For compatibility with C, which does not have multi-line string literals, we break strings up
// into multiple lines like:
//
//   const char *str[] = {
//   "multiple\n"
//   "line\n"
//   "strings may have \"quotes\"\n"
//   "and \\slashes\\\n",
//   };
//
// Note we need to emit extra escapes to ensure quotes and other special characters are preserved.
struct FmtMultiLineString
{
    FmtMultiLineString(const std::string &str) : strings()
    {
        std::string str2;

        // Strip any carriage returns before splitting, for consistency
        if (str.find("\r") != std::string::npos)
        {
            // str is const, so have to make a copy of it first
            str2 = str;
            ReplaceAllSubstrings(&str2, "\r", "");
        }

        strings =
            angle::SplitString(str2.empty() ? str : str2, "\n", WhitespaceHandling::KEEP_WHITESPACE,
                               SplitResult::SPLIT_WANT_ALL);
    }

    std::vector<std::string> strings;
};

std::ostream &operator<<(std::ostream &ostr, const FmtMultiLineString &fmt);

struct SaveFileHelper
{
  public:
    // We always use ios::binary to avoid inconsistent line endings when captured on Linux vs Win.
    SaveFileHelper(const std::string &filePathIn)
        : mOfs(filePathIn, std::ios::binary | std::ios::out), mFilePath(filePathIn)
    {
        if (!mOfs.is_open())
        {
            FATAL() << "Could not open " << filePathIn;
        }
    }
    ~SaveFileHelper() { printf("Saved '%s'.\n", mFilePath.c_str()); }

    template <typename T>
    SaveFileHelper &operator<<(const T &value)
    {
        mOfs << value;
        if (mOfs.bad())
        {
            FATAL() << "Error writing to " << mFilePath;
        }
        return *this;
    }

    void write(const uint8_t *data, size_t size)
    {
        mOfs.write(reinterpret_cast<const char *>(data), size);
    }

  private:
    void checkError();

    std::ofstream mOfs;
    std::string mFilePath;
};

// TODO: Consolidate to C output and remove option. http://anglebug.com/42266223

constexpr char kEnabledVarName[]        = "ANGLE_CAPTURE_ENABLED";
constexpr char kOutDirectoryVarName[]   = "ANGLE_CAPTURE_OUT_DIR";
constexpr char kFrameStartVarName[]     = "ANGLE_CAPTURE_FRAME_START";
constexpr char kFrameEndVarName[]       = "ANGLE_CAPTURE_FRAME_END";
constexpr char kBinaryDataSizeVarName[] = "ANGLE_CAPTURE_MAX_RESIDENT_BINARY_SIZE";
constexpr char kBlockSizeVarName[]      = "ANGLE_CAPTURE_BLOCK_SIZE";
constexpr char kTriggerVarName[]        = "ANGLE_CAPTURE_TRIGGER";
constexpr char kEndCaptureVarName[]     = "ANGLE_CAPTURE_END_CAPTURE";
constexpr char kCaptureLabelVarName[]   = "ANGLE_CAPTURE_LABEL";
constexpr char kCompressionVarName[]    = "ANGLE_CAPTURE_COMPRESSION";
constexpr char kSerializeStateVarName[] = "ANGLE_CAPTURE_SERIALIZE_STATE";
constexpr char kValidationVarName[]     = "ANGLE_CAPTURE_VALIDATION";
constexpr char kValidationExprVarName[] = "ANGLE_CAPTURE_VALIDATION_EXPR";
constexpr char kSourceExtVarName[]      = "ANGLE_CAPTURE_SOURCE_EXT";
constexpr char kSourceSizeVarName[]     = "ANGLE_CAPTURE_SOURCE_SIZE";
constexpr char kForceShadowVarName[]    = "ANGLE_CAPTURE_FORCE_SHADOW";

constexpr size_t kFunctionSizeLimit = 5000;

// Limit based on MSVC Compiler Error C2026
constexpr size_t kStringLengthLimit = 16380;

// Default limit to number of bytes in a capture source files.
constexpr char kDefaultSourceFileExt[]           = "cpp";
constexpr size_t kDefaultSourceFileSizeThreshold = 400000;

// Android debug properties that correspond to the above environment variables
constexpr char kAndroidEnabled[]        = "debug.angle.capture.enabled";
constexpr char kAndroidOutDir[]         = "debug.angle.capture.out_dir";
constexpr char kAndroidFrameStart[]     = "debug.angle.capture.frame_start";
constexpr char kAndroidFrameEnd[]       = "debug.angle.capture.frame_end";
constexpr char kAndroidBinaryDataSize[] = "debug.angle.capture.max_resident_binary_size";
constexpr char kAndroidBlockSize[]      = "debug.angle.capture.block_size";
constexpr char kAndroidTrigger[]        = "debug.angle.capture.trigger";
constexpr char kAndroidEndCapture[]     = "debug.angle.capture.end_capture";
constexpr char kAndroidCaptureLabel[]   = "debug.angle.capture.label";
constexpr char kAndroidCompression[]    = "debug.angle.capture.compression";
constexpr char kAndroidValidation[]     = "debug.angle.capture.validation";
constexpr char kAndroidValidationExpr[] = "debug.angle.capture.validation_expr";
constexpr char kAndroidSourceExt[]      = "debug.angle.capture.source_ext";
constexpr char kAndroidSourceSize[]     = "debug.angle.capture.source_size";
constexpr char kAndroidForceShadow[]    = "debug.angle.capture.force_shadow";

void WriteCppReplayForCall(const CallCapture &call,
                           ReplayWriter &replayWriter,
                           std::ostream &out,
                           std::ostream &header,
                           FrameCaptureBinaryData *binaryData,
                           size_t *maxResourceIDBufferSize);

void WriteCppReplayForCallCL(const CallCapture &call,
                             ReplayWriter &replayWriter,
                             std::ostream &out,
                             std::ostream &header,
                             FrameCaptureBinaryData *binaryData);

void WriteBinaryParamReplay(ReplayWriter &replayWriter,
                            std::ostream &out,
                            std::ostream &header,
                            const CallCapture &call,
                            const ParamCapture &param,
                            FrameCaptureBinaryData *binaryData);

std::string GetBinaryDataFilePath(bool compression, const std::string &captureLabel);

void WriteStringPointerParamReplay(ReplayWriter &replayWriter,
                                   std::ostream &out,
                                   std::ostream &header,
                                   const CallCapture &call,
                                   const ParamCapture &param);

void WriteCppReplayFunctionWithParts(const gl::ContextID contextID,
                                     ReplayFunc replayFunc,
                                     ReplayWriter &replayWriter,
                                     uint32_t frameIndex,
                                     FrameCaptureBinaryData *binaryData,
                                     const std::vector<CallCapture> &calls,
                                     std::stringstream &header,
                                     std::stringstream &out,
                                     size_t *maxResourceIDBufferSize);

void WriteComment(std::ostream &out, const CallCapture &call);

template <typename T, typename CastT = T>
void WriteInlineData(const std::vector<uint8_t> &vec, std::ostream &out)
{
    const T *data = reinterpret_cast<const T *>(vec.data());
    size_t count  = vec.size() / sizeof(T);

    if (data == nullptr)
    {
        return;
    }

    out << static_cast<CastT>(data[0]);

    for (size_t dataIndex = 1; dataIndex < count; ++dataIndex)
    {
        out << ", " << static_cast<CastT>(data[dataIndex]);
    }
}

template <>
void WriteInlineData<GLchar>(const std::vector<uint8_t> &vec, std::ostream &out);

void AddComment(std::vector<CallCapture> *outCalls, const std::string &comment);

std::string GetCaptureTrigger();

std::string GetEndCapture();

}  // namespace angle

template <typename T>
void CaptureTextureAndSamplerParameter_params(GLenum pname,
                                              const T *param,
                                              angle::ParamCapture *paramCapture)
{
    if (pname == GL_TEXTURE_BORDER_COLOR || pname == GL_TEXTURE_CROP_RECT_OES)
    {
        CaptureMemory(param, sizeof(T) * 4, paramCapture);
    }
    else
    {
        CaptureMemory(param, sizeof(T), paramCapture);
    }
}

namespace egl
{
angle::ParamCapture CaptureAttributeMap(const egl::AttributeMap &attribMap);
}  // namespace egl

#endif  // LIBANGLE_FRAME_CAPTURE_H_
