molstar
Version:
A comprehensive macromolecular library.
188 lines • 10.4 kB
JavaScript
/**
* Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.createGrid3dComputeRenderable = exports.canComputeGrid3dOnGPU = void 0;
var tslib_1 = require("tslib");
var schema_1 = require("../renderable/schema");
var common_1 = require("../../mol-math/geometry/common");
var grid3d_template_frag_1 = require("../shader/util/grid3d-template.frag");
var quad_vert_1 = require("../shader/quad.vert");
var shader_code_1 = require("../shader-code");
var mol_util_1 = require("../../mol-util");
var object_1 = require("../../mol-util/object");
var uniform_1 = require("../webgl/uniform");
var util_1 = require("./util");
var render_item_1 = require("../webgl/render-item");
var renderable_1 = require("../renderable");
var is_little_endian_1 = require("../../mol-util/is-little-endian");
function canComputeGrid3dOnGPU(webgl) {
return !!(webgl === null || webgl === void 0 ? void 0 : webgl.extensions.textureFloat);
}
exports.canComputeGrid3dOnGPU = canComputeGrid3dOnGPU;
var FrameBufferName = 'grid3d-computable';
var Texture0Name = 'grid3d-computable-0';
var Texture1Name = 'grid3d-computable-1';
var SchemaBase = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, util_1.QuadSchema), { uDimensions: (0, schema_1.UniformSpec)('v3'), uMin: (0, schema_1.UniformSpec)('v3'), uDelta: (0, schema_1.UniformSpec)('v3'), uWidth: (0, schema_1.UniformSpec)('f'), uLittleEndian: (0, schema_1.UniformSpec)('b') });
var CumulativeSumSchema = {
tCumulativeSum: (0, schema_1.TextureSpec)('texture', 'rgba', 'ubyte', 'nearest')
};
function createGrid3dComputeRenderable(spec) {
var _this = this;
var _a;
var id = mol_util_1.UUID.create22();
var uniforms = [];
(0, object_1.objectForEach)(spec.schema, function (u, k) {
var _a, _b;
if (u.type === 'define')
return;
if (u.kind.indexOf('[]') >= 0)
throw new Error('array uniforms are not supported');
var isBound = ((_b = (_a = spec.loopBounds) === null || _a === void 0 ? void 0 : _a.indexOf(k)) !== null && _b !== void 0 ? _b : -1) >= 0;
if (isBound)
uniforms.push("#ifndef " + k);
if (u.type === 'uniform')
uniforms.push("uniform " + (0, uniform_1.getUniformGlslType)(u.kind) + " " + k + ";");
else if (u.type === 'texture')
uniforms.push("uniform sampler2D " + k + ";");
if (isBound)
uniforms.push("#endif");
});
var code = grid3d_template_frag_1.grid3dTemplate_frag
.replace('{UNIFORMS}', uniforms.join('\n'))
.replace('{UTILS}', (_a = spec.utilCode) !== null && _a !== void 0 ? _a : '')
.replace('{MAIN}', spec.mainCode)
.replace('{RETURN}', spec.returnCode);
var shader = (0, shader_code_1.ShaderCode)(id, quad_vert_1.quad_vert, code);
return function (ctx, webgl, grid, params) { return (0, tslib_1.__awaiter)(_this, void 0, void 0, function () {
var schema, _i, _a, b, framebuffer, tex, _b, nx, ny, nz, uWidth, values, renderable, cells, array, gl, states, yieldPeriod, i;
var _c;
return (0, tslib_1.__generator)(this, function (_d) {
switch (_d.label) {
case 0:
schema = (0, tslib_1.__assign)((0, tslib_1.__assign)((0, tslib_1.__assign)({}, SchemaBase), (spec.cumulative ? CumulativeSumSchema : {})), spec.schema);
if (!webgl.isWebGL2) {
if (spec.loopBounds) {
for (_i = 0, _a = spec.loopBounds; _i < _a.length; _i++) {
b = _a[_i];
schema[b] = (0, schema_1.DefineSpec)('number');
}
}
schema['WEBGL1'] = (0, schema_1.DefineSpec)('boolean');
}
if (spec.cumulative) {
schema['CUMULATIVE'] = (0, schema_1.DefineSpec)('boolean');
}
if (!webgl.namedFramebuffers[FrameBufferName]) {
webgl.namedFramebuffers[FrameBufferName] = webgl.resources.framebuffer();
}
framebuffer = webgl.namedFramebuffers[FrameBufferName];
if (!webgl.namedTextures[Texture0Name]) {
webgl.namedTextures[Texture0Name] = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
}
if (spec.cumulative && !webgl.namedTextures[Texture1Name]) {
webgl.namedTextures[Texture1Name] = webgl.resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest');
}
tex = [webgl.namedTextures[Texture0Name], webgl.namedTextures[Texture1Name]];
_b = grid.dimensions, nx = _b[0], ny = _b[1], nz = _b[2];
uWidth = Math.ceil(Math.sqrt(nx * ny * nz));
values = (0, tslib_1.__assign)({ uDimensions: grid.dimensions, uMin: grid.box.min, uDelta: (0, common_1.getRegularGrid3dDelta)(grid), uWidth: uWidth, uLittleEndian: (0, is_little_endian_1.isLittleEndian)() }, spec.values(params, grid));
if (!webgl.isWebGL2) {
values.WEBGL1 = true;
}
if (spec.cumulative) {
values.tCumulativeSum = tex[0];
values.CUMULATIVE = true;
}
renderable = webgl.namedComputeRenderables[id];
if (renderable) {
cells = renderable.values;
(0, object_1.objectForEach)(values, function (c, k) {
var s = schema[k];
if ((s === null || s === void 0 ? void 0 : s.type) === 'value' || (s === null || s === void 0 ? void 0 : s.type) === 'attribute')
return;
if (!s || !(0, uniform_1.isUniformValueScalar)(s.kind)) {
mol_util_1.ValueCell.update(cells[k], c);
}
else {
mol_util_1.ValueCell.updateIfChanged(cells[k], c);
}
});
}
else {
cells = {};
(0, object_1.objectForEach)(util_1.QuadValues, function (v, k) { return cells[k] = v; });
(0, object_1.objectForEach)(values, function (v, k) { return cells[k] = mol_util_1.ValueCell.create(v); });
renderable = (0, renderable_1.createComputeRenderable)((0, render_item_1.createComputeRenderItem)(webgl, 'triangles', shader, schema, cells), cells);
}
array = new Uint8Array(uWidth * uWidth * 4);
if (!spec.cumulative) return [3 /*break*/, 7];
gl = webgl.gl;
states = spec.cumulative.states(params);
tex[0].define(uWidth, uWidth);
tex[1].define(uWidth, uWidth);
resetGl(webgl, uWidth);
gl.clearColor(0, 0, 0, 0);
tex[0].attachFramebuffer(framebuffer, 'color0');
gl.clear(gl.COLOR_BUFFER_BIT);
tex[1].attachFramebuffer(framebuffer, 'color0');
gl.clear(gl.COLOR_BUFFER_BIT);
if (!spec.cumulative.yieldPeriod) return [3 /*break*/, 2];
return [4 /*yield*/, ctx.update({ message: 'Computing...', isIndeterminate: false, current: 0, max: states.length })];
case 1:
_d.sent();
_d.label = 2;
case 2:
yieldPeriod = Math.max(1, (_c = spec.cumulative.yieldPeriod) !== null && _c !== void 0 ? _c : 1 | 0);
i = 0;
_d.label = 3;
case 3:
if (!(i < states.length)) return [3 /*break*/, 6];
mol_util_1.ValueCell.update(cells.tCumulativeSum, tex[(i + 1) % 2]);
tex[i % 2].attachFramebuffer(framebuffer, 'color0');
resetGl(webgl, uWidth);
spec.cumulative.update(params, states[i], cells);
renderable.update();
renderable.render();
if (!(spec.cumulative.yieldPeriod && i !== states.length - 1)) return [3 /*break*/, 5];
if (i % yieldPeriod === yieldPeriod - 1) {
webgl.readPixels(0, 0, 1, 1, array);
}
if (!ctx.shouldUpdate) return [3 /*break*/, 5];
return [4 /*yield*/, ctx.update({ current: i + 1 })];
case 4:
_d.sent();
_d.label = 5;
case 5:
i++;
return [3 /*break*/, 3];
case 6: return [3 /*break*/, 8];
case 7:
tex[0].define(uWidth, uWidth);
tex[0].attachFramebuffer(framebuffer, 'color0');
framebuffer.bind();
resetGl(webgl, uWidth);
renderable.update();
renderable.render();
_d.label = 8;
case 8:
webgl.readPixels(0, 0, uWidth, uWidth, array);
return [2 /*return*/, new Float32Array(array.buffer, array.byteOffset, nx * ny * nz)];
}
});
}); };
}
exports.createGrid3dComputeRenderable = createGrid3dComputeRenderable;
function resetGl(webgl, w) {
var gl = webgl.gl, state = webgl.state;
gl.viewport(0, 0, w, w);
gl.scissor(0, 0, w, w);
state.disable(gl.SCISSOR_TEST);
state.disable(gl.BLEND);
state.disable(gl.DEPTH_TEST);
state.depthMask(false);
}
//# sourceMappingURL=grid3d.js.map
;