misc cleanup for SDL+GL

This commit is contained in:
lifning 2021-08-21 21:45:57 -07:00
parent 71240de38c
commit 41c0864bef
3 changed files with 18 additions and 39 deletions

View File

@ -13,6 +13,7 @@ libloading = "0.5"
num_enum = "0.4" num_enum = "0.4"
ffmpeg-next = { version = "4.3.8", optional = true } ffmpeg-next = { version = "4.3.8", optional = true }
sdl2 = { version = "0.32", optional = true } sdl2 = { version = "0.32", optional = true }
gl = { version = "0.14", optional = true }
crossbeam-channel = { version = "0.4", optional = true } crossbeam-channel = { version = "0.4", optional = true }
[dev-dependencies] [dev-dependencies]
@ -21,4 +22,4 @@ structopt = "0.3"
[features] [features]
ffmpeg_comp = ["ffmpeg-next"] ffmpeg_comp = ["ffmpeg-next"]
sdl2_comp = ["sdl2", "crossbeam-channel"] sdl2_comp = ["sdl2", "gl", "crossbeam-channel"]

View File

@ -12,7 +12,7 @@ pub struct SimpleSdl2CanvasComponent {
} }
impl SimpleSdl2CanvasComponent { impl SimpleSdl2CanvasComponent {
pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Self { pub fn new(sdl_context: &mut Sdl, retro: &LibretroWrapper) -> Result<Self, Box<dyn std::error::Error>> {
let sys_info = retro.get_system_info(); let sys_info = retro.get_system_info();
let title = format!( let title = format!(
"{} - ferretro SDL", "{} - ferretro SDL",
@ -23,19 +23,16 @@ impl SimpleSdl2CanvasComponent {
let pixel_format = sdl2::pixels::PixelFormatEnum::ARGB1555; let pixel_format = sdl2::pixels::PixelFormatEnum::ARGB1555;
let window = sdl_context let window = sdl_context
.video() .video()?
.unwrap()
.window(title.as_str(), geometry.base_width, geometry.base_height) .window(title.as_str(), geometry.base_width, geometry.base_height)
.opengl() .build()?;
.build()
.unwrap();
let canvas = window.into_canvas().build().unwrap(); let canvas = window.into_canvas().build()?;
SimpleSdl2CanvasComponent { Ok(SimpleSdl2CanvasComponent {
canvas, canvas,
pixel_format, pixel_format,
} })
} }
} }

View File

@ -7,10 +7,6 @@ use sdl2::Sdl;
use sdl2::rect::Rect; use sdl2::rect::Rect;
use sdl2::render::WindowCanvas; use sdl2::render::WindowCanvas;
// TODO: get these from somewhere better without pulling in too much of a mess for the sdl2 feature
const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6;
const GL_COLOR_BUFFER_BIT: c_uint = 0x00004000;
#[allow(non_snake_case)] #[allow(non_snake_case)]
pub struct SimpleSdl2OpenglComponent { pub struct SimpleSdl2OpenglComponent {
canvas: WindowCanvas, canvas: WindowCanvas,
@ -55,7 +51,7 @@ impl SimpleSdl2OpenglComponent {
// http://forums.libsdl.org/viewtopic.php?p=43353 // http://forums.libsdl.org/viewtopic.php?p=43353
// likely to remain `0` on any platform that isn't iOS, but we'll do it anyhow. // likely to remain `0` on any platform that isn't iOS, but we'll do it anyhow.
// SDL_CreateRenderer, called by CanvasBuilder::build, creates a new GL Context. // SDL_CreateRenderer, called by CanvasBuilder::build, creates a new GL Context.
let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); fbo }; let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(gl::FRAMEBUFFER_BINDING, &mut fbo); fbo };
Ok(SimpleSdl2OpenglComponent { Ok(SimpleSdl2OpenglComponent {
canvas, canvas,
@ -72,7 +68,7 @@ impl SimpleSdl2OpenglComponent {
let mut fbo: c_uint = 0; let mut fbo: c_uint = 0;
unsafe { unsafe {
#[allow(non_snake_case)] #[allow(non_snake_case)]
(self.glGetIntegerv)(GL_FRAMEBUFFER_BINDING, &mut fbo); (self.glGetIntegerv)(gl::FRAMEBUFFER_BINDING, &mut fbo);
} }
fbo fbo
} }
@ -105,7 +101,7 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent {
fn video_refresh_hw(&mut self, _width: c_uint, _height: c_uint) { fn video_refresh_hw(&mut self, _width: c_uint, _height: c_uint) {
self.canvas.present(); self.canvas.present();
unsafe { (self.glClear)(GL_COLOR_BUFFER_BIT); } unsafe { (self.glClear)(gl::COLOR_BUFFER_BIT); }
} }
fn set_pixel_format(&mut self, pix_fmt: PixelFormat) -> Option<bool> { fn set_pixel_format(&mut self, pix_fmt: PixelFormat) -> Option<bool> {
@ -119,6 +115,10 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent {
// TODO: depth, stencil, cache_context, bottom_left_origin? // TODO: depth, stencil, cache_context, bottom_left_origin?
fn set_hw_render(&mut self, hw_render_callback: &HwRenderCallback) -> Option<bool> { fn set_hw_render(&mut self, hw_render_callback: &HwRenderCallback) -> Option<bool> {
self.canvas.window().subsystem().gl_attr().set_context_version(
hw_render_callback.version_major as u8,
hw_render_callback.version_minor as u8,
);
self.hw_context_reset_fn.replace(hw_render_callback.context_reset); self.hw_context_reset_fn.replace(hw_render_callback.context_reset);
self.hw_context_destroy_fn.replace(hw_render_callback.context_destroy); self.hw_context_destroy_fn.replace(hw_render_callback.context_destroy);
self.call_context_reset(); self.call_context_reset();
@ -138,29 +138,10 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent {
} }
fn set_geometry(&mut self, geom: &GameGeometry) -> Option<bool> { fn set_geometry(&mut self, geom: &GameGeometry) -> Option<bool> {
let _ = self.canvas.window_mut().set_size(geom.base_width, geom.base_height); eprintln!("set_geometry({:?})", geom);
let _ = self.canvas.set_logical_size(geom.base_width, geom.base_height); let _ = self.canvas.window_mut().set_size(geom.base_width, geom.base_height).ok()?;
let _ = self.canvas.set_logical_size(geom.base_width, geom.base_height).ok()?;
self.window_fbo = self.current_framebuffer_binding(); self.window_fbo = self.current_framebuffer_binding();
/*
let mut old_canvas = unsafe { MaybeUninit::uninit().assume_init() };
std::mem::swap(&mut old_canvas, &mut self.canvas);
// no funny ? operators here because we've got uninitialized memory in self.canvas!
let mut window = old_canvas.into_window();
window.set_size(geom.base_width, geom.base_height).unwrap();
self.call_context_destroy().unwrap();
let mut new_canvas = window.into_canvas()
.accelerated()
.target_texture()
.build()
.unwrap();
self.window_fbo = self.current_framebuffer_binding();
std::mem::swap(&mut self.canvas, &mut new_canvas);
std::mem::forget(new_canvas);
self.call_context_reset()?;
*/
Some(true) Some(true)
} }