UNPKG

molstar

Version:

A comprehensive macromolecular library.

188 lines 10.4 kB
"use strict"; /** * 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