blob: 29be9cce22e266efcbb8d5fc03873e23ef50923e [file] [log] [blame]
/*
* 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/BufferWriter.h"
#include "src/gpu/ganesh/GrThreadSafeCache.h"
class GrMeshDrawTarget;
// 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:
virtual void* lock(size_t stride, int eagerCount) = 0;
virtual void unlock(int actualCount) = 0;
virtual ~GrEagerVertexAllocator() {}
skgpu::VertexWriter lockWriter(size_t stride, int eagerCount) {
void* p = this->lock(stride, eagerCount);
return p ? skgpu::VertexWriter{p, stride * eagerCount} : skgpu::VertexWriter{};
}
};
// GrEagerVertexAllocator implementation that uses GrMeshDrawTarget::makeVertexSpace and
// GrMeshDrawTarget::putBackVertices.
class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator {
public:
GrEagerDynamicVertexAllocator(GrMeshDrawTarget* target,
sk_sp<const GrBuffer>* vertexBuffer,
int* baseVertex)
: fTarget(target)
, fVertexBuffer(vertexBuffer)
, fBaseVertex(baseVertex) {
}
#ifdef SK_DEBUG
~GrEagerDynamicVertexAllocator() override {
SkASSERT(!fLockCount);
}
#endif
// Mark "final" as a hint for the compiler to not use the vtable.
void* lock(size_t stride, int eagerCount) final;
// Mark "final" as a hint for the compiler to not use the vtable.
void unlock(int actualCount) final;
private:
GrMeshDrawTarget* const fTarget;
sk_sp<const GrBuffer>* const fVertexBuffer;
int* const fBaseVertex;
size_t fLockStride;
int fLockCount = 0;
};
class GrCpuVertexAllocator : public GrEagerVertexAllocator {
public:
GrCpuVertexAllocator() = default;
#ifdef SK_DEBUG
~GrCpuVertexAllocator() override {
SkASSERT(!fLockStride && !fVertices && !fVertexData);
}
#endif
void* lock(size_t stride, int eagerCount) override;
void unlock(int actualCount) override;
sk_sp<GrThreadSafeCache::VertexData> detachVertexData();
private:
sk_sp<GrThreadSafeCache::VertexData> fVertexData;
void* fVertices = nullptr;
size_t fLockStride = 0;
};
#endif