Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
af28d87
Update fill.rs
yagizgil Mar 13, 2026
52e6428
add new example
yagizgil Mar 13, 2026
ade77e9
Update win_with_soft.rs
yagizgil Mar 14, 2026
48ded92
Update win_with_soft.rs
yagizgil Mar 14, 2026
4cfeac9
Update fill.rs
yagizgil Mar 14, 2026
ce40fe5
Update fill.rs
yagizgil Mar 14, 2026
38f85d2
Update fill.rs
yagizgil Mar 14, 2026
858e04b
Update win_with_soft.rs
yagizgil Mar 14, 2026
ecf0a0a
Update win_with_soft.rs
yagizgil Mar 14, 2026
109f1e2
Update win_with_soft.rs
yagizgil Mar 14, 2026
85de3cd
Create win_with_soft_2.rs
yagizgil Mar 14, 2026
c242f59
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
1030024
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
60d5848
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
44c2b3f
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
6310dc0
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
74fabc5
Update win_with_soft_2.rs
yagizgil Mar 14, 2026
2a3a14a
complate keywrods and switch softbuffer source
yagizgil Mar 15, 2026
e2297b7
Update unreleased.md
yagizgil Mar 15, 2026
9838ef9
Update event_loop.rs
yagizgil Mar 15, 2026
e10fcb2
fix
yagizgil Mar 15, 2026
c6bd46c
fix: format
yagizgil Mar 15, 2026
909e079
fix example file named "application.rs"
yagizgil Mar 15, 2026
cfe55b4
format example named applicatio.rs
yagizgil Mar 15, 2026
284be22
remove keyboard mappings as requested
yagizgil Mar 15, 2026
bc3a2a6
Update unreleased.md
yagizgil Mar 15, 2026
d2bc9fe
Update fill.rs
yagizgil Mar 15, 2026
776f639
fmt fill.rs and exclude android for new examples
yagizgil Mar 15, 2026
5d01646
fix examples
yagizgil Mar 15, 2026
2afb39f
fmt examples
yagizgil Mar 15, 2026
6ff12eb
fix examples
yagizgil Mar 15, 2026
5feb83f
.
yagizgil Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ tracing = { version = "0.1.40", default-features = false }

