aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorMarvin Borner2024-12-23 23:05:14 +0100
committerMarvin Borner2024-12-23 23:05:14 +0100
commita442de647e4762bb0842af30081b74f2467feee9 (patch)
tree435872b09fdc35e6cefa0fc63277d7fdfb7a6aef
parente128423aea9c75e34797bdb4c12d1f02d36c6897 (diff)
Massive speedup
-rw-r--r--canvasWorker.js86
-rw-r--r--main.js86
2 files changed, 114 insertions, 58 deletions
diff --git a/canvasWorker.js b/canvasWorker.js
index 42f4b84..85944c1 100644
--- a/canvasWorker.js
+++ b/canvasWorker.js
@@ -25,21 +25,21 @@ const createProgram = (gl, vertexShader, fragmentShader) => {
const initGL = () => {
const vertexShaderSource = `
- attribute vec2 a_position;
- uniform vec2 u_resolution;
- void main() {
- vec2 inverted = vec2(a_position.x, u_resolution.y - a_position.y); // !! :)
- vec2 zeroToOne = inverted / u_resolution;
- vec2 zeroToTwo = zeroToOne * 2.0;
- vec2 clipSpace = zeroToTwo - 1.0;
- gl_Position = vec4(clipSpace, 0, 1);
- }`;
+ attribute vec2 a_position;
+ uniform vec2 u_resolution;
+ void main() {
+ vec2 inverted = vec2(a_position.x, u_resolution.y - a_position.y); // !! :)
+ vec2 zeroToOne = inverted / u_resolution;
+ vec2 zeroToTwo = zeroToOne * 2.0;
+ vec2 clipSpace = zeroToTwo - 1.0;
+ gl_Position = vec4(clipSpace, 0, 1);
+ }`;
const fragmentShaderSource = `
- precision mediump float;
- uniform vec4 u_color;
- void main() {
- gl_FragColor = u_color;
- }`;
+ precision mediump float;
+ uniform vec4 u_color;
+ void main() {
+ gl_FragColor = u_color;
+ }`;
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(
@@ -130,19 +130,51 @@ self.onmessage = (msg) => {
console.log("using canvas");
gl = canvas.getContext("2d");
}
- } else if (useWebGL) {
- const [color, x, y, width, height] = msg.data;
- let colorArr =
- color == "white"
- ? [1, 1, 1, 1]
- : color == "black"
- ? [0, 0, 0, 1]
- : [0.1, 0.1, 0.1, 0.3];
- draw([x, y + height, x + width, y + height, x + width, y, x, y], colorArr);
+ } else if ("drawAt" in msg.data) {
+ const [color, x, y, width, height] = msg.data.drawAt;
+ if (useWebGL) {
+ let colorArr =
+ color == "white"
+ ? [1, 1, 1, 1]
+ : color == "black"
+ ? [0, 0, 0, 1]
+ : [0.1, 0.1, 0.1, 0.3];
+ draw(
+ [x, y + height, x + width, y + height, x + width, y, x, y],
+ colorArr,
+ );
+ } else {
+ if (width < 3 || height < 3) return;
+ gl.fillStyle = color;
+ gl.fillRect(x, y, width, height);
+ }
+ } else if ("drawScreen" in msg.data) {
+ const [colors, xys] = msg.data.drawScreen;
+ if (useWebGL) {
+ let colorArrs = colors.map((color) =>
+ color == "white"
+ ? [1, 1, 1, 1]
+ : color == "black"
+ ? [0, 0, 0, 1]
+ : [0.1, 0.1, 0.1, 0.3],
+ );
+ // @JsDevs WHERE ZIP FUNCTION
+ let i = 0;
+ xys.forEach(([x, y, width, height]) =>
+ draw(
+ [x, y + height, x + width, y + height, x + width, y, x, y],
+ colorArrs[i++],
+ ),
+ );
+ } else {
+ let i = 0;
+ xys.forEach(([x, y, width, height]) => {
+ if (width < 3 || height < 3) return;
+ gl.fillStyle = colors[i++];
+ gl.fillRect(x, y, width, height);
+ });
+ }
} else {
- const [color, x, y, width, height] = msg.data;
- if (width < 3 || height < 3) return;
- gl.fillStyle = color;
- gl.fillRect(x, y, width, height);
+ console.warn(msg.data);
}
};
diff --git a/main.js b/main.js
index eb760a5..99a339a 100644
--- a/main.js
+++ b/main.js
@@ -18,41 +18,52 @@ const BLACK = 1;
const UNKNOWN = 2;
const drawAt = (worker, x, y, color) => {
- worker.postMessage([
- color == WHITE ? "white" : color == BLACK ? "black" : "#cccccc",
- x[0],
- y[0],
- x[1] - x[0],
- y[1] - y[0],
+ worker.postMessage({
+ drawAt: [
+ color == WHITE ? "white" : color == BLACK ? "black" : "#cccccc",
+ x[0],
+ y[0],
+ x[1] - x[0],
+ y[1] - y[0],
+ ],
+ });
+};
+
+const drawScreen = (worker, ctxs, colors) => {
+ ctxs = ctxs.map((ctx) => [
+ ctx.x[0],
+ ctx.y[0],
+ ctx.x[1] - ctx.x[0],
+ ctx.y[1] - ctx.y[0],
]);
+ colors = colors.map((color) =>
+ color == WHITE ? "white" : color == BLACK ? "black" : "#cccccc",
+ );
+ worker.postMessage({ drawScreen: [colors, ctxs] });
};
-const drawTopLeft = (worker, ctx, color) => {
- const newX = [ctx.x[0], ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2];
- const newY = [ctx.y[0], ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2];
- drawAt(worker, newX, newY, color);
- return { x: newX, y: newY };
+const ctxTopLeft = (ctx) => {
+ const x = [ctx.x[0], ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2];
+ const y = [ctx.y[0], ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2];
+ return { x, y };
};
-const drawTopRight = (worker, ctx, color) => {
- const newX = [ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2, ctx.x[1]];
- const newY = [ctx.y[0], ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2];
- drawAt(worker, newX, newY, color);
- return { x: newX, y: newY };
+const ctxTopRight = (ctx) => {
+ const x = [ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2, ctx.x[1]];
+ const y = [ctx.y[0], ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2];
+ return { x, y };
};
-const drawBottomLeft = (worker, ctx, color) => {
- const newX = [ctx.x[0], ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2];
- const newY = [ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2, ctx.y[1]];
- drawAt(worker, newX, newY, color);
- return { x: newX, y: newY };
+const ctxBottomLeft = (ctx) => {
+ const x = [ctx.x[0], ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2];
+ const y = [ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2, ctx.y[1]];
+ return { x, y };
};
-const drawBottomRight = (worker, ctx, color) => {
- const newX = [ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2, ctx.x[1]];
- const newY = [ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2, ctx.y[1]];
- drawAt(worker, newX, newY, color);
- return { x: newX, y: newY };
+const ctxBottomRight = (ctx) => {
+ const x = [ctx.x[0] + (ctx.x[1] - ctx.x[0]) / 2, ctx.x[1]];
+ const y = [ctx.y[0] + (ctx.y[1] - ctx.y[0]) / 2, ctx.y[1]];
+ return { x, y };
};
/* lambda calculus */
@@ -433,7 +444,7 @@ const subst = (i, t, s) => {
// guaranteed normal form
// only use if sure that t is not a (potentially diverging) screen
-// TODO: this assumes laziness LOL
+// TODO: this assumes laziness LOL (OR DOES IT)
const gnf = (t) => {
if (cancelReduction() || t === null) {
error("in gnf");
@@ -569,13 +580,26 @@ const reduceLoop = (worker, root, _t) => {
if (seemsScreeny(t)) {
const tl = t.body.left.left.left.right;
- stack.push({ ctx: drawTopLeft(worker, ctx, toColor(tl)), t: tl });
+ const tlCtx = ctxTopLeft(ctx);
+ stack.push({ ctx: tlCtx, t: tl });
+
const tr = t.body.left.left.right;
- stack.push({ ctx: drawTopRight(worker, ctx, toColor(tr)), t: tr });
+ const trCtx = ctxTopRight(ctx);
+ stack.push({ ctx: trCtx, t: tr });
+
const bl = t.body.left.right;
- stack.push({ ctx: drawBottomLeft(worker, ctx, toColor(bl)), t: bl });
+ const blCtx = ctxBottomLeft(ctx);
+ stack.push({ ctx: blCtx, t: bl });
+
const br = t.body.right;
- stack.push({ ctx: drawBottomRight(worker, ctx, toColor(br)), t: br });
+ const brCtx = ctxBottomRight(ctx);
+ stack.push({ ctx: brCtx, t: br });
+
+ drawScreen(
+ worker,
+ [tlCtx, trCtx, blCtx, brCtx],
+ [toColor(tl), toColor(tr), toColor(bl), toColor(br)],
+ );
} else {
// TODO: could we risk gnfing here?
drawAt(worker, ctx.x, ctx.y, toColor(t));