ProtoPie renderer — renderer-graph 개발 문서 원문 텍스트 추출본 / 2026-09-14 # renderer-graph SceneGraph 로부터 실행 DAG 를 빌드하고 패스 순서 + 중간 텍스처 수명을 관리하는 백엔드-독립 그래프 인프라. ## Module layout ``` src/ ├── lib.rs # module declarations + pub use ├── types.rs # PassNode, PassKind, CompiledRenderGraph, FrameSurfaceDesc, │ # DrawParams, DrawSource, CompositeParams, CaptureParams, ... ├── builder.rs # RenderGraphBuilder — DFS 순회 + pass emission + compile (toposort) ├── executor.rs # RenderGraphExecutor — 그래프 실행, GraphPassEncoder trait ├── transient.rs # TransientPool — 프레임 로컬 중간 텍스처 풀 └── clear_encoder.rs # ClearPassEncoder — 디버그용 클리어 패스 인코더 ``` ## Public surface ```rust RenderGraphBuilder ::build_from_scene_with_viewport_and_strokes(scene, surface, camera, viewport, stroke_plans, resources) -> CompiledRenderGraph CompiledRenderGraph ::execute(executor, encoder: &mut dyn GraphPassEncoder) trait GraphPassEncoder { fn encode(&mut self, pass: &PassNode, views: &PassResourceViews) -> Result<(), _>; } ``` ## Pass kinds | Kind | 역할 | |-----------------------|-------------------------------------------| | `DrawSolid` | solid / gradient fill 또는 stroke | | `DrawTexture` | image fill 또는 image stroke | | `BatchedDraw` | 인접 draw 의 batched 인코딩 | | `BlurH` / `BlurV` | separable Gaussian | | `KawaseDownsample` / `KawaseUpsample` | Dual Kawase blur | | `CompositeNode` | offscreen result 의 main 합성 | | `CaptureBackdrop` / `CaptureSubtree` | crop-copy via UV transform | | `Present` | swapchain present | | `MaskRaster` / `ApplyMask` | 미구현 (runtime error) | ## Design - Executor 는 `ResourceManager` 를 직접 참조하지 않는다. 외부 텍스처는 `external_views: HashMap` 으로 전달. - Transient texture 는 `round_up_texture_tier` (renderer-core) 로 크기 양자화. - `GraphPassEncoder` trait 로 백엔드 분리. wgpu 구현체는 각 백엔드 crate (`renderer-tess::TessPassEncoder` 등) 에서 제공. - Builder 가 traversal 중 계산한 world transform / opacity / `ClipState` 를 `DrawParams` / `CompositeParams` payload 로 실어 보낸다. Encoder / painter 는 scene lineage 를 재계산하지 않는다. - Stroke draw/culling/padding 판단은 caller 가 만든 `StrokePlanSet` 을 필수로 소비한다. Builder 는 frame path 에서 `StrokePlanCompiler::compile_node()` 를 반복 호출하지 않는다. - Offscreen `content_padding` 은 node-local padding 이다. Composite / capture transform 은 world 축 translation 이 아니라 `world * translate(-padding, -padding)` 합성으로 이동한다. - `CaptureBackdrop` / `CaptureSubtree` 는 surface sampling 이 필요. surface 가 `TextureBinding` 을 지원하지 않으면 wasm backend 는 graph 실행 전에 direct scene render fallback 으로 전환. ## Routing rules | Fill kind | Pass | |------------------------------------|------------------------------------------------| | Solid / Linear / Radial / Angular | `DrawSolid { source: Fill(index) }` | | Image | `DrawTexture { source: Fill(index) }` | | Solid / gradient stroke | `DrawSolid { source: Stroke }` | | Image stroke | `DrawTexture { source: Stroke }` | | Blur method | Passes | |-------------|-----------------------------------------| | Gaussian | `BlurH` → `BlurV` | | Kawase | `KawaseDownsample` × N → `KawaseUpsample` × N | ## Hard rules - `renderer-resource` 의존 금지 — 리소스 참조는 external_views 로만. - 새 PassKind 추가 시 모든 `GraphPassEncoder` 구현체 업데이트. - `DrawParams` / `CompositeParams` 필드 추가 시 builder + encoder 양쪽 sync. ## Dependencies - renderer-core (SceneGraph, CameraState, TextureSource, toposort) - renderer-gpu (RhiDevice, RhiTextureView, RhiCommandEncoder) - wgpu, log