Compare commits
No commits in common. "cc3f430bab7a9feae37d1d282bd82541a7a945b4" and "7d0e5c80bd1bffa2251cd8f9e8b625c7f0d74c30" have entirely different histories.
cc3f430bab
...
7d0e5c80bd
2
external/solanaceae_contact
vendored
2
external/solanaceae_contact
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 9ca6adee4f6f01d83fd1f5ece5c4b84396079ccc
|
Subproject commit 2d73c7272c3c254086fa067ccfdfb4072c20f7c9
|
2
external/solanaceae_message3
vendored
2
external/solanaceae_message3
vendored
@ -1 +1 @@
|
|||||||
Subproject commit a1f5add8d347da2eb8acb812cd6dbcb36a46778d
|
Subproject commit 20af7dd705fe1be68f7678292125620d48aa278b
|
2
external/solanaceae_util
vendored
2
external/solanaceae_util
vendored
@ -1 +1 @@
|
|||||||
Subproject commit d304d719e9b7c3c40d32fc45993f0ccfd34c556e
|
Subproject commit 390b123fb7380e5da30954d1b0a337208407f40d
|
@ -37,7 +37,7 @@ namespace Components {
|
|||||||
|
|
||||||
} // Components
|
} // Components
|
||||||
|
|
||||||
static constexpr float lerp(float a, float b, float t) {
|
static float lerp(float a, float b, float t) {
|
||||||
return a + t * (b - a);
|
return a + t * (b - a);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,10 +121,8 @@ ChatGui4::ChatGui4(
|
|||||||
ConfigModelI& conf,
|
ConfigModelI& conf,
|
||||||
RegistryMessageModel& rmm,
|
RegistryMessageModel& rmm,
|
||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
TextureUploaderI& tu,
|
TextureUploaderI& tu
|
||||||
ContactTextureCache& contact_tc,
|
) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) {
|
||||||
MessageTextureCache& msg_tc
|
|
||||||
) : _conf(conf), _rmm(rmm), _cr(cr), _contact_tc(contact_tc), _msg_tc(msg_tc), _sip(tu) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatGui4::~ChatGui4(void) {
|
ChatGui4::~ChatGui4(void) {
|
||||||
@ -138,7 +136,20 @@ ChatGui4::~ChatGui4(void) {
|
|||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
float ChatGui4::render(float time_delta) {
|
void ChatGui4::render(float time_delta) {
|
||||||
|
if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
|
||||||
|
std::vector<Contact3> to_purge;
|
||||||
|
_cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) {
|
||||||
|
to_purge.push_back(c);
|
||||||
|
});
|
||||||
|
_cr.remove<Contact::Components::TagAvatarInvalidate>(to_purge.cbegin(), to_purge.cend());
|
||||||
|
_contact_tc.invalidate(to_purge);
|
||||||
|
}
|
||||||
|
// ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE
|
||||||
|
// it might unload textures, so it needs to be done before rendering
|
||||||
|
_contact_tc.update();
|
||||||
|
_msg_tc.update();
|
||||||
|
|
||||||
_fss.render();
|
_fss.render();
|
||||||
_sip.render(time_delta);
|
_sip.render(time_delta);
|
||||||
|
|
||||||
@ -616,7 +627,8 @@ float ChatGui4::render(float time_delta) {
|
|||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
return 1000.f; // TODO: higher min fps?
|
_contact_tc.workLoadQueue();
|
||||||
|
_msg_tc.workLoadQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatGui4::sendFilePath(const char* file_path) {
|
void ChatGui4::sendFilePath(const char* file_path) {
|
||||||
|
@ -9,8 +9,7 @@
|
|||||||
#include "./message_image_loader.hpp"
|
#include "./message_image_loader.hpp"
|
||||||
#include "./file_selector.hpp"
|
#include "./file_selector.hpp"
|
||||||
#include "./send_image_popup.hpp"
|
#include "./send_image_popup.hpp"
|
||||||
|
#include "entt/container/dense_map.hpp"
|
||||||
#include <entt/container/dense_map.hpp>
|
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -18,16 +17,15 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using ContactTextureCache = TextureCache<void*, Contact3, ToxAvatarLoader>;
|
|
||||||
using MessageTextureCache = TextureCache<void*, Message3Handle, MessageImageLoader>;
|
|
||||||
|
|
||||||
class ChatGui4 {
|
class ChatGui4 {
|
||||||
ConfigModelI& _conf;
|
ConfigModelI& _conf;
|
||||||
RegistryMessageModel& _rmm;
|
RegistryMessageModel& _rmm;
|
||||||
Contact3Registry& _cr;
|
Contact3Registry& _cr;
|
||||||
|
|
||||||
ContactTextureCache& _contact_tc;
|
ToxAvatarLoader _tal;
|
||||||
MessageTextureCache& _msg_tc;
|
TextureCache<void*, Contact3, ToxAvatarLoader> _contact_tc;
|
||||||
|
MessageImageLoader _mil;
|
||||||
|
TextureCache<void*, Message3Handle, MessageImageLoader> _msg_tc;
|
||||||
|
|
||||||
FileSelector _fss;
|
FileSelector _fss;
|
||||||
SendImagePopup _sip;
|
SendImagePopup _sip;
|
||||||
@ -54,14 +52,12 @@ class ChatGui4 {
|
|||||||
ConfigModelI& conf,
|
ConfigModelI& conf,
|
||||||
RegistryMessageModel& rmm,
|
RegistryMessageModel& rmm,
|
||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
TextureUploaderI& tu,
|
TextureUploaderI& tu
|
||||||
ContactTextureCache& contact_tc,
|
|
||||||
MessageTextureCache& msg_tc
|
|
||||||
);
|
);
|
||||||
~ChatGui4(void);
|
~ChatGui4(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float render(float time_delta);
|
void render(float time_delta);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool any_unread {false};
|
bool any_unread {false};
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#include "./main_screen.hpp"
|
#include "./main_screen.hpp"
|
||||||
|
|
||||||
#include <solanaceae/contact/components.hpp>
|
|
||||||
|
|
||||||
#include <imgui/imgui.h>
|
#include <imgui/imgui.h>
|
||||||
|
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
@ -23,11 +21,7 @@ MainScreen::MainScreen(SDL_Renderer* renderer_, std::string save_path, std::stri
|
|||||||
mmil(rmm),
|
mmil(rmm),
|
||||||
tam(rmm, cr, conf),
|
tam(rmm, cr, conf),
|
||||||
sdlrtu(renderer_),
|
sdlrtu(renderer_),
|
||||||
tal(cr),
|
cg(conf, rmm, cr, sdlrtu),
|
||||||
contact_tc(tal, sdlrtu),
|
|
||||||
mil(),
|
|
||||||
msg_tc(mil, sdlrtu),
|
|
||||||
cg(conf, rmm, cr, sdlrtu, contact_tc, msg_tc),
|
|
||||||
sw(conf),
|
sw(conf),
|
||||||
tuiu(tc, conf),
|
tuiu(tc, conf),
|
||||||
tdch(tpi)
|
tdch(tpi)
|
||||||
@ -174,22 +168,7 @@ Screen* MainScreen::render(float time_delta, bool&) {
|
|||||||
|
|
||||||
const float pm_interval = pm.render(time_delta); // render
|
const float pm_interval = pm.render(time_delta); // render
|
||||||
|
|
||||||
// TODO: move this somewhere else!!!
|
cg.render(time_delta); // render
|
||||||
// needs both tal and tc <.<
|
|
||||||
if (!cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
|
|
||||||
std::vector<Contact3> to_purge;
|
|
||||||
cr.view<Contact::Components::TagAvatarInvalidate>().each([&to_purge](const Contact3 c) {
|
|
||||||
to_purge.push_back(c);
|
|
||||||
});
|
|
||||||
cr.remove<Contact::Components::TagAvatarInvalidate>(to_purge.cbegin(), to_purge.cend());
|
|
||||||
contact_tc.invalidate(to_purge);
|
|
||||||
}
|
|
||||||
// ACTUALLY NOT IF RENDERED, MOVED LOGIC TO ABOVE
|
|
||||||
// it might unload textures, so it needs to be done before rendering
|
|
||||||
const float ctc_interval = contact_tc.update();
|
|
||||||
const float msgtc_interval = msg_tc.update();
|
|
||||||
|
|
||||||
const float cg_interval = cg.render(time_delta); // render
|
|
||||||
sw.render(); // render
|
sw.render(); // render
|
||||||
tuiu.render(); // render
|
tuiu.render(); // render
|
||||||
tdch.render(); // render
|
tdch.render(); // render
|
||||||
@ -238,136 +217,20 @@ Screen* MainScreen::render(float time_delta, bool&) {
|
|||||||
ImGui::ShowDemoWindow();
|
ImGui::ShowDemoWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
float tc_unfinished_queue_interval;
|
if (
|
||||||
{ // load rendered but not loaded textures
|
_fps_perf_mode > 1 // TODO: magic
|
||||||
bool unfinished_work_queue = contact_tc.workLoadQueue();
|
) {
|
||||||
unfinished_work_queue = unfinished_work_queue || msg_tc.workLoadQueue();
|
// powersave forces 250ms
|
||||||
|
_render_interval = 1.f/4.f;
|
||||||
if (unfinished_work_queue) {
|
} else if (
|
||||||
tc_unfinished_queue_interval = 0.1f; // so we can get images loaded faster
|
_time_since_event > 1.f && ( // 1sec cool down
|
||||||
} else {
|
_fps_perf_mode == 1 || // TODO: magic
|
||||||
tc_unfinished_queue_interval = 1.f; // TODO: higher min fps?
|
_window_hidden
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate interval for next frame
|
|
||||||
// normal:
|
|
||||||
// - if < 1.5sec since last event
|
|
||||||
// - min all and clamp(1/60, 1/1)
|
|
||||||
// - if < 30sec since last event
|
|
||||||
// - min all (anim + everything else) clamp(1/60, 1/1) (maybe less?)
|
|
||||||
// - else
|
|
||||||
// - min without anim and clamp(1/60, 1/1) (maybe more?)
|
|
||||||
// reduced:
|
|
||||||
// - if < 1sec since last event
|
|
||||||
// - min all and clamp(1/60, 1/1)
|
|
||||||
// - if < 10sec since last event
|
|
||||||
// - min all (anim + everything else) clamp(1/10, 1/1)
|
|
||||||
// - else
|
|
||||||
// - min without anim and max clamp(1/10, 1/1)
|
|
||||||
// powersave:
|
|
||||||
// - if < 0sec since last event
|
|
||||||
// - (ignored)
|
|
||||||
// - if < 1sec since last event
|
|
||||||
// - min all (anim + everything else) clamp(1/8, 1/1)
|
|
||||||
// - else
|
|
||||||
// - min without anim and clamp(1/1, 1/1)
|
|
||||||
struct PerfProfileRender {
|
|
||||||
float low_delay_window {1.5f};
|
|
||||||
float low_delay_min {1.f/60.f};
|
|
||||||
float low_delay_max {1.f/30.f};
|
|
||||||
|
|
||||||
float mid_delay_window {30.f};
|
|
||||||
float mid_delay_min {1.f/60.f};
|
|
||||||
float mid_delay_max {1.f/2.f};
|
|
||||||
|
|
||||||
// also when main window hidden
|
|
||||||
float else_delay_min {1.f/60.f};
|
|
||||||
float else_delay_max {1.f/2.f};
|
|
||||||
};
|
|
||||||
|
|
||||||
const static PerfProfileRender normalPerfProfile{
|
|
||||||
//1.5f, // low_delay_window
|
|
||||||
//1.f/60.f, // low_delay_min
|
|
||||||
//1.f/30.f, // low_delay_max
|
|
||||||
|
|
||||||
//30.f, // mid_delay_window
|
|
||||||
//1.f/60.f, // mid_delay_min
|
|
||||||
//1.f/2.f, // mid_delay_max
|
|
||||||
|
|
||||||
//1.f/60.f, // else_delay_min
|
|
||||||
//1.f/2.f, // else_delay_max
|
|
||||||
};
|
|
||||||
const static PerfProfileRender reducedPerfProfile{
|
|
||||||
1.f, // low_delay_window
|
|
||||||
1.f/60.f, // low_delay_min
|
|
||||||
1.f/30.f, // low_delay_max
|
|
||||||
|
|
||||||
10.f, // mid_delay_window
|
|
||||||
1.f/10.f, // mid_delay_min
|
|
||||||
1.f/4.f, // mid_delay_max
|
|
||||||
|
|
||||||
1.f/10.f, // else_delay_min
|
|
||||||
1.f, // else_delay_max
|
|
||||||
};
|
|
||||||
// TODO: fix powersave by adjusting it in the events handler (make ppr member)
|
|
||||||
const static PerfProfileRender powersavePerfProfile{
|
|
||||||
// no window -> ignore first case
|
|
||||||
0.f, // low_delay_window
|
|
||||||
1.f, // low_delay_min
|
|
||||||
1.f, // low_delay_max
|
|
||||||
|
|
||||||
1.f, // mid_delay_window
|
|
||||||
1.f/8.f, // mid_delay_min
|
|
||||||
1.f/4.f, // mid_delay_max
|
|
||||||
|
|
||||||
1.f, // else_delay_min
|
|
||||||
1.f, // else_delay_max
|
|
||||||
};
|
|
||||||
|
|
||||||
const PerfProfileRender& curr_profile =
|
|
||||||
// TODO: magic
|
|
||||||
_fps_perf_mode > 1
|
|
||||||
? powersavePerfProfile
|
|
||||||
: (
|
|
||||||
_fps_perf_mode == 1
|
|
||||||
? reducedPerfProfile
|
|
||||||
: normalPerfProfile
|
|
||||||
)
|
)
|
||||||
;
|
) {
|
||||||
|
_render_interval = std::min<float>(1.f/1.f, pm_interval);
|
||||||
// min over non animations in all cases
|
|
||||||
_render_interval = std::min<float>(pm_interval, cg_interval);
|
|
||||||
_render_interval = std::min<float>(_render_interval, tc_unfinished_queue_interval);
|
|
||||||
|
|
||||||
// low delay time window
|
|
||||||
if (!_window_hidden && _time_since_event < curr_profile.low_delay_window) {
|
|
||||||
_render_interval = std::min<float>(_render_interval, ctc_interval);
|
|
||||||
_render_interval = std::min<float>(_render_interval, msgtc_interval);
|
|
||||||
|
|
||||||
_render_interval = std::clamp(
|
|
||||||
_render_interval,
|
|
||||||
curr_profile.low_delay_min,
|
|
||||||
curr_profile.low_delay_max
|
|
||||||
);
|
|
||||||
// mid delay time window
|
|
||||||
} else if (!_window_hidden && _time_since_event < curr_profile.mid_delay_window) {
|
|
||||||
_render_interval = std::min<float>(_render_interval, ctc_interval);
|
|
||||||
_render_interval = std::min<float>(_render_interval, msgtc_interval);
|
|
||||||
|
|
||||||
_render_interval = std::clamp(
|
|
||||||
_render_interval,
|
|
||||||
curr_profile.mid_delay_min,
|
|
||||||
curr_profile.mid_delay_max
|
|
||||||
);
|
|
||||||
// timed out or window hidden
|
|
||||||
} else {
|
} else {
|
||||||
// no animation timing here
|
_render_interval = std::min<float>(1.f/60.f, pm_interval);
|
||||||
_render_interval = std::clamp(
|
|
||||||
_render_interval,
|
|
||||||
curr_profile.else_delay_min,
|
|
||||||
curr_profile.else_delay_max
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_time_since_event += time_delta;
|
_time_since_event += time_delta;
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
#include "./tox_avatar_manager.hpp"
|
#include "./tox_avatar_manager.hpp"
|
||||||
|
|
||||||
#include "./sdlrenderer_texture_uploader.hpp"
|
#include "./sdlrenderer_texture_uploader.hpp"
|
||||||
#include "./texture_cache.hpp"
|
|
||||||
#include "./tox_avatar_loader.hpp"
|
|
||||||
#include "./message_image_loader.hpp"
|
|
||||||
|
|
||||||
#include "./chat_gui4.hpp"
|
#include "./chat_gui4.hpp"
|
||||||
#include "./settings_window.hpp"
|
#include "./settings_window.hpp"
|
||||||
#include "./tox_ui_utils.hpp"
|
#include "./tox_ui_utils.hpp"
|
||||||
@ -65,11 +61,6 @@ struct MainScreen final : public Screen {
|
|||||||
SDLRendererTextureUploader sdlrtu;
|
SDLRendererTextureUploader sdlrtu;
|
||||||
//OpenGLTextureUploader ogltu;
|
//OpenGLTextureUploader ogltu;
|
||||||
|
|
||||||
ToxAvatarLoader tal;
|
|
||||||
TextureCache<void*, Contact3, ToxAvatarLoader> contact_tc;
|
|
||||||
MessageImageLoader mil;
|
|
||||||
TextureCache<void*, Message3Handle, MessageImageLoader> msg_tc;
|
|
||||||
|
|
||||||
ChatGui4 cg;
|
ChatGui4 cg;
|
||||||
SettingsWindow sw;
|
SettingsWindow sw;
|
||||||
ToxUIUtils tuiu;
|
ToxUIUtils tuiu;
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
int64_t TextureEntry::doAnimation(const int64_t ts_now) {
|
void TextureEntry::doAnimation(const int64_t ts_now) {
|
||||||
if (frame_duration.size() > 1) { // is animation
|
if (frame_duration.size() > 1) { // is animation
|
||||||
do { // why is this loop so ugly
|
do { // why is this loop so ugly
|
||||||
const int64_t duration = getDuration();
|
const int64_t duration = getDuration();
|
||||||
@ -12,13 +11,11 @@ int64_t TextureEntry::doAnimation(const int64_t ts_now) {
|
|||||||
timestamp_last_rendered += duration;
|
timestamp_last_rendered += duration;
|
||||||
next();
|
next();
|
||||||
} else {
|
} else {
|
||||||
// return ts for next frame
|
break;
|
||||||
return timestamp_last_rendered + duration;
|
|
||||||
}
|
}
|
||||||
} while (true);
|
} while(true);
|
||||||
} else {
|
} else {
|
||||||
timestamp_last_rendered = ts_now;
|
timestamp_last_rendered = ts_now;
|
||||||
return std::numeric_limits<int64_t>::max(); // static image
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,8 +50,7 @@ struct TextureEntry {
|
|||||||
current_texture = (current_texture + 1) % frame_duration.size();
|
current_texture = (current_texture + 1) % frame_duration.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns ts for next frame
|
void doAnimation(const int64_t ts_now);
|
||||||
int64_t doAnimation(const int64_t ts_now);
|
|
||||||
|
|
||||||
template<typename TextureType>
|
template<typename TextureType>
|
||||||
TextureType getID(void) {
|
TextureType getID(void) {
|
||||||
@ -134,16 +133,14 @@ struct TextureCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float update(void) {
|
void update(void) {
|
||||||
const uint64_t ts_now = Message::getTimeMS();
|
const uint64_t ts_now = Message::getTimeMS();
|
||||||
uint64_t ts_min_next = ts_now + ms_before_purge;
|
|
||||||
|
|
||||||
std::vector<KeyType> to_purge;
|
std::vector<KeyType> to_purge;
|
||||||
for (auto&& [key, te] : _cache) {
|
for (auto&& [key, te] : _cache) {
|
||||||
if (te.rendered_this_frame) {
|
if (te.rendered_this_frame) {
|
||||||
const uint64_t ts_next = te.doAnimation(ts_now);
|
te.doAnimation(ts_now);
|
||||||
te.rendered_this_frame = false;
|
te.rendered_this_frame = false;
|
||||||
ts_min_next = std::min(ts_min_next, ts_next);
|
|
||||||
} else if (_cache.size() > min_count_before_purge && ts_now - te.timestamp_last_rendered >= ms_before_purge) {
|
} else if (_cache.size() > min_count_before_purge && ts_now - te.timestamp_last_rendered >= ms_before_purge) {
|
||||||
to_purge.push_back(key);
|
to_purge.push_back(key);
|
||||||
}
|
}
|
||||||
@ -151,10 +148,7 @@ struct TextureCache {
|
|||||||
|
|
||||||
invalidate(to_purge);
|
invalidate(to_purge);
|
||||||
|
|
||||||
// we ignore the default texture ts :)
|
|
||||||
_default_texture.doAnimation(ts_now);
|
_default_texture.doAnimation(ts_now);
|
||||||
|
|
||||||
return (ts_min_next - ts_now) / 1000.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidate(const std::vector<KeyType>& to_purge) {
|
void invalidate(const std::vector<KeyType>& to_purge) {
|
||||||
@ -168,22 +162,16 @@ struct TextureCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if there is still work queued up
|
void workLoadQueue(void) {
|
||||||
bool workLoadQueue(void) {
|
for (auto it = _to_load.begin(); it != _to_load.end(); it++) {
|
||||||
auto it = _to_load.begin();
|
|
||||||
for (; it != _to_load.end(); it++) {
|
|
||||||
auto new_entry_opt = _l.load(_tu, *it);
|
auto new_entry_opt = _l.load(_tu, *it);
|
||||||
if (new_entry_opt.has_value()) {
|
if (new_entry_opt.has_value()) {
|
||||||
_cache.emplace(*it, new_entry_opt.value());
|
_cache.emplace(*it, new_entry_opt.value());
|
||||||
it = _to_load.erase(it);
|
_to_load.erase(it);
|
||||||
|
// TODO: not a good idea
|
||||||
// TODO: not a good idea?
|
|
||||||
break; // end load from queue/onlyload 1 per update
|
break; // end load from queue/onlyload 1 per update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// peak
|
|
||||||
return it != _to_load.end();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user