1/*
2 * Copyright 2020 Google Inc.
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 GrAutoMapVertexBuffer_DEFINED
9#define GrAutoMapVertexBuffer_DEFINED
10
11#include "include/private/SkNoncopyable.h"
12#include "src/gpu/GrGpuBuffer.h"
13#include "src/gpu/GrOnFlushResourceProvider.h"
14
15// This class automatically allocates and maps a GPU vertex buffer, and polyfills the mapping
16// functionality with a mirror buffer on CPU if it is not supported.
17class GrAutoMapVertexBuffer : SkNoncopyable {
18public:
19 ~GrAutoMapVertexBuffer() {
20 if (this->isMapped()) {
21 this->unmapBuffer();
22 }
23 }
24
25 bool hasGpuBuffer() const { return SkToBool(fGpuBuffer.get()); }
26 sk_sp<const GrGpuBuffer> gpuBuffer() const { return fGpuBuffer; }
27 bool isMapped() const { return SkToBool(fData); }
28 void* data() const { SkASSERT(this->isMapped()); return fData; }
29
30 void resetAndMapBuffer(GrOnFlushResourceProvider* onFlushRP, size_t sizeInBytes) {
31 if (this->isMapped()) {
32 this->unmapBuffer();
33 }
34 fGpuBuffer = onFlushRP->makeBuffer(GrGpuBufferType::kVertex, sizeInBytes);
35 if (!fGpuBuffer) {
36 fSizeInBytes = 0;
37 fData = nullptr;
38 return;
39 }
40 fSizeInBytes = sizeInBytes;
41 fData = fGpuBuffer->map();
42 if (!fData) {
43 // Mapping failed. Allocate a mirror buffer on CPU.
44 fData = sk_malloc_throw(fSizeInBytes);
45 }
46 }
47
48 void unmapBuffer() {
49 SkASSERT(this->isMapped());
50 if (fGpuBuffer->isMapped()) {
51 fGpuBuffer->unmap();
52 } else {
53 // fData is a mirror buffer on CPU.
54 fGpuBuffer->updateData(fData, fSizeInBytes);
55 sk_free(fData);
56 }
57 fData = nullptr;
58 }
59
60protected:
61 sk_sp<GrGpuBuffer> fGpuBuffer;
62 size_t fSizeInBytes = 0;
63 void* fData = nullptr;
64};
65
66template<typename T> class GrTAutoMapVertexBuffer : public GrAutoMapVertexBuffer {
67public:
68 T& operator[](int idx) {
69 SkASSERT(this->isMapped());
70 SkASSERT(idx >= 0 && (size_t)idx < fSizeInBytes / sizeof(T));
71 return ((T*)fData)[idx];
72 }
73};
74
75#endif
76