From a2fd75ec1407e8261a0abbd4a8981eaa56b51243 Mon Sep 17 00:00:00 2001 From: Kyle Chong Date: Wed, 5 Aug 2026 12:17:30 -0700 Subject: [PATCH 1/3] Add Fast DU setting --- app-core/src/lib.rs | 51 +++++++++++++++++++++++++++++++-- display/src/epd/ssd1677.rs | 8 +++++- fw/src/display_flush/ssd1677.rs | 5 ++-- fw/src/display_flush/uc8253.rs | 1 + fw/src/tasks/display.rs | 7 +++++ proto/src/nvm.rs | 24 ++++++++++++---- 6 files changed, 86 insertions(+), 10 deletions(-) diff --git a/app-core/src/lib.rs b/app-core/src/lib.rs index 6270194b..ac82b54d 100644 --- a/app-core/src/lib.rs +++ b/app-core/src/lib.rs @@ -10,7 +10,7 @@ pub mod buttons; /// The storage/display task's command loop, as sequences a host test can drive. pub mod storage_loop; -pub const SETTINGS_ITEMS: u8 = 7; +pub const SETTINGS_ITEMS: u8 = 8; pub const MAX_SD_CHAPTERS: usize = 128; pub const FIRST_SD_BOOK_ID: u32 = 2; @@ -135,6 +135,12 @@ pub enum FrontButtons { PagesLeft, } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum RefreshQuality { + Normal, + Fast, +} + #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum RefreshPolicy { FastOnly, @@ -314,6 +320,7 @@ pub struct RenderRequest { /// sheet, relabel the key rail, and show the wait or its note. pub library_menu: LibraryMenu, pub refresh_policy: RefreshPolicy, + pub refresh_quality: RefreshQuality, pub font_size: FontSize, pub line_spacing: LineSpacing, pub font_weight: FontWeight, @@ -1322,6 +1329,7 @@ pub enum LibraryEvent { page_count: u32, reading_orientation: u8, refresh_policy: u8, + refresh_quality: u8, font_size: u8, line_spacing: u8, font_weight: u8, @@ -1835,6 +1843,7 @@ pub struct ReaderState { pub orientation: DisplayOrientation, pub front_buttons: FrontButtons, pub refresh_policy: RefreshPolicy, + pub refresh_quality: RefreshQuality, pub font_size: FontSize, pub line_spacing: LineSpacing, pub font_weight: FontWeight, @@ -1890,6 +1899,7 @@ impl ReaderState { orientation: DisplayOrientation::PortraitButtonsLeft, front_buttons: FrontButtons::PagesRight, refresh_policy: RefreshPolicy::FullOnWake, + refresh_quality: RefreshQuality::Normal, font_size: FontSize::Medium, line_spacing: LineSpacing::Normal, font_weight: FontWeight::Normal, @@ -2383,6 +2393,7 @@ impl ReaderState { page_count, reading_orientation, refresh_policy, + refresh_quality, font_size, line_spacing, font_weight, @@ -2416,6 +2427,9 @@ impl ReaderState { if let Some(policy) = refresh_policy_from_u8(refresh_policy) { self.refresh_policy = policy; } + if let Some(quality) = refresh_quality_from_u8(refresh_quality) { + self.refresh_quality = quality; + } if let Some(size) = FontSize::from_u8(font_size) { self.font_size = size; } @@ -2499,6 +2513,7 @@ impl ReaderState { reading_sheet: self.reading_sheet, library_menu: self.library_menu, refresh_policy: self.refresh_policy, + refresh_quality: self.refresh_quality, font_size: self.font_size, line_spacing: self.line_spacing, font_weight: self.font_weight, @@ -2658,6 +2673,14 @@ pub fn refresh_policy_from_u8(value: u8) -> Option { } } +pub fn refresh_quality_from_u8(value: u8) -> Option { + match value { + 0 => Some(RefreshQuality::Normal), + 1 => Some(RefreshQuality::Fast), + _ => None, + } +} + fn wrap_next(value: u16, len: u16) -> u16 { if value + 1 >= len { 0 @@ -2809,6 +2832,12 @@ fn apply_setting(mut state: ReaderState) -> ReaderState { FrontButtons::PagesLeft => FrontButtons::PagesRight, }; } + 7 => { + state.refresh_quality = match state.refresh_quality { + RefreshQuality::Normal => RefreshQuality::Fast, + RefreshQuality::Fast => RefreshQuality::Normal, + }; + } _ => {} } state @@ -3501,7 +3530,7 @@ mod tests { // 16 bytes and the planner's stored request four. Recorded because // `.bss` trades one-for-one against the main stack region on this // target, so a struct in a channel is never free. - assert_eq!(core::mem::size_of::(), 112); + assert_eq!(core::mem::size_of::(), 120); assert!( core::mem::size_of::() < core::mem::size_of::(), "the departing state has outgrown the credentials variant", @@ -4000,6 +4029,7 @@ mod tests { page_count: 0, reading_orientation: 0, refresh_policy: 0, + refresh_quality: 0, font_size: 0, line_spacing: 0, font_weight: 0, @@ -4846,6 +4876,7 @@ mod tests { page_count: 0, reading_orientation: DisplayOrientation::LandscapeButtonsBottom as u8, refresh_policy: RefreshPolicy::FullOnWake as u8, + refresh_quality: RefreshQuality::Normal as u8, font_size: FontSize::Medium as u8, line_spacing: LineSpacing::Normal as u8, font_weight: FontWeight::Normal as u8, @@ -4893,6 +4924,7 @@ mod tests { page_count: 0, reading_orientation: DisplayOrientation::LandscapeButtonsBottom as u8, refresh_policy: RefreshPolicy::FullOnWake as u8, + refresh_quality: RefreshQuality::Normal as u8, font_size: FontSize::Medium as u8, line_spacing: LineSpacing::Normal as u8, font_weight: FontWeight::Normal as u8, @@ -4968,9 +5000,23 @@ mod tests { let state = press(state, Button::Next); assert_eq!(state.selection, 6); let state = press(state, Button::Next); + assert_eq!(state.selection, 7); + let state = press(state, Button::Next); assert_eq!(state.selection, 0, "selection wraps after the last row"); } + #[test] + fn settings_change_key_toggles_refresh_quality() { + let mut state = press(ReaderState::boot(), Button::Next); + state.selection = 7; + + let state = press(state, Button::Confirm); + assert_eq!(state.refresh_quality, RefreshQuality::Fast); + + let state = press(state, Button::Confirm); + assert_eq!(state.refresh_quality, RefreshQuality::Normal); + } + #[test] fn settings_change_key_toggles_front_buttons() { let mut state = press(ReaderState::boot(), Button::Next); @@ -5188,6 +5234,7 @@ mod tests { page_count: 0, reading_orientation: DisplayOrientation::PortraitButtonsRight as u8, refresh_policy: RefreshPolicy::FastOnly as u8, + refresh_quality: RefreshQuality::Fast as u8, font_size: FontSize::Large as u8, line_spacing: LineSpacing::Compact as u8, font_weight: FontWeight::Normal as u8, diff --git a/display/src/epd/ssd1677.rs b/display/src/epd/ssd1677.rs index 860ec0c4..93f13ccc 100644 --- a/display/src/epd/ssd1677.rs +++ b/display/src/epd/ssd1677.rs @@ -130,7 +130,12 @@ pub const fn ram_y_counter(rect: Rect) -> [u8; 2] { [bottom as u8, (bottom >> 8) as u8] } -pub const fn update_control_2(mode: RefreshMode, screen_is_on: bool, turn_off: bool) -> u8 { +pub const fn update_control_2( + mode: RefreshMode, + screen_is_on: bool, + turn_off: bool, + fast_du: bool, +) -> u8 { let mut value = 0; if !screen_is_on { value |= 0xC0; @@ -140,6 +145,7 @@ pub const fn update_control_2(mode: RefreshMode, screen_is_on: bool, turn_off: b } match mode { RefreshMode::Full => value | 0x34, + RefreshMode::Fast if fast_du => value | 0x18, RefreshMode::Fast => value | 0x1C, // Load LUT (display mode 1) + display, deliberately without the // 0x20 load-temperature bit so the FAST_CLEAN_TEMPERATURE override diff --git a/fw/src/display_flush/ssd1677.rs b/fw/src/display_flush/ssd1677.rs index fb9a62a2..5d026b52 100644 --- a/fw/src/display_flush/ssd1677.rs +++ b/fw/src/display_flush/ssd1677.rs @@ -30,6 +30,7 @@ pub(crate) async fn flush( screen_on: bool, mode: RefreshMode, prev_staged: bool, + fast_du: bool, ) -> Result<(), PanelError> { let bw_start = Instant::now(); write_ram(epd, CMD_WRITE_RAM_BW, fb).await?; @@ -69,7 +70,7 @@ pub(crate) async fn flush( .await?; epd.command( CMD_DISPLAY_UPDATE_CTRL2, - &[update_control_2(mode, screen_on, false)], + &[update_control_2(mode, screen_on, false, fast_du)], ) .await?; epd.command(CMD_MASTER_ACTIVATION, &[]).await?; @@ -111,7 +112,7 @@ pub(crate) async fn sleep_panel(epd: &mut Epd) -> Result<(), PanelError> { ); epd.command( CMD_DISPLAY_UPDATE_CTRL2, - &[update_control_2(RefreshMode::PowerDown, true, false)], + &[update_control_2(RefreshMode::PowerDown, true, false, false)], ) .await?; epd.command(CMD_MASTER_ACTIVATION, &[]).await?; diff --git a/fw/src/display_flush/uc8253.rs b/fw/src/display_flush/uc8253.rs index 1499cbe3..af9d0cb4 100644 --- a/fw/src/display_flush/uc8253.rs +++ b/fw/src/display_flush/uc8253.rs @@ -67,6 +67,7 @@ pub(crate) async fn flush( _screen_on: bool, mode: RefreshMode, prev_staged: bool, + _fast_du: bool, ) -> Result<(), PanelError> { let plan = flush_plan(mode, SCREEN_POWERED.load(Ordering::Relaxed), prev_staged); bench_log!( diff --git a/fw/src/tasks/display.rs b/fw/src/tasks/display.rs index 47f776da..40ecc618 100644 --- a/fw/src/tasks/display.rs +++ b/fw/src/tasks/display.rs @@ -446,6 +446,7 @@ pub async fn run(mut epd: Epd, mut sd_cs: Output<'static>, deep_sleep_wake: bool refresh_planner.screen_on(), mode, prev_prestaged, + request.refresh_quality == app_core::RefreshQuality::Fast, ) .await .is_ok() @@ -692,6 +693,7 @@ pub async fn run(mut epd: Epd, mut sd_cs: Output<'static>, deep_sleep_wake: bool refresh_planner.screen_on(), RefreshMode::Full, prev_prestaged, + false, ) .await .is_ok() @@ -812,6 +814,7 @@ pub async fn run(mut epd: Epd, mut sd_cs: Output<'static>, deep_sleep_wake: bool refresh_planner.screen_on(), mode, prev_prestaged, + loading_request.refresh_quality == app_core::RefreshQuality::Fast, ) .await .is_ok() @@ -2035,6 +2038,7 @@ fn record_for_persisted(library: &ReaderStore, state: PersistedAppState) -> AppS shell_orientation: state.shell_orientation, reading_orientation: state.reading_orientation, refresh_policy: state.refresh_policy, + refresh_quality: state.refresh_quality, font_size: state.font_size, line_spacing: state.line_spacing, font_weight: state.font_weight, @@ -2135,6 +2139,7 @@ fn restore_saved_state( page_count, reading_orientation: record.reading_orientation, refresh_policy: record.refresh_policy, + refresh_quality: record.refresh_quality, font_size: record.font_size, line_spacing: record.line_spacing, font_weight: record.font_weight, @@ -2190,6 +2195,8 @@ fn sleep_request_from_saved_state( library_menu: app_core::LibraryMenu::None, refresh_policy: refresh_policy_from_u8(record.refresh_policy) .unwrap_or(app_core::RefreshPolicy::FullOnWake), + refresh_quality: app_core::refresh_quality_from_u8(record.refresh_quality) + .unwrap_or(app_core::RefreshQuality::Normal), font_size: display::font::FontSize::from_u8(record.font_size) .unwrap_or(display::font::FontSize::Medium), line_spacing: display::font::LineSpacing::from_u8(record.line_spacing) diff --git a/proto/src/nvm.rs b/proto/src/nvm.rs index 834590bd..62e2c89d 100644 --- a/proto/src/nvm.rs +++ b/proto/src/nvm.rs @@ -17,6 +17,7 @@ pub struct AppStateRecord { pub font_weight: u8, pub font_family: u8, pub front_buttons: u8, + pub refresh_quality: u8, pub source_hash: u32, pub source_size: u32, } @@ -26,7 +27,8 @@ impl AppStateRecord { const V3_ENCODED_LEN: usize = 32; const V1_ENCODED_LEN: usize = 24; const MAGIC: u32 = 0x5834_4F53; - const VERSION: u8 = 4; + const VERSION: u8 = 5; + const V4_VERSION: u8 = 4; const V3_VERSION: u8 = 3; const V2_VERSION: u8 = 2; const V1_VERSION: u8 = 1; @@ -50,6 +52,7 @@ impl AppStateRecord { font_weight: Self::DEFAULT_FONT_WEIGHT, font_family: Self::DEFAULT_FONT_FAMILY, front_buttons: 0, + refresh_quality: 0, source_hash: 0, source_size: 0, } @@ -73,10 +76,12 @@ impl AppStateRecord { // reserved tail. The font family later took reserved byte 29 and the // front-button layout byte 30: records written before either carry // zero there, which is the respective default (Literata, pages - // right), so no version bump was needed. Byte 31 stays reserved zero. + // right), so no version bump was needed. + // V5 adds refresh_quality at byte 31. out[28] = self.font_weight; out[29] = self.font_family; out[30] = self.front_buttons; + out[31] = self.refresh_quality; let checksum = checksum(&out[..32]); write_u32(&mut out, 32, checksum); out @@ -90,7 +95,7 @@ impl AppStateRecord { return None; } match bytes[4] { - Self::VERSION => { + Self::VERSION | Self::V4_VERSION => { if bytes.len() < Self::ENCODED_LEN { return None; } @@ -98,6 +103,11 @@ impl AppStateRecord { if checksum(&bytes[..32]) != expected { return None; } + let refresh_quality = if bytes[4] == Self::VERSION { + bytes[31] + } else { + 0 + }; Some(Self { book_id: read_u32(bytes, 8), chapter: read_u16(bytes, 12), @@ -110,6 +120,7 @@ impl AppStateRecord { font_weight: bytes[28], font_family: bytes[29], front_buttons: bytes[30], + refresh_quality, source_hash: read_u32(bytes, 18), source_size: read_u32(bytes, 22), }) @@ -139,6 +150,7 @@ impl AppStateRecord { font_weight: Self::DEFAULT_FONT_WEIGHT, font_family: Self::DEFAULT_FONT_FAMILY, front_buttons: 0, + refresh_quality: 0, source_hash: read_u32(bytes, 18), source_size: read_u32(bytes, 22), }) @@ -160,6 +172,7 @@ impl AppStateRecord { font_weight: Self::DEFAULT_FONT_WEIGHT, font_family: Self::DEFAULT_FONT_FAMILY, front_buttons: 0, + refresh_quality: 0, source_hash: 0, source_size: 0, }) @@ -344,6 +357,7 @@ mod tests { shell_orientation: 2, reading_orientation: 1, refresh_policy: 2, + refresh_quality: 1, font_size: 2, line_spacing: 0, font_weight: 1, @@ -363,9 +377,9 @@ mod tests { /// two firmwares, and every compatibility test in this module would still /// pass if the whole envelope shifted underneath them in lockstep. const STATE_GOLDEN: [u8; AppStateRecord::ENCODED_LEN] = [ - 0x53, 0x4f, 0x34, 0x58, 0x04, 0x02, 0x01, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, + 0x53, 0x4f, 0x34, 0x58, 0x05, 0x02, 0x01, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xad, 0xde, 0x40, 0xe2, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, - 0x01, 0x00, 0xa7, 0x76, 0x1e, 0x60, + 0x01, 0x01, 0xb1, 0x1b, 0xaa, 0xd8, ]; #[test] From 2fc356a629000aa817fd50f87d11b4773f8441a6 Mon Sep 17 00:00:00 2001 From: Kyle Chong Date: Wed, 5 Aug 2026 12:39:15 -0700 Subject: [PATCH 2/3] Fix CI failure: add refresh_quality to PersistedAppState and fix emulator args --- app-core/src/lib.rs | 3 +++ app-core/src/storage_loop.rs | 2 ++ tools/emulator/src/panel.rs | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app-core/src/lib.rs b/app-core/src/lib.rs index ac82b54d..cea21607 100644 --- a/app-core/src/lib.rs +++ b/app-core/src/lib.rs @@ -1809,6 +1809,7 @@ pub struct PersistedAppState { pub shell_orientation: u8, pub reading_orientation: u8, pub refresh_policy: u8, + pub refresh_quality: u8, pub font_size: u8, pub line_spacing: u8, pub font_weight: u8, @@ -2542,6 +2543,7 @@ impl ReaderState { shell_orientation: DisplayOrientation::PortraitButtonsLeft as u8, reading_orientation: self.orientation as u8, refresh_policy: self.refresh_policy as u8, + refresh_quality: self.refresh_quality as u8, font_size: self.font_size as u8, line_spacing: self.line_spacing as u8, font_weight: self.font_weight as u8, @@ -5534,6 +5536,7 @@ mod tests { shell_orientation: 0, reading_orientation: 0, refresh_policy: 0, + refresh_quality: 0, font_size: 0, line_spacing: 0, font_weight: 0, diff --git a/app-core/src/storage_loop.rs b/app-core/src/storage_loop.rs index 8785e419..9eb94fe2 100644 --- a/app-core/src/storage_loop.rs +++ b/app-core/src/storage_loop.rs @@ -626,6 +626,7 @@ impl OpenSequence { shell_orientation: 0, reading_orientation: 0, refresh_policy: 0, + refresh_quality: 0, font_size: 0, line_spacing: 0, font_weight: 0, @@ -756,6 +757,7 @@ mod tests { shell_orientation: 1, reading_orientation: 2, refresh_policy: 3, + refresh_quality: 0, font_size: 4, line_spacing: 5, font_weight: 6, diff --git a/tools/emulator/src/panel.rs b/tools/emulator/src/panel.rs index c32dd2ae..5f125bf3 100644 --- a/tools/emulator/src/panel.rs +++ b/tools/emulator/src/panel.rs @@ -135,7 +135,7 @@ impl PanelModel { )?; self.command( CMD_DISPLAY_UPDATE_CTRL2, - &[display::epd::update_control_2(mode, true, false)], + &[display::epd::update_control_2(mode, true, false, false)], )?; self.command(CMD_MASTER_ACTIVATION, &[])?; if mode == RefreshMode::FastClean { @@ -158,6 +158,7 @@ impl PanelModel { RefreshMode::PowerDown, true, false, + false, )], )?; self.command(CMD_MASTER_ACTIVATION, &[])?; From 7463c78a6eeda10f37b335086a0dec34babce264 Mon Sep 17 00:00:00 2001 From: Kyle Chong Date: Wed, 5 Aug 2026 14:25:36 -0700 Subject: [PATCH 3/3] Fix Fast DU setting review findings - Swap ssd1677 Fast refresh branches to correctly use 0x1C shortcut - Safely expand Settings UI to 8 rows by reducing SETTINGS_ROW_STEP - Revert AppStateRecord to V4 and use reserved byte 31 for compatibility - Update UI goldens for X4 and X3 targets --- display/src/epd/ssd1677.rs | 20 ++++++++++++++++++-- fixtures/golden/landscape-settings-x3.png | Bin 19487 -> 21490 bytes fixtures/golden/landscape-settings.png | Bin 19162 -> 21177 bytes fixtures/golden/settings-type-x3.png | Bin 17276 -> 18995 bytes fixtures/golden/settings-type.png | Bin 16763 -> 18445 bytes proto/src/nvm.rs | 20 +++++++------------- tools/preview/src/main.rs | 1 + ui/src/app_render.rs | 8 ++++++++ ui/src/lib.rs | 8 ++++++++ ui/src/render.rs | 21 ++++++++++++++++----- 10 files changed, 58 insertions(+), 20 deletions(-) diff --git a/display/src/epd/ssd1677.rs b/display/src/epd/ssd1677.rs index 93f13ccc..c97f0585 100644 --- a/display/src/epd/ssd1677.rs +++ b/display/src/epd/ssd1677.rs @@ -145,8 +145,8 @@ pub const fn update_control_2( } match mode { RefreshMode::Full => value | 0x34, - RefreshMode::Fast if fast_du => value | 0x18, - RefreshMode::Fast => value | 0x1C, + RefreshMode::Fast if fast_du => value | 0x1C, + RefreshMode::Fast => value | 0x18, // Load LUT (display mode 1) + display, deliberately without the // 0x20 load-temperature bit so the FAST_CLEAN_TEMPERATURE override // written via 0x1A decides which OTP waveform runs. @@ -165,3 +165,19 @@ pub const fn update_control_1(mode: RefreshMode) -> [u8; 2] { pub const fn is_byte_aligned(rect: Rect) -> bool { rect.x & 7 == 0 && rect.w & 7 == 0 && rect.w > 0 && rect.h > 0 && rect.x < WIDTH as u16 } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_update_control_2_fast_du() { + // Fast with fast_du = true uses 0x1C (the DU shortcut). + assert_eq!(update_control_2(RefreshMode::Fast, true, false, true), 0x1C); + // Fast with fast_du = false uses 0x18 (the stock temperature-compensated sequence). + assert_eq!( + update_control_2(RefreshMode::Fast, true, false, false), + 0x18 + ); + } +} diff --git a/fixtures/golden/landscape-settings-x3.png b/fixtures/golden/landscape-settings-x3.png index 14eab6d041f47327047ed5ca1bae0f168f7160d2..734f94f5983e62fb9ffff383927a0c3183801580 100644 GIT binary patch literal 21490 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 literal 19487 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 diff --git a/fixtures/golden/landscape-settings.png b/fixtures/golden/landscape-settings.png index 385c66f051e7767df5f5b13b41de9342b4889157..32f2ab0cca4d170e48b0a87f8edba6fc85419d76 100644 GIT binary patch literal 21177 zcmdsFLqgxBvPFHhq1nxbB%x|JOI}y84}~hp&44OX=^= z|9)`O?{6D?+z+fJ$DamEHCRXA6h!t$+V93J$d)Q?De|z;dKWpy$334 zQ2EhYnQ3vZIw|!o8mQdXdVKq-54F!*uTB_4-L}phs04e8C5)ne=(2o>$698s+_QD4 zI-;It@435u9_@Ej^w;}f5cg>{+M%m@iqS+sa}aPrB4DFNp}&?_xTj7v)MV86Jg8m1 zVewz@>MGjWH;q5L^zxVOpVhr`dezf+k5+n@wa%SfTKz}=f7R`Cd#>Hp_wUSnGn~;# ztM=VJ2`xtlZgLm9AnFGFV`|mk$zQ(q`I(RU?%A62Y(M+A^=Dtpg-5Sf*PZ8ld9=82 zVBbCEHIJ=s>RniBU$AFQX`p$}8jjJ`8@S$9UftAMzG9%cwY+*ScU$L7u5h#7g`;}v z37({V&-4?mb4##qa%u0P_IWxG;rjBdcCnx|P`P1X-yZ`wsRPlqc47M_w?E}E z52T)YlDyF@^eEH}3B4p2daLN3*dop9N9C41gN7ekihdl@RSP(M^xmmU!;<{V> z`m^f77U>buUD2Vj)3@2^zYIhlgHLJH^VHnNB9hXbAOnrxJ#Xcn;&zmHlZY>&i9FkI zSRqOp{J|vQ5=0!fP|>Zr=qJA;k#8!m*>%l2E0&lk{W`#?j33|BbLGPJ!)w}i>dEfZ zt)A>S92|%~rVeggJlXe%R9UyA-fI`uMuiROSTkapV|omMIW3kTpuciYNJCoP-hW&S zePOybh*LGehA@#YBKHK;>Fzm+UoejmkmvRTOs~$ipTshZbf2s?*mi4&Y#E6L-yuCY z1NyZ+-qt#|T^?0tiuynYM`~sN@$pBRtMg&G8130JV;XZeAJ1Th44e6fNkYnV8EcZ{ zCCtXeP5e`kB-?lhUoN87o=Q}sh8;a}v30-aaE&O*2k-k+5+yehN^go6w3fTZesFiY zY!X@$Ik_{K?+Hthzf_);qC<`3WXSNPukE87ijA5au?r??CeKK~FM_o2Y_>;8GY>z$ zu)E`~nh9F*lRlU%{DLjAb-$+|)v?t=w5WQ1`tV4}K}U$pGnPEVML$QL`9fx2Qnwm? zF(mOW%$xvw$gv;{)eb|AlG*AT;U0^U%7>!Y%>Z+`G`ytsMWIrP2%|AM88uW83pldM z;XP8AN`Zp7&?^=`vbs%rS|*&WwKo*;jlL(%#huA#_^~Hw-DVf5+l kLqJ&zGCOa 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 QDc`aDvP*{F^1)C1FGoxh%K!iX literal 19162 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 ayXgK8ee+|t@z literal 17276 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 diff --git a/fixtures/golden/settings-type.png b/fixtures/golden/settings-type.png index 997835af9067197276ca4d9eeaac1e0b792080cc..411e2d761c19f5b219372b7b4426f665a5a32005 100644 GIT binary patch literal 18445 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 V=eB%Af9L1o*_U3>GwZ6G{ujuh1{weW literal 16763 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 { + Self::VERSION => { if bytes.len() < Self::ENCODED_LEN { return None; } @@ -103,11 +102,6 @@ impl AppStateRecord { if checksum(&bytes[..32]) != expected { return None; } - let refresh_quality = if bytes[4] == Self::VERSION { - bytes[31] - } else { - 0 - }; Some(Self { book_id: read_u32(bytes, 8), chapter: read_u16(bytes, 12), @@ -120,7 +114,7 @@ impl AppStateRecord { font_weight: bytes[28], font_family: bytes[29], front_buttons: bytes[30], - refresh_quality, + refresh_quality: bytes[31], source_hash: read_u32(bytes, 18), source_size: read_u32(bytes, 22), }) @@ -377,9 +371,9 @@ mod tests { /// two firmwares, and every compatibility test in this module would still /// pass if the whole envelope shifted underneath them in lockstep. const STATE_GOLDEN: [u8; AppStateRecord::ENCODED_LEN] = [ - 0x53, 0x4f, 0x34, 0x58, 0x05, 0x02, 0x01, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, + 0x53, 0x4f, 0x34, 0x58, 0x04, 0x02, 0x01, 0x02, 0x07, 0x00, 0x00, 0x00, 0x03, 0x00, 0x29, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xad, 0xde, 0x40, 0xe2, 0x01, 0x00, 0x02, 0x00, 0x01, 0x01, - 0x01, 0x01, 0xb1, 0x1b, 0xaa, 0xd8, + 0x01, 0x01, 0x14, 0x75, 0x1e, 0x5f, ]; #[test] diff --git a/tools/preview/src/main.rs b/tools/preview/src/main.rs index 7cb143a4..4caefb5e 100644 --- a/tools/preview/src/main.rs +++ b/tools/preview/src/main.rs @@ -1820,6 +1820,7 @@ fn write_shell_preview(out: &Path, name: &str, view: UiView, selection: u16) -> orientation: UiOrientation::PortraitButtonsLeft, front_pages_left: false, refresh_policy: UiRefreshPolicy::FullOnWake, + refresh_quality: ui::UiRefreshQuality::Normal, font_size: display::font::FontSize::Medium, line_spacing: display::font::LineSpacing::Normal, font_weight: display::font::FontWeight::Normal, diff --git a/ui/src/app_render.rs b/ui/src/app_render.rs index 82d3aa40..9be4b6c4 100644 --- a/ui/src/app_render.rs +++ b/ui/src/app_render.rs @@ -70,6 +70,7 @@ pub fn render_request(fb: &mut Framebuffer, request: RenderRequest, model: &UiRe orientation: ui_orientation(request.orientation), front_pages_left: request.front_buttons == FrontButtons::PagesLeft, refresh_policy: ui_refresh_policy(request.refresh_policy), + refresh_quality: ui_refresh_quality(request.refresh_quality), font_size: request.font_size, line_spacing: request.line_spacing, font_weight: request.font_weight, @@ -272,6 +273,13 @@ fn ui_refresh_policy(policy: RefreshPolicy) -> UiRefreshPolicy { } } +fn ui_refresh_quality(quality: app_core::RefreshQuality) -> crate::UiRefreshQuality { + match quality { + app_core::RefreshQuality::Normal => crate::UiRefreshQuality::Normal, + app_core::RefreshQuality::Fast => crate::UiRefreshQuality::Fast, + } +} + fn button_label(button: Button) -> &'static str { match button { Button::Power => "POWER", diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 410b051f..cd973cf5 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -37,6 +37,12 @@ pub enum UiRefreshPolicy { FullEveryTen, } +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UiRefreshQuality { + Normal, + Fast, +} + /// Wireless screen lifecycle, mirrored from app-core so the renderer stays /// decoupled from reducer types the way UiView mirrors AppView. #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -98,6 +104,7 @@ pub struct UiShell<'a> { /// of it; the key rail's labels follow the buttons. pub front_pages_left: bool, pub refresh_policy: UiRefreshPolicy, + pub refresh_quality: UiRefreshQuality, pub font_size: display::font::FontSize, pub line_spacing: display::font::LineSpacing, pub font_weight: display::font::FontWeight, @@ -154,6 +161,7 @@ mod tests { orientation: UiOrientation::PortraitButtonsRight, front_pages_left: false, refresh_policy: UiRefreshPolicy::FullEveryTen, + refresh_quality: UiRefreshQuality::Normal, font_size: Default::default(), line_spacing: Default::default(), font_weight: Default::default(), diff --git a/ui/src/render.rs b/ui/src/render.rs index 37ba289b..0f8ad035 100644 --- a/ui/src/render.rs +++ b/ui/src/render.rs @@ -8,8 +8,8 @@ //! only — the device does not tell time. use crate::{ - join_qr, UiLibraryStatus, UiOrientation, UiRefreshPolicy, UiShell, UiSyncStatus, UiTocItem, - UiView, + join_qr, UiLibraryStatus, UiOrientation, UiRefreshPolicy, UiRefreshQuality, UiShell, + UiSyncStatus, UiTocItem, UiView, }; use display::fb::{FbFrame, Framebuffer}; use display::font::{ @@ -698,10 +698,10 @@ fn render_settings(fb: &mut Framebuffer, shell: &UiShell<'_>) { dash_key(fb, layout, 3, "next", false); heading(fb, layout, "Settings"); - // Seven rows must clear the landscape footer line, so the settings + // Eight rows must clear the landscape footer line, so the settings // index runs tighter than the Library's ROW_STEP. - const SETTINGS_ROW_STEP: i16 = 52; - let rows: [(&str, &str); 7] = [ + const SETTINGS_ROW_STEP: i16 = 46; + let rows: [(&str, &str); 8] = [ ( "Typeface", font_family_label(shell.font_family, shell.custom_font_name), @@ -710,6 +710,10 @@ fn render_settings(fb: &mut Framebuffer, shell: &UiShell<'_>) { ("Type weight", font_weight_label(shell.font_weight)), ("Line spacing", line_spacing_label(shell.line_spacing)), ("Refresh", refresh_policy_label(shell.refresh_policy)), + ( + "Refresh quality", + refresh_quality_label(shell.refresh_quality), + ), ("Orientation", orientation_label(shell.orientation)), ("Front buttons", front_buttons_label(shell.front_pages_left)), ]; @@ -1363,6 +1367,13 @@ fn refresh_policy_label(policy: UiRefreshPolicy) -> &'static str { } } +fn refresh_quality_label(quality: UiRefreshQuality) -> &'static str { + match quality { + UiRefreshQuality::Normal => "normal", + UiRefreshQuality::Fast => "fast", + } +} + fn orientation_label(orientation: UiOrientation) -> &'static str { match orientation { UiOrientation::LandscapeButtonsBottom => "buttons down",