From 550e688b3c6577ed856294b1037776671ba8b69d Mon Sep 17 00:00:00 2001 From: 3dtours Date: Mon, 12 Oct 2026 22:05:45 +0700 Subject: [PATCH] revert(studio): the repair is drawn once again, and the model's own answer is the only one the stage shows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two rounds were meant to answer the stroke sooner, but a preview cannot be half a repair: the blurred fill is what a machine without the runtime gets, and with it on the stage a spot of dirt came back smeared rather than gone — worst of all on a run of strokes, where each new one cancels the model's round that was still on its way and leaves the blur standing longest. The repair that works is the one that waits for the model, and the wait is worth it. The worker stays available but is switched off with the rest: this reverts the runtime's proxy along with the second round, so the stage is exactly what it was before, lag and all. Reverts 5489114. --- docker/frontend/src/App.tsx | 24 ---------------------- docker/frontend/src/engine/exportEngine.ts | 14 +------------ docker/frontend/src/engine/inpaint.ts | 7 ------- 3 files changed, 1 insertion(+), 44 deletions(-) diff --git a/docker/frontend/src/App.tsx b/docker/frontend/src/App.tsx index 28500b9..82ac03f 100644 --- a/docker/frontend/src/App.tsx +++ b/docker/frontend/src/App.tsx @@ -1032,30 +1032,6 @@ export function Workspace() { // render and the compare copy, so the two can never drift apart. const frame = cropEditing ? 'none' : frameId; const options = stageOptions; - // A repair in hand is drawn twice, and the first one is the cheap half: - // the blurred fill lands in a fraction of the model's fixed seconds and - // is a repair in its own right (it is what a machine without the runtime - // gets), so the stroke is answered at once and the model's version of - // the same mask replaces it when it arrives. Everything the app files or - // exports still waits for the model. - if (shownRecipe.adjustments.heal?.length) { - const quick = await renderPhoto({ - source: previewBytes, - recipe: shownRecipe, - frameId: frame, - useGeotag, - gpsInfo, - assets: engine.assets, - options: { ...options, healModel: false }, - }); - if (token !== renderToken.current) return; - if (quick) { - setPreviewUrl((prev) => { - if (prev) URL.revokeObjectURL(prev); - return URL.createObjectURL(new Blob([quick.bytes as BlobPart], { type: 'image/jpeg' })); - }); - } - } const out = await renderPhoto({ source: previewBytes, recipe: shownRecipe, diff --git a/docker/frontend/src/engine/exportEngine.ts b/docker/frontend/src/engine/exportEngine.ts index e47ce74..47ec3e2 100644 --- a/docker/frontend/src/engine/exportEngine.ts +++ b/docker/frontend/src/engine/exportEngine.ts @@ -120,14 +120,6 @@ export interface RenderOptions { // band appended below it, mirroring the landing page's `.lp-shot` + // `.lp-frame-meta`. Left off the live preview, which must not show it. caption?: { tag: string; title: string; meta: string } | null; - // The preview's own rush: draw the frame with the blurred fill alone, and the - // model's repair of the same mask arrives in the next render. The graph is a - // fixed cost whatever it is handed — through the runtime the app loads, 64x64 - // and 512x512 both measure the same two seconds — so the only thing that makes - // a stroke feel answered is showing the half of HEAL that is instant. - // Everything filed or exported leaves this on: a faster answer is worth - // something to an eye waiting on the brush, and to nothing else. - healModel?: boolean; } export interface RenderInput { @@ -1470,11 +1462,7 @@ export async function renderPhoto(input: RenderInput): Promise= 8 && srcH >= 8) { + if (srcW >= 8 && srcH >= 8) { const { w: mw, h: mh } = inpaintCropSize(srcW, srcH); const cropSurface = own(createSurface(mw, mh)); if (cropSurface) { diff --git a/docker/frontend/src/engine/inpaint.ts b/docker/frontend/src/engine/inpaint.ts index 7ead065..832c00c 100644 --- a/docker/frontend/src/engine/inpaint.ts +++ b/docker/frontend/src/engine/inpaint.ts @@ -99,13 +99,6 @@ function load(): Promise { ort.env.wasm.numThreads = self.crossOriginIsolated ? Math.min(4, navigator.hardwareConcurrency || 1) : 1; - // ...and the one thread there is runs in a worker of its own rather than - // on the page's own. The graph is seconds of solid arithmetic at this size, - // and a second of it on the main thread is a second in which the pointer - // does not move: the brush lagged behind the hand exactly as long as the - // repair took. The worker loads the same file WASM_DIR serves. WebGPU is - // off-thread on its own and ignores this. - ort.env.wasm.proxy = true; ort.env.webgpu.powerPreference = 'high-performance'; const session = await openSession(ort); return { ort, session };