blob: b64668ede2c18ec7540845c8468852152e9d19c5 [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 "GrGLIndexBuffer.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 +000018GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu,
19 GrGLuint id,
20 size_t sizeInBytes,
21 bool dynamic)
22 : INHERITED(gpu, sizeInBytes, dynamic)
23 , fBufferID(id)
24 , fLockPtr(NULL) {
25
reed@google.comac10a2d2010-12-22 21:39:39 +000026}
27
bsalomon@google.com8fe72472011-03-30 21:26:44 +000028void GrGLIndexBuffer::onRelease() {
reed@google.comac10a2d2010-12-22 21:39:39 +000029 // make sure we've not been abandoned
30 if (fBufferID) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000031 GPUGL->notifyIndexBufferDelete(this);
bsalomon@google.com0b77d682011-08-19 13:28:54 +000032 GL_CALL(DeleteBuffers(1, &fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000033 fBufferID = 0;
reed@google.comac10a2d2010-12-22 21:39:39 +000034 }
35}
36
bsalomon@google.com8fe72472011-03-30 21:26:44 +000037void GrGLIndexBuffer::onAbandon() {
38 fBufferID = 0;
39 fLockPtr = NULL;
40}
41
bsalomon@google.com1c13c962011-02-14 16:51:21 +000042void GrGLIndexBuffer::bind() const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000043 GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000044 GPUGL->notifyIndexBufferBind(this);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000045}
46
twiz@google.com0f31ca72011-03-18 17:38:11 +000047GrGLuint GrGLIndexBuffer::bufferID() const {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000048 return fBufferID;
49}
50
reed@google.comac10a2d2010-12-22 21:39:39 +000051void* GrGLIndexBuffer::lock() {
52 GrAssert(fBufferID);
53 GrAssert(!isLocked());
bsalomon@google.com18c9c192011-09-22 21:01:31 +000054 if (this->getGpu()->getCaps().fBufferLockSupport) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000055 this->bind();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000056 // Let driver know it can discard the old data
bsalomon@google.com0b77d682011-08-19 13:28:54 +000057 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
58 this->sizeInBytes(),
59 NULL,
60 this->dynamic() ? GR_GL_DYNAMIC_DRAW :
61 GR_GL_STATIC_DRAW));
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000062 GR_GL_CALL_RET(GPUGL->glInterface(),
63 fLockPtr,
64 MapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
65 GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000066
67 return fLockPtr;
68 }
69 return NULL;
70}
71
bsalomon@google.com1c13c962011-02-14 16:51:21 +000072void* GrGLIndexBuffer::lockPtr() const {
73 return fLockPtr;
74}
75
reed@google.comac10a2d2010-12-22 21:39:39 +000076void GrGLIndexBuffer::unlock() {
77 GrAssert(fBufferID);
78 GrAssert(isLocked());
bsalomon@google.com18c9c192011-09-22 21:01:31 +000079 GrAssert(this->getGpu()->getCaps().fBufferLockSupport);
reed@google.comac10a2d2010-12-22 21:39:39 +000080
bsalomon@google.com8fe72472011-03-30 21:26:44 +000081 this->bind();
bsalomon@google.com0b77d682011-08-19 13:28:54 +000082 GL_CALL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000083 fLockPtr = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000084}
85
86bool GrGLIndexBuffer::isLocked() const {
reed@google.comac10a2d2010-12-22 21:39:39 +000087#if GR_DEBUG
bsalomon@google.com18c9c192011-09-22 21:01:31 +000088 if (this->isValid() && this->getGpu()->getCaps().fBufferLockSupport) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000089 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000090 GrGLint mapped;
bsalomon@google.com0b77d682011-08-19 13:28:54 +000091 GL_CALL(GetBufferParameteriv(GR_GL_ELEMENT_ARRAY_BUFFER,
92 GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000093 GrAssert(!!mapped == !!fLockPtr);
94 }
95#endif
96 return NULL != fLockPtr;
97}
98
bsalomon@google.com1c13c962011-02-14 16:51:21 +000099bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000100 GrAssert(fBufferID);
101 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000102 if (srcSizeInBytes > this->sizeInBytes()) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000103 return false;
104 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000105 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000106 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000107#if !GR_GL_USE_BUFFER_DATA_NULL_HINT
108 // Note that we're cheating on the size here. Currently no methods
109 // allow a partial update that preserves contents of non-updated
110 // portions of the buffer (and lock() does a glBufferData(..size, NULL..))
111 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER, srcSizeInBytes, src, usage));
112#else
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000113 if (this->sizeInBytes() == srcSizeInBytes) {
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000114 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
115 srcSizeInBytes, src, usage));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000116 } else {
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000117 // Before we call glBufferSubData we give the driver a hint using
118 // glBufferData with NULL. This makes the old buffer contents
119 // inaccessible to future draws. The GPU may still be processing draws
120 // that reference the old contents. With this hint it can assign a
121 // different allocation for the new contents to avoid flushing the gpu
122 // past draws consuming the old contents.
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000123 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
124 this->sizeInBytes(), NULL, usage));
bsalomon@google.com0b77d682011-08-19 13:28:54 +0000125 GL_CALL(BufferSubData(GR_GL_ELEMENT_ARRAY_BUFFER,
126 0, srcSizeInBytes, src));
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000127 }
bsalomon@google.com96e96df2011-10-10 14:49:29 +0000128#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000129 return true;
130}
131