1use super::*;
2use softbuffer::{Buffer, Context, Surface};
3
4type W = Arc<Window>;
5
6pub struct Renderer {
7 _ctx: Context<W>,
8 surface: Surface<W, W>,
9}
10
11impl Renderer {
12 pub fn new(window: Arc<Window>, width: u32, height: u32) -> AppResult<Self> {
13 let ctx = Context::new(window.clone())?;
14 let surface = Surface::new(&ctx, window)?;
15 let mut this = Self { _ctx: ctx, surface };
16 this.resize(width, height)?;
17 Ok(this)
18 }
19
20 #[inline(always)]
21 pub fn resize(&mut self, width: u32, height: u32) -> AppResult<()> {
22 // println!("resizing to {}x{}", width, height);
23 Ok(self.surface.resize(width.try_into()?, height.try_into()?)?)
24 }
25
26 #[inline(always)]
27 pub fn present(&mut self) -> AppResult<()> {
28 Ok(self.surface.buffer_mut()?.present()?)
29 }
30
31 #[inline(always)]
32 pub fn frame_mut(&mut self) -> AppResult<Buffer<'_, W, W>> {
33 Ok(self.surface.buffer_mut()?)
34 }
35}
36
37/// convert tiny-skia RGBA8888 buffer (premultiplied) to BGRA8888 u32 for softbuffer.
38#[inline(always)]
39pub fn skia_rgba_to_bgra_u32(rgba: &[u8], out_bgra: &mut [u32]) {
40 debug_assert_eq!(rgba.len() / 4, out_bgra.len());
41 for (dst, src) in out_bgra.iter_mut().zip(rgba.chunks_exact(4)) {
42 let r = src[0] as u32;
43 let g = src[1] as u32;
44 let b = src[2] as u32;
45 let a = src[3] as u32;
46 *dst = (a << 24) | (r << 16) | (g << 8) | (b << 0); // RGBA -> ARGB little-endian == BGRA bytes
47 }
48}