Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete SukiBackground rewrite. #223

Merged
merged 3 commits into from
Jun 20, 2024
Merged

Conversation

sirdoombox
Copy link
Collaborator

@sirdoombox sirdoombox commented Jun 20, 2024

Major Changes

  • Completely rewrote the background renderer and simplified the associated API.
  • Background is now rendered entirely on the GPU via SkSL shaders and Skia's rendering API.
    • This means animations can run at the native framerate of the application completely unrestricted.
    • As the shader is run per-frame regardless, animated performance is now absolutely identical to static performance.
  • A set of 4 default shaders have been included to get started with, however these aren't final and just represent a reasonable starting point.
    • Unfortunately I wasn't able to recreate the precise way the old background looked, but I think the replacements are far nicer.
  • The API has been simplified massively, now every property related to the background is directly a part of the SukiWindow
    • New API surface includes BackgroundStyle for the default included ones, BackgroundShaderCode which allows devs to directly supply an SkSL shader string and BackgroundShaderFile which allows devs to give the filename of an embedded resource SkSL file to load and use. The properties take priority in the form File > Code > Style.
    • These properties are duplicated in SukiBackground without the Background prefix.
  • The SukiBackground control is now fast enough and generic enough to be used for other purposes, if you want to use it for GlassCard it should be absolutely fine, I haven't stress tested it myself but I see no reason why it would be an issue.
    • SukiBackground fully supports transparency too, this can even be used in shaders for the window and will work as-expected.

Minor changes

  • Tweaked the menu bar to account for the new background controls.
  • Tweaked the theming menu and it's appearance to account for the new background controls.

Important note

  • The version of Skia Avalonia currently targets has a somewhat more limited version of SkSL and possibly some performance issues, however Skia 3.0 is technically currently compatible with Avalonia 11.1 (though it won't be made the default until Avalonia 12 at least) so there is some scope for SukiUI to target SkiaSharp 3.0 if necessary. Related issue - SkiaSharp 3.0 support AvaloniaUI/Avalonia#15503

Outstanding issues

  • This feature really needs to be tested on multiple machines and OS' to ensure the hardware acceleration is behaving as expected cross-platform, hard one for me to test locally.
  • SukiBackground/SukiWindow now has an (essentially) entirely duplicated set of properties, but I think this is a worthwhile tradeoff to massively simplify the API for devs.
  • ManagedFilePicker currently just uses the Flat style for it's background to simplify things.
  • The shaders are (heavily adapted) versions of suitable things I found on shadertoy and aren't necessarily final.
  • The colours passed into the shader for dark/light aren't exactly black/white just to offset some shader multiplication issues.
  • The flat shader doesn't look very good, it just uses the base color passed in instead of making any attempt to look nice - but as an option for people who want a simple non-busy background I think it's very valuable.
  • This feature needs to be well documented for devs to take full advantage of it, with the focus being on making sure devs are aware of the data that is passed into the shader that they can use to render effects.
    • Right now the effects out of the box I think are fairly comprehensive
  • The uniform data passed into the GPU is currently fixed - iTime, iResolution, iBase, iPrimary, and iAccent are all that are made available to devs, though this should be enough to produce any necessary effect there is some scope for additional data.
    • A notable example might be the pointer position for creating backgrounds which are reactive to user input in some way, though how useful devs might find this is another question.
  • As far as I know (which isn't very far I'll admit) Skia's fragment shader doesn't allow you to sample the "texture" of the pixels being rendered "underneath" it, which means it can't be used for blurs unfortunately. Though I could be entirely wrong, the documentation is basically non existent.

Backgrounds are now localised entirely to their window and run entirely on the GPU via SkSL shaders.
@kikipoulet
Copy link
Owner

Hi doombox !

These are great news. I tried it and it indeed seems to make some things smoother. Weirdly, popups like MenuItem seem to be much smoother.

Isn't it possible to keep the old SukiBackground available as a possibility ? We can't overwrite the old background if we haven't something +/- exactly similar. Either we keep the old background as a possibility, and we add these new background options having time to polish it, or we need to ensure we have the same result as the old one before deleting it.

Except that, the performance gain is super promising and as you said, it opens load of opportunity to use it elsewhere.

@sirdoombox
Copy link
Collaborator Author

sirdoombox commented Jun 20, 2024

I can spend some time trying to recreate the old version in shaders, but honestly the old version has only been available since the start of the preview of 6 so it's quite weird to call it the old version and it was never particularly good anyway in terms of appearance, the colours were always weird. It does sort of exist (the same sort of style) in the Gradient shader. I can probably tweak it some to make it closer to the "old" one.

I think it's a bad idea to hold onto very bad legacy code that has never been out of preview, it's just more time and effort to maintain and the stack is completely different now which would increase complexity a lot trying to support both. The time would definitely be better spent improving on this new correct approach that is actually usable.

The real main issue is that the stack is so completely different with the new rendering that trying to make it interchangeable with the old one would be quite difficult.

I've tried a little to recreate the previous background in the gradient shader, but I'm actually struggling to make the colours "wrong" enough which is quite funny.

@sirdoombox
Copy link
Collaborator Author

I've adjusted the gradient shader so it's a bit closer to the old style gradient shader, but the colours are still not "wrong" enough so I'll need to have a think about that one.

I also fixed a bug that slipped through where new windows weren't detecting the base theme correctly.

@kikipoulet
Copy link
Owner

I can spend some time trying to recreate the old version in shaders, but honestly the old version has only been available since the start of the preview of 6 so it's quite weird to call it the old version and it was never particularly good anyway in terms of appearance, the colours were always weird. It does sort of exist (the same sort of style) in the Gradient shader. I can probably tweak it some to make it closer to the "old" one.

I guess it's subjective, I think the legacy one is wonderful. But that's why it's a good idea to offer multiple possibilities then !

I tried to tweak the gradient and indeed I'm optimistic that I can recreate the legacy one. I think at the end we should have 3 possibilities. "Bubble", the current legacy one, "Flat" and "Gradient", which would be a softer gradient, maybe without bubble, just with primary color. Something like this maybe :

image

I will try to tweak Gradient a little more for now, confirming I can recreate the Bubble one I like. So don't worry you don't have to do it for me 😵

@sirdoombox
Copy link
Collaborator Author

sirdoombox commented Jun 20, 2024

One of the big issues I had with recreating the older version was finding a workable simplex noise function, which is what the old one relies on.

Beyond that the code can (mostly) be recreated 1:1, but achieving the precise effect might be a little tricky.

The good thing about this approach however is you can freely add new effects and all they cost is a few kb of a text file and another line in the enum for the "default" effects. Devs can also implement their own and use them very, very easily.

Just thought I'd add a quick note here if you're trying to figure it out with trial and error, because the shaders are compiled at runtime, you can just set the shader via the ShaderCode or BackgroundShaderCode properties and it'll update live, it will throw exceptions if there's a compile error so you might want to throw a catch around the set. But that will let you very rapidly iterate on an idea.

@kikipoulet kikipoulet merged commit e8b2ee6 into kikipoulet:main Jun 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants