1 /* 2 * Copyright 2020 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrRingBuffer_DEFINED 9 #define GrRingBuffer_DEFINED 10 11 #include "src/gpu/GrGpuBuffer.h" 12 13 #include <vector> 14 15 class GrGpu; 16 17 /** 18 * A wrapper for a GPU buffer that allocates slices in a continuous ring. 19 * 20 * It's assumed that suballocate and startSubmit are always called in the same thread, 21 * and that finishSubmit could be called in a separate thread. 22 */ 23 class GrRingBuffer { 24 public: GrRingBuffer(GrGpu * gpu,size_t size,size_t alignment,GrGpuBufferType intendedType)25 GrRingBuffer(GrGpu* gpu, size_t size, size_t alignment, GrGpuBufferType intendedType) 26 : fGpu(gpu) 27 , fTotalSize(size) 28 , fAlignment(alignment) 29 , fType(intendedType) 30 , fHead(0) 31 , fTail(0) 32 , fGenID(0) { 33 // We increment fHead and fTail without bound and let overflow handle any wrapping. 34 // Because of this, size needs to be a power of two. 35 SkASSERT(SkIsPow2(size)); 36 } 37 38 struct Slice { 39 GrGpuBuffer* fBuffer; 40 size_t fOffset; 41 }; 42 Slice suballocate(size_t size); 43 44 // Backends should call startSubmit() at submit time 45 void startSubmit(GrGpu*); 46 size()47 size_t size() const { return fTotalSize; } 48 49 private: 50 size_t getAllocationOffset(size_t size); 51 struct SubmitData { 52 GrRingBuffer* fOwner; 53 size_t fLastHead; 54 size_t fGenID; 55 }; 56 static void FinishSubmit(void*); 57 58 GrGpu* fGpu; 59 sk_sp<GrGpuBuffer> fCurrentBuffer; 60 std::vector<sk_sp<GrGpuBuffer>> fTrackedBuffers; // all buffers we've used in this submit 61 size_t fTotalSize; 62 size_t fAlignment; 63 GrGpuBufferType fType; 64 size_t fHead; // where we start allocating 65 size_t fTail; // where we start deallocating 66 uint64_t fGenID; // incremented when createBuffer is called 67 }; 68 69 #endif 70