diff options
| author | 2023-03-09 19:05:38 +0100 | |
|---|---|---|
| committer | 2023-03-09 19:05:38 +0100 | |
| commit | caf2836b1b15bff6e8a2ea72441d67f297eb8707 (patch) | |
| tree | 0ffa0d1d604780999892b88de85ee93e3ed7d539 /wgpu/src/window | |
| parent | 11b2c3bbe31a43e73a61b9bd9f022233f302ae27 (diff) | |
| parent | 424ac8177309440bbd8efe0dd9f7622cb10807ce (diff) | |
| download | iced-caf2836b1b15bff6e8a2ea72441d67f297eb8707.tar.gz iced-caf2836b1b15bff6e8a2ea72441d67f297eb8707.tar.bz2 iced-caf2836b1b15bff6e8a2ea72441d67f297eb8707.zip | |
Merge pull request #1748 from iced-rs/feature/software-renderer
Software renderer, runtime renderer fallback, and core consolidation
Diffstat (limited to 'wgpu/src/window')
| -rw-r--r-- | wgpu/src/window/compositor.rs | 155 | 
1 files changed, 97 insertions, 58 deletions
| diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 365cb603..a67ac3c0 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -1,9 +1,12 @@ -use crate::{Backend, Color, Error, Renderer, Settings, Viewport}; +//! Connect a window with a renderer. +use crate::core::Color; +use crate::graphics; +use crate::graphics::compositor; +use crate::graphics::{Error, Primitive, Viewport}; +use crate::{Backend, Renderer, Settings};  use futures::stream::{self, StreamExt}; -use iced_graphics::compositor; -use iced_native::futures;  use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};  use std::marker::PhantomData; @@ -112,7 +115,78 @@ impl<Theme> Compositor<Theme> {      }  } -impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> { +/// Creates a [`Compositor`] and its [`Backend`] for the given [`Settings`] and +/// window. +pub fn new<Theme, W: HasRawWindowHandle + HasRawDisplayHandle>( +    settings: Settings, +    compatible_window: Option<&W>, +) -> Result<(Compositor<Theme>, Backend), Error> { +    let compositor = futures::executor::block_on(Compositor::request( +        settings, +        compatible_window, +    )) +    .ok_or(Error::GraphicsAdapterNotFound)?; + +    let backend = compositor.create_backend(); + +    Ok((compositor, backend)) +} + +/// Presents the given primitives with the given [`Compositor`] and [`Backend`]. +pub fn present<Theme, T: AsRef<str>>( +    compositor: &mut Compositor<Theme>, +    backend: &mut Backend, +    surface: &mut wgpu::Surface, +    primitives: &[Primitive], +    viewport: &Viewport, +    background_color: Color, +    overlay: &[T], +) -> Result<(), compositor::SurfaceError> { +    match surface.get_current_texture() { +        Ok(frame) => { +            let mut encoder = compositor.device.create_command_encoder( +                &wgpu::CommandEncoderDescriptor { +                    label: Some("iced_wgpu encoder"), +                }, +            ); + +            let view = &frame +                .texture +                .create_view(&wgpu::TextureViewDescriptor::default()); + +            backend.present( +                &compositor.device, +                &compositor.queue, +                &mut encoder, +                Some(background_color), +                view, +                primitives, +                viewport, +                overlay, +            ); + +            // Submit work +            let _submission = compositor.queue.submit(Some(encoder.finish())); +            frame.present(); + +            Ok(()) +        } +        Err(error) => match error { +            wgpu::SurfaceError::Timeout => { +                Err(compositor::SurfaceError::Timeout) +            } +            wgpu::SurfaceError::Outdated => { +                Err(compositor::SurfaceError::Outdated) +            } +            wgpu::SurfaceError::Lost => Err(compositor::SurfaceError::Lost), +            wgpu::SurfaceError::OutOfMemory => { +                Err(compositor::SurfaceError::OutOfMemory) +            } +        }, +    } +} + +impl<Theme> graphics::Compositor for Compositor<Theme> {      type Settings = Settings;      type Renderer = Renderer<Theme>;      type Surface = wgpu::Surface; @@ -121,13 +195,7 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {          settings: Self::Settings,          compatible_window: Option<&W>,      ) -> Result<(Self, Self::Renderer), Error> { -        let compositor = futures::executor::block_on(Self::request( -            settings, -            compatible_window, -        )) -        .ok_or(Error::GraphicsAdapterNotFound)?; - -        let backend = compositor.create_backend(); +        let (compositor, backend) = new(settings, compatible_window)?;          Ok((compositor, Renderer::new(backend)))      } @@ -135,11 +203,15 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {      fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(          &mut self,          window: &W, +        width: u32, +        height: u32,      ) -> wgpu::Surface {          #[allow(unsafe_code)] -        unsafe { -            self.instance.create_surface(window) -        } +        let mut surface = unsafe { self.instance.create_surface(window) }; + +        self.configure_surface(&mut surface, width, height); + +        surface      }      fn configure_surface( @@ -178,49 +250,16 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {          background_color: Color,          overlay: &[T],      ) -> Result<(), compositor::SurfaceError> { -        match surface.get_current_texture() { -            Ok(frame) => { -                let mut encoder = self.device.create_command_encoder( -                    &wgpu::CommandEncoderDescriptor { -                        label: Some("iced_wgpu encoder"), -                    }, -                ); - -                let view = &frame -                    .texture -                    .create_view(&wgpu::TextureViewDescriptor::default()); - -                renderer.with_primitives(|backend, primitives| { -                    backend.present( -                        &self.device, -                        &self.queue, -                        &mut encoder, -                        Some(background_color), -                        view, -                        primitives, -                        viewport, -                        overlay, -                    ); -                }); - -                // Submit work -                let _submission = self.queue.submit(Some(encoder.finish())); -                frame.present(); - -                Ok(()) -            } -            Err(error) => match error { -                wgpu::SurfaceError::Timeout => { -                    Err(compositor::SurfaceError::Timeout) -                } -                wgpu::SurfaceError::Outdated => { -                    Err(compositor::SurfaceError::Outdated) -                } -                wgpu::SurfaceError::Lost => Err(compositor::SurfaceError::Lost), -                wgpu::SurfaceError::OutOfMemory => { -                    Err(compositor::SurfaceError::OutOfMemory) -                } -            }, -        } +        renderer.with_primitives(|backend, primitives| { +            present( +                self, +                backend, +                surface, +                primitives, +                viewport, +                background_color, +                overlay, +            ) +        })      }  } | 
