1use crate::error::Result;
6use crate::pixel_format::PixelFormat;
7use fidl_fuchsia_hardware_display::{
8 BufferCollectionId as FidlBufferCollectionId, EventId as FidlEventId, ImageId as FidlImageId,
9 Info, LayerId as FidlLayerId,
10};
11use fidl_fuchsia_hardware_display_types::{
12 AlphaMode, Color as FidlColor, DisplayId as FidlDisplayId, INVALID_DISP_ID,
13};
14use fuchsia_async::OnSignals;
15use std::fmt;
16
17#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
19pub struct DisplayId(pub u64);
20
21pub const INVALID_DISPLAY_ID: DisplayId = DisplayId(INVALID_DISP_ID);
23
24impl Default for DisplayId {
25 fn default() -> Self {
26 INVALID_DISPLAY_ID
27 }
28}
29
30impl From<FidlDisplayId> for DisplayId {
31 fn from(fidl_display_id: FidlDisplayId) -> Self {
32 DisplayId(fidl_display_id.value)
33 }
34}
35
36impl From<DisplayId> for FidlDisplayId {
37 fn from(display_id: DisplayId) -> Self {
38 FidlDisplayId { value: display_id.0 }
39 }
40}
41
42#[derive(Clone, Copy, Debug, Eq, PartialEq)]
44pub struct EventId(pub u64);
45
46pub const INVALID_EVENT_ID: EventId = EventId(INVALID_DISP_ID);
48
49impl Default for EventId {
50 fn default() -> Self {
51 INVALID_EVENT_ID
52 }
53}
54
55impl From<FidlEventId> for EventId {
56 fn from(fidl_event_id: FidlEventId) -> Self {
57 EventId(fidl_event_id.value)
58 }
59}
60
61impl From<EventId> for FidlEventId {
62 fn from(event_id: EventId) -> Self {
63 FidlEventId { value: event_id.0 }
64 }
65}
66
67#[derive(Clone, Copy, Debug, Eq, PartialEq)]
69pub struct LayerId(pub u64);
70
71pub const INVALID_LAYER_ID: LayerId = LayerId(INVALID_DISP_ID);
73
74impl Default for LayerId {
75 fn default() -> Self {
76 INVALID_LAYER_ID
77 }
78}
79
80impl From<FidlLayerId> for LayerId {
81 fn from(fidl_layer_id: FidlLayerId) -> Self {
82 LayerId(fidl_layer_id.value)
83 }
84}
85
86impl From<LayerId> for FidlLayerId {
87 fn from(layer_id: LayerId) -> Self {
88 FidlLayerId { value: layer_id.0 }
89 }
90}
91
92#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
94pub struct ImageId(pub u64);
95
96pub const INVALID_IMAGE_ID: ImageId = ImageId(INVALID_DISP_ID);
98
99impl Default for ImageId {
100 fn default() -> Self {
101 INVALID_IMAGE_ID
102 }
103}
104
105impl From<FidlImageId> for ImageId {
106 fn from(fidl_image_id: FidlImageId) -> Self {
107 ImageId(fidl_image_id.value)
108 }
109}
110
111impl From<ImageId> for FidlImageId {
112 fn from(image_id: ImageId) -> Self {
113 FidlImageId { value: image_id.0 }
114 }
115}
116
117#[derive(Clone, Copy, Debug, Eq, PartialEq)]
119pub struct BufferCollectionId(pub u64);
120
121impl From<FidlBufferCollectionId> for BufferCollectionId {
122 fn from(fidl_buffer_collection_id: FidlBufferCollectionId) -> Self {
123 BufferCollectionId(fidl_buffer_collection_id.value)
124 }
125}
126
127impl From<BufferCollectionId> for FidlBufferCollectionId {
128 fn from(buffer_collection_id: BufferCollectionId) -> Self {
129 FidlBufferCollectionId { value: buffer_collection_id.0 }
130 }
131}
132
133#[derive(Clone, Debug)]
135pub struct DisplayInfo(pub Info);
136
137impl DisplayInfo {
138 pub fn id(&self) -> DisplayId {
140 self.0.id.into()
141 }
142}
143
144impl fmt::Display for DisplayInfo {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 writeln!(f, "Display (id: {})", self.0.id.value)?;
148 writeln!(f, "\tManufacturer Name: \"{}\"", self.0.manufacturer_name)?;
149 writeln!(f, "\tMonitor Name: \"{}\"", self.0.monitor_name)?;
150 writeln!(f, "\tMonitor Serial: \"{}\"", self.0.monitor_serial)?;
151 writeln!(
152 f,
153 "\tPhysical Dimensions: {}mm x {}mm",
154 self.0.horizontal_size_mm, self.0.vertical_size_mm
155 )?;
156
157 writeln!(f, "\tPixel Formats:")?;
158 for (i, format) in self.0.pixel_format.iter().map(PixelFormat::from).enumerate() {
159 writeln!(f, "\t\t{}:\t{}", i, format)?;
160 }
161
162 writeln!(f, "\tDisplay Modes:")?;
163 for (i, mode) in self.0.modes.iter().enumerate() {
164 writeln!(
165 f,
166 "\t\t{}:\t{:.2} Hz @ {}x{}",
167 i,
168 (mode.refresh_rate_millihertz as f32) / 1000.,
169 mode.active_area.width,
170 mode.active_area.height
171 )?;
172 }
173
174 write!(f, "")
175 }
176}
177
178pub struct Event {
180 id: EventId,
181 event: zx::Event,
182}
183
184impl Event {
185 pub(crate) fn new(id: EventId, event: zx::Event) -> Event {
186 Event { id, event }
187 }
188
189 pub fn id(&self) -> EventId {
191 self.id
192 }
193
194 pub async fn wait(&self) -> Result<()> {
196 OnSignals::new(&self.event, zx::Signals::EVENT_SIGNALED).await?;
197 self.event.as_handle_ref().signal(zx::Signals::EVENT_SIGNALED, zx::Signals::NONE)?;
198 Ok(())
199 }
200
201 pub fn signal(&self) -> Result<()> {
203 self.event.as_handle_ref().signal(zx::Signals::NONE, zx::Signals::EVENT_SIGNALED)?;
204 Ok(())
205 }
206}
207
208#[derive(Clone, Copy, Debug, PartialEq)]
210pub struct Alpha {
211 pub mode: AlphaMode,
213 pub val: f32,
215}
216
217#[derive(Clone, Copy, Debug, PartialEq)]
219pub struct Color {
220 pub format: PixelFormat,
222
223 pub bytes: [u8; 8],
225}
226
227impl From<FidlColor> for Color {
228 fn from(fidl_color: FidlColor) -> Self {
229 Color { format: fidl_color.format.into(), bytes: fidl_color.bytes }
230 }
231}
232
233impl From<&FidlColor> for Color {
234 fn from(fidl_color: &FidlColor) -> Self {
235 Self::from(*fidl_color)
236 }
237}
238
239impl From<Color> for FidlColor {
240 fn from(color: Color) -> Self {
241 FidlColor { format: color.format.into(), bytes: color.bytes }
242 }
243}
244
245impl From<&Color> for FidlColor {
246 fn from(color: &Color) -> Self {
247 Self::from(*color)
248 }
249}
250
251#[cfg(test)]
252mod tests {
253 use super::*;
254 use fidl_fuchsia_images2::PixelFormat as FidlPixelFormat;
255
256 #[fuchsia::test]
257 fn layer_id_from_fidl_layer_id() {
258 assert_eq!(LayerId(1), LayerId::from(FidlLayerId { value: 1 }));
259 assert_eq!(LayerId(2), LayerId::from(FidlLayerId { value: 2 }));
260 const LARGE: u64 = 1 << 63;
261 assert_eq!(LayerId(LARGE), LayerId::from(FidlLayerId { value: LARGE }));
262 assert_eq!(INVALID_LAYER_ID, LayerId::from(FidlLayerId { value: INVALID_DISP_ID }));
263 }
264
265 #[fuchsia::test]
266 fn fidl_layer_id_from_layer_id() {
267 assert_eq!(FidlLayerId { value: 1 }, FidlLayerId::from(LayerId(1)));
268 assert_eq!(FidlLayerId { value: 2 }, FidlLayerId::from(LayerId(2)));
269 const LARGE: u64 = 1 << 63;
270 assert_eq!(FidlLayerId { value: LARGE }, FidlLayerId::from(LayerId(LARGE)));
271 assert_eq!(FidlLayerId { value: INVALID_DISP_ID }, FidlLayerId::from(INVALID_LAYER_ID));
272 }
273
274 #[fuchsia::test]
275 fn fidl_layer_id_to_layer_id() {
276 assert_eq!(LayerId(1), FidlLayerId { value: 1 }.into());
277 assert_eq!(LayerId(2), FidlLayerId { value: 2 }.into());
278 const LARGE: u64 = 1 << 63;
279 assert_eq!(LayerId(LARGE), FidlLayerId { value: LARGE }.into());
280 assert_eq!(INVALID_LAYER_ID, FidlLayerId { value: INVALID_DISP_ID }.into());
281 }
282
283 #[fuchsia::test]
284 fn layer_id_to_fidl_layer_id() {
285 assert_eq!(FidlLayerId { value: 1 }, LayerId(1).into());
286 assert_eq!(FidlLayerId { value: 2 }, LayerId(2).into());
287 const LARGE: u64 = 1 << 63;
288 assert_eq!(FidlLayerId { value: LARGE }, LayerId(LARGE).into());
289 assert_eq!(FidlLayerId { value: INVALID_DISP_ID }, INVALID_LAYER_ID.into());
290 }
291
292 #[fuchsia::test]
293 fn layer_id_default() {
294 let default: LayerId = Default::default();
295 assert_eq!(default, INVALID_LAYER_ID);
296 }
297
298 #[fuchsia::test]
299 fn display_id_from_fidl_display_id() {
300 assert_eq!(DisplayId(1), DisplayId::from(FidlDisplayId { value: 1 }));
301 assert_eq!(DisplayId(2), DisplayId::from(FidlDisplayId { value: 2 }));
302 const LARGE: u64 = 1 << 63;
303 assert_eq!(DisplayId(LARGE), DisplayId::from(FidlDisplayId { value: LARGE }));
304 assert_eq!(INVALID_DISPLAY_ID, DisplayId::from(FidlDisplayId { value: INVALID_DISP_ID }));
305 }
306
307 #[fuchsia::test]
308 fn fidl_display_id_from_display_id() {
309 assert_eq!(FidlDisplayId { value: 1 }, FidlDisplayId::from(DisplayId(1)));
310 assert_eq!(FidlDisplayId { value: 2 }, FidlDisplayId::from(DisplayId(2)));
311 const LARGE: u64 = 1 << 63;
312 assert_eq!(FidlDisplayId { value: LARGE }, FidlDisplayId::from(DisplayId(LARGE)));
313 assert_eq!(
314 FidlDisplayId { value: INVALID_DISP_ID },
315 FidlDisplayId::from(INVALID_DISPLAY_ID)
316 );
317 }
318
319 #[fuchsia::test]
320 fn fidl_display_id_to_display_id() {
321 assert_eq!(DisplayId(1), FidlDisplayId { value: 1 }.into());
322 assert_eq!(DisplayId(2), FidlDisplayId { value: 2 }.into());
323 const LARGE: u64 = 1 << 63;
324 assert_eq!(DisplayId(LARGE), FidlDisplayId { value: LARGE }.into());
325 assert_eq!(INVALID_DISPLAY_ID, FidlDisplayId { value: INVALID_DISP_ID }.into());
326 }
327
328 #[fuchsia::test]
329 fn display_id_to_fidl_display_id() {
330 assert_eq!(FidlDisplayId { value: 1 }, DisplayId(1).into());
331 assert_eq!(FidlDisplayId { value: 2 }, DisplayId(2).into());
332 const LARGE: u64 = 1 << 63;
333 assert_eq!(FidlDisplayId { value: LARGE }, DisplayId(LARGE).into());
334 assert_eq!(FidlDisplayId { value: INVALID_DISP_ID }, INVALID_DISPLAY_ID.into());
335 }
336
337 #[fuchsia::test]
338 fn display_id_default() {
339 let default: DisplayId = Default::default();
340 assert_eq!(default, INVALID_DISPLAY_ID);
341 }
342
343 #[fuchsia::test]
344 fn buffer_collection_id_from_fidl_buffer_collection_id() {
345 assert_eq!(
346 BufferCollectionId(1),
347 BufferCollectionId::from(FidlBufferCollectionId { value: 1 })
348 );
349 assert_eq!(
350 BufferCollectionId(2),
351 BufferCollectionId::from(FidlBufferCollectionId { value: 2 })
352 );
353 const LARGE: u64 = 1 << 63;
354 assert_eq!(
355 BufferCollectionId(LARGE),
356 BufferCollectionId::from(FidlBufferCollectionId { value: LARGE })
357 );
358 }
359
360 #[fuchsia::test]
361 fn fidl_buffer_collection_id_from_buffer_collection_id() {
362 assert_eq!(
363 FidlBufferCollectionId { value: 1 },
364 FidlBufferCollectionId::from(BufferCollectionId(1))
365 );
366 assert_eq!(
367 FidlBufferCollectionId { value: 2 },
368 FidlBufferCollectionId::from(BufferCollectionId(2))
369 );
370 const LARGE: u64 = 1 << 63;
371 assert_eq!(
372 FidlBufferCollectionId { value: LARGE },
373 FidlBufferCollectionId::from(BufferCollectionId(LARGE))
374 );
375 }
376
377 #[fuchsia::test]
378 fn fidl_buffer_collection_id_to_buffer_collection_id() {
379 assert_eq!(BufferCollectionId(1), FidlBufferCollectionId { value: 1 }.into());
380 assert_eq!(BufferCollectionId(2), FidlBufferCollectionId { value: 2 }.into());
381 const LARGE: u64 = 1 << 63;
382 assert_eq!(BufferCollectionId(LARGE), FidlBufferCollectionId { value: LARGE }.into());
383 }
384
385 #[fuchsia::test]
386 fn buffer_collection_id_to_fidl_buffer_collection_id() {
387 assert_eq!(FidlBufferCollectionId { value: 1 }, BufferCollectionId(1).into());
388 assert_eq!(FidlBufferCollectionId { value: 2 }, BufferCollectionId(2).into());
389 const LARGE: u64 = 1 << 63;
390 assert_eq!(FidlBufferCollectionId { value: LARGE }, BufferCollectionId(LARGE).into());
391 }
392
393 #[fuchsia::test]
394 fn event_id_from_fidl_event_id() {
395 assert_eq!(EventId(1), EventId::from(FidlEventId { value: 1 }));
396 assert_eq!(EventId(2), EventId::from(FidlEventId { value: 2 }));
397 const LARGE: u64 = 1 << 63;
398 assert_eq!(EventId(LARGE), EventId::from(FidlEventId { value: LARGE }));
399 assert_eq!(INVALID_EVENT_ID, EventId::from(FidlEventId { value: INVALID_DISP_ID }));
400 }
401
402 #[fuchsia::test]
403 fn fidl_event_id_from_event_id() {
404 assert_eq!(FidlEventId { value: 1 }, FidlEventId::from(EventId(1)));
405 assert_eq!(FidlEventId { value: 2 }, FidlEventId::from(EventId(2)));
406 const LARGE: u64 = 1 << 63;
407 assert_eq!(FidlEventId { value: LARGE }, FidlEventId::from(EventId(LARGE)));
408 assert_eq!(FidlEventId { value: INVALID_DISP_ID }, FidlEventId::from(INVALID_EVENT_ID));
409 }
410
411 #[fuchsia::test]
412 fn fidl_event_id_to_event_id() {
413 assert_eq!(EventId(1), FidlEventId { value: 1 }.into());
414 assert_eq!(EventId(2), FidlEventId { value: 2 }.into());
415 const LARGE: u64 = 1 << 63;
416 assert_eq!(EventId(LARGE), FidlEventId { value: LARGE }.into());
417 assert_eq!(INVALID_EVENT_ID, FidlEventId { value: INVALID_DISP_ID }.into());
418 }
419
420 #[fuchsia::test]
421 fn event_id_to_fidl_event_id() {
422 assert_eq!(FidlEventId { value: 1 }, EventId(1).into());
423 assert_eq!(FidlEventId { value: 2 }, EventId(2).into());
424 const LARGE: u64 = 1 << 63;
425 assert_eq!(FidlEventId { value: LARGE }, EventId(LARGE).into());
426 assert_eq!(FidlEventId { value: INVALID_DISP_ID }, INVALID_EVENT_ID.into());
427 }
428
429 #[fuchsia::test]
430 fn event_id_default() {
431 let default: EventId = Default::default();
432 assert_eq!(default, INVALID_EVENT_ID);
433 }
434
435 #[fuchsia::test]
436 fn image_id_from_fidl_image_id() {
437 assert_eq!(ImageId(1), ImageId::from(FidlImageId { value: 1 }));
438 assert_eq!(ImageId(2), ImageId::from(FidlImageId { value: 2 }));
439 const LARGE: u64 = 1 << 63;
440 assert_eq!(ImageId(LARGE), ImageId::from(FidlImageId { value: LARGE }));
441 assert_eq!(INVALID_IMAGE_ID, ImageId::from(FidlImageId { value: INVALID_DISP_ID }));
442 }
443
444 #[fuchsia::test]
445 fn fidl_image_id_from_image_id() {
446 assert_eq!(FidlImageId { value: 1 }, FidlImageId::from(ImageId(1)));
447 assert_eq!(FidlImageId { value: 2 }, FidlImageId::from(ImageId(2)));
448 const LARGE: u64 = 1 << 63;
449 assert_eq!(FidlImageId { value: LARGE }, FidlImageId::from(ImageId(LARGE)));
450 assert_eq!(FidlImageId { value: INVALID_DISP_ID }, FidlImageId::from(INVALID_IMAGE_ID));
451 }
452
453 #[fuchsia::test]
454 fn fidl_image_id_to_image_id() {
455 assert_eq!(ImageId(1), FidlImageId { value: 1 }.into());
456 assert_eq!(ImageId(2), FidlImageId { value: 2 }.into());
457 const LARGE: u64 = 1 << 63;
458 assert_eq!(ImageId(LARGE), FidlImageId { value: LARGE }.into());
459 assert_eq!(INVALID_IMAGE_ID, FidlImageId { value: INVALID_DISP_ID }.into());
460 }
461
462 #[fuchsia::test]
463 fn image_id_to_fidl_image_id() {
464 assert_eq!(FidlImageId { value: 1 }, ImageId(1).into());
465 assert_eq!(FidlImageId { value: 2 }, ImageId(2).into());
466 const LARGE: u64 = 1 << 63;
467 assert_eq!(FidlImageId { value: LARGE }, ImageId(LARGE).into());
468 assert_eq!(FidlImageId { value: INVALID_DISP_ID }, INVALID_IMAGE_ID.into());
469 }
470
471 #[fuchsia::test]
472 fn image_id_default() {
473 let default: ImageId = Default::default();
474 assert_eq!(default, INVALID_IMAGE_ID);
475 }
476
477 #[fuchsia::test]
478 fn color_from_fidl_color() {
479 assert_eq!(
480 Color {
481 format: PixelFormat::R8G8B8A8,
482 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
483 },
484 Color::from(FidlColor {
485 format: FidlPixelFormat::R8G8B8A8,
486 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48],
487 })
488 );
489 }
490
491 #[fuchsia::test]
492 fn fidl_color_from_color() {
493 assert_eq!(
494 FidlColor {
495 format: FidlPixelFormat::R8G8B8A8,
496 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
497 },
498 FidlColor::from(Color {
499 format: PixelFormat::R8G8B8A8,
500 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48],
501 })
502 );
503 }
504
505 #[fuchsia::test]
506 fn fidl_color_to_color() {
507 assert_eq!(
508 Color {
509 format: PixelFormat::R8G8B8A8,
510 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
511 },
512 FidlColor {
513 format: FidlPixelFormat::R8G8B8A8,
514 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
515 }
516 .into()
517 );
518 }
519
520 #[fuchsia::test]
521 fn color_to_fidl_color() {
522 assert_eq!(
523 FidlColor {
524 format: FidlPixelFormat::R8G8B8A8,
525 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
526 },
527 Color {
528 format: PixelFormat::R8G8B8A8,
529 bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
530 }
531 .into()
532 );
533 }
534}