mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-28 13:28:01 +03:00
rsx: Implement notification queue
This commit is contained in:
parent
c471120a80
commit
0885884839
2 changed files with 122 additions and 43 deletions
|
@ -6,13 +6,23 @@ namespace rsx
|
||||||
{
|
{
|
||||||
namespace overlays
|
namespace overlays
|
||||||
{
|
{
|
||||||
template <typename T>
|
static u64 get_expiration_time(u64 duration)
|
||||||
message_item::message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs)
|
|
||||||
{
|
{
|
||||||
m_expiration_time = expiration == umax ? expiration : get_system_time() + expiration;
|
if (duration == umax)
|
||||||
|
{
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rsx::uclock() + duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
message_item::message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs, std::unique_ptr<overlay_element> icon)
|
||||||
|
{
|
||||||
|
m_visible_duration = expiration;
|
||||||
m_refs = std::move(refs);
|
m_refs = std::move(refs);
|
||||||
|
|
||||||
m_text.set_font("Arial", 16);
|
m_text.set_font("Arial", 14);
|
||||||
m_text.set_text(msg_id);
|
m_text.set_text(msg_id);
|
||||||
m_text.auto_resize();
|
m_text.auto_resize();
|
||||||
m_text.back_color.a = 0.f;
|
m_text.back_color.a = 0.f;
|
||||||
|
@ -21,9 +31,15 @@ namespace rsx
|
||||||
m_fade_animation.end = color4f(1.0f, 1.0f, 1.0f, 0.f);
|
m_fade_animation.end = color4f(1.0f, 1.0f, 1.0f, 0.f);
|
||||||
m_fade_animation.duration = 2.f;
|
m_fade_animation.duration = 2.f;
|
||||||
m_fade_animation.active = true;
|
m_fade_animation.active = true;
|
||||||
|
|
||||||
|
if (icon)
|
||||||
|
{
|
||||||
|
m_icon = std::move(icon);
|
||||||
|
m_icon->set_pos(m_text.x + m_text.w + 8, m_text.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
template message_item::message_item(std::string msg_id, u64, std::shared_ptr<atomic_t<u32>>);
|
template message_item::message_item(std::string msg_id, u64, std::shared_ptr<atomic_t<u32>>, std::unique_ptr<overlay_element>);
|
||||||
template message_item::message_item(localized_string_id msg_id, u64, std::shared_ptr<atomic_t<u32>>);
|
template message_item::message_item(localized_string_id msg_id, u64, std::shared_ptr<atomic_t<u32>>, std::unique_ptr<overlay_element>);
|
||||||
|
|
||||||
u64 message_item::get_expiration() const
|
u64 message_item::get_expiration() const
|
||||||
{
|
{
|
||||||
|
@ -31,28 +47,41 @@ namespace rsx
|
||||||
return m_refs && *m_refs == 0 ? 0 : m_expiration_time;
|
return m_refs && *m_refs == 0 ? 0 : m_expiration_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
compiled_resource message_item::get_compiled()
|
compiled_resource& message_item::get_compiled()
|
||||||
{
|
{
|
||||||
if (!m_processed)
|
if (!m_processed)
|
||||||
{
|
{
|
||||||
return {};
|
compiled_resources = {};
|
||||||
|
return compiled_resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cr = m_text.get_compiled();
|
compiled_resources = m_text.get_compiled();
|
||||||
m_fade_animation.apply(cr);
|
if (m_icon)
|
||||||
|
{
|
||||||
|
compiled_resources.add(m_icon->get_compiled());
|
||||||
|
}
|
||||||
|
m_fade_animation.apply(compiled_resources);
|
||||||
|
|
||||||
return cr;
|
return compiled_resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
void message_item::update(usz index, u64 time)
|
void message_item::update(usz index, u64 time, u16 origin, int grow_direction)
|
||||||
{
|
{
|
||||||
if (m_cur_pos != index)
|
if (m_cur_pos != index)
|
||||||
{
|
{
|
||||||
m_cur_pos = index;
|
m_cur_pos = index;
|
||||||
m_text.set_pos(10, static_cast<u16>(index * 18));
|
m_text.set_pos(10, static_cast<u16>(origin + (index * 18 * grow_direction)));
|
||||||
|
if (m_icon)
|
||||||
|
{
|
||||||
|
m_icon->set_pos(m_icon->x, m_text.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_expiration_time - time) < 2'000'000)
|
if (!m_processed)
|
||||||
|
{
|
||||||
|
m_expiration_time = get_expiration_time(m_visible_duration);
|
||||||
|
}
|
||||||
|
else if ((m_expiration_time - time) < 2'000'000)
|
||||||
{
|
{
|
||||||
m_fade_animation.update(rsx::get_current_renderer()->vblank_count);
|
m_fade_animation.update(rsx::get_current_renderer()->vblank_count);
|
||||||
}
|
}
|
||||||
|
@ -60,6 +89,34 @@ namespace rsx
|
||||||
m_processed = true;
|
m_processed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void message::update_queue(std::deque<message_item>& vis_set, std::deque<message_item>& ready_set, u16 origin, int grow_direction)
|
||||||
|
{
|
||||||
|
const u64 cur_time = rsx::uclock();
|
||||||
|
|
||||||
|
while (!vis_set.empty() && vis_set.front().get_expiration() < cur_time)
|
||||||
|
{
|
||||||
|
vis_set.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (vis_set.size() < max_visible_items && !ready_set.empty())
|
||||||
|
{
|
||||||
|
vis_set.emplace_back(std::move(ready_set.front()));
|
||||||
|
ready_set.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vis_set.empty() && ready_set.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
usz index = 0;
|
||||||
|
for (auto& item : vis_set)
|
||||||
|
{
|
||||||
|
item.update(index, cur_time, origin, grow_direction);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void message::update()
|
void message::update()
|
||||||
{
|
{
|
||||||
if (!visible)
|
if (!visible)
|
||||||
|
@ -68,26 +125,11 @@ namespace rsx
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(m_mutex_queue);
|
std::lock_guard lock(m_mutex_queue);
|
||||||
u64 cur_time = get_system_time();
|
|
||||||
|
|
||||||
while (!m_queue.empty() && m_queue.front().get_expiration() < cur_time)
|
update_queue(m_vis_items_top, m_ready_queue_top, 0, 1);
|
||||||
{
|
update_queue(m_vis_items_bottom, m_ready_queue_bottom, virtual_height - 18, -1);
|
||||||
m_queue.pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_queue.empty())
|
visible = !m_vis_items_top.empty() || !m_vis_items_bottom.empty();
|
||||||
{
|
|
||||||
visible = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
usz index = 0;
|
|
||||||
|
|
||||||
for (auto& item : m_queue)
|
|
||||||
{
|
|
||||||
item.update(index, cur_time);
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compiled_resource message::get_compiled()
|
compiled_resource message::get_compiled()
|
||||||
|
@ -101,7 +143,12 @@ namespace rsx
|
||||||
|
|
||||||
compiled_resource cr{};
|
compiled_resource cr{};
|
||||||
|
|
||||||
for (auto& item : m_queue)
|
for (auto& item : m_vis_items_top)
|
||||||
|
{
|
||||||
|
cr.add(item.get_compiled());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& item : m_vis_items_bottom)
|
||||||
{
|
{
|
||||||
cr.add(item.get_compiled());
|
cr.add(item.get_compiled());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,29 @@ namespace rsx
|
||||||
{
|
{
|
||||||
namespace overlays
|
namespace overlays
|
||||||
{
|
{
|
||||||
class message_item
|
enum message_pin_location
|
||||||
|
{
|
||||||
|
top,
|
||||||
|
bottom
|
||||||
|
};
|
||||||
|
|
||||||
|
class message_item : public overlay_element
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs);
|
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs, std::unique_ptr<overlay_element> icon = {});
|
||||||
void update(usz index, u64 time);
|
void update(usz index, u64 time, u16 origin, int grow_direction);
|
||||||
|
|
||||||
u64 get_expiration() const;
|
u64 get_expiration() const;
|
||||||
compiled_resource get_compiled();
|
compiled_resource& get_compiled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
label m_text{};
|
label m_text{};
|
||||||
|
std::unique_ptr<overlay_element> m_icon{};
|
||||||
animation_color_interpolate m_fade_animation;
|
animation_color_interpolate m_fade_animation;
|
||||||
|
|
||||||
u64 m_expiration_time = 0;
|
u64 m_expiration_time = 0;
|
||||||
|
u64 m_visible_duration = 0;
|
||||||
std::shared_ptr<atomic_t<u32>> m_refs;
|
std::shared_ptr<atomic_t<u32>> m_refs;
|
||||||
bool m_processed = false;
|
bool m_processed = false;
|
||||||
usz m_cur_pos = umax;
|
usz m_cur_pos = umax;
|
||||||
|
@ -34,32 +42,56 @@ namespace rsx
|
||||||
compiled_resource get_compiled() override;
|
compiled_resource get_compiled() override;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void queue_message(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs)
|
void queue_message(
|
||||||
|
T msg_id,
|
||||||
|
u64 expiration,
|
||||||
|
std::shared_ptr<atomic_t<u32>> refs,
|
||||||
|
message_pin_location location = message_pin_location::top,
|
||||||
|
std::unique_ptr<overlay_element> icon = {})
|
||||||
{
|
{
|
||||||
std::lock_guard lock(m_mutex_queue);
|
std::lock_guard lock(m_mutex_queue);
|
||||||
|
|
||||||
|
auto& queue = location == message_pin_location::top
|
||||||
|
? m_ready_queue_top
|
||||||
|
: m_ready_queue_bottom;
|
||||||
|
|
||||||
if constexpr (std::is_same_v<T, std::initializer_list<localized_string_id>>)
|
if constexpr (std::is_same_v<T, std::initializer_list<localized_string_id>>)
|
||||||
{
|
{
|
||||||
for (auto id : msg_id)
|
for (auto id : msg_id)
|
||||||
{
|
{
|
||||||
m_queue.emplace_back(id, expiration, refs);
|
queue.emplace_back(id, expiration, refs, icon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_queue.emplace_back(msg_id, expiration, std::move(refs));
|
queue.emplace_back(msg_id, expiration, std::move(refs), std::move(icon));
|
||||||
}
|
}
|
||||||
|
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const u32 max_visible_items = 3;
|
||||||
shared_mutex m_mutex_queue;
|
shared_mutex m_mutex_queue;
|
||||||
std::deque<message_item> m_queue;
|
|
||||||
|
// Top and bottom enqueued sets
|
||||||
|
std::deque<message_item> m_ready_queue_top;
|
||||||
|
std::deque<message_item> m_ready_queue_bottom;
|
||||||
|
|
||||||
|
// Top and bottom visible sets
|
||||||
|
std::deque<message_item> m_vis_items_top;
|
||||||
|
std::deque<message_item> m_vis_items_bottom;
|
||||||
|
|
||||||
|
void update_queue(std::deque<message_item>& vis_set, std::deque<message_item>& ready_set, u16 origin, int grow_direction);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void queue_message(T msg_id, u64 expiration = 5'000'000, std::shared_ptr<atomic_t<u32>> refs = {})
|
void queue_message(
|
||||||
|
T msg_id,
|
||||||
|
u64 expiration = 5'000'000,
|
||||||
|
std::shared_ptr<atomic_t<u32>> refs = {},
|
||||||
|
message_pin_location location = message_pin_location::top,
|
||||||
|
std::unique_ptr<overlay_element> icon = {})
|
||||||
{
|
{
|
||||||
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
|
if (auto manager = g_fxo->try_get<rsx::overlays::display_manager>())
|
||||||
{
|
{
|
||||||
|
@ -69,7 +101,7 @@ namespace rsx
|
||||||
msg_overlay = std::make_shared<rsx::overlays::message>();
|
msg_overlay = std::make_shared<rsx::overlays::message>();
|
||||||
msg_overlay = manager->add(msg_overlay);
|
msg_overlay = manager->add(msg_overlay);
|
||||||
}
|
}
|
||||||
msg_overlay->queue_message(msg_id, expiration, std::move(refs));
|
msg_overlay->queue_message(msg_id, expiration, std::move(refs), location, std::move(icon));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue