Skip to content

Commit

Permalink
Merge branch 'feature/continous-camera-movement-tracking' into featur…
Browse files Browse the repository at this point in the history
…e/increase-vr-performance-no-gl-query
  • Loading branch information
seankmartin committed Jul 1, 2024
2 parents 64ca78f + 6c639b9 commit 9940a88
Show file tree
Hide file tree
Showing 19 changed files with 560 additions and 87 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
run: |
build_info="{'tag':'$(git describe --always --tags)', 'url':'https://github.com/google/neuroglancer/commit/$(git rev-parse HEAD)', 'timestamp':'$(date)'}"
npm run build -- --no-typecheck --no-lint --define NEUROGLANCER_BUILD_INFO="${build_info}"
echo $build_info > ./dist/client/version.json
shell: bash
- name: Build Python client bundles
run: npm run build-python -- --no-typecheck --no-lint
Expand Down
35 changes: 34 additions & 1 deletion build_tools/build-package.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,24 @@ import fs from "node:fs/promises";
import path from "node:path";
import esbuild from "esbuild";
import { glob } from "glob";
import ts from "typescript";
import yargs from "yargs";

const rootDir = path.resolve(import.meta.dirname, "..");

function buildDeclarationFiles(
fileNames: string[],
options: ts.CompilerOptions,
): void {
options = {
...options,
declaration: true,
emitDeclarationOnly: true,
};
const program = ts.createProgram(fileNames, options);
program.emit();
}

async function buildPackage(options: { inplace?: boolean }) {
const { inplace = false } = options;

Expand Down Expand Up @@ -45,13 +59,32 @@ async function buildPackage(options: { inplace?: boolean }) {
nodir: true,
});

const entryPoints = typescriptSources.map((name) =>
path.resolve(srcDir, name),
);

await esbuild.build({
entryPoints: typescriptSources.map((name) => path.resolve(srcDir, name)),
entryPoints,
outbase: srcDir,
bundle: false,
outdir: libDir,
});

let compilerOptionsFromConfigFile: ts.CompilerOptions = {};
const configFileName = ts.findConfigFile("../", ts.sys.fileExists);
if (configFileName) {
const configFile = ts.readConfigFile(configFileName, ts.sys.readFile);
compilerOptionsFromConfigFile = ts.parseJsonConfigFileContent(
configFile.config,
ts.sys,
"./",
).options;
}
buildDeclarationFiles(entryPoints, {
...compilerOptionsFromConfigFile,
outDir: libDir,
});

