Uniform and Vertex buffer pool refactor

This commit is contained in:
Jack Andersen 2016-12-09 16:33:54 -10:00
parent 474ef07953
commit a9322292f5
33 changed files with 614 additions and 205 deletions

View File

@ -60,7 +60,9 @@ list(APPEND SPECTER_HEADERS
include/specter/FileBrowser.hpp
include/specter/Icon.hpp
include/specter/FontCache.hpp
include/specter/Translator.hpp)
include/specter/Translator.hpp
include/specter/UniformBufferPool.hpp
include/specter/VertexBufferPool.hpp)
atdna(atdna_FontCache.cpp include/specter/FontCache.hpp)

View File

@ -27,7 +27,12 @@ private:
std::unique_ptr<IconView> m_icon;
SolidShaderVert m_verts[40];
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
void _loadVerts()
{
m_vertsBinding.load<decltype(m_verts)>(m_verts);
}
RectangleConstraint m_constraint;
int m_nomWidth, m_nomHeight;
@ -117,7 +122,7 @@ public:
View::setMultiplyColor(color);
m_viewVertBlock.m_color = color;
if (m_viewVertBlockBuf)
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
m_viewVertBlockBuf->access() = m_viewVertBlock;
m_text->setMultiplyColor(color);
if (m_icon)
m_icon->setMultiplyColor(color);

View File

@ -55,7 +55,7 @@ public:
class IconView : public View
{
VertexBufferBinding m_vertexBinding;
VertexBufferBindingTex m_vertexBinding;
public:
IconView(ViewResources& res, View& parentView, Icon& icon);
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);

View File

@ -19,7 +19,7 @@ class Menu : public View
int m_cWidth, m_cHeight, m_cTop;
SolidShaderVert m_verts[8];
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
void setVerts(int width, int height, float pf);
struct ContentView : View
@ -29,7 +29,7 @@ class Menu : public View
boo::SWindowRect m_scissorRect;
SolidShaderVert m_hlVerts[4];
VertexBufferBinding m_hlVertsBinding;
VertexBufferBindingSolid m_hlVertsBinding;
size_t m_highlightedItem = -1;
void setHighlightedItem(size_t idx);

View File

@ -36,12 +36,16 @@ private:
zeus::CColor m_line2Clear;
ViewBlock m_viewBlock;
boo::IGraphicsBufferD* m_viewBlockBuf;
struct
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewBlockBuf;
union
{
SolidShaderVert lineVerts[22];
SolidShaderVert fillVerts[16];
} m_verts;
struct
{
SolidShaderVert lineVerts[22];
SolidShaderVert fillVerts[16];
} m_verts;
SolidShaderVert _m_verts[38];
};
void setLineVerts(int width, int height, float pf, float t);
void setLineVertsOut(int width, int height, float pf, float t);
@ -50,7 +54,11 @@ private:
void setFillVerts(int width, int height, float pf);
void setFillColors(float t);
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
void _loadVerts()
{
m_vertsBinding.load<decltype(_m_verts)>(_m_verts);
}
boo::GraphicsDataToken m_windowGfxData;

View File

@ -54,9 +54,9 @@ class RootView : public View
float m_interactiveSplit = 0.5;
bool m_interactiveDown = false;
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
ViewBlock m_viewBlock;
boo::IGraphicsBufferD* m_viewVertBlockBuf;
std::experimental::optional<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);

View File

