1 /*
2  * Copyright 2019 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 GrGpuBuffer_DEFINED
9 #define GrGpuBuffer_DEFINED
10 
11 #include "src/gpu/GrBuffer.h"
12 #include "src/gpu/GrGpuResource.h"
13 
14 class GrGpu;
15 
16 class GrGpuBuffer : public GrGpuResource, public GrBuffer {
17 public:
18     /**
19      * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with
20      * "static" and "stream" patterns are disqualified by nature from being cached and reused.)
21      */
22     static void ComputeScratchKeyForDynamicBuffer(size_t size, GrGpuBufferType, GrScratchKey*);
23 
accessPattern()24     GrAccessPattern accessPattern() const { return fAccessPattern; }
25 
size()26     size_t size() const final { return fSizeInBytes; }
27 
ref()28     void ref() const final { GrGpuResource::ref(); }
29 
unref()30     void unref() const final { GrGpuResource::unref(); }
31 
32     /**
33      * Maps the buffer to be read or written by the CPU.
34      *
35      * It is an error to draw from the buffer while it is mapped or transfer to/from the buffer. It
36      * may fail if the backend doesn't support mapping the buffer. Once a buffer is mapped,
37      * subsequent calls to map() trivially succeed. No matter how many times map() is called,
38      * umap() will unmap the buffer on the first call if it is mapped.
39      *
40      * If the buffer is of type GrGpuBufferType::kXferGpuToCpu then it is mapped for reading only.
41      * Otherwise it is mapped writing only. Writing to a buffer that is mapped for reading or vice
42      * versa produces undefined results. If the buffer is mapped for writing then then the buffer's
43      * previous contents are invalidated.
44      *
45      * @return a pointer to the data or nullptr if the map fails.
46      */
47     void* map();
48 
49     /**
50      * Unmaps the buffer if it is mapped.
51      *
52      * The pointer returned by the previous map call will no longer be valid.
53      */
54     void unmap();
55 
56     /**
57      * Queries whether the buffer has been mapped.
58      *
59      * @return true if the buffer is mapped, false otherwise.
60      */
61     bool isMapped() const;
62 
isCpuBuffer()63     bool isCpuBuffer() const final { return false; }
64 
65     /**
66      * Updates the buffer data.
67      *
68      * The size of the buffer will be preserved. The src data will be
69      * placed at the beginning of the buffer and any remaining contents will
70      * be undefined. srcSizeInBytes must be <= to the buffer size.
71      *
72      * The buffer must not be mapped.
73      *
74      * Fails for GrGpuBufferType::kXferGpuToCpu.
75      *
76      * Note that buffer updates do not go through GrContext and therefore are
77      * not serialized with other operations.
78      *
79      * @return returns true if the update succeeds, false otherwise.
80      */
81     bool updateData(const void* src, size_t srcSizeInBytes);
82 
83 protected:
84     GrGpuBuffer(GrGpu*, size_t sizeInBytes, GrGpuBufferType, GrAccessPattern);
intendedType()85     GrGpuBufferType intendedType() const { return fIntendedType; }
86 
87     void* fMapPtr;
88 
89 private:
90     virtual void onMap() = 0;
91     virtual void onUnmap() = 0;
92     virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0;
93 
onGpuMemorySize()94     size_t onGpuMemorySize() const override { return fSizeInBytes; }
getResourceType()95     const char* getResourceType() const override { return "Buffer Object"; }
96     void computeScratchKey(GrScratchKey* key) const override;
97 
98     size_t            fSizeInBytes;
99     GrAccessPattern   fAccessPattern;
100     GrGpuBufferType   fIntendedType;
101 
102 #ifdef SK_DEBUG
103     // Static and stream access buffers are only ever written to once. This is used to track that
104     // and assert it is true.
105     bool              fHasWrittenToBuffer = false;
106 #endif
107 };
108 
109 #endif
110