1bdf2d80f459d43f5a6df074431bacf41584f81b7shannon.woods@transgaming.com#include "precompiled.h"
229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com//
329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be
529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com// found in the LICENSE file.
629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com//
729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
8dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com// VertexBuffer.cpp: Defines the abstract VertexBuffer class and VertexBufferInterface
9dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com// class with derivations, classes that perform graphics API agnostic vertex buffer operations.
1029787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com#include "libGLESv2/renderer/VertexBuffer.h"
12d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com#include "libGLESv2/renderer/Renderer.h"
13d2811d688721a729f514bd78f7fd12a43beeb0a6shannon.woods@transgaming.com#include "libGLESv2/Context.h"
1429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.comnamespace rx
1629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
1729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
18dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.comunsigned int VertexBuffer::mNextSerial = 1;
19dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com
20dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.comVertexBuffer::VertexBuffer()
21dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com{
22dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com    updateSerial();
23dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com}
24dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com
25dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.comVertexBuffer::~VertexBuffer()
26dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com{
27dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com}
28dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com
29dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.comvoid VertexBuffer::updateSerial()
30dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com{
31dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com    mSerial = mNextSerial++;
32dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com}
33dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com
34dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.comunsigned int VertexBuffer::getSerial() const
35dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com{
36dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com    return mSerial;
37dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com}
38dcfb1f79cf7fd200276273949e864d268497b88cdaniel@transgaming.com
394150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comVertexBufferInterface::VertexBufferInterface(rx::Renderer *renderer, bool dynamic) : mRenderer(renderer)
4029787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
414150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mDynamic = dynamic;
42a41d07f0434c7b674510fda137daaaebb4b0ed6ddaniel@transgaming.com    mWritePosition = 0;
434150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mReservedSpace = 0;
4429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
454150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mVertexBuffer = renderer->createVertexBuffer();
4629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
4729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
484150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comVertexBufferInterface::~VertexBufferInterface()
4929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
504150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    delete mVertexBuffer;
5129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
5229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
534150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comunsigned int VertexBufferInterface::getSerial() const
5429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
554150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return mVertexBuffer->getSerial();
5629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
5729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
584150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comunsigned int VertexBufferInterface::getBufferSize() const
5929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
604150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return mVertexBuffer->getBufferSize();
6129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
6229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
634150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.combool VertexBufferInterface::setBufferSize(unsigned int size)
6429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
654150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (mVertexBuffer->getBufferSize() == 0)
664150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
674150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        return mVertexBuffer->initialize(size, mDynamic);
684150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
694150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    else
704150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
714150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        return mVertexBuffer->setBufferSize(size);
724150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
7329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
7429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
754150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comunsigned int VertexBufferInterface::getWritePosition() const
7629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
774150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return mWritePosition;
7829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
7929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
804150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comvoid VertexBufferInterface::setWritePosition(unsigned int writePosition)
8129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
824150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mWritePosition = writePosition;
8329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
8429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
854150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.combool VertexBufferInterface::discard()
8629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
874150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return mVertexBuffer->discard();
8829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
8929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
90f3fc6571dca9832876e09c63b0958d413737757bGeoff Langbool VertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib,  GLint start, GLsizei count, GLsizei instances,
91f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                                                  unsigned int *outStreamOffset)
9229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
93f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    unsigned int spaceRequired;
94f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (!mVertexBuffer->getSpaceRequired(attrib, count, instances, &spaceRequired))
95f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
96f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
97f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
98f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
99f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (mWritePosition + spaceRequired < mWritePosition)
100f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
101f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
102f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
103f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
1044150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (!reserveSpace(mReservedSpace))
10529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    {
106f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
1074150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
1084150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mReservedSpace = 0;
10929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1104150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (!mVertexBuffer->storeVertexAttributes(attrib, start, count, instances, mWritePosition))
1114150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
112f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
11329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
11429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
115f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (outStreamOffset)
116f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
117f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        *outStreamOffset = mWritePosition;
118f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
119f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
120f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    mWritePosition += spaceRequired;
1214150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
122f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    return true;
12329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
12429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
125f3fc6571dca9832876e09c63b0958d413737757bGeoff Langbool VertexBufferInterface::storeRawData(const void* data, unsigned int size, unsigned int *outStreamOffset)
12629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
127f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (mWritePosition + size < mWritePosition)
128f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
129f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
130f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
131f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
1324150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (!reserveSpace(mReservedSpace))
13329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    {
134f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
13529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
1364150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mReservedSpace = 0;
13729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1384150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (!mVertexBuffer->storeRawData(data, size, mWritePosition))
1394150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
140f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
141f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
142f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
143f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (outStreamOffset)
144f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
145f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        *outStreamOffset = mWritePosition;
14629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
14729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1484150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mWritePosition += size;
1494150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
150f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    return true;
15129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
15229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1530c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Langbool VertexBufferInterface::reserveVertexSpace(const gl::VertexAttribute &attribute, GLsizei count, GLsizei instances)
15429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
155f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    unsigned int requiredSpace;
156f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (!mVertexBuffer->getSpaceRequired(attribute, count, instances, &requiredSpace))
157f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
158f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
159f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
1600c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang
1610c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    // Protect against integer overflow
1620c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    if (mReservedSpace + requiredSpace < mReservedSpace)
1630c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    {
1640c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang         return false;
1650c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    }
1660c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang
1670c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    mReservedSpace += requiredSpace;
1680c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    return true;
16929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
17029787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1710c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Langbool VertexBufferInterface::reserveRawDataSpace(unsigned int size)
17229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
1730c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    // Protect against integer overflow
1740c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    if (mReservedSpace + size < mReservedSpace)
1750c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    {
1760c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang         return false;
1770c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    }
1780c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang
1794150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    mReservedSpace += size;
1800c8b4e563e2926f37b5b357c1fafb7115d272e03Geoff Lang    return true;
18129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
18229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1834150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comVertexBuffer* VertexBufferInterface::getVertexBuffer() const
18429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
1854150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return mVertexBuffer;
1864150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
18729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
18829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1894150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comStreamingVertexBufferInterface::StreamingVertexBufferInterface(rx::Renderer *renderer, std::size_t initialSize) : VertexBufferInterface(renderer, true)
1904150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
1914150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    setBufferSize(initialSize);
1924150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
19329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1944150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comStreamingVertexBufferInterface::~StreamingVertexBufferInterface()
1954150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
19629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
19729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
1984150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.combool StreamingVertexBufferInterface::reserveSpace(unsigned int size)
19929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
2004150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    bool result = true;
2014150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    unsigned int curBufferSize = getBufferSize();
2024150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (size > curBufferSize)
20329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    {
2044150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        result = setBufferSize(std::max(size, 3 * curBufferSize / 2));
2054150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        setWritePosition(0);
20629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
2074150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    else if (getWritePosition() + size > curBufferSize)
20829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    {
2094150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        if (!discard())
2104150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        {
2114150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com            return false;
2124150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        }
2134150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        setWritePosition(0);
21429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
21529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
2164150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    return result;
2174150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
2184150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
2194150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comStaticVertexBufferInterface::StaticVertexBufferInterface(rx::Renderer *renderer) : VertexBufferInterface(renderer, false)
2204150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
22129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
22229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
2234150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.comStaticVertexBufferInterface::~StaticVertexBufferInterface()
2244150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
2254150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
2264150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
227f3fc6571dca9832876e09c63b0958d413737757bGeoff Langbool StaticVertexBufferInterface::lookupAttribute(const gl::VertexAttribute &attribute, unsigned int *outStreamOffset)
22829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com{
22929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    for (unsigned int element = 0; element < mCache.size(); element++)
23029787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    {
23129787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com        if (mCache[element].type == attribute.mType &&
23229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            mCache[element].size == attribute.mSize &&
23329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            mCache[element].stride == attribute.stride() &&
23429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            mCache[element].normalized == attribute.mNormalized)
23529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com        {
23629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            if (mCache[element].attributeOffset == attribute.mOffset % attribute.stride())
23729787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            {
238f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                if (outStreamOffset)
239f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                {
240f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                    *outStreamOffset = mCache[element].streamOffset;
241f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                }
242f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                return true;
24329787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com            }
24429787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com        }
24529787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com    }
24629787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
247f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    return false;
24829787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
24929787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com
2504150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.combool StaticVertexBufferInterface::reserveSpace(unsigned int size)
2514150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
2524150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    unsigned int curSize = getBufferSize();
2534150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    if (curSize == 0)
2544150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
2554150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        setBufferSize(size);
2564150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        return true;
2574150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
2584150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    else if (curSize >= size)
2594150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
2604150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        return true;
2614150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
2624150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    else
2634150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    {
2644150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        UNREACHABLE();   // Static vertex buffers can't be resized
2654150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com        return false;
2664150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com    }
2674150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
2684150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
269f3fc6571dca9832876e09c63b0958d413737757bGeoff Langbool StaticVertexBufferInterface::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances,
270f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang                                                        unsigned int *outStreamOffset)
2714150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com{
272f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    unsigned int streamOffset;
273f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    if (VertexBufferInterface::storeVertexAttributes(attrib, start, count, instances, &streamOffset))
274f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
275f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        int attributeOffset = attrib.mOffset % attrib.stride();
276f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        VertexElement element = { attrib.mType, attrib.mSize, attrib.stride(), attrib.mNormalized, attributeOffset, streamOffset };
277f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        mCache.push_back(element);
2784150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
279f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        if (outStreamOffset)
280f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        {
281f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang            *outStreamOffset = streamOffset;
282f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        }
283f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang
284f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return true;
285f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
286f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    else
287f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    {
288f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang        return false;
289f3fc6571dca9832876e09c63b0958d413737757bGeoff Lang    }
2904150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com}
2914150d362e1d5f1e2cc4d63d171d1d72fb8be9cc7daniel@transgaming.com
29229787c319e2e8b10ccf0877d567a9b3d63c414f1daniel@transgaming.com}
293