Browse Source

Move point writes to WASM, already a lot faster!!!!

ssao
A.Olokhtonov 10 months ago
parent
commit
3bf812df39
  1. 55
      client/speed.js
  2. 31
      client/wasm/lod.c
  3. BIN
      client/wasm/lod.wasm
  4. 40
      client/webgl_geometry.js

55
client/speed.js

@ -52,7 +52,6 @@ function do_lod_wasm(state, context) { @@ -52,7 +52,6 @@ function do_lod_wasm(state, context) {
const segments_from = state.wasm.exports.alloc((context.clipped_indices.size + 1) * 4);
const segments = state.wasm.exports.alloc(state.segments.capacity * 4);
const coordinates = state.wasm.exports.alloc(state.coordinates.size * 4);
const mem = new Uint8Array(state.wasm.exports.memory.buffer);
mem.set(tv_bytes(context.clipped_indices), clipped_indices);
@ -71,6 +70,8 @@ function do_lod_wasm(state, context) { @@ -71,6 +70,8 @@ function do_lod_wasm(state, context) {
// copy result back
const wasm_segments = new Uint32Array(state.wasm.exports.memory.buffer, segments, segment_count);
const wasm_segments_from = new Uint32Array(state.wasm.exports.memory.buffer, segments_from, context.clipped_indices.size + 1);
const wasm_points = new Float32Array(state.wasm.exports.memory.buffer, coordinates + state.coordinates.size * 4, segment_count * 2);
const wasm_ids = new Uint32Array(state.wasm.exports.memory.buffer, coordinates + (state.coordinates.size + segment_count * 2) * 4, segment_count);
state.segments.data.set(wasm_segments);
state.segments.size = segment_count;
@ -78,8 +79,16 @@ function do_lod_wasm(state, context) { @@ -78,8 +79,16 @@ function do_lod_wasm(state, context) {
state.segments_from.data.set(wasm_segments_from);
state.segments_from.size = context.clipped_indices.size + 1;
state.wasm.exports.total_free();
tv_ensure(context.instance_data_points, segment_count * 2);
tv_ensure(context.instance_data_ids, segment_count);
context.instance_data_points.data.set(wasm_points);
context.instance_data_points.size = segment_count * 2;
context.instance_data_ids.data.set(wasm_ids);
context.instance_data_ids.size = segment_count;
state.wasm.exports.total_free();
return segment_count;
}
@ -164,5 +173,47 @@ function do_lod(state, context) { @@ -164,5 +173,47 @@ function do_lod(state, context) {
state.segments_from.size = context.clipped_indices.size + 1;
state.segments.size = segments_head;
write_coordinates(state, context);
return segments_head;
}
function write_coordinates(state, context) {
tv_ensure(context.instance_data_points, state.segments.size * 2);
tv_ensure(context.instance_data_ids, state.segments.size);
tv_clear(context.instance_data_points);
tv_clear(context.instance_data_ids);
const clipped = context.clipped_indices.data;
const segments_from = state.segments_from.data;
const segments = state.segments.data;
const coords = state.coordinates.data;
const events = state.events;
// TODO: move this loop to WASM
for (let i = 0; i < state.segments_from.size - 1; ++i) {
const stroke_index = clipped[i];
const coords_from = state.events[stroke_index].coords_from;
const from = segments_from[i];
const to = segments_from[i + 1];
for (let j = from; j < to; ++j) {
const base_this = segments[j];
const ax = coords[coords_from + base_this * 2 + 0];
const ay = coords[coords_from + base_this * 2 + 1];
tv_add(context.instance_data_points, ax);
tv_add(context.instance_data_points, ay);
// Pack 1 into highest bit of stroke_index if we should not draw a segemtn from this
// point to the next one
if (j != to - 1) {
tv_add(context.instance_data_ids, stroke_index);
} else {
tv_add(context.instance_data_ids, stroke_index | (1 << 31));
}
}
}
}

31
client/wasm/lod.c

@ -130,6 +130,37 @@ do_lod(int *clipped_indices, int clipped_count, float zoom, @@ -130,6 +130,37 @@ do_lod(int *clipped_indices, int clipped_count, float zoom,
}
segments_from[clipped_count] = segments_head;
// Write actual coordinates (points) and stroke ids
float *points = alloc(segments_head * 2 * 4);
int *ids = alloc(segments_head * 4);
int phead = 0;
int ihead = 0;
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];
for (int j = from; j < to; ++j) {
int point_index = segments[j];
float x = coordinates[base_stroke + point_index * 2 + 0];
float y = coordinates[base_stroke + point_index * 2 + 1];
points[phead++] = x;
points[phead++] = y;
if (j != to - 1) {
ids[ihead++] = stroke_index;
} else {
ids[ihead++] = stroke_index | (1 << 31);
}
}
}
return(segments_head);
}

BIN
client/wasm/lod.wasm

Binary file not shown.

40
client/webgl_geometry.js

@ -49,47 +49,9 @@ function geometry_write_instances(state, context) { @@ -49,47 +49,9 @@ function geometry_write_instances(state, context) {
const segment_count = do_lod(state, context);
tv_ensure(context.instance_data_points, state.segments.size * 2);
tv_ensure(context.instance_data_ids, state.segments.size);
tv_clear(context.instance_data_points);
tv_clear(context.instance_data_ids);
const clipped = context.clipped_indices.data;
const segments_from = state.segments_from.data;
const segments = state.segments.data;
const coords = state.coordinates.data;
const events = state.events;
// TODO: move this loop to WASM
for (let i = 0; i < state.segments_from.size - 1; ++i) {
const stroke_index = clipped[i];
const coords_from = state.events[stroke_index].coords_from;
const from = segments_from[i];
const to = segments_from[i + 1];
for (let j = from; j < to; ++j) {
const base_this = segments[j];
const ax = coords[coords_from + base_this * 2 + 0];
const ay = coords[coords_from + base_this * 2 + 1];
tv_add(context.instance_data_points, ax);
tv_add(context.instance_data_points, ay);
// Pack 1 into highest bit of stroke_index if we should not draw a segemtn from this
// point to the next one
if (j != to - 1) {
tv_add(context.instance_data_ids, stroke_index);
} else {
tv_add(context.instance_data_ids, stroke_index | (1 << 31));
}
}
}
if (config.debug_print) console.debug('instances:', state.segments.count, 'rdp max:', state.stats.rdp_max_count, 'rdp segments:', state.stats.rdp_segments);
return state.segments.size;
return segment_count;
}
function geometry_add_stroke(state, context, stroke, stroke_index, skip_bvh = false) {

Loading…
Cancel
Save