notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit 418e08541d9ccd8a4518ae032f59361c4a097457
parent f36390d8f87ab4cbfc242ad31ac7f63b6661299f
Author: William Casarin <jb55@jb55.com>
Date:   Sat, 29 Mar 2025 10:08:49 -0700

notedeck: include frame history

for debugging.

Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mcrates/notedeck/src/app.rs | 11++++++++---
Mcrates/notedeck/src/context.rs | 5+++--
Acrates/notedeck/src/frame_history.rs | 48++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/notedeck/src/lib.rs | 1+
Mcrates/notedeck_chrome/src/chrome.rs | 18++++++++++++------
Dcrates/notedeck_columns/src/frame_history.rs | 50--------------------------------------------------
Mcrates/notedeck_columns/src/lib.rs | 1-
Mcrates/notedeck_columns/src/ui/accounts.rs | 2+-
Mcrates/notedeck_columns/src/ui/images.rs | 1+
Mcrates/notedeck_columns/src/ui/relay.rs | 2+-
Mcrates/notedeck_columns/src/ui/timeline.rs | 6+++++-
Mcrates/notedeck_dave/src/avatar.rs | 1+
Mcrates/notedeck_ui/src/lib.rs | 2+-
13 files changed, 82 insertions(+), 66 deletions(-)

diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs @@ -2,8 +2,8 @@ use crate::persist::{AppSizeHandler, ZoomHandler}; use crate::wallet::GlobalWallet; use crate::zaps::Zaps; use crate::{ - AccountStorage, Accounts, AppContext, Args, DataPath, DataPathType, Directory, Images, - NoteCache, RelayDebugView, ThemeHandler, UnknownIds, + frame_history::FrameHistory, AccountStorage, Accounts, AppContext, Args, DataPath, + DataPathType, Directory, Images, NoteCache, RelayDebugView, ThemeHandler, UnknownIds, }; use egui::ThemePreference; use egui_winit::clipboard::Clipboard; @@ -37,6 +37,7 @@ pub struct Notedeck { unrecognized_args: BTreeSet<String>, clipboard: Clipboard, zaps: Zaps, + frame_history: FrameHistory, } /// Our chrome, which is basically nothing @@ -79,8 +80,10 @@ fn render_notedeck(notedeck: &mut Notedeck, ctx: &egui::Context) { } impl eframe::App for Notedeck { - fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { + fn update(&mut self, ctx: &egui::Context, frame: &mut eframe::Frame) { profiling::finish_frame!(); + self.frame_history + .on_new_frame(ctx.input(|i| i.time), frame.info().cpu_usage); // handle account updates self.accounts.update(&mut self.ndb, &mut self.pool, ctx); @@ -227,6 +230,7 @@ impl Notedeck { zoom, app_size, unrecognized_args, + frame_history: FrameHistory::default(), clipboard: Clipboard::new(None), zaps, } @@ -251,6 +255,7 @@ impl Notedeck { theme: &mut self.theme, clipboard: &mut self.clipboard, zaps: &mut self.zaps, + frame_history: &mut self.frame_history, } } diff --git a/crates/notedeck/src/context.rs b/crates/notedeck/src/context.rs @@ -1,6 +1,6 @@ use crate::{ - wallet::GlobalWallet, zaps::Zaps, Accounts, Args, DataPath, Images, NoteCache, ThemeHandler, - UnknownIds, + frame_history::FrameHistory, wallet::GlobalWallet, zaps::Zaps, Accounts, Args, DataPath, + Images, NoteCache, ThemeHandler, UnknownIds, }; use egui_winit::clipboard::Clipboard; @@ -22,4 +22,5 @@ pub struct AppContext<'a> { pub theme: &'a mut ThemeHandler, pub clipboard: &'a mut Clipboard, pub zaps: &'a mut Zaps, + pub frame_history: &'a mut FrameHistory, } diff --git a/crates/notedeck/src/frame_history.rs b/crates/notedeck/src/frame_history.rs @@ -0,0 +1,48 @@ +use egui::util::History; + +pub struct FrameHistory { + frame_times: History<f32>, +} + +impl Default for FrameHistory { + fn default() -> Self { + let max_age: f32 = 1.0; + let max_len = (max_age * 300.0).round() as usize; + Self { + frame_times: History::new(0..max_len, max_age), + } + } +} + +impl FrameHistory { + // Called first + pub fn on_new_frame(&mut self, now: f64, previous_frame_time: Option<f32>) { + let previous_frame_time = previous_frame_time.unwrap_or_default(); + if let Some(latest) = self.frame_times.latest_mut() { + *latest = previous_frame_time; // rewrite history now that we know + } + self.frame_times.add(now, previous_frame_time); // projected + } + + #[allow(unused)] + pub fn mean_frame_time(&self) -> f32 { + self.frame_times.average().unwrap_or_default() + } + + #[allow(unused)] + pub fn fps(&self) -> f32 { + 1.0 / self.frame_times.mean_time_interval().unwrap_or_default() + } + + pub fn _ui(&mut self, ui: &mut egui::Ui) { + ui.label(format!( + "Mean CPU usage: {:.2} ms / frame", + 1e3 * self.mean_frame_time() + )) + .on_hover_text( + "Includes egui layout and tessellation time.\n\ + Does not include GPU usage, nor overhead for sending data to GPU.", + ); + egui::warn_if_debug_build(ui); + } +} diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs @@ -6,6 +6,7 @@ pub mod debouncer; mod error; pub mod filter; pub mod fonts; +mod frame_history; mod imgcache; mod muted; pub mod note; diff --git a/crates/notedeck_chrome/src/chrome.rs b/crates/notedeck_chrome/src/chrome.rs @@ -177,18 +177,24 @@ impl Chrome { } }; - if support_button(ui).clicked() { - return Some(ChromePanelAction::Support); - } - - if theme_action.is_some() { - return theme_action; + let support_resp = support_button(ui); + + if ctx.args.debug { + ui.weak(format!("{}", ctx.frame_history.fps() as i32)); + ui.weak(format!( + "{:10.1}", + ctx.frame_history.mean_frame_time() * 1e3 + )); } if pfp_resp.clicked() { Some(ChromePanelAction::Account) } else if settings_resp.clicked() { Some(ChromePanelAction::Settings) + } else if theme_action.is_some() { + theme_action + } else if support_resp.clicked() { + Some(ChromePanelAction::Support) } else { None } diff --git a/crates/notedeck_columns/src/frame_history.rs b/crates/notedeck_columns/src/frame_history.rs @@ -1,50 +0,0 @@ -/* -use egui::util::History; - -pub struct FrameHistory { - frame_times: History<f32>, -} - -impl Default for FrameHistory { - fn default() -> Self { - let max_age: f32 = 1.0; - let max_len = (max_age * 300.0).round() as usize; - Self { - frame_times: History::new(0..max_len, max_age), - } - } -} - -impl FrameHistory { - // Called first - pub fn on_new_frame(&mut self, now: f64, previous_frame_time: Option<f32>) { - let previous_frame_time = previous_frame_time.unwrap_or_default(); - if let Some(latest) = self.frame_times.latest_mut() { - *latest = previous_frame_time; // rewrite history now that we know - } - self.frame_times.add(now, previous_frame_time); // projected - } - - #[allow(unused)] - pub fn mean_frame_time(&self) -> f32 { - self.frame_times.average().unwrap_or_default() - } - - #[allow(unused)] - pub fn fps(&self) -> f32 { - 1.0 / self.frame_times.mean_time_interval().unwrap_or_default() - } - - pub fn _ui(&mut self, ui: &mut egui::Ui) { - ui.label(format!( - "Mean CPU usage: {:.2} ms / frame", - 1e3 * self.mean_frame_time() - )) - .on_hover_text( - "Includes egui layout and tessellation time.\n\ - Does not include GPU usage, nor overhead for sending data to GPU.", - ); - egui::warn_if_debug_build(ui); - } -} -*/ diff --git a/crates/notedeck_columns/src/lib.rs b/crates/notedeck_columns/src/lib.rs @@ -13,7 +13,6 @@ mod column; mod deck_state; mod decks; mod draft; -mod frame_history; mod key_parsing; pub mod login_manager; mod media_upload; diff --git a/crates/notedeck_columns/src/ui/accounts.rs b/crates/notedeck_columns/src/ui/accounts.rs @@ -1,9 +1,9 @@ -use notedeck_ui::colors::PINK; use egui::{ Align, Button, Frame, Image, InnerResponse, Layout, RichText, ScrollArea, Ui, UiBuilder, Vec2, }; use nostrdb::{Ndb, Transaction}; use notedeck::{Accounts, Images}; +use notedeck_ui::colors::PINK; use super::profile::preview::SimpleProfilePreview; diff --git a/crates/notedeck_columns/src/ui/images.rs b/crates/notedeck_columns/src/ui/images.rs @@ -0,0 +1 @@ + diff --git a/crates/notedeck_columns/src/ui/relay.rs b/crates/notedeck_columns/src/ui/relay.rs @@ -1,11 +1,11 @@ use std::collections::HashMap; -use notedeck_ui::colors::PINK; use crate::relay_pool_manager::{RelayPoolManager, RelayStatus}; use crate::ui::{Preview, PreviewConfig, View}; use egui::{ Align, Button, CornerRadius, Frame, Id, Image, Layout, Margin, Rgba, RichText, Ui, Vec2, }; +use notedeck_ui::colors::PINK; use enostr::RelayPool; use notedeck::{Accounts, NotedeckTextStyle}; diff --git a/crates/notedeck_columns/src/ui/timeline.rs b/crates/notedeck_columns/src/ui/timeline.rs @@ -193,7 +193,11 @@ fn goto_top_button(center: Pos2) -> impl egui::Widget { }); let painter = ui.painter(); - painter.circle_filled(center, helper.scale_1d_pos(radius), notedeck_ui::colors::PINK); + painter.circle_filled( + center, + helper.scale_1d_pos(radius), + notedeck_ui::colors::PINK, + ); let create_pt = |angle: f32| { let side = radius / 2.0; diff --git a/crates/notedeck_dave/src/avatar.rs b/crates/notedeck_dave/src/avatar.rs @@ -352,6 +352,7 @@ impl DaveAvatar { .multiply(&z_rotation) .multiply(&self.rotation); + tracing::trace!("repainting due to avatar rotation"); ui.ctx().request_repaint(); } } diff --git a/crates/notedeck_ui/src/lib.rs b/crates/notedeck_ui/src/lib.rs @@ -1,9 +1,9 @@ mod anim; pub mod colors; pub mod gif; +pub mod icons; pub mod images; pub mod profile; -pub mod icons; pub use anim::AnimationHelper; pub use profile::ProfilePic;