<NME> winit.rs
<BEF> use std::{
    sync::{atomic::Ordering, Mutex},
    time::Duration,
};

use slog::Logger;
#[cfg(feature = "debug")]
use smithay::backend::renderer::ImportMem;
};
use smithay::{
    backend::{
        winit::{self, WinitEvent},
        SwapBuffersError,
    },
    wayland::dmabuf::{DmabufGlobal, DmabufHandler, DmabufState, ImportError},
};
use smithay::{
    backend::{
        renderer::{
            damage::{DamageTrackedRenderer, DamageTrackedRendererError},
            element::AsRenderElements,
            gles2::{Gles2Renderer, Gles2Texture},
        },
        winit::{self, WinitEvent, WinitGraphicsBackend},
        SwapBuffersError,
    },
    input::pointer::{CursorImageAttributes, CursorImageStatus},
    output::{Mode, Output, PhysicalProperties, Subpixel},
    reexports::{
        calloop::EventLoop,
        wayland_server::{protocol::wl_surface, Display},
    },
    utils::{IsAlive, Point, Scale, Transform},
    wayland::{compositor, input_method::InputMethodSeat},
};

use crate::state::{AnvilState, Backend, CalloopData};
use crate::{drawing::*, render::*};

pub const OUTPUT_NAME: &str = "winit";

pub struct WinitData {
    backend: WinitGraphicsBackend,
    damage_tracked_renderer: DamageTrackedRenderer,
    #[cfg(feature = "egl")]
    let mut event_loop = EventLoop::try_new().unwrap();
    let display = Rc::new(RefCell::new(Display::new()));

    let (renderer, mut winit) = match winit::init(log.clone()) {
        Ok(ret) => ret,
        Err(err) => {
            slog::crit!(log, "Failed to initialize Winit backend: {}", err);
            return;
        }
    };
    let renderer = Rc::new(RefCell::new(renderer));

    #[cfg(feature = "egl")]
    if renderer
        .borrow_mut()
        .renderer()
        .bind_wl_display(&display.borrow())
        .is_ok()
    {
        info!(log, "EGL hardware-acceleration enabled");
        let dmabuf_formats = renderer
            .borrow_mut()
            .renderer()
            .dmabuf_formats()
            .cloned()
            .collect::<Vec<_>>();
        let renderer = renderer.clone();
        init_dmabuf_global(
            &mut *display.borrow_mut(),
            dmabuf_formats,
            move |buffer, _| renderer.borrow_mut().renderer().import_dmabuf(buffer).is_ok(),
            log.clone(),
        );
    };

    let size = renderer.borrow().window_size().physical_size;

