make rfb handle disconnected pitch better
meh, it works. I really should probably do this in Frontend, but that would be another conversion step. idk
This commit is contained in:
parent
5944c5c1cb
commit
de2cfc07ae
4 changed files with 44 additions and 11 deletions
|
@ -24,7 +24,7 @@ pub(crate) static mut FRONTEND: *mut Frontend = std::ptr::null_mut();
|
|||
/// Interface for the frontend to call to user code.
|
||||
pub trait FrontendInterface {
|
||||
/// Called when video is updated.
|
||||
fn video_update(&mut self, slice: &[u32]);
|
||||
fn video_update(&mut self, slice: &[u32], pitch: u32);
|
||||
|
||||
/// Called when resize occurs.
|
||||
fn video_resize(&mut self, width: u32, height: u32);
|
||||
|
|
|
@ -202,7 +202,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
|||
.resize((pitch * height as usize) as usize, 0);
|
||||
|
||||
// some cores are stupid
|
||||
(*(*FRONTEND).interface).video_resize(pitch as u32, height);
|
||||
(*(*FRONTEND).interface).video_resize(width, height);
|
||||
}
|
||||
|
||||
// TODO: Make this convert from weird pitches to native resolution where possible.
|
||||
|
@ -217,7 +217,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
|||
}
|
||||
}
|
||||
|
||||
(*(*FRONTEND).interface).video_update(&(*FRONTEND).converted_pixel_buffer[..]);
|
||||
(*(*FRONTEND).interface).video_update(&(*FRONTEND).converted_pixel_buffer[..], pitch as u32);
|
||||
}
|
||||
_ => {
|
||||
let pixel_data_slice = std::slice::from_raw_parts(
|
||||
|
@ -225,7 +225,7 @@ pub(crate) unsafe extern "C" fn video_refresh_callback(
|
|||
(pitch * height as usize) as usize,
|
||||
);
|
||||
|
||||
(*(*FRONTEND).interface).video_update(&pixel_data_slice);
|
||||
(*(*FRONTEND).interface).video_update(&pixel_data_slice, pitch as u32);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,10 +104,10 @@ impl FrontendInterface for App {
|
|||
self.rfb_server.resize(width as u16, height as u16);
|
||||
}
|
||||
|
||||
fn video_update(&mut self, slice: &[u32]) {
|
||||
let framebuffer_size = self.get_frontend().get_size();
|
||||
fn video_update(&mut self, slice: &[u32], pitch: u32) {
|
||||
//let framebuffer_size = self.get_frontend().get_size();
|
||||
self.rfb_server
|
||||
.update_buffer(&slice, framebuffer_size.0 as u16, framebuffer_size.1 as u16);
|
||||
.update_buffer(&slice, pitch);
|
||||
}
|
||||
|
||||
fn audio_sample(&mut self, _slice: &[i16], _size: usize) {}
|
||||
|
|
|
@ -18,6 +18,9 @@ pub struct RfbServer {
|
|||
|
||||
// This follows the same format as libretro joypad buttons.
|
||||
buttons: [bool; 32],
|
||||
|
||||
width: u16,
|
||||
height: u16
|
||||
}
|
||||
|
||||
impl RfbServer {
|
||||
|
@ -53,6 +56,8 @@ impl RfbServer {
|
|||
ptr: NonNull::new_unchecked(screen),
|
||||
framebuffer: Vec::new(),
|
||||
buttons: [false; 32],
|
||||
width: config.width,
|
||||
height: config.height
|
||||
});
|
||||
|
||||
// Disable the normal libvnc cursor (it's annoying)
|
||||
|
@ -76,6 +81,9 @@ impl RfbServer {
|
|||
pub fn resize(&mut self, w: u16, h: u16) {
|
||||
let len = (w as usize) * (h as usize);
|
||||
|
||||
self.width = w;
|
||||
self.height = h;
|
||||
|
||||
self.framebuffer.resize(len, 0);
|
||||
|
||||
unsafe {
|
||||
|
@ -91,16 +99,41 @@ impl RfbServer {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update_buffer(&mut self, slice: &[u32], width: u16, height: u16) {
|
||||
self.framebuffer.copy_from_slice(&slice);
|
||||
pub fn update_buffer(&mut self, slice: &[u32], pitch: u32) {
|
||||
|
||||
//self.framebuffer.copy_from_slice(&slice);
|
||||
|
||||
let has_disconnected_pitch = pitch != self.width as u32;
|
||||
|
||||
#[cfg(debug)]
|
||||
if has_disconnected_pitch {
|
||||
info!("DEBUG: Pitch is not the same as width {}, {}", pitch, self.width);
|
||||
}
|
||||
|
||||
// copy a line at a time (test)
|
||||
for y in 0..self.height {
|
||||
let src_line_off = (y as u32 * pitch) as usize;
|
||||
let mut dest_line_off = src_line_off;
|
||||
|
||||
// copy only
|
||||
if has_disconnected_pitch {
|
||||
dest_line_off = (y * self.width) as usize;
|
||||
}
|
||||
|
||||
// Create slices repressenting each part
|
||||
let src_slice = &slice[src_line_off..src_line_off + self.width as usize];
|
||||
let dest_slice = &mut self.framebuffer[dest_line_off..dest_line_off + self.width as usize];
|
||||
|
||||
dest_slice.copy_from_slice(src_slice);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
rfb::bindings::rfbMarkRectAsModified(
|
||||
self.ptr.as_ptr(),
|
||||
0,
|
||||
0,
|
||||
width as i32,
|
||||
height as i32,
|
||||
self.width as i32,
|
||||
self.height as i32,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue