11use super :: buffer_params:: BufferParams ;
2- use crate :: wayland:: GraphicsInfo ;
2+ use crate :: wayland:: { GraphicsInfo , Message , MessageSink , core:: buffer:: Buffer } ;
3+ use drm_fourcc:: DrmFourcc ;
34use khronos_egl:: { self as egl, ClientBuffer } ;
45use mint:: Vector2 ;
56use std:: {
@@ -25,93 +26,140 @@ const EGL_NO_BUFFER: *mut std::ffi::c_void = std::ptr::null_mut();
2526#[ derive( Debug ) ]
2627pub struct DmabufBacking {
2728 params : Arc < BufferParams > ,
29+ message_sink : Option < MessageSink > ,
2830 size : Vector2 < usize > ,
29- format : u32 ,
31+ format : DrmFourcc ,
3032 _flags : Flags ,
3133 tex : OnceLock < Tex > ,
3234}
3335
3436impl DmabufBacking {
35- pub fn new ( params : Arc < BufferParams > , size : Vector2 < usize > , format : u32 , flags : Flags ) -> Self {
37+ pub fn new (
38+ params : Arc < BufferParams > ,
39+ message_sink : Option < MessageSink > ,
40+ size : Vector2 < usize > ,
41+ format : DrmFourcc ,
42+ flags : Flags ,
43+ ) -> Self {
44+ tracing:: info!(
45+ "Creating new DmabufBacking with BufferParams {:?}" ,
46+ params. id
47+ ) ;
3648 Self {
3749 params,
50+ message_sink,
3851 size,
3952 format,
4053 _flags : flags,
4154 tex : OnceLock :: new ( ) ,
4255 }
4356 }
4457
45- pub fn update_tex ( & self , graphics_info : & GraphicsInfo ) -> Option < Tex > {
46- let tex_ref = self . tex . get_or_init ( || {
47- let mut tex = Tex :: new (
48- TexType :: ImageNomips | TexType :: Dynamic ,
49- TexFormat :: RGBA32 ,
50- nanoid:: nanoid!( ) ,
58+ fn import_dmabuf ( & self , graphics_info : & GraphicsInfo ) -> Result < Tex , khronos_egl:: Error > {
59+ let mut tex = Tex :: new (
60+ TexType :: ImageNomips | TexType :: Dynamic ,
61+ TexFormat :: RGBA32 ,
62+ nanoid:: nanoid!( ) ,
63+ ) ;
64+
65+ tracing:: info!( format=?self . format, "Wayland: Updating DMABuf tex" ) ;
66+
67+ // Get plane info from params
68+ let planes = self . params . lock_planes ( ) ;
69+ let Some ( plane) = planes. get ( & 0 ) else {
70+ tracing:: error!(
71+ "Wayland: Failed to get plane 0 from BufferParams {:?}" ,
72+ self . params. id
5173 ) ;
74+ return Err ( khronos_egl:: Error :: BadParameter ) ;
75+ } ;
76+ tracing:: info!(
77+ "Using plane 0 with fd {} from BufferParams {:?}" ,
78+ plane. fd. as_raw_fd( ) ,
79+ self . params. id
80+ ) ;
81+ // Create EGL image
82+ let image = graphics_info. egl_instance . create_image (
83+ graphics_info. display ,
84+ graphics_info. context ,
85+ EGL_LINUX_DMA_BUF_EXT as u32 ,
86+ unsafe { ClientBuffer :: from_ptr ( EGL_NO_BUFFER ) } ,
87+ & [
88+ EGL_WIDTH as usize ,
89+ self . size . x as usize ,
90+ EGL_HEIGHT as usize ,
91+ self . size . y as usize ,
92+ EGL_LINUX_DRM_FOURCC_EXT as usize ,
93+ self . format as usize ,
94+ EGL_DMA_BUF_PLANE0_FD_EXT as usize ,
95+ plane. fd . as_raw_fd ( ) as usize , // EGL will dup() this fd internally
96+ EGL_DMA_BUF_PLANE0_OFFSET_EXT as usize ,
97+ plane. offset as usize ,
98+ EGL_DMA_BUF_PLANE0_PITCH_EXT as usize ,
99+ plane. stride as usize ,
100+ EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT as usize ,
101+ 0 ,
102+ EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT as usize ,
103+ 0 ,
104+ egl:: ATTRIB_NONE ,
105+ 0 ,
106+ ] ,
107+ ) ?;
108+
109+ // The cloned fd will be consumed by create_image, so we don't need to explicitly close it
110+ // Create and bind GL texture
111+ let mut gl_tex = 0 ;
112+ unsafe {
113+ gl:: GenTextures ( 1 , & mut gl_tex) ;
114+ gl:: BindTexture ( gl:: TEXTURE_2D , gl_tex) ;
115+ }
52116
53- // Get plane info from params
54- let planes = self . params . lock_planes ( ) ;
55- if let Some ( plane) = planes. get ( & 0 ) {
56- // Create EGL image
57- let image = graphics_info. egl_instance . create_image (
58- graphics_info. display ,
59- graphics_info. context ,
60- EGL_LINUX_DMA_BUF_EXT as u32 ,
61- unsafe { ClientBuffer :: from_ptr ( EGL_NO_BUFFER ) } ,
62- & [
63- EGL_WIDTH as usize ,
64- self . size . x as usize ,
65- EGL_HEIGHT as usize ,
66- self . size . y as usize ,
67- EGL_LINUX_DRM_FOURCC_EXT as usize ,
68- self . format as usize ,
69- EGL_DMA_BUF_PLANE0_FD_EXT as usize ,
70- plane. fd . as_raw_fd ( ) as usize ,
71- EGL_DMA_BUF_PLANE0_OFFSET_EXT as usize ,
72- plane. offset as usize ,
73- EGL_DMA_BUF_PLANE0_PITCH_EXT as usize ,
74- plane. stride as usize ,
75- EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT as usize ,
76- 0 ,
77- EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT as usize ,
78- 0 ,
79- egl:: ATTRIB_NONE ,
80- 0 ,
81- ] ,
82- ) ;
117+ // Set the native texture handle directly
118+ // Mesa will handle the OES texture implicitly
119+ tex. set_native_surface (
120+ gl_tex as * mut std:: os:: raw:: c_void ,
121+ TexType :: ImageNomips | TexType :: Dynamic ,
122+ 0x8058 , // GL_RGBA8
123+ self . size . x as i32 ,
124+ self . size . y as i32 ,
125+ 1 , // single surface
126+ true , // we own this texture
127+ ) ;
83128
84- if let Ok ( image) = image {
85- // Create and bind GL texture
86- let mut gl_tex = 0 ;
87- unsafe {
88- gl:: GenTextures ( 1 , & mut gl_tex) ;
89- gl:: BindTexture ( gl:: TEXTURE_2D , gl_tex) ;
90- }
129+ // Clean up EGL image
130+ graphics_info
131+ . egl_instance
132+ . destroy_image ( graphics_info. display , image)
133+ . ok ( ) ;
91134
92- // Set the native texture handle directly
93- // Mesa will handle the OES texture implicitly
94- tex. set_native_surface (
95- gl_tex as * mut std:: os:: raw:: c_void ,
96- TexType :: ImageNomips | TexType :: Dynamic ,
97- 0x8058 , // GL_RGBA8
98- self . size . x as i32 ,
99- self . size . y as i32 ,
100- 1 , // single surface
101- true , // we own this texture
102- ) ;
135+ Ok ( tex)
136+ }
103137
104- // Clean up EGL image
105- graphics_info
106- . egl_instance
107- . destroy_image ( graphics_info. display , image)
108- . ok ( ) ;
138+ pub fn init_tex ( & self , graphics_info : & GraphicsInfo , buffer : Arc < Buffer > ) {
139+ if self . tex . get ( ) . is_none ( ) {
140+ match self . import_dmabuf ( graphics_info) {
141+ Ok ( tex) => {
142+ let _ = self . tex . set ( tex) ;
143+ let _ = self
144+ . message_sink
145+ . as_ref ( )
146+ . unwrap ( )
147+ . send ( Message :: DmabufImportSuccess ( self . params . clone ( ) , buffer) ) ;
148+ }
149+ Err ( e) => {
150+ tracing:: error!( "Wayland: Error initializing DMABuf tex: {:?}" , e) ;
151+ let _ = self
152+ . message_sink
153+ . as_ref ( )
154+ . unwrap ( )
155+ . send ( Message :: DmabufImportFailure ( self . params . clone ( ) ) ) ;
109156 }
110- }
157+ } ;
158+ }
159+ }
111160
112- tex
113- } ) ;
114- Tex :: find ( tex_ref. get_id ( ) ) . ok ( )
161+ pub fn get_tex ( & self ) -> Option < & Tex > {
162+ self . tex . get ( )
115163 }
116164
117165 pub fn size ( & self ) -> Vector2 < usize > {
0 commit comments