Home | History | Annotate | Download | only in d3d
      1 //
      2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // IndexBuffer.cpp: Defines the abstract IndexBuffer class and IndexBufferInterface
      8 // class with derivations, classes that perform graphics API agnostic index buffer operations.
      9 
     10 #include "libGLESv2/renderer/d3d/IndexBuffer.h"
     11 #include "libGLESv2/renderer/Renderer.h"
     12 
     13 namespace rx
     14 {
     15 
     16 unsigned int IndexBuffer::mNextSerial = 1;
     17 
     18 IndexBuffer::IndexBuffer()
     19 {
     20     updateSerial();
     21 }
     22 
     23 IndexBuffer::~IndexBuffer()
     24 {
     25 }
     26 
     27 unsigned int IndexBuffer::getSerial() const
     28 {
     29     return mSerial;
     30 }
     31 
     32 void IndexBuffer::updateSerial()
     33 {
     34     mSerial = mNextSerial++;
     35 }
     36 
     37 
     38 IndexBufferInterface::IndexBufferInterface(Renderer *renderer, bool dynamic) : mRenderer(renderer)
     39 {
     40     mIndexBuffer = renderer->createIndexBuffer();
     41 
     42     mDynamic = dynamic;
     43     mWritePosition = 0;
     44 }
     45 
     46 IndexBufferInterface::~IndexBufferInterface()
     47 {
     48     if (mIndexBuffer)
     49     {
     50         delete mIndexBuffer;
     51     }
     52 }
     53 
     54 GLenum IndexBufferInterface::getIndexType() const
     55 {
     56     return mIndexBuffer->getIndexType();
     57 }
     58 
     59 unsigned int IndexBufferInterface::getBufferSize() const
     60 {
     61     return mIndexBuffer->getBufferSize();
     62 }
     63 
     64 unsigned int IndexBufferInterface::getSerial() const
     65 {
     66     return mIndexBuffer->getSerial();
     67 }
     68 
     69 gl::Error IndexBufferInterface::mapBuffer(unsigned int size, void** outMappedMemory, unsigned int *streamOffset)
     70 {
     71     // Protect against integer overflow
     72     if (mWritePosition + size < mWritePosition)
     73     {
     74         return gl::Error(GL_OUT_OF_MEMORY, "Mapping of internal index buffer would cause an integer overflow.");
     75     }
     76 
     77     gl::Error error = mIndexBuffer->mapBuffer(mWritePosition, size, outMappedMemory);
     78     if (error.isError())
     79     {
     80         if (outMappedMemory)
     81         {
     82             *outMappedMemory = NULL;
     83         }
     84         return error;
     85     }
     86 
     87     if (streamOffset)
     88     {
     89         *streamOffset = mWritePosition;
     90     }
     91 
     92     mWritePosition += size;
     93     return gl::Error(GL_NO_ERROR);
     94 }
     95 
     96 gl::Error IndexBufferInterface::unmapBuffer()
     97 {
     98     return mIndexBuffer->unmapBuffer();
     99 }
    100 
    101 IndexBuffer * IndexBufferInterface::getIndexBuffer() const
    102 {
    103     return mIndexBuffer;
    104 }
    105 
    106 unsigned int IndexBufferInterface::getWritePosition() const
    107 {
    108     return mWritePosition;
    109 }
    110 
    111 void IndexBufferInterface::setWritePosition(unsigned int writePosition)
    112 {
    113     mWritePosition = writePosition;
    114 }
    115 
    116 gl::Error IndexBufferInterface::discard()
    117 {
    118     return mIndexBuffer->discard();
    119 }
    120 
    121 gl::Error IndexBufferInterface::setBufferSize(unsigned int bufferSize, GLenum indexType)
    122 {
    123     if (mIndexBuffer->getBufferSize() == 0)
    124     {
    125         return mIndexBuffer->initialize(bufferSize, indexType, mDynamic);
    126     }
    127     else
    128     {
    129         return mIndexBuffer->setSize(bufferSize, indexType);
    130     }
    131 }
    132 
    133 StreamingIndexBufferInterface::StreamingIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, true)
    134 {
    135 }
    136 
    137 StreamingIndexBufferInterface::~StreamingIndexBufferInterface()
    138 {
    139 }
    140 
    141 gl::Error StreamingIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
    142 {
    143     unsigned int curBufferSize = getBufferSize();
    144     unsigned int writePos = getWritePosition();
    145     if (size > curBufferSize)
    146     {
    147         gl::Error error = setBufferSize(std::max(size, 2 * curBufferSize), indexType);
    148         if (error.isError())
    149         {
    150             return error;
    151         }
    152         setWritePosition(0);
    153     }
    154     else if (writePos + size > curBufferSize || writePos + size < writePos)
    155     {
    156         gl::Error error = discard();
    157         if (error.isError())
    158         {
    159             return error;
    160         }
    161         setWritePosition(0);
    162     }
    163 
    164     return gl::Error(GL_NO_ERROR);
    165 }
    166 
    167 
    168 StaticIndexBufferInterface::StaticIndexBufferInterface(Renderer *renderer) : IndexBufferInterface(renderer, false)
    169 {
    170 }
    171 
    172 StaticIndexBufferInterface::~StaticIndexBufferInterface()
    173 {
    174 }
    175 
    176 gl::Error StaticIndexBufferInterface::reserveBufferSpace(unsigned int size, GLenum indexType)
    177 {
    178     unsigned int curSize = getBufferSize();
    179     if (curSize == 0)
    180     {
    181         return setBufferSize(size, indexType);
    182     }
    183     else if (curSize >= size && indexType == getIndexType())
    184     {
    185         return gl::Error(GL_NO_ERROR);
    186     }
    187     else
    188     {
    189         UNREACHABLE();
    190         return gl::Error(GL_INVALID_OPERATION, "Internal static index buffers can't be resized");
    191     }
    192 }
    193 
    194 IndexRangeCache *StaticIndexBufferInterface::getIndexRangeCache()
    195 {
    196     return &mIndexRangeCache;
    197 }
    198 
    199 }
    200