Commit Graph
3 Commits
Author SHA1 Message Date
Mike-Solar 29204d1f63 node: virtual graph endpoints and the Kahn-order BFS sweep (M0b core)
Per docs/zh/plans/render-pipeline-threads.md §3.8:

- oak-node/nodes/graphendpoints.rs: the GraphInput/GraphOutput
  virtual node pair — factory-registered but hidden from every create
  menu, duplicate refused, real value() semantics (the input forwards
  its feed_in row, the output publishes its tex_in as the frame).
  The input endpoint also declares a connectable feed_in port
  (documented deviation: footage/generator sources have no connectable
  inputs, so the walk needs a feeder anchor).
- graph.rs: ensure_endpoints/endpoints/is_endpoint — idempotent,
  identified by type id, default input->output edge only while the
  output's tex_in is free; remove_node refuses endpoints.
- project.rs + serializer.rs: every project graph carries the pair;
  a legacy file without endpoints migrates on load (roundtrip and
  legacy-migration tests, re-save is idempotent).
- traverser.rs: eval_graph_bfs — the endpoint-to-endpoint Kahn
  sweep. Live set = (input's forward cone U its feeder cone) INTERSECT
  (output's backward cone); multi-input nodes dequeue at zero
  in-degree over the live subgraph; deterministic ascending-id ready
  order (Graph::edges is a BTreeSet, so insertion order is
  unrecoverable — documented); time-shifted upstreams pull through
  the shared DFS memo (walk_dfs, factored out of evaluate);
  un-orderable remainder reports a named cycle; missing endpoints /
  unreachable output are errors. Eight BFS tests cover the plan's
  acceptance bullets.
- oak-render: bfs_endpoint_sweep_renders_footage_through_position —
  real clip through a real Position node via the sweep, shifted
  pixels asserted against a reference decode.
- Endpoint names localized in all eight i18n packs; storage/structure
  tests updated for the two extra nodes.
2026-09-11 15:13:53 +08:00
Mike-Solar 3c05f7107b docs: harden the pipeline plan — GPU decode zero-copy, Job-graph BFS
Two user-mandated amendments:

- Decode must be GPU wherever possible and share the render GPU's
  memory: hardware surfaces (NV12/P010) are imported as GPU textures
  via the platform interop paths (DMA-BUF / DXGI / IOSurface /
  CUDA-Vulkan), av_hwframe_transfer_data is never executed on the hw
  path, and CPU decode + staging upload demotes to fallback only.
  FFmpeg hwaccel first (the hwdecode.rs device model already builds
  the device contexts; upstream Olive has no hw decode at all, so the
  reference for this part is FFmpeg + the existing crate), hand-written
  GPU decode strictly second. YUV->RGB becomes a built-in GPU pass
  replacing CPU swscale. Milestone M5 becomes the GPU-decode
  zero-copy track with HW_TRANSFERS zero as its acceptance counter.

- The Job graph becomes a real adjacency structure (no linear table,
  no 2D array, possibly not fully connected) with a fixed pair of
  virtual GraphInput/GraphOutput nodes per graph: connected by
  default, undeletable, un-duplicable, shown in the node editor.
  resolve is a Kahn-style BFS from the input node — multi-input joins
  wait for every input, multi-output fans out, the order is
  deterministic and graph-explicit, cycles error out, unreachable
  nodes never run — until every branch converges at the output node.
  M0 splits into M0a (Job enum + single-loop match) and M0b (virtual
  endpoints + BFS + node-editor display).
2026-09-11 10:01:55 +08:00
Mike-Solar 87ed45ffee docs: plan the decode/render thread pipeline with GPU zero-copy
Task book for the render-pipeline rearchitecture: one decode thread
and one render thread feeding queue-linked stages with the main
process presenting (the GPU's single queue makes the multi-process
backend dead weight), one dedicated OpenFX host process with
bounded respawn, GPU-resident frames end-to-end except at the CPU
OFX/export/cache boundaries, a per-backend interop table, and the
resolve rewrite to a single-loop match over a completed Job enum
(CacheJob included) following upstream Olive's
NodeTraverser::ResolveJobs. Milestones M0-M5 with the thread backend
kept behind an OAK_PIPELINE fallback switch.
2026-09-11 09:48:02 +08:00