display_utils/
types.rs

1// Copyright 2021 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use crate::error::Result;
6use crate::pixel_format::PixelFormat;
7use fidl_fuchsia_hardware_display::{
8    BufferCollectionId as FidlBufferCollectionId, BufferId as FidlBufferId, EventId as FidlEventId,
9    ImageId as FidlImageId, Info, LayerId as FidlLayerId,
10};
11use fidl_fuchsia_hardware_display_types::{
12    Color as FidlColor, DisplayId as FidlDisplayId, INVALID_DISP_ID,
13};
14use fuchsia_async::OnSignals;
15use std::fmt;
16use zx::{self as zx, AsHandleRef};
17
18/// Strongly typed wrapper around a display ID.
19#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
20pub struct DisplayId(pub u64);
21
22/// Represents an invalid DisplayId value.
23pub 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/// Strongly typed wrapper around a display driver event ID.
44#[derive(Clone, Copy, Debug, Eq, PartialEq)]
45pub struct EventId(pub u64);
46
47/// Represents an invalid EventId value.
48pub 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/// Strongly typed wrapper around a display layer ID.
69#[derive(Clone, Copy, Debug, Eq, PartialEq)]
70pub struct LayerId(pub u64);
71
72/// Represents an invalid LayerId value.
73pub 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/// Strongly typed wrapper around an image ID.
94#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
95pub struct ImageId(pub u64);
96
97/// Represents an invalid ImageId value.
98pub 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/// Strongly typed wrapper around a sysmem buffer collection ID.
119#[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/// Strongly typed wrapper around a sysmem buffer identifier, including a
135/// collection ID and the index of the buffer.
136/// Corresponds to [`fuchsia.hardware.display/BufferId`].
137#[derive(Clone, Copy, Debug, Eq, PartialEq)]
138pub struct BufferId {
139    /// Identifies the buffer collection.
140    pub buffer_collection_id: BufferCollectionId,
141    /// Index of the buffer within the buffer collection.
142    pub buffer_index: u32,
143}
144
145impl BufferId {
146    /// Creates a `BufferId` using given `buffer_collection_id` and `index`.
147    pub fn new(buffer_collection_id: BufferCollectionId, buffer_index: u32) -> Self {
148        BufferId { buffer_collection_id, buffer_index }
149    }
150}
151
152impl From<FidlBufferId> for BufferId {
153    fn from(fidl_buffer_id: FidlBufferId) -> Self {
154        BufferId {
155            buffer_collection_id: fidl_buffer_id.buffer_collection_id.into(),
156            buffer_index: fidl_buffer_id.buffer_index,
157        }
158    }
159}
160
161impl From<BufferId> for FidlBufferId {
162    fn from(buffer_id: BufferId) -> Self {
163        FidlBufferId {
164            buffer_collection_id: buffer_id.buffer_collection_id.into(),
165            buffer_index: buffer_id.buffer_index,
166        }
167    }
168}
169
170/// Enhances the `fuchsia.hardware.display.Info` FIDL struct.
171#[derive(Clone, Debug)]
172pub struct DisplayInfo(pub Info);
173
174impl DisplayInfo {
175    /// Returns the ID for this display.
176    pub fn id(&self) -> DisplayId {
177        self.0.id.into()
178    }
179}
180
181/// Custom user-friendly format representation.
182impl fmt::Display for DisplayInfo {
183    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
184        writeln!(f, "Display (id: {})", self.0.id.value)?;
185        writeln!(f, "\tManufacturer Name: \"{}\"", self.0.manufacturer_name)?;
186        writeln!(f, "\tMonitor Name: \"{}\"", self.0.monitor_name)?;
187        writeln!(f, "\tMonitor Serial: \"{}\"", self.0.monitor_serial)?;
188        writeln!(
189            f,
190            "\tPhysical Dimensions: {}mm x {}mm",
191            self.0.horizontal_size_mm, self.0.vertical_size_mm
192        )?;
193
194        writeln!(f, "\tPixel Formats:")?;
195        for (i, format) in self.0.pixel_format.iter().map(PixelFormat::from).enumerate() {
196            writeln!(f, "\t\t{}:\t{}", i, format)?;
197        }
198
199        writeln!(f, "\tDisplay Modes:")?;
200        for (i, mode) in self.0.modes.iter().enumerate() {
201            writeln!(
202                f,
203                "\t\t{}:\t{:.2} Hz @ {}x{}",
204                i,
205                (mode.refresh_rate_millihertz as f32) / 1000.,
206                mode.active_area.width,
207                mode.active_area.height
208            )?;
209        }
210
211        write!(f, "")
212    }
213}
214
215/// A zircon event that has been registered with the display driver.
216pub struct Event {
217    id: EventId,
218    event: zx::Event,
219}
220
221impl Event {
222    pub(crate) fn new(id: EventId, event: zx::Event) -> Event {
223        Event { id, event }
224    }
225
226    /// Returns the ID for this event.
227    pub fn id(&self) -> EventId {
228        self.id
229    }
230
231    /// Returns a future that completes when the event has been signaled.
232    pub async fn wait(&self) -> Result<()> {
233        OnSignals::new(&self.event, zx::Signals::EVENT_SIGNALED).await?;
234        self.event.as_handle_ref().signal(zx::Signals::EVENT_SIGNALED, zx::Signals::NONE)?;
235        Ok(())
236    }
237
238    /// Signals the event.
239    pub fn signal(&self) -> Result<()> {
240        self.event.as_handle_ref().signal(zx::Signals::NONE, zx::Signals::EVENT_SIGNALED)?;
241        Ok(())
242    }
243}
244
245/// Enhances the `fuchsia.hardware.display.typers.Color` FIDL struct.
246#[derive(Clone, Copy, Debug, PartialEq)]
247pub struct Color {
248    /// The format of `bytes`.
249    pub format: PixelFormat,
250
251    /// The constant color, represented as one pixel using `format`.
252    pub bytes: [u8; 8],
253}
254
255impl From<FidlColor> for Color {
256    fn from(fidl_color: FidlColor) -> Self {
257        Color { format: fidl_color.format.into(), bytes: fidl_color.bytes }
258    }
259}
260
261impl From<&FidlColor> for Color {
262    fn from(fidl_color: &FidlColor) -> Self {
263        Self::from(*fidl_color)
264    }
265}
266
267impl From<Color> for FidlColor {
268    fn from(color: Color) -> Self {
269        FidlColor { format: color.format.into(), bytes: color.bytes }
270    }
271}
272
273impl From<&Color> for FidlColor {
274    fn from(color: &Color) -> Self {
275        Self::from(*color)
276    }
277}
278
279#[cfg(test)]
280mod tests {
281    use super::*;
282    use fidl_fuchsia_images2::PixelFormat as FidlPixelFormat;
283
284    #[fuchsia::test]
285    fn layer_id_from_fidl_layer_id() {
286        assert_eq!(LayerId(1), LayerId::from(FidlLayerId { value: 1 }));
287        assert_eq!(LayerId(2), LayerId::from(FidlLayerId { value: 2 }));
288        const LARGE: u64 = 1 << 63;
289        assert_eq!(LayerId(LARGE), LayerId::from(FidlLayerId { value: LARGE }));
290        assert_eq!(INVALID_LAYER_ID, LayerId::from(FidlLayerId { value: INVALID_DISP_ID }));
291    }
292
293    #[fuchsia::test]
294    fn fidl_layer_id_from_layer_id() {
295        assert_eq!(FidlLayerId { value: 1 }, FidlLayerId::from(LayerId(1)));
296        assert_eq!(FidlLayerId { value: 2 }, FidlLayerId::from(LayerId(2)));
297        const LARGE: u64 = 1 << 63;
298        assert_eq!(FidlLayerId { value: LARGE }, FidlLayerId::from(LayerId(LARGE)));
299        assert_eq!(FidlLayerId { value: INVALID_DISP_ID }, FidlLayerId::from(INVALID_LAYER_ID));
300    }
301
302    #[fuchsia::test]
303    fn fidl_layer_id_to_layer_id() {
304        assert_eq!(LayerId(1), FidlLayerId { value: 1 }.into());
305        assert_eq!(LayerId(2), FidlLayerId { value: 2 }.into());
306        const LARGE: u64 = 1 << 63;
307        assert_eq!(LayerId(LARGE), FidlLayerId { value: LARGE }.into());
308        assert_eq!(INVALID_LAYER_ID, FidlLayerId { value: INVALID_DISP_ID }.into());
309    }
310
311    #[fuchsia::test]
312    fn layer_id_to_fidl_layer_id() {
313        assert_eq!(FidlLayerId { value: 1 }, LayerId(1).into());
314        assert_eq!(FidlLayerId { value: 2 }, LayerId(2).into());
315        const LARGE: u64 = 1 << 63;
316        assert_eq!(FidlLayerId { value: LARGE }, LayerId(LARGE).into());
317        assert_eq!(FidlLayerId { value: INVALID_DISP_ID }, INVALID_LAYER_ID.into());
318    }
319
320    #[fuchsia::test]
321    fn layer_id_default() {
322        let default: LayerId = Default::default();
323        assert_eq!(default, INVALID_LAYER_ID);
324    }
325
326    #[fuchsia::test]
327    fn display_id_from_fidl_display_id() {
328        assert_eq!(DisplayId(1), DisplayId::from(FidlDisplayId { value: 1 }));
329        assert_eq!(DisplayId(2), DisplayId::from(FidlDisplayId { value: 2 }));
330        const LARGE: u64 = 1 << 63;
331        assert_eq!(DisplayId(LARGE), DisplayId::from(FidlDisplayId { value: LARGE }));
332        assert_eq!(INVALID_DISPLAY_ID, DisplayId::from(FidlDisplayId { value: INVALID_DISP_ID }));
333    }
334
335    #[fuchsia::test]
336    fn fidl_display_id_from_display_id() {
337        assert_eq!(FidlDisplayId { value: 1 }, FidlDisplayId::from(DisplayId(1)));
338        assert_eq!(FidlDisplayId { value: 2 }, FidlDisplayId::from(DisplayId(2)));
339        const LARGE: u64 = 1 << 63;
340        assert_eq!(FidlDisplayId { value: LARGE }, FidlDisplayId::from(DisplayId(LARGE)));
341        assert_eq!(
342            FidlDisplayId { value: INVALID_DISP_ID },
343            FidlDisplayId::from(INVALID_DISPLAY_ID)
344        );
345    }
346
347    #[fuchsia::test]
348    fn fidl_display_id_to_display_id() {
349        assert_eq!(DisplayId(1), FidlDisplayId { value: 1 }.into());
350        assert_eq!(DisplayId(2), FidlDisplayId { value: 2 }.into());
351        const LARGE: u64 = 1 << 63;
352        assert_eq!(DisplayId(LARGE), FidlDisplayId { value: LARGE }.into());
353        assert_eq!(INVALID_DISPLAY_ID, FidlDisplayId { value: INVALID_DISP_ID }.into());
354    }
355
356    #[fuchsia::test]
357    fn display_id_to_fidl_display_id() {
358        assert_eq!(FidlDisplayId { value: 1 }, DisplayId(1).into());
359        assert_eq!(FidlDisplayId { value: 2 }, DisplayId(2).into());
360        const LARGE: u64 = 1 << 63;
361        assert_eq!(FidlDisplayId { value: LARGE }, DisplayId(LARGE).into());
362        assert_eq!(FidlDisplayId { value: INVALID_DISP_ID }, INVALID_DISPLAY_ID.into());
363    }
364
365    #[fuchsia::test]
366    fn display_id_default() {
367        let default: DisplayId = Default::default();
368        assert_eq!(default, INVALID_DISPLAY_ID);
369    }
370
371    #[fuchsia::test]
372    fn buffer_collection_id_from_fidl_buffer_collection_id() {
373        assert_eq!(
374            BufferCollectionId(1),
375            BufferCollectionId::from(FidlBufferCollectionId { value: 1 })
376        );
377        assert_eq!(
378            BufferCollectionId(2),
379            BufferCollectionId::from(FidlBufferCollectionId { value: 2 })
380        );
381        const LARGE: u64 = 1 << 63;
382        assert_eq!(
383            BufferCollectionId(LARGE),
384            BufferCollectionId::from(FidlBufferCollectionId { value: LARGE })
385        );
386    }
387
388    #[fuchsia::test]
389    fn fidl_buffer_collection_id_from_buffer_collection_id() {
390        assert_eq!(
391            FidlBufferCollectionId { value: 1 },
392            FidlBufferCollectionId::from(BufferCollectionId(1))
393        );
394        assert_eq!(
395            FidlBufferCollectionId { value: 2 },
396            FidlBufferCollectionId::from(BufferCollectionId(2))
397        );
398        const LARGE: u64 = 1 << 63;
399        assert_eq!(
400            FidlBufferCollectionId { value: LARGE },
401            FidlBufferCollectionId::from(BufferCollectionId(LARGE))
402        );
403    }
404
405    #[fuchsia::test]
406    fn fidl_buffer_collection_id_to_buffer_collection_id() {
407        assert_eq!(BufferCollectionId(1), FidlBufferCollectionId { value: 1 }.into());
408        assert_eq!(BufferCollectionId(2), FidlBufferCollectionId { value: 2 }.into());
409        const LARGE: u64 = 1 << 63;
410        assert_eq!(BufferCollectionId(LARGE), FidlBufferCollectionId { value: LARGE }.into());
411    }
412
413    #[fuchsia::test]
414    fn buffer_collection_id_to_fidl_buffer_collection_id() {
415        assert_eq!(FidlBufferCollectionId { value: 1 }, BufferCollectionId(1).into());
416        assert_eq!(FidlBufferCollectionId { value: 2 }, BufferCollectionId(2).into());
417        const LARGE: u64 = 1 << 63;
418        assert_eq!(FidlBufferCollectionId { value: LARGE }, BufferCollectionId(LARGE).into());
419    }
420
421    #[fuchsia::test]
422    fn event_id_from_fidl_event_id() {
423        assert_eq!(EventId(1), EventId::from(FidlEventId { value: 1 }));
424        assert_eq!(EventId(2), EventId::from(FidlEventId { value: 2 }));
425        const LARGE: u64 = 1 << 63;
426        assert_eq!(EventId(LARGE), EventId::from(FidlEventId { value: LARGE }));
427        assert_eq!(INVALID_EVENT_ID, EventId::from(FidlEventId { value: INVALID_DISP_ID }));
428    }
429
430    #[fuchsia::test]
431    fn fidl_event_id_from_event_id() {
432        assert_eq!(FidlEventId { value: 1 }, FidlEventId::from(EventId(1)));
433        assert_eq!(FidlEventId { value: 2 }, FidlEventId::from(EventId(2)));
434        const LARGE: u64 = 1 << 63;
435        assert_eq!(FidlEventId { value: LARGE }, FidlEventId::from(EventId(LARGE)));
436        assert_eq!(FidlEventId { value: INVALID_DISP_ID }, FidlEventId::from(INVALID_EVENT_ID));
437    }
438
439    #[fuchsia::test]
440    fn fidl_event_id_to_event_id() {
441        assert_eq!(EventId(1), FidlEventId { value: 1 }.into());
442        assert_eq!(EventId(2), FidlEventId { value: 2 }.into());
443        const LARGE: u64 = 1 << 63;
444        assert_eq!(EventId(LARGE), FidlEventId { value: LARGE }.into());
445        assert_eq!(INVALID_EVENT_ID, FidlEventId { value: INVALID_DISP_ID }.into());
446    }
447
448    #[fuchsia::test]
449    fn event_id_to_fidl_event_id() {
450        assert_eq!(FidlEventId { value: 1 }, EventId(1).into());
451        assert_eq!(FidlEventId { value: 2 }, EventId(2).into());
452        const LARGE: u64 = 1 << 63;
453        assert_eq!(FidlEventId { value: LARGE }, EventId(LARGE).into());
454        assert_eq!(FidlEventId { value: INVALID_DISP_ID }, INVALID_EVENT_ID.into());
455    }
456
457    #[fuchsia::test]
458    fn event_id_default() {
459        let default: EventId = Default::default();
460        assert_eq!(default, INVALID_EVENT_ID);
461    }
462
463    #[fuchsia::test]
464    fn image_id_from_fidl_image_id() {
465        assert_eq!(ImageId(1), ImageId::from(FidlImageId { value: 1 }));
466        assert_eq!(ImageId(2), ImageId::from(FidlImageId { value: 2 }));
467        const LARGE: u64 = 1 << 63;
468        assert_eq!(ImageId(LARGE), ImageId::from(FidlImageId { value: LARGE }));
469        assert_eq!(INVALID_IMAGE_ID, ImageId::from(FidlImageId { value: INVALID_DISP_ID }));
470    }
471
472    #[fuchsia::test]
473    fn fidl_image_id_from_image_id() {
474        assert_eq!(FidlImageId { value: 1 }, FidlImageId::from(ImageId(1)));
475        assert_eq!(FidlImageId { value: 2 }, FidlImageId::from(ImageId(2)));
476        const LARGE: u64 = 1 << 63;
477        assert_eq!(FidlImageId { value: LARGE }, FidlImageId::from(ImageId(LARGE)));
478        assert_eq!(FidlImageId { value: INVALID_DISP_ID }, FidlImageId::from(INVALID_IMAGE_ID));
479    }
480
481    #[fuchsia::test]
482    fn fidl_image_id_to_image_id() {
483        assert_eq!(ImageId(1), FidlImageId { value: 1 }.into());
484        assert_eq!(ImageId(2), FidlImageId { value: 2 }.into());
485        const LARGE: u64 = 1 << 63;
486        assert_eq!(ImageId(LARGE), FidlImageId { value: LARGE }.into());
487        assert_eq!(INVALID_IMAGE_ID, FidlImageId { value: INVALID_DISP_ID }.into());
488    }
489
490    #[fuchsia::test]
491    fn image_id_to_fidl_image_id() {
492        assert_eq!(FidlImageId { value: 1 }, ImageId(1).into());
493        assert_eq!(FidlImageId { value: 2 }, ImageId(2).into());
494        const LARGE: u64 = 1 << 63;
495        assert_eq!(FidlImageId { value: LARGE }, ImageId(LARGE).into());
496        assert_eq!(FidlImageId { value: INVALID_DISP_ID }, INVALID_IMAGE_ID.into());
497    }
498
499    #[fuchsia::test]
500    fn image_id_default() {
501        let default: ImageId = Default::default();
502        assert_eq!(default, INVALID_IMAGE_ID);
503    }
504
505    #[fuchsia::test]
506    fn buffer_id_new() {
507        assert_eq!(
508            BufferId { buffer_collection_id: BufferCollectionId(1), buffer_index: 2 },
509            BufferId::new(BufferCollectionId(1), 2)
510        );
511        assert_eq!(
512            BufferId { buffer_collection_id: BufferCollectionId(2), buffer_index: 3 },
513            BufferId::new(BufferCollectionId(2), 3)
514        );
515        const LARGE_64: u64 = 1 << 63;
516        const LARGE_32: u32 = 1 << 31;
517        assert_eq!(
518            BufferId { buffer_collection_id: BufferCollectionId(LARGE_64), buffer_index: LARGE_32 },
519            BufferId::new(BufferCollectionId(LARGE_64), LARGE_32)
520        );
521    }
522
523    #[fuchsia::test]
524    fn buffer_id_from_fidl_buffer_id() {
525        assert_eq!(
526            BufferId { buffer_collection_id: BufferCollectionId(1), buffer_index: 2 },
527            BufferId::from(FidlBufferId {
528                buffer_collection_id: FidlBufferCollectionId { value: 1 },
529                buffer_index: 2
530            })
531        );
532        assert_eq!(
533            BufferId { buffer_collection_id: BufferCollectionId(2), buffer_index: 3 },
534            BufferId::from(FidlBufferId {
535                buffer_collection_id: FidlBufferCollectionId { value: 2 },
536                buffer_index: 3
537            })
538        );
539        const LARGE_64: u64 = 1 << 63;
540        const LARGE_32: u32 = 1 << 31;
541        assert_eq!(
542            BufferId { buffer_collection_id: BufferCollectionId(LARGE_64), buffer_index: LARGE_32 },
543            BufferId::from(FidlBufferId {
544                buffer_collection_id: FidlBufferCollectionId { value: LARGE_64 },
545                buffer_index: LARGE_32
546            })
547        );
548    }
549
550    #[fuchsia::test]
551    fn fidl_buffer_id_from_buffer_id() {
552        assert_eq!(
553            FidlBufferId {
554                buffer_collection_id: FidlBufferCollectionId { value: 1 },
555                buffer_index: 2
556            },
557            FidlBufferId::from(BufferId {
558                buffer_collection_id: BufferCollectionId(1),
559                buffer_index: 2
560            })
561        );
562        assert_eq!(
563            FidlBufferId {
564                buffer_collection_id: FidlBufferCollectionId { value: 2 },
565                buffer_index: 3
566            },
567            FidlBufferId::from(BufferId {
568                buffer_collection_id: BufferCollectionId(2),
569                buffer_index: 3
570            })
571        );
572        const LARGE_64: u64 = 1 << 63;
573        const LARGE_32: u32 = 1 << 31;
574        assert_eq!(
575            FidlBufferId {
576                buffer_collection_id: FidlBufferCollectionId { value: LARGE_64 },
577                buffer_index: LARGE_32
578            },
579            FidlBufferId::from(BufferId {
580                buffer_collection_id: BufferCollectionId(LARGE_64),
581                buffer_index: LARGE_32
582            })
583        );
584    }
585
586    #[fuchsia::test]
587    fn fidl_buffer_id_to_buffer_id() {
588        assert_eq!(
589            BufferId { buffer_collection_id: BufferCollectionId(1), buffer_index: 2 },
590            FidlBufferId {
591                buffer_collection_id: FidlBufferCollectionId { value: 1 },
592                buffer_index: 2
593            }
594            .into()
595        );
596        assert_eq!(
597            BufferId { buffer_collection_id: BufferCollectionId(2), buffer_index: 3 },
598            FidlBufferId {
599                buffer_collection_id: FidlBufferCollectionId { value: 2 },
600                buffer_index: 3
601            }
602            .into()
603        );
604        const LARGE_64: u64 = 1 << 63;
605        const LARGE_32: u32 = 1 << 31;
606        assert_eq!(
607            BufferId { buffer_collection_id: BufferCollectionId(LARGE_64), buffer_index: LARGE_32 },
608            FidlBufferId {
609                buffer_collection_id: FidlBufferCollectionId { value: LARGE_64 },
610                buffer_index: LARGE_32
611            }
612            .into()
613        );
614    }
615
616    #[fuchsia::test]
617    fn color_from_fidl_color() {
618        assert_eq!(
619            Color {
620                format: PixelFormat::R8G8B8A8,
621                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
622            },
623            Color::from(FidlColor {
624                format: FidlPixelFormat::R8G8B8A8,
625                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48],
626            })
627        );
628    }
629
630    #[fuchsia::test]
631    fn fidl_color_from_color() {
632        assert_eq!(
633            FidlColor {
634                format: FidlPixelFormat::R8G8B8A8,
635                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
636            },
637            FidlColor::from(Color {
638                format: PixelFormat::R8G8B8A8,
639                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48],
640            })
641        );
642    }
643
644    #[fuchsia::test]
645    fn fidl_color_to_color() {
646        assert_eq!(
647            Color {
648                format: PixelFormat::R8G8B8A8,
649                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
650            },
651            FidlColor {
652                format: FidlPixelFormat::R8G8B8A8,
653                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
654            }
655            .into()
656        );
657    }
658
659    #[fuchsia::test]
660    fn color_to_fidl_color() {
661        assert_eq!(
662            FidlColor {
663                format: FidlPixelFormat::R8G8B8A8,
664                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
665            },
666            Color {
667                format: PixelFormat::R8G8B8A8,
668                bytes: [0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48]
669            }
670            .into()
671        );
672    }
673}