Merge pull request #219 from gwilymk/stop-freeing-still-in-use-tiles

Stop freeing still in use tiles
This commit is contained in:
Gwilym Kuiper 2022-04-23 23:34:00 +01:00 committed by GitHub
commit d51f61a6fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 63 additions and 37 deletions

View file

@ -33,7 +33,7 @@ fn main(mut gba: agb::Gba) -> ! {
} }
} }
bg.commit(); bg.commit(&mut vram);
bg.show(); bg.show();
let mut i = 0; let mut i = 0;

View file

@ -67,7 +67,7 @@ fn main(mut gba: agb::Gba) -> ! {
} }
background.show(); background.show();
background.commit(); background.commit(&mut vram);
let object = gba.display.object.get(); let object = gba.display.object.get();

View file

@ -41,7 +41,7 @@ fn main(mut gba: agb::Gba) -> ! {
} }
} }
bg.commit(); bg.commit(&mut vram);
bg.show(); bg.show();
loop { loop {

View file

@ -44,10 +44,20 @@ fn main(mut gba: agb::Gba) -> ! {
writer.commit(); writer.commit();
bg.commit(); bg.commit(&mut vram);
bg.show(); bg.show();
let mut frame = 0;
loop { loop {
let mut writer = FONT.render_text((4u16, 0u16).into(), 1, 2, &mut bg, &mut vram);
writeln!(&mut writer, "Frame {}", frame).unwrap();
writer.commit();
frame += 1;
vblank.wait_for_vblank(); vblank.wait_for_vblank();
bg.commit(&mut vram);
} }
} }

View file

@ -18,7 +18,7 @@ pub fn display_logo(map: &mut RegularMap, vram: &mut VRamManager) {
} }
} }
map.commit(); map.commit(vram);
map.show(); map.show();
} }
#[cfg(test)] #[cfg(test)]

View file

