Skip to content

fix(layer): keep layer settings when the layer type is auto-detected - #1135

Open
Thanatos9404 wants to merge 2 commits into
google:masterfrom
Thanatos9404:fix/auto-layer-keep-settings
Open

Thanatos9404 wants to merge 2 commits into
google:masterfrom
Thanatos9404:fix/auto-layer-keep-settings

Conversation

@Thanatos9404

@Thanatos9404 Thanatos9404 commented Oct 19, 2026 •

Copy link
Copy Markdown

Fixes #1085

When a layer has no type, Neuroglancer creates an AutoUserLayer and swaps it for the detected type once the data source loads. changeLayerType rebuilt the new layer from AutoUserLayer.toJSON(), which only has the generic layer state, so type-specific settings were lost. In the issue's example the image layer started with the default opacity.

  • AutoUserLayer keeps the specification it was restored from and passes it to changeLayerType as an optional baseSpecification, used for properties the auto layer doesn't set. If an invalid value makes the new layer's restoreState throw, the new layer is disposed and the auto layer stays.
  • The multi-channel image setup now only applies its opacity, blend and volumeRenderingDepthSamples defaults when the specification doesn't set them. A shader in the specification is kept, and the multi-channel color and contrast defaults are skipped in that case.

Testing: the new src/layer/index.browser_test.ts simulates type detection with stub data sources. Its checks fail on master, except the one for the multi-channel defaults, and pass with this change.

Not changed: the OMERO part of the issue (explicit "type": "image") is left for a separate change.

A layer specification without "type" creates an AutoUserLayer, which
changes to the detected layer type once its data source loads. The new
layer was restored only from the toJSON() of the AutoUserLayer, which
holds just the generic layer state, so settings for the detected type,
such as "opacity" for an image layer, were dropped.

AutoUserLayer now keeps the specification it was restored from, and
changeLayerType takes it as an optional base specification for the
properties that the state of the existing layer does not set. If the
new layer fails to restore its state, changeLayerType now disposes it
before passing the error on, so the existing layer stays in place.

For an auto-detected image layer, the multi-channel setup then set
opacity, blend and volumeRenderingDepthSamples to fixed defaults. It
now keeps any of these that the layer specification gives.

Fixes google#1085

@seankmartin seankmartin left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good thanks, I've left one comment as it's fine with me but could affect someone using it so in case they run into the issue they can see it here

});
});

it("stays an auto layer if the detected layer type rejects a setting", () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously since these settings were ignored the auto layer creation would have continued even with incorrect additional state. Now these layers would get rejected instead of creating. I'm ok with the rejection, but if it ends up affecting users we may want to instead drop parts of the state which are not compatible.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. If the rejection does end up affecting anyone, dropping only the parts of the state that don't fit the detected type would be a small follow-up, and I'm happy to do it.

@chrisj chrisj left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for this fix! looks good other than my one comment about keeping user shader

Comment thread src/layer/multi_channel_setup.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if a custom user shader is set, this line overrides it
visit https://neuroglancer--pr1135-hqp87jqf.web.app/
load this state:

{
  "dimensions": {
    "x": [8e-9, "m"],
    "y": [8e-9, "m"],
    "z": [8e-9, "m"]
  },
  "position": [128, 128, 128],
  "crossSectionScale": 8,
  "layers": [
    {
      "name": "shader-repro",
      "source": "precomputed://gs://neuroglancer-public-data/flyem_fib-25/image",
      "opacity": 1,
      "shader": "void main() { emitRGB(vec3(1.0, 0.0, 0.0)); }"
    }
  ],
  "layout": "xy"
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, thanks. In 6c16903 a shader given in the layer state is kept, and the color and contrast defaults are skipped in that case, since a custom shader may not have those controls. I added a test with the shader from your repro. For a source with several channels, each channel layer gets the same shader.

…el setup

When an auto-detected image layer is set up as a multi-channel layer, the
multi-channel shader replaced a shader given in the layer state. Keep that
shader and skip the color and contrast defaults, which only apply to the
multi-channel shader.
@jbms

jbms commented Oct 19, 2026

Copy link
Copy Markdown
Collaborator

I'm not sure if this is a good idea --- I think if we go with this we'd want to explicitly guarantee that all layer types assign the same meaning to a given attribute that applies to more than one layer type. Just allowing specific attributes may be better. Or an explicit auto image layer type.

@Thanatos9404

Copy link
Copy Markdown
Author

Fair point. shader and shaderControls already mean different things on image, annotation and single mesh layers, so passing the whole spec through could hand an image shader to an annotation layer. I could switch to an allowlist instead: carry over only image settings such as opacity, blend, shader and shaderControls, and only when the detected type is image, which still covers the OME-Zarr case in #1085. Would that work for you, or would you rather have an explicit auto image type?

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants