Browse Source

Merge pull request #552 from molstar/perf-caveat

add support for failIfMajorPerformanceCaveat
Alexander Rose 2 năm trước cách đây
mục cha
commit
1cf1f07232

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - [Fix] Clone ``Canvas3DParams`` when creating a ``Canvas3D`` instance to prevent shared state between multiple instances
 - Add ``includeResidueTest`` option to ``alignAndSuperposeWithSIFTSMapping``
 - Add ``parentDisplay`` param for interactions representation.
+- Support for ``failIfMajorPerformanceCaveat`` webgl attribute. Add ``PluginConfig.General.AllowMajorPerformanceCaveat`` and ``allow-major-performance-caveat`` Viewer GET param.
 - Fix handling of PDB TER records (#549)
 - Add support for getting multiple loci from a representation (``.getAllLoci()``)
 - Add ``key`` property to intra- and inter-bonds for referencing source data

+ 2 - 0
src/apps/viewer/app.ts

@@ -89,6 +89,7 @@ const DefaultViewerOptions = {
     pickPadding: PluginConfig.General.PickPadding.defaultValue,
     enableWboit: PluginConfig.General.EnableWboit.defaultValue,
     preferWebgl1: PluginConfig.General.PreferWebGl1.defaultValue,
+    allowMajorPerformanceCaveat: PluginConfig.General.AllowMajorPerformanceCaveat.defaultValue,
 
     viewportShowExpand: PluginConfig.Viewport.ShowExpand.defaultValue,
     viewportShowControls: PluginConfig.Viewport.ShowControls.defaultValue,
@@ -159,6 +160,7 @@ export class Viewer {
                 [PluginConfig.General.PickPadding, o.pickPadding],
                 [PluginConfig.General.EnableWboit, o.enableWboit],
                 [PluginConfig.General.PreferWebGl1, o.preferWebgl1],
+                [PluginConfig.General.AllowMajorPerformanceCaveat, o.allowMajorPerformanceCaveat],
                 [PluginConfig.Viewport.ShowExpand, o.viewportShowExpand],
                 [PluginConfig.Viewport.ShowControls, o.viewportShowControls],
                 [PluginConfig.Viewport.ShowSettings, o.viewportShowSettings],

+ 2 - 0
src/apps/viewer/index.html

@@ -61,6 +61,7 @@
             var pickPadding = getParam('pick-padding', '[^&]+').trim();
             var disableWboit = getParam('disable-wboit', '[^&]+').trim() === '1';
             var preferWebgl1 = getParam('prefer-webgl1', '[^&]+').trim() === '1' || void 0;
+            var allowMajorPerformanceCaveat = getParam('allow-major-performance-caveat', '[^&]+').trim() === '1';
 
             molstar.Viewer.create('app', {
                 layoutShowControls: !hideControls,
@@ -76,6 +77,7 @@
                 pickPadding: isNaN(parseFloat(pickPadding)) ? 1 : parseFloat(pickPadding),
                 enableWboit: disableWboit ? false : void 0, // use default value if disable-wboit is not set
                 preferWebgl1: preferWebgl1,
+                allowMajorPerformanceCaveat: allowMajorPerformanceCaveat,
             }).then(viewer => {
                 var snapshotId = getParam('snapshot-id', '[^&]+').trim();
                 if (snapshotId) viewer.setRemoteSnapshot(snapshotId);

+ 2 - 0
src/extensions/geo-export/ui.tsx

@@ -60,6 +60,8 @@ export class GeometryExporterUI extends CollapsableControls<{}, State> {
     }
 
     componentDidMount() {
+        if (!this.plugin.canvas3d) return;
+
         const merged = merge(
             this.controls.behaviors.params,
             this.plugin.canvas3d!.reprCount

+ 3 - 1
src/extensions/mp4-export/controls.ts

@@ -118,11 +118,13 @@ export class Mp4Controls extends PluginComponent {
     }
 
     private init() {
+        if (!this.plugin.canvas3d) return;
+
         this.subscribe(this.plugin.managers.animation.events.updated.pipe(debounceTime(16)), () => {
             this.sync();
         });
 
-        this.subscribe(this.plugin.canvas3d?.resized!, () => this.syncInfo());
+        this.subscribe(this.plugin.canvas3d.resized, () => this.syncInfo());
         this.subscribe(this.plugin.helpers.viewportScreenshot?.events.previewed!, () => this.syncInfo());
 
         this.subscribe(this.plugin.behaviors.state.isBusy, b => this.updateCanApply(b));

+ 3 - 1
src/mol-canvas3d/canvas3d.ts

@@ -117,6 +117,7 @@ interface Canvas3DContext {
 
 namespace Canvas3DContext {
     export const DefaultAttribs = {
+        failIfMajorPerformanceCaveat: false,
         /** true by default to avoid issues with Safari (Jan 2021) */
         antialias: true,
         /** true to support multiple Canvas3D objects with a single context */
@@ -132,8 +133,9 @@ namespace Canvas3DContext {
 
     export function fromCanvas(canvas: HTMLCanvasElement, assetManager: AssetManager, attribs: Partial<Attribs> = {}): Canvas3DContext {
         const a = { ...DefaultAttribs, ...attribs };
-        const { antialias, preserveDrawingBuffer, pixelScale, preferWebGl1 } = a;
+        const { failIfMajorPerformanceCaveat, antialias, preserveDrawingBuffer, pixelScale, preferWebGl1 } = a;
         const gl = getGLContext(canvas, {
+            failIfMajorPerformanceCaveat,
             antialias,
             preserveDrawingBuffer,
             alpha: true, // the renderer requires an alpha channel

+ 13 - 10
src/mol-plugin-ui/controls/screenshot.tsx

@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author David Sehnal <david.sehnal@gmail.com>
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import * as React from 'react';
@@ -25,7 +26,7 @@ export interface ScreenshotPreviewProps {
 const _ScreenshotPreview = (props: ScreenshotPreviewProps) => {
     const { plugin, cropFrameColor } = props;
 
-    const helper = plugin.helpers.viewportScreenshot!;
+    const helper = plugin.helpers.viewportScreenshot;
     const [currentCanvas, setCurrentCanvas] = useState<HTMLCanvasElement | null>(null);
     const canvasRef = useRef<HTMLCanvasElement | null>(null);
     const propsRef = useRef(props);
@@ -70,8 +71,8 @@ const _ScreenshotPreview = (props: ScreenshotPreviewProps) => {
         subscribe(plugin.state.data.behaviors.isUpdating, v => {
             if (!v) isDirty = true;
         });
-        subscribe(helper.behaviors.values, () => isDirty = true);
-        subscribe(helper.behaviors.cropParams, () => isDirty = true);
+        subscribe(helper?.behaviors.values, () => isDirty = true);
+        subscribe(helper?.behaviors.cropParams, () => isDirty = true);
 
         let resizeObserver: any = void 0;
         if (typeof ResizeObserver !== 'undefined') {
@@ -108,7 +109,9 @@ export const ScreenshotPreview = React.memo(_ScreenshotPreview, (prev, next) =>
 
 declare const ResizeObserver: any;
 
-function drawPreview(helper: ViewportScreenshotHelper, target: HTMLCanvasElement, customBackground?: string, borderColor?: string, borderWidth?: number) {
+function drawPreview(helper: ViewportScreenshotHelper | undefined, target: HTMLCanvasElement, customBackground?: string, borderColor?: string, borderWidth?: number) {
+    if (!helper) return;
+
     const { canvas, width, height } = helper.getPreview()!;
     const ctx = target.getContext('2d');
     if (!ctx) return;
@@ -151,9 +154,9 @@ function drawPreview(helper: ViewportScreenshotHelper, target: HTMLCanvasElement
 
 function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: { plugin: PluginContext, canvas: HTMLCanvasElement | null, color?: string }) {
     const helper = plugin.helpers.viewportScreenshot;
-    const params = useBehavior(helper?.behaviors.values!);
-    const cropParams = useBehavior(helper?.behaviors.cropParams!);
-    const crop = useBehavior(helper?.behaviors.relativeCrop!);
+    const params = useBehavior(helper?.behaviors.values);
+    const cropParams = useBehavior(helper?.behaviors.cropParams);
+    const crop = useBehavior(helper?.behaviors.relativeCrop);
     const cropFrameRef = useRef<Viewport>({ x: 0, y: 0, width: 0, height: 0 });
     useBehavior(params?.resolution.name === 'viewport' ? plugin.canvas3d?.resized : void 0);
 
@@ -161,7 +164,7 @@ function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: {
     const [start, setStart] = useState([0, 0]);
     const [current, setCurrent] = useState([0, 0]);
 
-    if (!helper || !canvas) return null;
+    if (!helper || !canvas || !crop) return null;
 
     const { width, height } = helper.getSizeAndViewport();
 
@@ -267,7 +270,7 @@ function ViewportFrame({ plugin, canvas, color = 'rgba(255, 87, 45, 0.75)' }: {
 
     function finish() {
         const cropFrame = cropFrameRef.current;
-        if (cropParams.auto) {
+        if (cropParams?.auto) {
             helper?.behaviors.cropParams.next({ ...cropParams, auto: false });
         }
         helper?.behaviors.relativeCrop.next({

+ 7 - 5
src/mol-plugin-ui/left-panel.tsx

@@ -141,11 +141,13 @@ class FullSettings extends PluginUIComponent {
         this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate());
         this.subscribe(this.plugin.layout.events.updated, () => this.forceUpdate());
 
-        this.subscribe(this.plugin.canvas3d!.camera.stateChanged, state => {
-            if (state.radiusMax !== undefined || state.radius !== undefined) {
-                this.forceUpdate();
-            }
-        });
+        if (this.plugin.canvas3d) {
+            this.subscribe(this.plugin.canvas3d.camera.stateChanged, state => {
+                if (state.radiusMax !== undefined || state.radius !== undefined) {
+                    this.forceUpdate();
+                }
+            });
+        }
     }
 
     render() {

+ 1 - 1
src/mol-plugin-ui/viewport/canvas.tsx

@@ -59,7 +59,7 @@ export class ViewportCanvas extends PluginUIComponent<ViewportCanvasParams, View
         return <div className='msp-no-webgl'>
             <div>
                 <p><b>WebGL does not seem to be available.</b></p>
-                <p>This can be caused by an outdated browser, graphics card driver issue, or bad weather. Sometimes, just restarting the browser helps.</p>
+                <p>This can be caused by an outdated browser, graphics card driver issue, or bad weather. Sometimes, just restarting the browser helps. Also, make sure hardware acceleration is enabled in your browser.</p>
                 <p>For a list of supported browsers, refer to <a href='http://caniuse.com/#feat=webgl' target='_blank'>http://caniuse.com/#feat=webgl</a>.</p>
             </div>
         </div>;

+ 8 - 5
src/mol-plugin-ui/viewport/screenshot.tsx

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2019-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author David Sehnal <david.sehnal@gmail.com>
@@ -96,18 +96,21 @@ export class DownloadScreenshotControls extends PluginUIComponent<{ close: () =>
 }
 
 function ScreenshotParams({ plugin, isDisabled }: { plugin: PluginContext, isDisabled: boolean }) {
-    const helper = plugin.helpers.viewportScreenshot!;
-    const values = useBehavior(helper.behaviors.values);
+    const helper = plugin.helpers.viewportScreenshot;
+
+    const values = useBehavior(helper?.behaviors.values);
+    if (!helper) return null;
 
     return <ParameterControls params={helper.params} values={values} onChangeValues={v => helper.behaviors.values.next(v)} isDisabled={isDisabled} />;
 }
 
 function CropControls({ plugin }: { plugin: PluginContext }) {
     const helper = plugin.helpers.viewportScreenshot;
-    const cropParams = useBehavior(helper?.behaviors.cropParams!);
+
+    const cropParams = useBehavior(helper?.behaviors.cropParams);
     useBehavior(helper?.behaviors.relativeCrop);
 
-    if (!helper) return null;
+    if (!helper || !cropParams) return null;
 
     return <div style={{ width: '100%', height: '24px', marginTop: '8px' }}>
         <ToggleButton icon={CropOrginalSvg} title='Auto-crop' inline isSelected={cropParams.auto}

+ 2 - 0
src/mol-plugin-ui/viewport/simple-settings.tsx

@@ -22,6 +22,8 @@ import { ViewportHelpContent } from './help';
 
 export class SimpleSettingsControl extends PluginUIComponent {
     componentDidMount() {
+        if (!this.plugin.canvas3d) return;
+
         this.subscribe(this.plugin.events.canvas3d.settingsUpdated, () => this.forceUpdate());
 
         this.subscribe(this.plugin.canvas3d!.camera.stateChanged, state => {

+ 1 - 0
src/mol-plugin/config.ts

@@ -35,6 +35,7 @@ export const PluginConfig = {
         // as of Oct 1 2021, WebGL 2 doesn't work on iOS 15.
         // TODO: check back in a few weeks to see if it was fixed
         PreferWebGl1: item('plugin-config.prefer-webgl1', PluginFeatureDetection.preferWebGl1),
+        AllowMajorPerformanceCaveat: item('plugin-config.allow-major-performance-caveat', false),
     },
     State: {
         DefaultServer: item('plugin-state.server', 'https://webchem.ncbr.muni.cz/molstar-state'),

+ 2 - 1
src/mol-plugin/context.ts

@@ -201,7 +201,8 @@ export class PluginContext {
                 const pickPadding = this.config.get(PluginConfig.General.PickPadding) ?? 1;
                 const enableWboit = this.config.get(PluginConfig.General.EnableWboit) || false;
                 const preferWebGl1 = this.config.get(PluginConfig.General.PreferWebGl1) || false;
-                (this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, this.managers.asset, { antialias, preserveDrawingBuffer, pixelScale, pickScale, pickPadding, enableWboit, preferWebGl1 });
+                const failIfMajorPerformanceCaveat = !(this.config.get(PluginConfig.General.AllowMajorPerformanceCaveat) ?? false);
+                (this.canvas3dContext as Canvas3DContext) = Canvas3DContext.fromCanvas(canvas, this.managers.asset, { antialias, preserveDrawingBuffer, pixelScale, pickScale, pickPadding, enableWboit, preferWebGl1, failIfMajorPerformanceCaveat });
             }
             (this.canvas3d as Canvas3D) = Canvas3D.create(this.canvas3dContext!);
             this.canvas3dInit.next(true);