Browse Source

Address review comments

Keep RawFrameBuffer alive as long as the Screen is, to ensure the Gfx is
not dropped while the FrameBuffer is alive.
pull/29/head
Ian Chamberlain 3 years ago
parent
commit
9aac807407
No known key found for this signature in database
GPG Key ID: AE5484D09405AA60
  1. 39
      ctru-rs/src/gfx.rs

39
ctru-rs/src/gfx.rs

@ -2,6 +2,7 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::default::Default; use std::default::Default;
use std::marker::PhantomData;
use std::ops::Drop; use std::ops::Drop;
use crate::services::gspgpu::{self, FramebufferFormat}; use crate::services::gspgpu::{self, FramebufferFormat};
@ -36,17 +37,19 @@ pub struct TopScreen;
#[non_exhaustive] #[non_exhaustive]
pub struct BottomScreen; pub struct BottomScreen;
#[derive(Debug)]
/// Representation of a framebuffer for one [`Side`] of the top screen, or the /// Representation of a framebuffer for one [`Side`] of the top screen, or the
/// entire bottom screen. The inner pointer is only valid for one frame if double /// entire bottom screen. The inner pointer is only valid for one frame if double
/// buffering is enabled. Data written to `ptr` will be rendered to the screen. /// buffering is enabled. Data written to `ptr` will be rendered to the screen.
pub struct RawFrameBuffer { #[derive(Debug)]
pub struct RawFrameBuffer<'screen> {
/// Pointer to graphics data to be rendered. /// Pointer to graphics data to be rendered.
pub ptr: *mut u8, pub ptr: *mut u8,
/// The width of the framebuffer in pixels. /// The width of the framebuffer in pixels.
pub width: u16, pub width: u16,
/// The height of the framebuffer in pixels. /// The height of the framebuffer in pixels.
pub height: u16, pub height: u16,
/// Keep a mutable reference to the Screen for which this framebuffer is tied.
screen: PhantomData<&'screen mut dyn Screen>,
} }
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
@ -142,7 +145,7 @@ impl TopScreen {
/// Note that the pointer of the framebuffer returned by this function can /// Note that the pointer of the framebuffer returned by this function can
/// change after each call to this function if double buffering is enabled. /// change after each call to this function if double buffering is enabled.
pub fn get_raw_framebuffer(&mut self, side: Side) -> RawFrameBuffer { pub fn get_raw_framebuffer(&mut self, side: Side) -> RawFrameBuffer {
RawFrameBuffer::for_screen_side(self.as_raw(), side.into()) RawFrameBuffer::for_screen_side(self, side)
} }
} }
@ -152,17 +155,23 @@ impl BottomScreen {
/// Note that the pointer of the framebuffer returned by this function can /// Note that the pointer of the framebuffer returned by this function can
/// change after each call to this function if double buffering is enabled. /// change after each call to this function if double buffering is enabled.
pub fn get_raw_framebuffer(&mut self) -> RawFrameBuffer { pub fn get_raw_framebuffer(&mut self) -> RawFrameBuffer {
RawFrameBuffer::for_screen_side(self.as_raw(), Side::Left.into()) RawFrameBuffer::for_screen_side(self, Side::Left)
} }
} }
impl RawFrameBuffer { impl<'screen> RawFrameBuffer<'screen> {
fn for_screen_side(screen: ctru_sys::gfxScreen_t, side: ctru_sys::gfx3dSide_t) -> Self { fn for_screen_side(screen: &'screen mut dyn Screen, side: Side) -> Self {
let mut buf = RawFrameBuffer::default(); let mut width = 0;
unsafe { let mut height = 0;
buf.ptr = ctru_sys::gfxGetFramebuffer(screen, side, &mut buf.width, &mut buf.height); let ptr = unsafe {
ctru_sys::gfxGetFramebuffer(screen.as_raw(), side.into(), &mut width, &mut height)
};
Self {
ptr,
width,
height,
screen: PhantomData,
} }
buf
} }
} }
@ -178,16 +187,6 @@ impl Screen for BottomScreen {
} }
} }
impl Default for RawFrameBuffer {
fn default() -> Self {
Self {
ptr: std::ptr::null_mut(),
width: 0,
height: 0,
}
}
}
impl From<Side> for ctru_sys::gfx3dSide_t { impl From<Side> for ctru_sys::gfx3dSide_t {
fn from(s: Side) -> ctru_sys::gfx3dSide_t { fn from(s: Side) -> ctru_sys::gfx3dSide_t {
use self::Side::*; use self::Side::*;

Loading…
Cancel
Save