Browse Source

Added framerate metric, and discovered that I'm doing too many floating point ops

master
Thomas Johnson 1 year ago
parent
commit
852b7d149c
  1. 11
      index.js
  2. 94
      src/lib.rs

11
index.js

@ -60,11 +60,18 @@ fetch("wtrelease.wasm").then(response => response.arrayBuffer()).then(bytes =>
},
} }).then(mod =>
{
var i = 100;
memory = mod.instance.exports.memory;
//mod.instance.exports.entrypoint();
mod.instance.exports.init_graphics(canvas.width, canvas.height);
anim(function(ts)
{
mod.instance.exports.paint_red(canvas.width, canvas.height, ts);
var fr = mod.instance.exports.do_paint(canvas.width, canvas.height, ts);
i--;
if (i == 0)
{
i = 100;
console.log("framerate: ", 1000 / fr);
}
});
}
)

94
src/lib.rs

@ -2,6 +2,7 @@
extern crate wee_alloc;
use core::mem::transmute;
use core::cell::RefCell;
#[global_allocator]
pub static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
@ -16,18 +17,23 @@ extern "C"
fn extern_paint();
}
fn log(string: &str)
fn log<T>(string: T) where
T: AsRef<str>
{
unsafe
{
let (ptr, size) = transmute::<_, (*const u8, usize)>(string);
let (ptr, size) = transmute::<&str, (*const u8, usize)>(string.as_ref());
console_log(ptr, size);
}
}
fn init_buffer(buffer: &[u8], w: usize, h: usize)
fn init_buffer(w: usize, h: usize)
{
unsafe { extern_init_buffer(buffer.as_ptr(), w, h); }
BUFFER.with(
|buffer|
{
unsafe { extern_init_buffer(buffer.borrow().as_ref().unwrap().as_ptr(), w, h); }
});
}
fn paint()
@ -35,6 +41,15 @@ fn paint()
unsafe { extern_paint(); }
}
const NFRAMES: usize = 100;
thread_local!
{
static BUFFER: RefCell<Option<Vec<u8>>> = RefCell::new(None);
static FRAMECOUNTER: RefCell<(usize, [(f64, f64); NFRAMES], f64, f64, f64, f64)> =
RefCell::new((1, [(0.0, 0.0); NFRAMES], 0.0, 0.0, 0.0, 0.0));
}
#[no_mangle]
pub extern "C" fn entrypoint()
{
@ -42,7 +57,19 @@ pub extern "C" fn entrypoint()
}
#[no_mangle]
pub extern "C" fn paint_red(w: usize, h: usize, ts: f64)
pub extern "C" fn init_graphics(w: usize, h: usize)
{
BUFFER.with(
|buf|
{
let mut buffer_ref = buf.borrow_mut();
*buffer_ref = Some(vec![0; 4 * w * h]);
});
init_buffer(w, h);
}
#[no_mangle]
pub extern "C" fn do_paint(w: usize, h: usize, ts: f64) -> f64
{
fn smooth_convert(v: f64, step: f64) -> u8
{
@ -54,20 +81,49 @@ pub extern "C" fn paint_red(w: usize, h: usize, ts: f64)
return (v * 255.0 / (256.0 - step)) as u8;
}
}
let t = (ts / 50.0).rem_euclid(256.0);
let mut buffer = vec![0; 4 * w * h];
init_buffer(&buffer, w, h);
let mut c: (f64, f64, f64) = (t, t, t);
let step = (1.0, 254.0, 2.0);
for ii in 0 .. w * h
{
buffer[4 * ii] = smooth_convert(c.0, step.0);
buffer[4 * ii + 1] = smooth_convert(c.1, step.1);
buffer[4 * ii + 2] = smooth_convert(c.2, step.2);
buffer[4 * ii + 3] = 255;
c = (c.0 + step.0, c.1 + step.1, c.2 + step.2);
c = (c.0.rem_euclid(256.0), c.1.rem_euclid(256.0), c.2.rem_euclid(256.0));
}
let mut ms_per_frame: f64 = 0.0;
// Now with Fun™ linear fit math for framerate!
FRAMECOUNTER.with(
|fcc|
{
let mut fc = fcc.borrow_mut();
let idx = fc.0 % NFRAMES;
let (x, y) = fc.1[idx];
fc.2 -= x * x;
fc.3 -= x;
fc.4 -= x * y;
fc.5 -= y;
let (x, y) = (fc.0 as f64, ts);
fc.1[idx] = (x, y);
fc.2 += x * x;
fc.3 += x;
fc.4 += x * y;
fc.5 += y;
ms_per_frame = (NFRAMES as f64 * fc.4 - fc.3 * fc.5) / (NFRAMES as f64 * fc.2 - fc.3 * fc.3);
fc.0 += 1;
});
let t = (ts / 10.0).rem_euclid(256.0);
BUFFER.with(
|buf|
{
let mut buffer_ref = buf.borrow_mut();
let buffer = buffer_ref.as_mut().unwrap();
let mut c: (f64, f64, f64) = (t, t, t);
let step = (3.0, 249.0, 5.0);
for ii in 0 .. w * h
{
buffer[4 * ii] = smooth_convert(c.0, step.0);
buffer[4 * ii + 1] = smooth_convert(c.1, step.1);
buffer[4 * ii + 2] = smooth_convert(c.2, step.2);
buffer[4 * ii + 3] = 255;
c = (c.0 + step.0, c.1 + step.1, c.2 + step.2);
c = (c.0.rem_euclid(256.0), c.1.rem_euclid(256.0), c.2.rem_euclid(256.0));
}
});
paint();
ms_per_frame
}
Loading…
Cancel
Save