mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00: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
|
||||
{
|
||||
template <typename T>
|
||||
message_item::message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs)
|
||||
static u64 get_expiration_time(u64 duration)
|
||||
{
|
||||
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_text.set_font("Arial", 16);
|
||||
m_text.set_font("Arial", 14);
|
||||
m_text.set_text(msg_id);
|
||||
m_text.auto_resize();
|
||||
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.duration = 2.f;
|
||||
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(localized_string_id 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>>, std::unique_ptr<overlay_element>);
|
||||
|
||||
u64 message_item::get_expiration() const
|
||||
{
|
||||
|
@ -31,28 +47,41 @@ namespace rsx
|
|||
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)
|
||||
{
|
||||
return {};
|
||||
compiled_resources = {};
|
||||
return compiled_resources;
|
||||
}
|
||||
|
||||
auto cr = m_text.get_compiled();
|
||||
m_fade_animation.apply(cr);
|
||||
compiled_resources = m_text.get_compiled();
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -60,6 +89,34 @@ namespace rsx
|
|||
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()
|
||||
{
|
||||
if (!visible)
|
||||
|
@ -68,26 +125,11 @@ namespace rsx
|
|||
}
|
||||
|
||||
std::lock_guard lock(m_mutex_queue);
|
||||
u64 cur_time = get_system_time();
|
||||
|
||||
while (!m_queue.empty() && m_queue.front().get_expiration() < cur_time)
|
||||
{
|
||||
m_queue.pop_front();
|
||||
}
|
||||
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);
|
||||
|
||||
if (m_queue.empty())
|
||||
{
|
||||
visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
usz index = 0;
|
||||
|
||||
for (auto& item : m_queue)
|
||||
{
|
||||
item.update(index, cur_time);
|
||||
index++;
|
||||
}
|
||||
visible = !m_vis_items_top.empty() || !m_vis_items_bottom.empty();
|
||||
}
|
||||
|
||||
compiled_resource message::get_compiled()
|
||||
|
@ -101,7 +143,12 @@ namespace rsx
|
|||
|
||||
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());
|
||||
}
|
||||
|
|
|
@ -7,21 +7,29 @@ namespace rsx
|
|||
{
|
||||
namespace overlays
|
||||
{
|
||||
class message_item
|
||||
enum message_pin_location
|
||||
{
|
||||
top,
|
||||
bottom
|
||||
};
|
||||
|
||||
class message_item : public overlay_element
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs);
|
||||
void update(usz index, u64 time);
|
||||
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, u16 origin, int grow_direction);
|
||||
|
||||
u64 get_expiration() const;
|
||||
compiled_resource get_compiled();
|
||||
compiled_resource& get_compiled();
|
||||
|
||||
private:
|
||||
label m_text{};
|
||||
std::unique_ptr<overlay_element> m_icon{};
|
||||
animation_color_interpolate m_fade_animation;
|
||||
|
||||
u64 m_expiration_time = 0;
|
||||
u64 m_visible_duration = 0;
|
||||
std::shared_ptr<atomic_t<u32>> m_refs;
|
||||
bool m_processed = false;
|
||||
usz m_cur_pos = umax;
|
||||
|
@ -34,32 +42,56 @@ namespace rsx
|
|||
compiled_resource get_compiled() override;
|
||||
|
||||
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);
|
||||
|
||||
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>>)
|
||||
{
|
||||
for (auto id : msg_id)
|
||||
{
|
||||
m_queue.emplace_back(id, expiration, refs);
|
||||
queue.emplace_back(id, expiration, refs, icon);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
const u32 max_visible_items = 3;
|
||||
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>
|
||||
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>())
|
||||
{
|
||||
|
@ -69,7 +101,7 @@ namespace rsx
|
|||
msg_overlay = std::make_shared<rsx::overlays::message>();
|
||||
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
Reference in a new issue