@ -32,7 +32,7 @@ private:
bool m_drawSideButtons = false;
SolidShaderVert m_verts[4];
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
enum class SideButtonState
{

View File

@ -37,7 +37,7 @@ class Space : public View
struct CornerView : View
{
Space& m_space;
VertexBufferBinding m_vertexBinding;
VertexBufferBindingSolid m_vertexBinding;
bool m_flip;
CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor);
void mouseEnter(const boo::SWindowCoord&);

View File

@ -43,7 +43,7 @@ private:
ViewChild<View*> m_views[2];
ViewBlock m_splitBlock;
boo::IGraphicsBufferD* m_splitBlockBuf;
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_splitBlockBuf;
TexShaderVert m_splitVerts[4];
int m_clearanceA, m_clearanceB;
@ -72,7 +72,7 @@ private:
m_splitVerts[3].m_uv.assign(1, 0);
}
VertexBufferBinding m_splitVertsBinding;
VertexBufferBindingTex m_splitVertsBinding;
public:
SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller,
@ -104,7 +104,7 @@ public:
{
View::setMultiplyColor(color);
m_splitBlock.m_color = color;
m_splitBlockBuf->load(&m_splitBlock, sizeof(m_splitBlock));
m_splitBlockBuf->access() = m_splitBlock;
if (m_views[0].m_view)
m_views[0].m_view->setMultiplyColor(color);

View File

@ -84,7 +84,7 @@ class Table : public View
size_t m_hDraggingIdx = 0;
std::unique_ptr<SolidShaderVert[]> m_hVerts;
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
void _setHeaderVerts(const boo::SWindowRect& rect);
std::vector<boo::SWindowRect> getCellRects(const boo::SWindowRect& tableRect) const;
@ -96,7 +96,7 @@ class Table : public View
Table& m_t;
std::unique_ptr<SolidShaderVert[]> m_verts;
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
size_t m_visibleStart = 0;
size_t m_visibleRows = 0;
boo::SWindowRect m_scissorRect;

View File

@ -19,7 +19,7 @@ class TextField : public ITextInputView
std::unique_ptr<TextView> m_errText;
SolidShaderVert m_verts[41];
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
int m_nomWidth = 0;
int m_nomHeight = 0;
@ -118,7 +118,7 @@ public:
View::setMultiplyColor(color);
m_viewVertBlock.m_color = color;
if (m_viewVertBlockBuf)
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
m_viewVertBlockBuf->access() = m_viewVertBlock;
m_text->setMultiplyColor(color);
if (m_errText)
m_errText->setMultiplyColor(color);

View File

@ -22,15 +22,33 @@ public:
Center,
Right
};
struct RenderGlyph
{
zeus::CVector3f m_pos[4];
zeus::CMatrix4f m_mv;
zeus::CVector3f m_uv[4];
zeus::CColor m_color;
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
};
struct RenderGlyphInfo
{
uint32_t m_char;
std::pair<int,int> m_dims;
int m_adv;
bool m_space = false;
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
};
private:
size_t m_capacity;
boo::IGraphicsBufferD* m_glyphBuf;
std::experimental::optional<VertexBufferPool<RenderGlyph>::Token> m_glyphBuf;
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
boo::IShaderDataBinding* m_shaderBinding;
const FontAtlas& m_fontAtlas;
Alignment m_align;
bool m_valid = false;
int m_width = 0;
friend class MultiLineTextView;
@ -42,6 +60,14 @@ public:
friend class ViewResources;
friend class TextView;
friend class MultiLineTextView;
VertexBufferPool<RenderGlyph> m_glyphPool;
void updateBuffers()
{
m_glyphPool.updateBuffers();
}
FontCache* m_fcache = nullptr;
boo::IShaderPipeline* m_regular = nullptr;
boo::IShaderPipeline* m_subpixel = nullptr;
@ -62,33 +88,14 @@ public:
TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align=Alignment::Left, size_t capacity=256);
TextView(ViewResources& res, View& parentView, FontTag font, Alignment align=Alignment::Left, size_t capacity=256);
struct RenderGlyph
{
zeus::CVector3f m_pos[4];
zeus::CMatrix4f m_mv;
zeus::CVector3f m_uv[4];
zeus::CColor m_color;
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
};
struct RenderGlyphInfo
{
uint32_t m_char;
std::pair<int,int> m_dims;
int m_adv;
bool m_space = false;
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
};
std::vector<RenderGlyph>& accessGlyphs() {return m_glyphs;}
const std::vector<RenderGlyph>& accessGlyphs() const {return m_glyphs;}
void updateGlyphs() {m_valid = false;}
void typesetGlyphs(const std::string& str,
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
void typesetGlyphs(const std::wstring& str,
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
void invalidateGlyphs();
void colorGlyphs(const zeus::CColor& newColor);
void colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5);

View File

@ -31,7 +31,7 @@ private:
std::vector<std::vector<ViewChild<View*>>> m_children;
ViewBlock m_tbBlock;
boo::IGraphicsBufferD* m_tbBlockBuf;
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_tbBlockBuf;
TexShaderVert m_tbVerts[10];
int m_nomGauge = 25;
int m_padding = 10;
@ -39,7 +39,7 @@ private:
void setHorizontalVerts(int width);
void setVerticalVerts(int height);
VertexBufferBinding m_vertsBinding;
VertexBufferBindingTex m_vertsBinding;
public:
Toolbar(ViewResources& res, View& parentView, Position toolbarPos, unsigned units);

View File

@ -10,14 +10,14 @@ namespace specter
class Tooltip : public View
{
ViewBlock m_ttBlock;
boo::IGraphicsBufferD* m_ttBlockBuf;
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_ttBlockBuf;
SolidShaderVert m_ttVerts[16];
int m_nomWidth = 25;
int m_nomHeight = 25;
void setVerts(int width, int height, float pf);
VertexBufferBinding m_vertsBinding;
VertexBufferBindingSolid m_vertsBinding;
std::string m_titleStr;
std::unique_ptr<TextView> m_title;

View File

@ -0,0 +1,155 @@
#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 64K '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 */
using IndexTp = ssize_t;
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 64K bucket */
static constexpr IndexTp m_countPerBucket = SPECTER_UBUFPOOL_ALLOCATION_BLOCK / m_stride;
/** Buffer size per bucket (ideally 64K) */
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;
std::unique_ptr<uint8_t[]> cpuBuffer;
bool dirty = false;
Bucket(const Bucket& other) = delete;
Bucket& operator=(const Bucket& other) = delete;
Bucket(Bucket&& other) = default;
Bucket& operator=(Bucket&& other) = default;
Bucket(UniformBufferPool& pool)
: cpuBuffer(new uint8_t[pool.m_sizePerBucket])
{
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Uniform, pool.m_stride, pool.m_countPerBucket);
}
void updateBuffer(UniformBufferPool& pool)
{
buffer->load(cpuBuffer.get(), pool.m_sizePerBucket);
dirty = false;
}
};
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(pool);
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);
}
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);
}
UniformStruct& access()
{
Bucket& bucket = m_pool.m_buckets[m_div.quot];
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(*this);
}
/** 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

View File

@ -0,0 +1,158 @@
#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 64K '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 */
using IndexTp = ssize_t;
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 64K bucket */
static constexpr IndexTp m_countPerBucket = SPECTER_VBUFPOOL_ALLOCATION_BLOCK / m_stride;
/** Buffer size per bucket (ideally 64K) */
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;
std::unique_ptr<uint8_t[]> cpuBuffer;
bool dirty = false;
Bucket(const Bucket& other) = delete;
Bucket& operator=(const Bucket& other) = delete;
Bucket(Bucket&& other) = default;
Bucket& operator=(Bucket&& other) = default;
Bucket(VertexBufferPool& pool)
: cpuBuffer(new uint8_t[pool.m_sizePerBucket])
{
buffer = pool.m_token.newPoolBuffer(boo::BufferUse::Vertex, pool.m_stride, pool.m_countPerBucket);
}
void updateBuffer(VertexBufferPool& pool)
{
buffer->load(cpuBuffer.get(), pool.m_sizePerBucket);
dirty = false;
}
};
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);
if (idx == -1)
{
buckets.emplace_back(pool);
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);
}
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);
}
VertStruct* access()
{
Bucket& bucket = m_pool.m_buckets[m_div.quot];
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(*this);
}
/** 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

View File

@ -2,11 +2,14 @@
#define SPECTER_VIEW_HPP
#include <boo/boo.hpp>
#include "optional.hpp"
#include "zeus/CVector3f.hpp"
#include "zeus/CMatrix4f.hpp"
#include "zeus/CTransform.hpp"
#include "zeus/CColor.hpp"
#include "hecl/CVar.hpp"
#include "UniformBufferPool.hpp"
#include "VertexBufferPool.hpp"
#include <boo/graphicsdev/GL.hpp>
#include <boo/graphicsdev/D3D.hpp>
@ -104,28 +107,57 @@ public:
}
};
template <typename VertStruct>
struct VertexBufferBinding
{
boo::IGraphicsBufferD* m_vertsBuf = nullptr;
std::experimental::optional<typename VertexBufferPool<VertStruct>::Token> m_vertsBuf;
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
boo::IShaderDataBinding* m_shaderBinding = nullptr;
void initSolid(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
boo::IGraphicsBuffer* viewBlockBuf);
void initTex(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
boo::IGraphicsBuffer* viewBlockBuf,
boo::ITexture* texture);
void load(const VertStruct* data, size_t count)
{
if (m_vertsBuf)
{
VertStruct* out = m_vertsBuf->access();
for (size_t i=0; i<count; ++i)
out[i] = data[i];
}
}
template <typename VertArray>
void load(const VertArray data)
{
static_assert(std::is_same<std::remove_all_extents_t<VertArray>,
VertStruct>::value, "mismatched type");
if (m_vertsBuf)
{
constexpr size_t count = sizeof(VertArray) / sizeof(VertStruct);
VertStruct* out = m_vertsBuf->access();
for (size_t i=0; i<count; ++i)
out[i] = data[i];
}
}
void load(const void* data, size_t sz) {if (m_vertsBuf) m_vertsBuf->load(data, sz);}
operator boo::IShaderDataBinding*() {return m_shaderBinding;}
operator boo::IShaderDataBinding*() { return m_shaderBinding; }
};
struct VertexBufferBindingSolid : VertexBufferBinding<SolidShaderVert>
{
void init(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
};
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
{
void init(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
boo::ITexture* texture);
};
private:
RootView& m_rootView;
View& m_parentView;
boo::SWindowRect m_subRect;
VertexBufferBinding m_bgVertsBinding;
VertexBufferBindingSolid m_bgVertsBinding;
SolidShaderVert m_bgRect[4];
boo::GraphicsDataToken m_gfxData;
@ -152,11 +184,22 @@ protected:
" float4x4 mv;\n"\
" float4 mulColor;\n"\
"};\n"
boo::IGraphicsBufferD* m_viewVertBlockBuf = nullptr;
std::experimental::optional<UniformBufferPool<ViewBlock>::Token> m_viewVertBlockBuf;
public:
struct Resources
{
UniformBufferPool<ViewBlock> m_bufPool;
VertexBufferPool<SolidShaderVert> m_solidPool;
VertexBufferPool<TexShaderVert> m_texPool;
void updateBuffers()
{
m_bufPool.updateBuffers();
m_solidPool.updateBuffers();
m_texPool.updateBuffers();
}
boo::IShaderPipeline* m_solidShader = nullptr;
boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */
@ -198,14 +241,14 @@ public:
{
for (int i=0 ; i<4 ; ++i)
m_bgRect[i].m_color = color;
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
}
virtual void setMultiplyColor(const zeus::CColor& color)
{
m_viewVertBlock.m_color = color;
if (m_viewVertBlockBuf)
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
m_viewVertBlockBuf->access() = m_viewVertBlock;
}
virtual int nominalWidth() const {return 0;}

