<NME> winit.rs
<BEF> use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration};

//#[cfg(feature = "egl")]
//use smithay::backend::egl::EGLGraphicsBackend;
use smithay::{
    backend::{input::InputBackend, renderer::Renderer, winit, SwapBuffersError},
    reexports::{
use slog::Logger;
#[cfg(feature = "debug")]
use smithay::backend::renderer::ImportMem;
#[cfg(feature = "egl")]
use smithay::{
    backend::{
        allocator::dmabuf::Dmabuf,
        renderer::{ImportDma, ImportEgl},

use slog::Logger;

use crate::buffer_utils::BufferUtils;
use crate::drawing::*;
use crate::state::AnvilState;

        renderer::{
            damage::{DamageTrackedRenderer, DamageTrackedRendererError},
    event_loop: &mut EventLoop<AnvilState>,
    log: Logger,
) -> Result<(), ()> {
    let (mut renderer, mut input) = winit::init(log.clone()).map_err(|err| {
        slog::crit!(log, "Failed to initialize Winit backend: {}", err);
    })?;

    #[cfg(feature = "egl")]
    let egl_buffer_reader = Rc::new(RefCell::new(
        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
            info!(log, "EGL hardware-acceleration enabled");
            Some(egl_buffer_reader)
        } else {
            None
        },
    ));

    #[cfg(feature = "egl")]
    let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone());
    #[cfg(not(feature = "egl"))]
    let buffer_utils = BufferUtils::new(log.clone());

    let (w, h): (u32, u32) = renderer.window_size().physical_size.into();

    /*
     * Initialize the globals
    backend: WinitGraphicsBackend,
    damage_tracked_renderer: DamageTrackedRenderer,
    let mut state = AnvilState::init(
        display.clone(),
        event_loop.handle(),
        buffer_utils.clone(),
        None,
        None,
        log.clone(),
impl DmabufHandler for AnvilState<WinitData> {
    fn dmabuf_state(&mut self) -> &mut DmabufState {
        &mut self.backend_data.dmabuf_state.as_mut().unwrap().0
    }

    fn dmabuf_imported(&mut self, _global: &DmabufGlobal, dmabuf: Dmabuf) -> Result<(), ImportError> {
        self.backend_data
            .backend
            .renderer()
            .import_dmabuf(&dmabuf, None)
            .map(|_| ())
            .map_err(|_| ImportError::Failed)
    }
}
#[cfg(feature = "egl")]
delegate_dmabuf!(AnvilState<WinitData>);

impl Backend for WinitData {
    fn seat_name(&self) -> String {
        String::from("winit")
    }
    fn reset_buffers(&mut self, _output: &Output) {
        self.full_redraw = 4;
    }
    fn early_import(&mut self, _surface: &wl_surface::WlSurface) {}
}

pub fn run_winit(log: Logger) {
    let mut event_loop = EventLoop::try_new().unwrap();
    let mut display = Display::new().unwrap();


    info!(log, "Initialization completed, starting the main loop.");

    let (texture_send, texture_receive) = std::sync::mpsc::channel();
    while state.running.load(Ordering::SeqCst) {
        if input
            .dispatch_new_events(|event, _| state.process_input_event(event))
        }
    };
    let size = backend.window_size().physical_size;

    let mode = Mode {
        size,
        refresh: 60_000,
    };
    let output = Output::new(
        OUTPUT_NAME.to_string(),
        PhysicalProperties {
            size: (0, 0).into(),

        // drawing logic
        {
            renderer.begin().expect("Failed to render frame");
            renderer
                .clear([0.8, 0.8, 0.9, 1.0])
    output.set_preferred(mode);

            // draw the windows
            draw_windows(
                &mut renderer,
                0,
                &texture_send,
                &buffer_utils,
                &*state.window_map.borrow(),
                None,
                state.ctoken,
        .renderer()
        .import_memory(
            &fps_image.to_rgba8(),
            (fps_image.width() as i32, fps_image.height() as i32).into(),
            false,
        )
        .expect("Unable to upload FPS texture");
    #[cfg(feature = "debug")]
                if let Some(ref surface) = *guard {
                    if surface.as_ref().is_alive() {
                        draw_dnd_icon(
                            &mut renderer,
                            0,
                            &texture_send,
                            &buffer_utils,
                            surface,
                            (x as i32, y as i32),
                            state.ctoken,
                            &log,
                &display.handle(),
                dmabuf_formats,
                log.clone(),
            );
            Some((state, global))
        } else {
            None
        };

        let damage_tracked_renderer = DamageTrackedRenderer::from_output(&output);

        WinitData {
            backend,
            damage_tracked_renderer,
            #[cfg(feature = "egl")]
            dmabuf_state,
            full_redraw: 0,
            #[cfg(feature = "debug")]
                if let CursorImageStatus::Image(ref surface) = *guard {
                    renderer.window().set_cursor_visible(false);
                    draw_cursor(
                        &mut renderer,
                        0,
                        &texture_send,
                        &buffer_utils,
                        surface,
                        (x as i32, y as i32),
                        state.ctoken,
                        &log,
    info!(log, "Initialization completed, starting the main loop.");

    let mut pointer_element = PointerElement::<Gles2Texture>::default();

    while state.running.load(Ordering::SeqCst) {
        if winit
            .dispatch_new_events(|event| match event {
                WinitEvent::Resized { size, .. } => {
                    // We only have one output
                    let output = state.space.outputs().next().unwrap().clone();
                    state.space.map_output(&output, (0, 0));
                    let mode = Mode {
                        size,
                        refresh: 60_000,
                    };
                    output.change_current_state(Some(mode), None, None, None);
                    output.set_preferred(mode);
                    crate::shell::fixup_positions(&mut state.space);
                }
            display.borrow_mut().flush_clients(&mut state);
            state.window_map.borrow_mut().refresh();
        }

        while let Ok(texture) = texture_receive.try_recv() {
            let _ = renderer.destroy_texture(texture);
        }
    }

    // Cleanup stuff
        {
            state.running.store(false, Ordering::SeqCst);
            break;
        }

        // drawing logic
        {
            let backend = &mut state.backend_data.backend;

            let mut cursor_guard = state.cursor_status.lock().unwrap();

            // draw the cursor as relevant
            // reset the cursor if the surface is no longer alive
            let mut reset = false;
            if let CursorImageStatus::Surface(ref surface) = *cursor_guard {
                reset = !surface.alive();
            }
            if reset {
                *cursor_guard = CursorImageStatus::Default;
            }
            let cursor_visible = !matches!(*cursor_guard, CursorImageStatus::Surface(_));

            pointer_element.set_status(cursor_guard.clone());

            #[cfg(feature = "debug")]
            let fps = state.backend_data.fps.avg().round() as u32;
            #[cfg(feature = "debug")]
            fps_element.update_fps(fps);

            let full_redraw = &mut state.backend_data.full_redraw;
            *full_redraw = full_redraw.saturating_sub(1);
            let space = &mut state.space;
            let damage_tracked_renderer = &mut state.backend_data.damage_tracked_renderer;

            let input_method = state.seat.input_method().unwrap();
            let dnd_icon = state.dnd_icon.as_ref();

            let scale = Scale::from(output.current_scale().fractional_scale());
            let cursor_hotspot = if let CursorImageStatus::Surface(ref surface) = *cursor_guard {
                compositor::with_states(surface, |states| {
                    states
                        .data_map
                        .get::<Mutex<CursorImageAttributes>>()
                        .unwrap()
                        .lock()
                        .unwrap()
                        .hotspot
                })
            } else {
                (0, 0).into()
            };
            let cursor_pos = state.pointer_location - cursor_hotspot.to_f64();
            let cursor_pos_scaled = cursor_pos.to_physical(scale).to_i32_round();

            let render_res = backend.bind().and_then(|_| {
                let age = if *full_redraw > 0 {
                    0
                } else {
                    backend.buffer_age().unwrap_or(0)
                };

                let renderer = backend.renderer();

                let mut elements = Vec::<CustomRenderElements<Gles2Renderer>>::new();

                elements.extend(pointer_element.render_elements(cursor_pos_scaled, scale));

                // draw input method surface if any
                let rectangle = input_method.coordinates();
                let position = Point::from((
                    rectangle.loc.x + rectangle.size.w,
                    rectangle.loc.y + rectangle.size.h,
                ));
                input_method.with_surface(|surface| {
                    elements.extend(AsRenderElements::<Gles2Renderer>::render_elements(
                        &smithay::desktop::space::SurfaceTree::from_surface(surface),
                        position.to_physical_precise_round(scale),
                        scale,
                    ));
                });

                // draw the dnd icon if any
                if let Some(surface) = dnd_icon {
                    if surface.alive() {
                        elements.extend(AsRenderElements::<Gles2Renderer>::render_elements(
                            &smithay::desktop::space::SurfaceTree::from_surface(surface),
                            cursor_pos_scaled,
                            scale,
                        ));
                    }
                }

                #[cfg(feature = "debug")]
                elements.push(CustomRenderElements::Fps(fps_element.clone()));

                render_output(
                    &output,
                    space,
                    &elements,
                    renderer,
                    damage_tracked_renderer,
                    age,
                    &log,
                )
                .map_err(|err| match err {
                    DamageTrackedRendererError::Rendering(err) => err.into(),
                    _ => unreachable!(),
                })
            });

            match render_res {
                Ok((damage, states)) => {
                    if let Some(damage) = damage {
                        if let Err(err) = backend.submit(Some(&*damage)) {
                            warn!(log, "Failed to submit buffer: {}", err);
                        }
                    }
                    backend.window().set_cursor_visible(cursor_visible);

                    // Send frame events so that client start drawing their next frame
                    state.send_frames(&output, &states);
                }
                Err(SwapBuffersError::ContextLost(err)) => {
                    error!(log, "Critical Rendering Error: {}", err);
                    state.running.store(false, Ordering::SeqCst);
                }
                Err(err) => warn!(log, "Rendering error: {}", err),
            }
        }

        let mut calloop_data = CalloopData { state, display };
        let result = event_loop.dispatch(Some(Duration::from_millis(16)), &mut calloop_data);
        CalloopData { state, display } = calloop_data;

        if result.is_err() {
            state.running.store(false, Ordering::SeqCst);
        } else {
            state.space.refresh();
            state.popups.cleanup();
            display.flush_clients().unwrap();
        }

        #[cfg(feature = "debug")]
        state.backend_data.fps.tick();
    }
}

<MSG> anvil: Update to new renderer changes

<DFF> @@ -1,7 +1,5 @@
 use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration};
 
-//#[cfg(feature = "egl")]
-//use smithay::backend::egl::EGLGraphicsBackend;
 use smithay::{
     backend::{input::InputBackend, renderer::Renderer, winit, SwapBuffersError},
     reexports::{
@@ -16,7 +14,6 @@ use smithay::{
 
 use slog::Logger;
 
-use crate::buffer_utils::BufferUtils;
 use crate::drawing::*;
 use crate::state::AnvilState;
 
@@ -25,26 +22,22 @@ pub fn run_winit(
     event_loop: &mut EventLoop<AnvilState>,
     log: Logger,
 ) -> Result<(), ()> {
-    let (mut renderer, mut input) = winit::init(log.clone()).map_err(|err| {
+    let (renderer, mut input) = winit::init(log.clone()).map_err(|err| {
         slog::crit!(log, "Failed to initialize Winit backend: {}", err);
     })?;
+    let renderer = Rc::new(RefCell::new(renderer));
 
     #[cfg(feature = "egl")]
-    let egl_buffer_reader = Rc::new(RefCell::new(
-        if let Ok(egl_buffer_reader) = renderer.bind_wl_display(&display.borrow()) {
-            info!(log, "EGL hardware-acceleration enabled");
-            Some(egl_buffer_reader)
-        } else {
-            None
-        },
-    ));
+    let reader = renderer.borrow().bind_wl_display(&display.borrow()).ok();
+    #[cfg(not(feature = "egl"))]
+    let reader = None;
 
     #[cfg(feature = "egl")]
-    let buffer_utils = BufferUtils::new(egl_buffer_reader, log.clone());
-    #[cfg(not(feature = "egl"))]
-    let buffer_utils = BufferUtils::new(log.clone());
+    if reader.is_some() {
+        info!(log, "EGL hardware-acceleration enabled");
+    };
 
-    let (w, h): (u32, u32) = renderer.window_size().physical_size.into();
+    let (w, h): (u32, u32) = renderer.borrow().window_size().physical_size.into();
 
     /*
      * Initialize the globals
@@ -53,7 +46,8 @@ pub fn run_winit(
     let mut state = AnvilState::init(
         display.clone(),
         event_loop.handle(),
-        buffer_utils.clone(),
+        #[cfg(feature = "egl")]
+        Rc::new(RefCell::new(reader.clone())),
         None,
         None,
         log.clone(),
@@ -91,7 +85,6 @@ pub fn run_winit(
 
     info!(log, "Initialization completed, starting the main loop.");
 
-    let (texture_send, texture_receive) = std::sync::mpsc::channel();
     while state.running.load(Ordering::SeqCst) {
         if input
             .dispatch_new_events(|event, _| state.process_input_event(event))
@@ -110,6 +103,8 @@ pub fn run_winit(
 
         // drawing logic
         {
+            let mut renderer = renderer.borrow_mut();
+
             renderer.begin().expect("Failed to render frame");
             renderer
                 .clear([0.8, 0.8, 0.9, 1.0])
@@ -117,10 +112,8 @@ pub fn run_winit(
 
             // draw the windows
             draw_windows(
-                &mut renderer,
-                0,
-                &texture_send,
-                &buffer_utils,
+                &mut *renderer,
+                reader.as_ref(),
                 &*state.window_map.borrow(),
                 None,
                 state.ctoken,
@@ -135,11 +128,9 @@ pub fn run_winit(
                 if let Some(ref surface) = *guard {
                     if surface.as_ref().is_alive() {
                         draw_dnd_icon(
-                            &mut renderer,
-                            0,
-                            &texture_send,
-                            &buffer_utils,
+                            &mut *renderer,
                             surface,
+                            reader.as_ref(),
                             (x as i32, y as i32),
                             state.ctoken,
                             &log,
@@ -164,11 +155,9 @@ pub fn run_winit(
                 if let CursorImageStatus::Image(ref surface) = *guard {
                     renderer.window().set_cursor_visible(false);
                     draw_cursor(
-                        &mut renderer,
-                        0,
-                        &texture_send,
-                        &buffer_utils,
+                        &mut *renderer,
                         surface,
+                        reader.as_ref(),
                         (x as i32, y as i32),
                         state.ctoken,
                         &log,
@@ -194,10 +183,6 @@ pub fn run_winit(
             display.borrow_mut().flush_clients(&mut state);
             state.window_map.borrow_mut().refresh();
         }
-
-        while let Ok(texture) = texture_receive.try_recv() {
-            let _ = renderer.destroy_texture(texture);
-        }
     }
 
     // Cleanup stuff

anvil: Update to new renderer changes