@ -242,7 +242,7 @@ mod tests {
writer.commit(); writer.commit();
bg.commit(); bg.commit(&mut vram);
bg.show(); bg.show();
crate::test_runner::assert_image_output("examples/font/font-test-output.png"); crate::test_runner::assert_image_output("examples/font/font-test-output.png");

View file

@ -206,8 +206,8 @@ impl<'a> InfiniteScrolledMap<'a> {
self.map.hide(); self.map.hide();
} }
pub fn commit(&mut self) { pub fn commit(&mut self, vram: &mut VRamManager) {
self.map.commit(); self.map.commit(vram);
} }
pub fn clear(&mut self, vram: &mut VRamManager) { pub fn clear(&mut self, vram: &mut VRamManager) {

View file

@ -92,13 +92,15 @@ impl RegularMap {
DISPLAY_CONTROL.set(new_mode); DISPLAY_CONTROL.set(new_mode);
} }
pub fn commit(&mut self) { pub fn commit(&mut self, vram: &mut VRamManager) {
let new_bg_control_value = (self.priority as u16) | ((self.screenblock as u16) << 8); let new_bg_control_value = (self.priority as u16) | ((self.screenblock as u16) << 8);
self.bg_control_register().set(new_bg_control_value); self.bg_control_register().set(new_bg_control_value);
self.bg_h_offset().set(self.x_scroll); self.bg_h_offset().set(self.x_scroll);
self.bg_v_offset().set(self.y_scroll); self.bg_v_offset().set(self.y_scroll);
vram.gc();
if !self.tiles_dirty { if !self.tiles_dirty {
return; return;
} }

View file

@ -116,6 +116,10 @@ impl TileReferenceCount {
self.reference_count = 0; self.reference_count = 0;
self.tile_in_tile_set = None; self.tile_in_tile_set = None;
} }
fn current_count(&self) -> u16 {
self.reference_count
}
} }
#[non_exhaustive] #[non_exhaustive]
@ -158,6 +162,8 @@ impl DynamicTile<'_> {
pub struct VRamManager { pub struct VRamManager {
tile_set_to_vram: HashMap<TileInTileSetReference, TileReference>, tile_set_to_vram: HashMap<TileInTileSetReference, TileReference>,
reference_counts: Vec<TileReferenceCount>, reference_counts: Vec<TileReferenceCount>,
indices_to_gc: Vec<TileIndex>,
} }
impl VRamManager { impl VRamManager {
@ -168,6 +174,7 @@ impl VRamManager {
Self { Self {
tile_set_to_vram, tile_set_to_vram,
reference_counts: Default::default(), reference_counts: Default::default(),
indices_to_gc: Default::default(),
} }
} }
@ -270,18 +277,29 @@ impl VRamManager {
return; return;
} }
let tile_reference = Self::reference_from_index(tile_index); self.indices_to_gc.push(tile_index);
unsafe { }
TILE_ALLOCATOR.dealloc_no_normalise(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
pub(crate) fn gc(&mut self) {
for tile_index in self.indices_to_gc.drain(..) {
let index = tile_index.index() as usize;
if self.reference_counts[index].current_count() > 0 {
continue; // it has since been added back
}
let tile_reference = Self::reference_from_index(tile_index);
unsafe {
TILE_ALLOCATOR.dealloc_no_normalise(tile_reference.0.cast().as_ptr(), TILE_LAYOUT);
}
let tile_ref = self.reference_counts[index]
.tile_in_tile_set
.as_ref()
.unwrap();
self.tile_set_to_vram.remove(tile_ref);
self.reference_counts[index].clear();
} }
let tile_ref = self.reference_counts[index]
.tile_in_tile_set
.as_ref()
.unwrap();
self.tile_set_to_vram.remove(tile_ref);
self.reference_counts[index].clear();
} }
pub fn replace_tile( pub fn replace_tile(
@ -330,12 +348,8 @@ impl VRamManager {
} }
fn set_background_palette(&mut self, pal_index: u8, palette: &palette16::Palette16) { fn set_background_palette(&mut self, pal_index: u8, palette: &palette16::Palette16) {
unsafe { for (colour_index, &colour) in palette.colours.iter().enumerate() {
dma_copy16( PALETTE_BACKGROUND.set(colour_index + 16 * pal_index as usize, colour);
palette.colours.as_ptr(),
PALETTE_BACKGROUND.as_ptr().add(16 * pal_index as usize),
palette.colours.len(),
);
} }
} }

View file

@ -273,8 +273,8 @@ impl<'a, 'b> Map<'a, 'b> {
self.background.set_pos(vram, self.position.floor()); self.background.set_pos(vram, self.position.floor());
self.foreground.set_pos(vram, self.position.floor()); self.foreground.set_pos(vram, self.position.floor());
self.background.commit(); self.background.commit(vram);
self.foreground.commit(); self.foreground.commit(vram);
} }
pub fn init_background(&mut self, vram: &mut VRamManager) -> PartialUpdateStatus { pub fn init_background(&mut self, vram: &mut VRamManager) -> PartialUpdateStatus {
@ -793,7 +793,7 @@ fn main(mut agb: agb::Gba) -> ! {
} }
} }
world_display.commit(); world_display.commit(&mut vram);
world_display.show(); world_display.show();
splash_screen::show_splash_screen( splash_screen::show_splash_screen(
@ -835,7 +835,7 @@ fn main(mut agb: agb::Gba) -> ! {
&mut vram, &mut vram,
); );
world_display.commit(); world_display.commit(&mut vram);
world_display.show(); world_display.show();
music_box.before_frame(&mut mixer); music_box.before_frame(&mut mixer);

View file

@ -76,7 +76,7 @@ pub fn show_splash_screen(
} }
} }
map.commit(); map.commit(vram);
vram.set_background_palettes(palette); vram.set_background_palettes(palette);
map.show(); map.show();

View file

@ -85,9 +85,9 @@ impl<'a> Level<'a> {
foreground.init(vram, start_pos, &mut between_updates); foreground.init(vram, start_pos, &mut between_updates);
clouds.init(vram, start_pos / 4, &mut between_updates); clouds.init(vram, start_pos / 4, &mut between_updates);
backdrop.commit(); backdrop.commit(vram);
foreground.commit(); foreground.commit(vram);
clouds.commit(); clouds.commit(vram);
backdrop.show(); backdrop.show();
foreground.show(); foreground.show();
@ -2081,9 +2081,9 @@ impl<'a> Game<'a> {
.commit_with_fudge(this_frame_offset, (0, 0).into()); .commit_with_fudge(this_frame_offset, (0, 0).into());
} }
self.level.background.commit(); self.level.background.commit(vram);
self.level.foreground.commit(); self.level.foreground.commit(vram);
self.level.clouds.commit(); self.level.clouds.commit(vram);
for i in remove { for i in remove {
self.particles.remove(i); self.particles.remove(i);