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

#ifndef GrVkBuffer_DEFINED
#define GrVkBuffer_DEFINED

#include "GrVkResource.h"
#include "vk/GrVkDefines.h"
#include "vk/GrVkTypes.h"

class GrVkGpu;

/**
 * This class serves as the base of GrVk*Buffer classes. It was written to avoid code
 * duplication in those classes.
 */
class GrVkBuffer : public SkNoncopyable {
public:
    virtual ~GrVkBuffer() {
        // either release or abandon should have been called by the owner of this object.
        SkASSERT(!fResource);
        delete [] (unsigned char*)fMapPtr;
    }

    VkBuffer                    buffer() const { return fResource->fBuffer; }
    const GrVkAlloc&            alloc() const { return fResource->fAlloc; }
    const GrVkRecycledResource* resource() const { return fResource; }
    size_t                      size() const { return fDesc.fSizeInBytes; }
    VkDeviceSize                offset() const { return fOffset;  }

    void addMemoryBarrier(const GrVkGpu* gpu,
                          VkAccessFlags srcAccessMask,
                          VkAccessFlags dstAccessMask,
                          VkPipelineStageFlags srcStageMask,
                          VkPipelineStageFlags dstStageMask,
                          bool byRegion) const;

    enum Type {
        kVertex_Type,
        kIndex_Type,
        kUniform_Type,
        kTexel_Type,
        kCopyRead_Type,
        kCopyWrite_Type,
    };

protected:
    struct Desc {
        size_t      fSizeInBytes;
        Type        fType;         // vertex buffer, index buffer, etc.
        bool        fDynamic;
    };

    class Resource : public GrVkRecycledResource {
    public:
        Resource(VkBuffer buf, const GrVkAlloc& alloc, Type type)
            : INHERITED(), fBuffer(buf), fAlloc(alloc), fType(type) {}

#ifdef SK_TRACE_VK_RESOURCES
        void dumpInfo() const override {
            SkDebugf("GrVkBuffer: %d (%d refs)\n", fBuffer, this->getRefCnt());
        }
#endif
        VkBuffer           fBuffer;
        GrVkAlloc          fAlloc;
        Type               fType;

    private:
        void freeGPUData(const GrVkGpu* gpu) const override;

        void onRecycle(GrVkGpu* gpu) const override { this->unref(gpu); }

        typedef GrVkRecycledResource INHERITED;
    };

    // convenience routine for raw buffer creation
    static const Resource* Create(const GrVkGpu* gpu,
                                  const Desc& descriptor);

    GrVkBuffer(const Desc& desc, const GrVkBuffer::Resource* resource)
        : fDesc(desc), fResource(resource), fOffset(0), fMapPtr(nullptr), fMappedSize(0) {
    }

    void* vkMap(GrVkGpu* gpu) {
        this->internalMap(gpu, fDesc.fSizeInBytes);
        return fMapPtr;
    }
    void vkUnmap(GrVkGpu* gpu) { this->internalUnmap(gpu, this->size()); }

    // If the caller passes in a non null createdNewBuffer, this function will set the bool to true
    // if it creates a new VkBuffer to upload the data to.
    bool vkUpdateData(GrVkGpu* gpu, const void* src, size_t srcSizeInBytes,
                      bool* createdNewBuffer = nullptr);

    void vkAbandon();
    void vkRelease(const GrVkGpu* gpu);

private:
    virtual const Resource* createResource(GrVkGpu* gpu,
                                           const Desc& descriptor) {
        return Create(gpu, descriptor);
    }

    void internalMap(GrVkGpu* gpu, size_t size, bool* createdNewBuffer = nullptr);
    void internalUnmap(GrVkGpu* gpu, size_t size);

    void validate() const;
    bool vkIsMapped() const;

    Desc                    fDesc;
    const Resource*         fResource;
    VkDeviceSize            fOffset;
    void*                   fMapPtr;
    // On certain Intel devices/drivers there is a bug if we try to flush non-coherent memory and
    // pass in VK_WHOLE_SIZE. Thus we track our mapped size and explicitly set it when calling flush
    VkDeviceSize            fMappedSize;

    typedef SkNoncopyable INHERITED;
};

#endif
