• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::{
2     device::queue::{
3         direction::{Capture, Direction, Output},
4         private,
5         qbuf::{QBuffer, QueueResult},
6         BuffersAllocated, CaptureQueueable, OutputQueueable, Queue, TryGetBufferError,
7     },
8     memory::DmaBufHandle,
9 };
10 use crate::{
11     memory::MmapHandle,
12     memory::{BufferHandles, MemoryType, UserPtrHandle},
13 };
14 use std::{fmt::Debug, fs::File, ops::Deref};
15 
16 /// Supported memory types for `GenericBufferHandles`.
17 /// TODO: This should be renamed to "DynamicBufferHandles", and be constructed
18 /// on-the-fly using a macro.
19 #[derive(Debug, Clone, Copy, PartialEq)]
20 pub enum GenericSupportedMemoryType {
21     Mmap,
22     UserPtr,
23     DmaBuf,
24 }
25 
26 impl From<GenericSupportedMemoryType> for MemoryType {
from(mem_type: GenericSupportedMemoryType) -> Self27     fn from(mem_type: GenericSupportedMemoryType) -> Self {
28         match mem_type {
29             GenericSupportedMemoryType::Mmap => MemoryType::Mmap,
30             GenericSupportedMemoryType::UserPtr => MemoryType::UserPtr,
31             GenericSupportedMemoryType::DmaBuf => MemoryType::DmaBuf,
32         }
33     }
34 }
35 
36 /// Buffer handle capable of holding either MMAP or UserPtr handles. Useful
37 /// for cases when we want to decide the memory type of a queue at runtime.
38 #[derive(Debug)]
39 pub enum GenericBufferHandles {
40     Mmap(Vec<MmapHandle>),
41     User(Vec<UserPtrHandle<Vec<u8>>>),
42     DmaBuf(Vec<DmaBufHandle<File>>),
43 }
44 
45 impl From<Vec<MmapHandle>> for GenericBufferHandles {
from(m: Vec<MmapHandle>) -> Self46     fn from(m: Vec<MmapHandle>) -> Self {
47         Self::Mmap(m)
48     }
49 }
50 
51 impl From<Vec<UserPtrHandle<Vec<u8>>>> for GenericBufferHandles {
from(u: Vec<UserPtrHandle<Vec<u8>>>) -> Self52     fn from(u: Vec<UserPtrHandle<Vec<u8>>>) -> Self {
53         Self::User(u)
54     }
55 }
56 
57 impl From<Vec<DmaBufHandle<File>>> for GenericBufferHandles {
from(d: Vec<DmaBufHandle<File>>) -> Self58     fn from(d: Vec<DmaBufHandle<File>>) -> Self {
59         Self::DmaBuf(d)
60     }
61 }
62 
63 impl BufferHandles for GenericBufferHandles {
64     type SupportedMemoryType = GenericSupportedMemoryType;
65 
len(&self) -> usize66     fn len(&self) -> usize {
67         match self {
68             GenericBufferHandles::Mmap(m) => m.len(),
69             GenericBufferHandles::User(u) => u.len(),
70             GenericBufferHandles::DmaBuf(d) => d.len(),
71         }
72     }
73 
fill_v4l2_plane(&self, index: usize, plane: &mut crate::bindings::v4l2_plane)74     fn fill_v4l2_plane(&self, index: usize, plane: &mut crate::bindings::v4l2_plane) {
75         match self {
76             GenericBufferHandles::Mmap(m) => m.fill_v4l2_plane(index, plane),
77             GenericBufferHandles::User(u) => u.fill_v4l2_plane(index, plane),
78             GenericBufferHandles::DmaBuf(d) => d.fill_v4l2_plane(index, plane),
79         }
80     }
81 }
82 
83 /// A QBuffer that holds either MMAP or UserPtr handles, depending on which
84 /// memory type has been selected for the queue at runtime.
85 pub enum GenericQBuffer<
86     D: Direction,
87     Q: Deref<Target = Queue<D, BuffersAllocated<GenericBufferHandles>>>,
88 > {
89     Mmap(QBuffer<D, Vec<MmapHandle>, GenericBufferHandles, Q>),
90     User(QBuffer<D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles, Q>),
91     DmaBuf(QBuffer<D, Vec<DmaBufHandle<File>>, GenericBufferHandles, Q>),
92 }
93 
94 impl<D, Q> From<QBuffer<D, Vec<MmapHandle>, GenericBufferHandles, Q>> for GenericQBuffer<D, Q>
95 where
96     D: Direction,
97     Q: Deref<Target = Queue<D, BuffersAllocated<GenericBufferHandles>>>,
98 {
from(qb: QBuffer<D, Vec<MmapHandle>, GenericBufferHandles, Q>) -> Self99     fn from(qb: QBuffer<D, Vec<MmapHandle>, GenericBufferHandles, Q>) -> Self {
100         GenericQBuffer::Mmap(qb)
101     }
102 }
103 
104 impl<D, Q> From<QBuffer<D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles, Q>>
105     for GenericQBuffer<D, Q>
106 where
107     D: Direction,
108     Q: Deref<Target = Queue<D, BuffersAllocated<GenericBufferHandles>>>,
109 {
from(qb: QBuffer<D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles, Q>) -> Self110     fn from(qb: QBuffer<D, Vec<UserPtrHandle<Vec<u8>>>, GenericBufferHandles, Q>) -> Self {
111         GenericQBuffer::User(qb)
112     }
113 }
114 
115 impl<D, Q> From<QBuffer<D, Vec<DmaBufHandle<File>>, GenericBufferHandles, Q>>
116     for GenericQBuffer<D, Q>
117 where
118     D: Direction,
119     Q: Deref<Target = Queue<D, BuffersAllocated<GenericBufferHandles>>>,
120 {
from(qb: QBuffer<D, Vec<DmaBufHandle<File>>, GenericBufferHandles, Q>) -> Self121     fn from(qb: QBuffer<D, Vec<DmaBufHandle<File>>, GenericBufferHandles, Q>) -> Self {
122         GenericQBuffer::DmaBuf(qb)
123     }
124 }
125 
126 impl<'a, D: Direction> private::QueueableProvider<'a>
127     for Queue<D, BuffersAllocated<GenericBufferHandles>>
128 {
129     type Queueable = GenericQBuffer<D, &'a Self>;
130 }
131 
132 impl<'a, D: Direction> private::GetBufferByIndex<'a>
133     for Queue<D, BuffersAllocated<GenericBufferHandles>>
134 {
try_get_buffer(&'a self, index: usize) -> Result<Self::Queueable, TryGetBufferError>135     fn try_get_buffer(&'a self, index: usize) -> Result<Self::Queueable, TryGetBufferError> {
136         let buffer_info = self.try_obtain_buffer(index)?;
137 
138         Ok(match self.state.memory_type {
139             GenericSupportedMemoryType::Mmap => {
140                 GenericQBuffer::Mmap(QBuffer::new(self, buffer_info))
141             }
142             GenericSupportedMemoryType::UserPtr => {
143                 GenericQBuffer::User(QBuffer::new(self, buffer_info))
144             }
145             GenericSupportedMemoryType::DmaBuf => {
146                 GenericQBuffer::DmaBuf(QBuffer::new(self, buffer_info))
147             }
148         })
149     }
150 }
151 
152 /// Any CAPTURE GenericQBuffer implements CaptureQueueable.
153 impl<Q> CaptureQueueable<GenericBufferHandles> for GenericQBuffer<Capture, Q>
154 where
155     Q: Deref<Target = Queue<Capture, BuffersAllocated<GenericBufferHandles>>>,
156 {
queue_with_handles( self, handles: GenericBufferHandles, ) -> QueueResult<(), GenericBufferHandles>157     fn queue_with_handles(
158         self,
159         handles: GenericBufferHandles,
160     ) -> QueueResult<(), GenericBufferHandles> {
161         match self {
162             GenericQBuffer::Mmap(m) => m.queue_with_handles(handles),
163             GenericQBuffer::User(u) => u.queue_with_handles(handles),
164             GenericQBuffer::DmaBuf(d) => d.queue_with_handles(handles),
165         }
166     }
167 }
168 
169 /// Any OUTPUT GenericQBuffer implements OutputQueueable.
170 impl<Q> OutputQueueable<GenericBufferHandles> for GenericQBuffer<Output, Q>
171 where
172     Q: Deref<Target = Queue<Output, BuffersAllocated<GenericBufferHandles>>>,
173 {
queue_with_handles( self, handles: GenericBufferHandles, bytes_used: &[usize], ) -> QueueResult<(), GenericBufferHandles>174     fn queue_with_handles(
175         self,
176         handles: GenericBufferHandles,
177         bytes_used: &[usize],
178     ) -> QueueResult<(), GenericBufferHandles> {
179         match self {
180             GenericQBuffer::Mmap(m) => m.queue_with_handles(handles, bytes_used),
181             GenericQBuffer::User(u) => u.queue_with_handles(handles, bytes_used),
182             GenericQBuffer::DmaBuf(d) => d.queue_with_handles(handles, bytes_used),
183         }
184     }
185 }
186