//
// Copyright 2024 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.
//

#ifndef LIBANGLE_RENDERER_WGPU_WGPU_UTILS_H_
#define LIBANGLE_RENDERER_WGPU_WGPU_UTILS_H_

#include <dawn/dawn_proc_table.h>
#include <stdint.h>
#include <webgpu/webgpu.h>
#include <climits>

#include "libANGLE/Caps.h"
#include "libANGLE/Error.h"
#include "libANGLE/angletypes.h"

#define ANGLE_WGPU_TRY(context, command)                                                     \
    do                                                                                       \
    {                                                                                        \
        auto ANGLE_LOCAL_VAR = command;                                                      \
        if (ANGLE_UNLIKELY(::rx::webgpu::IsWgpuError(ANGLE_LOCAL_VAR)))                      \
        {                                                                                    \
            (context)->handleError(GL_INVALID_OPERATION, "Internal WebGPU error.", __FILE__, \
                                   ANGLE_FUNCTION, __LINE__);                                \
            return angle::Result::Stop;                                                      \
        }                                                                                    \
    } while (0)

#define ANGLE_WGPU_BEGIN_DEBUG_ERROR_SCOPE(context)                            \
    ::rx::webgpu::DebugErrorScope(context->getProcs(), context->getInstance(), \
                                  context->getDevice(), WGPUErrorFilter_Validation)
#define ANGLE_WGPU_END_DEBUG_ERROR_SCOPE(context, scope) \
    ANGLE_TRY(scope.PopScope(context, __FILE__, ANGLE_FUNCTION, __LINE__))

#define ANGLE_WGPU_SCOPED_DEBUG_TRY(context, command)                                            \
    do                                                                                           \
    {                                                                                            \
        ::rx::webgpu::DebugErrorScope _errorScope = ANGLE_WGPU_BEGIN_DEBUG_ERROR_SCOPE(context); \
        (command);                                                                               \
        ANGLE_WGPU_END_DEBUG_ERROR_SCOPE(context, _errorScope);                                  \
    } while (0)

#define ANGLE_GL_OBJECTS_X(PROC) \
    PROC(Buffer)                 \
    PROC(Context)                \
    PROC(Framebuffer)            \
    PROC(Query)                  \
    PROC(Program)                \
    PROC(ProgramExecutable)      \
    PROC(Renderbuffer)           \
    PROC(Sampler)                \
    PROC(Texture)                \
    PROC(TransformFeedback)      \
    PROC(VertexArray)

#define ANGLE_EGL_OBJECTS_X(PROC) \
    PROC(Display)                 \
    PROC(ExternalImageSibling)    \
    PROC(Image)                   \
    PROC(Surface)                 \
    PROC(Sync)

#define ANGLE_WGPU_OBJECTS_X(PROC)                 \
    PROC(Adapter, adapter)                         \
    PROC(BindGroup, bindGroup)                     \
    PROC(BindGroupLayout, bindGroupLayout)         \
    PROC(Buffer, buffer)                           \
    PROC(CommandBuffer, commandBuffer)             \
    PROC(CommandEncoder, commandEncoder)           \
    PROC(ComputePassEncoder, computePassEncoder)   \
    PROC(ComputePipeline, computePipeline)         \
    PROC(Device, device)                           \
    PROC(ExternalTexture, externalTexture)         \
    PROC(Instance, instance)                       \
    PROC(PipelineLayout, pipelineLayout)           \
    PROC(QuerySet, querySet)                       \
    PROC(Queue, queue)                             \
    PROC(RenderBundle, renderBundle)               \
    PROC(RenderBundleEncoder, renderBundleEncoder) \
    PROC(RenderPassEncoder, renderPassEncoder)     \
    PROC(RenderPipeline, renderPipeline)           \
    PROC(Sampler, sampler)                         \
    PROC(ShaderModule, shaderModule)               \
    PROC(SharedBufferMemory, sharedBufferMemory)   \
    PROC(SharedFence, sharedFence)                 \
    PROC(SharedTextureMemory, sharedTextureMemory) \
    PROC(Surface, surface)                         \
    PROC(Texture, texture)                         \
    PROC(TextureView, textureView)

namespace gl
{
#define ANGLE_PRE_DECLARE_GL_OBJECT(OBJ) class OBJ;
ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_GL_OBJECT)
}  // namespace gl

