capsules_extra/screen/
screen_adapters.rs1use core::cell::Cell;
8
9use kernel::hil::screen::{Screen, ScreenClient, ScreenPixelFormat, ScreenRotation};
10use kernel::utilities::cells::OptionalCell;
11use kernel::utilities::leasable_buffer::SubSliceMut;
12use kernel::ErrorCode;
13
14pub struct ScreenARGB8888ToMono8BitPage<'a, S: Screen<'a>> {
19 screen: &'a S,
20 draw_buffer: OptionalCell<SubSliceMut<'static, u8>>,
21 draw_width: Cell<usize>,
22 client_buffer: OptionalCell<SubSliceMut<'static, u8>>,
23 client: OptionalCell<&'a dyn ScreenClient>,
24}
25
26impl<'a, S: Screen<'a>> ScreenARGB8888ToMono8BitPage<'a, S> {
27 pub fn new(screen: &'a S, draw_buffer: &'static mut [u8]) -> Self {
28 assert!(draw_buffer.len() % 4 == 0);
29
30 ScreenARGB8888ToMono8BitPage {
31 screen,
32 draw_buffer: OptionalCell::new(SubSliceMut::new(draw_buffer)),
33 draw_width: Cell::new(0),
34 client_buffer: OptionalCell::empty(),
35 client: OptionalCell::empty(),
36 }
37 }
38}
39
40struct EightRowColumnPixelIter<'a> {
41 buf: &'a mut [u8],
42 width: usize,
43 row: usize,
44 col: usize,
45}
46
47impl<'a> EightRowColumnPixelIter<'a> {
48 pub fn new(buf: &'a mut [u8], width: usize) -> Self {
49 EightRowColumnPixelIter {
50 buf,
51 width,
52 row: 0,
53 col: 0,
54 }
55 }
56
57 fn next(&mut self) -> Option<&mut [u8]> {
64 let pixel_offset = self
65 .row
66 .checked_mul(self.width)
67 .and_then(|off| off.checked_add(self.col))
68 .and_then(|off| off.checked_mul(4))?;
69
70 self.row += 1;
71 if self.row % 8 == 0 {
72 self.row -= 8;
73 self.col += 1;
74 }
75 if self.col == self.width {
76 self.col = 0;
77 self.row += 8;
78 }
79
80 self.buf.get_mut(pixel_offset..(pixel_offset + 4))
81 }
82}
83
84impl<'a, S: Screen<'a>> Screen<'a> for ScreenARGB8888ToMono8BitPage<'a, S> {
85 fn set_client(&self, client: &'a dyn ScreenClient) {
86 self.client.replace(client);
87 }
88
89 fn get_resolution(&self) -> (usize, usize) {
90 self.screen.get_resolution()
91 }
92
93 fn get_pixel_format(&self) -> ScreenPixelFormat {
94 ScreenPixelFormat::Mono_8BitPage
95 }
96
97 fn get_rotation(&self) -> ScreenRotation {
98 self.screen.get_rotation()
99 }
100
101 fn set_write_frame(
102 &self,
103 x: usize,
104 y: usize,
105 width: usize,
106 height: usize,
107 ) -> Result<(), ErrorCode> {
108 if y % 8 != 0 || height % 8 != 0 {
110 return Err(ErrorCode::INVAL);
111 }
112
113 self.draw_width.set(width);
114 self.screen.set_write_frame(x, y, width, height)
115 }
116
117 fn write(
118 &self,
119 buffer: SubSliceMut<'static, u8>,
120 continue_write: bool,
121 ) -> Result<(), ErrorCode> {
122 fn into_bits(byte: u8) -> [bool; 8] {
123 let mut dst = [false; 8];
124 for (i, d) in dst.iter_mut().enumerate() {
125 *d = (byte & (1 << i)) != 0;
126 }
127 dst
128 }
129
130 let Some(mut draw_buffer) = self.draw_buffer.take() else {
131 return Err(ErrorCode::BUSY);
132 };
133
134 draw_buffer.reset();
135
136 let mut bytes_written = 0;
140 let mut dst_iter =
141 EightRowColumnPixelIter::new(draw_buffer.as_mut_slice(), self.draw_width.get());
142 for src_mono_8bit_page in buffer.as_slice().iter() {
143 for v in into_bits(*src_mono_8bit_page) {
145 dst_iter.next().unwrap().copy_from_slice(&[
146 0x00,
147 0xFF * (v as u8),
148 0xFF * (v as u8),
149 0xFF * (v as u8),
150 ]);
151 bytes_written += 4;
152 }
153 }
154 draw_buffer.slice(..bytes_written);
155
156 assert!(self.client_buffer.replace(buffer).is_none());
158 self.screen.write(draw_buffer, continue_write)
159 }
160
161 fn set_brightness(&self, brightness: u16) -> Result<(), ErrorCode> {
162 self.screen.set_brightness(brightness)
163 }
164
165 fn set_power(&self, enabled: bool) -> Result<(), ErrorCode> {
166 self.screen.set_power(enabled)
167 }
168
169 fn set_invert(&self, enabled: bool) -> Result<(), ErrorCode> {
170 self.screen.set_invert(enabled)
171 }
172}
173
174impl<'a, S: Screen<'a>> ScreenClient for ScreenARGB8888ToMono8BitPage<'a, S> {
175 fn command_complete(&self, result: Result<(), ErrorCode>) {
176 self.client.map(|c| c.command_complete(result));
177 }
178
179 fn write_complete(&self, buffer: SubSliceMut<'static, u8>, _result: Result<(), ErrorCode>) {
180 self.draw_buffer.replace(buffer);
181 self.client
182 .map(|c| c.write_complete(self.client_buffer.take().unwrap(), Ok(())));
183 }
184
185 fn screen_is_ready(&self) {
186 self.client.map(|c| c.screen_is_ready());
187 }
188}