UNPKG

remotion

Version:

Make videos programmatically

85 lines (84 loc) 3.26 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CanvasPool = void 0; const webgl2_context_error_js_1 = require("./webgl2-context-error.js"); // Per-chain canvas pool. Each chain owns its own pool; pools are not shared // across chains because dimensions are chain-specific. // // Canvases are allocated lazily on first use of a given backend. Once // allocated, they are reused every frame for the chain's lifetime. Contexts // are created with the cross-backend alpha/sRGB contract enforced (see // `effect-types.ts`). class CanvasPool { constructor(width, height) { this.pairs = new Map(); this.lostContexts = new Set(); this.width = width; this.height = height; } getPair(backend) { const existing = this.pairs.get(backend); if (existing) { return existing; } const pair = [ this.allocateCanvas(backend), this.allocateCanvas(backend), ]; this.pairs.set(backend, pair); return pair; } assertContextNotLost(canvas) { if (this.lostContexts.has(canvas)) { throw new Error('WebGL context was lost during canvas effect rendering. ' + 'This typically happens in headless or memory-constrained environments (e.g. Remotion Lambda). ' + 'Try reducing concurrency or increasing the Lambda function memory.'); } } allocateCanvas(backend) { const canvas = document.createElement('canvas'); canvas.width = this.width; canvas.height = this.height; switch (backend) { case '2d': { const ctx = canvas.getContext('2d', { colorSpace: 'srgb', }); if (!ctx) { throw new Error('Failed to acquire 2D context for canvas effect'); } return canvas; } case 'webgl2': { const ctx = canvas.getContext('webgl2', { premultipliedAlpha: true, alpha: true, preserveDrawingBuffer: true, }); if (!ctx) { throw (0, webgl2_context_error_js_1.createWebGL2ContextError)('canvas effect'); } canvas.addEventListener('webglcontextlost', (e) => { e.preventDefault(); this.lostContexts.add(canvas); }); canvas.addEventListener('webglcontextrestored', () => { this.lostContexts.delete(canvas); }); ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); return canvas; } case 'webgpu': { if (typeof navigator === 'undefined' || !('gpu' in navigator)) { throw new Error('WebGPU is not available in this environment for canvas effect'); } return canvas; } default: { const exhaustive = backend; throw new Error(`Unknown effect backend: ${exhaustive}`); } } } } exports.CanvasPool = CanvasPool;