Browse Source

Fix GC pauses!

ssao
A.Olokhtonov 10 months ago
parent
commit
08ba8a7687
  1. 3
      README.md
  2. 32
      client/index.html
  3. 88
      client/webgl_geometry.js

3
README.md

@ -7,6 +7,9 @@ Release:
- Textured quads (pictures, code already written in older version) - Textured quads (pictures, code already written in older version)
- Resize and move pictures (draw handles) - Resize and move pictures (draw handles)
- Further investigate GC pauses in Firefox - Further investigate GC pauses in Firefox
* Bugs
+ GC stalls!!!
- Stroke previews get connected when drawn without panning on touch devices
- Debug - Debug
- Restore ability to limit event range - Restore ability to limit event range
* Listeners/events/multiplayer * Listeners/events/multiplayer

32
client/index.html

@ -7,22 +7,22 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link rel="shortcut icon" href="icons/favicon.svg" id="favicon"> <link rel="shortcut icon" href="icons/favicon.svg" id="favicon">
<link rel="stylesheet" type="text/css" href="default.css?v=68"> <link rel="stylesheet" type="text/css" href="default.css?v=69">
<script type="text/javascript" src="aux.js?v=68"></script> <script type="text/javascript" src="aux.js?v=69"></script>
<script type="text/javascript" src="heapify.js?v=68"></script> <script type="text/javascript" src="heapify.js?v=69"></script>
<script type="text/javascript" src="bvh.js?v=68"></script> <script type="text/javascript" src="bvh.js?v=69"></script>
<script type="text/javascript" src="math.js?v=68"></script> <script type="text/javascript" src="math.js?v=69"></script>
<script type="text/javascript" src="tools.js?v=68"></script> <script type="text/javascript" src="tools.js?v=69"></script>
<script type="text/javascript" src="webgl_geometry.js?v=68"></script> <script type="text/javascript" src="webgl_geometry.js?v=69"></script>
<script type="text/javascript" src="webgl_shaders.js?v=68"></script> <script type="text/javascript" src="webgl_shaders.js?v=69"></script>
<script type="text/javascript" src="webgl_listeners.js?v=68"></script> <script type="text/javascript" src="webgl_listeners.js?v=69"></script>
<script type="text/javascript" src="webgl_draw.js?v=68"></script> <script type="text/javascript" src="webgl_draw.js?v=69"></script>
<script type="text/javascript" src="index.js?v=68"></script> <script type="text/javascript" src="index.js?v=69"></script>
<script type="text/javascript" src="client_send.js?v=68"></script> <script type="text/javascript" src="client_send.js?v=69"></script>
<script type="text/javascript" src="client_recv.js?v=68"></script> <script type="text/javascript" src="client_recv.js?v=69"></script>
<script type="text/javascript" src="websocket.js?v=68"></script> <script type="text/javascript" src="websocket.js?v=69"></script>
</head> </head>
<body> <body>
<div class="main"> <div class="main">

88
client/webgl_geometry.js

@ -76,33 +76,18 @@ function rdp_find_max(state, zoom, stroke, start, end) {
return result; return result;
} }
function geometry_write_instances(state, context) { function do_lod(state, context) {
if (state.segments_from.cap < context.clipped_indices.count + 1) { let stack = new Array(4096);
state.segments_from.cap = round_to_pow2(context.clipped_indices.count + 1, 4096);
state.segments_from.data = new Uint32Array(state.segments_from.cap);
}
if (state.segments.cap < state.coordinates.size / 2) {
state.segments.cap = round_to_pow2(state.coordinates.size, 4096);
state.segments.data = new Uint32Array(state.segments.cap);
}
state.segments_from.count = 0;
state.segments.count = 0;
state.stats.rdp_max_count = 0;
state.stats.rdp_segments = 0;
let fast_path_count = 0;
let slow_path_count = 0;
const stack = [];
for (let i = 0; i < context.clipped_indices.count; ++i) { for (let i = 0; i < context.clipped_indices.count; ++i) {
const stroke_index = context.clipped_indices.data[i]; const stroke_index = context.clipped_indices.data[i];
const stroke = state.events[stroke_index]; const stroke = state.events[stroke_index];
const point_count = (stroke.coords_to - stroke.coords_from) / 2; const point_count = (stroke.coords_to - stroke.coords_from) / 2;
if (point_count > 4096) {
stack = new Array(round_to_pow2(point_count, 4096));
}
// Basic CSR crap // Basic CSR crap
state.segments_from.data[i] = state.segments.count; state.segments_from.data[i] = state.segments.count;
@ -113,22 +98,37 @@ function geometry_write_instances(state, context) {
let segment_count = 2; let segment_count = 2;
state.segments.data[state.segments.count++] = 0; state.segments.data[state.segments.count++] = 0;
stack.length = 0; let head = 0;
stack.push({'type': 0, 'start': 0, 'end': point_count - 1}); // Using stack.push() allocates even if the stack is pre-allocated!
while (stack.length > 0) { stack[head++] = 0;
const entry = stack.pop(); stack[head++] = 0;
stack[head++] = point_count - 1;
if (entry.type === 1) {
state.segments.data[state.segments.count++] = entry.value; while (head > 0) {
const end = stack[--head];
const value = start = stack[--head];
const type = stack[--head];
if (type === 1) {
state.segments.data[state.segments.count++] = value;
} else { } else {
const max = rdp_find_max(state, state.canvas.zoom, stroke, entry.start, entry.end); const max = rdp_find_max(state, state.canvas.zoom, stroke, start, end);
if (max !== -1) { if (max !== -1) {
segment_count += 1; segment_count += 1;
stack.push({'type': 0, 'start': max, 'end': entry.end});
stack.push({'type': 1, 'value': max}); stack[head++] = 0;
stack.push({'type': 0, 'start': entry.start, 'end': max}); stack[head++] = max;
stack[head++] = end;
stack[head++] = 1;
stack[head++] = max;
stack[head++] = -1;
stack[head++] = 0;
stack[head++] = start;
stack[head++] = max;
} }
} }
} }
@ -140,6 +140,26 @@ function geometry_write_instances(state, context) {
} }
} }
} }
}
function geometry_write_instances(state, context) {
if (state.segments_from.cap < context.clipped_indices.count + 1) {
state.segments_from.cap = round_to_pow2(context.clipped_indices.count + 1, 4096);
state.segments_from.data = new Uint32Array(state.segments_from.cap);
}
if (state.segments.cap < state.coordinates.size / 2) {
state.segments.cap = round_to_pow2(state.coordinates.size, 4096);
state.segments.data = new Uint32Array(state.segments.cap);
}
state.segments_from.count = 0;
state.segments.count = 0;
state.stats.rdp_max_count = 0;
state.stats.rdp_segments = 0;
do_lod(state, context);
state.segments_from.data[context.clipped_indices.count] = state.segments.count; state.segments_from.data[context.clipped_indices.count] = state.segments.count;
state.segments_from.count = context.clipped_indices.count + 1; state.segments_from.count = context.clipped_indices.count + 1;

Loading…
Cancel
Save