Owned pixel buffer for no-copy presentation
This is based on the API that will be used for no-copy presentation. But wraps it in `set_buffer`. This also fixes the Wayland buffer code to set `self.width` and `self.height` on resize, and set the length of the shared memory file when the buffer is created. Co-authored-by: jtnunley <jtnunley01@gmail.com>
This commit is contained in:
parent
e5d546ff9e
commit
a09e4cf679
19 changed files with 1176 additions and 438 deletions
|
|
@ -2,6 +2,7 @@ use instant::Instant;
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use rayon::prelude::*;
|
||||
use std::f64::consts::PI;
|
||||
use std::num::NonZeroU32;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -47,8 +48,17 @@ fn main() {
|
|||
frames = pre_render_frames(width as usize, height as usize);
|
||||
};
|
||||
|
||||
let buffer = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)];
|
||||
surface.set_buffer(buffer.as_slice(), width as u16, height as u16);
|
||||
let frame = &frames[((elapsed * 60.0).round() as usize).clamp(0, 59)];
|
||||
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(width).unwrap(),
|
||||
NonZeroU32::new(height).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
buffer.copy_from_slice(frame);
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
window.request_redraw();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use image::GenericImageView;
|
||||
use std::num::NonZeroU32;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -6,16 +7,6 @@ use winit::window::WindowBuilder;
|
|||
fn main() {
|
||||
//see fruit.jpg.license for the license of fruit.jpg
|
||||
let fruit = image::load_from_memory(include_bytes!("fruit.jpg")).unwrap();
|
||||
let buffer = fruit
|
||||
.pixels()
|
||||
.map(|(_x, _y, pixel)| {
|
||||
let red = pixel.0[0] as u32;
|
||||
let green = pixel.0[1] as u32;
|
||||
let blue = pixel.0[2] as u32;
|
||||
|
||||
blue | (green << 8) | (red << 16)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let event_loop = EventLoop::new();
|
||||
let window = WindowBuilder::new()
|
||||
|
|
@ -45,7 +36,25 @@ fn main() {
|
|||
|
||||
match event {
|
||||
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
||||
surface.set_buffer(&buffer, fruit.width() as u16, fruit.height() as u16);
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(fruit.width()).unwrap(),
|
||||
NonZeroU32::new(fruit.height()).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
let width = fruit.width() as usize;
|
||||
for (x, y, pixel) in fruit.pixels() {
|
||||
let red = pixel.0[0] as u32;
|
||||
let green = pixel.0[1] as u32;
|
||||
let blue = pixel.0[2] as u32;
|
||||
|
||||
let color = blue | (green << 8) | (red << 16);
|
||||
buffer[y as usize * width + x as usize] = color;
|
||||
}
|
||||
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#[cfg(all(feature = "x11", any(target_os = "linux", target_os = "freebsd")))]
|
||||
mod example {
|
||||
use raw_window_handle::{RawDisplayHandle, RawWindowHandle, XcbDisplayHandle, XcbWindowHandle};
|
||||
use std::num::NonZeroU32;
|
||||
use x11rb::{
|
||||
connection::Connection,
|
||||
protocol::{
|
||||
|
|
@ -12,6 +13,8 @@ mod example {
|
|||
xcb_ffi::XCBConnection,
|
||||
};
|
||||
|
||||
const RED: u32 = 255 << 16;
|
||||
|
||||
pub(crate) fn run() {
|
||||
// Create a new XCB connection
|
||||
let (conn, screen) = XCBConnection::connect(None).expect("Failed to connect to X server");
|
||||
|
|
@ -96,13 +99,15 @@ mod example {
|
|||
match event {
|
||||
Event::Expose(_) => {
|
||||
// Draw a width x height red rectangle.
|
||||
let red = 255 << 16;
|
||||
let source = std::iter::repeat(red)
|
||||
.take((width as usize * height as usize) as _)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Draw the buffer.
|
||||
surface.set_buffer(&source, width, height);
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(width.into()).unwrap(),
|
||||
NonZeroU32::new(height.into()).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
buffer.fill(RED);
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
Event::ConfigureNotify(configure_notify) => {
|
||||
width = configure_notify.width;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::num::NonZeroU32;
|
||||
use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -43,7 +44,6 @@ fn main() {
|
|||
let context = unsafe { softbuffer::Context::new(&window) }.unwrap();
|
||||
let mut surface = unsafe { softbuffer::Surface::new(&context, &window) }.unwrap();
|
||||
|
||||
let mut buffer = Vec::new();
|
||||
let mut flag = false;
|
||||
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
|
|
@ -54,19 +54,21 @@ fn main() {
|
|||
// Grab the window's client area dimensions
|
||||
let (width, height) = {
|
||||
let size = window.inner_size();
|
||||
(size.width as usize, size.height as usize)
|
||||
(size.width, size.height)
|
||||
};
|
||||
|
||||
// Resize the off-screen buffer if the window size has changed
|
||||
if buffer.len() != width * height {
|
||||
buffer.resize(width * height, 0);
|
||||
}
|
||||
// Resize surface if needed
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(width).unwrap(),
|
||||
NonZeroU32::new(height).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
// Draw something in the offscreen buffer
|
||||
redraw(&mut buffer, width, height, flag);
|
||||
|
||||
// Blit the offscreen buffer to the window's client area
|
||||
surface.set_buffer(&buffer, width as u16, height as u16);
|
||||
// Draw something in the window
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
redraw(&mut buffer, width as usize, height as usize, flag);
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
|
||||
Event::WindowEvent {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::num::NonZeroU32;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -32,21 +33,26 @@ fn main() {
|
|||
let size = window.inner_size();
|
||||
(size.width, size.height)
|
||||
};
|
||||
let buffer = (0..((width * height) as usize))
|
||||
.map(|index| {
|
||||
let y = index / (width as usize);
|
||||
let x = index % (width as usize);
|
||||
let red = x % 255;
|
||||
let green = y % 255;
|
||||
let blue = (x * y) % 255;
|
||||
|
||||
let color = blue | (green << 8) | (red << 16);
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(width).unwrap(),
|
||||
NonZeroU32::new(height).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
color as u32
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
for index in 0..(width * height) {
|
||||
let y = index / width;
|
||||
let x = index % width;
|
||||
let red = x % 255;
|
||||
let green = y % 255;
|
||||
let blue = (x * y) % 255;
|
||||
|
||||
surface.set_buffer(&buffer, width as u16, height as u16);
|
||||
buffer[index as usize] = blue | (green << 8) | (red << 16);
|
||||
}
|
||||
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use std::num::NonZeroU32;
|
||||
use winit::event::{Event, WindowEvent};
|
||||
use winit::event_loop::{ControlFlow, EventLoop};
|
||||
use winit::window::WindowBuilder;
|
||||
|
|
@ -31,21 +32,25 @@ fn main() {
|
|||
|
||||
match event {
|
||||
Event::RedrawRequested(window_id) if window_id == window.id() => {
|
||||
let buffer = (0..(BUFFER_WIDTH * BUFFER_HEIGHT))
|
||||
.map(|index| {
|
||||
let y = index / BUFFER_WIDTH;
|
||||
let x = index % BUFFER_WIDTH;
|
||||
let red = x % 255;
|
||||
let green = y % 255;
|
||||
let blue = (x * y) % 255;
|
||||
surface
|
||||
.resize(
|
||||
NonZeroU32::new(BUFFER_WIDTH as u32).unwrap(),
|
||||
NonZeroU32::new(BUFFER_HEIGHT as u32).unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut buffer = surface.buffer_mut().unwrap();
|
||||
for y in 0..BUFFER_HEIGHT {
|
||||
for x in 0..BUFFER_WIDTH {
|
||||
let red = x as u32 % 255;
|
||||
let green = y as u32 % 255;
|
||||
let blue = (x as u32 * y as u32) % 255;
|
||||
|
||||
let color = blue | (green << 8) | (red << 16);
|
||||
|
||||
color as u32
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
surface.set_buffer(&buffer, BUFFER_WIDTH as u16, BUFFER_HEIGHT as u16);
|
||||
buffer[y * BUFFER_WIDTH + x] = color;
|
||||
}
|
||||
}
|
||||
buffer.present().unwrap();
|
||||
}
|
||||
Event::WindowEvent {
|
||||
event: WindowEvent::CloseRequested,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue