Change VertexBufferInterface and VertexDataManager to use new VertexBuffer.

TRAC #22226

Signed-off-by: Nicolas Capens
Signed-off-by: Daniel Koch
Author: Geoff Lang

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1589 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/renderer/VertexBuffer.cpp b/src/libGLESv2/renderer/VertexBuffer.cpp
index 5ff4b90..7ffe2da 100644
--- a/src/libGLESv2/renderer/VertexBuffer.cpp
+++ b/src/libGLESv2/renderer/VertexBuffer.cpp
@@ -9,8 +9,6 @@
 
 #include "libGLESv2/renderer/VertexBuffer.h"
 
-#include "libGLESv2/renderer/Renderer9.h"
-
 namespace rx
 {
 
@@ -35,132 +33,142 @@
     return mSerial;
 }
 
-
-unsigned int VertexBufferInterface::mCurrentSerial = 1;
-
-VertexBufferInterface::VertexBufferInterface(rx::Renderer9 *renderer, std::size_t size, DWORD usageFlags) : mRenderer(renderer), mVertexBuffer(NULL)
+VertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
 {
-    if (size > 0)
-    {
-        // D3D9_REPLACE
-        HRESULT result = mRenderer->createVertexBuffer(size, usageFlags,&mVertexBuffer);
-        mSerial = issueSerial();
-
-        if (FAILED(result))
-        {
-            ERR("Out of memory allocating a vertex buffer of size %lu.", size);
-        }
-    }
-
-    mBufferSize = size;
+    mDynamic = dynamic;
     mWritePosition = 0;
-    mRequiredSpace = 0;
+    mReservedSpace = 0;
+
+    mVertexBuffer = renderer->createVertexBuffer();
 }
 
 VertexBufferInterface::~VertexBufferInterface()
 {
-    if (mVertexBuffer)
-    {
-        mVertexBuffer->Release();
-    }
-}
-
-void VertexBufferInterface::unmap()
-{
-    if (mVertexBuffer)
-    {
-        mVertexBuffer->Unlock();
-    }
-}
-
-IDirect3DVertexBuffer9 *VertexBufferInterface::getBuffer() const
-{
-    return mVertexBuffer;
+    delete mVertexBuffer;
 }
 
 unsigned int VertexBufferInterface::getSerial() const
 {
-    return mSerial;
+    return mVertexBuffer->getSerial();
 }
 
-unsigned int VertexBufferInterface::issueSerial()
+unsigned int VertexBufferInterface::getBufferSize() const
 {
-    return mCurrentSerial++;
+    return mVertexBuffer->getBufferSize();
 }
 
-void VertexBufferInterface::addRequiredSpace(UINT requiredSpace)
+bool VertexBufferInterface::setBufferSize(unsigned int size)
 {
-    mRequiredSpace += requiredSpace;
+    if (mVertexBuffer->getBufferSize() == 0)
+    {
+        return mVertexBuffer->initialize(size, mDynamic);
+    }
+    else
+    {
+        return mVertexBuffer->setBufferSize(size);
+    }
 }
 
-StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer9 *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, initialSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY)
+unsigned int VertexBufferInterface::getWritePosition() const
 {
+    return mWritePosition;
+}
+
+void VertexBufferInterface::setWritePosition(unsigned int writePosition)
+{
+    mWritePosition = writePosition;
+}
+
+bool VertexBufferInterface::discard()
+{
+    return mVertexBuffer->discard();
+}
+
+int VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+{
+    if (!reserveSpace(mReservedSpace))
+    {
+        return -1;
+    }
+    mReservedSpace = 0;
+
+    if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
+    {
+        return -1;
+    }
+
+    int oldWritePos = static_cast<int>(mWritePosition);
+    mWritePosition += mVertexBuffer->getSpaceRequired(attrib, count, instances);
+
+    return oldWritePos;
+}
+
+int VertexBufferInterface::storeRawData(const void* data, unsigned int size)
+{
+    if (!reserveSpace(mReservedSpace))
+    {
+        return -1;
+    }
+    mReservedSpace = 0;
+
+    if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
+    {
+        return -1;
+    }
+
+    int oldWritePos = static_cast<int>(mWritePosition);
+    mWritePosition += size;
+
+    return oldWritePos;
+}
+
+void VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
+{
+    mReservedSpace += mVertexBuffer->getSpaceRequired(attribute, count, instances);
+}
+
+void VertexBufferInterface::reserveRawDataSpace(unsigned int size)
+{
+    mReservedSpace += size;
+}
+
+VertexBuffer* VertexBufferInterface::getVertexBuffer() const
+{
+    return mVertexBuffer;
+}
+
+
+StreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
+{
+    setBufferSize(initialSize);
 }
 
 StreamingVertexBufferInterface::~StreamingVertexBufferInterface()
 {
 }
 