View File

@ -193,6 +193,12 @@ public:
m_resData.doDestroy();
}
void updateBuffers()
{
m_viewRes.updateBuffers();
m_textRes.updateBuffers();
}
~ViewResources()
{
if (m_fcacheThread.joinable())

View File

@ -25,7 +25,7 @@ Button::Button(ViewResources& res, View& parentView,
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, 40, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, 40, *m_viewVertBlockBuf);
return true;
});
@ -59,7 +59,7 @@ Button::Button(ViewResources& res, View& parentView,
}
for (int i=28 ; i<31 ; ++i)
m_verts[i].m_color = m_textColor;
m_vertsBinding.load(m_verts, sizeof(m_verts));
_loadVerts();
if (controlBinding)
m_menuStyle = controlBinding->menuStyle(this);
@ -156,7 +156,7 @@ void Button::setText(const std::string& text, const zeus::CColor& textColor)
m_verts[37].m_pos.assign(m_textIconWidth+1, height+1, 0);
m_verts[38].m_pos.assign(m_textIconWidth+1, 1, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
_loadVerts();
}
else
{
@ -191,7 +191,7 @@ void Button::setText(const std::string& text, const zeus::CColor& textColor)
m_verts[33].m_pos.assign(arrowX + arrowLineWidth, -1*pf, 0);
m_verts[34].m_pos.assign(arrowX + arrowLineWidth, -2*pf, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
_loadVerts();
}
m_nomWidth = width;
@ -214,7 +214,7 @@ void Button::colorGlyphs(const zeus::CColor& newColor)
m_text->colorGlyphs(newColor);
for (int i=28 ; i<31 ; ++i)
m_verts[i].m_color = newColor;
m_vertsBinding.load(m_verts, sizeof(m_verts));
_loadVerts();
}
void Button::ButtonTarget::setInactive()
@ -228,13 +228,13 @@ void Button::ButtonTarget::setInactive()
m_button.m_verts[2].m_color = c1;
m_button.m_verts[3].m_color = c2;
m_button.m_verts[4].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
for (int i=0 ; i<4 ; ++i)
m_button.m_verts[i].m_color = zeus::CColor::skClear;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
m_button.m_text->colorGlyphs(m_button.m_textColor);
}
}
@ -249,7 +249,7 @@ void Button::MenuTarget::setInactive()
m_button.m_verts[32].m_color = c2;
m_button.m_verts[33].m_color = c1;
m_button.m_verts[34].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
@ -257,7 +257,7 @@ void Button::MenuTarget::setInactive()
m_button.m_verts[i].m_color = m_button.m_textColor;
for (int i=31 ; i<35 ; ++i)
m_button.m_verts[i].m_color = zeus::CColor::skClear;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
}
@ -272,13 +272,13 @@ void Button::ButtonTarget::setHover()
m_button.m_verts[2].m_color = c1;
m_button.m_verts[3].m_color = c2;
m_button.m_verts[4].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
for (int i=0 ; i<4 ; ++i)
m_button.m_verts[i].m_color = m_button.m_textColor;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
m_button.m_text->colorGlyphs(m_button.m_textColor);
}
}
@ -293,7 +293,7 @@ void Button::MenuTarget::setHover()
m_button.m_verts[32].m_color = c2;
m_button.m_verts[33].m_color = c1;
m_button.m_verts[34].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
@ -301,7 +301,7 @@ void Button::MenuTarget::setHover()
m_button.m_verts[i].m_color = m_button.m_textColor;
for (int i=31 ; i<35 ; ++i)
m_button.m_verts[i].m_color = m_button.m_textColor;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
}
@ -316,13 +316,13 @@ void Button::ButtonTarget::setPressed()
m_button.m_verts[2].m_color = c1;
m_button.m_verts[3].m_color = c2;
m_button.m_verts[4].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
for (int i=0 ; i<4 ; ++i)
m_button.m_verts[i].m_color = m_button.m_textColor;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
m_button.m_text->colorGlyphs(m_button.m_textColor);
}
}
@ -337,7 +337,7 @@ void Button::MenuTarget::setPressed()
m_button.m_verts[32].m_color = c2;
m_button.m_verts[33].m_color = c1;
m_button.m_verts[34].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
@ -345,7 +345,7 @@ void Button::MenuTarget::setPressed()
m_button.m_verts[i].m_color = m_button.m_textColor;
for (int i=31 ; i<35 ; ++i)
m_button.m_verts[i].m_color = m_button.m_textColor;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
}
@ -360,13 +360,13 @@ void Button::ButtonTarget::setDisabled()
m_button.m_verts[2].m_color = c1;
m_button.m_verts[3].m_color = c2;
m_button.m_verts[4].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
for (int i=0 ; i<4 ; ++i)
m_button.m_verts[i].m_color = zeus::CColor::skClear;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
zeus::CColor dimText = m_button.m_textColor;
dimText[3] *= 0.5;
m_button.m_text->colorGlyphs(dimText);
@ -383,7 +383,7 @@ void Button::MenuTarget::setDisabled()
m_button.m_verts[32].m_color = c2;
m_button.m_verts[33].m_color = c1;
m_button.m_verts[34].m_color = c2;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
else
{
@ -393,7 +393,7 @@ void Button::MenuTarget::setDisabled()
m_button.m_verts[i].m_color = dimText;
for (int i=31 ; i<35 ; ++i)
m_button.m_verts[i].m_color = zeus::CColor::skClear;
m_button.m_vertsBinding.load(m_button.m_verts, sizeof(m_button.m_verts));
m_button._loadVerts();
}
}

