1 //! # Encoder
2 //!
3 //! An encoder is a bridge between a CRTC and a connector that takes the pixel
4 //! data of the CRTC and encodes it into a format the connector understands.
5 
6 use crate::control;
7 use drm_ffi as ffi;
8 
9 /// A handle to an encoder
10 #[repr(transparent)]
11 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
12 pub struct Handle(control::RawResourceHandle);
13 
14 // Safety: Handle is repr(transparent) over NonZeroU32
15 unsafe impl bytemuck::ZeroableInOption for Handle {}
16 unsafe impl bytemuck::PodInOption for Handle {}
17 
18 impl From<Handle> for control::RawResourceHandle {
from(handle: Handle) -> Self19     fn from(handle: Handle) -> Self {
20         handle.0
21     }
22 }
23 
24 impl From<Handle> for u32 {
from(handle: Handle) -> Self25     fn from(handle: Handle) -> Self {
26         handle.0.into()
27     }
28 }
29 
30 impl From<control::RawResourceHandle> for Handle {
from(handle: control::RawResourceHandle) -> Self31     fn from(handle: control::RawResourceHandle) -> Self {
32         Handle(handle)
33     }
34 }
35 
36 impl control::ResourceHandle for Handle {
37     const FFI_TYPE: u32 = ffi::DRM_MODE_OBJECT_ENCODER;
38 }
39 
40 impl std::fmt::Debug for Handle {
fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result41     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
42         f.debug_tuple("encoder::Handle").field(&self.0).finish()
43     }
44 }
45 
46 /// Information about an encoder
47 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
48 pub struct Info {
49     pub(crate) handle: Handle,
50     pub(crate) enc_type: Kind,
51     pub(crate) crtc: Option<control::crtc::Handle>,
52     pub(crate) pos_crtcs: u32,
53     pub(crate) pos_clones: u32,
54 }
55 
56 impl std::fmt::Display for Info {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result57     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58         write!(f, "Encoder {}", self.handle.0)
59     }
60 }
61 
62 impl Info {
63     /// Returns the handle to this encoder.
handle(&self) -> Handle64     pub fn handle(&self) -> Handle {
65         self.handle
66     }
67 
68     /// Returns the `Kind` of encoder this is.
kind(&self) -> Kind69     pub fn kind(&self) -> Kind {
70         self.enc_type
71     }
72 
73     /// Returns a handle to the CRTC this encoder is attached to.
crtc(&self) -> Option<control::crtc::Handle>74     pub fn crtc(&self) -> Option<control::crtc::Handle> {
75         self.crtc
76     }
77 
78     /// Returns a filter for the possible CRTCs that can use this encoder.
79     ///
80     /// Use with [`control::ResourceHandles::filter_crtcs`]
81     /// to receive a list of crtcs.
possible_crtcs(&self) -> control::CrtcListFilter82     pub fn possible_crtcs(&self) -> control::CrtcListFilter {
83         control::CrtcListFilter(self.pos_crtcs)
84     }
85 
86     /// Returns a filter for the possible encoders that clones this one.
possible_clones(&self)87     pub fn possible_clones(&self) {
88         unimplemented!()
89     }
90 }
91 
92 /// The type of encoder.
93 #[allow(missing_docs)]
94 #[allow(clippy::upper_case_acronyms)]
95 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
96 pub enum Kind {
97     None,
98     DAC,
99     TMDS,
100     LVDS,
101     TVDAC,
102     Virtual,
103     DSI,
104     DPMST,
105     DPI,
106 }
107 
108 impl From<u32> for Kind {
from(n: u32) -> Self109     fn from(n: u32) -> Self {
110         match n {
111             ffi::DRM_MODE_ENCODER_NONE => Kind::None,
112             ffi::DRM_MODE_ENCODER_DAC => Kind::DAC,
113             ffi::DRM_MODE_ENCODER_TMDS => Kind::TMDS,
114             ffi::DRM_MODE_ENCODER_LVDS => Kind::LVDS,
115             ffi::DRM_MODE_ENCODER_TVDAC => Kind::TVDAC,
116             ffi::DRM_MODE_ENCODER_VIRTUAL => Kind::Virtual,
117             ffi::DRM_MODE_ENCODER_DSI => Kind::DSI,
118             ffi::DRM_MODE_ENCODER_DPMST => Kind::DPMST,
119             ffi::DRM_MODE_ENCODER_DPI => Kind::DPI,
120             _ => Kind::None,
121         }
122     }
123 }
124 
125 impl From<Kind> for u32 {
from(kind: Kind) -> Self126     fn from(kind: Kind) -> Self {
127         match kind {
128             Kind::None => ffi::DRM_MODE_ENCODER_NONE,
129             Kind::DAC => ffi::DRM_MODE_ENCODER_DAC,
130             Kind::TMDS => ffi::DRM_MODE_ENCODER_TMDS,
131             Kind::LVDS => ffi::DRM_MODE_ENCODER_LVDS,
132             Kind::TVDAC => ffi::DRM_MODE_ENCODER_TVDAC,
133             Kind::Virtual => ffi::DRM_MODE_ENCODER_VIRTUAL,
134             Kind::DSI => ffi::DRM_MODE_ENCODER_DSI,
135             Kind::DPMST => ffi::DRM_MODE_ENCODER_DPMST,
136             Kind::DPI => ffi::DRM_MODE_ENCODER_DPI,
137         }
138     }
139 }
140