//
// 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 "sys/stat.h"

#include "common/PackedEnums.h"
#include "common/SimpleMutex.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 BigGLEnum;
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; }

    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();
        mMaxShaderPrograms = 0;
        mStartingFenceSyncs.clear();
        mFenceSyncRegenCalls.clear();
        mFenceSyncsToRegen.clear();
        mDefaultUniformsToReset.clear();
        mDefaultUniformResetCalls.clear();
        mDefaultUniformBaseLocations.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<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();
    void onEndFrame(gl::Context *context);
    void onDestroyContext(const gl::Context *context);
    bool onEndCLCapture();
    void onMakeCurrent(const gl::Context *context, const egl::Surface *drawSurface);
    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)(&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);

    void trackTextureUpdate(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 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.";
    }

  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 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;

    // We save one large buffer of binary data for the whole CPP replay.
    // This simplifies a lot of file management.
    std::vector<uint8_t> mBinaryData;

    bool mEnabled;
    static bool mRuntimeEnabled;
    static bool mRuntimeInitialized;
    bool mSerializeStateEnabled;
    std::string mOutDirectory;
    std::string mCaptureLabel;
    bool mCompression;
    gl::AttribArray<int> mClientVertexArrayMap;
    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;

    // 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;

    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 handle,
                                              gl::UniformBlockIndex uniformBlockIndex,
                                              GLenum pname,
                                              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 kTriggerVarName[]        = "ANGLE_CAPTURE_TRIGGER";
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 kBinaryAlignment   = 16;
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 kAndroidTrigger[]        = "debug.angle.capture.trigger";
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,
                           std::vector<uint8_t> *binaryData,
                           size_t *maxResourceIDBufferSize);

void WriteCppReplayForCallCL(const CallCapture &call,
                             ReplayWriter &replayWriter,
                             std::ostream &out,
                             std::ostream &header,
                             std::vector<uint8_t> *binaryData);

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

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

void SaveBinaryData(bool compression,
                    const std::string &outDir,
                    gl::ContextID contextId,
                    const std::string &captureLabel,
                    const std::vector<uint8_t> &binaryData);

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,
                                     std::vector<uint8_t> *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);

}  // 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_
