/*
 * Copyright 2022 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef skgpu_VulkanMemoryAllocator_DEFINED
#define skgpu_VulkanMemoryAllocator_DEFINED

#include "include/core/SkRefCnt.h"
#include "include/gpu/vk/VulkanTypes.h"
#include "include/private/gpu/vk/SkiaVulkan.h"

#include <cstdint>
#include <utility>

namespace skgpu {

class VulkanMemoryAllocator : public SkRefCnt {
public:
    enum AllocationPropertyFlags {
        kNone_AllocationPropertyFlag                = 0b0000,
        // Allocation will be placed in its own VkDeviceMemory and not suballocated from some larger
        // block.
        kDedicatedAllocation_AllocationPropertyFlag = 0b0001,
        // Says that the backing memory can only be accessed by the device. Additionally the device
        // may lazily allocate the memory. This cannot be used with buffers that will be host
        // visible. Setting this flag does not guarantee that we will allocate memory that respects
        // it, but we will try to prefer memory that can respect it.
        kLazyAllocation_AllocationPropertyFlag      = 0b0010,
        // The allocation will be mapped immediately and stay mapped until it is destroyed. This
        // flag is only valid for buffers which are host visible (i.e. must have a usage other than
        // BufferUsage::kGpuOnly).
        kPersistentlyMapped_AllocationPropertyFlag  = 0b0100,
        // Allocation can only be accessed by the device using a protected context.
        kProtected_AllocationPropertyFlag           = 0b1000,
    };

    enum class BufferUsage {
        // Buffers that will only be accessed from the device (large const buffers) will always be
        // in device local memory.
        kGpuOnly,
        // Buffers that typically will be updated multiple times by the host and read on the gpu
        // (e.g. uniform or vertex buffers). CPU writes will generally be sequential in the buffer
        // and will try to take advantage of the write-combined nature of the gpu buffers. Thus this
        // will always be mappable and coherent memory, and it will prefer to be in device local
        // memory.
        kCpuWritesGpuReads,
        // Buffers that will be accessed on the host and copied to another GPU resource (transfer
        // buffers). Will always be mappable and coherent memory.
        kTransfersFromCpuToGpu,
        // Buffers which are typically writted to by the GPU and then read on the host. Will always
        // be mappable memory, and will prefer cached memory.
        kTransfersFromGpuToCpu,
    };

    virtual VkResult allocateImageMemory(VkImage image,
                                         uint32_t allocationPropertyFlags,
                                         skgpu::VulkanBackendMemory* memory) = 0;

    virtual VkResult allocateBufferMemory(VkBuffer buffer,
                                          BufferUsage usage,
                                          uint32_t allocationPropertyFlags,
                                          skgpu::VulkanBackendMemory* memory) = 0;

    // Fills out the passed in skgpu::VulkanAlloc struct for the passed in
    // skgpu::VulkanBackendMemory.
    virtual void getAllocInfo(const skgpu::VulkanBackendMemory&, skgpu::VulkanAlloc*) const = 0;

    // Maps the entire allocation and returns a pointer to the start of the allocation. The
    // implementation may map more memory than just the allocation, but the returned pointer must
    // point at the start of the memory for the requested allocation.
    virtual void* mapMemory(const skgpu::VulkanBackendMemory&) { return nullptr; }
    virtual VkResult mapMemory(const skgpu::VulkanBackendMemory& memory, void** data) {
        *data = this->mapMemory(memory);
        // VK_ERROR_INITIALIZATION_FAILED is a bogus result to return from this function, but it is
        // just something to return that is not VK_SUCCESS and can't be interpreted by a caller to
        // mean something specific happened like device lost or oom. This will be removed once we
        // update clients to implement this virtual.
        return *data ? VK_SUCCESS : VK_ERROR_INITIALIZATION_FAILED;
    }
    virtual void unmapMemory(const skgpu::VulkanBackendMemory&) = 0;

    // The following two calls are used for managing non-coherent memory. The offset is relative to
    // the start of the allocation and not the underlying VkDeviceMemory. Additionaly the client
    // must make sure that the offset + size passed in is less that or equal to the allocation size.
    // It is the responsibility of the implementation to make sure all alignment requirements are
    // followed. The client should not have to deal with any sort of alignment issues.
    virtual void flushMappedMemory(const skgpu::VulkanBackendMemory&, VkDeviceSize, VkDeviceSize) {}
    virtual VkResult flushMemory(const skgpu::VulkanBackendMemory& memory,
                                 VkDeviceSize offset,
                                 VkDeviceSize size) {
        this->flushMappedMemory(memory, offset, size);
        return VK_SUCCESS;
    }
    virtual void invalidateMappedMemory(const skgpu::VulkanBackendMemory&,
                                        VkDeviceSize,
                                        VkDeviceSize) {}
    virtual VkResult invalidateMemory(const skgpu::VulkanBackendMemory& memory,
                                      VkDeviceSize offset,
                                      VkDeviceSize size) {
        this->invalidateMappedMemory(memory, offset, size);
        return VK_SUCCESS;
    }

    virtual void freeMemory(const skgpu::VulkanBackendMemory&) = 0;

    // Returns the total amount of memory that is allocated as well as total
    // amount of memory in use by an allocation from this allocator.
    // Return 1st param is total allocated memory, 2nd is total used memory.
    virtual std::pair<uint64_t, uint64_t> totalAllocatedAndUsedMemory() const = 0;
};

} // namespace skgpu

#endif // skgpu_VulkanMemoryAllocator_DEFINED
