1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLBuffer.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTraceMemoryDump.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/GpuTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLFunctions.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/ganesh/gl/GrGLInterface.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMalloc.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkTraceEvent.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/GrGpuResourcePriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLCaps.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLDefines.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLGpu.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ganesh/gl/GrGLUtil.h"
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
24*c8dee2aaSAndroid Build Coastguard Worker #include <cstring>
25*c8dee2aaSAndroid Build Coastguard Worker #include <string>
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker #define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X)
28*c8dee2aaSAndroid Build Coastguard Worker #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), RET, X)
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker #define GL_ALLOC_CALL(gpu, call) \
31*c8dee2aaSAndroid Build Coastguard Worker [&] { \
32*c8dee2aaSAndroid Build Coastguard Worker if (gpu->glCaps().skipErrorChecks()) { \
33*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL(gpu->glInterface(), call); \
34*c8dee2aaSAndroid Build Coastguard Worker return static_cast<GrGLenum>(GR_GL_NO_ERROR); \
35*c8dee2aaSAndroid Build Coastguard Worker } else { \
36*c8dee2aaSAndroid Build Coastguard Worker gpu->clearErrorsAndCheckForOOM(); \
37*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL_NOERRCHECK(gpu->glInterface(), call); \
38*c8dee2aaSAndroid Build Coastguard Worker return gpu->getErrorAndCheckForOOM(); \
39*c8dee2aaSAndroid Build Coastguard Worker } \
40*c8dee2aaSAndroid Build Coastguard Worker }()
41*c8dee2aaSAndroid Build Coastguard Worker
Make(GrGLGpu * gpu,size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern)42*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrGLBuffer> GrGLBuffer::Make(GrGLGpu* gpu,
43*c8dee2aaSAndroid Build Coastguard Worker size_t size,
44*c8dee2aaSAndroid Build Coastguard Worker GrGpuBufferType intendedType,
45*c8dee2aaSAndroid Build Coastguard Worker GrAccessPattern accessPattern) {
46*c8dee2aaSAndroid Build Coastguard Worker if (gpu->glCaps().transferBufferType() == GrGLCaps::TransferBufferType::kNone &&
47*c8dee2aaSAndroid Build Coastguard Worker (GrGpuBufferType::kXferCpuToGpu == intendedType ||
48*c8dee2aaSAndroid Build Coastguard Worker GrGpuBufferType::kXferGpuToCpu == intendedType)) {
49*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
50*c8dee2aaSAndroid Build Coastguard Worker }
51*c8dee2aaSAndroid Build Coastguard Worker
52*c8dee2aaSAndroid Build Coastguard Worker sk_sp<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern,
53*c8dee2aaSAndroid Build Coastguard Worker /*label=*/"MakeGlBuffer"));
54*c8dee2aaSAndroid Build Coastguard Worker if (0 == buffer->bufferID()) {
55*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
56*c8dee2aaSAndroid Build Coastguard Worker }
57*c8dee2aaSAndroid Build Coastguard Worker return buffer;
58*c8dee2aaSAndroid Build Coastguard Worker }
59*c8dee2aaSAndroid Build Coastguard Worker
60*c8dee2aaSAndroid Build Coastguard Worker // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
61*c8dee2aaSAndroid Build Coastguard Worker // objects are implemented as client-side-arrays on tile-deferred architectures.
62*c8dee2aaSAndroid Build Coastguard Worker #define DYNAMIC_DRAW_PARAM GR_GL_STREAM_DRAW
63*c8dee2aaSAndroid Build Coastguard Worker
gr_to_gl_access_pattern(GrGpuBufferType bufferType,GrAccessPattern accessPattern,const GrGLCaps & caps)64*c8dee2aaSAndroid Build Coastguard Worker inline static GrGLenum gr_to_gl_access_pattern(GrGpuBufferType bufferType,
65*c8dee2aaSAndroid Build Coastguard Worker GrAccessPattern accessPattern,
66*c8dee2aaSAndroid Build Coastguard Worker const GrGLCaps& caps) {
67*c8dee2aaSAndroid Build Coastguard Worker auto drawUsage = [](GrAccessPattern pattern) {
68*c8dee2aaSAndroid Build Coastguard Worker switch (pattern) {
69*c8dee2aaSAndroid Build Coastguard Worker case kDynamic_GrAccessPattern:
70*c8dee2aaSAndroid Build Coastguard Worker // TODO: Do we really want to use STREAM_DRAW here on non-Chromium?
71*c8dee2aaSAndroid Build Coastguard Worker return DYNAMIC_DRAW_PARAM;
72*c8dee2aaSAndroid Build Coastguard Worker case kStatic_GrAccessPattern:
73*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_STATIC_DRAW;
74*c8dee2aaSAndroid Build Coastguard Worker case kStream_GrAccessPattern:
75*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_STREAM_DRAW;
76*c8dee2aaSAndroid Build Coastguard Worker }
77*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
78*c8dee2aaSAndroid Build Coastguard Worker };
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker auto readUsage = [](GrAccessPattern pattern) {
81*c8dee2aaSAndroid Build Coastguard Worker switch (pattern) {
82*c8dee2aaSAndroid Build Coastguard Worker case kDynamic_GrAccessPattern:
83*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_DYNAMIC_READ;
84*c8dee2aaSAndroid Build Coastguard Worker case kStatic_GrAccessPattern:
85*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_STATIC_READ;
86*c8dee2aaSAndroid Build Coastguard Worker case kStream_GrAccessPattern:
87*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_STREAM_READ;
88*c8dee2aaSAndroid Build Coastguard Worker }
89*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
90*c8dee2aaSAndroid Build Coastguard Worker };
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker auto usageType = [&drawUsage, &readUsage, &caps](GrGpuBufferType type,
93*c8dee2aaSAndroid Build Coastguard Worker GrAccessPattern pattern) {
94*c8dee2aaSAndroid Build Coastguard Worker // GL_NV_pixel_buffer_object adds transfer buffers but not the related <usage> values.
95*c8dee2aaSAndroid Build Coastguard Worker if (caps.transferBufferType() == GrGLCaps::TransferBufferType::kNV_PBO) {
96*c8dee2aaSAndroid Build Coastguard Worker return drawUsage(pattern);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker switch (type) {
99*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kVertex:
100*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kIndex:
101*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kDrawIndirect:
102*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kXferCpuToGpu:
103*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kUniform:
104*c8dee2aaSAndroid Build Coastguard Worker return drawUsage(pattern);
105*c8dee2aaSAndroid Build Coastguard Worker case GrGpuBufferType::kXferGpuToCpu:
106*c8dee2aaSAndroid Build Coastguard Worker return readUsage(pattern);
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
109*c8dee2aaSAndroid Build Coastguard Worker };
110*c8dee2aaSAndroid Build Coastguard Worker
111*c8dee2aaSAndroid Build Coastguard Worker return usageType(bufferType, accessPattern);
112*c8dee2aaSAndroid Build Coastguard Worker }
113*c8dee2aaSAndroid Build Coastguard Worker
GrGLBuffer(GrGLGpu * gpu,size_t size,GrGpuBufferType intendedType,GrAccessPattern accessPattern,std::string_view label)114*c8dee2aaSAndroid Build Coastguard Worker GrGLBuffer::GrGLBuffer(GrGLGpu* gpu,
115*c8dee2aaSAndroid Build Coastguard Worker size_t size,
116*c8dee2aaSAndroid Build Coastguard Worker GrGpuBufferType intendedType,
117*c8dee2aaSAndroid Build Coastguard Worker GrAccessPattern accessPattern,
118*c8dee2aaSAndroid Build Coastguard Worker std::string_view label)
119*c8dee2aaSAndroid Build Coastguard Worker : INHERITED(gpu, size, intendedType, accessPattern, label)
120*c8dee2aaSAndroid Build Coastguard Worker , fIntendedType(intendedType)
121*c8dee2aaSAndroid Build Coastguard Worker , fBufferID(0)
122*c8dee2aaSAndroid Build Coastguard Worker , fUsage(gr_to_gl_access_pattern(intendedType, accessPattern, gpu->glCaps()))
123*c8dee2aaSAndroid Build Coastguard Worker , fHasAttachedToTexture(false) {
124*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(GenBuffers(1, &fBufferID));
125*c8dee2aaSAndroid Build Coastguard Worker if (fBufferID) {
126*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = gpu->bindBuffer(fIntendedType, this);
127*c8dee2aaSAndroid Build Coastguard Worker GrGLenum error = GL_ALLOC_CALL(this->glGpu(), BufferData(target,
128*c8dee2aaSAndroid Build Coastguard Worker (GrGLsizeiptr)size,
129*c8dee2aaSAndroid Build Coastguard Worker nullptr,
130*c8dee2aaSAndroid Build Coastguard Worker fUsage));
131*c8dee2aaSAndroid Build Coastguard Worker if (error != GR_GL_NO_ERROR) {
132*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(DeleteBuffers(1, &fBufferID));
133*c8dee2aaSAndroid Build Coastguard Worker fBufferID = 0;
134*c8dee2aaSAndroid Build Coastguard Worker }
135*c8dee2aaSAndroid Build Coastguard Worker }
136*c8dee2aaSAndroid Build Coastguard Worker this->registerWithCache(skgpu::Budgeted::kYes);
137*c8dee2aaSAndroid Build Coastguard Worker if (!fBufferID) {
138*c8dee2aaSAndroid Build Coastguard Worker this->resourcePriv().removeScratchKey();
139*c8dee2aaSAndroid Build Coastguard Worker }
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker
glGpu() const142*c8dee2aaSAndroid Build Coastguard Worker inline GrGLGpu* GrGLBuffer::glGpu() const {
143*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->wasDestroyed());
144*c8dee2aaSAndroid Build Coastguard Worker return static_cast<GrGLGpu*>(this->getGpu());
145*c8dee2aaSAndroid Build Coastguard Worker }
146*c8dee2aaSAndroid Build Coastguard Worker
glCaps() const147*c8dee2aaSAndroid Build Coastguard Worker inline const GrGLCaps& GrGLBuffer::glCaps() const {
148*c8dee2aaSAndroid Build Coastguard Worker return this->glGpu()->glCaps();
149*c8dee2aaSAndroid Build Coastguard Worker }
150*c8dee2aaSAndroid Build Coastguard Worker
onRelease()151*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::onRelease() {
152*c8dee2aaSAndroid Build Coastguard Worker TRACE_EVENT0("skia.gpu", TRACE_FUNC);
153*c8dee2aaSAndroid Build Coastguard Worker
154*c8dee2aaSAndroid Build Coastguard Worker if (!this->wasDestroyed()) {
155*c8dee2aaSAndroid Build Coastguard Worker // make sure we've not been abandoned or already released
156*c8dee2aaSAndroid Build Coastguard Worker if (fBufferID) {
157*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(DeleteBuffers(1, &fBufferID));
158*c8dee2aaSAndroid Build Coastguard Worker fBufferID = 0;
159*c8dee2aaSAndroid Build Coastguard Worker }
160*c8dee2aaSAndroid Build Coastguard Worker fMapPtr = nullptr;
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker INHERITED::onRelease();
164*c8dee2aaSAndroid Build Coastguard Worker }
165*c8dee2aaSAndroid Build Coastguard Worker
onAbandon()166*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::onAbandon() {
167*c8dee2aaSAndroid Build Coastguard Worker fBufferID = 0;
168*c8dee2aaSAndroid Build Coastguard Worker fMapPtr = nullptr;
169*c8dee2aaSAndroid Build Coastguard Worker INHERITED::onAbandon();
170*c8dee2aaSAndroid Build Coastguard Worker }
171*c8dee2aaSAndroid Build Coastguard Worker
invalidate_buffer(GrGLGpu * gpu,GrGLenum target,GrGLenum usage,GrGLuint bufferID,size_t bufferSize)172*c8dee2aaSAndroid Build Coastguard Worker [[nodiscard]] static inline GrGLenum invalidate_buffer(GrGLGpu* gpu,
173*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target,
174*c8dee2aaSAndroid Build Coastguard Worker GrGLenum usage,
175*c8dee2aaSAndroid Build Coastguard Worker GrGLuint bufferID,
176*c8dee2aaSAndroid Build Coastguard Worker size_t bufferSize) {
177*c8dee2aaSAndroid Build Coastguard Worker switch (gpu->glCaps().invalidateBufferType()) {
178*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::InvalidateBufferType::kNone:
179*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_NO_ERROR;
180*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::InvalidateBufferType::kNullData:
181*c8dee2aaSAndroid Build Coastguard Worker return GL_ALLOC_CALL(gpu, BufferData(target, bufferSize, nullptr, usage));
182*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::InvalidateBufferType::kInvalidate:
183*c8dee2aaSAndroid Build Coastguard Worker GR_GL_CALL(gpu->glInterface(), InvalidateBufferData(bufferID));
184*c8dee2aaSAndroid Build Coastguard Worker return GR_GL_NO_ERROR;
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
187*c8dee2aaSAndroid Build Coastguard Worker }
188*c8dee2aaSAndroid Build Coastguard Worker
onMap(MapType type)189*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::onMap(MapType type) {
190*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fBufferID);
191*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->wasDestroyed());
192*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!this->isMapped());
193*c8dee2aaSAndroid Build Coastguard Worker
194*c8dee2aaSAndroid Build Coastguard Worker // Handling dirty context is done in the bindBuffer call
195*c8dee2aaSAndroid Build Coastguard Worker switch (this->glCaps().mapBufferType()) {
196*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kNone_MapBufferType:
197*c8dee2aaSAndroid Build Coastguard Worker return;
198*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kMapBuffer_MapBufferType: {
199*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
200*c8dee2aaSAndroid Build Coastguard Worker if (type == MapType::kWriteDiscard) {
201*c8dee2aaSAndroid Build Coastguard Worker GrGLenum error = invalidate_buffer(this->glGpu(),
202*c8dee2aaSAndroid Build Coastguard Worker target,
203*c8dee2aaSAndroid Build Coastguard Worker fUsage,
204*c8dee2aaSAndroid Build Coastguard Worker fBufferID,
205*c8dee2aaSAndroid Build Coastguard Worker this->size());
206*c8dee2aaSAndroid Build Coastguard Worker if (error != GR_GL_NO_ERROR) {
207*c8dee2aaSAndroid Build Coastguard Worker return;
208*c8dee2aaSAndroid Build Coastguard Worker }
209*c8dee2aaSAndroid Build Coastguard Worker }
210*c8dee2aaSAndroid Build Coastguard Worker GrGLenum access = type == MapType::kRead ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY;
211*c8dee2aaSAndroid Build Coastguard Worker GL_CALL_RET(fMapPtr, MapBuffer(target, access));
212*c8dee2aaSAndroid Build Coastguard Worker break;
213*c8dee2aaSAndroid Build Coastguard Worker }
214*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kMapBufferRange_MapBufferType: {
215*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
216*c8dee2aaSAndroid Build Coastguard Worker GrGLbitfield access;
217*c8dee2aaSAndroid Build Coastguard Worker switch (type) {
218*c8dee2aaSAndroid Build Coastguard Worker case MapType::kRead:
219*c8dee2aaSAndroid Build Coastguard Worker access = GR_GL_MAP_READ_BIT;
220*c8dee2aaSAndroid Build Coastguard Worker break;
221*c8dee2aaSAndroid Build Coastguard Worker case MapType::kWriteDiscard:
222*c8dee2aaSAndroid Build Coastguard Worker access = GR_GL_MAP_WRITE_BIT | GR_GL_MAP_INVALIDATE_BUFFER_BIT;
223*c8dee2aaSAndroid Build Coastguard Worker break;
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker GL_CALL_RET(fMapPtr, MapBufferRange(target, 0, this->size(), access));
226*c8dee2aaSAndroid Build Coastguard Worker break;
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kChromium_MapBufferType: {
229*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
230*c8dee2aaSAndroid Build Coastguard Worker GrGLenum access = type == MapType::kRead ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY;
231*c8dee2aaSAndroid Build Coastguard Worker GL_CALL_RET(fMapPtr, MapBufferSubData(target, 0, this->size(), access));
232*c8dee2aaSAndroid Build Coastguard Worker break;
233*c8dee2aaSAndroid Build Coastguard Worker }
234*c8dee2aaSAndroid Build Coastguard Worker }
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker
onUnmap(MapType)237*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::onUnmap(MapType) {
238*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fBufferID);
239*c8dee2aaSAndroid Build Coastguard Worker // bind buffer handles the dirty context
240*c8dee2aaSAndroid Build Coastguard Worker switch (this->glCaps().mapBufferType()) {
241*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kNone_MapBufferType:
242*c8dee2aaSAndroid Build Coastguard Worker SkUNREACHABLE;
243*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kMapBuffer_MapBufferType: // fall through
244*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kMapBufferRange_MapBufferType: {
245*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
246*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(UnmapBuffer(target));
247*c8dee2aaSAndroid Build Coastguard Worker break;
248*c8dee2aaSAndroid Build Coastguard Worker }
249*c8dee2aaSAndroid Build Coastguard Worker case GrGLCaps::kChromium_MapBufferType:
250*c8dee2aaSAndroid Build Coastguard Worker this->glGpu()->bindBuffer(fIntendedType, this); // TODO: Is this needed?
251*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(UnmapBufferSubData(fMapPtr));
252*c8dee2aaSAndroid Build Coastguard Worker break;
253*c8dee2aaSAndroid Build Coastguard Worker }
254*c8dee2aaSAndroid Build Coastguard Worker fMapPtr = nullptr;
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker
onClearToZero()257*c8dee2aaSAndroid Build Coastguard Worker bool GrGLBuffer::onClearToZero() {
258*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fBufferID);
259*c8dee2aaSAndroid Build Coastguard Worker
260*c8dee2aaSAndroid Build Coastguard Worker // We could improve this on GL 4.3+ with glClearBufferData (also GL_ARB_clear_buffer_object).
261*c8dee2aaSAndroid Build Coastguard Worker this->onMap(GrGpuBuffer::MapType::kWriteDiscard);
262*c8dee2aaSAndroid Build Coastguard Worker if (fMapPtr) {
263*c8dee2aaSAndroid Build Coastguard Worker std::memset(fMapPtr, 0, this->size());
264*c8dee2aaSAndroid Build Coastguard Worker this->onUnmap(GrGpuBuffer::MapType::kWriteDiscard);
265*c8dee2aaSAndroid Build Coastguard Worker return true;
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker
268*c8dee2aaSAndroid Build Coastguard Worker void* zeros = sk_calloc_throw(this->size());
269*c8dee2aaSAndroid Build Coastguard Worker bool result = this->updateData(zeros, 0, this->size(), /*preserve=*/false);
270*c8dee2aaSAndroid Build Coastguard Worker sk_free(zeros);
271*c8dee2aaSAndroid Build Coastguard Worker return result;
272*c8dee2aaSAndroid Build Coastguard Worker }
273*c8dee2aaSAndroid Build Coastguard Worker
onUpdateData(const void * src,size_t offset,size_t size,bool preserve)274*c8dee2aaSAndroid Build Coastguard Worker bool GrGLBuffer::onUpdateData(const void* src, size_t offset, size_t size, bool preserve) {
275*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fBufferID);
276*c8dee2aaSAndroid Build Coastguard Worker
277*c8dee2aaSAndroid Build Coastguard Worker // bindbuffer handles dirty context
278*c8dee2aaSAndroid Build Coastguard Worker GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
279*c8dee2aaSAndroid Build Coastguard Worker if (!preserve) {
280*c8dee2aaSAndroid Build Coastguard Worker GrGLenum error = invalidate_buffer(this->glGpu(), target, fUsage, fBufferID, this->size());
281*c8dee2aaSAndroid Build Coastguard Worker if (error != GR_GL_NO_ERROR) {
282*c8dee2aaSAndroid Build Coastguard Worker return false;
283*c8dee2aaSAndroid Build Coastguard Worker }
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(BufferSubData(target, offset, size, src));
286*c8dee2aaSAndroid Build Coastguard Worker return true;
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker
onSetLabel()289*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::onSetLabel() {
290*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fBufferID);
291*c8dee2aaSAndroid Build Coastguard Worker if (!this->getLabel().empty()) {
292*c8dee2aaSAndroid Build Coastguard Worker const std::string label = "_Skia_" + this->getLabel();
293*c8dee2aaSAndroid Build Coastguard Worker if (this->glGpu()->glCaps().debugSupport()) {
294*c8dee2aaSAndroid Build Coastguard Worker GL_CALL(ObjectLabel(GR_GL_BUFFER, fBufferID, -1, label.c_str()));
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker }
298*c8dee2aaSAndroid Build Coastguard Worker
setMemoryBacking(SkTraceMemoryDump * traceMemoryDump,const SkString & dumpName) const299*c8dee2aaSAndroid Build Coastguard Worker void GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
300*c8dee2aaSAndroid Build Coastguard Worker const SkString& dumpName) const {
301*c8dee2aaSAndroid Build Coastguard Worker SkString buffer_id;
302*c8dee2aaSAndroid Build Coastguard Worker buffer_id.appendU32(this->bufferID());
303*c8dee2aaSAndroid Build Coastguard Worker traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer", buffer_id.c_str());
304*c8dee2aaSAndroid Build Coastguard Worker }
305