From 0c5d0b5338146fc85a711b2a3a354a9ee9136561 Mon Sep 17 00:00:00 2001 From: lifning <> Date: Fri, 20 Aug 2021 22:17:38 -0700 Subject: [PATCH] clear color buffer on vid refresh --- ferretro_components/src/base/mod.rs | 6 ++++ .../src/provided/sdl2/opengl.rs | 36 ++++++++++++++----- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/ferretro_components/src/base/mod.rs b/ferretro_components/src/base/mod.rs index 0587f6f..9d68197 100644 --- a/ferretro_components/src/base/mod.rs +++ b/ferretro_components/src/base/mod.rs @@ -210,6 +210,12 @@ impl RetroCallbacks for RetroComponentBase { } } + fn video_refresh_hw(&mut self, width: c_uint, height: c_uint) { + for comp in &mut self.components { + comp.video_refresh_hw(width, height); + } + } + fn audio_sample(&mut self, left: i16, right: i16) { for comp in &mut self.components { comp.audio_sample(left, right); diff --git a/ferretro_components/src/provided/sdl2/opengl.rs b/ferretro_components/src/provided/sdl2/opengl.rs index 75c3fbe..e288d7c 100644 --- a/ferretro_components/src/provided/sdl2/opengl.rs +++ b/ferretro_components/src/provided/sdl2/opengl.rs @@ -4,9 +4,14 @@ use crate::prelude::*; use std::ffi::CStr; use std::os::raw::c_uint; -use sdl2::{Sdl, VideoSubsystem}; +use sdl2::Sdl; use sdl2::video::{GLContext, Window}; +// 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)] pub struct SimpleSdl2OpenglComponent { window: Window, window_fbo: c_uint, @@ -14,6 +19,8 @@ pub struct SimpleSdl2OpenglComponent { pixel_format: sdl2::pixels::PixelFormatEnum, hw_context_reset_fn: Option, hw_context_destroy_fn: Option, + glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint), + glClear: unsafe extern "C" fn(c_uint), } impl SimpleSdl2OpenglComponent { @@ -33,10 +40,19 @@ impl SimpleSdl2OpenglComponent { .opengl() .build()?; + #[allow(non_snake_case)] + let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = unsafe { + std::mem::transmute(video.gl_get_proc_address("glGetIntegerv")) + }; + #[allow(non_snake_case)] + let glClear: unsafe extern "C" fn(c_uint) = unsafe { + std::mem::transmute(video.gl_get_proc_address("glClear")) + }; + // 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 let gl_context = window.gl_create_context()?; - let window_fbo = Self::current_framebuffer_binding(&video); + let window_fbo = unsafe { let mut fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); fbo }; Ok(SimpleSdl2OpenglComponent { window, @@ -45,18 +61,16 @@ impl SimpleSdl2OpenglComponent { pixel_format, hw_context_reset_fn: None, hw_context_destroy_fn: None, + glGetIntegerv, + glClear, }) } - fn current_framebuffer_binding(video: &VideoSubsystem) -> c_uint { + fn current_framebuffer_binding(&self) -> c_uint { let mut fbo: c_uint = 0; unsafe { - const GL_FRAMEBUFFER_BINDING: c_uint = 0x8CA6; #[allow(non_snake_case)] - let glGetIntegerv: unsafe extern "C" fn(c_uint, *mut c_uint) = std::mem::transmute( - video.gl_get_proc_address("glGetIntegerv") - ); - glGetIntegerv(GL_FRAMEBUFFER_BINDING, &mut fbo); + (self.glGetIntegerv)(GL_FRAMEBUFFER_BINDING, &mut fbo); } eprintln!("get_framebuffer_binding: {}", fbo); fbo @@ -72,6 +86,10 @@ impl SimpleSdl2OpenglComponent { } impl RetroCallbacks for SimpleSdl2OpenglComponent { + fn video_refresh_hw(&mut self, _width: c_uint, _height: c_uint) { + unsafe { (self.glClear)(GL_COLOR_BUFFER_BIT); } + } + fn set_pixel_format(&mut self, pix_fmt: PixelFormat) -> Option { self.pixel_format = match pix_fmt { PixelFormat::ARGB1555 => sdl2::pixels::PixelFormatEnum::RGB555, @@ -106,7 +124,7 @@ impl RetroCallbacks for SimpleSdl2OpenglComponent { self.window.set_size(geom.base_width, geom.base_height).ok()?; self.call_context_destroy()?; self.gl_context = self.window.gl_create_context().ok()?; - self.window_fbo = Self::current_framebuffer_binding(self.window.subsystem()); + self.window_fbo = self.current_framebuffer_binding(); self.call_context_reset()?; Some(true) }