slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
17.55k stars 602 forks source link

Render to texture/headless #704

Closed akiross closed 1 month ago

akiross commented 2 years ago

Hello, I've been playing with the toolkit for a bit¹ and I was wondering if there is any support (or plans to be) for headless rendering and/or rendering to texture (e.g. Image or SharedPixelBuffer). Here I mean render of the entire window to a buffer and/or elements rendered to buffer for a more general approach.

Use cases are e.g. automated testing and "save screen" functions.

¹ 60fps is pretty neat, kudos! :)

Be-ing commented 2 years ago

Another use case is screens on peripheral devices that don't use a standard display protocol. For example, I have a Native Instruments Traktor Kontrol S4 Mk3. To use SixtyFPS to draw the screens on this, I'd need to render to an off screen buffer and transform the rendered frames into the vendor-defined USB protocol.

ogoffart commented 2 years ago

Yes, it'd be nice to be able to render to images, if only for testing purposes. One question is at what level of the stack to do it. Should it be its own rendering backend, or should it be a feature of some rendering backend? Maybe we should have a matrix of rendering vs "window/eventloop provider" For example, the MCU backend we are working on already re-use all the winit code from the GL backend for its simulator. And another "offscreen" renderer would be helpful.

tronical commented 2 years ago

I think that both the GL and Qt backends are capable of rendering off-screen. With the GL backend it's a little "harder" in the sense that not all systems might support it, but this glutin example shows it, for example.

So my feeling is that it should be a feature of the rendering backend, not its own.

Right now the generated code for a .60 file implies the creation of a sixtyfps::Window. We've talked about the ability to detach and re-attach a component to a window, so perhaps if the backend had a create_offscreen_window() -> Rc<Window> function and we had a frontend API for this, it could be combined.

tronical commented 1 year ago

Some thoughts about this, in the meantime:

We've separated the FemtoVG and Skia renderers into internal crates of their own. We'd like to provide a public API for them that will be low-level. Ideally one of the ways of using the renderer APIs would be to render into a texture, thus allow for integrating Slint into other game engines, etc.

SkyLeite commented 1 month ago

Are there any updates on this? Implementing Slint into other game engines would be great.

tronical commented 1 month ago

This is theoretically possible with the femtovg renderer: https://docs.rs/slint/latest/slint/platform/femtovg_renderer/index.html . But it’s limited to OpenGL.

ogoffart commented 1 month ago

The Software renderer can also be used: https://docs.rs/slint/latest/slint/platform/software_renderer/struct.SoftwareRenderer.html#method.render (With a custom Platform)

There is also Window::take_snapshot

Given that I think we can close this issue.

SK83RJOSH commented 1 month ago

With this closed out, I have to wonder if there's anything tracking exposing a low-level api for the SkiaRenderer? As I'd like to do precisely this, but using skia as well as a custom platform implementation to handle multiple "virtual" windows.

For now I'll have to fallback to femtovg, but in general I would say this use case could still use a bit of love.

tronical commented 1 month ago

I agree. I've created https://github.com/slint-ui/slint/issues/6158 for this purpose.