@ -16,6 +16,52 @@ static struct wlr_gbm_buffer *get_gbm_buffer_from_buffer(
 
			
		
	
		
			
				
						return  ( struct  wlr_gbm_buffer  * ) buffer ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  bool  export_gbm_bo ( struct  gbm_bo  * bo ,  
			
		
	
		
			
				
							struct  wlr_dmabuf_attributes  * out )  { 
 
			
		
	
		
			
				
						struct  wlr_dmabuf_attributes  attribs  =  { 0 } ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						attribs . n_planes  =  gbm_bo_get_plane_count ( bo ) ; 
 
			
		
	
		
			
				
						if  ( attribs . n_planes  >  WLR_DMABUF_MAX_PLANES )  { 
 
			
		
	
		
			
				
							wlr_log ( WLR_ERROR ,  " GBM BO contains too many planes (%d) " , 
 
			
		
	
		
			
				
								attribs . n_planes ) ; 
 
			
		
	
		
			
				
							return  false ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						attribs . width  =  gbm_bo_get_width ( bo ) ; 
 
			
		
	
		
			
				
						attribs . height  =  gbm_bo_get_height ( bo ) ; 
 
			
		
	
		
			
				
						attribs . format  =  gbm_bo_get_format ( bo ) ; 
 
			
		
	
		
			
				
						attribs . modifier  =  gbm_bo_get_modifier ( bo ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						int  i ; 
 
			
		
	
		
			
				
						for  ( i  =  0 ;  i  <  attribs . n_planes ;  + + i )  { 
 
			
		
	
		
			
				
							union  gbm_bo_handle  handle  =  gbm_bo_get_handle_for_plane ( bo ,  i ) ; 
 
			
		
	
		
			
				
							if  ( handle . s32  <  0 )  { 
 
			
		
	
		
			
				
								wlr_log ( WLR_ERROR ,  " gbm_bo_get_handle_for_plane failed " ) ; 
 
			
		
	
		
			
				
								goto  error_fd ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							int  drm_fd  =  gbm_device_get_fd ( gbm_bo_get_device ( bo ) ) ; 
 
			
		
	
		
			
				
							int  ret  =  drmPrimeHandleToFD ( drm_fd ,  handle . s32 , 
 
			
		
	
		
			
				
								DRM_CLOEXEC ,  & attribs . fd [ i ] ) ; 
 
			
		
	
		
			
				
							if  ( ret  <  0  | |  attribs . fd [ i ]  <  0 )  { 
 
			
		
	
		
			
				
								wlr_log_errno ( WLR_ERROR ,  " drmPrimeHandleToFD failed " ) ; 
 
			
		
	
		
			
				
								goto  error_fd ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							attribs . offset [ i ]  =  gbm_bo_get_offset ( bo ,  i ) ; 
 
			
		
	
		
			
				
							attribs . stride [ i ]  =  gbm_bo_get_stride_for_plane ( bo ,  i ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						memcpy ( out ,  & attribs ,  sizeof ( attribs ) ) ; 
 
			
		
	
		
			
				
						return  true ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					error_fd :  
			
		
	
		
			
				
						for  ( int  j  =  0 ;  j  <  i ;  + + j )  { 
 
			
		
	
		
			
				
							close ( attribs . fd [ j ] ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						return  false ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  struct  wlr_gbm_buffer  * create_buffer ( struct  wlr_gbm_allocator  * alloc ,  
			
		
	
		
			
				
							int  width ,  int  height ,  const  struct  wlr_drm_format  * format )  { 
 
			
		
	
		
			
				
						struct  gbm_device  * gbm_device  =  alloc - > gbm_device ; 
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -47,6 +93,12 @@ static struct wlr_gbm_buffer *create_buffer(struct wlr_gbm_allocator *alloc,
 
			
		
	
		
			
				
						buffer - > gbm_bo  =  bo ; 
 
			
		
	
		
			
				
						wl_list_insert ( & alloc - > buffers ,  & buffer - > link ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						if  ( ! export_gbm_bo ( bo ,  & buffer - > dmabuf ) )  { 
 
			
		
	
		
			
				
							free ( buffer ) ; 
 
			
		
	
		
			
				
							gbm_bo_destroy ( bo ) ; 
 
			
		
	
		
			
				
							return  NULL ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						wlr_log ( WLR_DEBUG ,  " Allocated %dx%d GBM buffer (format 0x% " PRIX32 " ,  " 
 
			
		
	
		
			
				
							" modifier 0x% " PRIX64 " ) " ,  buffer - > base . width ,  buffer - > base . height , 
 
			
		
	
		
			
				
							gbm_bo_get_format ( bo ) ,  gbm_bo_get_modifier ( bo ) ) ; 
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -65,72 +117,10 @@ static void buffer_destroy(struct wlr_buffer *wlr_buffer) {
 
			
		
	
		
			
				
						free ( buffer ) ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  bool  buffer_create_dmabuf ( struct  wlr_gbm_buffer  * buffer )  {  
			
		
	
		
			
				
						assert ( buffer - > dmabuf . n_planes  = =  0 ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  gbm_bo  * bo  =  buffer - > gbm_bo ; 
 
			
		
	
		
			
				
						if  ( bo  = =  NULL )  { 
 
			
		
	
		
			
				
							return  false ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						struct  wlr_dmabuf_attributes  attribs  =  { 0 } ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						attribs . n_planes  =  gbm_bo_get_plane_count ( bo ) ; 
 
			
		
	
		
			
				
						if  ( attribs . n_planes  >  WLR_DMABUF_MAX_PLANES )  { 
 
			
		
	
		
			
				
							wlr_log ( WLR_ERROR ,  " GBM BO contains too many planes (%d) " , 
 
			
		
	
		
			
				
								attribs . n_planes ) ; 
 
			
		
	
		
			
				
							return  false ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						attribs . width  =  gbm_bo_get_width ( bo ) ; 
 
			
		
	
		
			
				
						attribs . height  =  gbm_bo_get_height ( bo ) ; 
 
			
		
	
		
			
				
						attribs . format  =  gbm_bo_get_format ( bo ) ; 
 
			
		
	
		
			
				
						attribs . modifier  =  gbm_bo_get_modifier ( bo ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						int  i ; 
 
			
		
	
		
			
				
						for  ( i  =  0 ;  i  <  attribs . n_planes ;  + + i )  { 
 
			
		
	
		
			
				
							union  gbm_bo_handle  handle  =  gbm_bo_get_handle_for_plane ( bo ,  i ) ; 
 
			
		
	
		
			
				
							if  ( handle . s32  <  0 )  { 
 
			
		
	
		
			
				
								wlr_log ( WLR_ERROR ,  " gbm_bo_get_handle_for_plane failed " ) ; 
 
			
		
	
		
			
				
								goto  error_fd ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							int  drm_fd  =  gbm_device_get_fd ( gbm_bo_get_device ( bo ) ) ; 
 
			
		
	
		
			
				
							int  ret  =  drmPrimeHandleToFD ( drm_fd ,  handle . s32 , 
 
			
		
	
		
			
				
								DRM_CLOEXEC ,  & attribs . fd [ i ] ) ; 
 
			
		
	
		
			
				
							if  ( ret  <  0  | |  attribs . fd [ i ]  <  0 )  { 
 
			
		
	
		
			
				
								wlr_log_errno ( WLR_ERROR ,  " drmPrimeHandleToFD failed " ) ; 
 
			
		
	
		
			
				
								goto  error_fd ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
							attribs . offset [ i ]  =  gbm_bo_get_offset ( bo ,  i ) ; 
 
			
		
	
		
			
				
							attribs . stride [ i ]  =  gbm_bo_get_stride_for_plane ( bo ,  i ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						memcpy ( & buffer - > dmabuf ,  & attribs ,  sizeof ( attribs ) ) ; 
 
			
		
	
		
			
				
						return  true ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					error_fd :  
			
		
	
		
			
				
						for  ( int  j  =  0 ;  j  <  i ;  + + j )  { 
 
			
		
	
		
			
				
							close ( attribs . fd [ j ] ) ; 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
						return  false ; 
 
			
		
	
		
			
				
					}  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					static  bool  buffer_get_dmabuf ( struct  wlr_buffer  * wlr_buffer ,  
			
		
	
		
			
				
							struct  wlr_dmabuf_attributes  * attribs )  { 
 
			
		
	
		
			
				
						struct  wlr_gbm_buffer  * buffer  = 
 
			
		
	
		
			
				
							get_gbm_buffer_from_buffer ( wlr_buffer ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						memset ( attribs ,  0 ,  sizeof ( * attribs ) ) ; 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						// Only export the buffer once
 
 
			
		
	
		
			
				
						if  ( buffer - > dmabuf . n_planes  = =  0 )  { 
 
			
		
	
		
			
				
							if  ( ! buffer_create_dmabuf ( buffer ) )  { 
 
			
		
	
		
			
				
								return  false ; 
 
			
		
	
		
			
				
							} 
 
			
		
	
		
			
				
						} 
 
			
		
	
		
			
				
					
 
			
		
	
		
			
				
						memcpy ( attribs ,  & buffer - > dmabuf ,  sizeof ( buffer - > dmabuf ) ) ; 
 
			
		
	
		
			
				
						return  true ; 
 
			
		
	
		
			
				
					}