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