mirror of https://github.com/AxioDL/metaforce.git
Move Vertex/Uniform buffer pools to hecl
This commit is contained in:
parent
e9dc6787ce
commit
9162db2dcf
|
@ -60,9 +60,7 @@ list(APPEND SPECTER_HEADERS
|
|||
include/specter/FileBrowser.hpp
|
||||
include/specter/Icon.hpp
|
||||
include/specter/FontCache.hpp
|
||||
include/specter/Translator.hpp
|
||||
include/specter/UniformBufferPool.hpp
|
||||
include/specter/VertexBufferPool.hpp)
|
||||
include/specter/Translator.hpp)
|
||||
|
||||
atdna(atdna_FontCache.cpp include/specter/FontCache.hpp)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ private:
|
|||
zeus::CColor m_line2Clear;
|
||||
|
||||
ViewBlock m_viewBlock;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
|
||||
union
|
||||
{
|
||||
struct
|
||||
|
|
|
@ -56,7 +56,7 @@ class RootView : public View
|
|||
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
ViewBlock m_viewBlock;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
SolidShaderVert m_verts[32];
|
||||
void setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir);
|
||||
void setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis);
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
|
||||
ViewChild<View*> m_views[2];
|
||||
ViewBlock m_splitBlock;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
|
||||
TexShaderVert m_splitVerts[4];
|
||||
|
||||
int m_clearanceA, m_clearanceB;
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
private:
|
||||
size_t m_capacity;
|
||||
std::experimental::optional<VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
|
||||
std::experimental::optional<hecl::VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
|
||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||
boo::IShaderDataBinding* m_shaderBinding;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
friend class TextView;
|
||||
friend class MultiLineTextView;
|
||||
|
||||
VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||
hecl::VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@ private:
|
|||
std::vector<std::vector<ViewChild<View*>>> m_children;
|
||||
|
||||
ViewBlock m_tbBlock;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
|
||||
TexShaderVert m_tbVerts[10];
|
||||
int m_nomGauge = 25;
|
||||
int m_padding = 10;
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace specter
|
|||
class Tooltip : public View
|
||||
{
|
||||
ViewBlock m_ttBlock;
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
|
||||
SolidShaderVert m_ttVerts[16];
|
||||
int m_nomWidth = 25;
|
||||
int m_nomHeight = 25;
|
||||
|
|
|
@ -1,186 +0,0 @@
|
|||
#ifndef SPECTER_UNIFORMBUFFERPOOL_HPP
|
||||
#define SPECTER_UNIFORMBUFFERPOOL_HPP
|
||||
|
||||
#include <boo/boo.hpp>
|
||||
#include <hecl/BitVector.hpp>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
|
||||
#define SPECTER_UBUFPOOL_ALLOCATION_BLOCK 262144
|
||||
|
||||
/** This class provides a uniform structure for packing instanced uniform-buffer
|
||||
* data with consistent stride into a vector of 256K 'Buckets'.
|
||||
*
|
||||
* This results in a space-efficient way of managing GPU data of things like UI
|
||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
||||
* allocating a full GPU buffer object for each. */
|
||||
template <typename UniformStruct>
|
||||
class UniformBufferPool
|
||||
{
|
||||
/* Resolve div_t type using ssize_t as basis */
|
||||
#if _WIN32
|
||||
using IndexTp = SSIZE_T;
|
||||
#else
|
||||
using IndexTp = ssize_t;
|
||||
#endif
|
||||
struct InvalidTp {};
|
||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
||||
|
||||
/** Size of single element, rounded up to 256-multiple */
|
||||
static constexpr IndexTp m_stride = ROUND_UP_256(sizeof(UniformStruct));
|
||||
static_assert(m_stride <= SPECTER_UBUFPOOL_ALLOCATION_BLOCK, "Stride too large for uniform pool");
|
||||
|
||||
/** Number of rounded elements per 256K bucket */
|
||||
static constexpr IndexTp m_countPerBucket = SPECTER_UBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
||||
|
||||
/** Buffer size per bucket (ideally 256K) */
|
||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
||||
|
||||
/** BitVector indicating free allocation blocks */
|
||||
hecl::llvm::BitVector m_freeBlocks;
|
||||
|
||||
/** Efficient way to get bucket and block simultaneously */
|
||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
||||
|
||||
/** Buffer pool token */
|
||||
boo::GraphicsBufferPoolToken m_token;
|
||||
|
||||
/** Private bucket info */
|
||||
struct Bucket
|
||||
{
|
||||
boo::IGraphicsBufferD* buffer;
|
||||
uint8_t* cpuBuffer = nullptr;
|
||||
size_t useCount = 0;
|
||||
bool dirty = false;
|
||||
Bucket() = default;
|
||||
Bucket(const Bucket& other) = delete;
|
||||
Bucket& operator=(const Bucket& other) = delete;
|
||||
Bucket(Bucket&& other) = default;
|
||||
Bucket& operator=(Bucket&& other) = default;
|
||||
|
||||
void updateBuffer()
|
||||
{
|
||||
if (buffer)
|
||||
buffer->unmap();
|
||||
cpuBuffer = nullptr;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void increment(UniformBufferPool& pool)
|
||||
{
|
||||
if (!useCount)
|
||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Uniform,
|
||||
pool.m_stride, pool.m_countPerBucket);
|
||||
++useCount;
|
||||
}
|
||||
|
||||
void decrement(UniformBufferPool& pool)
|
||||
{
|
||||
--useCount;
|
||||
if (!useCount)
|
||||
{
|
||||
pool.m_token.deletePoolBuffer(buffer);
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
std::vector<Bucket> m_buckets;
|
||||
|
||||
public:
|
||||
/** User block-owning token */
|
||||
class Token
|
||||
{
|
||||
friend class UniformBufferPool;
|
||||
UniformBufferPool& m_pool;
|
||||
IndexTp m_index;
|
||||
DivTp m_div;
|
||||
Token(UniformBufferPool& pool)
|
||||
: m_pool(pool)
|
||||
{
|
||||
auto& freeSpaces = pool.m_freeBlocks;
|
||||
auto& buckets = pool.m_buckets;
|
||||
int idx = freeSpaces.find_first();
|
||||
if (idx == -1)
|
||||
{
|
||||
buckets.emplace_back();
|
||||
m_index = freeSpaces.size();
|
||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index = idx;
|
||||
}
|
||||
freeSpaces.reset(m_index);
|
||||
m_div = pool.getBucketDiv(m_index);
|
||||
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.increment(m_pool);
|
||||
}
|
||||
|
||||
public:
|
||||
Token(const Token& other) = delete;
|
||||
Token& operator=(const Token& other) = delete;
|
||||
Token& operator=(Token&& other) = delete;
|
||||
Token(Token&& other)
|
||||
: m_pool(other.m_pool), m_index(other.m_index),
|
||||
m_div(other.m_div)
|
||||
{
|
||||
other.m_index = -1;
|
||||
}
|
||||
|
||||
~Token()
|
||||
{
|
||||
if (m_index != -1)
|
||||
{
|
||||
m_pool.m_freeBlocks.set(m_index);
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.decrement(m_pool);
|
||||
}
|
||||
}
|
||||
|
||||
UniformStruct& access()
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
if (!bucket.cpuBuffer)
|
||||
bucket.cpuBuffer = reinterpret_cast<uint8_t*>(bucket.buffer->map(m_sizePerBucket));
|
||||
bucket.dirty = true;
|
||||
return reinterpret_cast<UniformStruct&>(bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
||||
}
|
||||
|
||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
return {bucket.buffer, m_div.rem * m_pool.m_stride};
|
||||
}
|
||||
};
|
||||
|
||||
UniformBufferPool() = default;
|
||||
UniformBufferPool(const UniformBufferPool& other) = delete;
|
||||
UniformBufferPool& operator=(const UniformBufferPool& other) = delete;
|
||||
|
||||
/** Load dirty buffer data into GPU */
|
||||
void updateBuffers()
|
||||
{
|
||||
for (Bucket& bucket : m_buckets)
|
||||
if (bucket.dirty)
|
||||
bucket.updateBuffer();
|
||||
}
|
||||
|
||||
/** Allocate free block into client-owned Token */
|
||||
Token allocateBlock(boo::IGraphicsDataFactory* factory)
|
||||
{
|
||||
if (!m_token)
|
||||
m_token = factory->newBufferPool();
|
||||
return Token(*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_UNIFORMBUFFERPOOL_HPP
|
|
@ -1,189 +0,0 @@
|
|||
#ifndef SPECTER_VERTEXBUFFERPOOL_HPP
|
||||
#define SPECTER_VERTEXBUFFERPOOL_HPP
|
||||
|
||||
#include <boo/boo.hpp>
|
||||
#include <hecl/BitVector.hpp>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
|
||||
#define SPECTER_VBUFPOOL_ALLOCATION_BLOCK 262144
|
||||
|
||||
/** This class provides a uniform structure for packing instanced vertex-buffer
|
||||
* data with consistent stride into a vector of 256K 'Buckets'.
|
||||
*
|
||||
* This results in a space-efficient way of managing GPU data of things like UI
|
||||
* widgets. These can potentially have numerous binding instances, so this avoids
|
||||
* allocating a full GPU buffer object for each. */
|
||||
template <typename VertStruct>
|
||||
class VertexBufferPool
|
||||
{
|
||||
/* Resolve div_t type using ssize_t as basis */
|
||||
#if _WIN32
|
||||
using IndexTp = SSIZE_T;
|
||||
#else
|
||||
using IndexTp = ssize_t;
|
||||
#endif
|
||||
struct InvalidTp {};
|
||||
using DivTp = std::conditional_t<std::is_same<IndexTp, long long>::value, std::lldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, long>::value, std::ldiv_t,
|
||||
std::conditional_t<std::is_same<IndexTp, int>::value, std::div_t, InvalidTp>>>;
|
||||
static_assert(!std::is_same<DivTp, InvalidTp>::value, "unsupported IndexTp for DivTp resolution");
|
||||
|
||||
/** Size of single element */
|
||||
static constexpr IndexTp m_stride = sizeof(VertStruct);
|
||||
static_assert(m_stride <= SPECTER_VBUFPOOL_ALLOCATION_BLOCK, "Stride too large for vertex pool");
|
||||
|
||||
/** Number of elements per 256K bucket */
|
||||
static constexpr IndexTp m_countPerBucket = SPECTER_VBUFPOOL_ALLOCATION_BLOCK / m_stride;
|
||||
|
||||
/** Buffer size per bucket (ideally 256K) */
|
||||
static constexpr IndexTp m_sizePerBucket = m_stride * m_countPerBucket;
|
||||
|
||||
/** BitVector indicating free allocation elements */
|
||||
hecl::llvm::BitVector m_freeElements;
|
||||
|
||||
/** Efficient way to get bucket and element simultaneously */
|
||||
DivTp getBucketDiv(IndexTp idx) const { return std::div(idx, m_countPerBucket); }
|
||||
|
||||
/** Buffer pool token */
|
||||
boo::GraphicsBufferPoolToken m_token;
|
||||
|
||||
/** Private bucket info */
|
||||
struct Bucket
|
||||
{
|
||||
boo::IGraphicsBufferD* buffer;
|
||||
uint8_t* cpuBuffer = nullptr;
|
||||
size_t useCount = 0;
|
||||
bool dirty = false;
|
||||
Bucket() = default;
|
||||
Bucket(const Bucket& other) = delete;
|
||||
Bucket& operator=(const Bucket& other) = delete;
|
||||
Bucket(Bucket&& other) = default;
|
||||
Bucket& operator=(Bucket&& other) = default;
|
||||
|
||||
void updateBuffer()
|
||||
{
|
||||
if (buffer)
|
||||
buffer->unmap();
|
||||
cpuBuffer = nullptr;
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
void increment(VertexBufferPool& pool)
|
||||
{
|
||||
if (!useCount)
|
||||
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Vertex,
|
||||
pool.m_stride, pool.m_countPerBucket);
|
||||
++useCount;
|
||||
}
|
||||
|
||||
void decrement(VertexBufferPool& pool)
|
||||
{
|
||||
--useCount;
|
||||
if (!useCount)
|
||||
{
|
||||
pool.m_token.deletePoolBuffer(buffer);
|
||||
buffer = nullptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
std::vector<Bucket> m_buckets;
|
||||
|
||||
public:
|
||||
/** User element-owning token */
|
||||
class Token
|
||||
{
|
||||
friend class VertexBufferPool;
|
||||
VertexBufferPool& m_pool;
|
||||
IndexTp m_index;
|
||||
IndexTp m_count;
|
||||
DivTp m_div;
|
||||
Token(VertexBufferPool& pool, IndexTp count)
|
||||
: m_pool(pool), m_count(count)
|
||||
{
|
||||
assert(count <= pool.m_countPerBucket && "unable to fit in bucket");
|
||||
auto& freeSpaces = pool.m_freeElements;
|
||||
auto& buckets = pool.m_buckets;
|
||||
int idx = freeSpaces.find_first_contiguous(count, pool.m_countPerBucket);
|
||||
if (idx == -1)
|
||||
{
|
||||
buckets.emplace_back();
|
||||
m_index = freeSpaces.size();
|
||||
freeSpaces.resize(freeSpaces.size() + pool.m_countPerBucket, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_index = idx;
|
||||
}
|
||||
freeSpaces.reset(m_index, m_index + count);
|
||||
m_div = pool.getBucketDiv(m_index);
|
||||
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.increment(pool);
|
||||
}
|
||||
public:
|
||||
Token(const Token& other) = delete;
|
||||
Token& operator=(const Token& other) = delete;
|
||||
Token& operator=(Token&& other) = delete;
|
||||
Token(Token&& other)
|
||||
: m_pool(other.m_pool), m_index(other.m_index),
|
||||
m_count(other.m_count), m_div(other.m_div)
|
||||
{
|
||||
other.m_index = -1;
|
||||
}
|
||||
|
||||
~Token()
|
||||
{
|
||||
if (m_index != -1)
|
||||
{
|
||||
m_pool.m_freeElements.set(m_index, m_index + m_count);
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
bucket.decrement(m_pool);
|
||||
}
|
||||
}
|
||||
|
||||
VertStruct* access()
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
if (!bucket.cpuBuffer)
|
||||
bucket.cpuBuffer = reinterpret_cast<uint8_t*>(bucket.buffer->map(m_sizePerBucket));
|
||||
bucket.dirty = true;
|
||||
return reinterpret_cast<VertStruct*>(&bucket.cpuBuffer[m_div.rem * m_pool.m_stride]);
|
||||
}
|
||||
|
||||
std::pair<boo::IGraphicsBufferD*, IndexTp> getBufferInfo() const
|
||||
{
|
||||
Bucket& bucket = m_pool.m_buckets[m_div.quot];
|
||||
return {bucket.buffer, m_div.rem};
|
||||
}
|
||||
};
|
||||
|
||||
VertexBufferPool() = default;
|
||||
VertexBufferPool(const VertexBufferPool& other) = delete;
|
||||
VertexBufferPool& operator=(const VertexBufferPool& other) = delete;
|
||||
|
||||
/** Load dirty buffer data into GPU */
|
||||
void updateBuffers()
|
||||
{
|
||||
for (Bucket& bucket : m_buckets)
|
||||
if (bucket.dirty)
|
||||
bucket.updateBuffer();
|
||||
}
|
||||
|
||||
/** Allocate free block into client-owned Token */
|
||||
Token allocateBlock(boo::IGraphicsDataFactory* factory, IndexTp count)
|
||||
{
|
||||
if (!m_token)
|
||||
m_token = factory->newBufferPool();
|
||||
return Token(*this, count);
|
||||
}
|
||||
|
||||
static constexpr IndexTp bucketCapacity() { return m_countPerBucket; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_VERTEXBUFFERPOOL_HPP
|
|
@ -8,8 +8,8 @@
|
|||
#include "zeus/CTransform.hpp"
|
||||
#include "zeus/CColor.hpp"
|
||||
#include "hecl/CVar.hpp"
|
||||
#include "UniformBufferPool.hpp"
|
||||
#include "VertexBufferPool.hpp"
|
||||
#include "hecl/UniformBufferPool.hpp"
|
||||
#include "hecl/VertexBufferPool.hpp"
|
||||
|
||||
#include <boo/graphicsdev/GL.hpp>
|
||||
#include <boo/graphicsdev/D3D.hpp>
|
||||
|
@ -110,7 +110,7 @@ public:
|
|||
template <typename VertStruct>
|
||||
struct VertexBufferBinding
|
||||
{
|
||||
std::experimental::optional<typename VertexBufferPool<VertStruct>::Token> m_vertsBuf;
|
||||
std::experimental::optional<typename hecl::VertexBufferPool<VertStruct>::Token> m_vertsBuf;
|
||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||
boo::IShaderDataBinding* m_shaderBinding = nullptr;
|
||||
|
||||
|
@ -143,13 +143,13 @@ public:
|
|||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||
};
|
||||
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
boo::ITexture* texture);
|
||||
};
|
||||
|
||||
|
@ -184,14 +184,14 @@ protected:
|
|||
" float4x4 mv;\n"\
|
||||
" float4 mulColor;\n"\
|
||||
"};\n"
|
||||
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
std::experimental::optional<hecl::UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
|
||||
|
||||
public:
|
||||
struct Resources
|
||||
{
|
||||
UniformBufferPool<ViewBlock> m_bufPool;
|
||||
VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||
VertexBufferPool<TexShaderVert> m_texPool;
|
||||
hecl::UniformBufferPool<ViewBlock> m_bufPool;
|
||||
hecl::VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||
hecl::VertexBufferPool<TexShaderVert> m_texPool;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
|
|
|
@ -365,9 +365,9 @@ TextView::TextView(ViewResources& res,
|
|||
m_fontAtlas(font),
|
||||
m_align(align)
|
||||
{
|
||||
if (size_t(VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
||||
if (size_t(hecl::VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
||||
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
|
||||
capacity, VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||
capacity, hecl::VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||
|
||||
_commitResources(0);
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ int TextView::DoKern(FT_Pos val, const FontAtlas& atlas)
|
|||
void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& defaultColor)
|
||||
{
|
||||
UTF8Iterator it(str.begin());
|
||||
size_t charLen = str.size() ? std::min(it.countTo(str.end()), size_t(1024)) : 0;
|
||||
size_t charLen = str.size() ? std::min(it.countTo(str.end()), m_capacity) : 0;
|
||||
_commitResources(charLen);
|
||||
|
||||
uint32_t lCh = -1;
|
||||
|
@ -477,13 +477,14 @@ void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& default
|
|||
|
||||
void TextView::typesetGlyphs(const std::wstring& str, const zeus::CColor& defaultColor)
|
||||
{
|
||||
_commitResources(str.size());
|
||||
size_t charLen = std::min(str.size(), m_capacity);
|
||||
_commitResources(charLen);
|
||||
|
||||
uint32_t lCh = -1;
|
||||
m_glyphs.clear();
|
||||
m_glyphs.reserve(str.size());
|
||||
m_glyphs.reserve(charLen);
|
||||
m_glyphInfo.clear();
|
||||
m_glyphInfo.reserve(str.size());
|
||||
m_glyphInfo.reserve(charLen);
|
||||
int adv = 0;
|
||||
|
||||
for (wchar_t ch : str)
|
||||
|
|
|
@ -387,7 +387,7 @@ void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& com
|
|||
|
||||
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
||||
{
|
||||
m_vertsBuf.emplace(res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count));
|
||||
auto vBufInfo = m_vertsBuf->getBufferInfo();
|
||||
|
@ -422,7 +422,7 @@ void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ct
|
|||
|
||||
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
boo::ITexture* texture)
|
||||
{
|
||||
m_vertsBuf.emplace(res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count));
|
||||
|
|
Loading…
Reference in New Issue