Cache CPU memory buffers used for client side arrays.
Use same cache for CPU-side copy of data when using GPU buffers.
Change-Id: I09f2837211a30aabc50e9897c090f5fbc6d90492
Reviewed-on: https://skia-review.googlesource.com/c/189484
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrBufferAllocPool.h b/src/gpu/GrBufferAllocPool.h
index d0fda19..b499e80 100644
--- a/src/gpu/GrBufferAllocPool.h
+++ b/src/gpu/GrBufferAllocPool.h
@@ -8,14 +8,14 @@
#ifndef GrBufferAllocPool_DEFINED
#define GrBufferAllocPool_DEFINED
-#include "GrGpuBuffer.h"
+#include "GrCpuBuffer.h"
+#include "GrNonAtomicRef.h"
#include "GrTypesPriv.h"
#include "SkNoncopyable.h"
#include "SkTArray.h"
#include "SkTDArray.h"
#include "SkTypes.h"
-
class GrGpu;
/**
@@ -35,6 +35,28 @@
static constexpr size_t kDefaultBufferSize = 1 << 15;
/**
+ * A cache object that can be shared by multiple GrBufferAllocPool instances. It caches
+ * cpu buffer allocations to avoid reallocating them.
+ */
+ class CpuBufferCache : public GrNonAtomicRef<CpuBufferCache> {
+ public:
+ static sk_sp<CpuBufferCache> Make(int maxBuffersToCache);
+
+ sk_sp<GrCpuBuffer> makeBuffer(size_t size, bool mustBeInitialized);
+ void releaseAll();
+
+ private:
+ CpuBufferCache(int maxBuffersToCache);
+
+ struct Buffer {
+ sk_sp<GrCpuBuffer> fBuffer;
+ bool fCleared = false;
+ };
+ std::unique_ptr<Buffer[]> fBuffers;
+ int fMaxBuffersToCache = 0;
+ };
+
+ /**
* Ensures all buffers are unmapped and have all data written to them.
* Call before drawing using buffers from the pool.
*/
@@ -56,11 +78,11 @@
*
* @param gpu The GrGpu used to create the buffers.
* @param bufferType The type of buffers to create.
- * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
- * This parameter can be used to avoid malloc/free when all
- * usages can be satisfied with default-sized buffers.
+ * @param cpuBufferCache If non-null a cache for client side array buffers
+ * or staging buffers used before data is uploaded to
+ * GPU buffer objects.
*/
- GrBufferAllocPool(GrGpu* gpu, GrGpuBufferType bufferType, void* initialBuffer);
+ GrBufferAllocPool(GrGpu* gpu, GrGpuBufferType bufferType, sk_sp<CpuBufferCache> cpuBufferCache);
virtual ~GrBufferAllocPool();
@@ -129,18 +151,17 @@
void destroyBlock();
void deleteBlocks();
void flushCpuData(const BufferBlock& block, size_t flushSize);
- void* resetCpuData(size_t newSize);
+ void resetCpuData(size_t newSize);
#ifdef SK_DEBUG
void validate(bool unusedBlockAllowed = false) const;
#endif
size_t fBytesInUse = 0;
SkTArray<BufferBlock> fBlocks;
+ sk_sp<CpuBufferCache> fCpuBufferCache;
+ sk_sp<GrCpuBuffer> fCpuStagingBuffer;
GrGpu* fGpu;
GrGpuBufferType fBufferType;
- void* fInitialCpuData = nullptr;
- void* fCpuData = nullptr;
- size_t fCpuDataSize = 0;
void* fBufferPtr = nullptr;
};
@@ -153,11 +174,11 @@
* Constructor
*
* @param gpu The GrGpu used to create the vertex buffers.
- * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
- * This parameter can be used to avoid malloc/free when all
- * usages can be satisfied with default-sized buffers.
+ * @param cpuBufferCache If non-null a cache for client side array buffers
+ * or staging buffers used before data is uploaded to
+ * GPU buffer objects.
*/
- GrVertexBufferAllocPool(GrGpu* gpu, void* initialBuffer);
+ GrVertexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
/**
* Returns a block of memory to hold vertices. A buffer designated to hold
@@ -232,11 +253,11 @@
* Constructor
*
* @param gpu The GrGpu used to create the index buffers.
- * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
- * This parameter can be used to avoid malloc/free when all
- * usages can be satisfied with default-sized buffers.
+ * @param cpuBufferCache If non-null a cache for client side array buffers
+ * or staging buffers used before data is uploaded to
+ * GPU buffer objects.
*/
- GrIndexBufferAllocPool(GrGpu* gpu, void* initialBuffer);
+ GrIndexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
/**
* Returns a block of memory to hold indices. A buffer designated to hold