Merge remote-tracking branch 'origin/master' into damage
This commit is contained in:
commit
1e7b9213d2
13 changed files with 265 additions and 23 deletions
|
|
@ -1,2 +1,5 @@
|
||||||
[alias]
|
[alias]
|
||||||
run-wasm = ["run", "--release", "--package", "run-wasm", "--"]
|
run-wasm = ["run", "--release", "--package", "run-wasm", "--"]
|
||||||
|
|
||||||
|
[target.wasm32-unknown-unknown]
|
||||||
|
runner = "wasm-bindgen-test-runner"
|
||||||
|
|
|
||||||
33
.github/workflows/ci.yml
vendored
33
.github/workflows/ci.yml
vendored
|
|
@ -3,7 +3,7 @@ name: CI
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [master]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Check_Formatting:
|
Check_Formatting:
|
||||||
|
|
@ -47,12 +47,10 @@ jobs:
|
||||||
- { target: x86_64-unknown-freebsd, os: ubuntu-latest, }
|
- { target: x86_64-unknown-freebsd, os: ubuntu-latest, }
|
||||||
- { target: x86_64-unknown-netbsd, os: ubuntu-latest, }
|
- { target: x86_64-unknown-netbsd, os: ubuntu-latest, }
|
||||||
- { target: x86_64-apple-darwin, os: macos-latest, }
|
- { target: x86_64-apple-darwin, os: macos-latest, }
|
||||||
# We're using Windows rather than Ubuntu to run the wasm tests because caching cargo-web
|
- { target: wasm32-unknown-unknown, os: ubuntu-latest, }
|
||||||
# doesn't currently work on Linux.
|
|
||||||
- { target: wasm32-unknown-unknown, os: windows-latest, }
|
|
||||||
include:
|
include:
|
||||||
- rust_version: nightly
|
- rust_version: nightly
|
||||||
platform: { target: wasm32-unknown-unknown, os: windows-latest, options: "-Zbuild-std=panic_abort,std", rustflags: "-Ctarget-feature=+atomics,+bulk-memory" }
|
platform: { target: wasm32-unknown-unknown, os: ubuntu-latest, options: "-Zbuild-std=panic_abort,std", rustflags: "-Ctarget-feature=+atomics,+bulk-memory" }
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
|
|
@ -67,12 +65,10 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
# Used to cache cargo-web
|
- uses: taiki-e/install-action@v2
|
||||||
- name: Cache cargo folder
|
if: matrix.platform.target == 'wasm32-unknown-unknown'
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
with:
|
||||||
path: ~/.cargo
|
tool: wasm-bindgen-cli
|
||||||
key: ${{ matrix.platform.target }}-cargo-${{ matrix.rust_version }}
|
|
||||||
|
|
||||||
- uses: hecrj/setup-rust-action@v1
|
- uses: hecrj/setup-rust-action@v1
|
||||||
with:
|
with:
|
||||||
|
|
@ -102,12 +98,25 @@ jobs:
|
||||||
shell: bash
|
shell: bash
|
||||||
if: >
|
if: >
|
||||||
!((matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686')) &&
|
!((matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686')) &&
|
||||||
!contains(matrix.platform.target, 'wasm32') &&
|
|
||||||
!contains(matrix.platform.target, 'redox') &&
|
!contains(matrix.platform.target, 'redox') &&
|
||||||
!contains(matrix.platform.target, 'freebsd') &&
|
!contains(matrix.platform.target, 'freebsd') &&
|
||||||
!contains(matrix.platform.target, 'netbsd')
|
!contains(matrix.platform.target, 'netbsd') &&
|
||||||
|
!contains(matrix.platform.target, 'linux')
|
||||||
run: cargo $CMD test --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES
|
run: cargo $CMD test --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES
|
||||||
|
|
||||||
|
# TODO: We should also be using Wayland for testing here.
|
||||||
|
- name: Run tests using Xvfb
|
||||||
|
shell: bash
|
||||||
|
if: >
|
||||||
|
!((matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686')) &&
|
||||||
|
!contains(matrix.platform.target, 'redox') &&
|
||||||
|
!contains(matrix.platform.target, 'freebsd') &&
|
||||||
|
!contains(matrix.platform.target, 'netbsd') &&
|
||||||
|
contains(matrix.platform.target, 'linux') &&
|
||||||
|
!contains(matrix.platform.options, '--no-default-features') &&
|
||||||
|
!contains(matrix.platform.features, 'wayland')
|
||||||
|
run: xvfb-run cargo $CMD test --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES
|
||||||
|
|
||||||
- name: Lint with clippy
|
- name: Lint with clippy
|
||||||
shell: bash
|
shell: bash
|
||||||
if: >
|
if: >
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
* On MacOS, the contents scale is updated when set_buffer() is called, to adapt when the window is on a new screen.
|
* On MacOS, the contents scale is updated when set_buffer() is called, to adapt when the window is on a new screen.
|
||||||
|
|
||||||
|
# 0.2.1
|
||||||
|
|
||||||
|
* Bump `windows-sys` to 0.48
|
||||||
|
|
||||||
# 0.2.0
|
# 0.2.0
|
||||||
|
|
||||||
* Add support for Redox/Orbital.
|
* Add support for Redox/Orbital.
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ cfg_aliases = "0.1.1"
|
||||||
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] }
|
criterion = { version = "0.4.0", default-features = false, features = ["cargo_bench_support"] }
|
||||||
instant = "0.1.12"
|
instant = "0.1.12"
|
||||||
winit = "0.28.1"
|
winit = "0.28.1"
|
||||||
|
winit-test = "0.1.0"
|
||||||
|
|
||||||
[dev-dependencies.image]
|
[dev-dependencies.image]
|
||||||
version = "0.24.6"
|
version = "0.24.6"
|
||||||
|
|
@ -81,11 +82,19 @@ features = ["jpeg"]
|
||||||
image = "0.24.6"
|
image = "0.24.6"
|
||||||
rayon = "1.5.1"
|
rayon = "1.5.1"
|
||||||
|
|
||||||
|
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||||
|
wasm-bindgen-test = "0.3"
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"run-wasm",
|
"run-wasm",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[test]]
|
||||||
|
name = "present_and_fetch"
|
||||||
|
path = "tests/present_and_fetch.rs"
|
||||||
|
harness = false
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,11 @@ impl CGImpl {
|
||||||
imp: self,
|
imp: self,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
Err(SoftBufferError::Unimplemented)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BufferImpl<'a> {
|
pub struct BufferImpl<'a> {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ pub enum SoftBufferError {
|
||||||
|
|
||||||
#[error("Platform error")]
|
#[error("Platform error")]
|
||||||
PlatformError(Option<String>, Option<Box<dyn Error>>),
|
PlatformError(Option<String>, Option<Box<dyn Error>>),
|
||||||
|
|
||||||
|
#[error("This function is unimplemented on this platform")]
|
||||||
|
Unimplemented,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenient wrapper to cast errors into SoftBufferError.
|
/// Convenient wrapper to cast errors into SoftBufferError.
|
||||||
|
|
|
||||||
21
src/lib.rs
21
src/lib.rs
|
|
@ -98,6 +98,15 @@ macro_rules! make_dispatch {
|
||||||
)*
|
)*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
match self {
|
||||||
|
$(
|
||||||
|
$(#[$attr])*
|
||||||
|
Self::$name(inner) => inner.fetch(),
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BufferDispatch<'a> {
|
enum BufferDispatch<'a> {
|
||||||
|
|
@ -337,6 +346,18 @@ impl Surface {
|
||||||
self.surface_impl.resize(width, height)
|
self.surface_impl.resize(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Copies the window contents into a buffer.
|
||||||
|
///
|
||||||
|
/// ## Platform Dependent Behavior
|
||||||
|
///
|
||||||
|
/// - On X11, the window must be visible.
|
||||||
|
/// - On macOS, Redox and Wayland, this function is unimplemented.
|
||||||
|
/// - On Web, this will fail if the content was supplied by
|
||||||
|
/// a different origin depending on the sites CORS rules.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
self.surface_impl.fetch()
|
||||||
|
}
|
||||||
|
|
||||||
/// Return a [`Buffer`] that the next frame should be rendered into. The size must
|
/// Return a [`Buffer`] that the next frame should be rendered into. The size must
|
||||||
/// be set with [`Surface::resize`] first. The initial contents of the buffer may be zeroed, or
|
/// be set with [`Surface::resize`] first. The initial contents of the buffer may be zeroed, or
|
||||||
/// may contain a previous frame. Call [`Buffer::age`] to determine this.
|
/// may contain a previous frame. Call [`Buffer::age`] to determine this.
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,11 @@ impl OrbitalImpl {
|
||||||
// Tell orbital to show the latest window data
|
// Tell orbital to show the latest window data
|
||||||
syscall::fsync(self.window_fd()).expect("failed to sync orbital window");
|
syscall::fsync(self.window_fd()).expect("failed to sync orbital window");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
Err(SoftBufferError::Unimplemented)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Pixels {
|
enum Pixels {
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,6 @@ impl WaylandImpl {
|
||||||
};
|
};
|
||||||
|
|
||||||
let age = self.buffers.as_mut().unwrap().1.age;
|
let age = self.buffers.as_mut().unwrap().1.age;
|
||||||
|
|
||||||
Ok(BufferImpl {
|
Ok(BufferImpl {
|
||||||
stack: util::BorrowStack::new(self, |buffer| {
|
stack: util::BorrowStack::new(self, |buffer| {
|
||||||
Ok(unsafe { buffer.buffers.as_mut().unwrap().1.mapped_mut() })
|
Ok(unsafe { buffer.buffers.as_mut().unwrap().1.mapped_mut() })
|
||||||
|
|
@ -135,6 +134,11 @@ impl WaylandImpl {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
Err(SoftBufferError::Unimplemented)
|
||||||
|
}
|
||||||
|
|
||||||
fn present_with_damage(&mut self, damage: &[Rect]) -> Result<(), SoftBufferError> {
|
fn present_with_damage(&mut self, damage: &[Rect]) -> Result<(), SoftBufferError> {
|
||||||
let _ = self
|
let _ = self
|
||||||
.display
|
.display
|
||||||
|
|
|
||||||
29
src/web.rs
29
src/web.rs
|
|
@ -24,9 +24,9 @@ pub struct WebDisplayImpl {
|
||||||
impl WebDisplayImpl {
|
impl WebDisplayImpl {
|
||||||
pub(super) fn new() -> Result<Self, SoftBufferError> {
|
pub(super) fn new() -> Result<Self, SoftBufferError> {
|
||||||
let document = web_sys::window()
|
let document = web_sys::window()
|
||||||
.swbuf_err("`window` is not present in this runtime")?
|
.swbuf_err("`Window` is not present in this runtime")?
|
||||||
.document()
|
.document()
|
||||||
.swbuf_err("`document` is not present in this runtime")?;
|
.swbuf_err("`Document` is not present in this runtime")?;
|
||||||
|
|
||||||
Ok(Self { document })
|
Ok(Self { document })
|
||||||
}
|
}
|
||||||
|
|
@ -164,11 +164,36 @@ impl WebImpl {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
let (width, height) = self
|
||||||
|
.size
|
||||||
|
.expect("Must set size of surface before calling `fetch()`");
|
||||||
|
|
||||||
|
let image_data = self
|
||||||
|
.ctx
|
||||||
|
.get_image_data(0., 0., width.get().into(), height.get().into())
|
||||||
|
.ok()
|
||||||
|
// TODO: Can also error if width or height are 0.
|
||||||
|
.swbuf_err("`Canvas` contains pixels from a different origin")?;
|
||||||
|
|
||||||
|
Ok(image_data
|
||||||
|
.data()
|
||||||
|
.0
|
||||||
|
.chunks_exact(4)
|
||||||
|
.map(|chunk| u32::from_be_bytes([0, chunk[0], chunk[1], chunk[2]]))
|
||||||
|
.collect())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extension methods for the Wasm target on [`Surface`](crate::Surface).
|
/// Extension methods for the Wasm target on [`Surface`](crate::Surface).
|
||||||
pub trait SurfaceExtWeb: Sized {
|
pub trait SurfaceExtWeb: Sized {
|
||||||
/// Creates a new instance of this struct, using the provided [`HtmlCanvasElement`].
|
/// Creates a new instance of this struct, using the provided [`HtmlCanvasElement`].
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
/// - If the canvas was already controlled by an `OffscreenCanvas`.
|
||||||
|
/// - If a another context then "2d" was already created for this canvas.
|
||||||
fn from_canvas(canvas: HtmlCanvasElement) -> Result<Self, SoftBufferError>;
|
fn from_canvas(canvas: HtmlCanvasElement) -> Result<Self, SoftBufferError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
28
src/win32.rs
28
src/win32.rs
|
|
@ -228,6 +228,34 @@ impl Win32Impl {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
let buffer = self.buffer.as_ref().unwrap();
|
||||||
|
let temp_buffer = Buffer::new(self.dc, buffer.width, buffer.height);
|
||||||
|
|
||||||
|
// Just go the other way.
|
||||||
|
unsafe {
|
||||||
|
Gdi::BitBlt(
|
||||||
|
temp_buffer.dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
temp_buffer.width.get(),
|
||||||
|
temp_buffer.height.get(),
|
||||||
|
self.dc,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
Gdi::SRCCOPY,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush the operation so that it happens immediately.
|
||||||
|
unsafe {
|
||||||
|
Gdi::GdiFlush();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(temp_buffer.pixels().to_vec())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BufferImpl<'a>(&'a mut Win32Impl);
|
pub struct BufferImpl<'a>(&'a mut Win32Impl);
|
||||||
|
|
|
||||||
86
src/x11.rs
86
src/x11.rs
|
|
@ -109,6 +109,9 @@ pub struct X11Impl {
|
||||||
/// The depth (bits per pixel) of the drawing context.
|
/// The depth (bits per pixel) of the drawing context.
|
||||||
depth: u8,
|
depth: u8,
|
||||||
|
|
||||||
|
/// The visual ID of the drawing context.
|
||||||
|
visual_id: u32,
|
||||||
|
|
||||||
/// The buffer we draw to.
|
/// The buffer we draw to.
|
||||||
buffer: Buffer,
|
buffer: Buffer,
|
||||||
|
|
||||||
|
|
@ -183,11 +186,26 @@ impl X11Impl {
|
||||||
|
|
||||||
let window = window_handle.window;
|
let window = window_handle.window;
|
||||||
|
|
||||||
// Run in parallel: start getting the window depth.
|
// Run in parallel: start getting the window depth and (if necessary) visual.
|
||||||
let geometry_token = display
|
let display2 = display.clone();
|
||||||
.connection
|
let tokens = {
|
||||||
.get_geometry(window)
|
let geometry_token = display2
|
||||||
.swbuf_err("Failed to send geometry request")?;
|
.connection
|
||||||
|
.get_geometry(window)
|
||||||
|
.swbuf_err("Failed to send geometry request")?;
|
||||||
|
let window_attrs_token = if window_handle.visual_id == 0 {
|
||||||
|
Some(
|
||||||
|
display2
|
||||||
|
.connection
|
||||||
|
.get_window_attributes(window)
|
||||||
|
.swbuf_err("Failed to send window attributes request")?,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
(geometry_token, window_attrs_token)
|
||||||
|
};
|
||||||
|
|
||||||
// Create a new graphics context to draw to.
|
// Create a new graphics context to draw to.
|
||||||
let gc = display
|
let gc = display
|
||||||
|
|
@ -206,9 +224,23 @@ impl X11Impl {
|
||||||
.swbuf_err("Failed to create GC")?;
|
.swbuf_err("Failed to create GC")?;
|
||||||
|
|
||||||
// Finish getting the depth of the window.
|
// Finish getting the depth of the window.
|
||||||
let geometry_reply = geometry_token
|
let (geometry_reply, visual_id) = {
|
||||||
.reply()
|
let (geometry_token, window_attrs_token) = tokens;
|
||||||
.swbuf_err("Failed to get geometry reply")?;
|
let geometry_reply = geometry_token
|
||||||
|
.reply()
|
||||||
|
.swbuf_err("Failed to get geometry reply")?;
|
||||||
|
let visual_id = match window_attrs_token {
|
||||||
|
None => window_handle.visual_id,
|
||||||
|
Some(window_attrs) => {
|
||||||
|
window_attrs
|
||||||
|
.reply()
|
||||||
|
.swbuf_err("Failed to get window attributes reply")?
|
||||||
|
.visual
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
(geometry_reply, visual_id)
|
||||||
|
};
|
||||||
|
|
||||||
// See if SHM is available.
|
// See if SHM is available.
|
||||||
let buffer = if display.is_shm_available {
|
let buffer = if display.is_shm_available {
|
||||||
|
|
@ -227,6 +259,7 @@ impl X11Impl {
|
||||||
window,
|
window,
|
||||||
gc,
|
gc,
|
||||||
depth: geometry_reply.depth,
|
depth: geometry_reply.depth,
|
||||||
|
visual_id,
|
||||||
buffer,
|
buffer,
|
||||||
buffer_presented: false,
|
buffer_presented: false,
|
||||||
size: None,
|
size: None,
|
||||||
|
|
@ -278,6 +311,43 @@ impl X11Impl {
|
||||||
// We can now safely call `buffer_mut` on the buffer.
|
// We can now safely call `buffer_mut` on the buffer.
|
||||||
Ok(BufferImpl(self))
|
Ok(BufferImpl(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetch the buffer from the window.
|
||||||
|
pub fn fetch(&mut self) -> Result<Vec<u32>, SoftBufferError> {
|
||||||
|
log::trace!("fetch: window={:X}", self.window);
|
||||||
|
|
||||||
|
let (width, height) = self
|
||||||
|
.size
|
||||||
|
.expect("Must set size of surface before calling `fetch()`");
|
||||||
|
|
||||||
|
// TODO: Is it worth it to do SHM here? Probably not.
|
||||||
|
let reply = self
|
||||||
|
.display
|
||||||
|
.connection
|
||||||
|
.get_image(
|
||||||
|
xproto::ImageFormat::Z_PIXMAP,
|
||||||
|
self.window,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
width.get(),
|
||||||
|
height.get(),
|
||||||
|
u32::MAX,
|
||||||
|
)
|
||||||
|
.swbuf_err("Failed to send image fetching request")?
|
||||||
|
.reply()
|
||||||
|
.swbuf_err("Failed to fetch image from window")?;
|
||||||
|
|
||||||
|
if reply.depth == self.depth && reply.visual == self.visual_id {
|
||||||
|
let mut out = vec![0u32; reply.data.len() / 4];
|
||||||
|
bytemuck::cast_slice_mut::<u32, u8>(&mut out).copy_from_slice(&reply.data);
|
||||||
|
Ok(out)
|
||||||
|
} else {
|
||||||
|
Err(SoftBufferError::PlatformError(
|
||||||
|
Some("Mismatch between reply and window data".into()),
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BufferImpl<'a>(&'a mut X11Impl);
|
pub struct BufferImpl<'a>(&'a mut X11Impl);
|
||||||
|
|
|
||||||
56
tests/present_and_fetch.rs
Normal file
56
tests/present_and_fetch.rs
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
use softbuffer::{Context, Surface};
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
use winit::event_loop::EventLoopWindowTarget;
|
||||||
|
|
||||||
|
fn all_red(elwt: &EventLoopWindowTarget<()>) {
|
||||||
|
let window = winit::window::WindowBuilder::new()
|
||||||
|
.with_title("all_red")
|
||||||
|
.build(elwt)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
{
|
||||||
|
use winit::platform::web::WindowExtWebSys;
|
||||||
|
|
||||||
|
web_sys::window()
|
||||||
|
.unwrap()
|
||||||
|
.document()
|
||||||
|
.unwrap()
|
||||||
|
.body()
|
||||||
|
.unwrap()
|
||||||
|
.append_child(&window.canvas())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// winit does not wait for the window to be mapped... sigh
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(1));
|
||||||
|
|
||||||
|
let context = unsafe { Context::new(elwt) }.unwrap();
|
||||||
|
let mut surface = unsafe { Surface::new(&context, &window) }.unwrap();
|
||||||
|
let size = window.inner_size();
|
||||||
|
|
||||||
|
// Set the size of the surface to the size of the window.
|
||||||
|
surface
|
||||||
|
.resize(
|
||||||
|
NonZeroU32::new(size.width).unwrap(),
|
||||||
|
NonZeroU32::new(size.height).unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Set all pixels to red.
|
||||||
|
let mut buffer = surface.buffer_mut().unwrap();
|
||||||
|
buffer.fill(0x00FF0000);
|
||||||
|
buffer.present().unwrap();
|
||||||
|
|
||||||
|
// Check that all pixels are red.
|
||||||
|
let screen_contents = match surface.fetch() {
|
||||||
|
Err(softbuffer::SoftBufferError::Unimplemented) => return,
|
||||||
|
cont => cont.unwrap(),
|
||||||
|
};
|
||||||
|
for pixel in screen_contents.iter() {
|
||||||
|
assert_eq!(*pixel, 0x00FF0000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
winit_test::main!(all_red);
|
||||||
Loading…
Add table
Add a link
Reference in a new issue