Home | History | Annotate | Download | only in libGLESv2
      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