blob: 561133add857a6105162c756e39975024005dcb4 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
8
epoger@google.comec3ed6a2011-07-28 14:26:00 +00009
reed@google.comac10a2d2010-12-22 21:39:39 +000010#include "GrGLIndexBuffer.h"
11#include "GrGpuGL.h"
12
bsalomon@google.com8fe72472011-03-30 21:26:44 +000013#define GPUGL static_cast<GrGpuGL*>(getGpu())
14
bsalomon@google.com0b77d682011-08-19 13:28:54 +000015#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
16
bsalomon@google.com8fe72472011-03-30 21:26:44 +000017GrGLIndexBuffer::GrGLIndexBuffer(GrGpuGL* gpu,
bsalomon@google.com72830222013-01-23 20:25:22 +000018 bool isWrapped,
bsalomon@google.com8fe72472011-03-30 21:26:44 +000019 GrGLuint id,
20 size_t sizeInBytes,
21 bool dynamic)
bsalomon@google.com72830222013-01-23 20:25:22 +000022 : INHERITED(gpu, isWrapped, sizeInBytes, dynamic)
bsalomon@google.com8fe72472011-03-30 21:26:44 +000023 , 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
bsalomon@google.com72830222013-01-23 20:25:22 +000030 if (fBufferID && !this->isWrapped()) {
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 }
robertphillips@google.comd3645542012-09-05 18:37:39 +000035
36 INHERITED::onRelease();
reed@google.comac10a2d2010-12-22 21:39:39 +000037}
38
bsalomon@google.com8fe72472011-03-30 21:26:44 +000039void GrGLIndexBuffer::onAbandon() {
40 fBufferID = 0;
41 fLockPtr = NULL;
robertphillips@google.comd3645542012-09-05 18:37:39 +000042
43 INHERITED::onAbandon();
bsalomon@google.com8fe72472011-03-30 21:26:44 +000044}
45
bsalomon@google.com1c13c962011-02-14 16:51:21 +000046void GrGLIndexBuffer::bind() const {
bsalomon@google.com0b77d682011-08-19 13:28:54 +000047 GL_CALL(BindBuffer(GR_GL_ELEMENT_ARRAY_BUFFER, fBufferID));
bsalomon@google.com8fe72472011-03-30 21:26:44 +000048 GPUGL->notifyIndexBufferBind(this);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000049}
50
twiz@google.com0f31ca72011-03-18 17:38:11 +000051GrGLuint GrGLIndexBuffer::bufferID() const {
bsalomon@google.com1c13c962011-02-14 16:51:21 +000052 return fBufferID;
53}
54
reed@google.comac10a2d2010-12-22 21:39:39 +000055void* GrGLIndexBuffer::lock() {
56 GrAssert(fBufferID);
57 GrAssert(!isLocked());
bsalomon@google.comf6601872012-08-28 21:11:35 +000058 if (this->getGpu()->getCaps().bufferLockSupport()) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000059 this->bind();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000060 // Let driver know it can discard the old data
bsalomon@google.com0b77d682011-08-19 13:28:54 +000061 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
62 this->sizeInBytes(),
63 NULL,
64 this->dynamic() ? GR_GL_DYNAMIC_DRAW :
65 GR_GL_STATIC_DRAW));
bsalomon@google.com56bfc5a2011-09-01 13:28:16 +000066 GR_GL_CALL_RET(GPUGL->glInterface(),
67 fLockPtr,
68 MapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER,
69 GR_GL_WRITE_ONLY));
reed@google.comac10a2d2010-12-22 21:39:39 +000070
71 return fLockPtr;
72 }
73 return NULL;
74}
75
bsalomon@google.com1c13c962011-02-14 16:51:21 +000076void* GrGLIndexBuffer::lockPtr() const {
77 return fLockPtr;
78}
79
reed@google.comac10a2d2010-12-22 21:39:39 +000080void GrGLIndexBuffer::unlock() {
81 GrAssert(fBufferID);
82 GrAssert(isLocked());
bsalomon@google.comf6601872012-08-28 21:11:35 +000083 GrAssert(this->getGpu()->getCaps().bufferLockSupport());
reed@google.comac10a2d2010-12-22 21:39:39 +000084
bsalomon@google.com8fe72472011-03-30 21:26:44 +000085 this->bind();
bsalomon@google.com0b77d682011-08-19 13:28:54 +000086 GL_CALL(UnmapBuffer(GR_GL_ELEMENT_ARRAY_BUFFER));
bsalomon@google.com1c13c962011-02-14 16:51:21 +000087 fLockPtr = NULL;
reed@google.comac10a2d2010-12-22 21:39:39 +000088}
89
90bool GrGLIndexBuffer::isLocked() const {
bsalomon@google.comd850c182012-03-08 16:45:22 +000091 // this check causes a lot of noise in the gl log
92#if 0
bsalomon@google.com18c9c192011-09-22 21:01:31 +000093 if (this->isValid() && this->getGpu()->getCaps().fBufferLockSupport) {
bsalomon@google.com8fe72472011-03-30 21:26:44 +000094 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +000095 GrGLint mapped;
bsalomon@google.com0b77d682011-08-19 13:28:54 +000096 GL_CALL(GetBufferParameteriv(GR_GL_ELEMENT_ARRAY_BUFFER,
97 GR_GL_BUFFER_MAPPED, &mapped));
reed@google.comac10a2d2010-12-22 21:39:39 +000098 GrAssert(!!mapped == !!fLockPtr);
99 }
100#endif
101 return NULL != fLockPtr;
102}
103
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000104bool GrGLIndexBuffer::updateData(const void* src, size_t srcSizeInBytes) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000105 GrAssert(fBufferID);
106 GrAssert(!isLocked());
bsalomon@google.comcee661a2011-07-26 12:32:36 +0000107 if (srcSizeInBytes > this->sizeInBytes()) {
reed@google.comac10a2d2010-12-22 21:39:39 +0000108 return false;
109 }
bsalomon@google.com8fe72472011-03-30 21:26:44 +0000110 this->bind();
twiz@google.com0f31ca72011-03-18 17:38:11 +0000111 GrGLenum usage = dynamic() ? GR_GL_DYNAMIC_DRAW : GR_GL_STATIC_DRAW;
bsalomon@google.com5ffd5ba2012-03-01 15:29:07 +0000112
bsalomon@google.comc1dd8882012-03-02 20:36:18 +0000113#if GR_GL_USE_BUFFER_DATA_NULL_HINT
114 if (this->sizeInBytes() == srcSizeInBytes) {
115 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
116 srcSizeInBytes, src, usage));
bsalomon@google.com5ffd5ba2012-03-01 15:29:07 +0000117 } else {
bsalomon@google.comc1dd8882012-03-02 20:36:18 +0000118 // Before we call glBufferSubData we give the driver a hint using
119 // glBufferData with NULL. This makes the old buffer contents
120 // inaccessible to future draws. The GPU may still be processing
121 // draws that reference the old contents. With this hint it can
122 // assign a different allocation for the new contents to avoid
123 // flushing the gpu past draws consuming the old contents.
124 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
125 this->sizeInBytes(), NULL, usage));
126 GL_CALL(BufferSubData(GR_GL_ELEMENT_ARRAY_BUFFER,
127 0, srcSizeInBytes, src));
bsalomon@google.com5ffd5ba2012-03-01 15:29:07 +0000128 }
bsalomon@google.comc1dd8882012-03-02 20:36:18 +0000129#else
130 // Note that we're cheating on the size here. Currently no methods
131 // allow a partial update that preserves contents of non-updated
132 // portions of the buffer (lock() does a glBufferData(..size, NULL..))
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000133 GL_CALL(BufferData(GR_GL_ELEMENT_ARRAY_BUFFER,
bsalomon@google.comc1dd8882012-03-02 20:36:18 +0000134 srcSizeInBytes, src, usage));
135#endif
reed@google.comac10a2d2010-12-22 21:39:39 +0000136 return true;
137}