//
// Copyright 2017 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.
//
// ResourceManager11:
//   Centralized point of allocation for all D3D11 Resources.

#ifndef LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
#define LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_

#include <array>
#include <memory>

#include "common/angleutils.h"
#include "common/debug.h"
#include "libANGLE/Error.h"

namespace rx
{
class Renderer11;
class ResourceManager11;

// Format: ResourceType, D3D11 type, DESC type, init data type.
#define ANGLE_RESOURCE_TYPE_OP(NAME, OP)                                              \
    OP(NAME, RenderTargetView, ID3D11RenderTargetView, D3D11_RENDER_TARGET_VIEW_DESC, \
       ID3D11Resource)

#define ANGLE_RESOURCE_TYPE_LIST(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) RESTYPE,

enum class ResourceType
{
    ANGLE_RESOURCE_TYPE_OP(List, ANGLE_RESOURCE_TYPE_LIST) Last
};

#undef ANGLE_RESOURCE_TYPE_LIST

constexpr size_t ResourceTypeIndex(ResourceType resourceType)
{
    return static_cast<size_t>(resourceType);
}

constexpr size_t NumResourceTypes = ResourceTypeIndex(ResourceType::Last);

#define ANGLE_RESOURCE_TYPE_TO_D3D11(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    \
template<> struct NAME<ResourceType::RESTYPE>                                          \
    {                                                                                  \
        using Value = D3D11TYPE;                                                       \
    };

#define ANGLE_RESOURCE_TYPE_TO_DESC(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    \
template<> struct NAME<ResourceType::RESTYPE>                                         \
    {                                                                                 \
        using Value = DESCTYPE;                                                       \
    };

#define ANGLE_RESOURCE_TYPE_TO_INIT_DATA(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    \
template<> struct NAME<ResourceType::RESTYPE>                                              \
    {                                                                                      \
        using Value = INITDATATYPE;                                                        \
    };

#define ANGLE_RESOURCE_TYPE_TO_TYPE(NAME, OP) \
    template <ResourceType Param>             \
    struct NAME;                              \
    ANGLE_RESOURCE_TYPE_OP(NAME, OP)          \
    \
template<ResourceType Param> struct NAME      \
    {                                         \
    };                                        \
    \
template<ResourceType Param> using Get##NAME = typename NAME<Param>::Value;

ANGLE_RESOURCE_TYPE_TO_TYPE(D3D11Type, ANGLE_RESOURCE_TYPE_TO_D3D11)
ANGLE_RESOURCE_TYPE_TO_TYPE(DescType, ANGLE_RESOURCE_TYPE_TO_DESC)
ANGLE_RESOURCE_TYPE_TO_TYPE(InitDataType, ANGLE_RESOURCE_TYPE_TO_INIT_DATA)

#undef ANGLE_RESOURCE_TYPE_TO_D3D11
#undef ANGLE_RESOURCE_TYPE_TO_DESC
#undef ANGLE_RESOURCE_TYPE_TO_INIT_DATA
#undef ANGLE_RESOURCE_TYPE_TO_TYPE

#define ANGLE_TYPE_TO_RESOURCE_TYPE(NAME, OP)               \
    template <typename Param>                               \
    struct NAME;                                            \
    ANGLE_RESOURCE_TYPE_OP(NAME, OP)                        \
    \
template<typename Param> struct NAME                        \
    {                                                       \
    };                                                      \
    \
template<typename Param> constexpr ResourceType Get##NAME() \
    {                                                       \
        return NAME<Param>::Value;                          \
    }

#define ANGLE_D3D11_TO_RESOURCE_TYPE(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    \
template<> struct NAME<D3D11TYPE>                                                      \
    {                                                                                  \
        static constexpr ResourceType Value = ResourceType::RESTYPE;                   \
    };

ANGLE_TYPE_TO_RESOURCE_TYPE(ResourceTypeFromD3D11, ANGLE_D3D11_TO_RESOURCE_TYPE)

#undef ANGLE_D3D11_TO_RESOURCE_TYPE
#undef ANGLE_TYPE_TO_RESOURCE_TYPE

template <typename T>
using GetDescFromD3D11 = GetDescType<ResourceTypeFromD3D11<T>::Value>;

template <typename T>
using GetInitDataFromD3D11 = GetInitDataType<ResourceTypeFromD3D11<T>::Value>;

template <typename T>
constexpr size_t ResourceTypeIndex()
{
    return static_cast<size_t>(GetResourceTypeFromD3D11<T>());
}

template <typename T>
struct TypedData
{
    TypedData() {}
    ~TypedData();