View File

@ -10,7 +10,7 @@ IconView::IconView(ViewResources& res, View& parentView, Icon& icon)
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertexBinding.initTex(ctx, res, 4, m_viewVertBlockBuf, icon.m_tex);
m_vertexBinding.init(ctx, res, 4, *m_viewVertBlockBuf, icon.m_tex);
return true;
});
TexShaderVert verts[] =
@ -20,7 +20,7 @@ IconView::IconView(ViewResources& res, View& parentView, Icon& icon)
{{1, 1, 0}, icon.m_uvCoords[2]},
{{1, 0, 0}, icon.m_uvCoords[3]},
};
m_vertexBinding.load(verts, sizeof(verts));
m_vertexBinding.load<decltype(verts)>(verts);
setBackground(zeus::CColor::skBlue);
}

View File

@ -14,7 +14,7 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode)
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, 8, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, 8, *m_viewVertBlockBuf);
return true;
});
m_headText.reset(new TextView(res, *this, res.m_mainFont));
@ -32,7 +32,7 @@ void Menu::reset(IMenuNode* rootNode)
for (int i=0 ; i<8 ; ++i)
m_verts[i].m_color = res.themeData().tooltipBackground();
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_subMenu.reset();
@ -75,7 +75,7 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode*
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, 8, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, 8, *m_viewVertBlockBuf);
return true;
});
m_headText.reset(new TextView(res, *this, res.m_mainFont));
@ -90,7 +90,7 @@ Menu::ContentView::ContentView(ViewResources& res, Menu& menu)
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_hlVertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
m_hlVertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
return true;
});
@ -124,7 +124,7 @@ void Menu::setVerts(int width, int height, float pf)
m_verts[6].m_pos.assign(width, height, 0);
m_verts[7].m_pos.assign(width, height-m_cTop+pf, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
}
void Menu::ContentView::setHighlightedItem(size_t idx)
@ -152,7 +152,7 @@ void Menu::ContentView::setHighlightedItem(size_t idx)
m_hlVerts[2].m_pos.assign(itemRect.size[0], y+itemRect.size[1], 0);
m_hlVerts[3].m_pos.assign(itemRect.size[0], y, 0);
m_hlVertsBinding.load(m_hlVerts, sizeof(m_hlVerts));
m_hlVertsBinding.load<decltype(m_hlVerts)>(m_hlVerts);
}
void Menu::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)

