Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / d3d / IndexDataManager.cpp
index 98716c1..8d455b4 100644 (file)
@@ -1,4 +1,3 @@
-#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
 
 #include "libGLESv2/renderer/d3d/IndexDataManager.h"
 #include "libGLESv2/renderer/d3d/BufferD3D.h"
-
+#include "libGLESv2/renderer/d3d/IndexBuffer.h"
+#include "libGLESv2/renderer/Renderer.h"
 #include "libGLESv2/Buffer.h"
 #include "libGLESv2/main.h"
 #include "libGLESv2/formatutils.h"
-#include "libGLESv2/renderer/d3d/IndexBuffer.h"
-#include "libGLESv2/renderer/Renderer.h"
 
 namespace rx
 {
 
-IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
-{
-    mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
-    {
-        delete mStreamingBufferShort;
-        mStreamingBufferShort = NULL;
-    }
-
-    mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
-    if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
-    {
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-    }
-
-    if (!mStreamingBufferShort)
-    {
-        // Make sure both buffers are deleted.
-        delete mStreamingBufferInt;
-        mStreamingBufferInt = NULL;
-
-        ERR("Failed to allocate the streaming index buffer(s).");
-    }
-
-    mCountingBuffer = NULL;
-}
-
-IndexDataManager::~IndexDataManager()
-{
-    delete mStreamingBufferShort;
-    delete mStreamingBufferInt;
-    delete mCountingBuffer;
-}
-
-static void convertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
+static void ConvertIndices(GLenum sourceType, GLenum destinationType, const void *input, GLsizei count, void *output)
 {
     if (sourceType == GL_UNSIGNED_BYTE)
     {
@@ -94,43 +57,21 @@ static void convertIndices(GLenum sourceType, GLenum destinationType, const void
     else UNREACHABLE();
 }
 
-template <class IndexType>
-static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::IndexDataManager(Renderer *renderer)
+    : mRenderer(renderer),
+      mStreamingBufferShort(NULL),
+      mStreamingBufferInt(NULL)
 {
-    *minIndex = indices[0];
-    *maxIndex = indices[0];
-
-    for (GLsizei i = 0; i < count; i++)
-    {
-        if (*minIndex > indices[i]) *minIndex = indices[i];
-        if (*maxIndex < indices[i]) *maxIndex = indices[i];
-    }
 }
 
-static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
+IndexDataManager::~IndexDataManager()
 {
-    if (type == GL_UNSIGNED_BYTE)
-    {
-        computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
-    }
-    else if (type == GL_UNSIGNED_INT)
-    {
-        computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
-    }
-    else if (type == GL_UNSIGNED_SHORT)
-    {
-        computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
-    }
-    else UNREACHABLE();
+    SafeDelete(mStreamingBufferShort);
+    SafeDelete(mStreamingBufferInt);
 }
 
-GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
+gl::Error IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
 {
-    if (!mStreamingBufferShort)
-    {
-        return GL_OUT_OF_MEMORY;
-    }
-
     const gl::Type &typeInfo = gl::GetTypeInfo(type);
 
     GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
@@ -142,10 +83,6 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
 
     if (buffer != NULL)
     {
-        if (reinterpret_cast<uintptr_t>(indices) > std::numeric_limits<unsigned int>::max())
-        {
-            return GL_OUT_OF_MEMORY;
-        }
         offset = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(indices));
 
         storage = BufferD3D::makeBufferD3D(buffer->getImplementation());
@@ -158,17 +95,7 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
           default: UNREACHABLE(); alignedOffset = false;
         }
 
-        // check for integer overflows
-        if (static_cast<unsigned int>(count) > (std::numeric_limits<unsigned int>::max() / typeInfo.bytes) ||
-            typeInfo.bytes * static_cast<unsigned int>(count) + offset < offset)
-        {
-            return GL_OUT_OF_MEMORY;
-        }
-
-        if (typeInfo.bytes * static_cast<unsigned int>(count) + offset > storage->getSize())
-        {
-            return GL_INVALID_OPERATION;
-        }
+        ASSERT(typeInfo.bytes * static_cast<unsigned int>(count) + offset <= storage->getSize());
 
         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
     }
@@ -183,35 +110,25 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
     {
         streamOffset = offset;
 
-        if (!storage->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                     &translated->maxIndex, NULL))
+        if (!buffer->getIndexRangeCache()->findRange(type, offset, count, NULL, NULL))
         {
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            storage->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                   translated->maxIndex, offset);
+            buffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, offset);
         }
     }
     else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
     {
         indexBuffer = staticBuffer;
 
-        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
-                                                           &translated->maxIndex, &streamOffset))
+        if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, NULL, &streamOffset))
         {
             streamOffset = (offset / typeInfo.bytes) * gl::GetTypeInfo(destinationIndexType).bytes;
-            computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
-    else
-    {
-        computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
-    }
 
     // Avoid D3D11's primitive restart index value
     // see http://msdn.microsoft.com/en-us/library/windows/desktop/bb205124(v=vs.85).aspx
-    if (translated->maxIndex == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
+    if (translated->indexRange.end == 0xFFFF && type == GL_UNSIGNED_SHORT && mRenderer->getMajorShaderModel() > 3)
     {
         destinationIndexType = GL_UNSIGNED_INT;
         directStorage = false;
@@ -222,7 +139,11 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
 
     if (!directStorage && !indexBuffer)
     {
-        indexBuffer = (destinationIndexType == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
+        gl::Error error = getStreamingIndexBuffer(destinationIndexType, &indexBuffer);
+        if (error.isError())
+        {
+            return error;
+        }
 
         unsigned int convertCount = count;
 
@@ -240,45 +161,40 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
             }
         }
 
-        if (!indexBuffer)
-        {
-            ERR("No valid index buffer.");
-            return GL_INVALID_OPERATION;
-        }
+        ASSERT(indexBuffer);
 
         if (convertCount > std::numeric_limits<unsigned int>::max() / destTypeInfo.bytes)
         {
-            ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, destTypeInfo.bytes);
-            return GL_OUT_OF_MEMORY;
+            return gl::Error(GL_OUT_OF_MEMORY, "Reserving %u indices of %u bytes each exceeds the maximum buffer size.",
+                             convertCount, destTypeInfo.bytes);
         }
 
         unsigned int bufferSizeRequired = convertCount * destTypeInfo.bytes;
-        if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
+        error = indexBuffer->reserveBufferSpace(bufferSizeRequired, type);
+        if (error.isError())
         {
-            ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
         void* output = NULL;
-        if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
+        error = indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset);
+        if (error.isError())
         {
-            ERR("Failed to map index buffer.");
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
-        convertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
+        ConvertIndices(type, destinationIndexType, staticBuffer ? storage->getData() : indices, convertCount, output);
 
-        if (!indexBuffer->unmapBuffer())
+        error = indexBuffer->unmapBuffer();
+        if (error.isError())
         {
-            ERR("Failed to unmap index buffer.");
-            return GL_OUT_OF_MEMORY;
+            return error;
         }
 
         if (staticBuffer)
         {
             streamOffset = (offset / typeInfo.bytes) * destTypeInfo.bytes;
-            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
-                                                         translated->maxIndex, streamOffset);
+            staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->indexRange, streamOffset);
         }
     }
 
