More efficient iteration in graphics functions
This commit is contained in:
parent
0ccfd2125a
commit
ff4d06f678
13
Makefile
13
Makefile
|
@ -3,6 +3,9 @@ ARCH?=x86_64
|
||||||
QEMU=qemu-system-$(ARCH)
|
QEMU=qemu-system-$(ARCH)
|
||||||
QEMUFLAGS=-serial mon:stdio -d guest_errors
|
QEMUFLAGS=-serial mon:stdio -d guest_errors
|
||||||
|
|
||||||
|
RUSTCFLAGS=--target $(ARCH)-unknown-none.json -O -C soft-float
|
||||||
|
CARGOFLAGS=--target $(ARCH)-unknown-none.json -- -O -C soft-float
|
||||||
|
|
||||||
ifeq ($(ARCH),arm)
|
ifeq ($(ARCH),arm)
|
||||||
LD=$(ARCH)-none-eabi-ld
|
LD=$(ARCH)-none-eabi-ld
|
||||||
QEMUFLAGS+=-cpu arm1176 -machine integratorcp
|
QEMUFLAGS+=-cpu arm1176 -machine integratorcp
|
||||||
|
@ -34,23 +37,23 @@ FORCE:
|
||||||
|
|
||||||
build/libcore.rlib: rust/src/libcore/lib.rs
|
build/libcore.rlib: rust/src/libcore/lib.rs
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
./rustc.sh --target $(ARCH)-unknown-none.json -C soft-float -o $@ $<
|
./rustc.sh $(RUSTCFLAGS) -o $@ $<
|
||||||
|
|
||||||
build/liballoc.rlib: rust/src/liballoc/lib.rs build/libcore.rlib
|
build/liballoc.rlib: rust/src/liballoc/lib.rs build/libcore.rlib
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
./rustc.sh --target $(ARCH)-unknown-none.json -C soft-float -o $@ $<
|
./rustc.sh $(RUSTCFLAGS) -o $@ $<
|
||||||
|
|
||||||
build/librustc_unicode.rlib: rust/src/librustc_unicode/lib.rs build/libcore.rlib
|
build/librustc_unicode.rlib: rust/src/librustc_unicode/lib.rs build/libcore.rlib
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
./rustc.sh --target $(ARCH)-unknown-none.json -C soft-float -o $@ $<
|
./rustc.sh $(RUSTCFLAGS) -o $@ $<
|
||||||
|
|
||||||
build/libcollections.rlib: rust/src/libcollections/lib.rs build/libcore.rlib build/liballoc.rlib build/librustc_unicode.rlib
|
build/libcollections.rlib: rust/src/libcollections/lib.rs build/libcore.rlib build/liballoc.rlib build/librustc_unicode.rlib
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
./rustc.sh --target $(ARCH)-unknown-none.json -C soft-float -o $@ $<
|
./rustc.sh $(RUSTCFLAGS) -o $@ $<
|
||||||
|
|
||||||
build/libkernel.a: build/libcore.rlib build/liballoc.rlib build/libcollections.rlib FORCE
|
build/libkernel.a: build/libcore.rlib build/liballoc.rlib build/libcollections.rlib FORCE
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
RUSTC="./rustc.sh" cargo rustc --target $(ARCH)-unknown-none.json -- -C soft-float -o $@
|
RUSTC="./rustc.sh" cargo rustc $(CARGOFLAGS) -o $@
|
||||||
|
|
||||||
build/kernel.bin: build/libkernel.a
|
build/kernel.bin: build/libkernel.a
|
||||||
$(LD) --gc-sections -z max-page-size=0x1000 -T arch/$(ARCH)/src/linker.ld -o $@ $<
|
$(LD) --gc-sections -z max-page-size=0x1000 -T arch/$(ARCH)/src/linker.ld -o $@ $<
|
||||||
|
|
|
@ -8,6 +8,7 @@ use paging::{ActivePageTable, PhysicalAddress, entry};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[cold]
|
||||||
unsafe fn fast_copy64(dst: *mut u64, src: *const u64, len: usize) {
|
unsafe fn fast_copy64(dst: *mut u64, src: *const u64, len: usize) {
|
||||||
asm!("cld
|
asm!("cld
|
||||||
rep movsq"
|
rep movsq"
|
||||||
|
@ -20,6 +21,7 @@ unsafe fn fast_copy64(dst: *mut u64, src: *const u64, len: usize) {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[cold]
|
||||||
unsafe fn fast_set(dst: *mut u32, src: u32, len: usize) {
|
unsafe fn fast_set(dst: *mut u32, src: u32, len: usize) {
|
||||||
asm!("cld
|
asm!("cld
|
||||||
rep stosd"
|
rep stosd"
|
||||||
|
@ -32,6 +34,7 @@ unsafe fn fast_set(dst: *mut u32, src: u32, len: usize) {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
#[cold]
|
||||||
unsafe fn fast_set64(dst: *mut u64, src: u64, len: usize) {
|
unsafe fn fast_set64(dst: *mut u64, src: u64, len: usize) {
|
||||||
asm!("cld
|
asm!("cld
|
||||||
rep stosq"
|
rep stosq"
|
||||||
|
@ -81,7 +84,7 @@ pub struct VBEModeInfo {
|
||||||
|
|
||||||
pub static CONSOLE: Mutex<Option<Console>> = Mutex::new(None);
|
pub static CONSOLE: Mutex<Option<Console>> = Mutex::new(None);
|
||||||
|
|
||||||
pub static DISPLAY: Mutex<Option<Display<'static>>> = Mutex::new(None);
|
pub static DISPLAY: Mutex<Option<Display>> = Mutex::new(None);
|
||||||
|
|
||||||
static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");
|
static FONT: &'static [u8] = include_bytes!("../../../../res/unifont.font");
|
||||||
|
|
||||||
|
@ -105,8 +108,14 @@ pub unsafe fn init(active_table: &mut ActivePageTable) {
|
||||||
|
|
||||||
fast_set64(onscreen as *mut u64, 0, size/2);
|
fast_set64(onscreen as *mut u64, 0, size/2);
|
||||||
|
|
||||||
|
let offscreen = ::allocator::__rust_allocate(size * 4, 8);
|
||||||
|
fast_set64(offscreen as *mut u64, 0, size/2);
|
||||||
|
|
||||||
*CONSOLE.lock() = Some(Console::new(width/8, height/16));
|
*CONSOLE.lock() = Some(Console::new(width/8, height/16));
|
||||||
*DISPLAY.lock() = Some(Display::new(width, height, slice::from_raw_parts_mut(onscreen as *mut u32, size)));
|
*DISPLAY.lock() = Some(Display::new(width, height,
|
||||||
|
slice::from_raw_parts_mut(onscreen as *mut u32, size),
|
||||||
|
slice::from_raw_parts_mut(offscreen as *mut u32, size)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,18 +140,20 @@ pub unsafe fn init_ap(active_table: &mut ActivePageTable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A display
|
/// A display
|
||||||
pub struct Display<'a> {
|
pub struct Display {
|
||||||
pub width: usize,
|
pub width: usize,
|
||||||
pub height: usize,
|
pub height: usize,
|
||||||
pub data: &'a mut [u32],
|
pub onscreen: &'static mut [u32],
|
||||||
|
pub offscreen: &'static mut [u32],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Display<'a> {
|
impl Display {
|
||||||
fn new<'data>(width: usize, height: usize, data: &'data mut [u32]) -> Display<'data> {
|
fn new(width: usize, height: usize, onscreen: &'static mut [u32], offscreen: &'static mut [u32]) -> Display {
|
||||||
Display {
|
Display {
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
data: data,
|
onscreen: onscreen,
|
||||||
|
offscreen: offscreen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,35 +162,65 @@ impl<'a> Display<'a> {
|
||||||
let start_y = cmp::min(self.height - 1, y);
|
let start_y = cmp::min(self.height - 1, y);
|
||||||
let end_y = cmp::min(self.height, y + h);
|
let end_y = cmp::min(self.height, y + h);
|
||||||
|
|
||||||
let mut start_x = cmp::min(self.width - 1, x);
|
let start_x = cmp::min(self.width - 1, x);
|
||||||
let mut len = cmp::min(self.width, x + w) - start_x;
|
let len = cmp::min(self.width, x + w) - start_x;
|
||||||
|
|
||||||
let width = self.width;
|
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||||
let data_ptr = self.data.as_mut_ptr();
|
let mut onscreen_ptr = self.onscreen.as_mut_ptr() as usize;
|
||||||
for y in start_y..end_y {
|
|
||||||
let offset = y * self.width + start_x;
|
let stride = self.width * 4;
|
||||||
|
|
||||||
|
let offset = y * stride + start_x * 4;
|
||||||
|
offscreen_ptr += offset;
|
||||||
|
onscreen_ptr += offset;
|
||||||
|
|
||||||
|
let mut rows = end_y - start_y;
|
||||||
|
while rows > 0 {
|
||||||
unsafe {
|
unsafe {
|
||||||
fast_set(data_ptr.offset(offset as isize), color, len);
|
fast_set(offscreen_ptr as *mut u32, color, len);
|
||||||
|
fast_set(onscreen_ptr as *mut u32, color, len);
|
||||||
}
|
}
|
||||||
|
offscreen_ptr += stride;
|
||||||
|
onscreen_ptr += stride;
|
||||||
|
rows -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw a character
|
/// Draw a character
|
||||||
fn char(&mut self, x: usize, y: usize, character: char, color: u32) {
|
fn char(&mut self, x: usize, y: usize, character: char, color: u32) {
|
||||||
if x + 8 <= self.width && y + 16 <= self.height {
|
if x + 8 <= self.width && y + 16 <= self.height {
|
||||||
let mut offset = y * self.width + x;
|
let mut font_i = 16 * (character as usize);
|
||||||
|
let font_end = font_i + 16;
|
||||||
|
if font_end <= FONT.len() {
|
||||||
|
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||||
|
let mut onscreen_ptr = self.onscreen.as_mut_ptr() as usize;
|
||||||
|
|
||||||
let font_i = 16 * (character as usize);
|
let stride = self.width * 4;
|
||||||
if font_i + 16 <= FONT.len() {
|
|
||||||
for row in 0..16 {
|
let offset = y * stride + x * 4;
|
||||||
let row_data = FONT[font_i + row];
|
offscreen_ptr += offset;
|
||||||
for col in 0..8 {
|
onscreen_ptr += offset;
|
||||||
if (row_data >> (7 - col)) & 1 == 1 {
|
|
||||||
self.data[offset + col] = color;
|
while font_i < font_end {
|
||||||
|
let mut row_data = FONT[font_i];
|
||||||
|
let mut col = 8;
|
||||||
|
while col > 0 {
|
||||||
|
col -= 1;
|
||||||
|
if row_data & 1 == 1 {
|
||||||
|
unsafe {
|
||||||
|
*((offscreen_ptr + col * 4) as *mut u32) = color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
row_data = row_data >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
offset += self.width;
|
unsafe {
|
||||||
|
fast_copy64(onscreen_ptr as *mut u64, offscreen_ptr as *const u64, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
offscreen_ptr += stride;
|
||||||
|
onscreen_ptr += stride;
|
||||||
|
font_i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,9 +236,11 @@ impl<'a> Display<'a> {
|
||||||
let off1 = rows * width;
|
let off1 = rows * width;
|
||||||
let off2 = height * width - off1;
|
let off2 = height * width - off1;
|
||||||
unsafe {
|
unsafe {
|
||||||
let data_ptr = self.data.as_mut_ptr() as *mut u64;
|
let data_ptr = self.offscreen.as_mut_ptr() as *mut u64;
|
||||||
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
|
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
|
||||||
fast_set64(data_ptr.offset(off2 as isize), data, off1);
|
fast_set64(data_ptr.offset(off2 as isize), data, off1);
|
||||||
|
|
||||||
|
fast_copy64(self.onscreen.as_mut_ptr() as *mut u64, data_ptr, off1 + off2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,7 +297,7 @@ impl Ps2 {
|
||||||
self.mouse_x = cmp::max(0, cmp::min(display.width as isize - 1, self.mouse_x as isize + dx)) as usize;
|
self.mouse_x = cmp::max(0, cmp::min(display.width as isize - 1, self.mouse_x as isize + dx)) as usize;
|
||||||
self.mouse_y = cmp::max(0, cmp::min(display.height as isize - 1, self.mouse_y as isize - dy)) as usize;
|
self.mouse_y = cmp::max(0, cmp::min(display.height as isize - 1, self.mouse_y as isize - dy)) as usize;
|
||||||
let offset = self.mouse_y * display.width + self.mouse_x;
|
let offset = self.mouse_y * display.width + self.mouse_x;
|
||||||
display.data[offset as usize] = 0xFF0000;
|
display.onscreen[offset as usize] = 0xFF0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue