From 6c036117be85f5d8c5e0e3e7ba0e8c0dead288d1 Mon Sep 17 00:00:00 2001
From: tamaina <tamaina@hotmail.co.jp>
Date: Wed, 17 May 2023 07:55:20 +0000
Subject: [PATCH] Revert "wip"

This reverts commit 0801e7936116c58154d7cecfea955dd15fa61a77.
---
 .../src/components/MkImgWithBlurhash.vue      | 57 +++++--------------
 .../frontend/src/workers/draw-blurhash.ts     | 17 +++++-
 2 files changed, 29 insertions(+), 45 deletions(-)

diff --git a/packages/frontend/src/components/MkImgWithBlurhash.vue b/packages/frontend/src/components/MkImgWithBlurhash.vue
index a0e7ee30bc..ca912fabf5 100644
--- a/packages/frontend/src/components/MkImgWithBlurhash.vue
+++ b/packages/frontend/src/components/MkImgWithBlurhash.vue
@@ -22,13 +22,8 @@ import TestWebGL2 from '@/workers/test-webgl2?worker';
 const workerPromise = new Promise<Worker | null>(resolve => {
 	const testWorker = new TestWebGL2();
 	testWorker.addEventListener('message', event => {
-		if (event.data.result) {
-			console.log('WebGL2 is supported in worker.')
-			resolve(new DrawBlurhash());
-		} else {
-			console.log('WebGL2 is not supported in worker.')
-			resolve(null);
-		}
+		if (event.data.result) resolve(new DrawBlurhash());
+		else resolve(null);
 		testWorker.terminate();
 	});
 });
@@ -79,7 +74,6 @@ let canvasWidth = $ref(64);
 let canvasHeight = $ref(64);
 let imgWidth = $ref(props.width);
 let imgHeight = $ref(props.height);
-let bitmapTmp = $ref<ImageBitmap | undefined>();
 const hide = computed(() => !loaded || props.forceBlurhash);
 
 function waitForDecode() {
@@ -114,43 +108,19 @@ watch([() => props.width, () => props.height, root], () => {
 	immediate: true,
 });
 
-workerPromise.then(worker => {
-	if (!worker) return;
-
-	worker.postMessage({
-		id: viewId,
-		hash: props.hash,
-	});
-
-	worker.addEventListener('message', event => {
-		if (event.data.id !== viewId) return;
-		drawImage(event.data.bitmap as ImageBitmap);
-	});
-});
-
-function drawImage(bitmap: CanvasImageSource) {
-	// canvasがない(mountedされていない)場合はTmpに保存しておく
-	if (!canvas.value) {
-		bitmapTmp = bitmap;
-		return;
-	}
-
-	bitmapTmp = undefined;
-
-	// canvasがあったらすぐに描画する
-	const ctx = canvas.value.getContext('2d');
-	if (!ctx) return;
-	ctx.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);
-}
-
-async function draw() {
+async function draw(transfer: boolean = false) {
 	if (!canvas.value || props.hash == null) return;
 	const worker = await workerPromise;
 	if (worker) {
+		let offscreen: OffscreenCanvas | undefined;
+		if (transfer) {
+			offscreen = canvas.value.transferControlToOffscreen();
+		}
 		worker.postMessage({
 			id: viewId,
+			canvas: offscreen ?? undefined,
 			hash: props.hash,
-		});
+		}, offscreen ? [offscreen] : []);
 	} else {
 		try {
 			const work = document.createElement('canvas');
@@ -158,7 +128,8 @@ async function draw() {
 			work.height = canvasHeight;
 			render(props.hash, work);
 			const bitmap = await createImageBitmap(work);
-			drawImage(bitmap);
+			const ctx = canvas.value.getContext('2d');
+			ctx?.drawImage(bitmap, 0, 0, canvasWidth, canvasHeight);
 		} catch (error) {
 			console.error('Error occured during drawing blurhash', error);
 		}
@@ -174,10 +145,8 @@ watch(() => props.hash, () => {
 });
 
 onMounted(() => {
-	// drawImageがmountedより先に呼ばれている場合はここで描画する
-	if (bitmapTmp) {
-		drawImage(bitmapTmp);
-	}
+	draw(true);
+	waitForDecode();
 });
 
 onUnmounted(() => {
diff --git a/packages/frontend/src/workers/draw-blurhash.ts b/packages/frontend/src/workers/draw-blurhash.ts
index f5bb7f9716..3a19c63cc0 100644
--- a/packages/frontend/src/workers/draw-blurhash.ts
+++ b/packages/frontend/src/workers/draw-blurhash.ts
@@ -1,15 +1,30 @@
 import { render } from 'buraha';
 
+const canvases = new Map<string, OffscreenCanvas>();
+
 onmessage = async (event) => {
     // console.log(event.data);
     if (!('id' in event.data && typeof event.data.id === 'string')) {
         return;
     }
+    if (event.data.delete) {
+        canvases.delete(event.data.id);
+        return;
+    }
+    if (event.data.canvas) {
+        canvases.set(event.data.id, event.data.canvas);
+    }
     if (!('hash' in event.data && typeof event.data.hash === 'string')) {
         return;
     }
+    const canvas = event.data.canvas ?? canvases.get(event.data.id);
+    if (!canvas) {
+        throw new Error('No canvas');
+    }
     const work = new OffscreenCanvas(canvas.width, canvas.height);
     render(event.data.hash, work);
     const bitmap = await createImageBitmap(work);
-    postMessage({ id: event.data.id, bitmap });
+    const ctx = canvas.getContext('2d');
+    ctx?.drawImage(bitmap, 0, 0, canvas.width, canvas.height);
+    postMessage({ result: true });
 };