/* * Copyright 2020 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrRingBuffer_DEFINED #define GrRingBuffer_DEFINED #include "src/gpu/GrGpuBuffer.h" #include class GrGpu; /** * A wrapper for a GPU buffer that allocates slices in a continuous ring. * * It's assumed that suballocate and startSubmit are always called in the same thread, * and that finishSubmit could be called in a separate thread. */ class GrRingBuffer { public: GrRingBuffer(GrGpu* gpu, size_t size, size_t alignment, GrGpuBufferType intendedType) : fGpu(gpu) , fTotalSize(size) , fAlignment(alignment) , fType(intendedType) , fHead(0) , fTail(0) , fGenID(0) { // We increment fHead and fTail without bound and let overflow handle any wrapping. // Because of this, size needs to be a power of two. SkASSERT(SkIsPow2(size)); } struct Slice { GrGpuBuffer* fBuffer; size_t fOffset; }; Slice suballocate(size_t size); // Backends should call startSubmit() at submit time void startSubmit(GrGpu*); size_t size() const { return fTotalSize; } private: size_t getAllocationOffset(size_t size); struct SubmitData { GrRingBuffer* fOwner; size_t fLastHead; size_t fGenID; }; static void FinishSubmit(void*); GrGpu* fGpu; sk_sp fCurrentBuffer; std::vector> fTrackedBuffers; // all buffers we've used in this submit size_t fTotalSize; size_t fAlignment; GrGpuBufferType fType; size_t fHead; // where we start allocating size_t fTail; // where we start deallocating uint64_t fGenID; // incremented when createBuffer is called }; #endif