Introduce iced_renderer subcrate featuring runtime renderer fallback
This commit is contained in:
parent
368cadd25a
commit
5100b5d0a1
16 changed files with 371 additions and 72 deletions
|
|
@ -1,4 +1,5 @@
|
|||
//! Display rendering results on windows.
|
||||
mod compositor;
|
||||
pub mod compositor;
|
||||
|
||||
pub use compositor::Compositor;
|
||||
pub use wgpu::Surface;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{Backend, Color, Error, Renderer, Settings, Viewport};
|
||||
//! Connect a window with a renderer.
|
||||
use crate::{Backend, Color, Error, Primitive, Renderer, Settings, Viewport};
|
||||
|
||||
use futures::stream::{self, StreamExt};
|
||||
|
||||
use iced_graphics::compositor;
|
||||
use iced_graphics::window::compositor;
|
||||
use iced_native::futures;
|
||||
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
||||
|
||||
|
|
@ -112,6 +113,77 @@ impl<Theme> 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> iced_graphics::window::Compositor for Compositor<Theme> {
|
||||
type Settings = Settings;
|
||||
type Renderer = Renderer<Theme>;
|
||||
|
|
@ -121,13 +193,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)))
|
||||
}
|
||||
|
|
@ -178,49 +244,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,
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue