summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/web/src/preview/components/index.tsx9
-rw-r--r--apps/web/src/services/renderer/compositor/wasm-compositor.ts8
-rw-r--r--apps/web/src/services/renderer/gpu-renderer.ts27
3 files changed, 42 insertions, 2 deletions
diff --git a/apps/web/src/preview/components/index.tsx b/apps/web/src/preview/components/index.tsx
index 894eec78..643eb002 100644
--- a/apps/web/src/preview/components/index.tsx
+++ b/apps/web/src/preview/components/index.tsx
@@ -7,6 +7,7 @@ import { useRafLoop } from "@/hooks/use-raf-loop";
import { useContainerSize } from "@/hooks/use-container-size";
import { useFullscreen } from "@/hooks/use-fullscreen";
import { CanvasRenderer } from "@/services/renderer/canvas-renderer";
+import { onGpuCanvasRepaired } from "@/services/renderer/gpu-renderer";
import { TICKS_PER_SECOND } from "@/wasm";
import type { RootNode } from "@/services/renderer/nodes/root-node";
import { buildScene } from "@/services/renderer/scene-builder";
@@ -214,6 +215,14 @@ function PreviewCanvas({
useRafLoop(render);
useEffect(() => {
+ return onGpuCanvasRepaired({
+ callback: () => {
+ lastFrameRef.current = -1;
+ },
+ });
+ }, []);
+
+ useEffect(() => {
const container = viewportRef.current;
if (!container) return;
diff --git a/apps/web/src/services/renderer/compositor/wasm-compositor.ts b/apps/web/src/services/renderer/compositor/wasm-compositor.ts
index 10684f11..5d2ddc3f 100644
--- a/apps/web/src/services/renderer/compositor/wasm-compositor.ts
+++ b/apps/web/src/services/renderer/compositor/wasm-compositor.ts
@@ -96,6 +96,14 @@ class WasmCompositor {
}
}
+ repairSharedCanvas() {
+ if (!this.canvas || !this.initializedSize) return;
+ const { width, height } = this.initializedSize;
+ if (this.canvas.width === width && this.canvas.height === height) return;
+ resizeCompositor(width + 1, height);
+ resizeCompositor(width, height);
+ }
+
private syncExternalTexture(texture: ExternalTextureDescriptor) {
const previous = this.cache.get(texture.id);
if (
diff --git a/apps/web/src/services/renderer/gpu-renderer.ts b/apps/web/src/services/renderer/gpu-renderer.ts
index c1be3f1a..8ad11083 100644
--- a/apps/web/src/services/renderer/gpu-renderer.ts
+++ b/apps/web/src/services/renderer/gpu-renderer.ts
@@ -4,6 +4,25 @@ import {
initializeGpu,
} from "opencut-wasm";
import type { EffectPass, EffectUniformValue } from "@/effects/types";
+import { wasmCompositor } from "./compositor/wasm-compositor";
+
+const canvasRepairListeners = new Set<() => void>();
+
+export function onGpuCanvasRepaired({
+ callback,
+}: {
+ callback: () => void;
+}): () => void {
+ canvasRepairListeners.add(callback);
+ return () => canvasRepairListeners.delete(callback);
+}
+
+function repairSharedCompositorCanvas(): void {
+ wasmCompositor.repairSharedCanvas();
+ for (const listener of canvasRepairListeners) {
+ listener();
+ }
+}
let gpuAvailable = false;
let initPromise: Promise<void> | null = null;
@@ -43,12 +62,14 @@ export const gpuRenderer = {
return source;
}
- return applyEffectPasses({
+ const result = applyEffectPasses({
source,
width,
height,
passes: serializeEffectPasses(passes),
});
+ repairSharedCompositorCanvas();
+ return result;
},
applyMaskFeather({
@@ -66,12 +87,14 @@ export const gpuRenderer = {
return maskCanvas;
}
- return applyMaskFeatherWasm({
+ const result = applyMaskFeatherWasm({
mask: maskCanvas,
width,
height,
feather,
});
+ repairSharedCompositorCanvas();
+ return result;
},
};