blob: 516852b94f01011e1aa080a3c028c70939bf47b5 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#include "GrGLVertexBuffer.h"
12#include "GrGpuGL.h"
13
bsalomon@google.com8fe72472011-03-30 21:26:44 +000014#define GPUGL static_cast<GrGpuGL*>(getGpu())
15
16GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
17 GrGLuint id,
18 size_t sizeInBytes,
19 bool dynamic)
20 : INHERITED(gpu, sizeInBytes, dynamic)
21 , fBufferID(id)
22 , fLockPtr(NULL) {
reed@google.comac10a2d2010-12-22 21:39:39 +000023}
24
bsalomon@google.com8fe72472011-03-30 21:26:44 +000025void GrGLVertexBuffer::onRelease() {
reed@google.comac10a2d2010-12-22 21:39:39 +000026 // make sure we've not been abandoned
27 if (fBufferID) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000028 GPUGL->notifyVertexBufferDelete(this);
reed@google.comac10a2d2010-12-22 21:39:39 +000029 GR_GL(DeleteBuffers(1, &fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000030 fBufferID = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000031 }
32}
33
bsalomon@google.com8fe72472011-03-30 21:26:44 +000034void GrGLVertexBuffer::onAbandon() {
35 fBufferID = 0;
36 fLockPtr = NULL;
37}
38
bsalomon@google.com1c13c962011-02-14 16:51:21 +000039void GrGLVertexBuffer::bind() const {
twiz@google.com0f31ca72011-03-18 17:38:11 +000040 GR_GL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000041 GPUGL->notifyVertexBufferBind(this);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000042}
43
twiz@google.com0f31ca72011-03-18 17:38:11 +000044GrGLuint GrGLVertexBuffer::bufferID() const {
reed@google.comac10a2d2010-12-22 21:39:39 +000045 return fBufferID;
46}
47
reed@google.comac10a2d2010-12-22 21:39:39 +000048void* GrGLVertexBuffer::lock() {
49 GrAssert(fBufferID);
50 GrAssert(!isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000051 if (GPUGL->supportsBufferLocking()) {
52 this->bind();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000053 // Let driver know it can discard the old data
bsalomon@google.comcee661a2011-07-26 12:32:36 +000054 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL,
55 this->dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW));
bsalomon@google.comc312bf92011-03-21 21:10:33 +000056 fLockPtr = GR_GL(MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000057 return fLockPtr;
58 }
59 return NULL;
60}
61
bsalomon@google.com1c13c962011-02-14 16:51:21 +000062void* GrGLVertexBuffer::lockPtr() const {
63 return fLockPtr;
64}
65
reed@google.comac10a2d2010-12-22 21:39:39 +000066void GrGLVertexBuffer::unlock() {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000067
reed@google.comac10a2d2010-12-22 21:39:39 +000068 GrAssert(fBufferID);
69 GrAssert(isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000070 GrAssert(GPUGL->supportsBufferLocking());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000071
bsalomon@google.com8fe72472011-03-30 21:26:44 +000072 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000073 GR_GL(UnmapBuffer(GR_GL_ARRAY_BUFFER));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000074 fLockPtr = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000075}
76
77bool GrGLVertexBuffer::isLocked() const {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000078 GrAssert(!this->isValid() || fBufferID);
reed@google.comac10a2d2010-12-22 21:39:39 +000079#if GR_DEBUG
bsalomon@google.com8fe72472011-03-30 21:26:44 +000080 if (this->isValid() && GPUGL->supportsBufferLocking()) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000081 GrGLint mapped;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000082 this->bind();
bsalomon@google.comc312bf92011-03-21 21:10:33 +000083 GR_GL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER, GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000084 GrAssert(!!mapped == !!fLockPtr);
85 }
86#endif
87 return NULL != fLockPtr;
88}
89
bsalomon@google.com1c13c962011-02-14 16:51:21 +000090bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +000091 GrAssert(fBufferID);
92 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +000093 if (srcSizeInBytes > this->sizeInBytes()) {
reed@google.comac10a2d2010-12-22 21:39:39 +000094 return false;
95 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +000096 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000097 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.comcee661a2011-07-26 12:32:36 +000098 if (this->sizeInBytes() == srcSizeInBytes) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000099 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000100 } else {
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000101#if GR_GL_USE_BUFFER_DATA_NULL_HINT
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000102 GR_GL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL, usage));
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000103#endif
twiz@google.com0f31ca72011-03-18 17:38:11 +0000104 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000105 }
106 return true;
107}
108
109bool GrGLVertexBuffer::updateSubData(const void* src,
110 size_t srcSizeInBytes,
111 size_t offset) {
112 GrAssert(fBufferID);
113 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000114 if (srcSizeInBytes + offset > this->sizeInBytes()) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000115 return false;
116 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000117 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000118 GR_GL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
reed@google.comac10a2d2010-12-22 21:39:39 +0000119 return true;
120}
121