1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLBuffer.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#include "include/core/SkTraceMemoryDump.h"
11cb93a386Sopenharmony_ci#include "src/core/SkTraceEvent.h"
12cb93a386Sopenharmony_ci#include "src/gpu/GrGpuResourcePriv.h"
13cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLCaps.h"
14cb93a386Sopenharmony_ci#include "src/gpu/gl/GrGLGpu.h"
15cb93a386Sopenharmony_ci
16cb93a386Sopenharmony_ci#define GL_CALL(X) GR_GL_CALL(this->glGpu()->glInterface(), X)
17cb93a386Sopenharmony_ci#define GL_CALL_RET(RET, X) GR_GL_CALL_RET(this->glGpu()->glInterface(), RET, X)
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci#define GL_ALLOC_CALL(call)                                            \
20cb93a386Sopenharmony_ci    [&] {                                                              \
21cb93a386Sopenharmony_ci        if (this->glGpu()->glCaps().skipErrorChecks()) {               \
22cb93a386Sopenharmony_ci            GR_GL_CALL(this->glGpu()->glInterface(), call);            \
23cb93a386Sopenharmony_ci            return static_cast<GrGLenum>(GR_GL_NO_ERROR);              \
24cb93a386Sopenharmony_ci        } else {                                                       \
25cb93a386Sopenharmony_ci            this->glGpu()->clearErrorsAndCheckForOOM();                \
26cb93a386Sopenharmony_ci            GR_GL_CALL_NOERRCHECK(this->glGpu()->glInterface(), call); \
27cb93a386Sopenharmony_ci            return this->glGpu()->getErrorAndCheckForOOM();            \
28cb93a386Sopenharmony_ci        }                                                              \
29cb93a386Sopenharmony_ci    }()
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci#ifdef SK_DEBUG
32cb93a386Sopenharmony_ci#define VALIDATE() this->validate()
33cb93a386Sopenharmony_ci#else
34cb93a386Sopenharmony_ci#define VALIDATE() do {} while(false)
35cb93a386Sopenharmony_ci#endif
36cb93a386Sopenharmony_ci
37cb93a386Sopenharmony_cisk_sp<GrGLBuffer> GrGLBuffer::Make(GrGLGpu* gpu, size_t size, GrGpuBufferType intendedType,
38cb93a386Sopenharmony_ci                                   GrAccessPattern accessPattern, const void* data) {
39cb93a386Sopenharmony_ci    if (gpu->glCaps().transferBufferType() == GrGLCaps::TransferBufferType::kNone &&
40cb93a386Sopenharmony_ci        (GrGpuBufferType::kXferCpuToGpu == intendedType ||
41cb93a386Sopenharmony_ci         GrGpuBufferType::kXferGpuToCpu == intendedType)) {
42cb93a386Sopenharmony_ci        return nullptr;
43cb93a386Sopenharmony_ci    }
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci    sk_sp<GrGLBuffer> buffer(new GrGLBuffer(gpu, size, intendedType, accessPattern, data));
46cb93a386Sopenharmony_ci    if (0 == buffer->bufferID()) {
47cb93a386Sopenharmony_ci        return nullptr;
48cb93a386Sopenharmony_ci    }
49cb93a386Sopenharmony_ci    return buffer;
50cb93a386Sopenharmony_ci}
51cb93a386Sopenharmony_ci
52cb93a386Sopenharmony_ci// GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer
53cb93a386Sopenharmony_ci// objects are implemented as client-side-arrays on tile-deferred architectures.
54cb93a386Sopenharmony_ci#define DYNAMIC_DRAW_PARAM GR_GL_STREAM_DRAW
55cb93a386Sopenharmony_ci
56cb93a386Sopenharmony_ciinline static GrGLenum gr_to_gl_access_pattern(GrGpuBufferType bufferType,
57cb93a386Sopenharmony_ci                                               GrAccessPattern accessPattern,
58cb93a386Sopenharmony_ci                                               const GrGLCaps& caps) {
59cb93a386Sopenharmony_ci    auto drawUsage = [](GrAccessPattern pattern) {
60cb93a386Sopenharmony_ci        switch (pattern) {
61cb93a386Sopenharmony_ci            case kDynamic_GrAccessPattern:
62cb93a386Sopenharmony_ci                // TODO: Do we really want to use STREAM_DRAW here on non-Chromium?
63cb93a386Sopenharmony_ci                return DYNAMIC_DRAW_PARAM;
64cb93a386Sopenharmony_ci            case kStatic_GrAccessPattern:
65cb93a386Sopenharmony_ci                return GR_GL_STATIC_DRAW;
66cb93a386Sopenharmony_ci            case kStream_GrAccessPattern:
67cb93a386Sopenharmony_ci                return GR_GL_STREAM_DRAW;
68cb93a386Sopenharmony_ci        }
69cb93a386Sopenharmony_ci        SkUNREACHABLE;
70cb93a386Sopenharmony_ci    };
71cb93a386Sopenharmony_ci
72cb93a386Sopenharmony_ci    auto readUsage = [](GrAccessPattern pattern) {
73cb93a386Sopenharmony_ci        switch (pattern) {
74cb93a386Sopenharmony_ci            case kDynamic_GrAccessPattern:
75cb93a386Sopenharmony_ci                return GR_GL_DYNAMIC_READ;
76cb93a386Sopenharmony_ci            case kStatic_GrAccessPattern:
77cb93a386Sopenharmony_ci                return GR_GL_STATIC_READ;
78cb93a386Sopenharmony_ci            case kStream_GrAccessPattern:
79cb93a386Sopenharmony_ci                return GR_GL_STREAM_READ;
80cb93a386Sopenharmony_ci        }
81cb93a386Sopenharmony_ci        SkUNREACHABLE;
82cb93a386Sopenharmony_ci    };
83cb93a386Sopenharmony_ci
84cb93a386Sopenharmony_ci    auto usageType = [&drawUsage, &readUsage, &caps](GrGpuBufferType type,
85cb93a386Sopenharmony_ci                                                     GrAccessPattern pattern) {
86cb93a386Sopenharmony_ci        // GL_NV_pixel_buffer_object adds transfer buffers but not the related <usage> values.
87cb93a386Sopenharmony_ci        if (caps.transferBufferType() == GrGLCaps::TransferBufferType::kNV_PBO) {
88cb93a386Sopenharmony_ci            return drawUsage(pattern);
89cb93a386Sopenharmony_ci        }
90cb93a386Sopenharmony_ci        switch (type) {
91cb93a386Sopenharmony_ci            case GrGpuBufferType::kVertex:
92cb93a386Sopenharmony_ci            case GrGpuBufferType::kIndex:
93cb93a386Sopenharmony_ci            case GrGpuBufferType::kDrawIndirect:
94cb93a386Sopenharmony_ci            case GrGpuBufferType::kXferCpuToGpu:
95cb93a386Sopenharmony_ci            case GrGpuBufferType::kUniform:
96cb93a386Sopenharmony_ci                return drawUsage(pattern);
97cb93a386Sopenharmony_ci            case GrGpuBufferType::kXferGpuToCpu:
98cb93a386Sopenharmony_ci                return readUsage(pattern);
99cb93a386Sopenharmony_ci        }
100cb93a386Sopenharmony_ci        SkUNREACHABLE;
101cb93a386Sopenharmony_ci    };
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    return usageType(bufferType, accessPattern);
104cb93a386Sopenharmony_ci}
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ciGrGLBuffer::GrGLBuffer(GrGLGpu* gpu, size_t size, GrGpuBufferType intendedType,
107cb93a386Sopenharmony_ci                       GrAccessPattern accessPattern, const void* data)
108cb93a386Sopenharmony_ci        : INHERITED(gpu, size, intendedType, accessPattern)
109cb93a386Sopenharmony_ci        , fIntendedType(intendedType)
110cb93a386Sopenharmony_ci        , fBufferID(0)
111cb93a386Sopenharmony_ci        , fUsage(gr_to_gl_access_pattern(intendedType, accessPattern, gpu->glCaps()))
112cb93a386Sopenharmony_ci        , fGLSizeInBytes(0)
113cb93a386Sopenharmony_ci        , fHasAttachedToTexture(false) {
114cb93a386Sopenharmony_ci    GL_CALL(GenBuffers(1, &fBufferID));
115cb93a386Sopenharmony_ci    if (fBufferID) {
116cb93a386Sopenharmony_ci        GrGLenum target = gpu->bindBuffer(fIntendedType, this);
117cb93a386Sopenharmony_ci        GrGLenum error = GL_ALLOC_CALL(BufferData(target, (GrGLsizeiptr)size, data, fUsage));
118cb93a386Sopenharmony_ci        if (error != GR_GL_NO_ERROR) {
119cb93a386Sopenharmony_ci            GL_CALL(DeleteBuffers(1, &fBufferID));
120cb93a386Sopenharmony_ci            fBufferID = 0;
121cb93a386Sopenharmony_ci        } else {
122cb93a386Sopenharmony_ci            fGLSizeInBytes = size;
123cb93a386Sopenharmony_ci        }
124cb93a386Sopenharmony_ci    }
125cb93a386Sopenharmony_ci    VALIDATE();
126cb93a386Sopenharmony_ci    this->registerWithCache(SkBudgeted::kYes);
127cb93a386Sopenharmony_ci    if (!fBufferID) {
128cb93a386Sopenharmony_ci        this->resourcePriv().removeScratchKey();
129cb93a386Sopenharmony_ci    }
130cb93a386Sopenharmony_ci}
131cb93a386Sopenharmony_ci
132cb93a386Sopenharmony_ciinline GrGLGpu* GrGLBuffer::glGpu() const {
133cb93a386Sopenharmony_ci    SkASSERT(!this->wasDestroyed());
134cb93a386Sopenharmony_ci    return static_cast<GrGLGpu*>(this->getGpu());
135cb93a386Sopenharmony_ci}
136cb93a386Sopenharmony_ci
137cb93a386Sopenharmony_ciinline const GrGLCaps& GrGLBuffer::glCaps() const {
138cb93a386Sopenharmony_ci    return this->glGpu()->glCaps();
139cb93a386Sopenharmony_ci}
140cb93a386Sopenharmony_ci
141cb93a386Sopenharmony_civoid GrGLBuffer::onRelease() {
142cb93a386Sopenharmony_ci    TRACE_EVENT0("skia.gpu", TRACE_FUNC);
143cb93a386Sopenharmony_ci
144cb93a386Sopenharmony_ci    if (!this->wasDestroyed()) {
145cb93a386Sopenharmony_ci        VALIDATE();
146cb93a386Sopenharmony_ci        // make sure we've not been abandoned or already released
147cb93a386Sopenharmony_ci        if (fBufferID) {
148cb93a386Sopenharmony_ci            GL_CALL(DeleteBuffers(1, &fBufferID));
149cb93a386Sopenharmony_ci            fBufferID = 0;
150cb93a386Sopenharmony_ci            fGLSizeInBytes = 0;
151cb93a386Sopenharmony_ci        }
152cb93a386Sopenharmony_ci        fMapPtr = nullptr;
153cb93a386Sopenharmony_ci        VALIDATE();
154cb93a386Sopenharmony_ci    }
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ci    INHERITED::onRelease();
157cb93a386Sopenharmony_ci}
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_civoid GrGLBuffer::onAbandon() {
160cb93a386Sopenharmony_ci    fBufferID = 0;
161cb93a386Sopenharmony_ci    fGLSizeInBytes = 0;
162cb93a386Sopenharmony_ci    fMapPtr = nullptr;
163cb93a386Sopenharmony_ci    VALIDATE();
164cb93a386Sopenharmony_ci    INHERITED::onAbandon();
165cb93a386Sopenharmony_ci}
166cb93a386Sopenharmony_ci
167cb93a386Sopenharmony_civoid GrGLBuffer::onMap() {
168cb93a386Sopenharmony_ci    SkASSERT(fBufferID);
169cb93a386Sopenharmony_ci    SkASSERT(!this->wasDestroyed());
170cb93a386Sopenharmony_ci    VALIDATE();
171cb93a386Sopenharmony_ci    SkASSERT(!this->isMapped());
172cb93a386Sopenharmony_ci
173cb93a386Sopenharmony_ci    // TODO: Make this a function parameter.
174cb93a386Sopenharmony_ci    bool readOnly = (GrGpuBufferType::kXferGpuToCpu == fIntendedType);
175cb93a386Sopenharmony_ci
176cb93a386Sopenharmony_ci    // Handling dirty context is done in the bindBuffer call
177cb93a386Sopenharmony_ci    switch (this->glCaps().mapBufferType()) {
178cb93a386Sopenharmony_ci        case GrGLCaps::kNone_MapBufferType:
179cb93a386Sopenharmony_ci            return;
180cb93a386Sopenharmony_ci        case GrGLCaps::kMapBuffer_MapBufferType: {
181cb93a386Sopenharmony_ci            GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
182cb93a386Sopenharmony_ci            if (!readOnly) {
183cb93a386Sopenharmony_ci                // Let driver know it can discard the old data
184cb93a386Sopenharmony_ci                if (this->glCaps().useBufferDataNullHint() || fGLSizeInBytes != this->size()) {
185cb93a386Sopenharmony_ci                    GrGLenum error =
186cb93a386Sopenharmony_ci                            GL_ALLOC_CALL(BufferData(target, this->size(), nullptr, fUsage));
187cb93a386Sopenharmony_ci                    if (error != GR_GL_NO_ERROR) {
188cb93a386Sopenharmony_ci                        return;
189cb93a386Sopenharmony_ci                    }
190cb93a386Sopenharmony_ci                }
191cb93a386Sopenharmony_ci            }
192cb93a386Sopenharmony_ci            GL_CALL_RET(fMapPtr, MapBuffer(target, readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
193cb93a386Sopenharmony_ci            break;
194cb93a386Sopenharmony_ci        }
195cb93a386Sopenharmony_ci        case GrGLCaps::kMapBufferRange_MapBufferType: {
196cb93a386Sopenharmony_ci            GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
197cb93a386Sopenharmony_ci            // Make sure the GL buffer size agrees with fDesc before mapping.
198cb93a386Sopenharmony_ci            if (fGLSizeInBytes != this->size()) {
199cb93a386Sopenharmony_ci                GrGLenum error = GL_ALLOC_CALL(BufferData(target, this->size(), nullptr, fUsage));
200cb93a386Sopenharmony_ci                if (error != GR_GL_NO_ERROR) {
201cb93a386Sopenharmony_ci                    return;
202cb93a386Sopenharmony_ci                }
203cb93a386Sopenharmony_ci            }
204cb93a386Sopenharmony_ci            GrGLbitfield access;
205cb93a386Sopenharmony_ci            if (readOnly) {
206cb93a386Sopenharmony_ci                access = GR_GL_MAP_READ_BIT;
207cb93a386Sopenharmony_ci            } else {
208cb93a386Sopenharmony_ci                access = GR_GL_MAP_WRITE_BIT;
209cb93a386Sopenharmony_ci                if (GrGpuBufferType::kXferCpuToGpu != fIntendedType) {
210cb93a386Sopenharmony_ci                    // TODO: Make this a function parameter.
211cb93a386Sopenharmony_ci                    access |= GR_GL_MAP_INVALIDATE_BUFFER_BIT;
212cb93a386Sopenharmony_ci                }
213cb93a386Sopenharmony_ci            }
214cb93a386Sopenharmony_ci            GL_CALL_RET(fMapPtr, MapBufferRange(target, 0, this->size(), access));
215cb93a386Sopenharmony_ci            break;
216cb93a386Sopenharmony_ci        }
217cb93a386Sopenharmony_ci        case GrGLCaps::kChromium_MapBufferType: {
218cb93a386Sopenharmony_ci            GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
219cb93a386Sopenharmony_ci            // Make sure the GL buffer size agrees with fDesc before mapping.
220cb93a386Sopenharmony_ci            if (fGLSizeInBytes != this->size()) {
221cb93a386Sopenharmony_ci                GrGLenum error = GL_ALLOC_CALL(BufferData(target, this->size(), nullptr, fUsage));
222cb93a386Sopenharmony_ci                if (error != GR_GL_NO_ERROR) {
223cb93a386Sopenharmony_ci                    return;
224cb93a386Sopenharmony_ci                }
225cb93a386Sopenharmony_ci            }
226cb93a386Sopenharmony_ci            GL_CALL_RET(fMapPtr, MapBufferSubData(target, 0, this->size(),
227cb93a386Sopenharmony_ci                                                  readOnly ? GR_GL_READ_ONLY : GR_GL_WRITE_ONLY));
228cb93a386Sopenharmony_ci            break;
229cb93a386Sopenharmony_ci        }
230cb93a386Sopenharmony_ci    }
231cb93a386Sopenharmony_ci    fGLSizeInBytes = this->size();
232cb93a386Sopenharmony_ci    VALIDATE();
233cb93a386Sopenharmony_ci}
234cb93a386Sopenharmony_ci
235cb93a386Sopenharmony_civoid GrGLBuffer::onUnmap() {
236cb93a386Sopenharmony_ci    SkASSERT(fBufferID);
237cb93a386Sopenharmony_ci    VALIDATE();
238cb93a386Sopenharmony_ci    SkASSERT(this->isMapped());
239cb93a386Sopenharmony_ci    if (0 == fBufferID) {
240cb93a386Sopenharmony_ci        fMapPtr = nullptr;
241cb93a386Sopenharmony_ci        return;
242cb93a386Sopenharmony_ci    }
243cb93a386Sopenharmony_ci    // bind buffer handles the dirty context
244cb93a386Sopenharmony_ci    switch (this->glCaps().mapBufferType()) {
245cb93a386Sopenharmony_ci        case GrGLCaps::kNone_MapBufferType:
246cb93a386Sopenharmony_ci            SkDEBUGFAIL("Shouldn't get here.");
247cb93a386Sopenharmony_ci            return;
248cb93a386Sopenharmony_ci        case GrGLCaps::kMapBuffer_MapBufferType: // fall through
249cb93a386Sopenharmony_ci        case GrGLCaps::kMapBufferRange_MapBufferType: {
250cb93a386Sopenharmony_ci            GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
251cb93a386Sopenharmony_ci            GL_CALL(UnmapBuffer(target));
252cb93a386Sopenharmony_ci            break;
253cb93a386Sopenharmony_ci        }
254cb93a386Sopenharmony_ci        case GrGLCaps::kChromium_MapBufferType:
255cb93a386Sopenharmony_ci            this->glGpu()->bindBuffer(fIntendedType, this); // TODO: Is this needed?
256cb93a386Sopenharmony_ci            GL_CALL(UnmapBufferSubData(fMapPtr));
257cb93a386Sopenharmony_ci            break;
258cb93a386Sopenharmony_ci    }
259cb93a386Sopenharmony_ci    fMapPtr = nullptr;
260cb93a386Sopenharmony_ci}
261cb93a386Sopenharmony_ci
262cb93a386Sopenharmony_cibool GrGLBuffer::onUpdateData(const void* src, size_t srcSizeInBytes) {
263cb93a386Sopenharmony_ci    SkASSERT(fBufferID);
264cb93a386Sopenharmony_ci    if (this->wasDestroyed()) {
265cb93a386Sopenharmony_ci        return false;
266cb93a386Sopenharmony_ci    }
267cb93a386Sopenharmony_ci
268cb93a386Sopenharmony_ci    SkASSERT(!this->isMapped());
269cb93a386Sopenharmony_ci    VALIDATE();
270cb93a386Sopenharmony_ci    if (srcSizeInBytes > this->size()) {
271cb93a386Sopenharmony_ci        return false;
272cb93a386Sopenharmony_ci    }
273cb93a386Sopenharmony_ci    SkASSERT(srcSizeInBytes <= this->size());
274cb93a386Sopenharmony_ci    // bindbuffer handles dirty context
275cb93a386Sopenharmony_ci    GrGLenum target = this->glGpu()->bindBuffer(fIntendedType, this);
276cb93a386Sopenharmony_ci
277cb93a386Sopenharmony_ci    if (this->glCaps().useBufferDataNullHint()) {
278cb93a386Sopenharmony_ci        if (this->size() == srcSizeInBytes) {
279cb93a386Sopenharmony_ci            GrGLenum error =
280cb93a386Sopenharmony_ci                    GL_ALLOC_CALL(BufferData(target, (GrGLsizeiptr)srcSizeInBytes, src, fUsage));
281cb93a386Sopenharmony_ci            if (error != GR_GL_NO_ERROR) {
282cb93a386Sopenharmony_ci                return false;
283cb93a386Sopenharmony_ci            }
284cb93a386Sopenharmony_ci        } else {
285cb93a386Sopenharmony_ci            // Before we call glBufferSubData we give the driver a hint using
286cb93a386Sopenharmony_ci            // glBufferData with nullptr. This makes the old buffer contents
287cb93a386Sopenharmony_ci            // inaccessible to future draws. The GPU may still be processing
288cb93a386Sopenharmony_ci            // draws that reference the old contents. With this hint it can
289cb93a386Sopenharmony_ci            // assign a different allocation for the new contents to avoid
290cb93a386Sopenharmony_ci            // flushing the gpu past draws consuming the old contents.
291cb93a386Sopenharmony_ci            // TODO I think we actually want to try calling bufferData here
292cb93a386Sopenharmony_ci            GrGLenum error =
293cb93a386Sopenharmony_ci                    GL_ALLOC_CALL(BufferData(target, (GrGLsizeiptr)this->size(), nullptr, fUsage));
294cb93a386Sopenharmony_ci            if (error != GR_GL_NO_ERROR) {
295cb93a386Sopenharmony_ci                return false;
296cb93a386Sopenharmony_ci            }
297cb93a386Sopenharmony_ci            GL_CALL(BufferSubData(target, 0, (GrGLsizeiptr) srcSizeInBytes, src));
298cb93a386Sopenharmony_ci        }
299cb93a386Sopenharmony_ci        fGLSizeInBytes = this->size();
300cb93a386Sopenharmony_ci    } else {
301cb93a386Sopenharmony_ci        // Note that we're cheating on the size here. Currently no methods
302cb93a386Sopenharmony_ci        // allow a partial update that preserves contents of non-updated
303cb93a386Sopenharmony_ci        // portions of the buffer (map() does a glBufferData(..size, nullptr..))
304cb93a386Sopenharmony_ci        GrGLenum error =
305cb93a386Sopenharmony_ci                GL_ALLOC_CALL(BufferData(target, (GrGLsizeiptr)srcSizeInBytes, src, fUsage));
306cb93a386Sopenharmony_ci        if (error != GR_GL_NO_ERROR) {
307cb93a386Sopenharmony_ci            return false;
308cb93a386Sopenharmony_ci        }
309cb93a386Sopenharmony_ci        fGLSizeInBytes = srcSizeInBytes;
310cb93a386Sopenharmony_ci    }
311cb93a386Sopenharmony_ci    VALIDATE();
312cb93a386Sopenharmony_ci    return true;
313cb93a386Sopenharmony_ci}
314cb93a386Sopenharmony_ci
315cb93a386Sopenharmony_civoid GrGLBuffer::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
316cb93a386Sopenharmony_ci                                       const SkString& dumpName) const {
317cb93a386Sopenharmony_ci    SkString buffer_id;
318cb93a386Sopenharmony_ci    buffer_id.appendU32(this->bufferID());
319cb93a386Sopenharmony_ci    traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_buffer",
320cb93a386Sopenharmony_ci                                      buffer_id.c_str());
321cb93a386Sopenharmony_ci}
322cb93a386Sopenharmony_ci
323cb93a386Sopenharmony_ci#ifdef SK_DEBUG
324cb93a386Sopenharmony_ci
325cb93a386Sopenharmony_civoid GrGLBuffer::validate() const {
326cb93a386Sopenharmony_ci    SkASSERT(0 != fBufferID || 0 == fGLSizeInBytes);
327cb93a386Sopenharmony_ci    SkASSERT(nullptr == fMapPtr || fGLSizeInBytes <= this->size());
328cb93a386Sopenharmony_ci}
329cb93a386Sopenharmony_ci
330cb93a386Sopenharmony_ci#endif
331