View File

@ -295,8 +295,8 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView,
m_windowGfxData = res.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_viewBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_vertsBinding.initSolid(ctx, res, 38, m_viewBlockBuf);
m_viewBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_vertsBinding.init(ctx, res, 38, *m_viewBlockBuf);
return true;
});
@ -317,7 +317,7 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView,
setLineColors(0.0);
setFillColors(0.0);
m_vertsBinding.load(&m_verts, sizeof(m_verts));
_loadVerts();
}
static float CubicEase(float t)
@ -372,7 +372,7 @@ void ModalWindow::think()
if (doneCount == 3)
m_phase = Phase::Showing;
if (loadVerts)
m_vertsBinding.load(&m_verts, sizeof(m_verts));
_loadVerts();
++m_frame;
break;
}
@ -407,7 +407,7 @@ void ModalWindow::think()
tt = zeus::clamp(0.f, tt, 1.f);
updateContentOpacity(tt);
}
m_vertsBinding.load(&m_verts, sizeof(m_verts));
_loadVerts();
++m_frame;
break;
}
@ -427,7 +427,7 @@ bool ModalWindow::skipBuildInAnimation()
setLineVerts(m_width, m_height, pf, 1.0);
setLineColors(2.0);
setFillColors(2.0);
m_vertsBinding.load(&m_verts, sizeof(m_verts));
_loadVerts();
m_phase = Phase::ResWait;
return true;
}
@ -453,11 +453,11 @@ void ModalWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect&
centerRect.location[1] = root.size[1] / 2 - m_height / 2.0;
View::resized(root, centerRect);
m_viewBlock.setViewRect(root, centerRect);
m_viewBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
m_viewBlockBuf->access() = m_viewBlock;
setLineVerts(m_width, m_height, pf, m_lineTime);
setFillVerts(m_width, m_height, pf);
m_vertsBinding.load(&m_verts, sizeof(m_verts));
_loadVerts();
boo::SWindowRect cornerRect = centerRect;
cornerRect.size[0] = cornerRect.size[1] = 8 * pf;

View File

@ -26,8 +26,9 @@ RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv, boo::IGraphicsDataFacto
: m_rv(rv), m_text(rv.m_viewMan.translateOr("boundary_action", "Boundary Action")),
m_splitActionNode(*this), m_joinActionNode(*this)
{
m_viewVertBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(View::ViewBlock), 1);
m_vertsBinding.initSolid(ctx, *rv.m_viewRes, 32, m_viewVertBlockBuf);
ViewResources& res = *rv.m_viewRes;
m_viewVertBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_vertsBinding.init(ctx, res, 32, *m_viewVertBlockBuf);
zeus::CColor col = {0.0,0.0,0.0,0.5};
for (int i=0 ; i<32 ; ++i)
@ -71,7 +72,7 @@ RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv, boo::IGraphicsDataFacto
m_verts[30].m_pos.assign(1.0, 1.0, 0);
m_verts[31].m_pos.assign(1.0, -1.0, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
}
RootView::SplitMenuSystem::SplitActionNode::SplitActionNode(SplitMenuSystem& smn)
@ -105,7 +106,7 @@ void RootView::SplitMenuSystem::setArrowVerts(const boo::SWindowRect& rect, Spli
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + (dir == SplitView::ArrowDir::Down ? rect.size[1] : 0)) /
float(root.size[1]) - 1.0f;
}
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
m_viewVertBlockBuf->access() = m_viewBlock;
}
void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis)
@ -129,7 +130,7 @@ void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float
m_viewBlock.m_mv[3][0] = (rect.location[0] + split * rect.size[0]) * m_viewBlock.m_mv[0][0] - 1.0f;
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + rect.size[1] / 2.0f) / float(root.size[1]) - 1.0f;
}
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
m_viewVertBlockBuf->access() = m_viewBlock;
}
void RootView::destroyed()
@ -621,6 +622,7 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
m_resizeRTDirty = false;
gfxQ->schedulePostFrameHandler([&](){m_events.m_resizeCv.notify_one();});
}
m_viewRes->updateBuffers();
gfxQ->setRenderTarget(m_renderTex);
gfxQ->setViewport(m_rootRect);
gfxQ->setScissor(m_rootRect);

View File

@ -13,7 +13,7 @@ ScrollView::ScrollView(ViewResources& res, View& parentView, Style style)
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
return true;
});
@ -277,7 +277,7 @@ void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& s
const zeus::CColor& color = rootView().themeData().scrollIndicator();
for (int i=0 ; i<4 ; ++i)
m_verts[i].m_color = color;
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
}
}
else if (m_style == Style::SideButtons && m_drawSideButtons)

View File