@@ -294,77 +210,46 @@ GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer
         storage->promoteStaticUsage(count * typeInfo.bytes);
     }
 
-    return GL_NO_ERROR;
+    return gl::Error(GL_NO_ERROR);
 }
 
-StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
+gl::Error IndexDataManager::getStreamingIndexBuffer(GLenum destinationIndexType, IndexBufferInterface **outBuffer)
 {
-    if (count <= 65536)   // 16-bit indices
+    ASSERT(outBuffer);
+    if (destinationIndexType == GL_UNSIGNED_INT)
     {
-        const unsigned int spaceNeeded = count * sizeof(unsigned short);
-
-        if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+        if (!mStreamingBufferInt)
         {
-            delete mCountingBuffer;
-            mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
-            mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
-
-            void* mappedMemory = NULL;
-            if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
-            {
-                ERR("Failed to map counting buffer.");
-                return NULL;
-            }
-
-            unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
-            for(int i = 0; i < count; i++)
+            mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
+            gl::Error error = mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT);
+            if (error.isError())
             {
-                data[i] = i;
-            }
-
-            if (!mCountingBuffer->unmapBuffer())
-            {
-                ERR("Failed to unmap counting buffer.");
-                return NULL;
+                SafeDelete(mStreamingBufferInt);
+                return error;
             }
         }
+
+        *outBuffer = mStreamingBufferInt;
+        return gl::Error(GL_NO_ERROR);
     }
-    else if (mStreamingBufferInt)   // 32-bit indices supported
+    else
     {
-        const unsigned int spaceNeeded = count * sizeof(unsigned int);
+        ASSERT(destinationIndexType == GL_UNSIGNED_SHORT);
 
-        if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
+        if (!mStreamingBufferShort)
         {
-            delete mCountingBuffer;
-            mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
-            mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
-
-            void* mappedMemory = NULL;
-            if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
-            {
-                ERR("Failed to map counting buffer.");
-                return NULL;
-            }
-
-            unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
-            for(int i = 0; i < count; i++)
+            mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
+            gl::Error error = mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT);
+            if (error.isError())
             {
-                data[i] = i;
-            }
-
-            if (!mCountingBuffer->unmapBuffer())
-            {
-                ERR("Failed to unmap counting buffer.");
-                return NULL;
+                SafeDelete(mStreamingBufferShort);
+                return error;
             }
         }
-    }
-    else
-    {
-        return NULL;
-    }
 
-    return mCountingBuffer;
+        *outBuffer = mStreamingBufferShort;
+        return gl::Error(GL_NO_ERROR);
+    }
 }
 
 }