blob: c4c623886a852935883cc8a701fd1e7e8dffb4dc [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
bsalomon@google.com0b77d682011-08-19 13:28:54 +000016#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
17
bsalomon@google.com8fe72472011-03-30 21:26:44 +000018GrGLVertexBuffer::GrGLVertexBuffer(GrGpuGL* gpu,
19 GrGLuint id,
20 size_t sizeInBytes,
21 bool dynamic)
22 : INHERITED(gpu, sizeInBytes, dynamic)
23 , fBufferID(id)
24 , fLockPtr(NULL) {
reed@google.comac10a2d2010-12-22 21:39:39 +000025}
26
bsalomon@google.com8fe72472011-03-30 21:26:44 +000027void GrGLVertexBuffer::onRelease() {
reed@google.comac10a2d2010-12-22 21:39:39 +000028 // make sure we've not been abandoned
29 if (fBufferID) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000030 GPUGL->notifyVertexBufferDelete(this);
bsalomon@google.com0b77d682011-08-19 13:28:54 +000031 GL_CALL(DeleteBuffers(1, &fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000032 fBufferID = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000033 }
34}
35
bsalomon@google.com8fe72472011-03-30 21:26:44 +000036void GrGLVertexBuffer::onAbandon() {
37 fBufferID = 0;
38 fLockPtr = NULL;
39}
40
bsalomon@google.com1c13c962011-02-14 16:51:21 +000041void GrGLVertexBuffer::bind() const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000042 GL_CALL(BindBuffer(GR_GL_ARRAY_BUFFER, fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000043 GPUGL->notifyVertexBufferBind(this);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000044}
45
twiz@google.com0f31ca72011-03-18 17:38:11 +000046GrGLuint GrGLVertexBuffer::bufferID() const {
reed@google.comac10a2d2010-12-22 21:39:39 +000047 return fBufferID;
48}
49
reed@google.comac10a2d2010-12-22 21:39:39 +000050void* GrGLVertexBuffer::lock() {
51 GrAssert(fBufferID);
52 GrAssert(!isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000053 if (GPUGL->supportsBufferLocking()) {
54 this->bind();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000055 // Let driver know it can discard the old data
bsalomon@google.com0b77d682011-08-19 13:28:54 +000056 GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, this->sizeInBytes(), NULL,
57 this->dynamic() ? GR_GL_DYNAMIC_DRAW :
58 GR_GL_STATIC_DRAW));
59 fLockPtr = GL_CALL(MapBuffer(GR_GL_ARRAY_BUFFER, GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000060 return fLockPtr;
61 }
62 return NULL;
63}
64
bsalomon@google.com1c13c962011-02-14 16:51:21 +000065void* GrGLVertexBuffer::lockPtr() const {
66 return fLockPtr;
67}
68
reed@google.comac10a2d2010-12-22 21:39:39 +000069void GrGLVertexBuffer::unlock() {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000070
reed@google.comac10a2d2010-12-22 21:39:39 +000071 GrAssert(fBufferID);
72 GrAssert(isLocked());
bsalomon@google.com8fe72472011-03-30 21:26:44 +000073 GrAssert(GPUGL->supportsBufferLocking());
bsalomon@google.com1c13c962011-02-14 16:51:21 +000074
bsalomon@google.com8fe72472011-03-30 21:26:44 +000075 this->bind();
bsalomon@google.com0b77d682011-08-19 13:28:54 +000076 GL_CALL(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 {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000081 GrAssert(!this->isValid() || fBufferID);
reed@google.comac10a2d2010-12-22 21:39:39 +000082#if GR_DEBUG
bsalomon@google.com8fe72472011-03-30 21:26:44 +000083 if (this->isValid() && GPUGL->supportsBufferLocking()) {
twiz@google.com0f31ca72011-03-18 17:38:11 +000084 GrGLint mapped;
bsalomon@google.com8fe72472011-03-30 21:26:44 +000085 this->bind();
bsalomon@google.com0b77d682011-08-19 13:28:54 +000086 GL_CALL(GetBufferParameteriv(GR_GL_ARRAY_BUFFER,
87 GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000088 GrAssert(!!mapped == !!fLockPtr);
89 }
90#endif
91 return NULL != fLockPtr;
92}
93
bsalomon@google.com1c13c962011-02-14 16:51:21 +000094bool GrGLVertexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +000095 GrAssert(fBufferID);
96 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +000097 if (srcSizeInBytes > this->sizeInBytes()) {
reed@google.comac10a2d2010-12-22 21:39:39 +000098 return false;
99 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000100 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000101 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000102 if (this->sizeInBytes() == srcSizeInBytes) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000103 GL_CALL(BufferData(GR_GL_ARRAY_BUFFER, srcSizeInBytes, src, usage));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000104 } else {
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000105#if GR_GL_USE_BUFFER_DATA_NULL_HINT
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000106 GL_CALL(BufferData(GR_GL_ARRAY_BUFFER,
107 this->sizeInBytes(), NULL, usage));
bsalomon@google.com9ae44292011-07-01 15:21:59 +0000108#endif
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000109 GL_CALL(BufferSubData(GR_GL_ARRAY_BUFFER, 0, srcSizeInBytes, src));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000110 }
111 return true;
112}
113
114bool GrGLVertexBuffer::updateSubData(const void* src,
115 size_t srcSizeInBytes,
116 size_t offset) {
117 GrAssert(fBufferID);
118 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000119 if (srcSizeInBytes + offset > this->sizeInBytes()) {
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000120 return false;
121 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000122 this->bind();
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000123 GL_CALL(BufferSubData(GR_GL_ARRAY_BUFFER, offset, srcSizeInBytes, src));
reed@google.comac10a2d2010-12-22 21:39:39 +0000124 return true;
125}
126