@ -40,7 +40,7 @@ Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CCol
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertexBinding.initSolid(ctx, res, 34, m_viewVertBlockBuf);
m_vertexBinding.init(ctx, res, 34, *m_viewVertBlockBuf);
return true;
});
float pf = res.pixelFactor();
@ -113,7 +113,7 @@ Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CCol
verts[33].m_pos.assign((TRIANGLE_DIM5 + 1) * pf, 0, 0);
verts[33].m_color = edgeColor2;
m_vertexBinding.load(verts, sizeof(verts));
m_vertexBinding.load<decltype(verts)>(verts);
}
View* Space::setContentView(View* view)

View File

@ -28,8 +28,8 @@ SplitView::SplitView(ViewResources& res, View& parentView, ISplitSpaceController
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_splitBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_splitVertsBinding.initTex(ctx, res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex);
m_splitBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_splitVertsBinding.init(ctx, res, 4, *m_splitBlockBuf, res.m_splitRes.m_shadingTex);
return true;
});
}
@ -476,8 +476,8 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
m_splitBlock.setViewRect(root, ssub);
setVerticalVerts(ssub.size[1]);
}
m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock));
m_splitVertsBinding.load(m_splitVerts, sizeof(m_splitVerts));
m_splitBlockBuf->access() = m_splitBlock;
m_splitVertsBinding.load<decltype(m_splitVerts)>(m_splitVerts);
}
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
@ -489,7 +489,6 @@ void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
m_views[1].m_view->draw(gfxQ);
gfxQ->setShaderDataBinding(m_splitVertsBinding);
gfxQ->draw(0, 4);
}
}

View File

@ -22,7 +22,7 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data,
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, maxColumns * 6, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, maxColumns * 6, *m_viewVertBlockBuf);
return true;
});
m_scroll.m_view->setContentView(&m_rowsView);
@ -36,7 +36,7 @@ Table::RowsView::RowsView(Table& t, ViewResources& res)
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, *m_viewVertBlockBuf);
return true;
});
}
@ -120,7 +120,7 @@ void Table::_setHeaderVerts(const boo::SWindowRect& sub)
}
if (c)
m_vertsBinding.load(m_hVerts.get(), sizeof(SolidShaderVert) * 6 * c);
m_vertsBinding.load(m_hVerts.get(), 6 * c);
m_headerNeedsUpdate = false;
}
@ -178,7 +178,7 @@ void Table::RowsView::_setRowVerts(const boo::SWindowRect& sub, const boo::SWind
m_visibleStart = std::max(0, startIdx);
m_visibleRows = r;
if (r * c)
m_vertsBinding.load(m_verts.get(), sizeof(SolidShaderVert) * 6 * r * c);
m_vertsBinding.load(m_verts.get(), 6 * r * c);
}
void Table::cycleSortColumn(size_t c)

View File

@ -11,14 +11,14 @@ TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBi
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_vertsBinding.initSolid(ctx, res, 41, m_viewVertBlockBuf);
m_vertsBinding.init(ctx, res, 41, *m_viewVertBlockBuf);
return true;
});
for (int i=28 ; i<32 ; ++i)
m_verts[i].m_color = res.themeData().textfieldSelection();
setInactive();
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024));
if (strBind)
@ -90,7 +90,7 @@ void TextField::_setMarkedText()
size_t defLen = UTF8Iterator(m_deferredMarkStr.cbegin()).countTo(m_deferredMarkStr.cend());
for (auto it=glyphs.begin()+repPoint ; it<glyphs.begin()+repPoint+defLen ; ++it)
it->m_color = rootView().themeData().fieldMarkedText();
m_text->updateGlyphs();
m_text->invalidateGlyphs();
m_hasMarkSet = false;
@ -131,7 +131,7 @@ void TextField::setInactive()
for (int i=5 ; i<28 ; ++i)
m_verts[i].m_color = theme.textfield2Inactive();
}
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_bgState = BGState::Inactive;
}
@ -158,7 +158,7 @@ void TextField::setHover()
for (int i=5 ; i<28 ; ++i)
m_verts[i].m_color = theme.textfield2Inactive();
}
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_bgState = BGState::Hover;
}
@ -185,7 +185,7 @@ void TextField::setDisabled()
for (int i=5 ; i<28 ; ++i)
m_verts[i].m_color = theme.textfield2Disabled();
}
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_bgState = BGState::Disabled;
}
@ -605,7 +605,7 @@ void TextField::think()
}
for (size_t i=32 ; i<41 ; ++i)
m_verts[i].m_color = errBg;
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_errText->setMultiplyColor(errMult);
}
@ -648,7 +648,7 @@ void TextField::_reallySetCursorPos(size_t pos)
m_verts[30].m_color = selColor;
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
m_verts[31].m_color = selColor;
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
rootView().window()->claimKeyboardFocus(focusRect);
@ -723,13 +723,13 @@ void TextField::_reallySetSelectionRange(size_t start, size_t len)
else
glyphs[i].m_color = deselColor;
}
m_text->updateGlyphs();
m_text->invalidateGlyphs();
m_verts[28].m_pos.assign(offset1, 18 * pf, 0);
m_verts[29].m_pos.assign(offset1, 4 * pf, 0);
m_verts[30].m_pos.assign(offset2, 18 * pf, 0);
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
rootView().window()->claimKeyboardFocus(focusRect);
@ -754,7 +754,7 @@ void TextField::_reallySetMarkRange(size_t start, size_t len)
m_verts[30].m_color = selColor;
m_verts[31].m_pos.assign(offset2, 4 * pf, 0);
m_verts[31].m_color = selColor;
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]};
rootView().window()->claimKeyboardFocus(focusRect);
@ -803,7 +803,7 @@ void TextField::_clearSelectionRange()
std::vector<TextView::RenderGlyph>& glyphs = m_text->accessGlyphs();
for (size_t i=0 ; i<glyphs.size() ; ++i)
glyphs[i].m_color = deselColor;
m_text->updateGlyphs();
m_text->invalidateGlyphs();
m_hasSelectionClear = false;
}
@ -884,7 +884,7 @@ void TextField::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
m_verts[i].m_color = zeus::CColor::skClear;
}
m_vertsBinding.load(m_verts, sizeof(m_verts));
m_vertsBinding.load<decltype(m_verts)>(m_verts);
m_nomWidth = width;
m_nomHeight = height;