    /*
     * Initialize the globals
    let (mut backend, mut winit) = match winit::init(log.clone()) {
        Ok(ret) => ret,
    let data = WinitData {
        #[cfg(feature = "debug")]
        fps_texture: import_bitmap(
            renderer.borrow_mut().renderer(),
            &image::io::Reader::with_format(std::io::Cursor::new(FPS_NUMBERS_PNG), image::ImageFormat::Png)
                .decode()
                .unwrap()
    let mode = Mode {
        size,
        refresh: 60_000,
    };
    let output = Output::new(
        OUTPUT_NAME.to_string(),
        PhysicalProperties {
            size: (0, 0).into(),
            subpixel: Subpixel::Unknown,
            make: "Smithay".into(),
            model: "Winit".into(),
        },
        log.clone(),
    );
    let _global = output.create_global::<AnvilState<WinitData>>(&display.handle());
    output.change_current_state(Some(mode), Some(Transform::Flipped180), None, Some((0, 0).into()));
    output.set_preferred(mode);

    #[cfg(feature = "debug")]
    let fps_image =
        image::io::Reader::with_format(std::io::Cursor::new(FPS_NUMBERS_PNG), image::ImageFormat::Png)
            .decode()
            .unwrap();
    #[cfg(feature = "debug")]
    let fps_texture = backend
        .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")]
    let mut fps_element = FpsElement::new(fps_texture);

    let data = {
        #[cfg(feature = "egl")]
        let dmabuf_state = if backend.renderer().bind_wl_display(&display.handle()).is_ok() {
            info!(log, "EGL hardware-acceleration enabled");
            let dmabuf_formats = backend.renderer().dmabuf_formats().cloned().collect::<Vec<_>>();
            let mut state = DmabufState::new();
            let global = state.create_global::<AnvilState<WinitData>, _>(
                &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,

        // drawing logic
        {
            let mut renderer = renderer.borrow_mut();
            // This is safe to do as with winit we are guaranteed to have exactly one output
            let (output_geometry, output_scale) = state
                .output_map
    #[cfg(feature = "xwayland")]
    state.start_xwayland();
                .map(|output| (output.geometry(), output.scale()))
                .unwrap();

            let result = renderer
                .render(|renderer, frame| {
                    render_layers_and_windows(
                        renderer,
                        frame,
                        &*state.window_map.borrow(),
                        output_geometry,
                        output_scale,
                        &log,
                    )?;

                    let (x, y) = state.pointer_location.into();

                    // draw the dnd icon if any
                    {
                        let guard = state.dnd_icon.lock().unwrap();
                        if let Some(ref surface) = *guard {
                            if surface.as_ref().is_alive() {
                                draw_dnd_icon(
                                    renderer,
                                    frame,
                                    surface,
                                    (x as i32, y as i32).into(),
                                    output_scale,
                                    &log,
                                )?;
                            }
                        }
                    }
                    // draw the cursor as relevant
                    {
                        let mut guard = state.cursor_status.lock().unwrap();
                        // reset the cursor if the surface is no longer alive
                        let mut reset = false;
                        if let CursorImageStatus::Image(ref surface) = *guard {
                            reset = !surface.as_ref().is_alive();
                        }
                        if reset {
                            *guard = CursorImageStatus::Default;
                        }

                        // draw as relevant
                        if let CursorImageStatus::Image(ref surface) = *guard {
                            cursor_visible = false;
                            draw_cursor(
                                renderer,
                                frame,
                                surface,
                                (x as i32, y as i32).into(),
                                output_scale,
                                &log,
                            )?;
                        } else {
                            cursor_visible = true;
                        }
                    }

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

                        draw_fps(
                            renderer,
                            frame,
                            &state.backend_data.fps_texture,
                            output_scale as f64,
                            fps,
                        )?;
                    }

                    Ok(())
                })
                .map_err(Into::<SwapBuffersError>::into)
                .and_then(|x| x);

            renderer.window().set_cursor_visible(cursor_visible);

            if let Err(SwapBuffersError::ContextLost(err)) = result {
                error!(log, "Critical Rendering Error: {}", err);

                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 apis

<DFF> @@ -9,6 +9,7 @@ use smithay::{
 };
 use smithay::{
     backend::{
+        renderer::{Renderer, Transform},
         winit::{self, WinitEvent},
         SwapBuffersError,
     },
@@ -46,39 +47,39 @@ pub fn run_winit(log: Logger) {
     let mut event_loop = EventLoop::try_new().unwrap();
     let display = Rc::new(RefCell::new(Display::new()));
 
-    let (renderer, mut winit) = match winit::init(log.clone()) {
+    let (backend, mut winit) = match winit::init(log.clone()) {
         Ok(ret) => ret,
         Err(err) => {
             slog::crit!(log, "Failed to initialize Winit backend: {}", err);
             return;
         }
     };
-    let renderer = Rc::new(RefCell::new(renderer));
+    let backend = Rc::new(RefCell::new(backend));
 
     #[cfg(feature = "egl")]
-    if renderer
+    if backend
         .borrow_mut()
         .renderer()
         .bind_wl_display(&display.borrow())
         .is_ok()
     {
         info!(log, "EGL hardware-acceleration enabled");
-        let dmabuf_formats = renderer
+        let dmabuf_formats = backend
             .borrow_mut()
             .renderer()
             .dmabuf_formats()
             .cloned()
             .collect::<Vec<_>>();
-        let renderer = renderer.clone();
+        let backend = backend.clone();
         init_dmabuf_global(
             &mut *display.borrow_mut(),
             dmabuf_formats,
-            move |buffer, _| renderer.borrow_mut().renderer().import_dmabuf(buffer).is_ok(),
+            move |buffer, _| backend.borrow_mut().renderer().import_dmabuf(buffer).is_ok(),
             log.clone(),
         );
     };
 
-    let size = renderer.borrow().window_size().physical_size;
+    let size = backend.borrow().window_size().physical_size;
 
     /*
      * Initialize the globals
@@ -87,7 +88,7 @@ pub fn run_winit(log: Logger) {
     let data = WinitData {
         #[cfg(feature = "debug")]
         fps_texture: import_bitmap(
-            renderer.borrow_mut().renderer(),
+            backend.borrow_mut().renderer(),
             &image::io::Reader::with_format(std::io::Cursor::new(FPS_NUMBERS_PNG), image::ImageFormat::Png)
                 .decode()
                 .unwrap()
@@ -153,7 +154,7 @@ pub fn run_winit(log: Logger) {
 
         // drawing logic
         {
-            let mut renderer = renderer.borrow_mut();
+            let mut backend = backend.borrow_mut();
             // This is safe to do as with winit we are guaranteed to have exactly one output
             let (output_geometry, output_scale) = state
                 .output_map
@@ -162,82 +163,88 @@ pub fn run_winit(log: Logger) {
                 .map(|output| (output.geometry(), output.scale()))
                 .unwrap();
 
-            let result = renderer
-                .render(|renderer, frame| {
-                    render_layers_and_windows(
-                        renderer,
-                        frame,
-                        &*state.window_map.borrow(),
-                        output_geometry,
-                        output_scale,
-                        &log,
-                    )?;
-
-                    let (x, y) = state.pointer_location.into();
-
-                    // draw the dnd icon if any
-                    {
-                        let guard = state.dnd_icon.lock().unwrap();
-                        if let Some(ref surface) = *guard {
-                            if surface.as_ref().is_alive() {
-                                draw_dnd_icon(
-                                    renderer,
-                                    frame,
-                                    surface,
-                                    (x as i32, y as i32).into(),
-                                    output_scale,
-                                    &log,
-                                )?;
-                            }
-                        }
-                    }
-                    // draw the cursor as relevant
-                    {
-                        let mut guard = state.cursor_status.lock().unwrap();
-                        // reset the cursor if the surface is no longer alive
-                        let mut reset = false;
-                        if let CursorImageStatus::Image(ref surface) = *guard {
-                            reset = !surface.as_ref().is_alive();
-                        }
-                        if reset {
-                            *guard = CursorImageStatus::Default;
-                        }
-
-                        // draw as relevant
-                        if let CursorImageStatus::Image(ref surface) = *guard {
-                            cursor_visible = false;
-                            draw_cursor(
+            let result = backend
+                .bind()
+                .and_then(|_| {
+                    backend
+                        .renderer()
+                        .render(size, Transform::Flipped180, |renderer, frame| {
+                            render_layers_and_windows(
                                 renderer,
                                 frame,
-                                surface,
-                                (x as i32, y as i32).into(),
+                                &*state.window_map.borrow(),
+                                output_geometry,
                                 output_scale,
                                 &log,
                             )?;
-                        } else {
-                            cursor_visible = true;
-                        }
-                    }
-
-                    #[cfg(feature = "debug")]
-                    {
-                        let fps = state.backend_data.fps.avg().round() as u32;
-
-                        draw_fps(
-                            renderer,
-                            frame,
-                            &state.backend_data.fps_texture,
-                            output_scale as f64,
-                            fps,
-                        )?;
-                    }
-
-                    Ok(())
+
+                            let (x, y) = state.pointer_location.into();
+
+                            // draw the dnd icon if any
+                            {
+                                let guard = state.dnd_icon.lock().unwrap();
+                                if let Some(ref surface) = *guard {
+                                    if surface.as_ref().is_alive() {
+                                        draw_dnd_icon(
+                                            renderer,
+                                            frame,
+                                            surface,
+                                            (x as i32, y as i32).into(),
+                                            output_scale,
+                                            &log,
+                                        )?;
+                                    }
+                                }
+                            }
+                            // draw the cursor as relevant
+                            {
+                                let mut guard = state.cursor_status.lock().unwrap();
+                                // reset the cursor if the surface is no longer alive
+                                let mut reset = false;
+                                if let CursorImageStatus::Image(ref surface) = *guard {
+                                    reset = !surface.as_ref().is_alive();
+                                }
+                                if reset {
+                                    *guard = CursorImageStatus::Default;
+                                }
+
+                                // draw as relevant
+                                if let CursorImageStatus::Image(ref surface) = *guard {
+                                    cursor_visible = false;
+                                    draw_cursor(
+                                        renderer,
+                                        frame,
+                                        surface,
+                                        (x as i32, y as i32).into(),
+                                        output_scale,
+                                        &log,
+                                    )?;
+                                } else {
+                                    cursor_visible = true;
+                                }
+                            }
+
+                            #[cfg(feature = "debug")]
+                            {
+                                let fps = state.backend_data.fps.avg().round() as u32;
+
+                                draw_fps(
+                                    renderer,
+                                    frame,
+                                    &state.backend_data.fps_texture,
+                                    output_scale as f64,
+                                    fps,
+                                )?;
+                            }
+
+                            Ok(())
+                        })
+                        .map_err(Into::<SwapBuffersError>::into)
+                        .and_then(|x| x)
                 })
-                .map_err(Into::<SwapBuffersError>::into)
-                .and_then(|x| x);
+                .and_then(|_| backend.submit(None, 1.0));
 
-            renderer.window().set_cursor_visible(cursor_visible);
+            backend.window().set_cursor_visible(cursor_visible);
 
             if let Err(SwapBuffersError::ContextLost(err)) = result {
                 error!(log, "Critical Rendering Error: {}", err);

anvil: Update to new apis