render: draw into an offscreen texture and read frames back #465
No reviewers
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis!465
Loading…
Reference in a new issue
No description provided.
Delete branch "render-offscreen-target"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The renderer can now draw into a texture of its own and hand the frame back as RGBA, so a consumer with no window (felis-reel, which turns an
.fcastrecording into video, and screenshot tests) draws through the same code as a felis window. This is the offscreen half of #441; pinned fonts follow separately.Why
Both constructors took a window handle, chose the adapter and texture format from its surface, and
renderended inpresent. There was no way to build aRendererwithout a window. Rasterizing cells a second way on the CPU would drift from what a window shows.What changed
Renderer::new_offscreen(width, height, cfg, warmup)picks an adapter without a surface, reusing a warm device when aWarmupsupplies one, and draws into a fixedRgba8UnormSrgbtexture. It ignoresbackground_opacity, so the texture holds straight RGB.Renderer::read_frame(&mut self, out)replacesoutwith the last rendered frame as tightly packed RGBA. It copies in row strips sized under the device'smax_buffer_size, through one reused staging buffer. It makes no promise about alpha.ReadFrameError:NotOffscreenon a window renderer.NoFrameuntil something has been rendered into the current texture (construction andresizeboth start a fresh one).RowPastBufferLimitwhen even one row exceedsmax_buffer_size.Poll/Mapfor device failures.SurfaceConfigurationontoRendereritself, soresize, the viewport uniform andcursor_rect_uvserve both targets.reconfigure_surfacedoes nothing offscreen. The window path behaves as before.new_offscreenreturnsRendererError::OffscreenPostShaderwhen the config names a shader, andset_post_shader(Some(_))returnsPostShaderError::Offscreen. The stage's uniforms read the host clock, and the bundled trail shader paints the whole frame until the client drivesTrailState, so offscreen frames would depend on when they were rendered.capture_last_framekeeps re-encoding the cell pass into a scratch texture, since the smoke test calls it on a swapchain texture that cannot be copied from.NoFramebefore the first render and after a resize.max_buffer_size.background_opacity, a background override, then a resize) and checks every pixel of each. It is#[ignore]d in the default run.just test-gpuruns the crate's ignored tests with Vulkan pointed at lavapipe from the.#smokeshell, andpr.yml'slinux-smokejob runs it.pipeline.md"wgpu surface and resources" records why an offscreen renderer has no post stage, with a Revisit if.testing.md"Frontend smoke test" says that the Linux job runsjust test-gpu.Verification
just checkpasses.just test-gpupasses on lavapipe.background_opacityoffscreen is removed, the pixel test fails.