From 24917f2367c30f2235dc8ddbc2cc5a4238173446 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 7 Jan 2016 14:06:21 -1000 Subject: [PATCH] More conservative resource use in Table --- specter/include/Specter/Button.hpp | 4 +- specter/include/Specter/ModalWindow.hpp | 4 +- specter/include/Specter/ScrollView.hpp | 4 +- specter/include/Specter/SplitView.hpp | 5 +- specter/include/Specter/Table.hpp | 23 +- specter/include/Specter/TextField.hpp | 4 +- specter/include/Specter/Toolbar.hpp | 5 +- specter/include/Specter/Tooltip.hpp | 4 +- specter/include/Specter/View.hpp | 19 +- specter/lib/Button.cpp | 50 +--- specter/lib/ModalWindow.cpp | 38 +-- specter/lib/ScrollView.cpp | 28 +- specter/lib/SplitView.cpp | 31 +- specter/lib/Table.cpp | 375 ++++++++++++++++-------- specter/lib/TextField.cpp | 44 +-- specter/lib/Toolbar.cpp | 33 +-- specter/lib/Tooltip.cpp | 28 +- specter/lib/View.cpp | 89 ++++-- 18 files changed, 403 insertions(+), 385 deletions(-) diff --git a/specter/include/Specter/Button.hpp b/specter/include/Specter/Button.hpp index e05c419eb..eeee5cce4 100644 --- a/specter/include/Specter/Button.hpp +++ b/specter/include/Specter/Button.hpp @@ -23,9 +23,7 @@ private: std::unique_ptr m_text; SolidShaderVert m_verts[28]; - boo::IGraphicsBufferD* m_bVertsBuf = nullptr; - boo::IVertexFormat* m_bVtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_bShaderBinding = nullptr; + VertexBufferBinding m_vertsBinding; RectangleConstraint m_constraint; int m_nomWidth, m_nomHeight; diff --git a/specter/include/Specter/ModalWindow.hpp b/specter/include/Specter/ModalWindow.hpp index f28a26592..ade5d248c 100644 --- a/specter/include/Specter/ModalWindow.hpp +++ b/specter/include/Specter/ModalWindow.hpp @@ -46,9 +46,7 @@ class ModalWindow : public View void setFillVerts(int width, int height, float pf); void setFillColors(float t); - boo::IGraphicsBufferD* m_vertsBuf; - boo::IVertexFormat* m_vertsVtxFmt; /* OpenGL only */ - boo::IShaderDataBinding* m_vertsShaderBinding; + VertexBufferBinding m_vertsBinding; boo::GraphicsDataToken m_windowGfxData; diff --git a/specter/include/Specter/ScrollView.hpp b/specter/include/Specter/ScrollView.hpp index 01d4943ac..3efc75591 100644 --- a/specter/include/Specter/ScrollView.hpp +++ b/specter/include/Specter/ScrollView.hpp @@ -32,9 +32,7 @@ private: bool m_drawSideButtons = false; SolidShaderVert m_verts[4]; - boo::IGraphicsBufferD* m_vertsBuf = nullptr; - boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_shaderBinding = nullptr; + VertexBufferBinding m_vertsBinding; enum class SideButtonState { diff --git a/specter/include/Specter/SplitView.hpp b/specter/include/Specter/SplitView.hpp index 50f262ef3..377f9a9ce 100644 --- a/specter/include/Specter/SplitView.hpp +++ b/specter/include/Specter/SplitView.hpp @@ -60,9 +60,8 @@ private: m_splitVerts[3].m_uv.assign(1, 0); } - boo::IGraphicsBufferD* m_splitVertsBuf; - boo::IVertexFormat* m_splitVtxFmt; /* OpenGL only */ - boo::IShaderDataBinding* m_splitShaderBinding; + VertexBufferBinding m_splitVertsBinding; + public: SplitView(ViewResources& res, View& parentView, Axis axis, int clearanceA=-1, int clearanceB=-1); View* setContentView(int slot, View* view); diff --git a/specter/include/Specter/Table.hpp b/specter/include/Specter/Table.hpp index afcfa88d6..1c8fb4ca9 100644 --- a/specter/include/Specter/Table.hpp +++ b/specter/include/Specter/Table.hpp @@ -4,6 +4,7 @@ #include "View.hpp" #include "ScrollView.hpp" #include "TextView.hpp" +#include namespace Specter { @@ -53,11 +54,15 @@ class Table : public View std::unique_ptr m_text; size_t m_c, m_r; boo::SWindowRect m_scissorRect; - CellView(Table& t, ViewResources& res, size_t c, size_t r); + uint64_t m_textHash = 0; + CellView(Table& t, ViewResources& res); bool m_selected = false; void select(); void deselect(); + void reset(); + bool reset(size_t c); + bool reset(size_t c, size_t r); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); @@ -68,16 +73,18 @@ class Table : public View void draw(boo::IGraphicsCommandQueue* gfxQ); }; std::vector>> m_headerViews; - std::vector>>> m_cellViews; + using ColumnPool = std::array>, SPECTER_TABLE_MAX_ROWS>, 2>; + std::vector m_cellPools; + size_t m_ensuredRows = 0; + std::vector& ensureCellPools(size_t rows, size_t cols, ViewResources& res); + size_t m_activePool = -1; bool m_header = false; std::vector m_hCellRects; size_t m_hDraggingIdx = 0; std::unique_ptr m_hVerts; - boo::IGraphicsBufferD* m_hVertsBuf = nullptr; - boo::IVertexFormat* m_hVtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_hShaderBinding = nullptr; + VertexBufferBinding m_vertsBinding; void _setHeaderVerts(const boo::SWindowRect& rect); std::vector getCellRects(const boo::SWindowRect& tableRect) const; @@ -89,9 +96,7 @@ class Table : public View Table& m_t; std::unique_ptr m_verts; - boo::IGraphicsBufferD* m_vertsBuf = nullptr; - boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_shaderBinding = nullptr; + VertexBufferBinding m_vertsBinding; size_t m_visibleStart = 0; size_t m_visibleRows = 0; boo::SWindowRect m_scissorRect; @@ -111,6 +116,8 @@ class Table : public View bool m_headerNeedsUpdate = false; bool m_inSelectRow = false; + + void _updateData(); public: Table(ViewResources& res, View& parentView, ITableDataBinding* data, diff --git a/specter/include/Specter/TextField.hpp b/specter/include/Specter/TextField.hpp index b1bb04c0f..1b540a75c 100644 --- a/specter/include/Specter/TextField.hpp +++ b/specter/include/Specter/TextField.hpp @@ -19,9 +19,7 @@ class TextField : public ITextInputView std::unique_ptr m_errText; SolidShaderVert m_verts[41]; - boo::IGraphicsBufferD* m_bVertsBuf = nullptr; - boo::IVertexFormat* m_bVtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_bShaderBinding = nullptr; + VertexBufferBinding m_vertsBinding; int m_nomWidth = 0; int m_nomHeight = 0; diff --git a/specter/include/Specter/Toolbar.hpp b/specter/include/Specter/Toolbar.hpp index 7824a53ec..e912659fc 100644 --- a/specter/include/Specter/Toolbar.hpp +++ b/specter/include/Specter/Toolbar.hpp @@ -84,9 +84,8 @@ private: m_tbVerts[9].m_uv.assign(1, 0); } - boo::IGraphicsBufferD* m_tbVertsBuf; - boo::IVertexFormat* m_tbVtxFmt; /* OpenGL only */ - boo::IShaderDataBinding* m_tbShaderBinding; + VertexBufferBinding m_vertsBinding; + public: Toolbar(ViewResources& res, View& parentView, Position toolbarPos); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); diff --git a/specter/include/Specter/Tooltip.hpp b/specter/include/Specter/Tooltip.hpp index ccaefeb31..6cab426e5 100644 --- a/specter/include/Specter/Tooltip.hpp +++ b/specter/include/Specter/Tooltip.hpp @@ -17,9 +17,7 @@ class Tooltip : public View void setVerts(int width, int height, float pf); - boo::IGraphicsBufferD* m_ttVertsBuf; - boo::IVertexFormat* m_ttVtxFmt; /* OpenGL only */ - boo::IShaderDataBinding* m_ttShaderBinding; + VertexBufferBinding m_vertsBinding; std::string m_titleStr; std::unique_ptr m_title; diff --git a/specter/include/Specter/View.hpp b/specter/include/Specter/View.hpp index 9c278cd92..7d83b33b8 100644 --- a/specter/include/Specter/View.hpp +++ b/specter/include/Specter/View.hpp @@ -90,13 +90,24 @@ public: Zeus::CVector3f m_pos; Zeus::CVector2f m_uv; }; + + struct VertexBufferBinding + { + boo::IGraphicsBufferD* m_vertsBuf = nullptr; + boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */ + boo::IShaderDataBinding* m_shaderBinding = nullptr; + + void initSolid(ViewResources& res, size_t count, boo::IGraphicsBuffer* viewBlockBuf); + void initTex(ViewResources& res, size_t count, boo::IGraphicsBuffer* viewBlockBuf, boo::ITexture* texture); + + void load(const void* data, size_t sz) {m_vertsBuf->load(data, sz);} + operator boo::IShaderDataBinding*() {return m_shaderBinding;} + }; private: RootView& m_rootView; View& m_parentView; boo::SWindowRect m_subRect; - boo::IGraphicsBufferD* m_bgVertBuf; - boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */ - boo::IShaderDataBinding* m_bgShaderBinding; + VertexBufferBinding m_bgVertsBinding; SolidShaderVert m_bgRect[4]; boo::GraphicsDataToken m_gfxData; @@ -176,7 +187,7 @@ public: { for (int i=0 ; i<4 ; ++i) m_bgRect[i].m_color = color; - m_bgVertBuf->load(&m_bgRect, sizeof(SolidShaderVert) * 4); + m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect)); } virtual void setMultiplyColor(const Zeus::CColor& color) diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index 3729b7ea0..3700392a9 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -23,29 +23,7 @@ Button::Button(ViewResources& res, View& parentView, : Control(res, parentView, controlBinding), m_style(style), m_textColor(textColor), m_textStr(text), m_constraint(constraint) { - m_bVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 28); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_bVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_bVertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_bVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_bVtxFmt, m_bVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_texVtxFmt, - m_bVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, 28, m_viewVertBlockBuf); commitResources(res); if (style == Style::Block) @@ -57,13 +35,13 @@ Button::Button(ViewResources& res, View& parentView, m_verts[4].m_color = res.themeData().button2Inactive(); for (int i=5 ; i<28 ; ++i) m_verts[i].m_color = res.themeData().button2Inactive(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { for (int i=0 ; i<4 ; ++i) m_verts[i].m_color = Zeus::CColor::skClear; - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); } m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Center)); @@ -122,7 +100,7 @@ void Button::setText(const std::string& text, const Zeus::CColor& textColor) m_verts[26].m_pos.assign(width+1, 1, 0); m_verts[27].m_pos.assign(width+1, 0, 0); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { @@ -133,7 +111,7 @@ void Button::setText(const std::string& text, const Zeus::CColor& textColor) m_verts[2].m_pos.assign(width, -1*pf, 0); m_verts[3].m_pos.assign(width, -2*pf, 0); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); } m_nomWidth = width; @@ -155,13 +133,13 @@ void Button::setInactive() m_verts[2].m_color = rootView().themeData().button1Inactive(); m_verts[3].m_color = rootView().themeData().button2Inactive(); m_verts[4].m_color = rootView().themeData().button2Inactive(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { for (int i=0 ; i<4 ; ++i) m_verts[i].m_color = Zeus::CColor::skClear; - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); m_text->colorGlyphs(m_textColor); } } @@ -175,13 +153,13 @@ void Button::setHover() m_verts[2].m_color = rootView().themeData().button1Hover(); m_verts[3].m_color = rootView().themeData().button2Hover(); m_verts[4].m_color = rootView().themeData().button2Hover(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { for (int i=0 ; i<4 ; ++i) m_verts[i].m_color = m_textColor; - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); m_text->colorGlyphs(m_textColor); } } @@ -195,13 +173,13 @@ void Button::setPressed() m_verts[2].m_color = rootView().themeData().button1Press(); m_verts[3].m_color = rootView().themeData().button2Press(); m_verts[4].m_color = rootView().themeData().button2Press(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { for (int i=0 ; i<4 ; ++i) m_verts[i].m_color = m_textColor; - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); m_text->colorGlyphs(m_textColor); } } @@ -215,13 +193,13 @@ void Button::setDisabled() m_verts[2].m_color = rootView().themeData().button1Disabled(); m_verts[3].m_color = rootView().themeData().button2Disabled(); m_verts[4].m_color = rootView().themeData().button2Disabled(); - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 28); } else { for (int i=0 ; i<4 ; ++i) m_verts[i].m_color = Zeus::CColor::skClear; - m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 4); + m_vertsBinding.load(m_verts, sizeof(SolidShaderVert) * 4); Zeus::CColor dimText = m_textColor; dimText[3] *= 0.5; m_text->colorGlyphs(dimText); @@ -291,7 +269,7 @@ void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) void Button::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); - gfxQ->setShaderDataBinding(m_bShaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); if (m_style == Style::Block) gfxQ->draw(0, 28); diff --git a/specter/lib/ModalWindow.cpp b/specter/lib/ModalWindow.cpp index 5cd97f509..8eec2d370 100644 --- a/specter/lib/ModalWindow.cpp +++ b/specter/lib/ModalWindow.cpp @@ -290,29 +290,9 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView, const RectangleCo m_windowBgClear[3] = 0.0; m_line2Clear[3] = 0.0; m_viewBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); - m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 38); - - if (!res.m_viewRes.m_solidVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_vertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_vertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_vertsVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewBlockBuf}; - m_vertsShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_vertsVtxFmt, m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewBlockBuf}; - m_vertsShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_solidVtxFmt, - m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + + m_vertsBinding.initSolid(res, 38, m_viewBlockBuf); + m_windowGfxData = res.m_factory->commit(); for (int i=0 ; i<4 ; ++i) @@ -332,7 +312,7 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView, const RectangleCo setLineColors(0.0); setFillColors(0.0); - m_vertsBuf->load(&m_verts, sizeof(m_verts)); + m_vertsBinding.load(&m_verts, sizeof(m_verts)); } static float CubicEase(float t) @@ -387,7 +367,7 @@ void ModalWindow::think() if (doneCount == 3) m_phase = Phase::Showing; if (loadVerts) - m_vertsBuf->load(&m_verts, sizeof(m_verts)); + m_vertsBinding.load(&m_verts, sizeof(m_verts)); ++m_frame; break; } @@ -422,7 +402,7 @@ void ModalWindow::think() tt = Zeus::Math::clamp(0.f, tt, 1.f); updateContentOpacity(tt); } - m_vertsBuf->load(&m_verts, sizeof(m_verts)); + m_vertsBinding.load(&m_verts, sizeof(m_verts)); ++m_frame; break; } @@ -442,7 +422,7 @@ bool ModalWindow::skipBuildInAnimation() setLineVerts(m_width, m_height, pf, 1.0); setLineColors(2.0); setFillColors(2.0); - m_vertsBuf->load(&m_verts, sizeof(m_verts)); + m_vertsBinding.load(&m_verts, sizeof(m_verts)); m_phase = Phase::ResWait; return true; } @@ -472,7 +452,7 @@ void ModalWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect& setLineVerts(m_width, m_height, pf, m_lineTime); setFillVerts(m_width, m_height, pf); - m_vertsBuf->load(&m_verts, sizeof(m_verts)); + m_vertsBinding.load(&m_verts, sizeof(m_verts)); boo::SWindowRect cornerRect = centerRect; cornerRect.size[0] = cornerRect.size[1] = 8 * pf; @@ -495,7 +475,7 @@ void ModalWindow::draw(boo::IGraphicsCommandQueue* gfxQ) if (m_phase == Phase::Done) return; - gfxQ->setShaderDataBinding(m_vertsShaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 22); gfxQ->draw(22, 16); diff --git a/specter/lib/ScrollView.cpp b/specter/lib/ScrollView.cpp index 9f7169c09..8945fba0e 100644 --- a/specter/lib/ScrollView.cpp +++ b/specter/lib/ScrollView.cpp @@ -9,29 +9,7 @@ namespace Specter ScrollView::ScrollView(ViewResources& res, View& parentView, Style style) : View(res, parentView), m_style(style), m_sideButtonBind(*this, rootView().viewManager()) { - m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 4); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_vertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_vertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_vtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_vtxFmt, m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_texVtxFmt, - m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, 4, m_viewVertBlockBuf); commitResources(res); if (style == Style::SideButtons) @@ -271,7 +249,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_vertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); } } else if (m_style == Style::SideButtons && m_drawSideButtons) @@ -297,7 +275,7 @@ void ScrollView::draw(boo::IGraphicsCommandQueue* gfxQ) if (m_style == Style::ThinIndicator && m_drawInd) { - gfxQ->setShaderDataBinding(m_shaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 4); } diff --git a/specter/lib/SplitView.cpp b/specter/lib/SplitView.cpp index c5782821d..b87ae4833 100644 --- a/specter/lib/SplitView.cpp +++ b/specter/lib/SplitView.cpp @@ -22,32 +22,7 @@ SplitView::SplitView(ViewResources& res, View& parentView, Axis axis, int cleara : View(res, parentView), m_axis(axis), m_clearanceA(clearanceA), m_clearanceB(clearanceB) { m_splitBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); - m_splitVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 4); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_splitVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_splitVertsBuf, nullptr, boo::VertexSemantic::UV4} - }; - m_splitVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; - boo::ITexture* texs[] = {res.m_splitRes.m_shadingTex}; - m_splitShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, - m_splitVtxFmt, m_splitVertsBuf, nullptr, - nullptr, 1, bufs, 1, texs); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; - boo::ITexture* texs[] = {res.m_splitRes.m_shadingTex}; - m_splitShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, - res.m_viewRes.m_texVtxFmt, - m_splitVertsBuf, nullptr, - nullptr, 1, bufs, 1, texs); - } - + m_splitVertsBinding.initTex(res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex); commitResources(res); } @@ -210,7 +185,7 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su setVerticalVerts(ssub.size[1]); } m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock)); - m_splitVertsBuf->load(m_splitVerts, sizeof(TexShaderVert) * 4); + m_splitVertsBinding.load(m_splitVerts, sizeof(m_splitVerts)); } void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) @@ -220,7 +195,7 @@ void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) m_views[0].m_view->draw(gfxQ); if (m_views[1].m_view) m_views[1].m_view->draw(gfxQ); - gfxQ->setShaderDataBinding(m_splitShaderBinding); + gfxQ->setShaderDataBinding(m_splitVertsBinding); gfxQ->draw(0, 4); } diff --git a/specter/lib/Table.cpp b/specter/lib/Table.cpp index f30908d16..296018659 100644 --- a/specter/lib/Table.cpp +++ b/specter/lib/Table.cpp @@ -16,31 +16,7 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, if (!maxColumns) Log.report(LogVisor::FatalError, "0-column tables not supported"); - m_hVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, - sizeof(SolidShaderVert), - maxColumns * 6); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_hVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_hVertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_hVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_hShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_hVtxFmt, m_hVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_hShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_texVtxFmt, - m_hVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, maxColumns * 6, m_viewVertBlockBuf); commitResources(res); m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator)); @@ -51,35 +27,12 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, Table::RowsView::RowsView(Table& t, ViewResources& res) : View(res, t), m_t(t), m_verts(new SolidShaderVert[SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6]) { - m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), - SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_vertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_vertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_vtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_vtxFmt, m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_texVtxFmt, - m_vertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, m_viewVertBlockBuf); commitResources(res); } -Table::CellView::CellView(Table& t, ViewResources& res, size_t c, size_t r) -: View(res, t), m_t(t), m_text(new TextView(res, *this, res.m_mainFont)), m_c(c), m_r(r) {} +Table::CellView::CellView(Table& t, ViewResources& res) +: View(res, t), m_t(t), m_text(new TextView(res, *this, res.m_mainFont)), m_c(-1), m_r(-1) {} void Table::_setHeaderVerts(const boo::SWindowRect& sub) {; @@ -157,7 +110,7 @@ void Table::_setHeaderVerts(const boo::SWindowRect& sub) } if (c) - m_hVertsBuf->load(m_hVerts.get(), sizeof(SolidShaderVert) * 6 * c); + m_vertsBinding.load(m_hVerts.get(), sizeof(SolidShaderVert) * 6 * c); m_headerNeedsUpdate = false; } @@ -167,7 +120,7 @@ void Table::RowsView::_setRowVerts(const boo::SWindowRect& sub, const boo::SWind SolidShaderVert* v = m_verts.get(); const ThemeData& theme = rootView().themeData(); - if (m_t.m_cellViews.empty()) + if (m_t.m_cellPools.empty()) return; float pf = rootView().viewRes().pixelFactor(); @@ -182,8 +135,6 @@ void Table::RowsView::_setRowVerts(const boo::SWindowRect& sub, const boo::SWind ++idx; } int startIdx = int(m_t.m_rows) - idx; - if (!m_t.m_header) - startIdx -= 1; std::vector cellRects = m_t.getCellRects(sub); @@ -217,7 +168,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_vertsBuf->load(m_verts.get(), sizeof(SolidShaderVert) * 6 * r * c); + m_vertsBinding.load(m_verts.get(), sizeof(SolidShaderVert) * 6 * r * c); } void Table::cycleSortColumn(size_t c) @@ -255,22 +206,61 @@ void Table::selectRow(size_t r) } return; } - if (m_selectedRow != -1) - for (auto& col : m_cellViews) + + if (m_selectedRow != -1 && m_activePool != -1) + { + size_t poolIdx = m_selectedRow / SPECTER_TABLE_MAX_ROWS; + int pool0 = (poolIdx & 1) != 0; + int pool1 = (poolIdx & 1) == 0; + if (m_activePool == poolIdx) { - ViewChild>& cv = col.at(m_selectedRow); - if (cv.m_view) - cv.m_view->deselect(); + for (auto& col : m_cellPools) + { + ViewChild>& cv = col[pool0].at(m_selectedRow % SPECTER_TABLE_MAX_ROWS); + if (cv.m_view) + cv.m_view->deselect(); + } } + else if (m_activePool+1 == poolIdx) + { + for (auto& col : m_cellPools) + { + ViewChild>& cv = col[pool1].at(m_selectedRow % SPECTER_TABLE_MAX_ROWS); + if (cv.m_view) + cv.m_view->deselect(); + } + } + } + m_selectedRow = r; - if (m_selectedRow != -1) - for (auto& col : m_cellViews) + + if (m_selectedRow != -1 && m_activePool != -1) + { + size_t poolIdx = m_selectedRow / SPECTER_TABLE_MAX_ROWS; + int pool0 = (poolIdx & 1) != 0; + int pool1 = (poolIdx & 1) == 0; + if (m_activePool == poolIdx) { - ViewChild>& cv = col.at(m_selectedRow); - if (cv.m_view) - cv.m_view->select(); + for (auto& col : m_cellPools) + { + ViewChild>& cv = col[pool0].at(m_selectedRow % SPECTER_TABLE_MAX_ROWS); + if (cv.m_view) + cv.m_view->select(); + } } + else if (m_activePool+1 == poolIdx) + { + for (auto& col : m_cellPools) + { + ViewChild>& cv = col[pool1].at(m_selectedRow % SPECTER_TABLE_MAX_ROWS); + if (cv.m_view) + cv.m_view->select(); + } + } + } + updateSize(); + if (m_state) { m_inSelectRow = true; @@ -287,9 +277,12 @@ void Table::setMultiplyColor(const Zeus::CColor& color) for (ViewChild>& hv : m_headerViews) if (hv.m_view) hv.m_view->m_text->setMultiplyColor(color); - for (auto& col : m_cellViews) + for (auto& col : m_cellPools) { - for (ViewChild>& cv : col) + for (ViewChild>& cv : col[0]) + if (cv.m_view) + cv.m_view->m_text->setMultiplyColor(color); + for (ViewChild>& cv : col[1]) if (cv.m_view) cv.m_view->m_text->setMultiplyColor(color); } @@ -349,9 +342,13 @@ void Table::RowsView::mouseDown(const boo::SWindowCoord& coord, for (ViewChild>& hv : m_t.m_headerViews) if (hv.mouseDown(coord, button, mod)) return; /* Trap header event */ - for (std::vector>>& col : m_t.m_cellViews) - for (ViewChild>& cv : col) + for (auto& col : m_t.m_cellPools) + { + for (ViewChild>& cv : col[0]) cv.mouseDown(coord, button, mod); + for (ViewChild>& cv : col[1]) + cv.mouseDown(coord, button, mod); + } } void Table::CellView::mouseDown(const boo::SWindowCoord& coord, @@ -393,9 +390,13 @@ void Table::RowsView::mouseUp(const boo::SWindowCoord& coord, hv.mouseUp(coord, button, mod); ++idx; } - for (std::vector>>& col : m_t.m_cellViews) - for (ViewChild>& cv : col) + for (auto& col : m_t.m_cellPools) + { + for (ViewChild>& cv : col[0]) cv.mouseUp(coord, button, mod); + for (ViewChild>& cv : col[1]) + cv.mouseUp(coord, button, mod); + } } void Table::CellView::mouseUp(const boo::SWindowCoord& coord, @@ -453,9 +454,13 @@ void Table::RowsView::mouseMove(const boo::SWindowCoord& coord) { for (ViewChild>& hv : m_t.m_headerViews) hv.mouseMove(coord); - for (std::vector>>& col : m_t.m_cellViews) - for (ViewChild>& cv : col) + for (auto& col : m_t.m_cellPools) + { + for (ViewChild>& cv : col[0]) cv.mouseMove(coord); + for (ViewChild>& cv : col[1]) + cv.mouseMove(coord); + } } void Table::mouseEnter(const boo::SWindowCoord& coord) @@ -482,9 +487,13 @@ void Table::RowsView::mouseLeave(const boo::SWindowCoord& coord) { for (ViewChild>& hv : m_t.m_headerViews) hv.mouseLeave(coord); - for (std::vector>>& col : m_t.m_cellViews) - for (ViewChild>& cv : col) + for (auto& col : m_t.m_cellPools) + { + for (ViewChild>& cv : col[0]) cv.mouseLeave(coord); + for (ViewChild>& cv : col[1]) + cv.mouseLeave(coord); + } } void Table::CellView::mouseLeave(const boo::SWindowCoord& coord) @@ -504,12 +513,108 @@ void Table::think() m_scroll.m_view->think(); ++m_clickFrames; } + +void Table::CellView::reset() +{ + m_c = -1; + m_r = -1; + if (m_textHash) + { + m_text->typesetGlyphs(""); + m_textHash = 0; + } +} + +bool Table::CellView::reset(size_t c) +{ + m_c = c; + m_r = -1; + const std::string* headerText = m_t.m_data->header(c); + if (headerText) + { + uint64_t hash = XXH64(headerText->data(), headerText->size(), 0); + if (hash != m_textHash) + { + m_text->typesetGlyphs(*headerText, rootView().themeData().uiText()); + m_textHash = hash; + } + return true; + } + else if (m_textHash) + { + m_text->typesetGlyphs(""); + m_textHash = 0; + } + return false; +} -void Table::updateData() +bool Table::CellView::reset(size_t c, size_t r) +{ + m_c = c; + m_r = r; + const std::string* cellText = m_t.m_data->cell(c, r); + if (cellText) + { + uint64_t hash = XXH64(cellText->data(), cellText->size(), 0); + if (hash != m_textHash) + { + m_text->typesetGlyphs(*cellText, rootView().themeData().uiText()); + m_textHash = hash; + } + return true; + } + else if (m_textHash) + { + m_text->typesetGlyphs(""); + m_textHash = 0; + } + return false; +} + +std::vector& Table::ensureCellPools(size_t rows, size_t cols, ViewResources& res) +{ + if (m_cellPools.size() < cols) + { + m_cellPools.reserve(cols); + for (size_t i=m_cellPools.size() ; i SPECTER_TABLE_MAX_ROWS) + { + for (int p=0 ; p<2 ; ++p) + for (ViewChild>& cv : cp[p]) + if (!cv.m_view) + cv.m_view.reset(new CellView(*this, res)); + } + else + { + size_t r = 0; + for (ViewChild>& cv : cp[0]) + { + if (!cv.m_view) + cv.m_view.reset(new CellView(*this, res)); + ++r; + if (r >= rows) + break; + } + } + } + m_ensuredRows = rows; + } + return m_cellPools; +} + +void Table::_updateData() { m_header = false; bool newViewChildren = false; - if (m_columns != m_data->columnCount()) + if (m_columns != m_data->columnCount() || m_rows > m_data->rowCount() + SPECTER_TABLE_MAX_ROWS) newViewChildren = true; m_rows = m_data->rowCount(); @@ -517,52 +622,66 @@ void Table::updateData() if (!m_columns) return; + ViewResources& res = rootView().viewRes(); if (newViewChildren) { m_headerViews.clear(); - m_cellViews.clear(); + m_cellPools.clear(); m_headerViews.reserve(m_columns); - m_cellViews.reserve(m_columns); for (size_t c=0 ; cheader(c); - if (headerText) - { + std::unique_ptr& cv = m_headerViews[c].m_view; + if (!cv) + cv.reset(new CellView(*this, res)); + if (cv->reset(c)) m_header = true; - CellView* cv = new CellView(*this, res, c, -1); - m_headerViews[c].m_view.reset(cv); - cv->m_text->typesetGlyphs(*headerText, textColor); - } - else - m_headerViews[c].m_view.reset(); - std::vector>>& col = m_cellViews[c]; - col.clear(); - col.reserve(m_rows); - for (size_t r=0 ; rcell(c, r); - if (cellText) + for (size_t r=startRow, i=0 ; im_text->typesetGlyphs(*cellText, textColor); + ViewChild>& cv = col[pool0][i]; + if (cv.m_view) + { + if (r < m_rows) + cv.m_view->reset(c, r); + else + cv.m_view->reset(); + } + } + for (size_t r=startRow+SPECTER_TABLE_MAX_ROWS, i=0 ; i>& cv = col[pool1][i]; + if (cv.m_view) + { + if (r < m_rows) + cv.m_view->reset(c, r); + else + cv.m_view->reset(); + } } - else - col.emplace_back(); } } - + + m_activePool = poolIdx; +} + +void Table::updateData() +{ + m_activePool = -1; updateSize(); } @@ -643,9 +762,7 @@ void Table::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) int Table::RowsView::nominalHeight() const { float pf = rootView().viewRes().pixelFactor(); - int rows = m_t.m_rows; - if (m_t.m_header) - rows += 1; + int rows = m_t.m_rows + 1; return rows * (ROW_HEIGHT + CELL_MARGIN * 2) * pf; } @@ -654,6 +771,7 @@ void Table::RowsView::resized(const boo::SWindowRect& root, const boo::SWindowRe { View::resized(root, sub); _setRowVerts(sub, scissor); + m_t._updateData(); if (!m_t.m_columns) return; @@ -666,9 +784,20 @@ void Table::RowsView::resized(const boo::SWindowRect& root, const boo::SWindowRe int spacing = (ROW_HEIGHT + CELL_MARGIN * 2) * pf; std::vector cellRects = m_t.getCellRects(rowRect); auto cellRectIt = cellRects.begin(); - for (auto& col : m_t.m_cellViews) + int poolIdx = m_visibleStart / SPECTER_TABLE_MAX_ROWS; + int pool0 = (poolIdx & 1) != 0; + int pool1 = (poolIdx & 1) == 0; + int locationStart = spacing * poolIdx * SPECTER_TABLE_MAX_ROWS; + for (auto& col : m_t.m_cellPools) { - for (ViewChild>& cv : col) + cellRectIt->location[1] -= locationStart; + for (ViewChild>& cv : col[pool0]) + { + cellRectIt->location[1] -= spacing; + if (cv.m_view) + cv.m_view->resized(root, *cellRectIt, cellScissor); + } + for (ViewChild>& cv : col[pool1]) { cellRectIt->location[1] -= spacing; if (cv.m_view) @@ -701,15 +830,25 @@ void Table::draw(boo::IGraphicsCommandQueue* gfxQ) void Table::RowsView::draw(boo::IGraphicsCommandQueue* gfxQ) { - gfxQ->setShaderDataBinding(m_shaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->setScissor(m_scissorRect); gfxQ->draw(1, m_visibleRows * m_t.m_columns * 6 - 2); - for (auto& col : m_t.m_cellViews) + + int poolIdx = m_t.m_activePool; + int pool0 = (poolIdx & 1) != 0; + int pool1 = (poolIdx & 1) == 0; + for (auto& col : m_t.m_cellPools) { - size_t idx = 0; - for (ViewChild>& cv : col) + size_t idx = poolIdx * SPECTER_TABLE_MAX_ROWS; + for (ViewChild>& cv : col[pool0]) + { + if (cv.m_view && idx >= m_visibleStart && idx < m_visibleStart + m_visibleRows) + cv.m_view->draw(gfxQ); + ++idx; + } + for (ViewChild>& cv : col[pool1]) { if (cv.m_view && idx >= m_visibleStart && idx < m_visibleStart + m_visibleRows) cv.m_view->draw(gfxQ); @@ -719,7 +858,7 @@ void Table::RowsView::draw(boo::IGraphicsCommandQueue* gfxQ) if (m_t.m_header) { - gfxQ->setShaderDataBinding(m_t.m_hShaderBinding); + gfxQ->setShaderDataBinding(m_t.m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->setScissor(rootView().subRect()); gfxQ->draw(1, m_t.m_columns * 6 - 2); diff --git a/specter/lib/TextField.cpp b/specter/lib/TextField.cpp index 7301fa834..d26fdf57b 100644 --- a/specter/lib/TextField.cpp +++ b/specter/lib/TextField.cpp @@ -8,35 +8,13 @@ namespace Specter TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBind) : ITextInputView(res, parentView, strBind) { - m_bVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 41); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_bVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_bVertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_bVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_bVtxFmt, m_bVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_viewVertBlockBuf}; - m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_texVtxFmt, - m_bVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, 41, m_viewVertBlockBuf); commitResources(res); for (int i=28 ; i<32 ; ++i) m_verts[i].m_color = res.themeData().textfieldSelection(); setInactive(); - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024)); if (strBind) @@ -149,7 +127,7 @@ void TextField::setInactive() for (int i=5 ; i<28 ; ++i) m_verts[i].m_color = theme.textfield2Inactive(); } - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_bgState = BGState::Inactive; } @@ -176,7 +154,7 @@ void TextField::setHover() for (int i=5 ; i<28 ; ++i) m_verts[i].m_color = theme.textfield2Inactive(); } - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_bgState = BGState::Hover; } @@ -203,7 +181,7 @@ void TextField::setDisabled() for (int i=5 ; i<28 ; ++i) m_verts[i].m_color = theme.textfield2Disabled(); } - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_bgState = BGState::Disabled; } @@ -623,7 +601,7 @@ void TextField::think() } for (size_t i=32 ; i<41 ; ++i) m_verts[i].m_color = errBg; - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_errText->setMultiplyColor(errMult); } @@ -666,7 +644,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_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]}; rootView().window()->claimKeyboardFocus(focusRect); @@ -747,7 +725,7 @@ void TextField::_reallySetSelectionRange(size_t start, size_t len) 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_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]}; rootView().window()->claimKeyboardFocus(focusRect); @@ -772,7 +750,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_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); int focusRect[2] = {subRect().location[0] + offset1, subRect().location[1]}; rootView().window()->claimKeyboardFocus(focusRect); @@ -902,7 +880,7 @@ void TextField::resized(const boo::SWindowRect& root, const boo::SWindowRect& su m_verts[i].m_color = Zeus::CColor::skClear; } - m_bVertsBuf->load(m_verts, sizeof(m_verts)); + m_vertsBinding.load(m_verts, sizeof(m_verts)); m_nomWidth = width; m_nomHeight = height; @@ -916,7 +894,7 @@ void TextField::resized(const boo::SWindowRect& root, const boo::SWindowRect& su void TextField::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); - gfxQ->setShaderDataBinding(m_bShaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 28); if (m_active) diff --git a/specter/lib/Toolbar.cpp b/specter/lib/Toolbar.cpp index bf86a2438..aa0ee01f7 100644 --- a/specter/lib/Toolbar.cpp +++ b/specter/lib/Toolbar.cpp @@ -27,34 +27,9 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos) m_padding(res.pixelFactor() * TOOLBAR_PADDING) { m_tbBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); - m_tbVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 10); - - if (!res.m_viewRes.m_texVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_tbVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_tbVertsBuf, nullptr, boo::VertexSemantic::UV4} - }; - m_tbVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_tbBlockBuf}; - boo::ITexture* texs[] = {res.m_toolbarRes.m_shadingTex}; - m_tbShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, - m_tbVtxFmt, m_tbVertsBuf, nullptr, - nullptr, 1, bufs, 1, texs); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_tbBlockBuf}; - boo::ITexture* texs[] = {res.m_toolbarRes.m_shadingTex}; - m_tbShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, - res.m_viewRes.m_texVtxFmt, - m_tbVertsBuf, nullptr, - nullptr, 1, bufs, 1, texs); - } - - setBackground(res.themeData().toolbarBackground()); + m_vertsBinding.initTex(res, 10, m_tbBlockBuf, res.m_toolbarRes.m_shadingTex); commitResources(res); + setBackground(res.themeData().toolbarBackground()); } void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) @@ -91,7 +66,7 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); setHorizontalVerts(sub.size[0]); - m_tbVertsBuf->load(&m_tbVerts, sizeof(TexShaderVert) * 10); + m_vertsBinding.load(m_tbVerts, sizeof(m_tbVerts)); m_tbBlock.setViewRect(root, sub); m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock)); @@ -110,7 +85,7 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); - gfxQ->setShaderDataBinding(m_tbShaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 10); diff --git a/specter/lib/Tooltip.cpp b/specter/lib/Tooltip.cpp index 14968e04f..8071fef23 100644 --- a/specter/lib/Tooltip.cpp +++ b/specter/lib/Tooltip.cpp @@ -13,29 +13,7 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, const std::string& title, : View(res, parentView), m_titleStr(title), m_messageStr(message) { m_ttBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); - m_ttVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 16); - - if (!res.m_viewRes.m_solidVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_ttVertsBuf, nullptr, boo::VertexSemantic::Position4}, - {m_ttVertsBuf, nullptr, boo::VertexSemantic::Color} - }; - m_ttVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - boo::IGraphicsBuffer* bufs[] = {m_ttBlockBuf}; - m_ttShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - m_ttVtxFmt, m_ttVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } - else - { - boo::IGraphicsBuffer* bufs[] = {m_ttBlockBuf}; - m_ttShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, - res.m_viewRes.m_solidVtxFmt, - m_ttVertsBuf, nullptr, - nullptr, 1, bufs, 0, nullptr); - } + m_vertsBinding.initSolid(res, 16, m_ttBlockBuf); for (int i=0 ; i<16 ; ++i) m_ttVerts[i].m_color = res.themeData().tooltipBackground(); @@ -94,7 +72,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_ttVertsBuf->load(m_ttVerts, sizeof(SolidShaderVert) * 16); + m_vertsBinding.load(m_ttVerts, sizeof(m_ttVerts)); } void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -132,7 +110,7 @@ void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) void Tooltip::draw(boo::IGraphicsCommandQueue* gfxQ) { - gfxQ->setShaderDataBinding(m_ttShaderBinding); + gfxQ->setShaderDataBinding(m_vertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 16); diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index 230fa346a..d06b4ce2d 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -286,36 +286,10 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them void View::buildResources(ViewResources& res) { - m_bgVertBuf = - res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, - sizeof(SolidShaderVert), 4); - m_viewVertBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); - - if (!res.m_viewRes.m_solidVtxFmt) - { - boo::VertexElementDescriptor vdescs[] = - { - {m_bgVertBuf, nullptr, boo::VertexSemantic::Position4}, - {m_bgVertBuf, nullptr, boo::VertexSemantic::Color} - }; - m_bgVtxFmt = res.m_factory->newVertexFormat(2, vdescs); - m_bgShaderBinding = - res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, m_bgVtxFmt, - m_bgVertBuf, nullptr, nullptr, 1, - (boo::IGraphicsBuffer**)&m_viewVertBlockBuf, - 0, nullptr); - } - else - { - m_bgShaderBinding = - res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, res.m_viewRes.m_solidVtxFmt, - m_bgVertBuf, nullptr, nullptr, 1, - (boo::IGraphicsBuffer**)&m_viewVertBlockBuf, - 0, nullptr); - } + m_bgVertsBinding.initSolid(res, 4, m_viewVertBlockBuf); } View::View(ViewResources& res) @@ -346,12 +320,12 @@ 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); m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock)); - m_bgVertBuf->load(m_bgRect, sizeof(SolidShaderVert) * 4); + m_bgVertsBinding.load(m_bgRect, sizeof(m_bgRect)); } void View::draw(boo::IGraphicsCommandQueue* gfxQ) { - gfxQ->setShaderDataBinding(m_bgShaderBinding); + gfxQ->setShaderDataBinding(m_bgVertsBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 4); } @@ -362,5 +336,62 @@ void View::commitResources(ViewResources& res) Log.report(LogVisor::FatalError, "multiple resource commits not allowed"); m_gfxData = res.m_factory->commit(); } + +void View::VertexBufferBinding::initSolid(ViewResources& res, size_t count, boo::IGraphicsBuffer* viewBlockBuf) +{ + m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), count); + + if (!res.m_viewRes.m_solidVtxFmt) + { + boo::VertexElementDescriptor vdescs[] = + { + {m_vertsBuf, nullptr, boo::VertexSemantic::Position4}, + {m_vertsBuf, nullptr, boo::VertexSemantic::Color} + }; + m_vtxFmt = res.m_factory->newVertexFormat(2, vdescs); + boo::IGraphicsBuffer* bufs[] = {viewBlockBuf}; + m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, + m_vtxFmt, m_vertsBuf, nullptr, + nullptr, 1, bufs, 0, nullptr); + } + else + { + boo::IGraphicsBuffer* bufs[] = {viewBlockBuf}; + m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, + res.m_viewRes.m_solidVtxFmt, + m_vertsBuf, nullptr, + nullptr, 1, bufs, 0, nullptr); + } +} + +void View::VertexBufferBinding::initTex(ViewResources& res, size_t count, boo::IGraphicsBuffer* viewBlockBuf, boo::ITexture* texture) +{ + m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), count); + + if (!res.m_viewRes.m_texVtxFmt) + { + boo::VertexElementDescriptor vdescs[] = + { + {m_vertsBuf, nullptr, boo::VertexSemantic::Position4}, + {m_vertsBuf, nullptr, boo::VertexSemantic::UV4} + }; + m_vtxFmt = res.m_factory->newVertexFormat(2, vdescs); + boo::IGraphicsBuffer* bufs[] = {viewBlockBuf}; + boo::ITexture* tex[] = {texture}; + m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, + m_vtxFmt, m_vertsBuf, nullptr, + nullptr, 1, bufs, 1, tex); + } + else + { + boo::IGraphicsBuffer* bufs[] = {viewBlockBuf}; + boo::ITexture* tex[] = {texture}; + m_shaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_texShader, + res.m_viewRes.m_texVtxFmt, + m_vertsBuf, nullptr, + nullptr, 1, bufs, 1, tex); + } +} + }