Browse Source

Pass stroke widths to wasm (not actually writing any values right now,

just some busywork to allocate memory and pass pointers)
sdf
A.Olokhtonov 10 months ago
parent
commit
ce824a8e31
  1. 1
      client/lod_worker.js
  2. 19
      client/speed.js
  3. 21
      client/wasm/lod.c
  4. BIN
      client/wasm/lod.wasm
  5. 2
      client/webgl_draw.js

1
client/lod_worker.js

@ -19,6 +19,7 @@ function work(indices_base, indices_count, zoom, offsets) { @@ -19,6 +19,7 @@ function work(indices_base, indices_count, zoom, offsets) {
exports.do_lod(
indices_base, indices_count, zoom,
offsets['coords_from'],
offsets['width'],
offsets['xs'],
offsets['ys'],
offsets['pressures'],

19
client/speed.js

@ -80,12 +80,17 @@ async function init_wasm(state) { @@ -80,12 +80,17 @@ async function init_wasm(state) {
'used': 0,
'cap': initial
},
'width': {
'used': 0,
'cap': initial
}
};
state.wasm.buffers['xs'].offset = state.wasm.exports.alloc_static(initial);
state.wasm.buffers['ys'].offset = state.wasm.exports.alloc_static(initial);
state.wasm.buffers['pressures'].offset = state.wasm.exports.alloc_static(initial);
state.wasm.buffers['coords_from'].offset = state.wasm.exports.alloc_static(initial);
state.wasm.buffers['width'].offset = state.wasm.exports.alloc_static(initial);
const mem = state.wasm.memory.buffer;
@ -97,6 +102,8 @@ async function init_wasm(state) { @@ -97,6 +102,8 @@ async function init_wasm(state) {
mem, state.wasm.buffers['pressures'].offset);
state.wasm.buffers['coords_from'].tv = tv_create_on(Uint32Array, initial / 4,
mem, state.wasm.buffers['coords_from'].offset);
state.wasm.buffers['width'].tv = tv_create_on(Uint32Array, initial / 4,
mem, state.wasm.buffers['width'].offset);
tv_add(state.wasm.buffers['coords_from'].tv, 0);
state.wasm.buffers['coords_from'].used = 4;
@ -108,6 +115,7 @@ function wasm_ensure_by(state, nstrokes, ncoords) { @@ -108,6 +115,7 @@ function wasm_ensure_by(state, nstrokes, ncoords) {
const old_ys_offset = buffers['ys'].offset;
const old_coords_from_offset = buffers['coords_from'].offset;
const old_pressures_offset = buffers['pressures'].offset;
const old_width_offset = buffers['width'].offset;
let realloc = false;
let coords_bytes = buffers['xs'].cap;
@ -135,23 +143,31 @@ function wasm_ensure_by(state, nstrokes, ncoords) { @@ -135,23 +143,31 @@ function wasm_ensure_by(state, nstrokes, ncoords) {
buffers['ys'].offset = state.wasm.exports.alloc_static(coords_bytes);
buffers['pressures'].offset = state.wasm.exports.alloc_static(coords_bytes);
buffers['coords_from'].offset = state.wasm.exports.alloc_static(stroke_bytes);
buffers['width'].offset = state.wasm.exports.alloc_static(stroke_bytes);
buffers['xs'].tv = tv_create_on(Float32Array, coords_bytes / 4, mem, buffers['xs'].offset);
buffers['ys'].tv = tv_create_on(Float32Array, coords_bytes / 4, mem, buffers['ys'].offset);
buffers['pressures'].tv = tv_create_on(Uint8Array, coords_bytes, mem, buffers['pressures'].offset);
buffers['coords_from'].tv = tv_create_on(Uint32Array, stroke_bytes / 4, mem, buffers['coords_from'].offset);
buffers['width'].tv = tv_create_on(Uint32Array, stroke_bytes / 4, mem, buffers['width'].offset);
// TODO: this should have been automatic maybe?
buffers['xs'].tv.size = buffers['xs'].used / 4;
buffers['ys'].tv.size = buffers['ys'].used / 4;
buffers['pressures'].tv.size = buffers['pressures'].used;
buffers['coords_from'].tv.size = buffers['coords_from'].used / 4;
buffers['width'].tv.size = buffers['width'].used / 4;
// TODO: this is SUS, should all the caps really be coords_bytes?
buffers['xs'].cap = buffers['ys'].cap = buffers['pressures'].cap = coords_bytes;
buffers['coords_from'].cap = stroke_bytes;
buffers['coords_from'].cap = buffers['width'].cap = stroke_bytes;
const tmp = new Uint8Array(Math.max(coords_bytes, stroke_bytes));
// Copy from back to front (otherwise we will overwrite)
tmp.set(new Uint8Array(mem, old_width_offset, buffers['width'].used));
memv.set(new Uint8Array(tmp.buffer, 0, buffers['width'].used), buffers['width'].offset);
tmp.set(new Uint8Array(mem, old_coords_from_offset, buffers['coords_from'].used));
memv.set(new Uint8Array(tmp.buffer, 0, buffers['coords_from'].used), buffers['coords_from'].offset);
@ -180,6 +196,7 @@ async function do_lod(state, context) { @@ -180,6 +196,7 @@ async function do_lod(state, context) {
const indices_per_thread = Math.floor(context.clipped_indices.size / state.wasm.workers.length);
const offsets = {
'coords_from': buffers['coords_from'].offset,
'width': buffers['width'].offset,
'xs': buffers['xs'].offset,
'ys': buffers['ys'].offset,
'pressures': buffers['pressures'].offset,

21
client/wasm/lod.c

@ -197,6 +197,7 @@ rdp_find_max(float *xs, float *ys, unsigned char *pressures, float zoom, int coo @@ -197,6 +197,7 @@ rdp_find_max(float *xs, float *ys, unsigned char *pressures, float zoom, int coo
void
do_lod(int *clipped_indices, int clipped_count, float zoom,
int *stroke_coords_from,
int *width,
float *xs,
float *ys,
unsigned char *pressures,
@ -280,18 +281,20 @@ do_lod(int *clipped_indices, int clipped_count, float zoom, @@ -280,18 +281,20 @@ do_lod(int *clipped_indices, int clipped_count, float zoom,
// Write actual coordinates (points) and stroke ids
// Do this in one allocation so that they're not interleaved between threads
char *output = alloc_dynamic(segments_head * (3 * 4 + 1));
char *output = alloc_dynamic(segments_head * (3 * 4 + 1) + clipped_count * 4);
float *points = (float *) output;
int *ids = (int *) (output + segments_head * 4 * 2);
unsigned char *pressures_res = (unsigned char *) (output + segments_head * 4 * 3);
unsigned int *batches = (unsigned int *) (output + segments_head * (4 * 3 + 1));
int phead = 0;
int ihead = 0;
float sqrt_zoom = __builtin_sqrtf(zoom);
int last_lod = -1;
for (int i = 0; i < clipped_count; ++i) {
int stroke_index = clipped_indices[i];
// TODO: convert to a proper CSR, save half the memory
int base_stroke = stroke_coords_from[stroke_index];
int from = segments_from[i];
int to = segments_from[i + 1];
@ -312,6 +315,20 @@ do_lod(int *clipped_indices, int clipped_count, float zoom, @@ -312,6 +315,20 @@ do_lod(int *clipped_indices, int clipped_count, float zoom,
ids[ihead++] = stroke_index | (1 << 31);
}
}
// Compute recommended LOD level, add to current batch or start new batch
float sqrt_width = __builtin_sqrtf(width[stroke_index]); // TOOD: pass in stroke width
int lod = __builtin_round(sqrt_zoom * sqrt_width * 0.3333f);
#if 0
if (__builtin_abs(lod - last_lod) > 2) {
// Start new batch
} else {
// Add to existing batch
}
last_lod = lod;
#endif
}
result_buffer[0] = output;

BIN
client/wasm/lod.wasm

Binary file not shown.

2
client/webgl_draw.js

@ -305,7 +305,7 @@ async function draw(state, context, animate, ts) { @@ -305,7 +305,7 @@ async function draw(state, context, animate, ts) {
});
if (i % 2 == 1) {
batches[batches.length - 1].lod = Math.max(0, batches[batches.length - 1].lod - 4);
batches[batches.length - 1].lod = Math.max(0, batches[batches.length - 1].lod);
}
}
batches.push({'index': segment_count, 'lod': -1}); // lod unused

Loading…
Cancel
Save