No description
Find a file
Ian Douglas Scott aad40343bc wayland: Block dispatching if back buffer isn't released
https://github.com/rust-windowing/softbuffer/issues/41

If `set_buffer` can just be called in a loop without waiting for buffers
to be released or a frame callback, but can also be called in other
ways, I don't know if there's a better solution than blocking.

Should fix https://github.com/rust-windowing/softbuffer/issues/48. The
animation example could probably be implemented better, but this is at
least better.

I guess it should be documented that `set_buffer` may block? I don't
know how this compares to other backends.
2022-12-27 15:42:28 -08:00
.github Merge pull request #47 from rust-windowing/clarify-maintainership 2022-12-23 06:34:06 +01:00
examples x11: Add XCB support to the X11 backend (#52) 2022-12-27 09:14:54 -08:00
src wayland: Block dispatching if back buffer isn't released 2022-12-27 15:42:28 -08:00
.gitignore Port to win32 2022-12-20 09:11:45 -07:00
Cargo.toml Specify rust-version in Cargo.toml 2022-12-27 12:20:07 -08:00
LICENSE-APACHE Fork to swbuf 2022-12-20 07:07:57 -07:00
LICENSE-MIT Fork to swbuf 2022-12-20 07:07:57 -07:00
README.md Remove notice about fork 2022-12-23 08:24:26 -07:00

Overview

As the popularity of the library minifb shows, it is useful to put a 2D buffer/image on a window in a platform-independent way. Minifb's approach to doing window management itself, however, is problematic code duplication. We already have very high quality libraries for this in the Rust ecosystem (such as winit), and minifb's implementation of window management is not ideal. For example, it occasionally segfaults on some platforms and is missing key features such as the ability to set a window icon. While it would be possible to add these features to minifb, it makes more sense to instead use the standard window handling systems.

Softbuffer integrates with the raw-window-handle crate to allow writing to a window in a cross-platform way while using the very high quality dedicated window management libraries that are available in the Rust ecosystem.

What about pixels? Pixels accomplishes a very similar goal to Softbuffer, however there are two key differences. Pixels provides some capacity for GPU-accelerated post-processing of what is displayed, while Softbuffer does not. Due to not having this post-processing, Softbuffer does not rely on the GPU or hardware accelerated graphics stack in any way, and is thus more portable to installations that do not have access to hardware acceleration (e.g. VMs, older computers, computers with misconfigured drivers). Softbuffer should be used over pixels when its GPU-accelerated post-processing effects are not needed.

License & Credits

This library is dual-licensed under MIT or Apache-2.0, just like minifb and rust. Significant portions of code were taken from the minifb library to do platform-specific work.

Platform support:

Some, but not all, platforms supported in raw-window-handle are supported by Softbuffer. Pull requests are welcome to add new platforms! Nonetheless, all major desktop platforms that winit uses on desktop are supported.

For now, the priority for new platforms is:

  1. to have at least one platform on each OS working (e.g. one of Win32 or WinRT, or one of Xlib, Xcb, and Wayland) and
  2. for that one platform on each OS to be the one that winit uses.

(PRs will be accepted for any platform, even if it does not follow the above priority.)

: Present | : Absent

  • AndroidNdk
  • AppKit (Thanks to Seo Sanghyeon and lunixbochs!)
  • Orbital
  • UiKit
  • Wayland (Wayland support in winit is immature at the moment, so it might be wise to force X11 if you're using winit)
  • Web (Thanks to Liamolucko!)
  • Win32
  • WinRt
  • Xcb
  • Xlib

Example

use softbuffer::GraphicsContext;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::WindowBuilder;

fn main() {
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new().build(&event_loop).unwrap();
    let mut graphics_context = unsafe { GraphicsContext::new(&window, &window) }.unwrap();

    event_loop.run(move |event, _, control_flow| {
        *control_flow = ControlFlow::Wait;

        match event {
            Event::RedrawRequested(window_id) if window_id == window.id() => {
                let (width, height) = {
                    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);

                        color as u32
                    })
                    .collect::<Vec<_>>();

                graphics_context.set_buffer(&buffer, width as u16, height as u16);
            }
            Event::WindowEvent {
                event: WindowEvent::CloseRequested,
                window_id,
            } if window_id == window.id() => {
                *control_flow = ControlFlow::Exit;
            }
            _ => {}
        }
    });
}

Changelog

See git tags for associated commits.

0.1.1

  • Added WASM support (Thanks to Liamolucko!)
  • CALayer is now used for Mac OS backend, which is more flexible about what happens in the windowing library (Thanks to lunixbochs!)

0.1.0

Initial published version with support for Linux (X11 and Wayland), Mac OS (but buggy), and WIndows.