@@ -210,7 +210,7 @@ static int linux_cma_alloc(size_t size)
210
210
211
211
// Some devices (mostly ARM SBCs) need CMA for hardware encoders.
212
212
static struct gbm_bo * create_cma_gbm_bo (int width , int height , uint32_t fourcc ,
213
- struct gbm_device * gbm )
213
+ struct wv_gbm_device * gbm )
214
214
{
215
215
int bpp = pixel_size_from_fourcc (fourcc );
216
216
if (!bpp ) {
@@ -241,7 +241,8 @@ static struct gbm_bo* create_cma_gbm_bo(int width, int height, uint32_t fourcc,
241
241
.strides [0 ] = stride ,
242
242
};
243
243
244
- struct gbm_bo * bo = gbm_bo_import (gbm , GBM_BO_IMPORT_FD_MODIFIER , & d , 0 );
244
+ struct gbm_bo * bo = gbm_bo_import (gbm -> dev , GBM_BO_IMPORT_FD_MODIFIER ,
245
+ & d , 0 );
245
246
if (!bo ) {
246
247
nvnc_log (NVNC_LOG_DEBUG , "Failed to import dmabuf: %m" );
247
248
close (fd );
@@ -252,8 +253,30 @@ static struct gbm_bo* create_cma_gbm_bo(int width, int height, uint32_t fourcc,
252
253
}
253
254
#endif // HAVE_LINUX_DMA_HEAP
254
255
256
+ #ifdef ENABLE_SCREENCOPY_DMABUF
257
+ static void wv_gbm_device_ref (struct wv_gbm_device * dev )
258
+ {
259
+ ++ dev -> ref ;
260
+ }
261
+
262
+ static void wv_gbm_device_unref (struct wv_gbm_device * dev )
263
+ {
264
+ if (!dev || -- dev -> ref != 0 )
265
+ return ;
266
+
267
+ if (dev -> dev )
268
+ gbm_device_destroy (dev -> dev );
269
+
270
+ if (dev -> fd > 0 )
271
+ close (dev -> fd );
272
+
273
+ free (dev );
274
+ }
275
+ #endif
276
+
255
277
static struct wv_buffer * wv_buffer_create_dmabuf (
256
- const struct wv_buffer_config * config , struct gbm_device * gbm )
278
+ const struct wv_buffer_config * config ,
279
+ struct wv_gbm_device * gbm )
257
280
{
258
281
assert (zwp_linux_dmabuf );
259
282
@@ -278,7 +301,7 @@ static struct wv_buffer* wv_buffer_create_dmabuf(
278
301
self -> bo = have_linux_cma () ?
279
302
create_cma_gbm_bo (config -> width , config -> height ,
280
303
config -> format , gbm ) :
281
- gbm_bo_create_with_modifiers2 (gbm , config -> width ,
304
+ gbm_bo_create_with_modifiers2 (gbm -> dev , config -> width ,
282
305
config -> height , config -> format ,
283
306
config -> modifiers , config -> n_modifiers ,
284
307
GBM_BO_USE_RENDERING );
@@ -325,6 +348,9 @@ static struct wv_buffer* wv_buffer_create_dmabuf(
325
348
pixman_region_init_rect (& self -> buffer_damage , 0 , 0 , config -> width ,
326
349
config -> height );
327
350
351
+ self -> gbm = gbm ;
352
+ wv_gbm_device_ref (gbm );
353
+
328
354
LIST_INSERT_HEAD (& buffer_registry , self , registry_link );
329
355
330
356
return self ;
@@ -343,7 +369,7 @@ static struct wv_buffer* wv_buffer_create_dmabuf(
343
369
#endif
344
370
345
371
struct wv_buffer * wv_buffer_create (const struct wv_buffer_config * config ,
346
- struct gbm_device * gbm )
372
+ struct wv_gbm_device * gbm )
347
373
{
348
374
nvnc_trace ("wv_buffer_create: %dx%d, stride: %d, format: %" PRIu32 " gbm: %p" ,
349
375
config -> width , config -> height , config -> stride ,
@@ -378,6 +404,7 @@ static void wv_buffer_destroy_dmabuf(struct wv_buffer* self)
378
404
wl_buffer_destroy (self -> wl_buffer );
379
405
free (self -> modifiers );
380
406
gbm_bo_destroy (self -> bo );
407
+ wv_gbm_device_unref (self -> gbm );
381
408
free (self );
382
409
}
383
410
#endif
@@ -428,7 +455,6 @@ struct wv_buffer_pool* wv_buffer_pool_create(
428
455
return NULL ;
429
456
430
457
TAILQ_INIT (& self -> queue );
431
- self -> gbm_fd = -1 ;
432
458
433
459
if (config )
434
460
wv_buffer_pool_reconfig (self , config );
@@ -450,10 +476,7 @@ void wv_buffer_pool_destroy(struct wv_buffer_pool* pool)
450
476
wv_buffer_pool_clear (pool );
451
477
free (pool -> config .modifiers );
452
478
#ifdef ENABLE_SCREENCOPY_DMABUF
453
- if (pool -> gbm )
454
- gbm_device_destroy (pool -> gbm );
455
- if (pool -> gbm_fd > 0 )
456
- close (pool -> gbm_fd );
479
+ wv_gbm_device_unref (pool -> gbm );
457
480
#endif
458
481
free (pool );
459
482
}
@@ -509,16 +532,26 @@ static void open_render_node(struct wv_buffer_pool* pool)
509
532
510
533
nvnc_log (NVNC_LOG_DEBUG , "Using render node: %s" , path );
511
534
512
- pool -> gbm_fd = open (path , O_RDWR );
513
- if (pool -> gbm_fd < 0 ) {
535
+ pool -> gbm = calloc (1 , sizeof (* pool -> gbm ));
536
+ assert (pool -> gbm );
537
+
538
+ pool -> gbm -> ref = 1 ;
539
+
540
+ pool -> gbm -> fd = open (path , O_RDWR );
541
+ if (pool -> gbm -> fd < 0 ) {
514
542
nvnc_log (NVNC_LOG_ERROR , "Failed to open render node %s: %m" ,
515
543
path );
544
+ free (pool -> gbm );
545
+ pool -> gbm = NULL ;
516
546
return ;
517
547
}
518
548
519
- pool -> gbm = gbm_create_device (pool -> gbm_fd );
549
+ pool -> gbm -> dev = gbm_create_device (pool -> gbm -> fd );
520
550
if (!pool -> gbm ) {
521
551
nvnc_log (NVNC_LOG_ERROR , "Failed to create a GBM device" );
552
+ close (pool -> gbm -> fd );
553
+ free (pool -> gbm );
554
+ pool -> gbm = NULL ;
522
555
}
523
556
}
524
557
#endif // ENABLE_SCREENCOPY_DMABUF
@@ -535,12 +568,8 @@ void wv_buffer_pool_reconfig(struct wv_buffer_pool* pool,
535
568
536
569
#ifdef ENABLE_SCREENCOPY_DMABUF
537
570
if (old_node != config -> node ) {
538
- if (pool -> gbm )
539
- gbm_device_destroy (pool -> gbm );
571
+ wv_gbm_device_unref (pool -> gbm );
540
572
pool -> gbm = NULL ;
541
- if (pool -> gbm_fd > 0 )
542
- close (pool -> gbm_fd );
543
- pool -> gbm_fd = -1 ;
544
573
545
574
open_render_node (pool );
546
575
}
0 commit comments