Skip to content

Commit 0f3e315

Browse files
committed
gpu: Avoid calling obj_buffer_get twice
1 parent f78a7b6 commit 0f3e315

File tree

2 files changed

+37
-29
lines changed

2 files changed

+37
-29
lines changed

core/src/gpu/rgb15.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl Rgb15 {
1717
pub const WHITE: Rgb15 = Rgb15(0x7fff);
1818
pub const TRANSPARENT: Rgb15 = Rgb15(0x8000);
1919

20+
#[must_use]
2021
pub fn to_rgb24(&self) -> u32 {
2122
((self.r() as u32) << 19) | ((self.g() as u32) << 11) | ((self.b() as u32) << 3)
2223
}

core/src/gpu/sfx.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,17 @@ impl Gpu {
5454

5555
let y = self.vcount;
5656

57+
let output = unsafe {
58+
let ptr = self.frame_buffer[y * DISPLAY_WIDTH..].as_mut_ptr();
59+
std::slice::from_raw_parts_mut(ptr, DISPLAY_WIDTH)
60+
};
61+
5762
if !self.dispcnt.is_using_windows() {
5863
for x in 0..DISPLAY_WIDTH {
5964
let win = WindowInfo::new(WindowType::WinNone, WindowFlags::all());
60-
self.finalize_pixel(x, y, &win, &sorted_backgrounds, backdrop_color);
65+
output[x] = self
66+
.finalize_pixel(x, y, &win, &sorted_backgrounds, backdrop_color)
67+
.to_rgb24();
6168
}
6269
} else {
6370
let mut occupied = [false; DISPLAY_WIDTH];
@@ -71,7 +78,9 @@ impl Gpu {
7178
.take(self.win0.right())
7279
.skip(self.win0.left())
7380
{
74-
self.finalize_pixel(x, y, &win, &backgrounds, backdrop_color);
81+
output[x] = self
82+
.finalize_pixel(x, y, &win, &backgrounds, backdrop_color)
83+
.to_rgb24();
7584
*is_occupid = true;
7685
occupied_count += 1;
7786
}
@@ -91,7 +100,9 @@ impl Gpu {
91100
if *is_occupid {
92101
continue;
93102
}
94-
self.finalize_pixel(x, y, &win, &backgrounds, backdrop_color);
103+
output[x] = self
104+
.finalize_pixel(x, y, &win, &backgrounds, backdrop_color)
105+
.to_rgb24();
95106
*is_occupid = true;
96107
occupied_count += 1;
97108
}
@@ -112,36 +123,38 @@ impl Gpu {
112123
let obj_entry = self.obj_buffer_get(x, y);
113124
if obj_entry.window {
114125
// WinObj
115-
self.finalize_pixel(x, y, &win_obj, &win_obj_backgrounds, backdrop_color);
126+
output[x] = self
127+
.finalize_pixel(x, y, &win_obj, &win_obj_backgrounds, backdrop_color)
128+
.to_rgb24();
116129
} else {
117130
// WinOut
118-
self.finalize_pixel(x, y, &win_out, &win_out_backgrounds, backdrop_color);
131+
output[x] = self
132+
.finalize_pixel(x, y, &win_out, &win_out_backgrounds, backdrop_color)
133+
.to_rgb24();
119134
}
120135
}
121136
} else {
122137
for (x, is_occupied) in occupied.iter().enumerate() {
123138
if *is_occupied {
124139
continue;
125140
}
126-
self.finalize_pixel(x, y, &win_out, &win_out_backgrounds, backdrop_color);
141+
output[x] = self
142+
.finalize_pixel(x, y, &win_out, &win_out_backgrounds, backdrop_color)
143+
.to_rgb24();
127144
}
128145
}
129146
}
130147
}
131148

149+
#[must_use]
132150
fn finalize_pixel(
133151
&mut self,
134152
x: usize,
135153
y: usize,
136154
win: &WindowInfo,
137155
backgrounds: &[usize],
138156
backdrop_color: Rgb15,
139-
) {
140-
let output = unsafe {
141-
let ptr = self.frame_buffer[y * DISPLAY_WIDTH..].as_mut_ptr();
142-
std::slice::from_raw_parts_mut(ptr, DISPLAY_WIDTH)
143-
};
144-
157+
) -> Rgb15 {
145158
// The backdrop layer is the default
146159
let backdrop_layer = RenderLayer::backdrop(backdrop_color);
147160

@@ -174,40 +187,34 @@ impl Gpu {
174187
}
175188
}
176189

177-
let obj_entry = self.obj_buffer_get(x, y);
178-
let obj_alpha_blend = top_layer.is_object() && obj_entry.alpha;
179-
180190
let top_flags = self.bldcnt.target1;
181191
let bot_flags = self.bldcnt.target2;
182192

183-
let sfx_enabled = self.bldcnt.mode != BlendMode::BldNone
184-
&& top_flags.contains_render_layer(&top_layer); // sfx must at least have a first target configured
193+
let sfx_enabled =
194+
self.bldcnt.mode != BlendMode::BldNone && top_flags.contains_render_layer(&top_layer); // sfx must at least have a first target configured
185195

186-
if top_layer.is_object()
187-
&& obj_alpha_blend
188-
&& bot_flags.contains_render_layer(&bot_layer)
189-
{
190-
output[x] = self.do_alpha(top_layer.pixel, bot_layer.pixel).to_rgb24();
196+
if top_layer.is_object() && obj_entry.alpha && bot_flags.contains_render_layer(&bot_layer) {
197+
self.do_alpha(top_layer.pixel, bot_layer.pixel)
191198
} else if win.flags.sfx_enabled() && sfx_enabled {
192199
let (top_layer, bot_layer) = (top_layer, bot_layer);
193200
match self.bldcnt.mode {
194201
BlendMode::BldAlpha => {
195-
output[x] = if bot_flags.contains_render_layer(&bot_layer) {
196-
self.do_alpha(top_layer.pixel, bot_layer.pixel).to_rgb24()
202+
if bot_flags.contains_render_layer(&bot_layer) {
203+
self.do_alpha(top_layer.pixel, bot_layer.pixel)
197204
} else {
198205
// alpha blending must have a 2nd target
199-
top_layer.pixel.to_rgb24()
206+
top_layer.pixel
200207
}
201208
}
202-
BlendMode::BldWhite => output[x] = self.do_brighten(top_layer.pixel).to_rgb24(),
209+
BlendMode::BldWhite => self.do_brighten(top_layer.pixel),
203210

204-
BlendMode::BldBlack => output[x] = self.do_darken(top_layer.pixel).to_rgb24(),
211+
BlendMode::BldBlack => self.do_darken(top_layer.pixel),
205212

206-
BlendMode::BldNone => output[x] = top_layer.pixel.to_rgb24(),
213+
BlendMode::BldNone => top_layer.pixel,
207214
}
208215
} else {
209216
// no blending, just use the top pixel
210-
output[x] = top_layer.pixel.to_rgb24();
217+
top_layer.pixel
211218
}
212219
}
213220

0 commit comments

Comments
 (0)