1 #include "precompiled.h" 2 // 3 // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style license that can be 5 // found in the LICENSE file. 6 // 7 8 // Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or 9 // index data. Implements GL buffer objects and related functionality. 10 // [OpenGL ES 2.0.24] section 2.9 page 21. 11 12 #include "libGLESv2/Buffer.h" 13 14 #include "libGLESv2/renderer/VertexBuffer.h" 15 #include "libGLESv2/renderer/IndexBuffer.h" 16 #include "libGLESv2/renderer/BufferStorage.h" 17 #include "libGLESv2/renderer/Renderer.h" 18 19 namespace gl 20 { 21 22 Buffer::Buffer(rx::Renderer *renderer, GLuint id) 23 : RefCountObject(id), 24 mRenderer(renderer), 25 mUsage(GL_DYNAMIC_DRAW), 26 mAccessFlags(0), 27 mMapped(GL_FALSE), 28 mMapPointer(NULL), 29 mMapOffset(0), 30 mMapLength(0), 31 mBufferStorage(NULL), 32 mStaticVertexBuffer(NULL), 33 mStaticIndexBuffer(NULL), 34 mUnmodifiedDataUse(0) 35 { 36 mBufferStorage = renderer->createBufferStorage(); 37 } 38 39 Buffer::~Buffer() 40 { 41 delete mBufferStorage; 42 delete mStaticVertexBuffer; 43 delete mStaticIndexBuffer; 44 } 45 46 void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) 47 { 48 mBufferStorage->clear(); 49 mIndexRangeCache.clear(); 50 mBufferStorage->setData(data, size, 0); 51 52 mUsage = usage; 53 54 invalidateStaticData(); 55 56 if (usage == GL_STATIC_DRAW) 57 { 58 mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer); 59 mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer); 60 } 61 } 62 63 void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) 64 { 65 mBufferStorage->setData(data, size, offset); 66 mIndexRangeCache.invalidateRange(offset, size); 67 invalidateStaticData(); 68 } 69 70 void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) 71 { 72 mBufferStorage->copyData(source->mBufferStorage, size, sourceOffset, destOffset); 73 invalidateStaticData(); 74 } 75 76 GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) 77 { 78 ASSERT(!mMapped); 79 80 void *dataPointer = mBufferStorage->map(access); 81 82 mMapped = GL_TRUE; 83 mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer) + offset); 84 mMapOffset = static_cast<GLint64>(offset); 85 mMapLength = static_cast<GLint64>(length); 86 mAccessFlags = static_cast<GLint>(access); 87 88 return mMapPointer; 89 } 90 91 void Buffer::unmap() 92 { 93 ASSERT(mMapped); 94 95 mBufferStorage->unmap(); 96 97 mMapped = GL_FALSE; 98 mMapPointer = NULL; 99 mMapOffset = 0; 100 mMapLength = 0; 101 mAccessFlags = 0; 102 } 103 104 rx::BufferStorage *Buffer::getStorage() const 105 { 106 return mBufferStorage; 107 } 108 109 GLint64 Buffer::size() const 110 { 111 return static_cast<GLint64>(mBufferStorage->getSize()); 112 } 113 114 GLenum Buffer::usage() const 115 { 116 return mUsage; 117 } 118 119 GLint Buffer::accessFlags() const 120 { 121 return mAccessFlags; 122 } 123 124 GLboolean Buffer::mapped() const 125 { 126 return mMapped; 127 } 128 129 GLvoid *Buffer::mapPointer() const 130 { 131 return mMapPointer; 132 } 133 134 GLint64 Buffer::mapOffset() const 135 { 136 return mMapOffset; 137 } 138 139 GLint64 Buffer::mapLength() const 140 { 141 return mMapLength; 142 } 143 144 void Buffer::markTransformFeedbackUsage() 145 { 146 mBufferStorage->markTransformFeedbackUsage(); 147 invalidateStaticData(); 148 } 149 150 rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer() 151 { 152 return mStaticVertexBuffer; 153 } 154 155 rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer() 156 { 157 return mStaticIndexBuffer; 158 } 159 160 void Buffer::invalidateStaticData() 161 { 162 if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) 163 { 164 delete mStaticVertexBuffer; 165 mStaticVertexBuffer = NULL; 166 167 delete mStaticIndexBuffer; 168 mStaticIndexBuffer = NULL; 169 } 170 171 mUnmodifiedDataUse = 0; 172 } 173 174 // Creates static buffers if sufficient used data has been left unmodified 175 void Buffer::promoteStaticUsage(int dataSize) 176 { 177 if (!mStaticVertexBuffer && !mStaticIndexBuffer) 178 { 179 mUnmodifiedDataUse += dataSize; 180 181 if (mUnmodifiedDataUse > 3 * mBufferStorage->getSize()) 182 { 183 mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer); 184 mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer); 185 } 186 } 187 } 188 189 rx::IndexRangeCache *Buffer::getIndexRangeCache() 190 { 191 return &mIndexRangeCache; 192 } 193 194 } 195