View File

@ -304,13 +304,16 @@ TextView::TextView(ViewResources& res,
m_fontAtlas(font),
m_align(align)
{
if (VertexBufferPool<RenderGlyph>::bucketCapacity() < capacity)
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
capacity, VertexBufferPool<RenderGlyph>::bucketCapacity());
m_glyphs.reserve(capacity);
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_glyphBuf =
ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(RenderGlyph), capacity);
m_glyphBuf.emplace(res.m_textRes.m_glyphPool.allocateBlock(res.m_factory, capacity));
boo::IShaderPipeline* shader;
if (font.subpixel())
@ -318,38 +321,43 @@ TextView::TextView(ViewResources& res,
else
shader = res.m_textRes.m_regular;
auto vBufInfo = m_glyphBuf->getBufferInfo();
auto uBufInfo = m_viewVertBlockBuf->getBufferInfo();
boo::IGraphicsBuffer* uBufs[] = {uBufInfo.first};
size_t uBufOffs[] = {uBufInfo.second};
size_t uBufSizes[] = {sizeof(ViewBlock)};
boo::ITexture* texs[] = {m_fontAtlas.texture()};
if (!res.m_textRes.m_vtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
{m_glyphBuf, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 0},
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{m_glyphBuf, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
{m_glyphBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4 | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first, nullptr, boo::VertexSemantic::ModelView | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 0},
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 1},
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 2},
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
{vBufInfo.first, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
};
m_vtxFmt = ctx.newVertexFormat(13, vdescs);
boo::ITexture* texs[] = {m_fontAtlas.texture()};
m_vtxFmt = ctx.newVertexFormat(13, vdescs, 0, vBufInfo.second);
m_shaderBinding = ctx.newShaderDataBinding(shader, m_vtxFmt,
nullptr, m_glyphBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
nullptr, 1, texs);
nullptr, vBufInfo.first, nullptr, 1,
uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, 0, vBufInfo.second);
}
else
{
boo::ITexture* texs[] = {m_fontAtlas.texture()};
m_shaderBinding = ctx.newShaderDataBinding(shader, res.m_textRes.m_vtxFmt,
nullptr, m_glyphBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
nullptr, 1, texs);
nullptr, vBufInfo.first, nullptr, 1,
uBufs, nullptr, uBufOffs, uBufSizes,
1, texs, 0, vBufInfo.second);
}
return true;
});
@ -453,7 +461,7 @@ void TextView::typesetGlyphs(const std::string& str, const zeus::CColor& default
}
m_width = adv;
m_valid = false;
invalidateGlyphs();
updateSize();
}
@ -510,7 +518,7 @@ void TextView::typesetGlyphs(const std::wstring& str, const zeus::CColor& defaul
}
m_width = adv;
m_valid = false;
invalidateGlyphs();
updateSize();
}
@ -518,11 +526,21 @@ void TextView::colorGlyphs(const zeus::CColor& newColor)
{
for (RenderGlyph& glyph : m_glyphs)
glyph.m_color = newColor;
m_valid = false;
invalidateGlyphs();
}
void TextView::colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval, float fadeTime)
{
}
void TextView::invalidateGlyphs()
{
RenderGlyph* out = m_glyphBuf->access();
size_t i = 0;
for (RenderGlyph& glyph : m_glyphs)
out[i++] = glyph;
}
void TextView::think()
{
}
@ -537,11 +555,6 @@ void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
View::draw(gfxQ);
if (m_glyphs.size())
{
if (!m_valid)
{
m_glyphBuf->load(m_glyphs.data(), m_glyphs.size() * sizeof(RenderGlyph));
m_valid = true;
}
gfxQ->setShaderDataBinding(m_shaderBinding);
gfxQ->drawInstances(0, 4, m_glyphs.size());
}

View File

@ -33,8 +33,8 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos, unsigned
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_tbBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_vertsBinding.initTex(ctx, res, 10, m_tbBlockBuf, res.m_toolbarRes.m_shadingTex);
m_tbBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_vertsBinding.init(ctx, res, 10, *m_tbBlockBuf, res.m_toolbarRes.m_shadingTex);
return true;
});
setBackground(res.themeData().toolbarBackground());
@ -138,9 +138,9 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
View::resized(root, sub);
setHorizontalVerts(sub.size[0]);
m_vertsBinding.load(m_tbVerts, sizeof(m_tbVerts));
m_vertsBinding.load<decltype(m_tbVerts)>(m_tbVerts);
m_tbBlock.setViewRect(root, sub);
m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock));
m_tbBlockBuf->access() = m_tbBlock;
float gaugeUnit = rootView().viewRes().pixelFactor() * SPECTER_TOOLBAR_GAUGE;
float yOff = 0.0;

View File