# Dev dependencies.
image = { version = "0.25.0", default-features = false }
softbuffer = { version = "0.4.6", default-features = false, features = [
softbuffer = { git = "https://github.com/rust-windowing/softbuffer", branch = "master", default-features = false, features = [
"x11",
"x11-dlopen",
"wayland",
Expand Down
46 changes: 25 additions & 21 deletions winit/examples/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,32 +964,36 @@ impl WindowState {
return Ok(());
}

let mut buffer = self.surface.buffer_mut()?;
let mut buffer = self.surface.next_buffer()?;

// Draw a different color inside the safe area
let surface_size = self.window.surface_size();
let insets = self.window.safe_area();
for y in 0..surface_size.height {
for x in 0..surface_size.width {
let index = y as usize * surface_size.width as usize + x as usize;
if insets.left <= x
&& x <= (surface_size.width - insets.right)
&& insets.top <= y
&& y <= (surface_size.height - insets.bottom)
{
// In safe area
buffer[index] = match self.theme {
Theme::Light => 0xffe8e8e8, // Light gray
Theme::Dark => 0xff525252, // Medium gray
};
} else {
// Outside safe area
buffer[index] = match self.theme {
Theme::Light => 0xffffffff, // White
Theme::Dark => 0xff181818, // Dark gray
};
for (x, y, pixel) in buffer.pixels_iter() {
let is_inside_safe_area = insets.left <= x
&& x <= (surface_size.width - insets.right)
&& insets.top <= y
&& y <= (surface_size.height - insets.bottom);

let color: u32 = if is_inside_safe_area {
// In safe area
match self.theme {
Theme::Light => 0xffe8e8e8, // Light gray
Theme::Dark => 0xff525252, // Medium gray
}
}
} else {
// Outside safe area
match self.theme {
Theme::Light => 0xffffffff, // White
Theme::Dark => 0xff181818, // Dark gray
}
};

let red = ((color >> 16) & 0xff) as u8;
let green = ((color >> 8) & 0xff) as u8;
let blue = (color & 0xff) as u8;

*pixel = softbuffer::Pixel::new_rgb(red, green, blue);
}

// Present the buffer
Expand Down
11 changes: 9 additions & 2 deletions winit/examples/util/fill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,15 @@ mod platform {

surface.resize(width, height).expect("Failed to resize the softbuffer surface");

let mut buffer = surface.buffer_mut().expect("Failed to get the softbuffer buffer");
buffer.fill(color);
let mut buffer = surface.next_buffer().expect("Failed to get the softbuffer buffer");

for (_, _, pixel) in buffer.pixels_iter() {
let red = ((color >> 16) & 0xff) as u8;
let green = ((color >> 8) & 0xff) as u8;
let blue = (color & 0xff) as u8;

*pixel = softbuffer::Pixel::new_rgb(red, green, blue);
}
buffer.present().expect("Failed to present the softbuffer buffer");
})
}
Expand Down
104 changes: 104 additions & 0 deletions winit/examples/win_with_soft.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#![cfg(not(target_os = "android"))]

use std::error::Error;
use std::num::NonZeroU32;
use std::sync::Arc;
use std::time::{Duration, Instant};

use softbuffer::{Context, Surface};
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};

struct App {
window: Option<Arc<dyn Window>>,
surface: Option<Surface<Arc<dyn Window>, Arc<dyn Window>>>,
frame_count: u32,
last_fps_print: Instant,
}

impl App {
fn new() -> Self {
Self { window: None, surface: None, frame_count: 0, last_fps_print: Instant::now() }
}
}

impl ApplicationHandler for App {
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
let attributes = WindowAttributes::default().with_title("framebuffer test");
let window: Arc<dyn Window> = Arc::from(event_loop.create_window(attributes).unwrap());

let context = Context::new(window.clone()).expect("context except");
let surface = Surface::new(&context, window.clone()).expect("surface except");

self.window = Some(window);
self.surface = Some(surface);
}

fn about_to_wait(&mut self, _event_loop: &dyn ActiveEventLoop) {
if let Some(window) = self.window.as_ref() {
window.request_redraw();
}
}

fn window_event(
&mut self,
event_loop: &dyn ActiveEventLoop,
_id: WindowId,
event: WindowEvent,
) {
match event {
WindowEvent::CloseRequested => event_loop.exit(),

WindowEvent::SurfaceResized(size) => {
if let Some(surface) = self.surface.as_mut() {
let w = NonZeroU32::new(size.width.max(1)).unwrap();
let h = NonZeroU32::new(size.height.max(1)).unwrap();
surface.resize(w, h).unwrap();
}
},

WindowEvent::RedrawRequested => {
if let Some(surface) = self.surface.as_mut() {
let mut buffer = surface.next_buffer().expect("buffer except");

for (x, y, pixel) in buffer.pixels_iter() {
let red = (x % 255) as u8;
let green = (y % 255) as u8;
let blue = ((x * y) % 255) as u8;

*pixel = softbuffer::Pixel::new_rgb(red, green, blue);
}

buffer.present().unwrap();

let now = Instant::now();
self.frame_count += 1;

if now.duration_since(self.last_fps_print) >= Duration::from_secs(1) {
let fps = self.frame_count;
println!("FPS: {}", fps);

self.frame_count = 0;
self.last_fps_print = now;
}
}
},
_ => (),
}
}
}

fn main() -> Result<(), Box<dyn Error>> {
let event_loop = EventLoop::new()?;

let app = Box::leak(Box::new(App::new()));

event_loop.run_app(app)?;

Ok(())
}

#[cfg(target_os = "android")]
fn main() {}
120 changes: 120 additions & 0 deletions winit/examples/win_with_soft_2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#![cfg(not(target_os = "android"))]

use std::error::Error;
use std::num::NonZeroU32;
use std::sync::Arc;
use std::time::{Duration, Instant};

use softbuffer::{Context, Pixel, Surface};
use winit::application::ApplicationHandler;
use winit::event::WindowEvent;
use winit::event_loop::{ActiveEventLoop, EventLoop};
use winit::window::{Window, WindowAttributes, WindowId};

struct App {
window: Option<Arc<dyn Window>>,
surface: Option<Surface<Arc<dyn Window>, Arc<dyn Window>>>,
start_time: Instant,
frame_count: u32,
last_fps_print: Instant,
total_frame_count: u64,
}

impl ApplicationHandler for App {
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
let window: Arc<dyn Window> =
Arc::from(event_loop.create_window(WindowAttributes::default()).unwrap());
self.surface =
Some(Surface::new(&Context::new(window.clone()).unwrap(), window.clone()).unwrap());
self.window = Some(window);
}

fn about_to_wait(&mut self, _: &dyn ActiveEventLoop) {
if let Some(w) = self.window.as_ref() {
w.request_redraw();
}
}

fn window_event(
&mut self,
event_loop: &dyn ActiveEventLoop,
_id: WindowId,
event: WindowEvent,
) {
match event {
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::SurfaceResized(size) => {
if let Some(s) = self.surface.as_mut() {
s.resize(
NonZeroU32::new(size.width.max(1)).unwrap(),
NonZeroU32::new(size.height.max(1)).unwrap(),
)
.unwrap();
}
},
WindowEvent::RedrawRequested => {
if let (Some(window), Some(surface)) = (&self.window, self.surface.as_mut()) {
let mut buffer = surface.next_buffer().unwrap();
let size = window.outer_size();
let elapsed = self.start_time.elapsed();
let t = elapsed.as_secs_f32();
let total_secs = elapsed.as_secs();

let ball_x = ((t * 1.5).sin() * 0.5 + 0.5) * size.width as f32;
let ball_y = ((t * 2.1).cos() * 0.5 + 0.5) * size.height as f32;

for (x, y, pixel) in buffer.pixels_iter() {
let dx = x as f32 - ball_x;
let dy = y as f32 - ball_y;
let dist = (dx * dx + dy * dy).sqrt();

let p1 = (x as f32 * 0.01 + t).sin();
let p2 = (y as f32 * 0.01 + t * 0.5).cos();
let p3 = ((x as f32 + y as f32) * 0.005 + t).sin();
let plasma = (p1 + p2 + p3) * 0.33;

if dist < 50.0 {
*pixel = Pixel::new_rgb(255, 255, 255);
} else if (y as f32 + t * 50.0) % 20.0 < 2.0 {
*pixel = Pixel::new_rgb(0, 0, 0);
} else {
let r = ((plasma + 1.0) * 127.0) as u8;
let g = (x % 255) as u8;
let b = (y % 255).wrapping_add((t * 20.0) as u32) as u8;
*pixel = Pixel::new_rgb(r, g, b);
}
}
buffer.present().unwrap();

self.frame_count += 1;
self.total_frame_count += 1;
if self.last_fps_print.elapsed() >= Duration::from_secs(1) {
let avg = self.total_frame_count as f64 / elapsed.as_secs_f64();
window.set_title(&format!(
"FPS: {} | AVG: {:.2} | TIME: {}s | {}x{}",
self.frame_count, avg, total_secs, size.width, size.height
));
self.frame_count = 0;
self.last_fps_print = Instant::now();
}
}
},
_ => (),
}
}
}

fn main() -> Result<(), Box<dyn Error>> {
let app = App {
window: None,
surface: None,
start_time: Instant::now(),
frame_count: 0,
last_fps_print: Instant::now(),
total_frame_count: 0,
};
EventLoop::new()?.run_app(app).map_err(Into::into)
}

#[cfg(target_os = "android")]
fn main() {}
Loading