blob: 2babce80285cc1f2bb61e34e657db58b727a7142 [file] [log] [blame]
bsalomon@google.come49ad452013-02-20 19:33:20 +00001/*
2 * Copyright 2013 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#include "GrGLBufferImpl.h"
jvanverth39edf762014-12-22 11:44:19 -08009#include "GrGLGpu.h"
bsalomon@google.come49ad452013-02-20 19:33:20 +000010
11#define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X)
12
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +000013#ifdef SK_DEBUG
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000014#define VALIDATE() this->validate()
15#else
16#define VALIDATE() do {} while(false)
17#endif
18
bsalomon861e1032014-12-16 07:33:49 -080019GrGLBufferImpl::GrGLBufferImpl(GrGLGpu* gpu, const Desc& desc, GrGLenum bufferType)
bsalomon@google.come49ad452013-02-20 19:33:20 +000020 : fDesc(desc)
21 , fBufferType(bufferType)
halcanary96fcdcc2015-08-27 07:41:13 -070022 , fMapPtr(nullptr) {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000023 if (0 == desc.fID) {
bsalomon7dea7b72015-08-19 08:26:51 -070024 if (gpu->caps()->mustClearUploadedBufferData()) {
25 fCPUData = sk_calloc_throw(desc.fSizeInBytes);
26 } else {
27 fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW);
28 }
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000029 fGLSizeInBytes = 0;
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000030 } else {
halcanary96fcdcc2015-08-27 07:41:13 -070031 fCPUData = nullptr;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000032 // We assume that the GL buffer was created at the desc's size initially.
33 fGLSizeInBytes = fDesc.fSizeInBytes;
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000034 }
35 VALIDATE();
bsalomon@google.come49ad452013-02-20 19:33:20 +000036}
37
bsalomon861e1032014-12-16 07:33:49 -080038void GrGLBufferImpl::release(GrGLGpu* gpu) {
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000039 VALIDATE();
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000040 // make sure we've not been abandoned or already released
bsalomon49f085d2014-09-05 13:34:00 -070041 if (fCPUData) {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000042 sk_free(fCPUData);
halcanary96fcdcc2015-08-27 07:41:13 -070043 fCPUData = nullptr;
bsalomon5236cf42015-01-14 10:42:08 -080044 } else if (fDesc.fID) {
joshualitt93316b92015-10-23 09:08:08 -070045 gpu->releaseBuffer(fDesc.fID, fBufferType);
bsalomon@google.come49ad452013-02-20 19:33:20 +000046 fDesc.fID = 0;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000047 fGLSizeInBytes = 0;
bsalomon@google.come49ad452013-02-20 19:33:20 +000048 }
halcanary96fcdcc2015-08-27 07:41:13 -070049 fMapPtr = nullptr;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000050 VALIDATE();
bsalomon@google.come49ad452013-02-20 19:33:20 +000051}
52
53void GrGLBufferImpl::abandon() {
54 fDesc.fID = 0;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000055 fGLSizeInBytes = 0;
halcanary96fcdcc2015-08-27 07:41:13 -070056 fMapPtr = nullptr;
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000057 sk_free(fCPUData);
halcanary96fcdcc2015-08-27 07:41:13 -070058 fCPUData = nullptr;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000059 VALIDATE();
bsalomon@google.come49ad452013-02-20 19:33:20 +000060}
61
bsalomon861e1032014-12-16 07:33:49 -080062void* GrGLBufferImpl::map(GrGLGpu* gpu) {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000063 VALIDATE();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000064 SkASSERT(!this->isMapped());
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000065 if (0 == fDesc.fID) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000066 fMapPtr = fCPUData;
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000067 } else {
jvanverth73063dc2015-12-03 09:15:47 -080068 fMapPtr = gpu->mapBuffer(fDesc.fID, fBufferType, fDesc.fUsage, fGLSizeInBytes,
joshualitt93316b92015-10-23 09:08:08 -070069 fDesc.fSizeInBytes);
70 fGLSizeInBytes = fDesc.fSizeInBytes;
bsalomon@google.come49ad452013-02-20 19:33:20 +000071 }
commit-bot@chromium.org160b4782014-05-05 12:32:37 +000072 VALIDATE();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000073 return fMapPtr;
bsalomon@google.come49ad452013-02-20 19:33:20 +000074}
75
bsalomon861e1032014-12-16 07:33:49 -080076void GrGLBufferImpl::unmap(GrGLGpu* gpu) {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000077 VALIDATE();
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000078 SkASSERT(this->isMapped());
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000079 if (0 != fDesc.fID) {
joshualitt93316b92015-10-23 09:08:08 -070080 gpu->unmapBuffer(fDesc.fID, fBufferType, fMapPtr);
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000081 }
halcanary96fcdcc2015-08-27 07:41:13 -070082 fMapPtr = nullptr;
bsalomon@google.come49ad452013-02-20 19:33:20 +000083}
84
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000085bool GrGLBufferImpl::isMapped() const {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000086 VALIDATE();
bsalomon49f085d2014-09-05 13:34:00 -070087 return SkToBool(fMapPtr);
bsalomon@google.come49ad452013-02-20 19:33:20 +000088}
89
bsalomon861e1032014-12-16 07:33:49 -080090bool GrGLBufferImpl::updateData(GrGLGpu* gpu, const void* src, size_t srcSizeInBytes) {
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000091 SkASSERT(!this->isMapped());
jvanverth73063dc2015-12-03 09:15:47 -080092 SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType);
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000093 VALIDATE();
bsalomon@google.come49ad452013-02-20 19:33:20 +000094 if (srcSizeInBytes > fDesc.fSizeInBytes) {
95 return false;
96 }
97 if (0 == fDesc.fID) {
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +000098 memcpy(fCPUData, src, srcSizeInBytes);
99 return true;
bsalomon@google.come49ad452013-02-20 19:33:20 +0000100 }
jvanverth73063dc2015-12-03 09:15:47 -0800101 gpu->bufferData(fDesc.fID, fBufferType, fDesc.fUsage, fDesc.fSizeInBytes, src,
joshualitt93316b92015-10-23 09:08:08 -0700102 srcSizeInBytes);
joshualitt6df232d2015-10-23 13:54:12 -0700103#if GR_GL_USE_BUFFER_DATA_NULL_HINT
104 fGLSizeInBytes = fDesc.fSizeInBytes;
105#else
joshualittccdbc1d2015-10-23 07:33:54 -0700106 fGLSizeInBytes = srcSizeInBytes;
joshualitt6df232d2015-10-23 13:54:12 -0700107#endif
joshualitt93316b92015-10-23 09:08:08 -0700108 VALIDATE();
bsalomon@google.come49ad452013-02-20 19:33:20 +0000109 return true;
110}
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +0000111
112void GrGLBufferImpl::validate() const {
jvanverth73063dc2015-12-03 09:15:47 -0800113 SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType ||
jvanverthd7a2c1f2015-12-07 07:36:44 -0800114 GR_GL_PIXEL_PACK_BUFFER == fBufferType || GR_GL_PIXEL_UNPACK_BUFFER == fBufferType ||
115 GR_GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM == fBufferType ||
116 GR_GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM == fBufferType);
bsalomon@google.com1b8014c2013-05-08 12:49:49 +0000117 // The following assert isn't valid when the buffer has been abandoned:
bsalomon49f085d2014-09-05 13:34:00 -0700118 // SkASSERT((0 == fDesc.fID) == (fCPUData));
halcanary96fcdcc2015-08-27 07:41:13 -0700119 SkASSERT(nullptr == fCPUData || 0 == fGLSizeInBytes);
joshualitt93316b92015-10-23 09:08:08 -0700120 SkASSERT(nullptr == fMapPtr || fCPUData || fGLSizeInBytes <= fDesc.fSizeInBytes);
halcanary96fcdcc2015-08-27 07:41:13 -0700121 SkASSERT(nullptr == fCPUData || nullptr == fMapPtr || fCPUData == fMapPtr);
bsalomon@google.comee3bc3b2013-02-21 14:33:46 +0000122}