kobo_core/rendering/
eink.rs1pub const FBIOGET_VSCREENINFO: libc::c_ulong = 0x4600;
8pub const FBIOGET_FSCREENINFO: libc::c_ulong = 0x4602;
9pub const MXCFB_SEND_UPDATE: libc::c_ulong = 0x4024462E;
10
11#[repr(C)]
12#[derive(Default)]
13pub struct FbVarScreeninfo {
14 pub xres: u32,
15 pub yres: u32,
16 pub xres_virtual: u32,
17 pub yres_virtual: u32,
18 pub xoffset: u32,
19 pub yoffset: u32,
20 pub bits_per_pixel: u32,
21 pub grayscale: u32,
22 pub rest: [u32; 32],
23}
24
25#[repr(C)]
26#[derive(Default)]
27pub struct FbFixScreeninfo {
28 id: [u8; 16],
29 pub smem_start: usize,
30 pub smem_len: u32,
31 typ: u32,
32 type_aux: u32,
33 visual: u32,
34 xpanstep: u16,
35 ypanstep: u16,
36 ywrapstep: u16,
37 pub line_length: u32,
38 rest: [u32; 16],
39}
40
41#[repr(C)]
42pub struct MxcfbRect {
43 pub top: u32,
44 pub left: u32,
45 pub width: u32,
46 pub height: u32,
47}
48
49#[repr(C)]
50pub struct MxcfbUpdateData {
51 pub update_region: MxcfbRect,
52 pub waveform_mode: u32,
53 pub update_mode: u32,
54 pub update_marker: u32,
55 pub temp: u32,
56 pub flags: u32,
57}
58
59pub const WAVE_INIT: u32 = 0;
60pub const WAVE_DU: u32 = 1;
61pub const WAVE_GC16: u32 = 2;
62pub const WAVE_GL16: u32 = 3;
63pub const WAVE_A2: u32 = 4;
64pub const WAVE_GLR16: u32 = 5;
65pub const WAVE_GLD16: u32 = 6;
66
67pub fn waveform_for(scenario: RenderScenario) -> u32 {
77 match scenario {
78 RenderScenario::Transition => WAVE_GL16,
79 RenderScenario::Content => WAVE_GL16,
80 RenderScenario::Animation => WAVE_A2,
81 }
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq)]
85pub enum RenderScenario {
86 Transition,
87 Content,
88 Animation,
89}
90
91pub fn diff_rows(prev: &[u8], cur: &[u8], w: usize, h: usize) -> Option<(usize, usize)> {
99 let mut min_y = h;
100 let mut max_y = 0;
101 let mut dirty = false;
102 for y in 0..h {
103 let base = y * w * 2;
104 if prev[base..base + w * 2] != cur[base..base + w * 2] {
105 dirty = true;
106 if y < min_y {
107 min_y = y;
108 }
109 if y > max_y {
110 max_y = y;
111 }
112 }
113 }
114 if !dirty {
115 return None;
116 }
117 const A: usize = 8;
118 let top = (min_y / A) * A;
119 let bottom = ((max_y + A) / A) * A;
120 let rh = bottom.min(h) - top;
121 Some((top, rh))
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 fn make_buf(w: usize, h: usize, fill: u8) -> Vec<u8> {
129 vec![fill; w * h * 2]
130 }
131
132 #[test]
133 fn diff_rows_detects_change() {
134 let w = 10;
135 let h = 16;
136 let prev = make_buf(w, h, 0);
137 let mut cur = prev.clone();
138 let px = (5 * w + 3) * 2;
139 cur[px] = 1;
140 cur[px + 1] = 1;
141 let (top, rh) = diff_rows(&prev, &cur, w, h).unwrap();
142 assert_eq!(top, 0);
143 assert!(rh > 0);
144 }
145
146 #[test]
147 fn diff_rows_returns_none_when_identical() {
148 let w = 10;
149 let h = 10;
150 let buf = make_buf(w, h, 0);
151 assert!(diff_rows(&buf, &buf, w, h).is_none());
152 }
153
154 #[test]
155 fn diff_rows_aligns_to_8px_boundary() {
156 let w = 10;
157 let h = 32;
158 let prev = make_buf(w, h, 0);
159 let mut cur = prev.clone();
160 let px = (13 * w) * 2;
161 cur[px] = 1;
162 let (top, rh) = diff_rows(&prev, &cur, w, h).unwrap();
163 assert_eq!(top, 8);
164 assert_eq!(rh, 8);
165 }
166}