@thewtex/vtk.js-esm
Version:
Visualization Toolkit for the Web
142 lines (114 loc) • 4.34 kB
JavaScript
import macro from '../../macro.js';
import vtkWebGPUTexture from './Texture.js';
// Global methods
// ----------------------------------------------------------------------------
function requestMatches(req1, req2) {
if (req1.time !== req2.time) return false;
if (req1.nativeArray !== req2.nativeArray) return false;
if (req1.format !== req2.format) return false;
return true;
} // ----------------------------------------------------------------------------
// vtkWebGPUTextureManager methods
// ----------------------------------------------------------------------------
function vtkWebGPUTextureManager(publicAPI, model) {
// Set our className
model.classHierarchy.push('vtkWebGPUTextureManager'); // The keys fields of a request are
// - source, this is what owns the data and when it does away
// the data should be freed
// - imageData - when provided use as the source of the data
//
publicAPI.getTexture = function (req) {
// fill in values based on imageData if the request has it
if (req.imageData) {
req.dataArray = req.imageData.getPointData().getScalars();
req.time = req.dataArray.getMTime();
req.nativeArray = req.dataArray.getData();
var dims = req.imageData.getDimensions();
req.width = dims[0];
req.height = dims[1];
req.depth = dims[2];
var numComp = req.dataArray.getNumberOfComponents(); // todo pick format based on native type
// todo fix handling of 3 component
switch (numComp) {
case 1:
req.format = 'r8unorm';
break;
case 2:
req.format = 'rg8unorm';
break;
default:
case 3:
case 4:
req.format = 'rgba8unorm';
break;
}
} // fill in values based on image if the request has it
if (req.image) {
req.time = 0;
req.width = req.image.width;
req.height = req.image.height;
req.depth = 1;
req.format = 'rgba8unorm';
}
if (req.source) {
// if a matching texture already exists then return it
if (model.textures.has(req.source)) {
var dabuffers = model.textures.get(req.source);
for (var i = 0; i < dabuffers.length; i++) {
if (requestMatches(dabuffers[i].request, req)) {
return dabuffers[i].texture;
}
}
}
}
var newTex = vtkWebGPUTexture.newInstance();
newTex.create(model.device, {
width: req.width,
height: req.height,
depth: req.depth,
format: req.format
}); // fill the texture if we have data
if (req.nativeArray || req.image) {
newTex.writeImageData(req);
} // cache the texture if we have a source
// We create a new req that only has the fields required for
// a comparison to avoid GC cycles
if (req.source) {
if (!model.textures.has(req.source)) {
model.textures.set(req.source, []);
}
var _dabuffers = model.textures.get(req.source);
_dabuffers.push({
request: {
time: req.time,
nativeArray: req.nativeArray,
format: req.format
},
texture: newTex
});
}
return newTex;
};
} // ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------
var DEFAULT_VALUES = {
textures: null,
handle: null,
device: null
}; // ----------------------------------------------------------------------------
function extend(publicAPI, model) {
var initialValues = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
Object.assign(model, DEFAULT_VALUES, initialValues); // Object methods
macro.obj(publicAPI, model); // this is a cache, and a cache with GC pretty much means WeakMap
model.textures = new WeakMap();
macro.setGet(publicAPI, model, ['device']);
vtkWebGPUTextureManager(publicAPI, model);
} // ----------------------------------------------------------------------------
var newInstance = macro.newInstance(extend); // ----------------------------------------------------------------------------
var vtkWebGPUTextureManager$1 = {
newInstance: newInstance,
extend: extend
};
export default vtkWebGPUTextureManager$1;
export { extend, newInstance };