Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
355
libs/drape/drape_tests/batcher_tests.cpp
Normal file
355
libs/drape/drape_tests/batcher_tests.cpp
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
#include "testing/testing.hpp"
|
||||
|
||||
#include "drape/drape_tests/gl_mock_functions.hpp"
|
||||
#include "drape/drape_tests/memory_comparer.hpp"
|
||||
#include "drape/drape_tests/testing_graphics_context.hpp"
|
||||
|
||||
#include "drape/batcher.hpp"
|
||||
#include "drape/gl_constants.hpp"
|
||||
#include "drape/index_storage.hpp"
|
||||
#include "drape/vertex_array_buffer.hpp"
|
||||
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
|
||||
using testing::_;
|
||||
using testing::AnyOf;
|
||||
using testing::IgnoreResult;
|
||||
using testing::InSequence;
|
||||
using testing::Invoke;
|
||||
using testing::Return;
|
||||
using namespace dp;
|
||||
using namespace std::placeholders;
|
||||
|
||||
namespace
|
||||
{
|
||||
struct VAOAcceptor
|
||||
{
|
||||
virtual void FlushFullBucket(RenderState const & /* state */, drape_ptr<RenderBucket> && bucket)
|
||||
{
|
||||
m_vao.push_back(std::move(bucket));
|
||||
}
|
||||
|
||||
std::vector<drape_ptr<RenderBucket>> m_vao;
|
||||
};
|
||||
|
||||
class TestExtension : public dp::BaseRenderStateExtension
|
||||
{
|
||||
public:
|
||||
bool Less(ref_ptr<dp::BaseRenderStateExtension> other) const override { return false; }
|
||||
bool Equal(ref_ptr<dp::BaseRenderStateExtension> other) const override { return true; }
|
||||
};
|
||||
|
||||
class BatcherExpectations
|
||||
{
|
||||
public:
|
||||
BatcherExpectations() : m_indexBufferID(1), m_dataBufferID(2) {}
|
||||
|
||||
template <typename TBatcherCall>
|
||||
void RunTest(float * vertexes, void * indexes, uint32_t vertexCount, uint8_t vertexComponentCount,
|
||||
uint32_t indexCount, TBatcherCall const & fn)
|
||||
{
|
||||
uint32_t const vertexSize = vertexCount * vertexComponentCount;
|
||||
MemoryComparer const dataCmp(vertexes, vertexSize * sizeof(float));
|
||||
MemoryComparer const indexCmp(indexes, indexCount * dp::IndexStorage::SizeOfIndex());
|
||||
|
||||
ExpectBufferCreation(vertexSize, indexCount, indexCmp, dataCmp);
|
||||
|
||||
auto renderState = make_unique_dp<TestExtension>();
|
||||
auto state = RenderState(0, make_ref(renderState));
|
||||
|
||||
BindingInfo binding(1);
|
||||
BindingDecl & decl = binding.GetBindingDecl(0);
|
||||
decl.m_attributeName = "position";
|
||||
decl.m_componentCount = vertexComponentCount;
|
||||
decl.m_componentType = gl_const::GLFloatType;
|
||||
decl.m_offset = 0;
|
||||
decl.m_stride = 0;
|
||||
|
||||
AttributeProvider provider(1, vertexCount);
|
||||
provider.InitStream(0, binding, make_ref(vertexes));
|
||||
|
||||
TestingGraphicsContext context;
|
||||
VAOAcceptor vaoAcceptor;
|
||||
Batcher batcher(65000, 65000);
|
||||
batcher.StartSession(std::bind(&VAOAcceptor::FlushFullBucket, &vaoAcceptor, _1, _2));
|
||||
fn(&batcher, state, make_ref(&provider));
|
||||
batcher.EndSession(make_ref(&context));
|
||||
|
||||
ExpectBufferDeletion();
|
||||
|
||||
for (size_t i = 0; i < vaoAcceptor.m_vao.size(); ++i)
|
||||
vaoAcceptor.m_vao[i].reset();
|
||||
}
|
||||
|
||||
void ExpectBufferCreation(uint32_t vertexCount, uint32_t indexCount, MemoryComparer const & indexCmp,
|
||||
MemoryComparer const & vertexCmp)
|
||||
{
|
||||
InSequence seq;
|
||||
|
||||
// data buffer creation
|
||||
EXPECTGL(glGenBuffer()).WillOnce(Return(m_dataBufferID));
|
||||
EXPECTGL(glBindBuffer(m_dataBufferID, gl_const::GLArrayBuffer));
|
||||
EXPECTGL(glBufferData(gl_const::GLArrayBuffer, vertexCount * sizeof(float), _, gl_const::GLDynamicDraw))
|
||||
.WillOnce(Invoke(&vertexCmp, &MemoryComparer::cmpSubBuffer));
|
||||
|
||||
// Index buffer creation
|
||||
EXPECTGL(glGenBuffer()).WillOnce(Return(m_indexBufferID));
|
||||
EXPECTGL(glBindBuffer(m_indexBufferID, gl_const::GLElementArrayBuffer));
|
||||
EXPECTGL(glBufferData(gl_const::GLElementArrayBuffer, indexCount * dp::IndexStorage::SizeOfIndex(), _,
|
||||
gl_const::GLDynamicDraw))
|
||||
.WillOnce(Invoke(&indexCmp, &MemoryComparer::cmpSubBuffer));
|
||||
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLElementArrayBuffer));
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLArrayBuffer));
|
||||
}
|
||||
|
||||
void ExpectBufferDeletion()
|
||||
{
|
||||
InSequence seq;
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLElementArrayBuffer));
|
||||
EXPECTGL(glDeleteBuffer(m_indexBufferID));
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLArrayBuffer));
|
||||
EXPECTGL(glDeleteBuffer(m_dataBufferID));
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_indexBufferID = 0;
|
||||
uint32_t m_dataBufferID = 0;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(BatchLists_Test)
|
||||
{
|
||||
TestingGraphicsContext context;
|
||||
uint32_t const kVerticesCount = 12;
|
||||
uint32_t const kFloatsCount = 3 * 12; // 3 component on each vertex.
|
||||
float data[kFloatsCount];
|
||||
for (uint32_t i = 0; i < kFloatsCount; ++i)
|
||||
data[i] = static_cast<float>(i);
|
||||
|
||||
std::vector<uint32_t> indexesRaw(kVerticesCount);
|
||||
for (uint32_t i = 0; i < kVerticesCount; ++i)
|
||||
indexesRaw[i] = i;
|
||||
dp::IndexStorage indexes(std::move(indexesRaw));
|
||||
|
||||
BatcherExpectations expectations;
|
||||
auto fn = [&context](Batcher * batcher, RenderState const & state, ref_ptr<AttributeProvider> p)
|
||||
{ batcher->InsertTriangleList(make_ref(&context), state, p); };
|
||||
expectations.RunTest(data, indexes.GetRaw(), kVerticesCount, 3, kVerticesCount, fn);
|
||||
}
|
||||
|
||||
UNIT_TEST(BatchListOfStript_4stride)
|
||||
{
|
||||
TestingGraphicsContext context;
|
||||
uint32_t const kVerticesCount = 12;
|
||||
uint32_t const kIndicesCount = 18;
|
||||
|
||||
float data[3 * kVerticesCount];
|
||||
for (uint32_t i = 0; i < kVerticesCount * 3; ++i)
|
||||
data[i] = static_cast<float>(i);
|
||||
|
||||
std::vector<uint32_t> indexesRaw = {0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7, 6, 8, 9, 10, 9, 11, 10};
|
||||
dp::IndexStorage indexes(std::move(indexesRaw));
|
||||
|
||||
BatcherExpectations expectations;
|
||||
auto fn = [&context](Batcher * batcher, RenderState const & state, ref_ptr<AttributeProvider> p)
|
||||
{ batcher->InsertListOfStrip(make_ref(&context), state, p, dp::Batcher::VertexPerQuad); };
|
||||
|
||||
expectations.RunTest(data, indexes.GetRaw(), kVerticesCount, 3, kIndicesCount, fn);
|
||||
}
|
||||
|
||||
UNIT_TEST(BatchListOfStript_5stride)
|
||||
{
|
||||
TestingGraphicsContext context;
|
||||
uint32_t const kVerticesCount = 15;
|
||||
uint32_t const kIndicesCount = 27;
|
||||
|
||||
float data[3 * kVerticesCount];
|
||||
for (uint32_t i = 0; i < kVerticesCount * 3; ++i)
|
||||
data[i] = static_cast<float>(i);
|
||||
|
||||
std::vector<uint32_t> indexesRaw = {0, 1, 2, 1, 3, 2, 2, 3, 4, 5, 6, 7, 6, 8,
|
||||
7, 7, 8, 9, 10, 11, 12, 11, 13, 12, 12, 13, 14};
|
||||
dp::IndexStorage indexes(std::move(indexesRaw));
|
||||
|
||||
BatcherExpectations expectations;
|
||||
auto fn = [&context](Batcher * batcher, RenderState const & state, ref_ptr<AttributeProvider> p)
|
||||
{ batcher->InsertListOfStrip(make_ref(&context), state, p, 5); };
|
||||
expectations.RunTest(data, indexes.GetRaw(), kVerticesCount, 3, kIndicesCount, fn);
|
||||
}
|
||||
|
||||
UNIT_TEST(BatchListOfStript_6stride)
|
||||
{
|
||||
TestingGraphicsContext context;
|
||||
uint32_t const kVerticesCount = 18;
|
||||
uint32_t const kIndicesCount = 36;
|
||||
|
||||
float data[3 * kVerticesCount];
|
||||
for (uint32_t i = 0; i < kVerticesCount * 3; ++i)
|
||||
data[i] = static_cast<float>(i);
|
||||
|
||||
std::vector<uint32_t> indexesRaw = {0, 1, 2, 1, 3, 2, 2, 3, 4, 3, 5, 4, 6, 7, 8, 7, 9, 8,
|
||||
8, 9, 10, 9, 11, 10, 12, 13, 14, 13, 15, 14, 14, 15, 16, 15, 17, 16};
|
||||
dp::IndexStorage indexes(std::move(indexesRaw));
|
||||
|
||||
BatcherExpectations expectations;
|
||||
auto fn = [&context](Batcher * batcher, RenderState const & state, ref_ptr<AttributeProvider> p)
|
||||
{ batcher->InsertListOfStrip(make_ref(&context), state, p, 6); };
|
||||
expectations.RunTest(data, indexes.GetRaw(), kVerticesCount, 3, kIndicesCount, fn);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
class PartialBatcherTest
|
||||
{
|
||||
public:
|
||||
struct BufferNode
|
||||
{
|
||||
BufferNode(uint32_t indexByteCount, uint32_t vertexByteCount, void * indexData, void * vertexData)
|
||||
: m_indexByteCount(indexByteCount)
|
||||
, m_vertexByteCount(vertexByteCount)
|
||||
, m_indexData(indexData)
|
||||
, m_vertexData(vertexData)
|
||||
, m_indexBufferID(0)
|
||||
, m_vertexBufferID(0)
|
||||
{}
|
||||
|
||||
uint32_t m_indexByteCount;
|
||||
uint32_t m_vertexByteCount;
|
||||
void * m_indexData;
|
||||
void * m_vertexData;
|
||||
uint32_t m_indexBufferID;
|
||||
uint32_t m_vertexBufferID;
|
||||
};
|
||||
|
||||
PartialBatcherTest() = default;
|
||||
|
||||
~PartialBatcherTest() { std::for_each(m_comparators.begin(), m_comparators.end(), base::DeleteFunctor()); }
|
||||
|
||||
void AddBufferNode(BufferNode const & node)
|
||||
{
|
||||
m_nodes.push_back(node);
|
||||
BufferNode & currentNode = m_nodes.back();
|
||||
currentNode.m_indexBufferID = m_bufferIDCounter++;
|
||||
currentNode.m_vertexBufferID = m_bufferIDCounter++;
|
||||
|
||||
// data buffer creation
|
||||
EXPECTGL(glGenBuffer()).WillOnce(Return(currentNode.m_vertexBufferID));
|
||||
EXPECTGL(glBindBuffer(currentNode.m_vertexBufferID, gl_const::GLArrayBuffer));
|
||||
|
||||
m_comparators.push_back(new MemoryComparer(currentNode.m_vertexData, currentNode.m_vertexByteCount));
|
||||
MemoryComparer * vertexComparer = m_comparators.back();
|
||||
|
||||
EXPECTGL(glBufferData(gl_const::GLArrayBuffer, currentNode.m_vertexByteCount, _, gl_const::GLDynamicDraw))
|
||||
.WillOnce(Invoke(vertexComparer, &MemoryComparer::cmpSubBuffer));
|
||||
|
||||
// Index buffer creation
|
||||
EXPECTGL(glGenBuffer()).WillOnce(Return(currentNode.m_indexBufferID));
|
||||
EXPECTGL(glBindBuffer(currentNode.m_indexBufferID, gl_const::GLElementArrayBuffer));
|
||||
|
||||
m_comparators.push_back(new MemoryComparer(currentNode.m_indexData, currentNode.m_indexByteCount));
|
||||
MemoryComparer * indexComparer = m_comparators.back();
|
||||
|
||||
EXPECTGL(glBufferData(gl_const::GLElementArrayBuffer, currentNode.m_indexByteCount, _, gl_const::GLDynamicDraw))
|
||||
.WillOnce(Invoke(indexComparer, &MemoryComparer::cmpSubBuffer));
|
||||
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLElementArrayBuffer));
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLArrayBuffer));
|
||||
}
|
||||
|
||||
void CloseExpection()
|
||||
{
|
||||
for (auto const & node : m_nodes)
|
||||
{
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLElementArrayBuffer));
|
||||
EXPECTGL(glDeleteBuffer(node.m_indexBufferID));
|
||||
EXPECTGL(glBindBuffer(0, gl_const::GLArrayBuffer));
|
||||
EXPECTGL(glDeleteBuffer(node.m_vertexBufferID));
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t m_bufferIDCounter = 1;
|
||||
|
||||
std::vector<BufferNode> m_nodes;
|
||||
std::vector<MemoryComparer *> m_comparators;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
UNIT_TEST(BatchListOfStript_partial)
|
||||
{
|
||||
TestingGraphicsContext context;
|
||||
uint32_t const VertexCount = 16;
|
||||
uint32_t const ComponentCount = 3;
|
||||
uint32_t const VertexArraySize = VertexCount * ComponentCount;
|
||||
uint32_t const IndexCount = 24;
|
||||
|
||||
uint32_t const FirstBufferVertexPortion = 12;
|
||||
uint32_t const SecondBufferVertexPortion = VertexCount - FirstBufferVertexPortion;
|
||||
uint32_t const FirstBufferIndexPortion = 18;
|
||||
uint32_t const SecondBufferIndexPortion = IndexCount - FirstBufferIndexPortion;
|
||||
|
||||
float vertexData[VertexArraySize];
|
||||
for (uint32_t i = 0; i < VertexArraySize; ++i)
|
||||
vertexData[i] = static_cast<float>(i);
|
||||
|
||||
std::vector<uint32_t> indexDataRaw = {0, 1, 2, 1, 3, 2, 4, 5, 6, 5, 7,
|
||||
6, 8, 9, 10, 9, 11, 10, 0, 1, 2, // start new buffer
|
||||
1, 3, 2};
|
||||
dp::IndexStorage indexData(std::move(indexDataRaw));
|
||||
|
||||
PartialBatcherTest::BufferNode node1(FirstBufferIndexPortion * dp::IndexStorage::SizeOfIndex(),
|
||||
FirstBufferVertexPortion * ComponentCount * sizeof(float), indexData.GetRaw(),
|
||||
vertexData);
|
||||
|
||||
PartialBatcherTest::BufferNode node2(SecondBufferIndexPortion * dp::IndexStorage::SizeOfIndex(),
|
||||
SecondBufferVertexPortion * ComponentCount * sizeof(float),
|
||||
indexData.GetRaw(FirstBufferIndexPortion),
|
||||
vertexData + FirstBufferVertexPortion * ComponentCount);
|
||||
|
||||
using IndexVertexCount = std::pair<uint32_t, uint32_t>;
|
||||
std::vector<IndexVertexCount> srcData;
|
||||
srcData.emplace_back(30, 12);
|
||||
srcData.emplace_back(30, 13);
|
||||
srcData.emplace_back(18, 30);
|
||||
srcData.emplace_back(19, 30);
|
||||
|
||||
for (size_t i = 0; i < srcData.size(); ++i)
|
||||
{
|
||||
InSequence seq;
|
||||
PartialBatcherTest test;
|
||||
test.AddBufferNode(node1);
|
||||
test.AddBufferNode(node2);
|
||||
test.CloseExpection();
|
||||
|
||||
auto renderState = make_unique_dp<TestExtension>();
|
||||
auto state = RenderState(0, make_ref(renderState));
|
||||
|
||||
BindingInfo binding(1);
|
||||
BindingDecl & decl = binding.GetBindingDecl(0);
|
||||
decl.m_attributeName = "position";
|
||||
decl.m_componentCount = ComponentCount;
|
||||
decl.m_componentType = gl_const::GLFloatType;
|
||||
decl.m_offset = 0;
|
||||
decl.m_stride = 0;
|
||||
|
||||
AttributeProvider provider(1, VertexCount);
|
||||
provider.InitStream(0, binding, make_ref(vertexData));
|
||||
|
||||
VAOAcceptor vaoAcceptor;
|
||||
Batcher batcher(srcData[i].first, srcData[i].second);
|
||||
batcher.StartSession(std::bind(&VAOAcceptor::FlushFullBucket, &vaoAcceptor, _1, _2));
|
||||
batcher.InsertListOfStrip(make_ref(&context), state, make_ref(&provider), 4);
|
||||
batcher.EndSession(make_ref(&context));
|
||||
|
||||
for (size_t i = 0; i < vaoAcceptor.m_vao.size(); ++i)
|
||||
vaoAcceptor.m_vao[i].reset();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue