UNPKG

@kitware/vtk.js

Version:

Visualization Toolkit for the Web

247 lines (190 loc) 8.96 kB
import _typeof from '@babel/runtime/helpers/typeof'; import _classCallCheck from '@babel/runtime/helpers/classCallCheck'; import _createClass from '@babel/runtime/helpers/createClass'; import _assertThisInitialized from '@babel/runtime/helpers/assertThisInitialized'; import _inherits from '@babel/runtime/helpers/inherits'; import _possibleConstructorReturn from '@babel/runtime/helpers/possibleConstructorReturn'; import _get from '@babel/runtime/helpers/get'; import _getPrototypeOf from '@babel/runtime/helpers/getPrototypeOf'; import _wrapNativeSuper from '@babel/runtime/helpers/wrapNativeSuper'; import { newInstance as newInstance$1, obj, setGet, get } from '../../macros.js'; import vtkWebGPUBufferManager from './BufferManager.js'; import vtkWebGPUShaderCache from './ShaderCache.js'; import vtkWebGPUTextureManager from './TextureManager.js'; function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** * provide a simple WeakRefMap class to share device objects based on * hash values so that buffers/textures etc can be shared betwen mappers. * This is roughly based on WeakLRUCache but without the actual caching * behavior. This is just a map of key -> WeakRef(value) */ /* eslint-disable no-undef */ var WeakRefMap = /*#__PURE__*/function (_Map) { _inherits(WeakRefMap, _Map); var _super = _createSuper(WeakRefMap); function WeakRefMap() { var _thisSuper, _thisSuper2, _this; _classCallCheck(this, WeakRefMap); _this = _super.call(this); _this.registry = new FinalizationRegistry(function (key) { var entry = _get((_thisSuper = _assertThisInitialized(_this), _getPrototypeOf(WeakRefMap.prototype)), "get", _thisSuper).call(_thisSuper, key); if (entry && entry.deref && entry.deref() === undefined) _get((_thisSuper2 = _assertThisInitialized(_this), _getPrototypeOf(WeakRefMap.prototype)), "delete", _thisSuper2).call(_thisSuper2, key); }); return _this; } _createClass(WeakRefMap, [{ key: "getValue", value: function getValue(key) { var entry = _get(_getPrototypeOf(WeakRefMap.prototype), "get", this).call(this, key); if (entry) { var value = entry.deref(); if (value !== undefined) return value; _get(_getPrototypeOf(WeakRefMap.prototype), "delete", this).call(this, key); } return undefined; } }, { key: "setValue", value: function setValue(key, value) { var entry; if (value && _typeof(value) === 'object') { entry = new WeakRef(value); this.registry.register(value, key); _get(_getPrototypeOf(WeakRefMap.prototype), "set", this).call(this, key, entry); } // else entry is undefined return entry; } }]); return WeakRefMap; }( /*#__PURE__*/_wrapNativeSuper(Map)); /* eslint-enable no-undef */ // ---------------------------------------------------------------------------- // vtkWebGPUDevice methods // ---------------------------------------------------------------------------- function vtkWebGPUDevice(publicAPI, model) { // Set our className model.classHierarchy.push('vtkWebGPUDevice'); publicAPI.initialize = function (handle) { model.handle = handle; }; publicAPI.createCommandEncoder = function () { return model.handle.createCommandEncoder(); }; publicAPI.submitCommandEncoder = function (commandEncoder) { model.handle.queue.submit([commandEncoder.finish()]); }; publicAPI.getShaderModule = function (sd) { return model.shaderCache.getShaderModule(sd); }; /* eslint-disable no-bitwise */ /* eslint-disable no-undef */ publicAPI.getBindGroupLayout = function (val) { if (!val.entries) { return null; } // add in basic required values if missing for (var i = 0; i < val.entries.length; i++) { var ent = val.entries[i]; ent.binding = ent.binding || 0; ent.visibility = ent.visibility || GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT; } // do we already have one? var sval = JSON.stringify(val); for (var _i = 0; _i < model.bindGroupLayouts.length; _i++) { if (model.bindGroupLayouts[_i].sval === sval) { return model.bindGroupLayouts[_i].layout; } } // create one and store it var layout = model.handle.createBindGroupLayout(val); // we actually only store the stringified version // as that is what we always compare against model.bindGroupLayouts.push({ sval: sval, layout: layout }); return layout; }; publicAPI.getBindGroupLayoutDescription = function (layout) { for (var i = 0; i < model.bindGroupLayouts.length; i++) { if (model.bindGroupLayouts[i].layout === layout) { return model.bindGroupLayouts[i].sval; } } vtkErrorMacro('layout not found'); console.trace(); return null; }; publicAPI.getPipeline = function (hash) { if (hash in model.pipelines) { return model.pipelines[hash]; } return null; }; publicAPI.createPipeline = function (hash, pipeline) { pipeline.initialize(publicAPI, hash); model.pipelines[hash] = pipeline; }; publicAPI.onSubmittedWorkDone = function () { return model.handle.queue.onSubmittedWorkDone(); }; // The Device has an object cache that can be used to cache buffers, // textures and other objects that can be shared. The basic approach is to // call getCachedObject with a request and a create function. The request // is based on a hash. The cache lookup just returns any entry that has a // matching hash. If a match isn't found then the create function is // called with any extra arguments. // is the object already cached? publicAPI.hasCachedObject = function (hash) { return model.objectCache.getValue(hash); }; publicAPI.getCachedObject = function (hash, creator) { if (!hash) { vtkErrorMacro('attempt to cache an object without a hash'); return null; } var existingValue = model.objectCache.getValue(hash); if (existingValue) { return existingValue; } for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = arguments[_key]; } var createdObject = creator.apply(void 0, args); model.objectCache.setValue(hash, createdObject); return createdObject; }; } // ---------------------------------------------------------------------------- // Object factory // ---------------------------------------------------------------------------- var DEFAULT_VALUES = { handle: null, pipelines: null, shaderCache: null, bindGroupLayouts: null, bufferManager: null, textureManager: null }; // ---------------------------------------------------------------------------- function extend(publicAPI, model) { var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; Object.assign(model, DEFAULT_VALUES, initialValues); // Build VTK API obj(publicAPI, model); setGet(publicAPI, model, ['handle']); get(publicAPI, model, ['bufferManager', 'shaderCache', 'textureManager']); // this is a weak ref cache implementation, we create it without // an expirer (so it is strictly based on garbage collection and // objects are not held if there are no external references) // model.objectCache = new WeakLRUCache({ expirer: false }); model.objectCache = new WeakRefMap(); model.shaderCache = vtkWebGPUShaderCache.newInstance(); model.shaderCache.setDevice(publicAPI); model.bindGroupLayouts = []; model.bufferManager = vtkWebGPUBufferManager.newInstance(); model.bufferManager.setDevice(publicAPI); model.textureManager = vtkWebGPUTextureManager.newInstance(); model.textureManager.setDevice(publicAPI); model.pipelines = {}; // For more macro methods, see "Sources/macros.js" // Object specific methods vtkWebGPUDevice(publicAPI, model); } // ---------------------------------------------------------------------------- var newInstance = newInstance$1(extend, 'vtkWebGPUDevice'); // ---------------------------------------------------------------------------- var vtkWebGPUDevice$1 = { newInstance: newInstance, extend: extend }; export { WeakRefMap, vtkWebGPUDevice$1 as default, extend, newInstance };