overlays: use timestamp for fade animations

Fixes jojo when using sceNp dialogs
This commit is contained in:
Megamouse 2024-01-31 00:13:20 +01:00
parent d7f317fa58
commit f28c7d029c
27 changed files with 114 additions and 129 deletions

View File

@ -451,7 +451,7 @@ namespace gl
overlay_pass::run(cmd_, viewport, target, gl::image_aspect::color, true);
}
ui.update();
ui.update(get_system_time());
}
video_out_calibration_pass::video_out_calibration_pass()

View File

@ -33,28 +33,16 @@ namespace rsx
m_time_display.set_pos(virtual_width - (20 + m_time_display.w), (m_description.y + m_description.h) - m_time_display.h);
m_time_display.back_color.a = 0.f;
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
}
void home_menu_dialog::update()
void home_menu_dialog::update(u64 timestamp_us)
{
static u64 frame = 0;
if (Emu.IsPaused())
{
// Let's keep updating the animation anyway
frame++;
}
else
{
frame = rsx::get_current_renderer()->vblank_count;
}
if (fade_animation.active)
{
fade_animation.update(frame);
fade_animation.update(timestamp_us);
}
static std::string last_time;

View File

@ -13,7 +13,7 @@ namespace rsx
public:
home_menu_dialog();
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
compiled_resource get_compiled() override;

View File

@ -54,16 +54,16 @@ namespace rsx
m_description->auto_resize();
m_description->back_color.a = 0.f;
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
}
void recvmessage_dialog::update()
void recvmessage_dialog::update(u64 timestamp_us)
{
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
}

View File

@ -30,7 +30,7 @@ namespace rsx
public:
recvmessage_dialog();
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
compiled_resource get_compiled() override;

View File

@ -51,16 +51,16 @@ namespace rsx
m_description->auto_resize();
m_description->back_color.a = 0.f;
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
}
void sendmessage_dialog::update()
void sendmessage_dialog::update(u64 timestamp_us)
{
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
}

View File

@ -32,7 +32,7 @@ namespace rsx
public:
sendmessage_dialog();
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
compiled_resource get_compiled() override;

View File

@ -7,30 +7,30 @@ namespace rsx
{
namespace overlays
{
void animation_base::begin_animation(u64 frame)
void animation_base::begin_animation(u64 timestamp_us)
{
frame_start = frame;
frame_end = frame + get_duration_in_frames();
timestamp_start_us = timestamp_us;
timestamp_end_us = timestamp_us + get_total_duration_us();
}
u64 animation_base::get_duration_in_frames() const
u64 animation_base::get_total_duration_us() const
{
return u64(duration * g_cfg.video.vblank_rate);
return u64(duration_sec * 1'000'000.f);
}
u64 animation_base::get_remaining_frames(u64 frame) const
u64 animation_base::get_remaining_duration_us(u64 timestamp_us) const
{
return frame >= frame_end ? 0 : (frame_end - frame);
return timestamp_us >= timestamp_end_us ? 0 : (timestamp_end_us - timestamp_us);
}
f32 animation_base::get_progress_ratio(u64 frame) const
f32 animation_base::get_progress_ratio(u64 timestamp_us) const
{
if (!frame_start)
if (!timestamp_start_us)
{
return 0.f;
}
f32 t = f32(frame - frame_start) / (frame_end - frame_start);
f32 t = f32(timestamp_us - timestamp_start_us) / (timestamp_end_us - timestamp_start_us);
switch (type) {
case animation_type::linear:
@ -49,15 +49,15 @@ namespace rsx
return t;
}
void animation_translate::reset(u64 start_frame)
void animation_translate::reset(u64 start_timestamp_us)
{
active = false;
current = start;
frame_start = start_frame;
timestamp_start_us = start_timestamp_us;
if (frame_start > 0)
if (timestamp_start_us > 0)
{
frame_end = frame_start + get_duration_in_frames();
timestamp_end_us = timestamp_start_us + get_total_duration_us();
}
}
@ -78,36 +78,36 @@ namespace rsx
}
}
void animation_translate::update(u64 frame)
void animation_translate::update(u64 timestamp_us)
{
if (!active)
{
return;
}
if (frame_start == 0)
if (timestamp_start_us == 0)
{
start = current;
begin_animation(frame);
begin_animation(timestamp_us);
return;
}
if (frame >= frame_end)
if (timestamp_us >= timestamp_end_us)
{
// Exit condition
finish();
return;
}
f32 t = get_progress_ratio(frame);
f32 t = get_progress_ratio(timestamp_us);
current = lerp(start, end, t);
}
void animation_translate::finish()
{
active = false;
frame_start = 0;
frame_end = 0;
timestamp_start_us = 0;
timestamp_end_us = 0;
current = end; // Snap current to limit in case we went over
if (on_finish)
@ -116,15 +116,15 @@ namespace rsx
}
}
void animation_color_interpolate::reset(u64 start_frame)
void animation_color_interpolate::reset(u64 start_timestamp_us)
{
active = false;
current = start;
frame_start = start_frame;
timestamp_start_us = start_timestamp_us;
if (frame_start > 0)
if (timestamp_start_us > 0)
{
frame_end = frame_start + get_duration_in_frames();
timestamp_end_us = timestamp_start_us + get_total_duration_us();
}
}
@ -141,35 +141,35 @@ namespace rsx
}
}
void animation_color_interpolate::update(u64 frame)
void animation_color_interpolate::update(u64 timestamp_us)
{
if (!active)
{
return;
}
if (frame_start == 0)
if (timestamp_start_us == 0)
{
start = current;
begin_animation(frame);
begin_animation(timestamp_us);
return;
}
if (frame >= frame_end)
if (timestamp_us >= timestamp_end_us)
{
finish();
return;
}
f32 t = get_progress_ratio(frame);
f32 t = get_progress_ratio(timestamp_us);
current = lerp(start, end, t);
}
void animation_color_interpolate::finish()
{
active = false;
frame_start = 0;
frame_end = 0;
timestamp_start_us = 0;
timestamp_end_us = 0;
current = end;
if (on_finish)

View File

@ -23,11 +23,11 @@ namespace rsx
struct animation_base
{
protected:
u64 frame_start = 0;
u64 frame_end = 0;
u64 timestamp_start_us = 0;
u64 timestamp_end_us = 0;
void begin_animation(u64 frame);
f32 get_progress_ratio(u64 frame) const;
void begin_animation(u64 timestamp_us);
f32 get_progress_ratio(u64 timestamp_us) const;
template<typename T>
static T lerp(const T& a, const T& b, f32 t)
@ -38,16 +38,16 @@ namespace rsx
public:
bool active = false;
animation_type type { animation_type::linear };
f32 duration = 1.f; // in seconds
f32 duration_sec = 1.f; // in seconds
std::function<void()> on_finish;
u64 get_duration_in_frames() const;
u64 get_remaining_frames(u64 frame) const;
u64 get_total_duration_us() const;
u64 get_remaining_duration_us(u64 timestamp_us) const;
virtual void apply(compiled_resource&) = 0;
virtual void reset(u64 start_frame) = 0;
virtual void update(u64 frame) = 0;
virtual void reset(u64 start_timestamp_us) = 0;
virtual void update(u64 timestamp_us) = 0;
};
struct animation_translate : animation_base
@ -61,8 +61,8 @@ namespace rsx
vector3f end{};
void apply(compiled_resource& data) override;
void reset(u64 start_frame = 0) override;
void update(u64 frame) override;
void reset(u64 start_timestamp_us = 0) override;
void update(u64 timestamp_us) override;
void finish();
};
@ -76,8 +76,8 @@ namespace rsx
color4f end{};
void apply(compiled_resource& data) override;
void reset(u64 start_frame = 0) override;
void update(u64 frame) override;
void reset(u64 start_timestamp_us = 0) override;
void update(u64 timestamp_us) override;
void finish();
};
}

View File

@ -76,7 +76,7 @@ namespace rsx
return cr;
}
void cursor_manager::update()
void cursor_manager::update(u64 timestamp_us)
{
if (!visible)
{
@ -85,12 +85,11 @@ namespace rsx
std::lock_guard lock(m_mutex);
const u64 cur_time = get_system_time();
bool any_cursor_visible = false;
for (auto& entry : m_cursors)
{
any_cursor_visible |= entry.second.update_visibility(cur_time);
any_cursor_visible |= entry.second.update_visibility(timestamp_us);
}
if (!any_cursor_visible)

View File

@ -39,7 +39,7 @@ namespace rsx
class cursor_manager final : public overlay
{
public:
void update() override;
void update(u64 timestamp_us) override;
compiled_resource get_compiled() override;
void update_cursor(u32 id, u16 x, u16 y, const color4f& color, u64 duration_us, bool force_update);

View File

@ -30,12 +30,12 @@ namespace rsx
m_fade_in_animation.current = color4f(1.f, 1.f, 1.f, 0.f);
m_fade_in_animation.end = color4f(1.0f);
m_fade_in_animation.duration = 1.f;
m_fade_in_animation.duration_sec = 1.f;
m_fade_in_animation.active = true;
m_fade_out_animation.current = color4f(1.f);
m_fade_out_animation.end = color4f(1.f, 1.f, 1.f, 0.f);
m_fade_out_animation.duration = 1.f;
m_fade_out_animation.duration_sec = 1.f;
m_fade_out_animation.active = false;
back_color = color4f(0.25f, 0.25f, 0.25f, 0.85f);
@ -108,7 +108,7 @@ namespace rsx
return compiled_resources;
}
void message_item::update(usz index, u64 time, u16 y_offset)
void message_item::update(usz index, u64 timestamp_us, u16 y_offset)
{
if (m_cur_pos != index)
{
@ -124,32 +124,31 @@ namespace rsx
if (m_fade_in_animation.active)
{
// We are fading in.
m_fade_in_animation.update(rsx::get_current_renderer()->vblank_count);
m_fade_in_animation.update(timestamp_us);
}
else if (time + u64(m_fade_out_animation.duration * 1'000'000) > get_expiration())
else if (timestamp_us + u64(m_fade_out_animation.duration_sec * 1'000'000) > get_expiration())
{
// We are fading out.
// Only activate the animation if the message hasn't expired yet (prevents glitches afterwards).
if (time <= get_expiration())
if (timestamp_us <= get_expiration())
{
m_fade_out_animation.active = true;
}
m_fade_out_animation.update(rsx::get_current_renderer()->vblank_count);
m_fade_out_animation.update(timestamp_us);
}
else if (m_fade_out_animation.active)
{
// We are fading out, but the expiration was extended.
// Reset the fade in animation to the state of the fade out animation to prevent opacity pop.
const usz current_frame = rsx::get_current_renderer()->vblank_count;
const f32 fade_out_progress = static_cast<f32>(m_fade_out_animation.get_remaining_frames(current_frame)) / static_cast<f32>(m_fade_out_animation.get_duration_in_frames());
const u64 fade_in_frames_done = u64(fade_out_progress * m_fade_in_animation.get_duration_in_frames());
const f32 fade_out_progress = static_cast<f32>(m_fade_out_animation.get_remaining_duration_us(timestamp_us)) / static_cast<f32>(m_fade_out_animation.get_total_duration_us());
const u64 fade_in_us_done = u64(fade_out_progress * m_fade_in_animation.get_total_duration_us());
m_fade_in_animation.reset(current_frame - fade_in_frames_done);
m_fade_in_animation.reset(timestamp_us - fade_in_us_done);
m_fade_in_animation.active = true;
m_fade_in_animation.update(current_frame);
m_fade_in_animation.update(timestamp_us);
// Reset the fade out animation.
m_fade_out_animation.reset();
@ -203,7 +202,7 @@ namespace rsx
}
}
void message::update()
void message::update(u64 /*timestamp_us*/)
{
if (!visible)
{

View File

@ -20,7 +20,7 @@ namespace rsx
public:
template <typename T>
message_item(T msg_id, u64 expiration, std::shared_ptr<atomic_t<u32>> refs, std::shared_ptr<overlay_element> icon = {});
void update(usz index, u64 time, u16 y_offset);
void update(usz index, u64 timestamp_us, u16 y_offset);
void set_pos(u16 _x, u16 _y) override;
void reset_expiration();
@ -46,7 +46,7 @@ namespace rsx
class message final : public overlay
{
public:
void update() override;
void update(u64 timestamp_us) override;
compiled_resource get_compiled() override;
template <typename T>

View File

@ -58,7 +58,7 @@ namespace rsx
btn_cancel.set_image_resource(resource_config::standard_image_resource::circle);
}
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
update_custom_background();
@ -196,10 +196,10 @@ namespace rsx
user_interface::close(use_callback, stop_pad_interception);
}
void message_dialog::update()
void message_dialog::update(u64 timestamp_us)
{
if (fade_animation.active)
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
error_code message_dialog::show(bool is_blocking, const std::string& text, const MsgDialogType& type, std::function<void(s32 status)> on_close)

View File

@ -40,7 +40,7 @@ namespace rsx
compiled_resource get_compiled() override;
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
void close(bool use_callback, bool stop_pad_interception) override;

View File

@ -48,7 +48,7 @@ namespace rsx
fade_animation.current = color4f(1.f);
fade_animation.end = color4f(0.f);
fade_animation.duration = 0.5f;
fade_animation.duration_sec = 0.5f;
fade_animation.on_finish = [this, status]
{
@ -532,7 +532,7 @@ namespace rsx
fade_animation.current = color4f(0.f);
fade_animation.end = color4f(1.f);
fade_animation.duration = 0.5f;
fade_animation.duration_sec = 0.5f;
fade_animation.active = true;
}
@ -1151,11 +1151,11 @@ namespace rsx
return get_localized_u32string(id);
}
void osk_dialog::update()
void osk_dialog::update(u64 timestamp_us)
{
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
m_update = true;
}

View File

@ -116,7 +116,7 @@ namespace rsx
void step_panel(bool next_panel);
void update_panel();
void update_layout();
void update() override;
void update(u64 timestamp_us) override;
void update_controls();
void update_selection_by_index(u32 index);

View File

@ -260,7 +260,7 @@ namespace rsx
m_frametime_timer.Start();
}
update();
update(get_system_time());
// The text might have changed during the update. Recalculate positions.
reset_transforms();
@ -432,7 +432,7 @@ namespace rsx
m_force_update = true;
}
void perf_metrics_overlay::update()
void perf_metrics_overlay::update(u64 /*timestamp_us*/)
{
const auto elapsed_update = m_update_timer.GetElapsedTimeInMilliSec();
const bool do_update = m_force_update || elapsed_update >= m_update_interval;

View File

@ -102,7 +102,7 @@ namespace rsx
void set_title_colors(std::string color, std::string background);
void force_next_update();
void update() override;
void update(u64 timestamp_us) override;
compiled_resource get_compiled() override;
};

View File

@ -105,19 +105,19 @@ namespace rsx
m_description->back_color.a = 0.f;
m_time_thingy->back_color.a = 0.f;
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
}
void save_dialog::update()
void save_dialog::update(u64 timestamp_us)
{
m_time_thingy->set_text(date_time::current_time());
m_time_thingy->auto_resize();
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
}

View File

@ -33,7 +33,7 @@ namespace rsx
public:
save_dialog();
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
compiled_resource get_compiled() override;

View File

@ -51,14 +51,14 @@ namespace rsx
text_view.align_text(overlay_element::text_align::center);
text_view.back_color.a = 0.f;
sliding_animation.duration = 1.5f;
sliding_animation.duration_sec = 1.5f;
sliding_animation.type = animation_type::ease_in_out_cubic;
// Make the fade animation a bit shorter to see the trophy better.
fade_animation.duration = 1.0f;
fade_animation.duration_sec = 1.0f;
}
void trophy_notification::update()
void trophy_notification::update(u64 timestamp_us)
{
if (!s_trophy_semaphore.try_acquire(display_sched_id))
{
@ -66,19 +66,18 @@ namespace rsx
return;
}
const u64 t = get_system_time();
if (!creation_time)
if (!creation_time_us)
{
// First tick
creation_time = t;
creation_time_us = timestamp_us;
Emu.GetCallbacks().play_sound(fs::get_config_dir() + "sounds/snd_trophy.wav");
return;
}
const u64 time_since_creation = ((t - creation_time) / 1000);
u64 end_animation_begin = 5000;
const u64 time_since_creation_us = timestamp_us - creation_time_us;
u64 end_animation_begin_us = 5'000'000;
if (time_since_creation > end_animation_begin)
if (time_since_creation_us > end_animation_begin_us)
{
if (!sliding_animation.active)
{
@ -94,12 +93,12 @@ namespace rsx
}
// Match both animation ends based on their durations
if (sliding_animation.duration > fade_animation.duration)
if (sliding_animation.duration_sec > fade_animation.duration_sec)
{
end_animation_begin += static_cast<u64>((sliding_animation.duration - fade_animation.duration) * 1000);
end_animation_begin_us += static_cast<u64>((sliding_animation.duration_sec - fade_animation.duration_sec) * 1'000'000);
}
if (time_since_creation > end_animation_begin)
if (time_since_creation_us > end_animation_begin_us)
{
if (!fade_animation.active)
{
@ -112,18 +111,18 @@ namespace rsx
if (sliding_animation.active)
{
sliding_animation.update(rsx::get_current_renderer()->vblank_count);
sliding_animation.update(timestamp_us);
}
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
}
compiled_resource trophy_notification::get_compiled()
{
if (!creation_time || !visible)
if (!creation_time_us || !visible)
{
return {};
}

View File

@ -15,7 +15,7 @@ namespace rsx
label text_view;
u64 display_sched_id = 0;
u64 creation_time = 0;
u64 creation_time_us = 0;
std::unique_ptr<image_info> icon_info;
animation_translate sliding_animation;
@ -24,7 +24,7 @@ namespace rsx
public:
trophy_notification();
void update() override;
void update(u64 timestamp_us) override;
compiled_resource get_compiled() override;

View File

@ -83,16 +83,16 @@ namespace rsx
m_description->auto_resize();
m_description->back_color.a = 0.f;
fade_animation.duration = 0.15f;
fade_animation.duration_sec = 0.15f;
return_code = selection_code::canceled;
}
void user_list_dialog::update()
void user_list_dialog::update(u64 timestamp_us)
{
if (fade_animation.active)
{
fade_animation.update(rsx::get_current_renderer()->vblank_count);
fade_animation.update(timestamp_us);
}
}

View File

@ -30,7 +30,7 @@ namespace rsx
public:
user_list_dialog();
void update() override;
void update(u64 timestamp_us) override;
void on_button_pressed(pad_button button_press, bool is_auto_repeat) override;
compiled_resource get_compiled() override;

View File

@ -40,7 +40,7 @@ namespace rsx
virtual ~overlay() = default;
virtual void update() {}
virtual void update(u64 /*timestamp_us*/) {}
virtual compiled_resource get_compiled() = 0;
void refresh() const;
@ -123,7 +123,7 @@ namespace rsx
bool is_detached() const { return m_input_thread_detached; }
void detach_input() { m_input_thread_detached.store(true); }
void update() override {}
void update(u64 /*timestamp_us*/) override {}
compiled_resource get_compiled() override = 0;

View File

@ -695,7 +695,7 @@ namespace vk
overlay_pass::run(cmd, viewport, target, image_views, render_pass);
}
ui.update();
ui.update(get_system_time());
}
attachment_clear_pass::attachment_clear_pass()