| #include "precompiled.h" |
| // |
| // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| |
| // Buffer.cpp: Implements the gl::Buffer class, representing storage of vertex and/or |
| // index data. Implements GL buffer objects and related functionality. |
| // [OpenGL ES 2.0.24] section 2.9 page 21. |
| |
| #include "libGLESv2/Buffer.h" |
| |
| #include "libGLESv2/renderer/VertexBuffer.h" |
| #include "libGLESv2/renderer/IndexBuffer.h" |
| #include "libGLESv2/renderer/BufferStorage.h" |
| #include "libGLESv2/renderer/Renderer.h" |
| |
| namespace gl |
| { |
| |
| Buffer::Buffer(rx::Renderer *renderer, GLuint id) |
| : RefCountObject(id), |
| mRenderer(renderer), |
| mUsage(GL_DYNAMIC_DRAW), |
| mAccessFlags(0), |
| mMapped(GL_FALSE), |
| mMapPointer(NULL), |
| mMapOffset(0), |
| mMapLength(0), |
| mBufferStorage(NULL), |
| mStaticVertexBuffer(NULL), |
| mStaticIndexBuffer(NULL), |
| mUnmodifiedDataUse(0) |
| { |
| mBufferStorage = renderer->createBufferStorage(); |
| } |
| |
| Buffer::~Buffer() |
| { |
| delete mBufferStorage; |
| delete mStaticVertexBuffer; |
| delete mStaticIndexBuffer; |
| } |
| |
| void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) |
| { |
| mBufferStorage->clear(); |
| mIndexRangeCache.clear(); |
| mBufferStorage->setData(data, size, 0); |
| |
| mUsage = usage; |
| |
| invalidateStaticData(); |
| |
| if (usage == GL_STATIC_DRAW) |
| { |
| mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer); |
| mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer); |
| } |
| } |
| |
| void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) |
| { |
| mBufferStorage->setData(data, size, offset); |
| mIndexRangeCache.invalidateRange(offset, size); |
| invalidateStaticData(); |
| } |
| |
| void Buffer::copyBufferSubData(Buffer* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) |
| { |
| mBufferStorage->copyData(source->mBufferStorage, size, sourceOffset, destOffset); |
| invalidateStaticData(); |
| } |
| |
| GLvoid *Buffer::mapRange(GLintptr offset, GLsizeiptr length, GLbitfield access) |
| { |
| ASSERT(!mMapped); |
| |
| void *dataPointer = mBufferStorage->map(access); |
| |
| mMapped = GL_TRUE; |
| mMapPointer = static_cast<GLvoid*>(static_cast<GLubyte*>(dataPointer) + offset); |
| mMapOffset = static_cast<GLint64>(offset); |
| mMapLength = static_cast<GLint64>(length); |
| mAccessFlags = static_cast<GLint>(access); |
| |
| return mMapPointer; |
| } |
| |
| void Buffer::unmap() |
| { |
| ASSERT(mMapped); |
| |
| mBufferStorage->unmap(); |
| |
| mMapped = GL_FALSE; |
| mMapPointer = NULL; |
| mMapOffset = 0; |
| mMapLength = 0; |
| mAccessFlags = 0; |
| } |
| |
| rx::BufferStorage *Buffer::getStorage() const |
| { |
| return mBufferStorage; |
| } |
| |
| GLint64 Buffer::size() const |
| { |
| return static_cast<GLint64>(mBufferStorage->getSize()); |
| } |
| |
| GLenum Buffer::usage() const |
| { |
| return mUsage; |
| } |
| |
| GLint Buffer::accessFlags() const |
| { |
| return mAccessFlags; |
| } |
| |
| GLboolean Buffer::mapped() const |
| { |
| return mMapped; |
| } |
| |
| GLvoid *Buffer::mapPointer() const |
| { |
| return mMapPointer; |
| } |
| |
| GLint64 Buffer::mapOffset() const |
| { |
| return mMapOffset; |
| } |
| |
| GLint64 Buffer::mapLength() const |
| { |
| return mMapLength; |
| } |
| |
| void Buffer::markTransformFeedbackUsage() |
| { |
| mBufferStorage->markTransformFeedbackUsage(); |
| invalidateStaticData(); |
| } |
| |
| rx::StaticVertexBufferInterface *Buffer::getStaticVertexBuffer() |
| { |
| return mStaticVertexBuffer; |
| } |
| |
| rx::StaticIndexBufferInterface *Buffer::getStaticIndexBuffer() |
| { |
| return mStaticIndexBuffer; |
| } |
| |
| void Buffer::invalidateStaticData() |
| { |
| if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) |
| { |
| delete mStaticVertexBuffer; |
| mStaticVertexBuffer = NULL; |
| |
| delete mStaticIndexBuffer; |
| mStaticIndexBuffer = NULL; |
| } |
| |
| mUnmodifiedDataUse = 0; |
| } |
| |
| // Creates static buffers if sufficient used data has been left unmodified |
| void Buffer::promoteStaticUsage(int dataSize) |
| { |
| if (!mStaticVertexBuffer && !mStaticIndexBuffer) |
| { |
| mUnmodifiedDataUse += dataSize; |
| |
| if (mUnmodifiedDataUse > 3 * mBufferStorage->getSize()) |
| { |
| mStaticVertexBuffer = new rx::StaticVertexBufferInterface(mRenderer); |
| mStaticIndexBuffer = new rx::StaticIndexBufferInterface(mRenderer); |
| } |
| } |
| } |
| |
| rx::IndexRangeCache *Buffer::getIndexRangeCache() |
| { |
| return &mIndexRangeCache; |
| } |
| |
| } |