blob: bb51b4ee37631b553f55447ece08d683d09ac213 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
twiz@google.com59a190b2011-03-14 21:23:01 +00002 Copyright 2011 Google Inc.
reed@google.comac10a2d2010-12-22 21:39:39 +00003
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17
18#include "GrGLVertexBuffer.h"
19#include "GrGpuGL.h"
20
bsalomon@google.com8fe72472011-03-30 21:26:44 +000021#define GPUGL static_cast<GrGpuGL*>(getGpu())
22
23GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
24 GrGLuint id,
25 size_t sizeInBytes,
26 bool dynamic)
27 : INHERITED(gpu, sizeInBytes, dynamic)
28 , fBufferID(id)
29 , fLockPtr(NULL) {
reed@google.comac10a2d2010-12-22 21:39:39 +000030}
31
bsalomon@google.com8fe72472011-03-30 21:26:44 +000032void GrGLVertexBuffer::onRelease() {
reed@google.comac10a2d2010-12-22 21:39:39 +000033 // make sure we've not been abandoned
34 if (fBufferID) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000035 GPUGL->notifyVertexBufferDelete(this);
reed@google.comac10a2d2010-12-22 21:39:39 +000036 GR_GL(DeleteBuffers(1, &fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000037 fBufferID = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000038 }
39}
40
bsalomon@google.com8fe72472011-03-30 21:26:44 +000041void GrGLVertexBuffer::onAbandon() {
42 fBufferID = 0;
43 fLockPtr = NULL;
44}
45
bsalomon@google.com1c13c962011-02-14 16:51:21 +000046void GrGLVertexBuffer::bind() const {
twiz@google.com0f31ca72011-03-18 17:38:11 +000047 GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000048 GPUGL->notifyVertexBufferBind(this);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000049}
50
twiz@google.com0f31ca72011-03-18 17:38:11 +000051GrGLuint GrGLVertexBuffer::bufferID() const {
reed@google.comac10a2d2010-12-22 21:39:39 +000052 return fBufferID;
53}
54
reed@google.comac10a2d2010-12-22 21:39:39 +000055void* GrGLVertexBuffer::lock() {
56 GrAssert(fBufferID);
57 GrAssert(!isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000058 if (GPUGL->supportsBufferLocking()) {
59 this->bind();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000060 // Let driver know it can discard the old data
bsalomon@google.comcee661a2011-07-26 12:32:36 +000061 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL,
62 this->dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
bsalomon@google.comc312bf92011-03-21 21:10:33 +000063 fLockPtr = GR_GL(MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000064 return fLockPtr;
65 }
66 return NULL;
67}
68
bsalomon@google.com1c13c962011-02-14 16:51:21 +000069void* GrGLVertexBuffer::lockPtr() const {
70 return fLockPtr;
71}
72
reed@google.comac10a2d2010-12-22 21:39:39 +000073void GrGLVertexBuffer::unlock() {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000074
reed@google.comac10a2d2010-12-22 21:39:39 +000075 GrAssert(fBufferID);
76 GrAssert(isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000077 GrAssert(GPUGL->supportsBufferLocking());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000078
bsalomon@google.com8fe72472011-03-30 21:26:44 +000079 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000080 GR_GL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000081 fLockPtr = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000082}
83
84bool GrGLVertexBuffer::isLocked() const {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000085 GrAssert(!this->isValid() || fBufferID);
reed@google.comac10a2d2010-12-22 21:39:39 +000086#if GR_DEBUG
bsalomon@google.com8fe72472011-03-30 21:26:44 +000087 if (this->isValid() && GPUGL->supportsBufferLocking()) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000088 GrGLint mapped;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000089 this->bind();
bsalomon@google.comc312bf92011-03-21 21:10:33 +000090 GR_GL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER, GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000091 GrAssert(!!mapped == !!fLockPtr);
92 }
93#endif
94 return NULL != fLockPtr;
95}
96
bsalomon@google.com1c13c962011-02-14 16:51:21 +000097bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +000098 GrAssert(fBufferID);
99 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000100 if (srcSizeInBytes > this->sizeInBytes()) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000101 return false;
102 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000103 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000104 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000105 if (this->sizeInBytes() == srcSizeInBytes) {
twiz@google.com0f31ca72011-03-18 17:38:11 +0000106 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000107 } else {
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000108#if GR_GL_USE_BUFFER_DATA_NULL_HINT
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000109 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL, usage));
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000110#endif
twiz@google.com0f31ca72011-03-18 17:38:11 +0000111 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000112 }
113 return true;
114}
115
116bool GrGLVertexBuffer::updateSubData(const void* src,
117 size_t srcSizeInBytes,
118 size_t offset) {
119 GrAssert(fBufferID);
120 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000121 if (srcSizeInBytes + offset > this->sizeInBytes()) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000122 return false;
123 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000124 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000125 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
reed@google.comac10a2d2010-12-22 21:39:39 +0000126 return true;
127}
128