From 89f6693584ebaab6452b2b1e72b00895f8699461 Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Thu, 21 May 2026 16:22:01 +0200 Subject: [PATCH 1/4] feat(panel, debug): add offscreen texture debug vis --- src/display_context.ts | 31 +++++++++++++++++++++++++++++++ src/perspective_view/panel.ts | 27 ++++++++++++++++++++++----- src/sliceview/panel.ts | 28 ++++++++++++++++++++++------ 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/display_context.ts b/src/display_context.ts index b15d64a68f..615e5b97ce 100644 --- a/src/display_context.ts +++ b/src/display_context.ts @@ -276,6 +276,37 @@ export abstract class RenderedPanel extends RefCounted { gl.scissor(canvasRelativeClippedLeft, glBottom, width, height); } + setSubdividedGLClippedViewport(cellIndex: number, totalCells: number) { + const { + gl, + canvasRelativeClippedTop, + canvasRelativeClippedLeft, + renderViewport: { width, height }, + } = this; + + const numCols = Math.ceil(Math.sqrt(totalCells)); + const numRows = Math.ceil(totalCells / numCols); + + const col = cellIndex % numCols; + const row = Math.floor(cellIndex / numCols); + + const cellWidth = width / numCols; + const cellHeight = height / numRows; + + const left = canvasRelativeClippedLeft + col * cellWidth; + const top = canvasRelativeClippedTop + row * cellHeight; + const bottom = top + cellHeight; + + const glLeft = Math.floor(left); + const glBottom = Math.floor(this.context.canvas.height - bottom); + const glWidth = Math.ceil(cellWidth); + const glHeight = Math.ceil(cellHeight); + + gl.enable(WebGL2RenderingContext.SCISSOR_TEST); + gl.viewport(glLeft, glBottom, glWidth, glHeight); + gl.scissor(glLeft, glBottom, glWidth, glHeight); + } + // Sets the viewport to the logical viewport, using the scissor test to constrain drawing to the // clipped viewport. Drawing does not need to take `visible{Left,Top,Width,Height}Fraction` into // account. diff --git a/src/perspective_view/panel.ts b/src/perspective_view/panel.ts index 7b062b436c..387000eb77 100644 --- a/src/perspective_view/panel.ts +++ b/src/perspective_view/panel.ts @@ -83,6 +83,12 @@ import { MultipleScaleBarTextures } from "#src/widget/scale_bar.js"; import type { RPC } from "#src/worker_rpc.js"; import { SharedObject } from "#src/worker_rpc.js"; +// Turn on to see each of the offscreen textures +// render order is from bottom left to top right +// picking will not work as expected in a subdivision +// of the full panel, pretend you are picking from the full panel +const DEBUG_OFFSCREEN_TEXTURES = false; + export interface PerspectiveViewerState extends RenderedDataViewerState { wireFrame: WatchableValueInterface; enableAdaptiveDownsampling: WatchableValueInterface; @@ -1419,11 +1425,22 @@ export class PerspectivePanel extends RenderedDataPanel { } this.offscreenFramebuffer.unbind(); - // Draw the texture over the whole viewport. - this.setGLClippedViewport(); - this.offscreenCopyHelper.draw( - this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, - ); + if (DEBUG_OFFSCREEN_TEXTURES) { + const numTextures = OffscreenTextures.NUM_TEXTURES; + for (let i = 0; i < numTextures; i++) { + const texture = this.offscreenFramebuffer.colorBuffers[i].texture; + if (texture) { + this.setSubdividedGLClippedViewport(i, numTextures); + this.offscreenCopyHelper.draw(texture); + } + } + } else { + // Draw the texture over the whole viewport. + this.setGLClippedViewport(); + this.offscreenCopyHelper.draw( + this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, + ); + } return true; } diff --git a/src/sliceview/panel.ts b/src/sliceview/panel.ts index fe616f185d..acbfb6f2c0 100644 --- a/src/sliceview/panel.ts +++ b/src/sliceview/panel.ts @@ -59,6 +59,12 @@ import type { ShaderBuilder } from "#src/webgl/shader.js"; import type { TrackableScaleBarOptions } from "#src/widget/scale_bar.js"; import { MultipleScaleBarTextures } from "#src/widget/scale_bar.js"; +// Turn on to see each of the offscreen textures +// render order is from bottom left to top right +// picking will not work as expected in a subdivision +// of the full panel, pretend you are picking from the full panel +const DEBUG_OFFSCREEN_TEXTURES = false; + export interface SliceViewerState extends RenderedDataViewerState { showScaleBar: TrackableBoolean; wireFrame: TrackableBoolean; @@ -431,14 +437,24 @@ export class SliceViewPanel extends RenderedDataPanel { gl.disable(WebGL2RenderingContext.BLEND); } } - this.offscreenFramebuffer.unbind(); - // Draw the texture over the whole viewport. - this.setGLClippedViewport(); - this.offscreenCopyHelper.draw( - this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, - ); + if (DEBUG_OFFSCREEN_TEXTURES) { + const numTextures = OffscreenTextures.NUM_TEXTURES; + for (let i = 0; i < numTextures; i++) { + const texture = this.offscreenFramebuffer.colorBuffers[i].texture; + if (texture) { + this.setSubdividedGLClippedViewport(i, numTextures); + this.offscreenCopyHelper.draw(texture); + } + } + } else { + // Draw the texture over the whole viewport. + this.setGLClippedViewport(); + this.offscreenCopyHelper.draw( + this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, + ); + } return true; } From d48bb37b2cc7d1f3f65f6d7806ca04175ff0c936 Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Thu, 21 May 2026 16:35:34 +0200 Subject: [PATCH 2/4] fix(comment): correct render order in comment --- src/perspective_view/panel.ts | 2 +- src/sliceview/panel.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/perspective_view/panel.ts b/src/perspective_view/panel.ts index 387000eb77..c53ce7c1bd 100644 --- a/src/perspective_view/panel.ts +++ b/src/perspective_view/panel.ts @@ -84,7 +84,7 @@ import type { RPC } from "#src/worker_rpc.js"; import { SharedObject } from "#src/worker_rpc.js"; // Turn on to see each of the offscreen textures -// render order is from bottom left to top right +// render order is from top left to bottom right // picking will not work as expected in a subdivision // of the full panel, pretend you are picking from the full panel const DEBUG_OFFSCREEN_TEXTURES = false; diff --git a/src/sliceview/panel.ts b/src/sliceview/panel.ts index acbfb6f2c0..838f07d0f0 100644 --- a/src/sliceview/panel.ts +++ b/src/sliceview/panel.ts @@ -60,7 +60,7 @@ import type { TrackableScaleBarOptions } from "#src/widget/scale_bar.js"; import { MultipleScaleBarTextures } from "#src/widget/scale_bar.js"; // Turn on to see each of the offscreen textures -// render order is from bottom left to top right +// render order is from top left to bottom right // picking will not work as expected in a subdivision // of the full panel, pretend you are picking from the full panel const DEBUG_OFFSCREEN_TEXTURES = false; From 1026fb9672fa92ec76483e2ced3f1a03357358df Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Thu, 21 May 2026 16:42:12 +0200 Subject: [PATCH 3/4] refactor: use early return on debug for cleaner diff --- src/perspective_view/panel.ts | 12 ++++++------ src/sliceview/panel.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/perspective_view/panel.ts b/src/perspective_view/panel.ts index c53ce7c1bd..af6113ecd5 100644 --- a/src/perspective_view/panel.ts +++ b/src/perspective_view/panel.ts @@ -1434,13 +1434,13 @@ export class PerspectivePanel extends RenderedDataPanel { this.offscreenCopyHelper.draw(texture); } } - } else { - // Draw the texture over the whole viewport. - this.setGLClippedViewport(); - this.offscreenCopyHelper.draw( - this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, - ); + return true; } + // Draw the texture over the whole viewport. + this.setGLClippedViewport(); + this.offscreenCopyHelper.draw( + this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, + ); return true; } diff --git a/src/sliceview/panel.ts b/src/sliceview/panel.ts index 838f07d0f0..df6e64c2de 100644 --- a/src/sliceview/panel.ts +++ b/src/sliceview/panel.ts @@ -448,13 +448,13 @@ export class SliceViewPanel extends RenderedDataPanel { this.offscreenCopyHelper.draw(texture); } } - } else { - // Draw the texture over the whole viewport. - this.setGLClippedViewport(); - this.offscreenCopyHelper.draw( - this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, - ); + return true; } + // Draw the texture over the whole viewport + this.setGLClippedViewport(); + this.offscreenCopyHelper.draw( + this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture, + ); return true; } From 491690598cb4ce9edf8f70972de6d94a49071932 Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Thu, 21 May 2026 16:43:15 +0200 Subject: [PATCH 4/4] chore: add back full stop for diff --- src/sliceview/panel.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sliceview/panel.ts b/src/sliceview/panel.ts index df6e64c2de..c21edc6105 100644 --- a/src/sliceview/panel.ts +++ b/src/sliceview/panel.ts @@ -450,7 +450,7 @@ export class SliceViewPanel extends RenderedDataPanel { } return true; } - // Draw the texture over the whole viewport + // Draw the texture over the whole viewport. this.setGLClippedViewport(); this.offscreenCopyHelper.draw( this.offscreenFramebuffer.colorBuffers[OffscreenTextures.COLOR].texture,