Skip to content

refactor(engine)!: GPU pass fusion stack 2/5 — rendering pipeline - #2167

Open
yuto-trd wants to merge 1 commit into
speckit/004-s1-specfrom
speckit/004-s2-engine
Open

refactor(engine)!: GPU pass fusion stack 2/5 — rendering pipeline#2167
yuto-trd wants to merge 1 commit into
speckit/004-s1-specfrom
speckit/004-s2-engine

Conversation

@yuto-trd

@yuto-trd yuto-trd commented Jul 31, 2026

Copy link
Copy Markdown
Member

Description

Stacked-PR slice 2/5 of speckit/004-gpu-pass-fusion (204 files, +49,286/-4,000).

This slice replaces executable render-node pulling with transactional RenderNodeContext recording, complete-request DAG planning, ROI propagation, cache substitution, execution-island planning, typed Shader/Geometry lowering, renderer-wide CurrentPixel fusion, and one ordered executor. All in-tree render-node consumers migrate with the public API change.

FilterEffect.ApplyTo(FilterEffectContext, Resource) remains the authoring entry point. Existing FilterEffect operation calls remain available, while FilterEffectContext.Shader and Geometry provide the new deferred opt-in surface. Built-in FilterEffect call sites are intentionally not migrated here; that work is isolated in slice 5. Blur and DropShadow retain their legacy implementations throughout the stack.

Stack

  1. speckit/004-s1-spec — specification and contracts
  2. This PR — record-then-plan engine and consumer migration
  3. speckit/004-s3-tests — pipeline and rendering test suites
  4. speckit/004-s4-evidence — benchmarks, paired evidence, and acceptance
  5. speckit/004-s5-shader-migration — built-in Shader migration, excluding Blur and DropShadow

Affected areas

  • Beutl.Engine (rendering / scene / track)
  • Beutl.ProjectSystem (project / document persistence)
  • UI (Beutl.Editor, Beutl.Editor.Components, Beutl.Controls)
  • Beutl.Extensibility (plugin abstractions)
  • Beutl.NodeGraph (node editor)
  • Beutl.FFmpegIpc / Beutl.FFmpegWorker (media IPC boundary)
  • Beutl.Api (server API client)
  • Build / CI / docs only

Also affects Beutl.AgentToolkit and application render consumers.

Breaking changes

Custom RenderNode.Process implementations and executable RenderNodeOperation consumers migrate to void Process(RenderNodeContext), context-owned fragment handles, and RenderNodeRenderer. See docs/specs/004-gpu-pass-fusion/contracts/breaking-changes.md in slice 1.

Ordinary FilterEffect operation calls remain source-compatible unless they directly consumed removed operation-backed EffectTarget members.

Test plan

  • Slice 4 restores the verified legacy-compatible integration tree byte-for-byte.
  • At that tree: 5,956 UnitTests passed, 5 skipped; related compatibility tests 30/30; evidence gates 11/11.
  • Intermediate-slice CI remains the authoritative per-slice build gate.

Fixed issues / References

  • Feature 004: renderer-wide GPU pass fusion

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1978582a-9bf1-47ac-a562-f0dff70fc2db

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

The PR does not appear safe to merge while repaired recovered elements can still silently lose valid edits.

The displayed reply, whose author is blank, says PR #2159 supersedes this recovery implementation, but current HEAD still sets IsStorageWriteSuppressed permanently and all explicit-save and autosave StoreToUri calls continue returning without persisting repaired elements.

Files Needing Attention: src/Beutl.ProjectSystem/ProjectSystem/Scene.cs, src/Beutl.Core/Serialization/CoreSerializer.cs, src/Beutl.Editor/AutoSaveService.cs

Important Files Changed

Filename Overview
src/Beutl.Engine/Graphics/Rendering/RenderNodeContext.cs Introduces context-owned recording and fragment handling for the deferred rendering pipeline.
src/Beutl.Engine/Graphics/Rendering/Planning/RenderRequestCompiler.cs Compiles recorded requests into planned execution with region, cache, and resource decisions.
src/Beutl.Engine/Graphics/Rendering/Planning/RenderRequestExecutor.cs Executes the compiled render plan in its prescribed order.
src/Beutl.ProjectSystem/ProjectSystem/Scene.cs Extends scene deserialization with malformed-element fallback recovery and protected source preservation.
src/Beutl.Core/Serialization/CoreSerializer.cs Adds discriminator assignability validation and storage-write suppression support.
src/Beutl.Editor/AutoSaveService.cs Integrates storage-write suppression into autosave and detached-object cleanup.

Reviews (17): Last reviewed commit: "refactor(engine)!: stack 2/5 — record-th..." | Re-trigger Greptile

Comment thread src/Beutl.ProjectSystem/ProjectSystem/Scene.cs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3ef886221b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.ProjectSystem/ProjectSystem/Scene.cs
Copilot AI review requested due to automatic review settings July 31, 2026 18:39
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 3ef8862 to 8cb333b Compare July 31, 2026 18:40

Copilot AI 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.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 8cb333b to f23b914 Compare July 31, 2026 20:59
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from f23b914 to 4f7cdfe Compare July 31, 2026 21:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f7cdfe182

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics/Rendering/Renderer.cs Outdated
Comment thread src/Beutl.NodeGraph/Nodes/Utilities/PreviewNode.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNodeRenderer.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 4f7cdfe to c8a396b Compare July 31, 2026 22:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c8a396b9ea

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNodeRenderer.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNodeRenderer.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNodeContext.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from c8a396b to ed9bda0 Compare August 1, 2026 00:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed9bda004a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.NodeGraph/Nodes/Utilities/PreviewNode.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Particles/ParticleRenderNode.cs Outdated
Comment thread src/Beutl.Engine/Graphics/FilterEffects/TransformEffect.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/DrawBackdropRenderNode.cs Outdated
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from ed9bda0 to 7bbb011 Compare August 1, 2026 00:47

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7bbb0111ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl/Helpers/AvaloniaTypeConverter.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 7bbb011 to 31992b2 Compare August 1, 2026 02:14

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31992b2473

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.ProjectSystem/ProjectSystem/Scene.cs
Comment thread src/Beutl.Engine/Graphics/BrushConstructor.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/Renderer.cs Outdated
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 31992b2 to 01a0310 Compare August 1, 2026 03:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 01a03104b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics/Rendering/BlendModeRenderNode.cs
Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNode.cs
Comment thread src/Beutl.Engine/Graphics/Rendering/Renderer.cs Outdated
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 01a0310 to fdc8f99 Compare August 1, 2026 04:46

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fdc8f99a91

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics/Rendering/Renderer.cs Outdated
Comment thread src/Beutl.Engine/Graphics/SourceVideo.Thumbnails.cs Outdated
Comment thread src/Beutl.Engine/Graphics/FilterEffects/SplitEffect.cs Outdated
Comment thread src/Beutl.Engine/Graphics/Rendering/RenderNodeRenderer.cs Outdated
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from fdc8f99 to 959e4d4 Compare August 1, 2026 06:06

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 959e4d45cb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

EnsureFallbackProjection(fallback);
}

MarkRecoveredElement(element, rawText);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Persist edits to partially recovered elements

When a valid element contains only a nested fallback object, this marks the entire successfully parsed Element as storage-write-suppressed. Subsequent edits to the element's valid fields or healthy sibling objects are therefore skipped by Scene.Serialize, so Save reports success but reopening restores their old values. Reserve raw-sidecar suppression for wholly unreadable element JSON, or serialize parsed elements while retaining each fallback's preserved Json.

Useful? React with 👍 / 👎.

@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 959e4d4 to 85b3797 Compare August 1, 2026 07:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85b37979ee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -84,10 +224,12 @@ static void SafeStep(string step, Action action)

_isDisposed = true;
SafeStep(nameof(OnDispose), () => OnDispose(false));
SafeStep(nameof(_frameRenderer), () => _frameRenderer?.Dispose());

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Dispatch finalizer-owned renderer cleanup

