Browse Source

Trade: repack MeshData internals to save 8 bytes on 64-bit.

Now it's a 104-byte structure, was 112 before.
catastrophic-cross
Vladimír Vondruš 6 years ago
parent
commit
dac646e66b
  1. 29
      src/Magnum/Trade/MeshData.cpp
  2. 9
      src/Magnum/Trade/MeshData.h

29
src/Magnum/Trade/MeshData.cpp

@ -79,7 +79,12 @@ Containers::Array<MeshAttributeData> meshAttributeDataNonOwningArray(const Conta
return Containers::Array<MeshAttributeData>{const_cast<MeshAttributeData*>(view.data()), view.size(), reinterpret_cast<void(*)(MeshAttributeData*, std::size_t)>(Implementation::nonOwnedArrayDeleter)}; return Containers::Array<MeshAttributeData>{const_cast<MeshAttributeData*>(view.data()), view.size(), reinterpret_cast<void(*)(MeshAttributeData*, std::size_t)>(Implementation::nonOwnedArrayDeleter)};
} }
MeshData::MeshData(const MeshPrimitive primitive, Containers::Array<char>&& indexData, const MeshIndexData& indices, Containers::Array<char>&& vertexData, Containers::Array<MeshAttributeData>&& attributes, const UnsignedInt vertexCount, const void* const importerState) noexcept: _indexType{indices._type}, _primitive{primitive}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)}, _attributes{std::move(attributes)}, _indices{Containers::arrayCast<const char>(indices._data)} { MeshData::MeshData(const MeshPrimitive primitive, Containers::Array<char>&& indexData, const MeshIndexData& indices, Containers::Array<char>&& vertexData, Containers::Array<MeshAttributeData>&& attributes, const UnsignedInt vertexCount, const void* const importerState) noexcept: _primitive{primitive}, _indexType{indices._type}, _indexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _vertexDataFlags{DataFlag::Owned|DataFlag::Mutable}, _importerState{importerState}, _indices{static_cast<const char*>(indices._data.data())}, _attributes{std::move(attributes)}, _indexData{std::move(indexData)}, _vertexData{std::move(vertexData)} {
/* Save index count, only if the indices are actually specified */
if(_indexType != MeshIndexType{})
_indexCount = UnsignedInt(indices._data.size()/meshIndexTypeSize(indices._type));
else _indexCount = 0;
/* Save vertex count. If it's passed explicitly, use that (but still check /* Save vertex count. If it's passed explicitly, use that (but still check
that all attributes have the same vertex count for safety), otherwise that all attributes have the same vertex count for safety), otherwise
expect at least one attribute */ expect at least one attribute */
@ -103,10 +108,10 @@ MeshData::MeshData(const MeshPrimitive primitive, Containers::Array<char>&& inde
#endif #endif
} }
CORRADE_ASSERT(!_indices.empty() || _indexData.empty(), CORRADE_ASSERT(_indexCount || _indexData.empty(),
"Trade::MeshData: indexData passed for a non-indexed mesh", ); "Trade::MeshData: indexData passed for a non-indexed mesh", );
CORRADE_ASSERT(!_indices || (_indices.begin() >= _indexData.begin() && _indices.end() <= _indexData.end()), CORRADE_ASSERT(!_indices || (_indices >= _indexData.begin() && _indices + indices._data.size() <= _indexData.end()),
"Trade::MeshData: indices [" << Debug::nospace << static_cast<const void*>(_indices.begin()) << Debug::nospace << ":" << Debug::nospace << static_cast<const void*>(_indices.end()) << Debug::nospace << "] are not contained in passed indexData array [" << Debug::nospace << static_cast<const void*>(_indexData.begin()) << Debug::nospace << ":" << Debug::nospace << static_cast<const void*>(_indexData.end()) << Debug::nospace << "]", ); "Trade::MeshData: indices [" << Debug::nospace << static_cast<const void*>(_indices) << Debug::nospace << ":" << Debug::nospace << static_cast<const void*>(_indices + indices._data.size()) << Debug::nospace << "] are not contained in passed indexData array [" << Debug::nospace << static_cast<const void*>(_indexData.begin()) << Debug::nospace << ":" << Debug::nospace << static_cast<const void*>(_indexData.end()) << Debug::nospace << "]", );
#ifndef CORRADE_NO_ASSERT #ifndef CORRADE_NO_ASSERT
/* Not checking what's already checked in MeshIndexData / MeshAttributeData /* Not checking what's already checked in MeshIndexData / MeshAttributeData
@ -209,7 +214,7 @@ Containers::ArrayView<char> MeshData::mutableVertexData() & {
UnsignedInt MeshData::indexCount() const { UnsignedInt MeshData::indexCount() const {
CORRADE_ASSERT(isIndexed(), CORRADE_ASSERT(isIndexed(),
"Trade::MeshData::indexCount(): the mesh is not indexed", {}); "Trade::MeshData::indexCount(): the mesh is not indexed", {});
return _indices.size()/meshIndexTypeSize(_indexType); return _indexCount;
} }
MeshIndexType MeshData::indexType() const { MeshIndexType MeshData::indexType() const {
@ -221,7 +226,7 @@ MeshIndexType MeshData::indexType() const {
std::size_t MeshData::indexOffset() const { std::size_t MeshData::indexOffset() const {
CORRADE_ASSERT(isIndexed(), CORRADE_ASSERT(isIndexed(),
"Trade::MeshData::indexOffset(): the mesh is not indexed", {}); "Trade::MeshData::indexOffset(): the mesh is not indexed", {});
return _indices.data() - _indexData.data(); return _indices - _indexData.data();
} }
Containers::StridedArrayView2D<const char> MeshData::indices() const { Containers::StridedArrayView2D<const char> MeshData::indices() const {
@ -229,7 +234,7 @@ Containers::StridedArrayView2D<const char> MeshData::indices() const {
"Trade::MeshData::indices(): the mesh is not indexed", {}); "Trade::MeshData::indices(): the mesh is not indexed", {});
const std::size_t indexTypeSize = meshIndexTypeSize(_indexType); const std::size_t indexTypeSize = meshIndexTypeSize(_indexType);
/* Build a 2D view using information about attribute type size */ /* Build a 2D view using information about attribute type size */
return {_indices, {_indices.size()/indexTypeSize, indexTypeSize}}; return {{_indices, _indexCount*indexTypeSize}, {_indexCount, indexTypeSize}};
} }
Containers::StridedArrayView2D<char> MeshData::mutableIndices() { Containers::StridedArrayView2D<char> MeshData::mutableIndices() {
@ -239,7 +244,7 @@ Containers::StridedArrayView2D<char> MeshData::mutableIndices() {
"Trade::MeshData::mutableIndices(): the mesh is not indexed", {}); "Trade::MeshData::mutableIndices(): the mesh is not indexed", {});
const std::size_t indexTypeSize = meshIndexTypeSize(_indexType); const std::size_t indexTypeSize = meshIndexTypeSize(_indexType);
/* Build a 2D view using information about attribute type size */ /* Build a 2D view using information about attribute type size */
Containers::StridedArrayView2D<const char> out{_indices, {_indices.size()/indexTypeSize, indexTypeSize}}; Containers::StridedArrayView2D<const char> out{{_indices, _indexCount*indexTypeSize}, {_indexCount, indexTypeSize}};
/** @todo some arrayConstCast? UGH */ /** @todo some arrayConstCast? UGH */
return Containers::StridedArrayView2D<char>{ return Containers::StridedArrayView2D<char>{
/* The view size is there only for a size assert, we're pretty sure the /* The view size is there only for a size assert, we're pretty sure the
@ -401,11 +406,11 @@ void MeshData::indicesInto(const Containers::StridedArrayView1D<UnsignedInt> des
auto destination1ui = Containers::arrayCast<2, UnsignedInt>(destination); auto destination1ui = Containers::arrayCast<2, UnsignedInt>(destination);
if(_indexType == MeshIndexType::UnsignedInt) if(_indexType == MeshIndexType::UnsignedInt)
return Utility::copy(Containers::arrayCast<const UnsignedInt>(_indices), destination); return Utility::copy(Containers::arrayView(reinterpret_cast<const UnsignedInt*>(_indices), _indexCount), destination);
else if(_indexType == MeshIndexType::UnsignedShort) else if(_indexType == MeshIndexType::UnsignedShort)
return Math::castInto(Containers::arrayCast<2, const UnsignedShort>(Containers::arrayCast<const UnsignedShort>(_indices)), destination1ui); return Math::castInto(Containers::arrayCast<2, const UnsignedShort>(Containers::arrayView(reinterpret_cast<const UnsignedShort*>(_indices), _indexCount)), destination1ui);
else if(_indexType == MeshIndexType::UnsignedByte) else if(_indexType == MeshIndexType::UnsignedByte)
return Math::castInto(Containers::arrayCast<2, const UnsignedByte>(Containers::arrayCast<const UnsignedByte>(_indices)), destination1ui); return Math::castInto(Containers::arrayCast<2, const UnsignedByte>(Containers::arrayView(reinterpret_cast<const UnsignedByte*>(_indices), _indexCount)), destination1ui);
else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */ else CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
@ -773,7 +778,7 @@ Containers::Array<UnsignedInt> MeshData::objectIdsAsArray(const UnsignedInt id)
} }
Containers::Array<char> MeshData::releaseIndexData() { Containers::Array<char> MeshData::releaseIndexData() {
_indices = {_indices.data(), 0}; _indexCount = 0;
Containers::Array<char> out = std::move(_indexData); Containers::Array<char> out = std::move(_indexData);
_indexData = Containers::Array<char>{out.data(), 0, Implementation::nonOwnedArrayDeleter}; _indexData = Containers::Array<char>{out.data(), 0, Implementation::nonOwnedArrayDeleter};
return out; return out;

9
src/Magnum/Trade/MeshData.h

@ -1789,15 +1789,14 @@ class MAGNUM_TRADE_EXPORT MeshData {
/* GPUs don't currently support more than 32-bit index types / vertex /* GPUs don't currently support more than 32-bit index types / vertex
counts so this should be enough. Sanity check: counts so this should be enough. Sanity check:
https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkIndexType.html */ https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkIndexType.html */
UnsignedInt _vertexCount; UnsignedInt _indexCount, _vertexCount;
MeshIndexType _indexType;
MeshPrimitive _primitive; MeshPrimitive _primitive;
MeshIndexType _indexType;
DataFlags _indexDataFlags, _vertexDataFlags; DataFlags _indexDataFlags, _vertexDataFlags;
const void* _importerState; const void* _importerState;
Containers::Array<char> _indexData, _vertexData; const char* _indices;
Containers::Array<MeshAttributeData> _attributes; Containers::Array<MeshAttributeData> _attributes;
/* MeshIndexData are "unpacked" in order to avoid excessive padding */ Containers::Array<char> _indexData, _vertexData;
Containers::ArrayView<const char> _indices;
}; };
#if !defined(CORRADE_NO_ASSERT) || defined(CORRADE_GRACEFUL_ASSERT) #if !defined(CORRADE_NO_ASSERT) || defined(CORRADE_GRACEFUL_ASSERT)

Loading…
Cancel
Save