diff options
author | Marvin Borner | 2024-12-23 23:05:14 +0100 |
---|---|---|
committer | Marvin Borner | 2024-12-23 23:05:14 +0100 |
commit | a442de647e4762bb0842af30081b74f2467feee9 (patch) | |
tree | 435872b09fdc35e6cefa0fc63277d7fdfb7a6aef | |
parent | e128423aea9c75e34797bdb4c12d1f02d36c6897 (diff) |
Massive speedup
-rw-r--r-- | canvasWorker.js | 86 | ||||
-rw-r--r-- | main.js | 86 |
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); } }; @@ -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)); |