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

#ifndef GrBuffer_DEFINED
#define GrBuffer_DEFINED

#include "GrGpuResource.h"

class GrGpu;

class GrBuffer : public GrGpuResource {
public:
    /**
     * Creates a client-side buffer.
     */
    static SK_WARN_UNUSED_RESULT sk_sp<GrBuffer> MakeCPUBacked(GrGpu*, size_t sizeInBytes,
                                                               GrBufferType,
                                                               const void* data = nullptr);

    /**
     * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with
     * "static" and "stream" patterns are disqualified by nature from being cached and reused.)
     */
    static void ComputeScratchKeyForDynamicVBO(size_t size, GrBufferType, GrScratchKey*);

    GrAccessPattern accessPattern() const { return fAccessPattern; }
    size_t sizeInBytes() const { return fSizeInBytes; }

    /**
     * Returns true if the buffer is a wrapper around a CPU array. If true it
     * indicates that map will always succeed and will be free.
     */
    bool isCPUBacked() const { return SkToBool(fCPUData); }
    size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); }

    /**
     * Maps the buffer to be written by the CPU.
     *
     * The previous content of the buffer is invalidated. It is an error
     * to draw from the buffer while it is mapped. It may fail if the backend
     * doesn't support mapping the buffer. If the buffer is CPU backed then
     * it will always succeed and is a free operation. Once a buffer is mapped,
     * subsequent calls to map() are ignored.
     *
     * Note that buffer mapping does not go through GrContext and therefore is
     * not serialized with other operations.
     *
     * @return a pointer to the data or nullptr if the map fails.
     */
     void* map() {
         if (!fMapPtr) {
             this->onMap();
         }
         return fMapPtr;
     }

    /**
     * Unmaps the buffer.
     *
     * The pointer returned by the previous map call will no longer be valid.
     */
     void unmap() {
         SkASSERT(fMapPtr);
         this->onUnmap();
         fMapPtr = nullptr;
     }

    /**
     Queries whether the buffer has been mapped.

     @return true if the buffer is mapped, false otherwise.
     */
     bool isMapped() const { return SkToBool(fMapPtr); }

    /**
     * Updates the buffer data.
     *
     * The size of the buffer will be preserved. The src data will be
     * placed at the beginning of the buffer and any remaining contents will
     * be undefined. srcSizeInBytes must be <= to the buffer size.
     *
     * The buffer must not be mapped.
     *
     * Note that buffer updates do not go through GrContext and therefore are
     * not serialized with other operations.
     *
     * @return returns true if the update succeeds, false otherwise.
     */
    bool updateData(const void* src, size_t srcSizeInBytes) {
        SkASSERT(!this->isMapped());
        SkASSERT(srcSizeInBytes <= fSizeInBytes);
        return this->onUpdateData(src, srcSizeInBytes);
    }

    ~GrBuffer() override {
        sk_free(fCPUData);
    }

protected:
    GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, GrAccessPattern);

    void* fMapPtr;

private:
    /**
     * Internal constructor to make a CPU-backed buffer.
     */
    GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, void* cpuData);

    virtual void onMap() { SkASSERT(this->isCPUBacked()); fMapPtr = fCPUData; }
    virtual void onUnmap() { SkASSERT(this->isCPUBacked()); }
    virtual bool onUpdateData(const void* src, size_t srcSizeInBytes);

    size_t onGpuMemorySize() const override { return fSizeInBytes; } // TODO: zero for cpu backed?
    const char* getResourceType() const override { return "Buffer Object"; }
    void computeScratchKey(GrScratchKey* key) const override;

    size_t            fSizeInBytes;
    GrAccessPattern   fAccessPattern;
    void*             fCPUData;
    GrBufferType      fIntendedType;

    typedef GrGpuResource INHERITED;
};

#endif