If a GPU-backed Renderer is abandoned without an explicit Dispose(), this finalizer invokes RenderNodeRenderer.Dispose() directly on the finalizer thread. That disposes _targetRegistry, whose pool evicts retained RenderTarget backend resources and explicitly requires renderer-thread disposal, risking context-thread violations or native failures. The earlier disposal fix only dispatches the normal Dispose() path; this finalizer call is fresh evidence that not all render-owned cleanup is marshalled. Queue _frameRenderer cleanup through RenderThread.Dispatcher, like the entry finalizer does.

Useful? React with 👍 / 👎.

var entries = _nodeCache.ToArray();
_nodeCache.Clear();
_allCurrentEntries.Clear();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear the frame renderer's retained caches

When ClearAllCaches() runs after a frame that required intermediate targets or compiled shaders, this clears only the per-drawable entries and leaves _frameRenderer untouched. The per-entry renderers are used for metadata queries, while _frameRenderer.Render() owns the frame execution pool, structural plans, and GPU program cache, so its retained targets and programs survive a call whose purpose is to release all caches (including the call from OutputViewModel.ClearEditViewModelCaches). Dispose and recreate the frame renderer here, or otherwise explicitly clear all of its owned caches without changing CacheOptions.

Useful? React with 👍 / 👎.

Comment thread src/Beutl.Engine/Graphics/Rendering/TextRenderNode.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 85b3797 to 9fbd500 Compare August 1, 2026 08:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9fbd5003ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics3D/Scene3DRenderNode.cs

return element;
}
catch (JsonException ex)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Recover non-JSON element deserialization failures

When a syntactically valid sidecar has a known but non-Element top-level discriminator, CoreSerializer.RestoreFromUri<Element> creates that type and the generic cast throws InvalidCastException; other top-level conversion failures can likewise escape as non-JsonException types. This catch therefore misses the failure and one malformed .belm still aborts opening the entire project instead of producing the disabled recovery element. Handle the relevant deserialization/type failures here (or validate assignability in CoreSerializer) without swallowing unrelated I/O errors.

Useful? React with 👍 / 👎.

internal static async Task DisposeThumbnailRenderResourcesAsync(params IDisposable?[] resources)
{
ArgumentNullException.ThrowIfNull(resources);
await RenderThread.Dispatcher.InvokeAsync(() =>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid awaiting thumbnail dispatch after shutdown

When thumbnail enumeration is finalized after RenderThread.Dispatcher has begun shutting down, this InvokeAsync enqueues work and awaits it with a non-cancelable token. The repository dispatcher sets _running to false before raising ShutdownStarted and never drains newly queued operations afterward, so the returned task never completes and application shutdown can hang while thumbnails are active. Arrange cleanup before shutdown or explicitly handle the shutdown state without awaiting an operation that cannot run.

Useful? React with 👍 / 👎.

Comment thread src/Beutl.Engine/Graphics/Rendering/OpacityRenderNode.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 9fbd500 to 0ee15b3 Compare August 1, 2026 11:26

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ee15b3fbf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Beutl.Engine/Graphics/Rendering/Renderer.cs Outdated
Comment thread src/Beutl.ProjectSystem/ProjectSystem/Scene.cs
Comment thread src/Beutl.Engine/Graphics/Rendering/GraphicsContext2D.cs
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 0ee15b3 to ebe4bc1 Compare August 1, 2026 13:46
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

No TODO comments were found.

@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from ebe4bc1 to 5564e90 Compare August 1, 2026 18:37
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

No TODO comments were found.

1 similar comment
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

No TODO comments were found.

@yuto-trd yuto-trd changed the title refactor(engine)!: GPU pass fusion stack 2/4 — record-then-plan pipeline and consumer migration refactor(engine)!: GPU pass fusion stack 2/5 — rendering pipeline Aug 1, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5564e907b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Stacked-PR slice 2 of 5: RenderNode.Process records into RenderNodeContext as the sole transactional recorder; sealed RenderFragmentHandle replaces the executable RenderNodeOperation lifecycle; recording lowers into metadata, ROI, cache substitution, island planning, fusion, and one execution; consumers use the disposable RenderNodeRenderer with immutable per-call RenderNodeRenderRequest descriptors. All in-tree RenderNode consumers migrate in this slice, existing tests are migrated, the public authoring surface is pinned by tests/Beutl.PublicApiContractTests, and the authoring guidance that documents the landed API lands here with it. Existing FilterEffect call sites retain their legacy CustomEffect placement contract.

BREAKING CHANGE: Beutl.Engine and out-of-tree Engine/plugin RenderNode implementations must migrate from RenderNodeOperation[] Process(RenderNodeContext) to void Process(RenderNodeContext), publish context-owned RenderFragmentHandle values, and use the high-level request APIs (RenderNodeRenderer with RenderNodeRenderRequest); see docs/specs/004-gpu-pass-fusion/contracts/breaking-changes.md.

BREAKING CHANGE: RenderNodeRenderRequest.UseRenderCache is removed; use CacheOptions = RenderCacheOptions.Enabled/Disabled, or new RenderCacheOptions(enabled, rules) for custom admission rules.

BREAKING CHANGE: Beutl.Engine target captures now use TargetCaptureScaleContract instead of RenderScaleContract; migrate to MaterializeAtWorkingScale, Custom, or PreserveTargetSupply.

BREAKING CHANGE: Beutl.Engine custom ShaderBindingBuilder binder overloads replace RenderRuntimeIdentity with ShaderBindingCachePolicy; use RequestUnique or the non-capturing ReuseFromSnapshot policy.
@yuto-trd
yuto-trd force-pushed the speckit/004-s2-engine branch from 5564e90 to 080fa9e Compare August 1, 2026 21:02
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

No TODO comments were found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 080fa9e444

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +352 to +354
executionCanvas.Transform = destination.Transform;
executionCanvas.Opacity = destination.Opacity;
executionCanvas.BlendMode = destination.BlendMode;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply the destination clip during expanded execution

When target access expands ExecutionTargetBounds beyond SelectedOutputBounds and the caller has an active PushClip, this offscreen canvas receives the destination transform, opacity, and blend mode but not its clip; the clip is applied only during the final commit. Consequently, an earlier target command can write outside the caller's clip and a later blur, backdrop, or other sampling stage can feed those pixels back inside it, unlike direct rendering and despite Render() promising to preserve the active clip. Mirror the destination clip onto the execution canvas before executing the graph.

Useful? React with 👍 / 👎.

Comment on lines +396 to 400
foreach (Entry entry in pendingEntries)
{
RevalidateAll(entry.Node);
entry.InvalidateBounds();
_allCurrentEntries.Add(entry);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Publish frame metadata only after all revalidation succeeds

When RevalidateAll throws while invalidating a cached target—for example because a custom/backend render target fails during disposal—the frame has already rendered and _allCurrentEntries was cleared, but this loop has published only the entries preceding the failure. Subsequent boundary queries therefore expose a partial frame. Fresh evidence beyond the fixed preparation and UpdateFrame paths is this separate post-render publication loop; revalidate every pending entry first, then add the complete list atomically.

Useful? React with 👍 / 👎.

Comment on lines +299 to +302
CaptureCleanupFailure(
() => RenderThread.Dispatcher.Invoke(
() => renderResourceFailure = DisposeRenderResourcesCore()),
ref primary);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid invoking the render dispatcher after shutdown

When a Renderer is disposed from a non-render thread after RenderThread.Dispatcher has begun shutting down—for example when a late export continuation releases its SceneRenderer during application teardown—this non-cancelable Invoke enqueues cleanup and waits forever. QueueSynchronizationContext.Shutdown() sets _running to false before raising ShutdownStarted, and its execution loop never drains operations posted afterward, so this can hang shutdown. Fresh evidence beyond the render-thread marshaling fix is that the synchronous disposal path does not check HasShutdownStarted; arrange disposal before shutdown or avoid waiting on an operation that can no longer run.

Useful? React with 👍 / 👎.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants