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 2 weeks 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