namespace egl
{
#define ANGLE_PRE_DECLARE_EGL_OBJECT(OBJ) class OBJ;
ANGLE_EGL_OBJECTS_X(ANGLE_PRE_DECLARE_EGL_OBJECT)
}  // namespace egl

namespace angle
{
struct FeaturesWgpu;
}

namespace rx
{

class ContextWgpu;
class DisplayWgpu;

#define ANGLE_PRE_DECLARE_WGPU_OBJECT(OBJ) class OBJ##Wgpu;

ANGLE_GL_OBJECTS_X(ANGLE_PRE_DECLARE_WGPU_OBJECT)
ANGLE_EGL_OBJECTS_X(ANGLE_PRE_DECLARE_WGPU_OBJECT)

namespace webgpu
{
#define ANGLE_DECLARE_WGPU_HANDLE_REF_FUNCS(OBJ, obj)                           \
    inline void AddRefWGPUCHandle(const DawnProcTable *wgpu, WGPU##OBJ handle)  \
    {                                                                           \
        if (handle)                                                             \
        {                                                                       \
            ASSERT(wgpu != nullptr);                                            \
            wgpu->obj##AddRef(handle);                                          \
        }                                                                       \
    }                                                                           \
                                                                                \
    inline void ReleaseWGPUCHandle(const DawnProcTable *wgpu, WGPU##OBJ handle) \
    {                                                                           \
        if (handle)                                                             \
        {                                                                       \
            ASSERT(wgpu != nullptr);                                            \
            wgpu->obj##Release(handle);                                         \
        }                                                                       \
    }

ANGLE_WGPU_OBJECTS_X(ANGLE_DECLARE_WGPU_HANDLE_REF_FUNCS)
#undef ANGLE_DECLARE_WGPU_HANDLE_REF_FUNCS

template <typename CType>
class WrapperBase
{
  public:
    using ObjectType = CType;

    WrapperBase() = default;
    WrapperBase(const WrapperBase<CType> &other)
        : mProcTable(other.mProcTable), mHandle(other.mHandle)
    {
        AddRefWGPUCHandle(mProcTable, mHandle);
    }

    ~WrapperBase() { ReleaseWGPUCHandle(mProcTable, mHandle); }

    WrapperBase<CType> &operator=(const WrapperBase<CType> &other)
    {
        if (&other != this)
        {
            ReleaseWGPUCHandle(mProcTable, mHandle);
            mProcTable = other.mProcTable;
            mHandle    = other.mHandle;
            AddRefWGPUCHandle(mProcTable, mHandle);
        }
        return *this;
    }

    WrapperBase(WrapperBase<CType> &&other)
    {
        mProcTable       = other.mProcTable;
        mHandle          = other.mHandle;
        other.mProcTable = nullptr;
        other.mHandle    = nullptr;
    }

    WrapperBase &operator=(WrapperBase<CType> &&other)
    {
        if (&other != this)
        {
            ReleaseWGPUCHandle(mProcTable, mHandle);
            mProcTable       = other.mProcTable;
            mHandle          = other.mHandle;
            other.mProcTable = nullptr;
            other.mHandle    = nullptr;
        }
        return *this;
    }

    WrapperBase(std::nullptr_t) {}

    WrapperBase &operator=(std::nullptr_t)
    {
        ReleaseWGPUCHandle(mProcTable, mHandle);
        mProcTable = nullptr;
        mHandle    = nullptr;
        return *this;
    }

    bool operator==(const WrapperBase<CType> &other) const { return mHandle == other.mHandle; }

    bool operator!=(const WrapperBase<CType> &other) const { return !(*this == other); }

    bool operator==(std::nullptr_t) const { return mHandle == nullptr; }

    bool operator!=(std::nullptr_t) const { return mHandle != nullptr; }

    explicit operator bool() const { return mHandle != nullptr; }

    const CType &get() const { return mHandle; }

    static WrapperBase<CType> Acquire(const DawnProcTable *procTable, CType handle)
    {
        WrapperBase<CType> result;
        result.mHandle    = handle;
        result.mProcTable = procTable;
        return result;
    }

    size_t hash() const
    {
        std::hash<CType> hasher;
        return hasher(mHandle);
    }

  private:
    const DawnProcTable *mProcTable = nullptr;
    CType mHandle                   = nullptr;
};

#define ANGLE_DECLARE_WGPU_OBJECT_WRAPPER(OBJ, obj) using OBJ##Handle = WrapperBase<WGPU##OBJ>;

ANGLE_WGPU_OBJECTS_X(ANGLE_DECLARE_WGPU_OBJECT_WRAPPER)
#undef ANGLE_DECLARE_WGPU_OBJECT_WRAPPER

template <typename T>
struct ImplTypeHelper;

#define ANGLE_IMPL_TYPE_HELPER(frontendNamespace, OBJ) \
    template <>                                        \
    struct ImplTypeHelper<frontendNamespace::OBJ>      \
    {                                                  \
        using ImplType = rx::OBJ##Wgpu;                \
    };
#define ANGLE_IMPL_TYPE_HELPER_GL(OBJ) ANGLE_IMPL_TYPE_HELPER(gl, OBJ)
#define ANGLE_IMPL_TYPE_HELPER_EGL(OBJ) ANGLE_IMPL_TYPE_HELPER(egl, OBJ)

ANGLE_GL_OBJECTS_X(ANGLE_IMPL_TYPE_HELPER_GL)
ANGLE_EGL_OBJECTS_X(ANGLE_IMPL_TYPE_HELPER_EGL)

#undef ANGLE_IMPL_TYPE_HELPER_GL
#undef ANGLE_IMPL_TYPE_HELPER_EGL

template <typename T>
using GetImplType = typename ImplTypeHelper<T>::ImplType;

template <typename T>
GetImplType<T> *GetImpl(const T *glObject)
{
    return GetImplAs<GetImplType<T>>(glObject);
}

constexpr size_t kUnpackedDepthIndex   = gl::IMPLEMENTATION_MAX_DRAW_BUFFERS;
constexpr size_t kUnpackedStencilIndex = gl::IMPLEMENTATION_MAX_DRAW_BUFFERS + 1;
constexpr uint32_t kUnpackedColorBuffersMask =
    angle::BitMask<uint32_t>(gl::IMPLEMENTATION_MAX_DRAW_BUFFERS);
// WebGPU image level index.
using LevelIndex = gl::LevelIndexWrapper<uint32_t>;

class ErrorScope : public angle::NonCopyable
{
  public:
    ErrorScope(const DawnProcTable *procTable,
               webgpu::InstanceHandle instance,
               webgpu::DeviceHandle device,
               WGPUErrorFilter errorType);
    ~ErrorScope();

    angle::Result PopScope(ContextWgpu *context,
                           const char *file,
                           const char *function,
                           unsigned int line);

  private:
    const DawnProcTable *mProcTable = nullptr;
    webgpu::InstanceHandle mInstance;
    webgpu::DeviceHandle mDevice;
    bool mActive = false;
};

class NoOpErrorScope : public angle::NonCopyable
{
  public:
    NoOpErrorScope(const DawnProcTable *procTable,
                   webgpu::InstanceHandle instance,
                   webgpu::DeviceHandle device,
                   WGPUErrorFilter errorType)
    {}
    ~NoOpErrorScope() {}

    angle::Result PopScope(ContextWgpu *context,
                           const char *file,
                           const char *function,
                           unsigned int line)
    {
        return angle::Result::Continue;
    }
};

#if defined(ANGLE_ENABLE_ASSERTS)
using DebugErrorScope = ErrorScope;
#else
using DebugErrorScope = NoOpErrorScope;
#endif

enum class RenderPassClosureReason
{
    NewRenderPass,
    FramebufferBindingChange,
    FramebufferInternalChange,
    GLFlush,
    GLFinish,
    EGLSwapBuffers,
    GLReadPixels,
    IndexRangeReadback,
    VertexArrayStreaming,
    VertexArrayLineLoop,
    CopyBufferToTexture,
    CopyTextureToTexture,
    CopyImage,
    ClearWithDraw,

    InvalidEnum,
    EnumCount = InvalidEnum,
};

struct ClearValues
{
    gl::ColorF clearColor;
    uint32_t depthSlice;
    float depthValue;
    uint32_t stencilValue;
};

class ClearValuesArray final
{
  public:
    ClearValuesArray();
    ~ClearValuesArray();

    ClearValuesArray(const ClearValuesArray &other);
    ClearValuesArray &operator=(const ClearValuesArray &rhs);

    void store(uint32_t index, const ClearValues &clearValues);

    gl::DrawBufferMask getColorMask() const;
    void reset()
    {
        mValues.fill({});
        mEnabled.reset();
    }
    void reset(size_t index)
    {
        mValues[index] = {};
        mEnabled.reset(index);
    }
    void resetDepth()
    {
        mValues[kUnpackedDepthIndex] = {};
        mEnabled.reset(kUnpackedDepthIndex);
    }
    void resetStencil()
    {
        mValues[kUnpackedStencilIndex] = {};
        mEnabled.reset(kUnpackedStencilIndex);
    }
    const ClearValues &operator[](size_t index) const { return mValues[index]; }

    bool empty() const { return mEnabled.none(); }
    bool any() const { return mEnabled.any(); }

    bool test(size_t index) const { return mEnabled.test(index); }

    float getDepthValue() const { return mValues[kUnpackedDepthIndex].depthValue; }
    uint32_t getStencilValue() const { return mValues[kUnpackedStencilIndex].stencilValue; }
    bool hasDepth() const { return mEnabled.test(kUnpackedDepthIndex); }
    bool hasStencil() const { return mEnabled.test(kUnpackedStencilIndex); }

  private:
    gl::AttachmentArray<ClearValues> mValues;
    gl::AttachmentsMask mEnabled;
};

struct PackedRenderPassColorAttachment
{
    TextureViewHandle view;
    uint32_t depthSlice = WGPU_DEPTH_SLICE_UNDEFINED;
    WGPULoadOp loadOp   = WGPULoadOp_Undefined;
    WGPUStoreOp storeOp = WGPUStoreOp_Undefined;
    gl::ColorF clearValue;
};

bool operator==(const PackedRenderPassColorAttachment &a, const PackedRenderPassColorAttachment &b);

struct PackedRenderPassDepthStencilAttachment
{
    TextureViewHandle view;
    WGPULoadOp depthLoadOp     = WGPULoadOp_Undefined;
    WGPUStoreOp depthStoreOp   = WGPUStoreOp_Undefined;
    bool depthReadOnly         = false;
    float depthClearValue      = NAN;
    WGPULoadOp stencilLoadOp   = WGPULoadOp_Undefined;
    WGPUStoreOp stencilStoreOp = WGPUStoreOp_Undefined;
    bool stencilReadOnly       = false;
    uint32_t stencilClearValue = 0;
};

bool operator==(const PackedRenderPassDepthStencilAttachment &a,
                const PackedRenderPassDepthStencilAttachment &b);

struct PackedRenderPassDescriptor
{
    angle::FixedVector<PackedRenderPassColorAttachment, gl::IMPLEMENTATION_MAX_DRAW_BUFFERS>
        colorAttachments;
    std::optional<PackedRenderPassDepthStencilAttachment> depthStencilAttachment;
};

bool operator==(const PackedRenderPassDescriptor &a, const PackedRenderPassDescriptor &b);
bool operator!=(const PackedRenderPassDescriptor &a, const PackedRenderPassDescriptor &b);

RenderPassEncoderHandle CreateRenderPass(const DawnProcTable *wgpu,
                                         webgpu::CommandEncoderHandle commandEncoder,
                                         const webgpu::PackedRenderPassDescriptor &desc);

void GenerateCaps(const WGPULimits &limitWgpu,
                  gl::Caps *glCaps,
                  gl::TextureCapsMap *glTextureCapsMap,
                  gl::Extensions *glExtensions,
                  gl::Limitations *glLimitations,
                  egl::Caps *eglCaps,
                  egl::DisplayExtensions *eglExtensions,
                  gl::Version *maxSupportedESVersion);

DisplayWgpu *GetDisplay(const gl::Context *context);
const DawnProcTable *GetProcs(const gl::Context *context);
const DawnProcTable *GetProcs(const ContextWgpu *context);
const angle::FeaturesWgpu &GetFeatures(const gl::Context *context);
const angle::FeaturesWgpu &GetFeatures(const ContextWgpu *context);
webgpu::DeviceHandle GetDevice(const gl::Context *context);
webgpu::InstanceHandle GetInstance(const gl::Context *context);
PackedRenderPassColorAttachment CreateNewClearColorAttachment(const gl::ColorF &clearValue,
                                                              uint32_t depthSlice,
                                                              TextureViewHandle textureView);
PackedRenderPassDepthStencilAttachment CreateNewClearDepthStencilAttachment(
    float depthClearValue,
    uint32_t stencilClearValue,
    TextureViewHandle textureView,
    bool hasDepthValue   = false,
    bool hasStencilValue = false);
PackedRenderPassDepthStencilAttachment CreateNewDepthStencilAttachment(
    TextureViewHandle textureView,
    bool hasDepthValue   = false,
    bool hasStencilValue = false);

bool IsWgpuError(WGPUWaitStatus waitStatus);
bool IsWgpuError(WGPUMapAsyncStatus mapAsyncStatus);

bool IsStripPrimitiveTopology(WGPUPrimitiveTopology topology);

// Required alignments for buffer sizes and mapping
constexpr size_t kBufferSizeAlignment         = 4;
constexpr size_t kBufferCopyToBufferAlignment = 4;
constexpr size_t kBufferMapSizeAlignment   = kBufferSizeAlignment;
constexpr size_t kBufferMapOffsetAlignment = 8;

// Required alignments for texture row uploads
constexpr size_t kTextureRowSizeAlignment = 256;

// Structs in WGPU's uniform address space are always aligned to 16. I.e. RequiredAlignOf(struct S,
// uniform) = roundUp(16, AlignOf(S)) and AlignOf(S) is at most 16.
constexpr size_t kUniformStructAlignment = 16;

// min and max LOD clamp values.
constexpr float kWGPUMinLod = 0.0;
constexpr float kWGPUMaxLod = 32.0;

}  // namespace webgpu

namespace wgpu_gl
{
gl::LevelIndex GetLevelIndex(webgpu::LevelIndex levelWgpu, gl::LevelIndex baseLevel);
gl::Extents GetExtents(WGPUExtent3D wgpuExtent);
}  // namespace wgpu_gl

namespace gl_wgpu
{
webgpu::LevelIndex getLevelIndex(gl::LevelIndex levelGl, gl::LevelIndex baseLevel);
WGPUTextureViewDimension GetWgpuTextureViewDimension(gl::TextureType textureType);
WGPUTextureDimension GetWgpuTextureDimension(gl::TextureType glTextureType);
WGPUExtent3D GetExtent3D(const gl::Extents &glExtent);

WGPUPrimitiveTopology GetPrimitiveTopology(gl::PrimitiveMode mode);

WGPUIndexFormat GetIndexFormat(gl::DrawElementsType drawElementsTYpe);
WGPUFrontFace GetFrontFace(GLenum frontFace);
WGPUCullMode GetCullMode(gl::CullFaceMode mode, bool cullFaceEnabled);
WGPUColorWriteMask GetColorWriteMask(bool r, bool g, bool b, bool a);

WGPUBlendFactor GetBlendFactor(gl::BlendFactorType blendFactor);
WGPUBlendOperation GetBlendEquation(gl::BlendEquationType blendEquation);

WGPUCompareFunction GetCompareFunc(const GLenum glCompareFunc, bool testEnabled);
WGPUTextureSampleType GetTextureSampleType(gl::SamplerFormat samplerFormat);
WGPUStencilOperation GetStencilOp(const GLenum glStencilOp);
WGPUFilterMode GetFilter(const GLenum filter);
WGPUMipmapFilterMode GetSamplerMipmapMode(const GLenum filter);
WGPUAddressMode GetSamplerAddressMode(const GLenum wrap);

WGPUSamplerDescriptor GetWgpuSamplerDesc(const gl::SamplerState *samplerState);

uint32_t GetFirstIndexForDrawCall(gl::DrawElementsType indexType, const void *indices);
}  // namespace gl_wgpu

// Number of reserved binding slots to implement the default uniform block
constexpr uint32_t kReservedPerStageDefaultUniformSlotCount = 0;

}  // namespace rx

namespace std
{
template <typename CType>
struct hash<rx::webgpu::WrapperBase<CType>>
{
    size_t operator()(const rx::webgpu::WrapperBase<CType> &obj) const { return obj.hash(); }
};
}  // namespace std

#endif  // LIBANGLE_RENDERER_WGPU_WGPU_UTILS_H_
