Avoid repeated background index sort
Former-commit-id: 5c7aab3a416cc1cfd9cbd6033457b111fe409d98 Former-commit-id: 0594872c527f57bfd77d0afd9635eed3b88f9be8
This commit is contained in:
parent
9d08ac13e6
commit
8dee829e26
|
@ -38,25 +38,24 @@ impl From<WindowFlags> for BlendFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Gpu {
|
impl Gpu {
|
||||||
/// returns a none sorted array of background indexes that are enabled
|
/// Returns background indexes in render order. Filters range by bg_start..=bg_end.
|
||||||
fn active_backgrounds_sorted(
|
fn sorted_backgrounds(&self, bg_start: usize, bg_end: usize) -> ArrayVec<[usize; 4]> {
|
||||||
|
let mut backgrounds: ArrayVec<[usize; 4]> = (bg_start..=bg_end).collect();
|
||||||
|
backgrounds.sort_by_key(|bg| (self.backgrounds[*bg].bgcnt.priority(), *bg));
|
||||||
|
backgrounds
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Filters a background indexes array by whether they're active
|
||||||
|
fn active_backgrounds(
|
||||||
&self,
|
&self,
|
||||||
bg_start: usize,
|
backgrounds: &[usize],
|
||||||
bg_end: usize,
|
|
||||||
window_flags: WindowFlags,
|
window_flags: WindowFlags,
|
||||||
) -> ArrayVec<[usize; 4]> {
|
) -> ArrayVec<[usize; 4]> {
|
||||||
let mut backgrounds = ArrayVec::<[usize; 4]>::new();
|
|
||||||
|
|
||||||
for bg in bg_start..=bg_end {
|
|
||||||
if self.dispcnt.enable_bg(bg) && window_flags.bg_enabled(bg) {
|
|
||||||
unsafe {
|
|
||||||
backgrounds.push_unchecked(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
backgrounds.sort_by_key(|bg| (self.backgrounds[*bg].bgcnt.priority(), *bg));
|
|
||||||
|
|
||||||
backgrounds
|
backgrounds
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.filter(|bg| self.dispcnt.enable_bg(*bg) && window_flags.bg_enabled(*bg))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
@ -74,6 +73,7 @@ impl Gpu {
|
||||||
/// Composes the render layers into a final scanline while applying needed special effects, and render it to the frame buffer
|
/// Composes the render layers into a final scanline while applying needed special effects, and render it to the frame buffer
|
||||||
pub fn finalize_scanline(&mut self, bg_start: usize, bg_end: usize) {
|
pub fn finalize_scanline(&mut self, bg_start: usize, bg_end: usize) {
|
||||||
let backdrop_color = Rgb15(self.palette_ram.read_16(0));
|
let backdrop_color = Rgb15(self.palette_ram.read_16(0));
|
||||||
|
let sorted_backgrounds = self.sorted_backgrounds(bg_start, bg_end);
|
||||||
|
|
||||||
let y = self.vcount;
|
let y = self.vcount;
|
||||||
let output = unsafe {
|
let output = unsafe {
|
||||||
|
@ -82,7 +82,7 @@ impl Gpu {
|
||||||
};
|
};
|
||||||
if !self.dispcnt.is_using_windows() {
|
if !self.dispcnt.is_using_windows() {
|
||||||
let win = WindowInfo::new(WindowType::WinNone, WindowFlags::all());
|
let win = WindowInfo::new(WindowType::WinNone, WindowFlags::all());
|
||||||
let backgrounds = self.active_backgrounds_sorted(bg_start, bg_end, win.flags);
|
let backgrounds = self.active_backgrounds(&sorted_backgrounds, win.flags);
|
||||||
for x in 0..DISPLAY_WIDTH {
|
for x in 0..DISPLAY_WIDTH {
|
||||||
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
||||||
output[x] = pixel.to_rgb24();
|
output[x] = pixel.to_rgb24();
|
||||||
|
@ -92,7 +92,7 @@ impl Gpu {
|
||||||
let mut occupied_count = 0;
|
let mut occupied_count = 0;
|
||||||
if self.dispcnt.enable_window0() && self.win0.contains_y(y) {
|
if self.dispcnt.enable_window0() && self.win0.contains_y(y) {
|
||||||
let win = WindowInfo::new(WindowType::Win0, self.win0.flags);
|
let win = WindowInfo::new(WindowType::Win0, self.win0.flags);
|
||||||
let backgrounds = self.active_backgrounds_sorted(bg_start, bg_end, win.flags);
|
let backgrounds = self.active_backgrounds(&sorted_backgrounds, win.flags);
|
||||||
for x in self.win0.left()..self.win0.right() {
|
for x in self.win0.left()..self.win0.right() {
|
||||||
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
||||||
output[x] = pixel.to_rgb24();
|
output[x] = pixel.to_rgb24();
|
||||||
|
@ -105,7 +105,7 @@ impl Gpu {
|
||||||
}
|
}
|
||||||
if self.dispcnt.enable_window1() && self.win1.contains_y(y) {
|
if self.dispcnt.enable_window1() && self.win1.contains_y(y) {
|
||||||
let win = WindowInfo::new(WindowType::Win1, self.win1.flags);
|
let win = WindowInfo::new(WindowType::Win1, self.win1.flags);
|
||||||
let backgrounds = self.active_backgrounds_sorted(bg_start, bg_end, win.flags);
|
let backgrounds = self.active_backgrounds(&sorted_backgrounds, win.flags);
|
||||||
for x in self.win1.left()..self.win1.right() {
|
for x in self.win1.left()..self.win1.right() {
|
||||||
if !occupied[x] {
|
if !occupied[x] {
|
||||||
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
let pixel = self.compose_pixel(x, y, &win, &backgrounds, backdrop_color);
|
||||||
|
@ -119,12 +119,11 @@ impl Gpu {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let win_out = WindowInfo::new(WindowType::WinOut, self.winout_flags);
|
let win_out = WindowInfo::new(WindowType::WinOut, self.winout_flags);
|
||||||
let win_out_backgrounds =
|
let win_out_backgrounds = self.active_backgrounds(&sorted_backgrounds, win_out.flags);
|
||||||
self.active_backgrounds_sorted(bg_start, bg_end, win_out.flags);
|
|
||||||
if self.dispcnt.enable_obj_window() {
|
if self.dispcnt.enable_obj_window() {
|
||||||
let win_obj = WindowInfo::new(WindowType::WinObj, self.winobj_flags);
|
let win_obj = WindowInfo::new(WindowType::WinObj, self.winobj_flags);
|
||||||
let win_obj_backgrounds =
|
let win_obj_backgrounds =
|
||||||
self.active_backgrounds_sorted(bg_start, bg_end, win_obj.flags);
|
self.active_backgrounds(&sorted_backgrounds, win_obj.flags);
|
||||||
for x in 0..DISPLAY_WIDTH {
|
for x in 0..DISPLAY_WIDTH {
|
||||||
if occupied[x] {
|
if occupied[x] {
|
||||||
continue;
|
continue;
|
||||||
|
|
Reference in a new issue