Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/typescript-5.6.2
Browse files Browse the repository at this point in the history
  • Loading branch information
ilan-gold committed Dec 9, 2024
2 parents d686e35 + f2f02af commit 9b3e39a
Show file tree
Hide file tree
Showing 53 changed files with 2,458 additions and 1,649 deletions.
29 changes: 29 additions & 0 deletions .changeset/chatty-ravens-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"@vivjs/constants": minor
"@vivjs/extensions": minor
"@vivjs/layers": minor
"@vivjs/loaders": minor
"@hms-dbmi/viv": minor
"@vivjs/types": minor
"@vivjs/viewers": minor
"@vivjs/views": minor
---

**This release includes backward-incompatible changes**. To avoid automatically adopting such releases, ensure you are either pinning the exact version of `@hms-dbmi/viv` in your `package.json` file or using a version range syntax that only accepts patch updates, such as `~0.16.1`. Refer to npm's [semver documentation](https://docs.npmjs.com/cli/v6/using-npm/semver/) for details.

**Migrate to deck.gl v9**

This update modifies our code internally to support deck.gl v9, dropping compatibility with deck.gl v8. See the [release notes](https://deck.gl/docs/whats-new#deckgl-v90) to learn more.

**Impact**:

We haven’t changed Viv's public API, but the upgrade to deck.gl 9.0 is considered **breaking** due to changes in its dependencies, which may require updates to WebGL-related code (e.g., shaders, injections, constants). Here are potential issues users may face in migrating:

- deprecating WebGL1
- changing any public-facing GL-specific variables to use the new luma.gl backend-agnostic variables (such as `interpolation` on the `ImageLayer`)
- shader injection-location name changes (i.e., `gl_fragColor` -> `fragColor`)

**Action**:

- You will need to upgrade to deck.gl `9.0.x` if you use it directly as having multiple versions of deck.gl is not supported. The above list only includes changes internally to Viv and is not an exhaustive summary of all changes required for our migration. For full details on upgrading to deck.gl `9.0.x`, please refer to the [upgrade guide](https://deck.gl/docs/upgrade-guide#upgrading-to-v90).
- Pin a specific Viv version or semver range to prevent unintended updates.
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,4 @@ The [Changesets GitHub Action](https://github.com/changesets/action) will create

## 🌎 Browser Support

Viv supports both [WebGL1](https://caniuse.com/?search=webgl) and [WebGL2](https://caniuse.com/?search=webgl2)
contexts, to provides coverage across Safari, Firefox, Chrome, and Edge. Please
[file an issue](https://github.com/hms-dbmi/viv/issues/new) if you find a browser
in which Viv does not work.
Viv supports coverage across Safari, Firefox, Chrome, and Edge. Please [file an issue](https://github.com/hms-dbmi/viv/issues/new) if you find a browser in which Viv does not work.
18 changes: 9 additions & 9 deletions packages/constants/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import GL from '@luma.gl/constants';
import { GL } from '@luma.gl/constants';

export const MAX_COLOR_INTENSITY = 255;

Expand All @@ -18,28 +18,28 @@ export const DEFAULT_FONT_FAMILY =
*/
export const DTYPE_VALUES = {
Uint8: {
format: GL.R8UI,
format: 'r8uint',
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_BYTE,
max: 2 ** 8 - 1,
sampler: 'usampler2D'
},
Uint16: {
format: GL.R16UI,
format: 'r16uint',
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_SHORT,
max: 2 ** 16 - 1,
sampler: 'usampler2D'
},
Uint32: {
format: GL.R32UI,
format: 'r32uint',
dataFormat: GL.RED_INTEGER,
type: GL.UNSIGNED_INT,
max: 2 ** 32 - 1,
sampler: 'usampler2D'
},
Float32: {
format: GL.R32F,
format: 'r32float',
dataFormat: GL.RED,
type: GL.FLOAT,
// Not sure what to do about this one - a good use case for channel stats, I suppose:
Expand All @@ -48,29 +48,29 @@ export const DTYPE_VALUES = {
sampler: 'sampler2D'
},
Int8: {
format: GL.R8I,
format: 'r8int',
dataFormat: GL.RED_INTEGER,
type: GL.BYTE,
max: 2 ** (8 - 1) - 1,
sampler: 'isampler2D'
},
Int16: {
format: GL.R16I,
format: 'r16int',
dataFormat: GL.RED_INTEGER,
type: GL.SHORT,
max: 2 ** (16 - 1) - 1,
sampler: 'isampler2D'
},
Int32: {
format: GL.R32I,
format: 'r32int',
dataFormat: GL.RED_INTEGER,
type: GL.INT,
max: 2 ** (32 - 1) - 1,
sampler: 'isampler2D'
},
// Cast Float64 as 32 bit float point so it can be rendered.
Float64: {
format: GL.R32F,
format: 'r32float',
dataFormat: GL.RED,
type: GL.FLOAT,
// Not sure what to do about this one - a good use case for channel stats, I suppose:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ const BaseExtension = class extends LayerExtension {
updateState({ props, oldProps, changeFlags, ...rest }) {
super.updateState({ props, oldProps, changeFlags, ...rest });
if (props.colormap !== oldProps.colormap) {
const { gl } = this.context;
const { device } = this.context;
if (this.state.model) {
this.state.model.delete();
this.setState({ model: this._getModel(gl) });
this.state.model.destroy();
this.setState({ model: this._getModel(device) });
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ const AdditiveColormapExtension = class extends LayerExtension {
updateState({ props, oldProps, changeFlags, ...rest }) {
super.updateState({ props, oldProps, changeFlags, ...rest });
if (props.colormap !== oldProps.colormap) {
const { gl } = this.context;
const { device } = this.context;
if (this.state.model) {
this.state.model.delete();
this.setState({ model: this._getModel(gl) });
this.state.model.destroy();
this.setState({ model: this._getModel(device) });
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/extensions/src/lens-extension/lens-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default {
`,
'fs:#main-end': `
bool isFragOnLensBounds = frag_on_lens_bounds(vTexCoord);
gl_FragColor = (lensEnabled && isFragOnLensBounds) ? vec4(lensBorderColor, 1.) : gl_FragColor;
fragColor = (lensEnabled && isFragOnLensBounds) ? vec4(lensBorderColor, 1.) : fragColor;
`
}
};
1 change: 1 addition & 0 deletions packages/layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@deck.gl/geo-layers": "catalog:",
"@deck.gl/layers": "catalog:",
"@luma.gl/constants": "catalog:",
"@luma.gl/shadertools": "catalog:",
"@luma.gl/core": "catalog:",
"@luma.gl/engine": "catalog:",
"@luma.gl/webgl": "catalog:"
Expand Down
31 changes: 12 additions & 19 deletions packages/layers/src/bitmap-layer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { COORDINATE_SYSTEM, CompositeLayer } from '@deck.gl/core';
import { BitmapLayer as BaseBitmapLayer } from '@deck.gl/layers';
import GL from '@luma.gl/constants';
import { Geometry, Model } from '@luma.gl/core';
import { GL } from '@luma.gl/constants';
import { Model } from '@luma.gl/engine';
import { addAlpha } from './utils';

const PHOTOMETRIC_INTERPRETATIONS = {
WhiteIsZero: 0,
Expand Down Expand Up @@ -88,22 +89,11 @@ class BitmapLayerWrapper extends BaseBitmapLayer {
photometricInterpretation,
transparentColorInHook
);
if (!gl) {
return null;
}

/*
0,0 --- 1,0
| |
0,1 --- 1,1
*/
return new Model(gl, {
return new Model(this.context.device, {
...this.getShaders(),
id: this.props.id,
geometry: new Geometry({
drawMode: GL.TRIANGLES,
vertexCount: 6
}),
bufferLayout: this.getAttributeManager().getBufferLayouts(),
topology: 'triangle-list',
isInstanced: false,
inject: {
'fs:DECKGL_FILTER_COLOR': photometricInterpretationShader
Expand Down Expand Up @@ -131,15 +121,17 @@ class BitmapLayerWrapper extends BaseBitmapLayer {
*/
const BitmapLayer = class extends CompositeLayer {
initializeState(args) {
const { gl } = this.context;
const { device } = this.context;
// This tells WebGL how to read row data from the texture. For example, the default here is 4 (i.e for RGBA, one byte per channel) so
// each row of data is expected to be a multiple of 4. This setting (i.e 1) allows us to have non-multiple-of-4 row sizes. For example, for 2 byte (16 bit data),
// we could use 2 as the value and it would still work, but 1 also works fine (and is more flexible for 8 bit - 1 byte - textures as well).
// https://stackoverflow.com/questions/42789896/webgl-error-arraybuffer-not-big-enough-for-request-in-case-of-gl-luminance
// This needs to be called here and not in the BitmapLayerWrapper because the `image` prop is converted to a texture outside of the layer, as controlled by the `image` type.
// See: https://github.com/visgl/deck.gl/pull/5197
gl.pixelStorei(GL.UNPACK_ALIGNMENT, 1);
gl.pixelStorei(GL.PACK_ALIGNMENT, 1);
device.setParametersWebGL({
[GL.UNPACK_ALIGNMENT]: 1,
[GL.PACK_ALIGNMENT]: 1
});
super.initializeState(args);
}

Expand All @@ -149,6 +141,7 @@ const BitmapLayer = class extends CompositeLayer {
transparentColor: transparentColorInHook
} = this.props;
const transparentColor = getTransparentColor(photometricInterpretation);
this.props.image.data = addAlpha(this.props.image.data);
return new BitmapLayerWrapper(this.props, {
// transparentColor is a prop applied to the original image data by deck.gl's
// BitmapLayer and needs to be in the original colorspace. It is used to determine
Expand Down
9 changes: 4 additions & 5 deletions packages/layers/src/image-layer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { COORDINATE_SYSTEM, CompositeLayer } from '@deck.gl/core';
import GL from '@luma.gl/constants';
import { GL } from '@luma.gl/constants';

import { ColorPaletteExtension } from '@vivjs/extensions';
import { SIGNAL_ABORTED, isInterleaved } from '@vivjs/loaders';
Expand Down Expand Up @@ -27,7 +27,7 @@ const defaultProps = {
onViewportLoad: { type: 'function', value: null, compare: true },
interpolation: {
type: 'number',
value: GL.NEAREST,
value: 'nearest',
compare: true
},
extensions: {
Expand Down Expand Up @@ -88,9 +88,8 @@ const ImageLayer = class extends CompositeLayer {
// data is for BitmapLayer and needs to be of form { data: Uint8Array, width, height };
raster.data = raster.data[0];
if (raster.data.length === raster.width * raster.height * 3) {
// data is RGB (not RGBA) and need to update texture formats
raster.format = GL.RGB;
raster.dataFormat = GL.RGB;
// Previously there was a rgb format, but now we only convert to rgba in BitmapLater
raster.format = 'rgba8unorm';
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CompositeLayer } from '@deck.gl/core';
import GL from '@luma.gl/constants';
import { GL } from '@luma.gl/constants';
import { Matrix4 } from '@math.gl/core';

import { ColorPaletteExtension } from '@vivjs/extensions';
Expand Down Expand Up @@ -108,8 +108,8 @@ const MultiscaleImageLayer = class extends CompositeLayer {
if (isInterleaved(loader[resolution].shape)) {
tile.data = tile.data[0];
if (tile.data.length === tile.width * tile.height * 3) {
tile.format = GL.RGB;
tile.dataFormat = GL.RGB; // is this not properly inferred?
// This indicates the data is RGB but it will be converted to RGBA
tile.format = 'rgba8unorm';
}
// can just return early, no need to check for webgl2
return tile;
Expand Down Expand Up @@ -179,7 +179,7 @@ const MultiscaleImageLayer = class extends CompositeLayer {
onHover,
onClick,
// Background image is nicest when LINEAR in my opinion.
interpolation: GL.LINEAR,
interpolation: 'linear',
onViewportLoad: null
});
const layers = [baseLayer, tiledLayer];
Expand Down
3 changes: 1 addition & 2 deletions packages/layers/src/multiscale-image-layer/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import GL from '@luma.gl/constants';
import { getImageSize, isInterleaved } from '@vivjs/loaders';

import BitmapLayer from '../bitmap-layer';
Expand Down Expand Up @@ -50,6 +49,6 @@ export function renderSubLayers(props) {
id: `tile-sub-layer-${bounds}-${id}`,
tileId: { x, y, z },
// The auto setting is NEAREST at the highest resolution but LINEAR otherwise.
interpolation: z === maxZoom ? GL.NEAREST : GL.LINEAR
interpolation: z === maxZoom ? 'nearest' : 'linear'
});
}
2 changes: 1 addition & 1 deletion packages/layers/src/scale-bar-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const defaultProps = {
pickable: { type: 'boolean', value: true, compare: true },
viewState: {
type: 'object',
value: { zoom: 0, target: [0, 0, 0] },
value: { zoom: 0, target: [0, 0, 0], width: 1, height: 1 },
compare: true
},
unit: { type: 'string', value: '', compare: true },
Expand Down
14 changes: 14 additions & 0 deletions packages/layers/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,17 @@ export function snapValue(value) {

return [targetOrigUnits, targetNewUnits, snappedUnit.symbol];
}

export function addAlpha(array) {
if (!(array instanceof Uint8Array)) {
throw new Error('Expected Uint8Array');
}
const alphaArray = new Uint8Array(array.length + array.length / 3);
for (let i = 0; i < array.length / 3; i += 1) {
alphaArray[i * 4] = array[i * 3];
alphaArray[i * 4 + 1] = array[i * 3 + 1];
alphaArray[i * 4 + 2] = array[i * 3 + 2];
alphaArray[i * 4 + 3] = 255;
}
return alphaArray;
}
22 changes: 2 additions & 20 deletions packages/layers/src/volume-layer/volume-layer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { COORDINATE_SYSTEM, CompositeLayer } from '@deck.gl/core';
import GL from '@luma.gl/constants';
import { isWebGL2 } from '@luma.gl/core';
import { GL } from '@luma.gl/constants';
import { Matrix4 } from '@math.gl/core';
import { ColorPalette3DExtensions } from '@vivjs/extensions';

Expand Down Expand Up @@ -34,7 +33,6 @@ const defaultProps = {
clippingPlanes: { type: 'array', value: [], compare: true },
onUpdate: { type: 'function', value: () => {}, compare: true },
useProgressIndicator: { type: 'boolean', value: true, compare: true },
useWebGL1Warning: { type: 'boolean', value: true, compare: true },
extensions: {
type: 'array',
value: [new ColorPalette3DExtensions.AdditiveBlendExtension()],
Expand All @@ -58,7 +56,6 @@ const defaultProps = {
* @property {function=} onViewportLoad Function that gets called when the data in the viewport loads.
* @property {Array.<Object>=} clippingPlanes List of math.gl [Plane](https://math.gl/modules/culling/docs/api-reference/plane) objects.
* @property {boolean=} useProgressIndicator Whether or not to use the default progress text + indicator (default is true)
* @property {boolean=} useWebGL1Warning Whether or not to use the default WebGL1 warning (default is true)
* @property {function=} onUpdate A callback to be used for getting updates of the progress, ({ progress }) => {}
* @property {Array=} extensions [deck.gl extensions](https://deck.gl/docs/developer-guide/custom-layers/layer-extensions) to add to the layers - default is AdditiveBlendExtension from ColorPalette3DExtensions.
*/
Expand Down Expand Up @@ -150,8 +147,7 @@ const VolumeLayer = class extends CompositeLayer {
}

renderLayers() {
const { loader, id, resolution, useProgressIndicator, useWebGL1Warning } =
this.props;
const { loader, id, resolution, useProgressIndicator } = this.props;
const { dtype } = loader[resolution];
const {
data,
Expand All @@ -162,20 +158,6 @@ const VolumeLayer = class extends CompositeLayer {
physicalSizeScalingMatrix,
resolutionMatrix
} = this.state;
const { gl } = this.context;
if (!isWebGL2(gl) && useWebGL1Warning) {
const { viewport } = this.context;
return getTextLayer(
[
'Volume rendering is only available on browsers that support WebGL2. If you',
'are using Safari, you can turn on WebGL2 by navigating in the top menubar',
'to check Develop > Experimental Features > WebGL 2.0 and then refreshing',
'the page.'
].join('\n'),
viewport,
id
);
}
if (!(width && height) && useProgressIndicator) {
const { viewport } = this.context;
return getTextLayer(
Expand Down
Loading

0 comments on commit 9b3e39a

Please sign in to comment.