gfx/angle/src/libGLESv2/renderer/IndexDataManager.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2002-2012 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 //
     8 // IndexDataManager.cpp: Defines the IndexDataManager, a class that
     9 // runs the Buffer translation process for index buffers.
    11 #include "libGLESv2/renderer/IndexDataManager.h"
    12 #include "libGLESv2/renderer/BufferStorage.h"
    14 #include "libGLESv2/Buffer.h"
    15 #include "libGLESv2/main.h"
    16 #include "libGLESv2/utilities.h"
    17 #include "libGLESv2/renderer/IndexBuffer.h"
    19 namespace rx
    20 {
    22 IndexDataManager::IndexDataManager(Renderer *renderer) : mRenderer(renderer)
    23 {
    24     mStreamingBufferShort = new StreamingIndexBufferInterface(mRenderer);
    25     if (!mStreamingBufferShort->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT))
    26     {
    27         delete mStreamingBufferShort;
    28         mStreamingBufferShort = NULL;
    29     }
    31     mStreamingBufferInt = new StreamingIndexBufferInterface(mRenderer);
    32     if (!mStreamingBufferInt->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT))
    33     {
    34         delete mStreamingBufferInt;
    35         mStreamingBufferInt = NULL;
    36     }
    38     if (!mStreamingBufferShort)
    39     {
    40         // Make sure both buffers are deleted.
    41         delete mStreamingBufferInt;
    42         mStreamingBufferInt = NULL;
    44         ERR("Failed to allocate the streaming index buffer(s).");
    45     }
    47     mCountingBuffer = NULL;
    48 }
    50 IndexDataManager::~IndexDataManager()
    51 {
    52     delete mStreamingBufferShort;
    53     delete mStreamingBufferInt;
    54     delete mCountingBuffer;
    55 }
    57 static void convertIndices(GLenum type, const void *input, GLsizei count, void *output)
    58 {
    59     if (type == GL_UNSIGNED_BYTE)
    60     {
    61         const GLubyte *in = static_cast<const GLubyte*>(input);
    62         GLushort *out = static_cast<GLushort*>(output);
    64         for (GLsizei i = 0; i < count; i++)
    65         {
    66             out[i] = in[i];
    67         }
    68     }
    69     else if (type == GL_UNSIGNED_INT)
    70     {
    71         memcpy(output, input, count * sizeof(GLuint));
    72     }
    73     else if (type == GL_UNSIGNED_SHORT)
    74     {
    75         memcpy(output, input, count * sizeof(GLushort));
    76     }
    77     else UNREACHABLE();
    78 }
    80 template <class IndexType>
    81 static void computeRange(const IndexType *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
    82 {
    83     *minIndex = indices[0];
    84     *maxIndex = indices[0];
    86     for (GLsizei i = 0; i < count; i++)
    87     {
    88         if (*minIndex > indices[i]) *minIndex = indices[i];
    89         if (*maxIndex < indices[i]) *maxIndex = indices[i];
    90     }
    91 }
    93 static void computeRange(GLenum type, const GLvoid *indices, GLsizei count, GLuint *minIndex, GLuint *maxIndex)
    94 {
    95     if (type == GL_UNSIGNED_BYTE)
    96     {
    97         computeRange(static_cast<const GLubyte*>(indices), count, minIndex, maxIndex);
    98     }
    99     else if (type == GL_UNSIGNED_INT)
   100     {
   101         computeRange(static_cast<const GLuint*>(indices), count, minIndex, maxIndex);
   102     }
   103     else if (type == GL_UNSIGNED_SHORT)
   104     {
   105         computeRange(static_cast<const GLushort*>(indices), count, minIndex, maxIndex);
   106     }
   107     else UNREACHABLE();
   108 }
   110 GLenum IndexDataManager::prepareIndexData(GLenum type, GLsizei count, gl::Buffer *buffer, const GLvoid *indices, TranslatedIndexData *translated)
   111 {
   112     if (!mStreamingBufferShort)
   113     {
   114         return GL_OUT_OF_MEMORY;
   115     }
   117     GLenum destinationIndexType = (type == GL_UNSIGNED_INT) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT;
   118     intptr_t offset = reinterpret_cast<intptr_t>(indices);
   119     bool alignedOffset = false;
   121     BufferStorage *storage = NULL;
   123     if (buffer != NULL)
   124     {
   125         storage = buffer->getStorage();
   127         switch (type)
   128         {
   129           case GL_UNSIGNED_BYTE:  alignedOffset = (offset % sizeof(GLubyte) == 0);  break;
   130           case GL_UNSIGNED_SHORT: alignedOffset = (offset % sizeof(GLushort) == 0); break;
   131           case GL_UNSIGNED_INT:   alignedOffset = (offset % sizeof(GLuint) == 0);   break;
   132           default: UNREACHABLE(); alignedOffset = false;
   133         }
   135         unsigned int typeSize = gl::ComputeTypeSize(type);
   137         // check for integer overflows and underflows
   138         if (static_cast<unsigned int>(offset) > (std::numeric_limits<unsigned int>::max() / typeSize) ||
   139             static_cast<unsigned int>(count) > ((std::numeric_limits<unsigned int>::max() / typeSize) - offset))
   140         {
   141             return GL_OUT_OF_MEMORY;
   142         }
   144         if (typeSize * static_cast<unsigned int>(count) + offset > storage->getSize())
   145         {
   146             return GL_INVALID_OPERATION;
   147         }
   149         indices = static_cast<const GLubyte*>(storage->getData()) + offset;
   150     }
   152     StreamingIndexBufferInterface *streamingBuffer = (type == GL_UNSIGNED_INT) ? mStreamingBufferInt : mStreamingBufferShort;
   154     StaticIndexBufferInterface *staticBuffer = buffer ? buffer->getStaticIndexBuffer() : NULL;
   155     IndexBufferInterface *indexBuffer = streamingBuffer;
   156     bool directStorage = alignedOffset && storage && storage->supportsDirectBinding() &&
   157                          destinationIndexType == type;
   158     unsigned int streamOffset = 0;
   160     if (directStorage)
   161     {
   162         indexBuffer = streamingBuffer;
   163         streamOffset = offset;
   164         storage->markBufferUsage();
   166         if (!buffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
   167                                                      &translated->maxIndex, NULL))
   168         {
   169             computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
   170             buffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
   171                                                    translated->maxIndex, offset);
   172         }
   173     }
   174     else if (staticBuffer && staticBuffer->getBufferSize() != 0 && staticBuffer->getIndexType() == type && alignedOffset)
   175     {
   176         indexBuffer = staticBuffer;
   177         if (!staticBuffer->getIndexRangeCache()->findRange(type, offset, count, &translated->minIndex,
   178                                                            &translated->maxIndex, &streamOffset))
   179         {
   180             streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType);
   181             computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
   182             staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
   183                                                          translated->maxIndex, streamOffset);
   184         }
   185     }
   186     else
   187     {
   188         unsigned int convertCount = count;
   190         if (staticBuffer)
   191         {
   192             if (staticBuffer->getBufferSize() == 0 && alignedOffset)
   193             {
   194                 indexBuffer = staticBuffer;
   195                 convertCount = storage->getSize() / gl::ComputeTypeSize(type);
   196             }
   197             else
   198             {
   199                 buffer->invalidateStaticData();
   200                 staticBuffer = NULL;
   201             }
   202         }
   204         if (!indexBuffer)
   205         {
   206             ERR("No valid index buffer.");
   207             return GL_INVALID_OPERATION;
   208         }
   210         unsigned int indexTypeSize = gl::ComputeTypeSize(destinationIndexType);
   211         if (convertCount > std::numeric_limits<unsigned int>::max() / indexTypeSize)
   212         {
   213             ERR("Reserving %u indicies of %u bytes each exceeds the maximum buffer size.", convertCount, indexTypeSize);
   214             return GL_OUT_OF_MEMORY;
   215         }
   217         unsigned int bufferSizeRequired = convertCount * indexTypeSize;
   218         if (!indexBuffer->reserveBufferSpace(bufferSizeRequired, type))
   219         {
   220             ERR("Failed to reserve %u bytes in an index buffer.", bufferSizeRequired);
   221             return GL_OUT_OF_MEMORY;
   222         }
   224         void* output = NULL;
   225         if (!indexBuffer->mapBuffer(bufferSizeRequired, &output, &streamOffset))
   226         {
   227             ERR("Failed to map index buffer.");
   228             return GL_OUT_OF_MEMORY;
   229         }
   231         convertIndices(type, staticBuffer ? storage->getData() : indices, convertCount, output);
   233         if (!indexBuffer->unmapBuffer())
   234         {
   235             ERR("Failed to unmap index buffer.");
   236             return GL_OUT_OF_MEMORY;
   237         }
   239         computeRange(type, indices, count, &translated->minIndex, &translated->maxIndex);
   241         if (staticBuffer)
   242         {
   243             streamOffset = (offset / gl::ComputeTypeSize(type)) * gl::ComputeTypeSize(destinationIndexType);
   244             staticBuffer->getIndexRangeCache()->addRange(type, offset, count, translated->minIndex,
   245                                                          translated->maxIndex, streamOffset);
   246         }
   247     }
   249     translated->storage = directStorage ? storage : NULL;
   250     translated->indexBuffer = indexBuffer->getIndexBuffer();
   251     translated->serial = directStorage ? storage->getSerial() : indexBuffer->getSerial();
   252     translated->startIndex = streamOffset / gl::ComputeTypeSize(destinationIndexType);
   253     translated->startOffset = streamOffset;
   255     if (buffer)
   256     {
   257         buffer->promoteStaticUsage(count * gl::ComputeTypeSize(type));
   258     }
   260     return GL_NO_ERROR;
   261 }
   263 StaticIndexBufferInterface *IndexDataManager::getCountingIndices(GLsizei count)
   264 {
   265     if (count <= 65536)   // 16-bit indices
   266     {
   267         const unsigned int spaceNeeded = count * sizeof(unsigned short);
   269         if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
   270         {
   271             delete mCountingBuffer;
   272             mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
   273             mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT);
   275             void* mappedMemory = NULL;
   276             if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
   277             {
   278                 ERR("Failed to map counting buffer.");
   279                 return NULL;
   280             }
   282             unsigned short *data = reinterpret_cast<unsigned short*>(mappedMemory);
   283             for(int i = 0; i < count; i++)
   284             {
   285                 data[i] = i;
   286             }
   288             if (!mCountingBuffer->unmapBuffer())
   289             {
   290                 ERR("Failed to unmap counting buffer.");
   291                 return NULL;
   292             }
   293         }
   294     }
   295     else if (mStreamingBufferInt)   // 32-bit indices supported
   296     {
   297         const unsigned int spaceNeeded = count * sizeof(unsigned int);
   299         if (!mCountingBuffer || mCountingBuffer->getBufferSize() < spaceNeeded)
   300         {
   301             delete mCountingBuffer;
   302             mCountingBuffer = new StaticIndexBufferInterface(mRenderer);
   303             mCountingBuffer->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT);
   305             void* mappedMemory = NULL;
   306             if (!mCountingBuffer->mapBuffer(spaceNeeded, &mappedMemory, NULL))
   307             {
   308                 ERR("Failed to map counting buffer.");
   309                 return NULL;
   310             }
   312             unsigned int *data = reinterpret_cast<unsigned int*>(mappedMemory);
   313             for(int i = 0; i < count; i++)
   314             {
   315                 data[i] = i;
   316             }
   318             if (!mCountingBuffer->unmapBuffer())
   319             {
   320                 ERR("Failed to unmap counting buffer.");
   321                 return NULL;
   322             }
   323         }
   324     }
   325     else
   326     {
   327         return NULL;
   328     }
   330     return mCountingBuffer;
   331 }
   333 }

mercurial