@ -18,8 +18,8 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title,
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{
buildResources(ctx, res);
m_ttBlockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_vertsBinding.initSolid(ctx, res, 16, m_ttBlockBuf);
m_ttBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_vertsBinding.init(ctx, res, 16, *m_ttBlockBuf);
return true;
});
@ -75,7 +75,7 @@ void Tooltip::setVerts(int width, int height, float pf)
m_ttVerts[14].m_pos.assign(width-margin.first, margin.second, 0);
m_ttVerts[15].m_pos.assign(width-margin.first, 0, 0);
m_vertsBinding.load(m_ttVerts, sizeof(m_ttVerts));
m_vertsBinding.load<decltype(m_ttVerts)>(m_ttVerts);
}
void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
@ -84,7 +84,7 @@ void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
float pf = rootView().viewRes().pixelFactor();
setVerts(m_nomWidth, m_nomHeight, pf);
m_ttBlock.setViewRect(root, sub);
m_ttBlockBuf->load(&m_ttBlock, sizeof(ViewBlock));
m_ttBlockBuf->access() = m_ttBlock;
std::pair<int,int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);

View File

@ -322,9 +322,8 @@ void View::Resources::init(boo::VulkanDataFactory::Context& ctx, const IThemeDat
void View::buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res)
{
m_viewVertBlockBuf =
ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_bgVertsBinding.initSolid(ctx, res, 4, m_viewVertBlockBuf);
m_viewVertBlockBuf.emplace(res.m_viewRes.m_bufPool.allocateBlock(res.m_factory));
m_bgVertsBinding.init(ctx, res, 4, *m_viewVertBlockBuf);
}
View::View(ViewResources& res)
@ -349,8 +348,8 @@ void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
if (m_viewVertBlockBuf)
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
m_viewVertBlockBuf->access() = m_viewVertBlock;
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
}
void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub)
@ -361,8 +360,8 @@ void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub)
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
if (m_viewVertBlockBuf)
m_viewVertBlockBuf->load(&vb, sizeof(ViewBlock));
m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect));
m_viewVertBlockBuf->access() = vb;
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
}
void View::draw(boo::IGraphicsCommandQueue* gfxQ)
@ -381,64 +380,76 @@ void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& com
m_gfxData = res.m_factory->commitTransaction(commitFunc);
}
void View::VertexBufferBinding::initSolid(boo::IGraphicsDataFactory::Context& ctx,
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
boo::IGraphicsBuffer* viewBlockBuf)
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
{
m_vertsBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), count);
m_vertsBuf.emplace(res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count));
auto vBufInfo = m_vertsBuf->getBufferInfo();
auto uBufInfo = viewBlockBuf.getBufferInfo();
boo::IGraphicsBuffer* bufs[] = {uBufInfo.first};
size_t bufOffs[] = {uBufInfo.second};
size_t bufSizes[] = {sizeof(ViewBlock)};
if (!res.m_viewRes.m_solidVtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_vertsBuf, nullptr, boo::VertexSemantic::Position4},
{m_vertsBuf, nullptr, boo::VertexSemantic::Color}
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4},
{vBufInfo.first, nullptr, boo::VertexSemantic::Color}
};
m_vtxFmt = ctx.newVertexFormat(2, vdescs);
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second);
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader,
m_vtxFmt, m_vertsBuf, nullptr,
nullptr, 1, bufs, nullptr, 0, nullptr);
m_vtxFmt, vBufInfo.first, nullptr,
nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 0, nullptr, vBufInfo.second);
}
else
{
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader,
res.m_viewRes.m_solidVtxFmt,
m_vertsBuf, nullptr,
nullptr, 1, bufs, nullptr, 0, nullptr);
vBufInfo.first, nullptr,
nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 0, nullptr, vBufInfo.second);
}
}
void View::VertexBufferBinding::initTex(boo::IGraphicsDataFactory::Context& ctx,
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
ViewResources& res, size_t count,
boo::IGraphicsBuffer* viewBlockBuf,
const UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
boo::ITexture* texture)
{
m_vertsBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), count);
m_vertsBuf.emplace(res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count));
auto vBufInfo = m_vertsBuf->getBufferInfo();
auto uBufInfo = viewBlockBuf.getBufferInfo();
boo::IGraphicsBuffer* bufs[] = {uBufInfo.first};
size_t bufOffs[] = {uBufInfo.second};
size_t bufSizes[] = {sizeof(ViewBlock)};
boo::ITexture* tex[] = {texture};
if (!res.m_viewRes.m_texVtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_vertsBuf, nullptr, boo::VertexSemantic::Position4},
{m_vertsBuf, nullptr, boo::VertexSemantic::UV4}
{vBufInfo.first, nullptr, boo::VertexSemantic::Position4},
{vBufInfo.first, nullptr, boo::VertexSemantic::UV4}
};
m_vtxFmt = ctx.newVertexFormat(2, vdescs);
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
boo::ITexture* tex[] = {texture};
m_vtxFmt = ctx.newVertexFormat(2, vdescs, vBufInfo.second);
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader,
m_vtxFmt, m_vertsBuf, nullptr,
nullptr, 1, bufs, nullptr, 1, tex);
m_vtxFmt, vBufInfo.first, nullptr,
nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 1, tex, vBufInfo.second);
}
else
{
boo::IGraphicsBuffer* bufs[] = {viewBlockBuf};
boo::ITexture* tex[] = {texture};
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader,
res.m_viewRes.m_texVtxFmt,
m_vertsBuf, nullptr,
nullptr, 1, bufs, nullptr, 1, tex);
vBufInfo.first, nullptr,
nullptr, 1, bufs, nullptr, bufOffs,
bufSizes, 1, tex, vBufInfo.second);
}
}

@ -1 +1 @@
Subproject commit 7185e13abe85233086a94258d60d89666f7d3e4d
Subproject commit a136d77458514201b8593824dca33289b0c9b69e