-void *StreamingVertexBufferInterface::map(const gl::VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *offset)
+bool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
 {
-    void *mapPtr = NULL;
-
-    if (mVertexBuffer)
+    bool result = true;
+    unsigned int curBufferSize = getBufferSize();
+    if (size > curBufferSize)
     {
-        HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, D3DLOCK_NOOVERWRITE);
-
-        if (FAILED(result))
+        result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
+        setWritePosition(0);
+    }
+    else if (getWritePosition() + size > curBufferSize)
+    {
+        if (!discard())
         {
-            ERR("Lock failed with error 0x%08x", result);
-            return NULL;
+            return false;
         }
-
-        *offset = mWritePosition;
-        mWritePosition += requiredSpace;
+        setWritePosition(0);
     }
 
-    return mapPtr;
+    return result;
 }
 
-void StreamingVertexBufferInterface::reserveRequiredSpace()
-{
-    if (mRequiredSpace > mBufferSize)
-    {
-        if (mVertexBuffer)
-        {
-            mVertexBuffer->Release();
-            mVertexBuffer = NULL;
-        }
-
-        mBufferSize = std::max(mRequiredSpace, 3 * mBufferSize / 2);   // 1.5 x mBufferSize is arbitrary and should be checked to see we don't have too many reallocations.
-
-        // D3D9_REPLACE
-        HRESULT result = mRenderer->createVertexBuffer(mBufferSize, D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, &mVertexBuffer);
-        mSerial = issueSerial();
-
-        if (FAILED(result))
-        {
-            ERR("Out of memory allocating a vertex buffer of size %lu.", mBufferSize);
-        }
-
-        mWritePosition = 0;
-    }
-    else if (mWritePosition + mRequiredSpace > mBufferSize)   // Recycle
-    {
-        if (mVertexBuffer)
-        {
-            void *dummy;
-            mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD);
-            mVertexBuffer->Unlock();
-        }
-
-        mWritePosition = 0;
-    }
-
-    mRequiredSpace = 0;
-}
-
-StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer9 *renderer) : VertexBufferInterface(renderer, 0, D3DUSAGE_WRITEONLY)
+StaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
 {
 }
 
@@ -168,56 +176,7 @@
 {
 }
 
-void *StaticVertexBufferInterface::map(const gl::VertexAttribute &attribute, std::size_t requiredSpace, std::size_t *streamOffset)
-{
-    void *mapPtr = NULL;
-
-    if (mVertexBuffer)
-    {
-        HRESULT result = mVertexBuffer->Lock(mWritePosition, requiredSpace, &mapPtr, 0);
-
-        if (FAILED(result))
-        {
-            ERR("Lock failed with error 0x%08x", result);
-            return NULL;
-        }
-
-        int attributeOffset = attribute.mOffset % attribute.stride();
-        VertexElement element = {attribute.mType, attribute.mSize, attribute.stride(), attribute.mNormalized, attributeOffset, mWritePosition};
-        mCache.push_back(element);
-
-        *streamOffset = mWritePosition;
-        mWritePosition += requiredSpace;
-    }
-
-    return mapPtr;
-}
-
-void StaticVertexBufferInterface::reserveRequiredSpace()
-{
-    if (!mVertexBuffer && mBufferSize == 0)
-    {
-        // D3D9_REPLACE
-        HRESULT result = mRenderer->createVertexBuffer(mRequiredSpace, D3DUSAGE_WRITEONLY, &mVertexBuffer);
-        mSerial = issueSerial();
-
-        if (FAILED(result))
-        {
-            ERR("Out of memory allocating a vertex buffer of size %lu.", mRequiredSpace);
-        }
-
-        mBufferSize = mRequiredSpace;
-    }
-    else if (mVertexBuffer && mBufferSize >= mRequiredSpace)
-    {
-        // Already allocated
-    }
-    else UNREACHABLE();   // Static vertex buffers can't be resized
-
-    mRequiredSpace = 0;
-}
-
-std::size_t StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
+int StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute)
 {
     for (unsigned int element = 0; element < mCache.size(); element++)
     {
@@ -236,4 +195,32 @@
     return -1;
 }
 
+bool StaticVertexBufferInterface::reserveSpace(unsigned int size)
+{
+    unsigned int curSize = getBufferSize();
+    if (curSize == 0)
+    {
+        setBufferSize(size);
+        return true;
+    }
+    else if (curSize >= size)
+    {
+        return true;
+    }
+    else
+    {
+        UNREACHABLE();   // Static vertex buffers can't be resized
+        return false;
+    }
+}
+
+int StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances)
+{
+    int attributeOffset = attrib.mOffset % attrib.stride();
+    VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, getWritePosition() };
+    mCache.push_back(element);
+
+    return VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances);
+}
+
 }