From 58f2a60295713b7cee06e0d8ee3ee6a9c55f3e57 Mon Sep 17 00:00:00 2001 From: "A.Olokhtonov" Date: Sun, 17 Mar 2024 15:43:25 +0300 Subject: [PATCH] Fix wrong wasm allocation, remove unused js LOD code, take radius of stroke into account when doing LOD, reduce EPS for LOD --- client/client_recv.js | 2 +- client/index.html | 1 - client/index.js | 5 +-- client/speed.js | 87 +------------------------------------- client/wasm/lod.c | 10 +++-- client/wasm/lod.wasm | Bin 1965 -> 7584 bytes client/webgl_listeners.js | 6 --- server/milton.js | 17 +++++--- 8 files changed, 22 insertions(+), 106 deletions(-) diff --git a/client/client_recv.js b/client/client_recv.js index 6b6bf68..d74ae9d 100644 --- a/client/client_recv.js +++ b/client/client_recv.js @@ -434,7 +434,7 @@ async function handle_message(state, context, d) { const user_count = des_u32(d); const total_points = des_u32(d); - wasm_ensure_by(state, event_count, round_to_pow2(total_points * 2)); + wasm_ensure_by(state, event_count, round_to_pow2(total_points * 2, 4096)); if (config.debug_print) console.debug(`${event_count} events in init`); diff --git a/client/index.html b/client/index.html index e9268ec..2bbdaf0 100644 --- a/client/index.html +++ b/client/index.html @@ -39,7 +39,6 @@ -
diff --git a/client/index.js b/client/index.js index eee568c..0f484b4 100644 --- a/client/index.js +++ b/client/index.js @@ -25,8 +25,8 @@ const config = { stroke_texture_size: 1024, // means no more than 1024^2 = 1M strokes in total (this is a LOT. HMH blackboard has like 80K) dynamic_stroke_texture_size: 128, // means no more than 128^2 = 16K dynamic strokes at once benchmark: { - zoom: 0.03, - offset: { x: 720, y: 400 }, + zoom: 0.00001, + offset: { x: 425, y: -1195 }, frames: 500, }, }; @@ -205,7 +205,6 @@ async function main() { 'debug': { 'red': false, 'do_prepass': true, - 'use_wasm': true, 'limit_from': false, 'limit_to': false, 'render_from': 0, diff --git a/client/speed.js b/client/speed.js index 97ab900..f4459a8 100644 --- a/client/speed.js +++ b/client/speed.js @@ -99,7 +99,7 @@ function wasm_ensure_by(state, nstrokes, ncoords) { } } -function do_lod_wasm(state, context) { +function do_lod(state, context) { state.wasm.exports.free_dynamic(); const clipped_indices = state.wasm.exports.alloc_dynamic(context.clipped_indices.size * 4); @@ -140,88 +140,3 @@ function do_lod_wasm(state, context) { return segment_count; } - -function do_lod(state, context) { - if (state.debug.use_wasm) { - return do_lod_wasm(state, context); - } - - const zoom = state.canvas.zoom; - const segments_data = state.segments.data; - - let segments_head = 0; - - for (let i = 0; i < context.clipped_indices.size; ++i) { - const stroke_index = context.clipped_indices.data[i]; - const stroke = state.events[stroke_index]; - const point_count = (stroke.coords_to - stroke.coords_from) / 2; - const coords_from = stroke.coords_from; - - if (point_count > state.rdp_traverse_stack.length) { - //console.size('allocate') - state.rdp_traverse_stack = new Uint32Array(round_to_pow2(point_count, 4096)); - } - - const stack = state.rdp_traverse_stack; - - // Basic CSR crap - state.segments_from.data[i] = segments_head; - - if (state.canvas.zoom <= state.line_threshold.data[stroke_index]) { - segments_data[segments_head++] = 0; - segments_data[segments_head++] = point_count - 1; - } else { - let segment_count = 2; - - segments_data[segments_head++] = 0; - - let head = 0; - // Using stack.push() allocates even if the stack is pre-allocated! - - stack[head++] = 0; - stack[head++] = 0; - stack[head++] = point_count - 1; - - while (head > 0) { - const end = stack[--head]; - const value = start = stack[--head]; - const type = stack[--head]; - - if (type === 1) { - segments_data[segments_head++] = value; - } else { - const max = rdp_find_max(state, zoom, coords_from, start, end); - if (max !== -1) { - segment_count += 1; - - stack[head++] = 0; - stack[head++] = max; - stack[head++] = end; - - stack[head++] = 1; - stack[head++] = max; - stack[head++] = -1; - - stack[head++] = 0; - stack[head++] = start; - stack[head++] = max; - } - } - } - - segments_data[segments_head++] = point_count - 1; - - if (segment_count === 2 && state.canvas.zoom > state.line_threshold.data[stroke_index]) { - state.line_threshold.data[stroke_index] = state.canvas.zoom; - } - } - } - - state.segments_from.data[context.clipped_indices.size] = segments_head; - state.segments_from.size = context.clipped_indices.size + 1; - state.segments.size = segments_head; - - write_coordinates(state, context); - - return segments_head; -} diff --git a/client/wasm/lod.c b/client/wasm/lod.c index 233359f..19a13e3 100644 --- a/client/wasm/lod.c +++ b/client/wasm/lod.c @@ -1,3 +1,5 @@ +#include + extern char __heap_base; static int allocated_static; @@ -35,8 +37,10 @@ static int rdp_find_max(float *coordinates, unsigned char *pressures, float zoom, int coords_from, int segment_start, int segment_end) { - float EPS = 1.0 / zoom; + float EPS = 0.125 / zoom; +// __i32x4 a = wasm_i32x4_load16x4(coordinates); + int result = -1; float max_dist = 0.0f; @@ -64,8 +68,8 @@ rdp_find_max(float *coordinates, unsigned char *pressures, float zoom, int coord float apx = px - ax; float apy = py - ay; - float dist = __builtin_fabsf(apx * dir_nx + apy * dir_ny); - //+ __builtin_abs(pp - ap) / 255.0f + __builtin_abs(pp - bp) / 255.0f; + float dist = __builtin_fabsf(apx * dir_nx + apy * dir_ny) + + __builtin_abs(pp - ap) / 255.0f + __builtin_abs(pp - bp) / 255.0f; if (dist > EPS && dist > max_dist) { result = i; diff --git a/client/wasm/lod.wasm b/client/wasm/lod.wasm index 324b0df30ad89f5b81d7d93743f41094b9e7bcf6..64b42bf740ac1292484401323144888252d49603 100755 GIT binary patch literal 7584 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 I&EPWn7fk!8fB*mh diff --git a/client/webgl_listeners.js b/client/webgl_listeners.js index a2309c1..6848d4d 100644 --- a/client/webgl_listeners.js +++ b/client/webgl_listeners.js @@ -26,7 +26,6 @@ function debug_panel_init(state, context) { document.getElementById('debug-do-prepass').checked = state.debug.do_prepass; document.getElementById('debug-limit-from').checked = state.debug.limit_from; document.getElementById('debug-limit-to').checked = state.debug.limit_to; - document.getElementById('debug-use-wasm').checked = state.debug.use_wasm; document.getElementById('debug-red').addEventListener('change', (e) => { state.debug.red = e.target.checked; @@ -38,11 +37,6 @@ function debug_panel_init(state, context) { schedule_draw(state, context); }); - document.getElementById('debug-use-wasm').addEventListener('change', (e) => { - state.debug.use_wasm = e.target.checked; - schedule_draw(state, context); - }); - document.getElementById('debug-limit-from').addEventListener('change', (e) => { state.debug.limit_from = e.target.checked; schedule_draw(state, context); diff --git a/server/milton.js b/server/milton.js index fc24fe1..e437ee1 100644 --- a/server/milton.js +++ b/server/milton.js @@ -9,22 +9,27 @@ let first_point_y = null; function parse_and_insert_stroke(desk_id, line) { const words = line.split(' '); const width = parseInt(words.shift()); - const points = new Float32Array(words.map(i => parseFloat(i))); + const data = new Float32Array(words.map(i => parseFloat(i))); + + const points = new Float32Array(data.length / 3 * 2); + const pressures = new Uint8Array(data.length / 3); if (first_point_x === null) { first_point_x = points[0]; first_point_y = points[1]; } - for (let i = 0; i < points.length; i += 2) { - points[i + 0] -= first_point_x; - points[i + 1] -= first_point_y; + for (let i = 0; i < data.length; i += 3) { + points[i / 3 * 2 + 0] = data[i + 0]; + points[i / 3 * 2 + 1] = data[i + 1]; + pressures[i / 3 + 0] = Math.floor(data[i + 2] * 255); } const stroke_res = storage.queries.insert_stroke.get({ '$width': width, '$color': 0, - '$points': points + '$points': points, + '$pressures': pressures, }); storage.queries.insert_event.run({ @@ -62,4 +67,4 @@ async function import_milton_file_to_sqlite(fullpath) { console.log(`Finished importing desk ${desk_id}`); } -import_milton_file_to_sqlite("/code/desk2/server/points.txt"); +import_milton_file_to_sqlite("/home/aolo2/Documents/bin/milton/build/points_pressure.txt");