Optimised putImageData
This commit is contained in:
parent
e0551fcee4
commit
4eb1e5035e
|
@ -161,6 +161,9 @@ function CPU(bus, wm, next_tick_immediately)
|
|||
|
||||
this.reg_pdpte = v86util.view(Int32Array, memory, 968, 8);
|
||||
|
||||
this.svga_dirty_bitmap_min_offset = v86util.view(Uint32Array, memory, 716, 1);
|
||||
this.svga_dirty_bitmap_max_offset = v86util.view(Uint32Array, memory, 720, 1);
|
||||
|
||||
this.fw_value = [];
|
||||
this.fw_pointer = 0;
|
||||
this.option_roms = [];
|
||||
|
|
|
@ -40,6 +40,10 @@ pub const instruction_counter: *mut u32 = 664 as *mut u32;
|
|||
pub const sreg: *mut u16 = 668 as *mut u16;
|
||||
pub const dreg: *mut i32 = 684 as *mut i32;
|
||||
|
||||
// filled in by svga_fill_pixel_buffer, read by javacsript for optimised putImageData calls
|
||||
pub const svga_dirty_bitmap_min_offset: *mut u32 = 716 as *mut u32;
|
||||
pub const svga_dirty_bitmap_max_offset: *mut u32 = 720 as *mut u32;
|
||||
|
||||
pub const segment_is_null: *mut bool = 724 as *mut bool;
|
||||
pub const segment_offsets: *mut i32 = 736 as *mut i32;
|
||||
pub const segment_limits: *mut u32 = 768 as *mut u32;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
|
||||
use cpu::global_pointers;
|
||||
use cpu::memory;
|
||||
|
||||
pub static mut dirty_bitmap: Vec<u64> = Vec::new();
|
||||
|
@ -26,6 +27,9 @@ pub unsafe fn svga_mark_dirty() {
|
|||
}
|
||||
|
||||
fn iter_dirty_pages(f: &dyn Fn(isize)) {
|
||||
let mut min_off = u32::MAX;
|
||||
let mut max_off = u32::MIN;
|
||||
|
||||
for (i, &word) in unsafe { &dirty_bitmap }.iter().enumerate() {
|
||||
if word == 0 {
|
||||
continue;
|
||||
|
@ -36,13 +40,22 @@ fn iter_dirty_pages(f: &dyn Fn(isize)) {
|
|||
}
|
||||
let off = ((i << 6 | j) << 12) as isize;
|
||||
dbg_assert!(off < unsafe { memory::vga_memory_size as isize });
|
||||
if min_off == u32::MAX {
|
||||
min_off = off as u32;
|
||||
}
|
||||
max_off = off as u32;
|
||||
f(off);
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
*global_pointers::svga_dirty_bitmap_min_offset = min_off;
|
||||
*global_pointers::svga_dirty_bitmap_max_offset = max_off;
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn svga_fill_pixel_buffer(bpp: i32, svga_dest_offset: i32) {
|
||||
pub unsafe fn svga_fill_pixel_buffer(bpp: u32, svga_dest_offset: u32) {
|
||||
let debug_bounds = false;
|
||||
|
||||
match bpp {
|
||||
|
@ -58,6 +71,8 @@ pub unsafe fn svga_fill_pixel_buffer(bpp: i32, svga_dest_offset: i32) {
|
|||
isize::min(1024, dest_buffer.len() as isize - dest_offset)
|
||||
};
|
||||
|
||||
dbg_assert!(src as u32 % 8 == 0);
|
||||
dbg_assert!(dest as u32 % 8 == 0);
|
||||
for i in 0..end {
|
||||
dbg_assert!(off + i < memory::vga_memory_size as isize);
|
||||
let dword = *src.offset(i);
|
||||
|
|
28
src/vga.js
28
src/vga.js
|
@ -2279,6 +2279,9 @@ VGAScreen.prototype.screen_fill_buffer = function()
|
|||
|
||||
if(this.svga_enabled)
|
||||
{
|
||||
let min_y = 0;
|
||||
let max_y = this.svga_height - 1;
|
||||
|
||||
if(this.svga_bpp === 8)
|
||||
{
|
||||
// XXX: Slow, should be ported to rust, but it doesn't have access to vga256_palette
|
||||
|
@ -2295,18 +2298,23 @@ VGAScreen.prototype.screen_fill_buffer = function()
|
|||
else
|
||||
{
|
||||
this.cpu.svga_fill_pixel_buffer(this.svga_bpp, this.svga_offset);
|
||||
|
||||
const bytes_per_pixel = this.svga_bpp === 15 ? 2 : this.svga_bpp / 8;
|
||||
const bytes_per_line = bytes_per_pixel * this.svga_width;
|
||||
min_y = this.cpu.svga_dirty_bitmap_min_offset[0] / bytes_per_line | 0;
|
||||
max_y = this.cpu.svga_dirty_bitmap_max_offset[0] / bytes_per_line | 0;
|
||||
}
|
||||
|
||||
const min_y = 0;
|
||||
const max_y = this.svga_height;
|
||||
|
||||
this.bus.send("screen-fill-buffer-end", [{
|
||||
image_data: this.image_data,
|
||||
screen_x: 0, screen_y: min_y,
|
||||
buffer_x: 0, buffer_y: min_y,
|
||||
buffer_width: this.svga_width,
|
||||
buffer_height: max_y - min_y + 1,
|
||||
}]);
|
||||
if(min_y < max_y)
|
||||
{
|
||||
this.bus.send("screen-fill-buffer-end", [{
|
||||
image_data: this.image_data,
|
||||
screen_x: 0, screen_y: min_y,
|
||||
buffer_x: 0, buffer_y: min_y,
|
||||
buffer_width: this.svga_width,
|
||||
buffer_height: max_y - min_y + 1,
|
||||
}]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue