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 "include/core/SkRefCnt.h" 12 #include "include/private/base/SkAssert.h" 13 #include "include/private/base/SkMath.h" 14 #include "src/gpu/ganesh/GrGpuBuffer.h" 15 16 #include <cstddef> 17 #include <cstdint> 18 #include <vector> 19 20 class GrGpu; 21 enum class GrGpuBufferType; 22 23 /** 24 * A wrapper for a GPU buffer that allocates slices in a continuous ring. 25 * 26 * It's assumed that suballocate and startSubmit are always called in the same thread, 27 * and that finishSubmit could be called in a separate thread. 28 */ 29 class GrRingBuffer { 30 public: GrRingBuffer(GrGpu * gpu,size_t size,size_t alignment,GrGpuBufferType intendedType)31 GrRingBuffer(GrGpu* gpu, size_t size, size_t alignment, GrGpuBufferType intendedType) 32 : fGpu(gpu) 33 , fTotalSize(size) 34 , fAlignment(alignment) 35 , fType(intendedType) 36 , fNewAllocation(false) 37 , fHead(0) 38 , fTail(0) 39 , fGenID(0) { 40 // We increment fHead and fTail without bound and let overflow handle any wrapping. 41 // Because of this, size needs to be a power of two. 42 SkASSERT(SkIsPow2(size)); 43 } 44 45 struct Slice { 46 GrGpuBuffer* fBuffer; 47 size_t fOffset; 48 }; 49 Slice suballocate(size_t size); 50 51 // Backends should call startSubmit() at submit time 52 void startSubmit(GrGpu*); 53 size()54 size_t size() const { return fTotalSize; } 55 56 private: 57 size_t getAllocationOffset(size_t size); 58 struct SubmitData { 59 GrRingBuffer* fOwner; 60 size_t fLastHead; 61 size_t fGenID; 62 }; 63 static void FinishSubmit(void*); 64 65 GrGpu* fGpu; 66 sk_sp<GrGpuBuffer> fCurrentBuffer; 67 std::vector<sk_sp<GrGpuBuffer>> fPreviousBuffers; // previous buffers we've used in this submit 68 size_t fTotalSize; 69 size_t fAlignment; 70 GrGpuBufferType fType; 71 bool fNewAllocation; // true if there's been a new allocation in this submit 72 size_t fHead; // where we start allocating 73 size_t fTail; // where we start deallocating 74 uint64_t fGenID; // incremented when createBuffer is called 75 }; 76 77 #endif 78