@@ -68,7 +68,8 @@ trait ModeObject: Send + Sync + Downcastable {
6868
6969trait DrmDevice : Send + Sync {
7070 /// Returns weather the DRM device supports creating dumb buffers.
71- fn dumb_create ( & self ) -> bool ;
71+ fn can_dumb_create ( & self ) -> bool ;
72+ fn dumb_create ( & self , width : u32 , height : u32 , bpp : u32 ) -> BufferObject ;
7273
7374 /// Returns tuple containing the minumum dimensions (`xmin`, `ymin`).
7475 fn min_dim ( & self ) -> ( usize , usize ) ;
@@ -81,6 +82,24 @@ trait DrmDevice: Send + Sync {
8182 fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) ;
8283}
8384
85+ struct BufferObject {
86+ width : u32 ,
87+ height : u32 ,
88+ size : usize ,
89+ mapping : usize ,
90+ }
91+
92+ impl BufferObject {
93+ pub fn new ( width : u32 , height : u32 , size : usize ) -> Self {
94+ Self {
95+ width,
96+ height,
97+ size,
98+ mapping : 0 ,
99+ }
100+ }
101+ }
102+
84103// ## Notes:
85104//
86105// Plane: Image source
@@ -287,6 +306,10 @@ struct Drm {
287306 device : Arc < dyn DrmDevice > ,
288307
289308 id_alloc : IdAllocator ,
309+ mapping_alloc : IdAllocator ,
310+ buffer_alloc : IdAllocator ,
311+
312+ buffers : Mutex < HashMap < u32 , BufferObject > > ,
290313 mode_objs : Mutex < HashMap < u32 , Arc < dyn ModeObject > > > ,
291314
292315 // All of the mode objects:
@@ -305,7 +328,11 @@ impl Drm {
305328 card_id : DRM_CARD_ID . fetch_add ( 1 , Ordering :: SeqCst ) ,
306329 device,
307330
331+ buffer_alloc : IdAllocator :: new ( ) ,
308332 id_alloc : IdAllocator :: new ( ) ,
333+ mapping_alloc : IdAllocator :: new ( ) ,
334+
335+ buffers : Mutex :: new ( HashMap :: new ( ) ) ,
309336 mode_objs : Mutex :: new ( HashMap :: new ( ) ) ,
310337
311338 crtcs : Mutex :: new ( alloc:: vec![ ] ) ,
@@ -344,6 +371,13 @@ impl Drm {
344371 fn find_object ( & self , id : u32 ) -> Option < Arc < dyn ModeObject > > {
345372 self . mode_objs . lock ( ) . get ( & id) . map ( |obj| obj. clone ( ) )
346373 }
374+
375+ fn create_handle ( & self , buffer : BufferObject ) -> u32 {
376+ let handle = self . buffer_alloc . alloc ( ) as u32 ;
377+
378+ self . buffers . lock ( ) . insert ( handle, buffer) ;
379+ handle
380+ }
347381}
348382
349383impl INodeInterface for Drm {
@@ -374,7 +408,7 @@ impl INodeInterface for Drm {
374408 // NOTE: The user is responsible for zeroing out the structure.
375409 match struc. capability {
376410 DRM_CAP_DUMB_BUFFER => {
377- if self . device . dumb_create ( ) {
411+ if self . device . can_dumb_create ( ) {
378412 struc. value = 1 ;
379413 }
380414 }
@@ -505,6 +539,23 @@ impl INodeInterface for Drm {
505539 Ok ( 0 )
506540 }
507541
542+ DRM_IOCTL_MODE_CREATE_DUMB => {
543+ let struc = VirtAddr :: new ( arg as u64 )
544+ . read_mut :: < DrmModeCreateDumb > ( )
545+ . unwrap ( ) ;
546+
547+ let mut buffer = self
548+ . device
549+ . dumb_create ( struc. width , struc. height , struc. bpp ) ;
550+
551+ assert ! ( buffer. size < ( 1usize << 32 ) ) ;
552+
553+ buffer. mapping = self . mapping_alloc . alloc ( ) << 32 ;
554+ struc. handle = self . create_handle ( buffer) ;
555+
556+ Ok ( 0 )
557+ }
558+
508559 _ => {
509560 // command[8..16] is the ASCII character supposedly unique to each driver.
510561 if command. get_bits ( 8 ..16 ) == DRM_IOCTL_BASE {
0 commit comments