blob: f96f90ea5f37f4ffb175a0ec6798de913c5e1e4d [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
twiz@google.com0f31ca72011-03-18 17:38:11 +000021GrGLVertexBuffer::GrGLVertexBuffer(GrGLuint id, GrGpuGL* gl, size_t sizeInBytes,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000022 bool dynamic) :
reed@google.comac10a2d2010-12-22 21:39:39 +000023 INHERITED(sizeInBytes, dynamic),
24 fGL(gl),
25 fBufferID(id),
26 fLockPtr(NULL) {
27}
28
29GrGLVertexBuffer::~GrGLVertexBuffer() {
30 // make sure we've not been abandoned
31 if (fBufferID) {
32 fGL->notifyVertexBufferDelete(this);
33 GR_GL(DeleteBuffers(1, &fBufferID));
34 }
35}
36
bsalomon@google.com1c13c962011-02-14 16:51:21 +000037void GrGLVertexBuffer::bind() const {
twiz@google.com0f31ca72011-03-18 17:38:11 +000038 GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000039 fGL->notifyVertexBufferBind(this);
40}
41
twiz@google.com0f31ca72011-03-18 17:38:11 +000042GrGLuint GrGLVertexBuffer::bufferID() const {
reed@google.comac10a2d2010-12-22 21:39:39 +000043 return fBufferID;
44}
45
bsalomon@google.com1c13c962011-02-14 16:51:21 +000046void GrGLVertexBuffer::abandon() {
reed@google.comac10a2d2010-12-22 21:39:39 +000047 fBufferID = 0;
48 fGL = NULL;
49 fLockPtr = NULL;
50}
51
52void* GrGLVertexBuffer::lock() {
53 GrAssert(fBufferID);
54 GrAssert(!isLocked());
55 if (fGL->supportsBufferLocking()) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000056 bind();
57 // Let driver know it can discard the old data
twiz@google.com0f31ca72011-03-18 17:38:11 +000058 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, size(), NULL,
59 dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
bsalomon@google.comc312bf92011-03-21 21:10:33 +000060 fLockPtr = GR_GL(MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000061 return fLockPtr;
62 }
63 return NULL;
64}
65
bsalomon@google.com1c13c962011-02-14 16:51:21 +000066void* GrGLVertexBuffer::lockPtr() const {
67 return fLockPtr;
68}
69
reed@google.comac10a2d2010-12-22 21:39:39 +000070void GrGLVertexBuffer::unlock() {
71 GrAssert(fBufferID);
72 GrAssert(isLocked());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000073 GrAssert(fGL->supportsBufferLocking());
74
75 bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000076 GR_GL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000077 fLockPtr = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000078}
79
80bool GrGLVertexBuffer::isLocked() const {
81 GrAssert(fBufferID);
82#if GR_DEBUG
83 if (fGL->supportsBufferLocking()) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000084 GrGLint mapped;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000085 bind();
bsalomon@google.comc312bf92011-03-21 21:10:33 +000086 GR_GL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER, GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000087 GrAssert(!!mapped == !!fLockPtr);
88 }
89#endif
90 return NULL != fLockPtr;
91}
92
bsalomon@google.com1c13c962011-02-14 16:51:21 +000093bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +000094 GrAssert(fBufferID);
95 GrAssert(!isLocked());
96 if (srcSizeInBytes > size()) {
97 return false;
98 }
bsalomon@google.com1c13c962011-02-14 16:51:21 +000099 bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000100 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000101 if (size() == srcSizeInBytes) {
twiz@google.com0f31ca72011-03-18 17:38:11 +0000102 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000103 } else {
twiz@google.com0f31ca72011-03-18 17:38:11 +0000104 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, size(), NULL, usage));
105 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000106 }
107 return true;
108}
109
110bool GrGLVertexBuffer::updateSubData(const void* src,
111 size_t srcSizeInBytes,
112 size_t offset) {
113 GrAssert(fBufferID);
114 GrAssert(!isLocked());
115 if (srcSizeInBytes + offset > size()) {
116 return false;
117 }
118 bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000119 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
reed@google.comac10a2d2010-12-22 21:39:39 +0000120 return true;
121}
122