2023-03-04 05:37:11 +01:00
|
|
|
use crate::core::Color;
|
|
|
|
|
use crate::graphics::compositor::{self, Information, SurfaceError};
|
|
|
|
|
use crate::graphics::{Error, Primitive, Viewport};
|
|
|
|
|
use crate::{Backend, Renderer, Settings};
|
2023-02-25 15:38:25 +01:00
|
|
|
|
|
|
|
|
use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle};
|
|
|
|
|
use std::marker::PhantomData;
|
2023-04-05 19:23:48 +02:00
|
|
|
use std::num::NonZeroU32;
|
2023-02-25 15:38:25 +01:00
|
|
|
|
|
|
|
|
pub struct Compositor<Theme> {
|
2023-03-02 00:40:36 +01:00
|
|
|
clip_mask: tiny_skia::ClipMask,
|
2023-02-25 15:38:25 +01:00
|
|
|
_theme: PhantomData<Theme>,
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 16:05:42 +01:00
|
|
|
pub struct Surface {
|
2023-04-05 19:23:48 +02:00
|
|
|
window: softbuffer::Surface,
|
2023-02-25 16:05:42 +01:00
|
|
|
}
|
2023-02-25 15:38:25 +01:00
|
|
|
|
2023-03-04 05:37:11 +01:00
|
|
|
impl<Theme> crate::graphics::Compositor for Compositor<Theme> {
|
2023-02-25 15:38:25 +01:00
|
|
|
type Settings = Settings;
|
|
|
|
|
type Renderer = Renderer<Theme>;
|
|
|
|
|
type Surface = Surface;
|
|
|
|
|
|
|
|
|
|
fn new<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
|
|
|
|
settings: Self::Settings,
|
|
|
|
|
_compatible_window: Option<&W>,
|
|
|
|
|
) -> Result<(Self, Self::Renderer), Error> {
|
|
|
|
|
let (compositor, backend) = new(settings);
|
|
|
|
|
|
|
|
|
|
Ok((compositor, Renderer::new(backend)))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn create_surface<W: HasRawWindowHandle + HasRawDisplayHandle>(
|
|
|
|
|
&mut self,
|
2023-02-25 16:05:42 +01:00
|
|
|
window: &W,
|
|
|
|
|
width: u32,
|
|
|
|
|
height: u32,
|
2023-02-25 15:38:25 +01:00
|
|
|
) -> Surface {
|
2023-04-05 19:23:48 +02:00
|
|
|
let platform = unsafe { softbuffer::Context::new(window) }
|
|
|
|
|
.expect("Create softbuffer context");
|
2023-02-25 16:05:42 +01:00
|
|
|
|
2023-04-05 19:23:48 +02:00
|
|
|
let mut window = unsafe { softbuffer::Surface::new(&platform, window) }
|
|
|
|
|
.expect("Create softbuffer surface");
|
|
|
|
|
|
|
|
|
|
window
|
|
|
|
|
.resize(
|
|
|
|
|
NonZeroU32::new(width).unwrap(),
|
|
|
|
|
NonZeroU32::new(height).unwrap(),
|
|
|
|
|
)
|
|
|
|
|
.expect("Resize surface");
|
|
|
|
|
|
|
|
|
|
Surface { window }
|
2023-02-25 15:38:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn configure_surface(
|
|
|
|
|
&mut self,
|
2023-02-25 16:05:42 +01:00
|
|
|
surface: &mut Surface,
|
|
|
|
|
width: u32,
|
|
|
|
|
height: u32,
|
2023-02-25 15:38:25 +01:00
|
|
|
) {
|
2023-04-05 19:23:48 +02:00
|
|
|
surface
|
|
|
|
|
.window
|
|
|
|
|
.resize(
|
|
|
|
|
NonZeroU32::new(width).unwrap(),
|
|
|
|
|
NonZeroU32::new(height).unwrap(),
|
|
|
|
|
)
|
|
|
|
|
.expect("Resize surface");
|
2023-02-25 15:38:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn fetch_information(&self) -> Information {
|
|
|
|
|
Information {
|
|
|
|
|
adapter: String::from("CPU"),
|
|
|
|
|
backend: String::from("tiny-skia"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn present<T: AsRef<str>>(
|
|
|
|
|
&mut self,
|
|
|
|
|
renderer: &mut Self::Renderer,
|
|
|
|
|
surface: &mut Self::Surface,
|
|
|
|
|
viewport: &Viewport,
|
|
|
|
|
background_color: Color,
|
|
|
|
|
overlay: &[T],
|
|
|
|
|
) -> Result<(), SurfaceError> {
|
|
|
|
|
renderer.with_primitives(|backend, primitives| {
|
|
|
|
|
present(
|
|
|
|
|
self,
|
|
|
|
|
backend,
|
|
|
|
|
surface,
|
|
|
|
|
primitives,
|
|
|
|
|
viewport,
|
|
|
|
|
background_color,
|
|
|
|
|
overlay,
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn new<Theme>(settings: Settings) -> (Compositor<Theme>, Backend) {
|
2023-03-02 00:40:36 +01:00
|
|
|
// TOD
|
2023-02-25 15:38:25 +01:00
|
|
|
(
|
|
|
|
|
Compositor {
|
2023-03-02 00:40:36 +01:00
|
|
|
clip_mask: tiny_skia::ClipMask::new(),
|
2023-02-25 15:38:25 +01:00
|
|
|
_theme: PhantomData,
|
|
|
|
|
},
|
|
|
|
|
Backend::new(settings),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn present<Theme, T: AsRef<str>>(
|
2023-03-02 00:40:36 +01:00
|
|
|
compositor: &mut Compositor<Theme>,
|
2023-02-25 16:05:42 +01:00
|
|
|
backend: &mut Backend,
|
|
|
|
|
surface: &mut Surface,
|
|
|
|
|
primitives: &[Primitive],
|
|
|
|
|
viewport: &Viewport,
|
|
|
|
|
background_color: Color,
|
|
|
|
|
overlay: &[T],
|
2023-02-25 15:38:25 +01:00
|
|
|
) -> Result<(), compositor::SurfaceError> {
|
2023-02-26 00:49:27 +01:00
|
|
|
let physical_size = viewport.physical_size();
|
|
|
|
|
|
2023-04-05 19:23:48 +02:00
|
|
|
let mut buffer = surface.window.buffer_mut().expect("Get window buffer");
|
|
|
|
|
|
2023-04-05 18:41:40 +02:00
|
|
|
let drawn = backend.draw(
|
2023-02-26 00:49:27 +01:00
|
|
|
&mut tiny_skia::PixmapMut::from_bytes(
|
2023-04-05 19:23:48 +02:00
|
|
|
bytemuck::cast_slice_mut(&mut buffer),
|
2023-02-26 00:49:27 +01:00
|
|
|
physical_size.width,
|
|
|
|
|
physical_size.height,
|
|
|
|
|
)
|
|
|
|
|
.expect("Create pixel map"),
|
2023-03-02 00:40:36 +01:00
|
|
|
&mut compositor.clip_mask,
|
2023-02-25 16:05:42 +01:00
|
|
|
primitives,
|
|
|
|
|
viewport,
|
|
|
|
|
background_color,
|
|
|
|
|
overlay,
|
|
|
|
|
);
|
|
|
|
|
|
2023-04-05 18:41:40 +02:00
|
|
|
if drawn {
|
2023-04-05 19:23:48 +02:00
|
|
|
let _ = buffer.present();
|
2023-04-05 18:41:40 +02:00
|
|
|
}
|
2023-02-25 16:05:42 +01:00
|
|
|
|
2023-02-25 15:38:25 +01:00
|
|
|
Ok(())
|
|
|
|
|
}
|