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

#ifndef GrEagerVertexAllocator_DEFINED
#define GrEagerVertexAllocator_DEFINED

#include "src/gpu/ops/GrMeshDrawOp.h"

// This interface is used to allocate and map GPU vertex data before the exact number of required
// vertices is known. Usage pattern:
//
//   1. Call lock(eagerCount) with an upper bound on the number of required vertices.
//   2. Compute and write vertex data to the returned pointer (if not null).
//   3. Call unlock(actualCount) and provide the actual number of vertices written during step #2.
//
// On step #3, the implementation will attempt to shrink the underlying GPU memory slot to fit the
// actual vertex count.
class GrEagerVertexAllocator {
public:
    template<typename T> T* lock(int eagerCount) {
        return static_cast<T*>(this->lock(sizeof(T), eagerCount));
    }
    virtual void* lock(size_t stride, int eagerCount) = 0;

    virtual void unlock(int actualCount) = 0;

    virtual ~GrEagerVertexAllocator() {}
};

// GrEagerVertexAllocator implementation that uses GrMeshDrawOp::Target::makeVertexSpace and
// GrMeshDrawOp::Target::putBackVertices.
class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator {
public:
    GrEagerDynamicVertexAllocator(GrMeshDrawOp::Target* target,
                                   sk_sp<const GrBuffer>* vertexBuffer, int* baseVertex)
            : fTarget(target)
            , fVertexBuffer(vertexBuffer)
            , fBaseVertex(baseVertex) {
    }

#ifdef SK_DEBUG
    ~GrEagerDynamicVertexAllocator() override {
        SkASSERT(!fLockCount);
    }
#endif

    void* lock(size_t stride, int eagerCount) override {
        SkASSERT(!fLockCount);
        SkASSERT(eagerCount);
        if (void* data = fTarget->makeVertexSpace(stride, eagerCount, fVertexBuffer, fBaseVertex)) {
            fLockStride = stride;
            fLockCount = eagerCount;
            return data;
        }
        fVertexBuffer->reset();
        *fBaseVertex = 0;
        return nullptr;
    }

    void unlock(int actualCount) override {
        SkASSERT(fLockCount);
        SkASSERT(actualCount <= fLockCount);
        fTarget->putBackVertices(fLockCount - actualCount, fLockStride);
        if (!actualCount) {
            fVertexBuffer->reset();
            *fBaseVertex = 0;
        }
        fLockCount = 0;
    }

private:
    GrMeshDrawOp::Target* const fTarget;
    sk_sp<const GrBuffer>* const fVertexBuffer;
    int* const fBaseVertex;

    size_t fLockStride;
    int fLockCount = 0;
};

#endif
