@@ -68,7 +68,8 @@ trait ModeObject: Send + Sync + Downcastable {
68
68
69
69
trait DrmDevice : Send + Sync {
70
70
/// 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 ;
72
73
73
74
/// Returns tuple containing the minumum dimensions (`xmin`, `ymin`).
74
75
fn min_dim ( & self ) -> ( usize , usize ) ;
@@ -81,6 +82,24 @@ trait DrmDevice: Send + Sync {
81
82
fn driver_info ( & self ) -> ( & ' static str , & ' static str , & ' static str ) ;
82
83
}
83
84
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
+
84
103
// ## Notes:
85
104
//
86
105
// Plane: Image source
@@ -287,6 +306,10 @@ struct Drm {
287
306
device : Arc < dyn DrmDevice > ,
288
307
289
308
id_alloc : IdAllocator ,
309
+ mapping_alloc : IdAllocator ,
310
+ buffer_alloc : IdAllocator ,
311
+
312
+ buffers : Mutex < HashMap < u32 , BufferObject > > ,
290
313
mode_objs : Mutex < HashMap < u32 , Arc < dyn ModeObject > > > ,
291
314
292
315
// All of the mode objects:
@@ -305,7 +328,11 @@ impl Drm {
305
328
card_id : DRM_CARD_ID . fetch_add ( 1 , Ordering :: SeqCst ) ,
306
329
device,
307
330
331
+ buffer_alloc : IdAllocator :: new ( ) ,
308
332
id_alloc : IdAllocator :: new ( ) ,
333
+ mapping_alloc : IdAllocator :: new ( ) ,
334
+
335
+ buffers : Mutex :: new ( HashMap :: new ( ) ) ,
309
336
mode_objs : Mutex :: new ( HashMap :: new ( ) ) ,
310
337
311
338
crtcs : Mutex :: new ( alloc:: vec![ ] ) ,
@@ -344,6 +371,13 @@ impl Drm {
344
371
fn find_object ( & self , id : u32 ) -> Option < Arc < dyn ModeObject > > {
345
372
self . mode_objs . lock ( ) . get ( & id) . map ( |obj| obj. clone ( ) )
346
373
}
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
+ }
347
381
}
348
382
349
383
impl INodeInterface for Drm {
@@ -374,7 +408,7 @@ impl INodeInterface for Drm {
374
408
// NOTE: The user is responsible for zeroing out the structure.
375
409
match struc. capability {
376
410
DRM_CAP_DUMB_BUFFER => {
377
- if self . device . dumb_create ( ) {
411
+ if self . device . can_dumb_create ( ) {
378
412
struc. value = 1 ;
379
413
}
380
414
}
@@ -505,6 +539,23 @@ impl INodeInterface for Drm {
505
539
Ok ( 0 )
506
540
}
507
541
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
+
508
559
_ => {
509
560
// command[8..16] is the ASCII character supposedly unique to each driver.
510
561
if command. get_bits ( 8 ..16 ) == DRM_IOCTL_BASE {
0 commit comments