UNPKG

@lightningtv/renderer

Version:
141 lines 4.8 kB
/* * If not stated otherwise in this file or this component's LICENSE file the * following copyright and licenses apply: * * Copyright 2023 Comcast Cable Communications Management, LLC. * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { deepClone } from '../utils.js'; import { CoreShaderNode, resolveShaderProps, } from './renderers/CoreShaderNode.js'; export class CoreShaderManager { stage; shTypes = {}; shCache = new Map(); /** * valuesCache is used to store calculations that can be shared between shader nodes. */ valuesCache = new Map(); valuesCacheUsage = new Map(); attachedShader = null; constructor(stage) { this.stage = stage; } registerShaderType(name, shType) { /** * block name duplicates */ if (this.shTypes[name] !== undefined) { console.warn(`ShaderType already exists with the name: ${name}. Breaking off registration.`); return; } /** * Check renderer if shader type is supported. */ if (this.stage.renderer.supportsShaderType(shType) === false) { console.warn(`The renderer being used does not support this shader type. Breaking off registration.`); return; } this.shTypes[name] = deepClone(shType); } /** * Loads a shader (if not already loaded) and returns a controller for it. * * @param shType * @param props * @returns */ createShader(name, props) { const shType = this.shTypes[name]; if (shType === undefined) { console.warn(`ShaderType not found falling back on renderer default shader`); return this.stage.defShaderNode; } let shaderKey = name; if (shType.props !== undefined) { /** * if props is undefined create empty obj to fill */ props = props || {}; /** * resolve shader values */ resolveShaderProps(props, shType.props); if (shType.getCacheMarkers !== undefined) { shaderKey += `-${shType.getCacheMarkers(props)}`; } } if (this.stage.renderer.mode === 'canvas') { return this.stage.renderer.createShaderNode(shaderKey, shType, props); } /** * get shaderProgram by cacheKey */ let shProgram = this.shCache.get(shaderKey); /** * if shaderProgram was not found create a new one */ if (shProgram === undefined) { shProgram = this.stage.renderer.createShaderProgram(shType, props); this.shCache.set(shaderKey, shProgram); } return this.stage.renderer.createShaderNode(shaderKey, shType, props, shProgram); } mutateShaderValueUsage(key, mutation) { let usage = this.valuesCacheUsage.get(key) || 0; this.valuesCacheUsage.set(key, usage + mutation); } getShaderValues(key) { const values = this.valuesCache.get(key); if (values === undefined) { return undefined; } this.mutateShaderValueUsage(key, 1); return values; } setShaderValues(key, values) { this.valuesCache.set(key, values); this.mutateShaderValueUsage(key, 1); } cleanup() { const values = [...this.valuesCacheUsage.entries()].sort((entryA, entryB) => { if (entryA[1] < entryB[1]) { return -1; } else if (entryA[1] > entryB[1]) { return 1; } return 0; }); for (let i = 0; i < values.length; i++) { if (values[i][1] > 0) { break; } this.valuesCacheUsage.delete(values[i][0]); this.valuesCache.delete(values[i][0]); } } useShader(shader) { if (this.attachedShader === shader) { return; } if (this.attachedShader && this.attachedShader.detach) { this.attachedShader.detach(); } if (shader.attach) { shader.attach(); } this.attachedShader = shader; } } //# sourceMappingURL=CoreShaderManager.js.map