Skip to content

Commit 5f12ecb

Browse files
committed
wasm: Fix canvas flickering
1 parent 7709265 commit 5f12ecb

File tree

2 files changed

+59
-26
lines changed

2 files changed

+59
-26
lines changed

src/backends/wasm/capy-worker.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ const env = {
157157
self.postMessage(["lineTo", ctx, x, y]);
158158
},
159159
fillText: function(ctx, textPtr, textLen, x, y) {
160-
throw new Error("TODO: fill text");
160+
self.postMessage(["fillText", ctx, readString(textPtr, textLen), x, y]);
161161
},
162162
fillImage: function(ctx, img, x, y) {
163163
self.postMessage(["fillImage", ctx, img, x, y]);
@@ -226,8 +226,6 @@ const env = {
226226
},
227227
};
228228

229-
console.log("WEB WORKER RUN");
230-
231229
(async function() {
232230
const importObject = {
233231
env: env,

src/backends/wasm/capy.js

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ let arrayBuffer = undefined;
1818
**/
1919
let pendingAnswer = undefined;
2020

21+
/**
22+
Draw commands scheduled for the next frame
23+
**/
24+
let drawCommands = [];
25+
2126
function pushEvent(evt) {
2227
const eventId = events.push(evt);
2328
pendingEvents.push(eventId - 1);
@@ -115,11 +120,11 @@ const env = {
115120
});
116121
});
117122
elem.addEventListener("mousemove", function(e) {
118-
pushEvent({
119-
type: 4,
120-
target: idx,
121-
args: [e.clientX, e.clientY]
122-
});
123+
// pushEvent({
124+
// type: 4,
125+
// target: idx,
126+
// args: [e.clientX, e.clientY]
127+
// });
123128
});
124129
elem.addEventListener("wheel", function(e) {
125130
console.log(e.deltaY);
@@ -254,7 +259,7 @@ const env = {
254259

255260
for (let ctxId in canvasContexts) {
256261
if (canvasContexts[ctxId].owner === element) {
257-
canvasContexts[ctxId].clearRect(0, 0, canvas.width, canvas.height);
262+
// canvasContexts[ctxId].clearRect(0, 0, canvas.width, canvas.height);
258263
return Number.parseInt(ctxId);
259264
}
260265
}
@@ -265,25 +270,22 @@ const env = {
265270
return canvasContexts.push(ctx) - 1;
266271
},
267272
setColor: function(ctx, r, g, b, a) {
268-
canvasContexts[ctx].fillStyle = "rgba(" + r + "," + g + "," + b + "," + a + ")";
269-
canvasContexts[ctx].strokeStyle = canvasContexts[ctx].fillStyle;
273+
drawCommands.push([ctx, "setColor", r, g, b, a]);
270274
},
271275
rectPath: function(ctx, x, y, w, h) {
272-
canvasContexts[ctx].rect(x, y, w, h);
276+
drawCommands.push([ctx, "rectPath", x, y, w, h]);
273277
},
274278
moveTo: function(ctx, x, y) {
275-
canvasContexts[ctx].moveTo(x, y);
279+
drawCommands.push([ctx, "moveTo", x, y]);
276280
},
277281
lineTo: function(ctx, x, y) {
278-
canvasContexts[ctx].lineTo(x, y);
282+
drawCommands.push([ctx, "lineTo", x, y]);
279283
},
280-
fillText: function(ctx, textPtr, textLen, x, y) {
281-
const text = readString(textPtr, textLen);
282-
canvasContexts[ctx].textAlign = "left";
283-
canvasContexts[ctx].textBaseline = "top";
284-
canvasContexts[ctx].fillText(text, x, y);
284+
fillText: function(ctx, text, x, y) {
285+
drawCommands.push([ctx, "fillText", text, x, y]);
285286
},
286287
fillImage: function(ctx, img, x, y) {
288+
drawCommands.push([ctx, "fillImage", img, x, y]);
287289
const canvas = canvasContexts[ctx];
288290
const image = resources[img];
289291
if (!image.imageDatas[ctx]) {
@@ -308,12 +310,10 @@ const env = {
308310
canvas.putImageData(image.imageDatas[ctx], x, y);
309311
},
310312
fill: function(ctx) {
311-
canvasContexts[ctx].fill();
312-
canvasContexts[ctx].beginPath();
313+
drawCommands.push([ctx, "fill"]);
313314
},
314315
stroke: function(ctx) {
315-
canvasContexts[ctx].stroke();
316-
canvasContexts[ctx].beginPath();
316+
drawCommands.push([ctx, "stroke"]);
317317
},
318318

319319
// Resources
@@ -394,10 +394,45 @@ const env = {
394394

395395
// TODO: when we're in blocking mode, avoid updating so often
396396
function update() {
397-
if (executeProgram) {
398-
// obj.instance.exports._capyStep();
399-
// requestAnimationFrame(update);
397+
// Fulfill draw commands
398+
for (const command of drawCommands) {
399+
const ctx = canvasContexts[command[0]];
400+
401+
switch (command[1]) {
402+
case "moveTo":
403+
ctx.moveTo(command[2], command[3]);
404+
break;
405+
case "lineTo":
406+
ctx.lineTo(command[2], command[3]);
407+
break;
408+
case "rectPath":
409+
ctx.rect(command[2], command[3], command[4], command[5]);
410+
break;
411+
case "fillText":
412+
ctx.textAlign = "left"; ctx.textBaseline = "top";
413+
ctx.fillText(command[2], command[3], command[4]);
414+
break;
415+
case "setColor":
416+
const r = command[2];
417+
const g = command[3];
418+
const b = command[4];
419+
const a = command[5];
420+
ctx.fillStyle = "rgba(" + r + "," + g + "," + b + "," + a + ")";
421+
ctx.strokeStyle = ctx.fillStyle;
422+
break;
423+
case "stroke":
424+
ctx.stroke();
425+
ctx.beginPath();
426+
break;
427+
case "fill":
428+
ctx.fill();
429+
ctx.beginPath();
430+
break;
431+
}
400432
}
433+
drawCommands = [];
434+
435+
requestAnimationFrame(update);
401436
}
402437
//setInterval(update, 32);
403438
requestAnimationFrame(update);

0 commit comments

Comments
 (0)