summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/OnScreenDisplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/OnScreenDisplay.cpp')
-rw-r--r--Source/Core/VideoCommon/OnScreenDisplay.cpp62
1 files changed, 55 insertions, 7 deletions
diff --git a/Source/Core/VideoCommon/OnScreenDisplay.cpp b/Source/Core/VideoCommon/OnScreenDisplay.cpp
index e860c53ec0..0e07dbc397 100644
--- a/Source/Core/VideoCommon/OnScreenDisplay.cpp
+++ b/Source/Core/VideoCommon/OnScreenDisplay.cpp
@@ -18,6 +18,10 @@
#include "Core/Config/MainSettings.h"
+#include "VideoCommon/AbstractGfx.h"
+#include "VideoCommon/AbstractTexture.h"
+#include "VideoCommon/TextureConfig.h"
+
namespace OSD
{
constexpr float LEFT_MARGIN = 10.0f; // Pixels to the left of OSD messages.
@@ -32,8 +36,8 @@ static std::atomic<int> s_obscured_pixels_top = 0;
struct Message
{
Message() = default;
- Message(std::string text_, u32 duration_, u32 color_)
- : text(std::move(text_)), duration(duration_), color(color_)
+ Message(std::string text_, u32 duration_, u32 color_, std::unique_ptr<Icon> icon_ = nullptr)
+ : text(std::move(text_)), duration(duration_), color(color_), icon(std::move(icon_))
{
timer.Start();
}
@@ -42,7 +46,10 @@ struct Message
Common::Timer timer;
u32 duration = 0;
bool ever_drawn = false;
+ bool should_discard = false;
u32 color = 0;
+ std::unique_ptr<Icon> icon;
+ std::unique_ptr<AbstractTexture> texture;
};
static std::multimap<MessageType, Message> s_messages;
static std::mutex s_messages_mutex;
@@ -77,6 +84,33 @@ static float DrawMessage(int index, Message& msg, const ImVec2& position, int ti
ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
{
+ if (msg.icon)
+ {
+ if (!msg.texture)
+ {
+ const u32 width = msg.icon->width;
+ const u32 height = msg.icon->height;
+ TextureConfig tex_config(width, height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0);
+ msg.texture = g_gfx->CreateTexture(tex_config);
+ if (msg.texture)
+ {
+ msg.texture->Load(0, width, height, width, msg.icon->rgba_data.data(),
+ sizeof(u32) * width * height);
+ }
+ else
+ {
+ // don't try again next time
+ msg.icon.reset();
+ }
+ }
+
+ if (msg.texture)
+ {
+ ImGui::Image(msg.texture.get(), ImVec2(static_cast<float>(msg.icon->width),
+ static_cast<float>(msg.icon->height)));
+ }
+ }
+
// Use %s in case message contains %.
ImGui::TextColored(ARGBToImVec4(msg.color), "%s", msg.text.c_str());
window_height =
@@ -91,17 +125,25 @@ static float DrawMessage(int index, Message& msg, const ImVec2& position, int ti
return window_height;
}
-void AddTypedMessage(MessageType type, std::string message, u32 ms, u32 argb)
+void AddTypedMessage(MessageType type, std::string message, u32 ms, u32 argb,
+ std::unique_ptr<Icon> icon)
{
std::lock_guard lock{s_messages_mutex};
- s_messages.erase(type);
- s_messages.emplace(type, Message(std::move(message), ms, argb));
+
+ // A message may hold a reference to a texture that can only be destroyed on the video thread, so
+ // only mark the old typed message (if any) for removal. It will be discarded on the next call to
+ // DrawMessages().
+ auto range = s_messages.equal_range(type);
+ for (auto it = range.first; it != range.second; ++it)
+ it->second.should_discard = true;
+
+ s_messages.emplace(type, Message(std::move(message), ms, argb, std::move(icon)));
}
-void AddMessage(std::string message, u32 ms, u32 argb)
+void AddMessage(std::string message, u32 ms, u32 argb, std::unique_ptr<Icon> icon)
{
std::lock_guard lock{s_messages_mutex};
- s_messages.emplace(MessageType::Typeless, Message(std::move(message), ms, argb));
+ s_messages.emplace(MessageType::Typeless, Message(std::move(message), ms, argb, std::move(icon)));
}
void DrawMessages()
@@ -117,6 +159,12 @@ void DrawMessages()
for (auto it = s_messages.begin(); it != s_messages.end();)
{
Message& msg = it->second;
+ if (msg.should_discard)
+ {
+ it = s_messages.erase(it);
+ continue;
+ }
+
const s64 time_left = msg.TimeRemaining();
// Make sure we draw them at least once if they were printed with 0ms,