Browse Source

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

Thomas Johnson 7 months ago
parent
commit
852b7d149c
2 changed files with 84 additions and 21 deletions
  1. 9
    2
      index.js
  2. 75
    19
      src/lib.rs

+ 9
- 2
index.js View File

@@ -60,11 +60,18 @@ fetch("wtrelease.wasm").then(response => response.arrayBuffer()).then(bytes =>
60 60
         },
61 61
       } }).then(mod =>
62 62
       {
63
+        var i = 100;
63 64
         memory = mod.instance.exports.memory;
64
-        //mod.instance.exports.entrypoint();
65
+        mod.instance.exports.init_graphics(canvas.width, canvas.height);
65 66
         anim(function(ts)
66 67
           {
67
-            mod.instance.exports.paint_red(canvas.width, canvas.height, ts);
68
+            var fr = mod.instance.exports.do_paint(canvas.width, canvas.height, ts);
69
+            i--;
70
+            if (i == 0)
71
+            {
72
+              i = 100;
73
+              console.log("framerate: ", 1000 / fr);
74
+            }
68 75
           });
69 76
       }
70 77
     )

+ 75
- 19
src/lib.rs View File

@@ -2,6 +2,7 @@
2 2
 extern crate wee_alloc;
3 3
 
4 4
 use core::mem::transmute;
5
+use core::cell::RefCell;
5 6
 
6 7
 #[global_allocator]
7 8
 pub static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
@@ -16,18 +17,23 @@ extern "C"
16 17
   fn extern_paint();
17 18
 }
18 19
 
19
-fn log(string: &str)
20
+fn log<T>(string: T) where
21
+T: AsRef<str>
20 22
 {
21 23
   unsafe
22 24
   {
23
-    let (ptr, size) = transmute::<_, (*const u8, usize)>(string);
25
+    let (ptr, size) = transmute::<&str, (*const u8, usize)>(string.as_ref());
24 26
     console_log(ptr, size);
25 27
   }
26 28
 }
27 29
 
28
-fn init_buffer(buffer: &[u8], w: usize, h: usize)
30
+fn init_buffer(w: usize, h: usize)
29 31
 {
30
-  unsafe { extern_init_buffer(buffer.as_ptr(), w, h); }
32
+  BUFFER.with(
33
+    |buffer| 
34
+    {
35
+      unsafe { extern_init_buffer(buffer.borrow().as_ref().unwrap().as_ptr(), w, h); }
36
+    });
31 37
 }
32 38
 
33 39
 fn paint()
@@ -35,6 +41,15 @@ fn paint()
35 41
   unsafe { extern_paint(); }
36 42
 }
37 43
 
44
+const NFRAMES: usize = 100;
45
+
46
+thread_local!
47
+{
48
+  static BUFFER: RefCell<Option<Vec<u8>>> = RefCell::new(None);
49
+  static FRAMECOUNTER: RefCell<(usize, [(f64, f64); NFRAMES], f64, f64, f64, f64)> =
50
+    RefCell::new((1, [(0.0, 0.0); NFRAMES], 0.0, 0.0, 0.0, 0.0));
51
+}
52
+
38 53
 #[no_mangle]
39 54
 pub extern "C" fn entrypoint()
40 55
 {
@@ -42,7 +57,19 @@ pub extern "C" fn entrypoint()
42 57
 }
43 58
 
44 59
 #[no_mangle]
45
-pub extern "C" fn paint_red(w: usize, h: usize, ts: f64)
60
+pub extern "C" fn init_graphics(w: usize, h: usize)
61
+{
62
+  BUFFER.with(
63
+    |buf|
64
+    {
65
+      let mut buffer_ref = buf.borrow_mut();
66
+      *buffer_ref = Some(vec![0; 4 * w * h]);
67
+    });
68
+  init_buffer(w, h);
69
+}
70
+
71
+#[no_mangle]
72
+pub extern "C" fn do_paint(w: usize, h: usize, ts: f64) -> f64
46 73
 {
47 74
   fn smooth_convert(v: f64, step: f64) -> u8
48 75
   {
@@ -54,20 +81,49 @@ pub extern "C" fn paint_red(w: usize, h: usize, ts: f64)
54 81
       return (v * 255.0 / (256.0 - step)) as u8;
55 82
     }
56 83
   }
57
-  let t = (ts / 50.0).rem_euclid(256.0);
58
-  let mut buffer = vec![0; 4 * w * h];
59
-  init_buffer(&buffer, w, h);
60
-  let mut c: (f64, f64, f64) = (t, t, t);
61
-  let step = (1.0, 254.0, 2.0);
62
-  for ii in 0 .. w * h
63
-  {
64
-    buffer[4 * ii]     = smooth_convert(c.0, step.0);
65
-    buffer[4 * ii + 1] = smooth_convert(c.1, step.1);
66
-    buffer[4 * ii + 2] = smooth_convert(c.2, step.2);
67
-    buffer[4 * ii + 3] = 255;
68
-    c = (c.0 + step.0, c.1 + step.1, c.2 + step.2);
69
-    c = (c.0.rem_euclid(256.0), c.1.rem_euclid(256.0), c.2.rem_euclid(256.0));
70
-  }
84
+
85
+  let mut ms_per_frame: f64 = 0.0;
86
+
87
+  // Now with Fun™ linear fit math for framerate!
88
+  FRAMECOUNTER.with(
89
+    |fcc|
90
+    {
91
+      let mut fc = fcc.borrow_mut();
92
+      let idx = fc.0 % NFRAMES;
93
+      let (x, y) = fc.1[idx];
94
+      fc.2 -= x * x;
95
+      fc.3 -= x;
96
+      fc.4 -= x * y;
97
+      fc.5 -= y;
98
+      let (x, y) = (fc.0 as f64, ts);
99
+      fc.1[idx] = (x, y);
100
+      fc.2 += x * x;
101
+      fc.3 += x;
102
+      fc.4 += x * y;
103
+      fc.5 += y;
104
+      ms_per_frame = (NFRAMES as f64 * fc.4 - fc.3 * fc.5) / (NFRAMES as f64 * fc.2 - fc.3 * fc.3);
105
+      fc.0 += 1;
106
+    });
107
+
108
+  let t = (ts / 10.0).rem_euclid(256.0);
109
+  BUFFER.with(
110
+    |buf|
111
+    {
112
+      let mut buffer_ref = buf.borrow_mut();
113
+      let buffer = buffer_ref.as_mut().unwrap();
114
+      let mut c: (f64, f64, f64) = (t, t, t);
115
+      let step = (3.0, 249.0, 5.0);
116
+      for ii in 0 .. w * h
117
+      {
118
+        buffer[4 * ii]     = smooth_convert(c.0, step.0);
119
+        buffer[4 * ii + 1] = smooth_convert(c.1, step.1);
120
+        buffer[4 * ii + 2] = smooth_convert(c.2, step.2);
121
+        buffer[4 * ii + 3] = 255;
122
+        c = (c.0 + step.0, c.1 + step.1, c.2 + step.2);
123
+        c = (c.0.rem_euclid(256.0), c.1.rem_euclid(256.0), c.2.rem_euclid(256.0));
124
+      }
125
+    });
71 126
   paint();
127
+  ms_per_frame
72 128
 }
73 129
 

Loading…
Cancel
Save