fix: WebGL frame rendering and opencut-wasm 0.2.8

This commit is contained in:
Maze Winther
2026-04-19 07:42:52 +02:00
parent 9da365bc01
commit 729d10592f
14 changed files with 338 additions and 127 deletions
@@ -10,7 +10,10 @@ import { useKeybindingsStore } from "@/stores/keybindings-store";
import { useTimelineStore } from "@/stores/timeline-store";
import { useEditorActions } from "@/hooks/actions/use-editor-actions";
import { loadFontAtlas } from "@/lib/fonts/google-fonts";
import { initializeGpuRenderer, isGpuAvailable } from "@/services/renderer/gpu-renderer";
import {
initializeGpuRenderer,
isGpuAvailable,
} from "@/services/renderer/gpu-renderer";
interface EditorProviderProps {
projectId: string;
@@ -62,9 +65,16 @@ export function EditorProvider({ projectId, children }: EditorProviderProps) {
setIsLoading(false);
}
} else {
setError(
err instanceof Error ? err.message : "Failed to load project",
);
const wasmPanic = (window as Window & { __wasmPanic?: string })
.__wasmPanic;
if (wasmPanic) {
delete (window as Window & { __wasmPanic?: string }).__wasmPanic;
setError(wasmPanic);
} else {
setError(
err instanceof Error ? err.message : "Failed to load project",
);
}
setIsLoading(false);
}
}
@@ -167,9 +167,13 @@ export class ProjectManager {
});
if (!project.metadata.thumbnail) {
const didUpdateThumbnail = await this.updateThumbnailFromTimeline();
if (didUpdateThumbnail) {
await this.saveCurrentProject();
try {
const didUpdateThumbnail = await this.updateThumbnailFromTimeline();
if (didUpdateThumbnail) {
await this.saveCurrentProject();
}
} catch (error) {
console.error("Failed to generate project thumbnail:", error);
}
}
} catch (error) {
@@ -18,11 +18,7 @@ class EffectPreviewService {
this.loadPreviewImage();
}
onPreviewImageReady({
callback,
}: {
callback: () => void;
}): () => void {
onPreviewImageReady({ callback }: { callback: () => void }): () => void {
this.onReadyCallbacks.add(callback);
return () => this.onReadyCallbacks.delete(callback);
}
@@ -39,35 +35,47 @@ class EffectPreviewService {
uniformDimensions?: { width: number; height: number };
}): void {
const size = PREVIEW_SIZE;
const source = this.getTestSource({ width: size, height: size });
if (!source) return;
const definition = effectsRegistry.get(effectType);
const resolvedParams =
Object.keys(params).length > 0
? params
: buildDefaultParamValues(definition.params);
const passes = resolveEffectPasses({
definition,
effectParams: resolvedParams,
width: uniformDimensions?.width ?? size,
height: uniformDimensions?.height ?? size,
});
const result = this.applyGpuEffect({
source,
width: size,
height: size,
passes,
});
const targetCtx = targetCanvas.getContext(
"2d",
) as CanvasRenderingContext2D | null;
if (targetCtx) {
targetCanvas.width = size;
targetCanvas.height = size;
if (!targetCtx) {
return;
}
targetCanvas.width = size;
targetCanvas.height = size;
const source = this.getTestSource({ width: size, height: size });
if (!source) {
targetCtx.clearRect(0, 0, size, size);
return;
}
try {
const definition = effectsRegistry.get(effectType);
const resolvedParams =
Object.keys(params).length > 0
? params
: buildDefaultParamValues(definition.params);
const passes = resolveEffectPasses({
definition,
effectParams: resolvedParams,
width: uniformDimensions?.width ?? size,
height: uniformDimensions?.height ?? size,
});
const result = this.applyGpuEffect({
source,
width: size,
height: size,
passes,
});
targetCtx.drawImage(result, 0, 0, size, size);
} catch (error) {
console.warn("Failed to render effect preview", { effectType, error });
targetCtx.clearRect(0, 0, size, size);
targetCtx.drawImage(source, 0, 0, size, size);
}
}