Commit afe7585
openscreen-bot
feat(compositor): compositor_macos engine — render targets, MSL pipeline, first-pass compose_frame
Wires up the Metal compositor engine. new_sized now allocates render
targets and compiles the MSL shader library at compositor construction:
Render targets (MTLStorageMode::Private for GPU-only, Shared for readback):
- rt (RGBA8) — main composition target
- rt_read (RGBA8) — CPU-readable mirror for preview live
- nv12_y (R8) — Y plane of the NV12 output
- nv12_uv (RG8) — UV plane of the NV12 output
- nv12_read_y/_uv — CPU-readable mirrors for encode
MSL library: include_str! of shaders.metal, compiled at new_sized via
MTLDevice.new_library_with_source. Function lookups for vs_main, vs_fs,
ps_main, ps_y, ps_uv, ps_tex.
Pipeline states:
- pipeline_main — vs_main + ps_main, RGBA8 color attachment,
premultiplied alpha blend (SrcOne / DstOneMinusSrcAlpha)
- pipeline_fs_y — vs_fs + ps_y, R8 color attachment
- pipeline_fs_uv — vs_fs + ps_uv, RG8 color attachment
- pipeline_fs_tex — vs_fs + ps_tex, RGBA8 color attachment
Engine methods (first-pass implementation):
compose_frame(screen, _webcam, _frame, _cfg)
— first-pass blit: full-canvas (LayerCB mode=0) of the screen frame's
Y+UV textures (via nv12_srvs) into the RGBA8 RT. The webcam is
ignored, the layered composition (rounded corners, shadows, blur
pyramid, motion blur, timeline interpolation) is left to follow-up
commits that wire each LayerCB quad individually. This passes the
encode / preview-loop test path: a full-canvas video frame lands
on the RT.
— Empty screen → clear_rt (RT to black).
render_nv12()
— Two-pass fullscreen conversion: pass 1 (vs_fs + ps_y) writes Y to
nv12_y; pass 2 (vs_fs + ps_uv) writes UV to nv12_uv. Same BT.709
limited RGB→Y'CbCr pipeline as compositor_windows::render_nv12.
rgb_to_nv12(out_tex, slice) / rgb_to_nv12_scaled(...)
— First-pass: route to render_nv12 (writes the internal nv12_y/_uv).
The cross-engine zero-copy path to an external encoder-owned
CVPixelBuffer lands with the encodeur VT commit.
readback_direct()
— Synchronous get_bytes on rt_read → Vec<u8> RGBA8.
readback_resized(target_w, target_h)
— First-pass: routes to readback_direct; the resize is left to a
follow-up commit.
read_nv12_scaled(target_w, target_h, dst_y, pitch_y, dst_uv, pitch_uv)
— get_bytes from nv12_read_y/_uv → caller-provided AVFrame planes.
compose_frame_mb, dump_nv12, dump_raw, blit_to remain Err/no-op — they
exercise engine layers that are not yet wired (the layer-by-layer
composition that compose_frame_mb needs).
Helper: Layer (repr(C, align(16))) matches the HLSL/MSL cbuffer layout
field-for-field (each float4 naturally 16-byte aligned, float2 inside
float4 padded the same way on both sides). Uploaded via
set_fragment_bytes (the VS doesn't read it in full-canvas mode).1 parent 3257688 commit afe7585
1 file changed
Lines changed: 474 additions & 41 deletions
0 commit comments