const otherSources = await glob(["**/*.{css,js,html,wasm}"], {
cwd: srcDir,
nodir: true,
Expand Down
27 changes: 10 additions & 17 deletions src/annotation/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import {
} from "#src/chunk_manager/backend.js";
import { ChunkPriorityTier, ChunkState } from "#src/chunk_manager/base.js";
import type { DisplayDimensionRenderInfo } from "#src/navigation_state.js";
import { displayDimensionRenderInfosEqual } from "#src/navigation_state.js";
import { validateDisplayDimensionRenderInfoProperty } from "#src/navigation_state.js";
import type {
RenderedViewBackend,
RenderLayerBackendAttachment,
Expand Down Expand Up @@ -412,22 +412,15 @@ class AnnotationSpatiallyIndexedRenderLayerBackend extends withChunkManager(
}
const attachmentState =
attachment.state! as AnnotationRenderLayerAttachmentState;
const { transformedSources, displayDimensionRenderInfo } =
attachmentState;
if (transformedSources.length === 0) continue;
const viewDisplayDimensionRenderInfo =
view.projectionParameters.value.displayDimensionRenderInfo;
if (displayDimensionRenderInfo !== viewDisplayDimensionRenderInfo) {
if (
!displayDimensionRenderInfosEqual(
displayDimensionRenderInfo,
viewDisplayDimensionRenderInfo,
)
) {
continue;
}
attachmentState.displayDimensionRenderInfo =
viewDisplayDimensionRenderInfo;
const { transformedSources } = attachmentState;
if (
transformedSources.length === 0 ||
!validateDisplayDimensionRenderInfoProperty(
attachmentState,
view.projectionParameters.value.displayDimensionRenderInfo,
)
) {
continue;
}
const priorityTier = getPriorityTier(visibility);
const basePriority = getBasePriority(visibility);
Expand Down
35 changes: 16 additions & 19 deletions src/datasource/graphene/frontend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import "#src/datasource/graphene/graphene.css";
import { debounce } from "lodash-es";
import {
AnnotationDisplayState,
AnnotationLayerState,
Expand Down Expand Up @@ -935,7 +936,7 @@ class MergeState extends RefCounted implements Trackable {
ERROR_JSON_KEY,
verifyString,
);
const locked = verifyObjectProperty(obj, LOCKED_JSON_KEY, verifyBoolean);
const locked = false; // TODO(chrisj) verifyObjectProperty(obj, LOCKED_JSON_KEY, verifyBoolean);
const sink = restoreSegmentSelection(obj[SINK_JSON_KEY]);
const source = restoreSegmentSelection(obj[SOURCE_JSON_KEY]);
return {
Expand Down Expand Up @@ -1531,11 +1532,11 @@ class GraphConnection extends SegmentationGraphSourceConnection {
segmentsToAdd.push(submission.mergedRoot);
}
}
const latestRoots =
await this.graph.graphServer.filterLatestRoots(segmentsToAdd);
const segmentsState = this.layer.displayState.segmentationGroupState.value;
const { visibleSegments, selectedSegments } = segmentsState;
selectedSegments.delete(segmentsToRemove);
const latestRoots =
await this.graph.graphServer.filterLatestRoots(segmentsToAdd);
this.meshAddNewSegments(latestRoots);
selectedSegments.add(latestRoots);
visibleSegments.add(latestRoots);
Expand Down Expand Up @@ -2196,39 +2197,32 @@ class MulticutSegmentsTool extends LayerTool<SegmentationUserLayer> {
displayState.baseSegmentHighlighting.value = priorBaseSegmentHighlighting;
displayState.highlightColor.value = priorHighlightColor;
});

const resetMulticutDisplay = () => {
resetTemporaryVisibleSegmentsState(segmentationGroupState);
displayState.useTempSegmentStatedColors2d.value = false;
displayState.tempSegmentStatedColors2d.value.clear(); // TODO, should only clear those that are in temp sets
displayState.tempSegmentDefaultColor2d.value = undefined;
displayState.highlightColor.value = undefined;
};

const updateMulticutDisplay = () => {
resetMulticutDisplay();
activeGroupIndicator.classList.toggle(
"blueGroup",
multicutState.blueGroup.value,
);

const focusSegment = multicutState.focusSegment.value;
if (focusSegment === undefined) return;

displayState.baseSegmentHighlighting.value = true;
displayState.highlightColor.value = multicutState.blueGroup.value
? BLUE_COLOR_HIGHTLIGHT
: RED_COLOR_HIGHLIGHT;
segmentsState.useTemporaryVisibleSegments.value = true;
segmentsState.useTemporarySegmentEquivalences.value = true;

// add to focus segments and temporary sets
// add focus segment and red/blue segments
segmentsState.temporaryVisibleSegments.add(focusSegment);

for (const segment of multicutState.segments) {
segmentsState.temporaryVisibleSegments.add(segment);
}

// all other segments are added to the focus segment equivalences
for (const equivalence of segmentsState.segmentEquivalences.setElements(
focusSegment,
Expand All @@ -2240,14 +2234,12 @@ class MulticutSegmentsTool extends LayerTool<SegmentationUserLayer> {
);
}
}

// set colors
displayState.tempSegmentDefaultColor2d.value = MULTICUT_OFF_COLOR;
displayState.tempSegmentStatedColors2d.value.set(
focusSegment,
TRANSPARENT_COLOR_PACKED,
);

for (const segment of multicutState.redSegments) {
displayState.tempSegmentStatedColors2d.value.set(
segment,
Expand All @@ -2263,18 +2255,19 @@ class MulticutSegmentsTool extends LayerTool<SegmentationUserLayer> {

displayState.useTempSegmentStatedColors2d.value = true;
};

updateMulticutDisplay();

activation.registerDisposer(
multicutState.changed.add(updateMulticutDisplay),
);

activation.registerDisposer(
segmentationGroupState.segmentEquivalences.changed.add(
debounce(() => updateMulticutDisplay(), 0),
),
);
activation.bindAction("swap-group", (event) => {
event.stopPropagation();
multicutState.swapGroup();
});

activation.bindAction("set-anchor", (event) => {
event.stopPropagation();
const currentSegmentSelection = maybeGetSelection(
Expand Down Expand Up @@ -2308,7 +2301,6 @@ class MulticutSegmentsTool extends LayerTool<SegmentationUserLayer> {
}
multicutState.activeGroup.add(currentSegmentSelection);
});

activation.bindAction("submit", (event) => {
event.stopPropagation();
submitAction();
Expand Down Expand Up @@ -2488,7 +2480,12 @@ class MergeSegmentsTool extends LayerTool<SegmentationUserLayer> {
text: "Clear",
title: "Clear pending merges",
onClick: () => {
merges.value = [];
lineTool.deactivate();
for (const merge of merges.value) {
if (!merge.locked) {
graphConnection.deleteMergeSubmission(merge);
}
}
},
}),
);
Expand Down
23 changes: 23 additions & 0 deletions src/display_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

import { debounce } from "lodash-es";

import type { FrameNumberCounter } from "#src/chunk_manager/frontend.js";
import { TrackableValue } from "#src/trackable_value.js";
import { animationFrameDebounce } from "#src/util/animation_frame_debounce.js";
Expand All @@ -26,6 +28,8 @@ import type { WatchableVisibilityPriority } from "#src/visibility_priority/front
import type { GL } from "#src/webgl/context.js";
import { initializeWebGL } from "#src/webgl/context.js";

const DELAY_AFTER_CONTINUOUS_CAMERA_MOTION_MS = 300;

export class RenderViewport {
// Width of visible portion of panel in canvas pixels.
width = 0;
Expand Down Expand Up @@ -390,13 +394,16 @@ export class DisplayContext extends RefCounted implements FrameNumberCounter {
gl: GL;
updateStarted = new NullarySignal();
updateFinished = new NullarySignal();
continuousCameraMotionFinished = new NullarySignal();
changed = this.updateFinished;
panels = new Set<RenderedPanel>();
canvasRect: DOMRect | undefined;
rootRect: DOMRect | undefined;
resizeGeneration = 0;
boundsGeneration = -1;

private continuousCameraMotionInProgress = false;

// Panels ordered by `drawOrder`. If length is 0, needs to be recomputed.
private orderedPanels: RenderedPanel[] = [];

Expand Down Expand Up @@ -447,6 +454,22 @@ export class DisplayContext extends RefCounted implements FrameNumberCounter {

private resizeObserver = new ResizeObserver(this.resizeCallback);

private debouncedEndContinuousCameraMotion = this.registerCancellable(
debounce(() => {
this.continuousCameraMotionInProgress = false;
this.continuousCameraMotionFinished.dispatch();
}, DELAY_AFTER_CONTINUOUS_CAMERA_MOTION_MS),
);

flagContinuousCameraMotion() {
this.continuousCameraMotionInProgress = true;
this.debouncedEndContinuousCameraMotion();
}

get isContinuousCameraMotionInProgress() {
return this.continuousCameraMotionInProgress;
}

constructor(public container: HTMLElement) {
super();
const { canvas, resizeObserver } = this;
Expand Down
13 changes: 13 additions & 0 deletions src/navigation_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1432,6 +1432,19 @@ export function displayDimensionRenderInfosEqual(
);
}

export function validateDisplayDimensionRenderInfoProperty(
obj: { displayDimensionRenderInfo: DisplayDimensionRenderInfo },
expected: DisplayDimensionRenderInfo,
): boolean {
const actual = obj.displayDimensionRenderInfo;
if (actual === expected) return true;
if (displayDimensionRenderInfosEqual(actual, expected)) {
obj.displayDimensionRenderInfo = expected;
return true;
}
return false;
}

export class WatchableDisplayDimensionRenderInfo extends RefCounted {
changed = new NullarySignal();
private curRelativeDisplayScales: RelativeDisplayScales =
Expand Down
Loading

0 comments on commit 9940a88

Please sign in to comment.