Hash :
f8b58a0c
Author :
Date :
2010-03-26T04:08:45
Support translating indices. TRAC #11393 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Andrew Lewycky git-svn-id: https://angleproject.googlecode.com/svn/trunk@72 736b8ea6-26fd-11df-bfd4-992fa37f6226
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
//
// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// geometry/IndexDataManager.cpp: Defines the IndexDataManager, a class that
// runs the Buffer translation process for index buffers.
#include "geometry/IndexDataManager.h"
#include "common/debug.h"
#include "Buffer.h"
#include "geometry/backend.h"
namespace
{
enum { INITIAL_INDEX_BUFFER_SIZE = sizeof(gl::Index) * 8192 };
}
namespace gl
{
IndexDataManager::IndexDataManager(Context *context, BufferBackEnd *backend)
: mContext(context), mBackend(backend)
{
mStreamBuffer = mBackend->createIndexBuffer(INITIAL_INDEX_BUFFER_SIZE);
}
IndexDataManager::~IndexDataManager()
{
delete mStreamBuffer;
}
namespace
{
template <class InputIndexType>
void copyIndices(const InputIndexType *in, GLsizei count, Index *out, GLuint *minIndex, GLuint *maxIndex)
{
GLuint minIndexSoFar = *in;
GLuint maxIndexSoFar = *in;
for (GLsizei i = 0; i < count; i++)
{
if (minIndexSoFar > *in) minIndexSoFar = *in;
if (maxIndexSoFar < *in) maxIndexSoFar = *in;
*out++ = *in++;
}
*minIndex = minIndexSoFar;
*maxIndex = maxIndexSoFar;
}
}
TranslatedIndexData IndexDataManager::preRenderValidate(GLenum mode, GLenum type, GLsizei count, Buffer *arrayElementBuffer, const void *indices)
{
ASSERT(type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_BYTE);
ASSERT(count > 0);
TranslatedIndexData translated;
translated.count = count;
std::size_t requiredSpace = spaceRequired(mode, type, count);
if (requiredSpace > mStreamBuffer->size())
{
std::size_t newSize = std::max(requiredSpace, 2 * mStreamBuffer->size());
TranslatedIndexBuffer *newStreamBuffer = mBackend->createIndexBuffer(newSize);
delete mStreamBuffer;
mStreamBuffer = newStreamBuffer;
}
mStreamBuffer->reserveSpace(requiredSpace);
size_t offset;
void *output = mStreamBuffer->map(requiredSpace, &offset);
translated.buffer = mStreamBuffer;
translated.offset = offset;
translated.indices = static_cast<const Index*>(output);
if (arrayElementBuffer != NULL)
{
indices = static_cast<const GLubyte*>(arrayElementBuffer->data()) + reinterpret_cast<GLsizei>(indices);
}
Index *out = static_cast<Index*>(output);
if (type == GL_UNSIGNED_SHORT)
{
const GLushort *in = static_cast<const GLushort*>(indices);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
else
{
const GLubyte *in = static_cast<const GLubyte*>(indices);
copyIndices(in, count, out, &translated.minIndex, &translated.maxIndex);
}
mStreamBuffer->unmap();
return translated;
}
std::size_t IndexDataManager::spaceRequired(GLenum mode, GLenum type, GLsizei count)
{
return count * sizeof(Index);
}
}