fix(image-pipeline): diagnose and stabilize webgl preview path

This commit is contained in:
2026-04-05 11:28:42 +02:00
parent 186a5b9f92
commit 451ab0b986
11 changed files with 401 additions and 25 deletions

View File

@@ -3,7 +3,10 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ImagePipelineBackend } from "@/lib/image-pipeline/backend/backend-types";
import { detectBackendCapabilities } from "@/lib/image-pipeline/backend/capabilities";
import {
detectBackendCapabilities,
resetBackendCapabilitiesCache,
} from "@/lib/image-pipeline/backend/capabilities";
import { createBackendRouter } from "@/lib/image-pipeline/backend/backend-router";
const previewRendererMocks = vi.hoisted(() => ({
@@ -23,6 +26,10 @@ vi.mock("@/lib/image-pipeline/bridge", () => ({
}));
describe("detectBackendCapabilities", () => {
beforeEach(() => {
resetBackendCapabilitiesCache();
});
it("reports webgl, wasmSimd and offscreenCanvas independently", () => {
expect(
detectBackendCapabilities({
@@ -48,6 +55,39 @@ describe("detectBackendCapabilities", () => {
offscreenCanvas: false,
});
});
it("caches default WebGL capability detection and releases the probe context", () => {
const loseContext = vi.fn();
const getContext = vi.fn(() => ({
getExtension: vi.fn((name: string) => {
if (name === "WEBGL_lose_context") {
return { loseContext };
}
return null;
}),
}));
const originalCreateElement = document.createElement.bind(document);
const createElementSpy = vi.spyOn(document, "createElement").mockImplementation((tagName) => {
if (tagName === "canvas") {
return {
getContext,
} as unknown as HTMLCanvasElement;
}
return originalCreateElement(tagName);
});
const first = detectBackendCapabilities();
const second = detectBackendCapabilities();
expect(first.webgl).toBe(true);
expect(second.webgl).toBe(true);
expect(getContext).toHaveBeenCalledTimes(1);
expect(loseContext).toHaveBeenCalledTimes(1);
createElementSpy.mockRestore();
});
});
describe("backend router fallback reasons", () => {