    T *object                  = nullptr;
    ResourceManager11 *manager = nullptr;
};

// Smart pointer type. Wraps the resource and a factory for safe deletion.
template <typename T, template <class> class Pointer, typename DataT>
class Resource11Base : angle::NonCopyable
{
  public:
    T *get() const { return mData->object; }

    void setDebugName(const char *name) { d3d11::SetDebugName(mData->object, name); }

    void set(T *object)
    {
        ASSERT(!valid());
        mData->object = object;
    }

    bool valid() const { return (mData->object != nullptr); }

    void reset() { mData.reset(new DataT()); }

  protected:
    friend class TextureHelper11;

    Resource11Base() : mData(new DataT()) {}

    Resource11Base(Resource11Base &&movedObj) : mData(new DataT())
    {
        std::swap(mData, movedObj.mData);
    }

    virtual ~Resource11Base() { mData.reset(); }

    Resource11Base &operator=(Resource11Base &&movedObj)
    {
        std::swap(mData, movedObj.mData);
        return *this;
    }

    Pointer<DataT> mData;
};

template <typename T>
using UniquePtr = typename std::unique_ptr<T, std::default_delete<T>>;

template <typename ResourceT>
class Resource11 : public Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>
{
  public:
    Resource11() {}
    Resource11(Resource11 &&other)
        : Resource11Base<ResourceT, UniquePtr, TypedData<ResourceT>>(std::move(other))
    {
    }
    Resource11 &operator=(Resource11 &&other)
    {
        std::swap(this->mData, other.mData);
        return *this;
    }

  private:
    friend class ResourceManager11;

    Resource11(ResourceT *object, ResourceManager11 *manager)
    {
        this->mData->object  = object;
        this->mData->manager = manager;
    }
};

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

    template <typename T>
    gl::Error allocate(Renderer11 *renderer,
                       const GetDescFromD3D11<T> *desc,
                       GetInitDataFromD3D11<T> *initData,
                       Resource11<T> *resourceOut);

    template <typename T>
    void onRelease(T *resource);

  private:
    void incrResource(ResourceType resourceType, size_t memorySize);
    void decrResource(ResourceType resourceType, size_t memorySize);

    std::array<size_t, NumResourceTypes> mAllocatedResourceCounts;
    std::array<size_t, NumResourceTypes> mAllocatedResourceDeviceMemory;
};

template <typename ResourceT>
TypedData<ResourceT>::~TypedData()
{
    if (object)
    {
        // We can have a nullptr factory when holding passed-in resources.
        if (manager)
        {
            manager->onRelease(object);
        }
        object->Release();
    }
}

#define ANGLE_RESOURCE_TYPE_CLASS(NAME, RESTYPE, D3D11TYPE, DESCTYPE, INITDATATYPE) \
    using RESTYPE = Resource11<D3D11TYPE>;

namespace d3d11
{
ANGLE_RESOURCE_TYPE_OP(ClassList, ANGLE_RESOURCE_TYPE_CLASS)
}  // namespace d3d11

#undef ANGLE_RESOURCE_TYPE_CLASS

}  // namespace rx

#endif  // LIBANGLE_RENDERER_D3D_D3D11_RESOURCEFACTORY11_H_
