mod audio_format;
mod audio_player;
mod audio_stream;
mod error;
mod event;
mod ffi;
mod pixel_buffer;
mod renderer;
mod texture;
mod video_format;
mod video_frame;
mod video_player;
mod window;
pub use audio_format::AudioFormat;
pub use audio_player::{AudioPlayer, AudioPlayerStats};
pub use error::{Error, Result};
pub use event::{Event, KEYCODE_ESCAPE, KEYCODE_S, poll_event};
pub use pixel_buffer::PixelBufferRef;
pub use renderer::Renderer;
pub use texture::Texture;
pub use video_format::VideoFormat;
pub use video_player::{
VideoPlayer, VideoPlayerStats, validate_bgra, validate_i420, validate_i420_strided,
validate_nv12, validate_nv12_strided, validate_rgba, validate_yuy2, validate_yuy2_strided,
};
pub use window::Window;
use std::sync::Mutex;
pub const BUILD_REPOSITORY: &str = ffi::BUILD_METADATA_REPOSITORY;
pub const BUILD_VERSION: &str = ffi::BUILD_METADATA_VERSION;
#[allow(clippy::unnecessary_cast)]
pub const BLENDMODE_BLEND: u32 = ffi::SDL_BLENDMODE_BLEND as u32;
pub const DEBUG_TEXT_FONT_CHARACTER_SIZE: i32 = ffi::SDL_DEBUG_TEXT_FONT_CHARACTER_SIZE as i32;
static SDL_INITIALIZED: Mutex<bool> = Mutex::new(false);
pub fn init() -> Result<()> {
let mut initialized = SDL_INITIALIZED.lock().unwrap();
if *initialized {
return Ok(());
}
#[allow(clippy::unnecessary_cast)]
let flags = ffi::SDL_INIT_VIDEO as u32 | ffi::SDL_INIT_AUDIO as u32;
if unsafe { ffi::SDL_Init(flags) } {
*initialized = true;
Ok(())
} else {
Err(Error::from_sdl())
}
}
pub unsafe fn quit() {
let mut initialized = SDL_INITIALIZED.lock().unwrap();
if *initialized {
unsafe { ffi::SDL_Quit() };
*initialized = false;
}
}
pub mod sys {
pub use crate::ffi::*;
}
#[cfg(all(test, target_os = "linux"))]
mod init_concurrency_tests {
use std::sync::{Arc, Barrier};
use std::thread;
use crate::{init, quit};
#[test]
fn init_serializes_concurrent_first_calls() {
unsafe { quit() };
unsafe {
std::env::set_var("SDL_VIDEODRIVER", "dummy");
}
let barrier = Arc::new(Barrier::new(2));
let b1 = Arc::clone(&barrier);
let b2 = Arc::clone(&barrier);
let h1 = thread::spawn(move || {
b1.wait();
init().is_ok()
});
let h2 = thread::spawn(move || {
b2.wait();
init().is_ok()
});
assert!(
h1.join().unwrap(),
"first thread init failed (SDL unavailable?)"
);
assert!(h2.join().unwrap(), "second thread init failed");
unsafe { quit() };
}
}