[hud] Add new HUD item abstraction

Allows for a cleaner and more flexible implementation of new HUD elements.
The old implementation was not intended to support quite as many elements
as it does, and now there is some need for API-specific HUD elements.
This commit is contained in:
Philip Rebohle 2019-12-12 20:46:17 +01:00
parent 4346f82209
commit 6931f03120
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
5 changed files with 182 additions and 1 deletions

View File

@ -43,6 +43,7 @@ namespace dxvk::hud {
void Hud::update() {
m_hudItems.update();
m_hudFramerate.update();
m_hudStats.update(m_device);
}
@ -84,8 +85,10 @@ namespace dxvk::hud {
void Hud::renderHudElements(const Rc<DxvkContext>& ctx) {
m_hudItems.render(m_renderer);
HudPos position = { 8.0f, 24.0f };
if (m_config.elements.test(HudElement::DxvkVersion)) {
m_renderer.drawText(16.0f,
{ position.x, position.y },

View File

@ -6,6 +6,7 @@
#include "dxvk_hud_config.h"
#include "dxvk_hud_devinfo.h"
#include "dxvk_hud_item.h"
#include "dxvk_hud_fps.h"
#include "dxvk_hud_renderer.h"
#include "dxvk_hud_stats.h"
@ -54,6 +55,18 @@ namespace dxvk::hud {
void render(
const Rc<DxvkContext>& ctx,
VkExtent2D surfaceSize);
/**
* \brief Adds a HUD item if enabled
*
* \tparam T The HUD item type
* \param [in] name HUD item name
* \param [in] args Constructor arguments
*/
template<typename T, typename... Args>
void addItem(const char* name, Args... args) {
m_hudItems.add<T>(name, std::forward<Args>(args)...);
}
/**
* \brief Creates the HUD
@ -81,6 +94,7 @@ namespace dxvk::hud {
HudDeviceInfo m_hudDeviceInfo;
HudFps m_hudFramerate;
HudStats m_hudStats;
HudItemSet m_hudItems;
void setupRendererState(
const Rc<DxvkContext>& ctx);

View File

@ -0,0 +1,61 @@
#include "dxvk_hud_item.h"
namespace dxvk::hud {
HudItem::~HudItem() {
}
void HudItem::update(dxvk::high_resolution_clock::time_point time) {
// Do nothing by default. Some items won't need this.
}
HudItemSet::HudItemSet() {
std::string configStr = env::getEnvVar("DXVK_HUD");
if (configStr == "full") {
// Just enable everything
m_enableFull = true;
} else if (configStr == "1") {
m_enabled.insert("devinfo");
m_enabled.insert("fps");
} else {
std::string::size_type pos = 0;
std::string::size_type end = 0;
while (pos < configStr.size()) {
end = configStr.find(',', pos);
if (end == std::string::npos)
end = configStr.size();
m_enabled.insert(configStr.substr(pos, end - pos));
pos = end + 1;
}
}
}
HudItemSet::~HudItemSet() {
}
void HudItemSet::update() {
auto time = dxvk::high_resolution_clock::now();
for (const auto& item : m_items)
item->update(time);
}
void HudItemSet::render(HudRenderer& renderer) {
HudPos position = { 8.0f, 8.0f };
for (const auto& item : m_items)
position = item->render(renderer, position);
}
}

View File

@ -0,0 +1,102 @@
#pragma once
#include <string>
#include <unordered_set>
#include <vector>
#include "../../util/util_time.h"
#include "dxvk_hud_renderer.h"
namespace dxvk::hud {
/**
* \brief HUD item
*
* A single named item in the HUD that
* can be enabled by the user.
*/
class HudItem : public RcObject {
public:
virtual ~HudItem();
/**
* \brief Updates the HUD item
* \param [in] time Current time
*/
virtual void update(
dxvk::high_resolution_clock::time_point time);
/**
* \brief Renders the HUD
*
* \param [in] renderer HUD renderer
* \param [in] position Base offset
* \returns Base offset for next item
*/
virtual HudPos render(
HudRenderer& renderer,
HudPos position) = 0;
};
/**
* \brief HUD item set
*
* Manages HUD items.
*/
class HudItemSet {
public:
HudItemSet();
~HudItemSet();
/**
* \brief Updates the HUD
* Updates all enabled HUD items.
*/
void update();
/**
* \brief Renders the HUD
*
* \param [in] renderer HUD renderer
* \returns Base offset for next item
*/
void render(
HudRenderer& renderer);
/**
* \brief Creates a HUD item if enabled
*
* \tparam T The HUD item type
* \param [in] name HUD item name
* \param [in] args Constructor arguments
*/
template<typename T, typename... Args>
void add(const char* name, Args... args) {
bool enable = m_enableFull;
if (!enable) {
auto entry = m_enabled.find(name);
enable = entry != m_enabled.end();
}
if (enable)
m_items.push_back(new T(std::forward<Args>(args)...));
}
private:
bool m_enableFull = false;
std::unordered_set<std::string> m_enabled;
std::vector<Rc<HudItem>> m_items;
};
}

View File

@ -106,6 +106,7 @@ dxvk_src = files([
'hud/dxvk_hud_devinfo.cpp',
'hud/dxvk_hud_font.cpp',
'hud/dxvk_hud_fps.cpp',
'hud/dxvk_hud_item.cpp',
'hud/dxvk_hud_renderer.cpp',
'hud/dxvk_hud_stats.cpp',
])