Performance considerations when skinning
#16
(2022-06-12, 13:33)wyrm Wrote: thanks for posting details and wiki for renderdoc. Have had a little play but unfortunately my system does not seem to have the ponies to handle it. I’m running the 64 bit version on my 4th gen i5 with 8G of ram and windows 10. Will running the 32 bit version be enough, or do I have to let the moths out of the wallet to make it work.
This should be perfectly fine. My laptop is far worse.
 
(2022-06-12, 13:33)wyrm Wrote: As a side note, have made your (most of) suggested changes to my skin, but can’t tell if there has been any improvement in render speed. Don’t seem to have broken anything, so that’s something I guess.
👍
 
(2022-06-13, 11:27)jurialmunkey Wrote: A lot of us use diffuse textures to round the edges of posters but currently we need to make a new diffuse texture for every size/shape. If there was a border attribute for the diffuse we could essentially use one 64x64 diffuse texture with rounded corners everywhere (it would also mean it would be much simpler for pixel perfect support of different resolutions and aspects).
No promises.
Reply
#17
(2022-06-13, 11:27)jurialmunkey Wrote: On the topic of texture optimisation, something I've thought would be particularly useful is for diffuse textures to specify a border value.

I second this, this would be a great feature. I wrote my own GIMP script to just create diffuse textures with user defined size and corner radius as it became annoying having to hand create them. Being able to set a separate border for the diffuse texture would be fantastic, as @jurialmunkey said you could then just have a single diffuse texture with the correct corner radius and set the border so it scales correctly.
Reply
#18
fTV

Looks pretty lean already. There are just a few small opportunities to improve.

- The gradient for the text on the start menu covers the whole screen. Limiting this to the text would save a huge chunk of overdraw.
- Shadow elements (bordered images) which have no inner filling can signal the GUI engine that the inner portion doesn't have to be drawn (infill="false", see https://kodi.wiki/view/Skinning_Manual#Image_Control).
- The shadow overlay covering video add-on icons could be reduced in size by omitting the transparent potion.
- In the content view, you can ditch the uniform filtering texture and animate the diffuse color as soon as https://github.com/xbmc/xbmc/pull/21400 drops.
- Disable visibility of the menu if the info screen is on. (see below)
- The lower gradient in the player OSD features a gradient with ~30% transparent space. This can be reduced.


Amber

Unfortunately it was crashing all the time, due to the scripts hitting Python bugs. But from what I've seen, there is almost no room for improvement.

- The info dialog renders over the previous menu. (see below for the explanation).
- Maybe the shadow behind the posters could be made with an "L" shaped border texture. But this would be an extreme optimization.
- The round indicators have rendering issues at 4k (see below).


General thoughts

For most skins, the info dialog seems to cover the whole screen. Even in those cases, the background elements are still being processed and rendered. It would be very beneficial to set them to being invisible via the <visible> tag. The GUI engine has no way to tell when underlying elements are covered, so everything has to be rendered If there is a reason why this isn't done I'm not aware of, please tell me.

In Nexus, elements which are faded out will be set to invisible automatically (see https://github.com/xbmc/xbmc/pull/21387 for more details). In case of Estuary, it has reduced the overdraw as far less has to be processed when elements are invisible.

In the future, it will be possible to use grayscale/alpha/grayscale+alpha textures. This will save up to 75% of texture resources depending on the system. See https://github.com/xbmc/xbmc/pull/21557.

Not a performance issue but a cosmetic one. A lot of RGBA textures feature no "safety" space around them. If rendered in a higher resolution than originally intended (e.g. on a 4k screen), this leaves rendering artifacts on the edges of the element. Especially round buttons are problematic (see https://github.com/xbmc/xbmc/pull/21549). Ideally, the textures would feature a one pixel wide safe zone around them.


Some takeaways for me

- Background color could be animated to facilitate dimming.
- Have fallback textures and colors as a skin feature.
Reply
#19
(2022-06-18, 02:26)sarbes Wrote: fTV

Looks pretty lean already. There are just a few small opportunities to improve.

- The gradient for the text on the start menu covers the whole screen. Limiting this to the text would save a huge chunk of overdraw.
- Shadow elements (bordered images) which have no inner filling can signal the GUI engine that the inner portion doesn't have to be drawn (infill="false", see https://kodi.wiki/view/Skinning_Manual#Image_Control).
- The shadow overlay covering video add-on icons could be reduced in size by omitting the transparent potion.
- In the content view, you can ditch the uniform filtering texture and animate the diffuse color as soon as https://github.com/xbmc/xbmc/pull/21400 drops.
- Disable visibility of the menu if the info screen is on. (see below)
- The lower gradient in the player OSD features a gradient with ~30% transparent space. This can be reduced.
Thanks for taking the time to do this. I'll certainly look into making changes when I can.
Reply
#20
(2022-06-18, 02:26)sarbes Wrote: Not a performance issue but a cosmetic one. A lot of RGBA textures feature no "safety" space around them. If rendered in a higher resolution than originally intended (e.g. on a 4k screen), this leaves rendering artifacts on the edges of the element. Especially round buttons are problematic (see https://github.com/xbmc/xbmc/pull/21549). Ideally, the textures would feature a one pixel wide safe zone around them.
I ran into this problem when I started using my skin on a 4k TV for the first time and ended up scaling a lot of the textures to get rid of it. Glad it's been identified now though.
Reply
#21
Asset optimization for fTV

You might consider to quarter the size of the shutdown.png (960x540), as is features smooth gradients. I would encourage you to get rid of the alpha channel, as fully opaque textures are better on desktop (AMD/Intel/NVIDIA) systems. But it is just a shutdown screen with nothing much else going on, so don't sweat it.

The default.png is a uniform grey texture with a resolution of 1920x1080. You got to remember that GPU's can't handle PNG's, so that texture will be decoded to an uncompressed texture*. To display this surface, you are wasting over 500Mb/s* at a frame rate of 60fps (1920*1080*4*60). A 1x1 texture is far more suitable in this case.

The diffuse.png is uniform in the X direction. You can crop the texture to to 1x256.

Same thing for the button textures. The gradients can be squashed to a 1x94 texture, while the grey buttons can be 1x1.


Some tech background

The reason to decrease texture size is to decrease memory bandwidth, which is especially important on SOC's.

ARM GPU's have tiny caches. They may have 16KB L1 cache per shader core and 32KB L2 cache shared by all cores. That's enough for a 64x64/64x128 RGBA texture. If a pixel has too much to render to, non-cached data has to be fetched from RAM (which is slow). As a result, it might stall the core. Even worse, cache content which could be used in a different place might be evicted, resulting in a cascading effect requiring even more memory bandwidth.

Even if the shader cores aren't stalling much and the system meets the target frame rate, memory bandwidth should be avoided as the GPU shares the memory bus with the rest of the system. On a system with 5GB/s available bandwidth, a 1080p RGBA texture occupies 10% of the bandwidth resources*, which the CPU could be using doing its tasks.

That's why I'm keen on introducing grayscale textures and textureless surfaces. Also, image compression (ETC1/ETC2/ASTC) might be on the table.


*Some GPU's do compress the texture internally, but this varies wildly.
Reply
#22
The smallest a texture should be is 4x4 pixels for the texture packer.

https://kodi.wiki/index.php?title=Textur...turePacker
Reply
#23
On the topic of alpha channels - suppose I have a "panel" type texture that is semi transparent and has rounded corners. Am I better to:

A) have one texture with rounded corners using alpha and then apply transparency using a colordiffuse (current method I use)

B) have a solid texture without alpha and then use a diffuse texture to apply rounding and transparency

C) combine both methods by using a solid texture with diffuse to round corners and transparency using colordiffuse.

I assume © is the worst approach but thought I'd include it as a possibility. Interest to know what is better between (a) and (b) though.
Arctic Fuse - Alpha now available. Support me on Ko-fi.
Reply
#24
Short answer: I wouldn't think about it too much if they are just small buttons.

Long answer: it depends on multiple factors.

If it is a normal 2D RGB texture, including the border in the alpha channel is the way to go. Some GPU's don't support RGB textures, so they are converted to RGBA on upload anyway.

Only if it is a 1D gradient, one could make the argument that separating alpha into a diffuse textures might be better. Typically, this would double the shader execution time but it would save texture bandwidth. This might be desirable as often the texture bandwidth is a bottleneck, but this would have to be tested. If it doesn't span a large area, I'd say it is not worth it.

As for the colordiffuse, it is without cost on all the systems I've seen. When sampling a texture, there are usually two or more arithmetic units available which can be used for such calculations.
Reply
#25
@sarbes Along with your overdraw recommendations, are there or should there be limits to the number of draw calls / events in a frame?
I've noticed the number varies wildly with some frames hitting over 1700 calls with a fair chunk rendering elements like progress bars, horizontal lines and scrollbars. As someone who uses Kodi on a shield, those high draw count scenes are very noticeable affecting input responsiveness.
Reply
#26
OSMC
Resource friendly skin in theory, which can be improved by removing invisible background elements. This should reduce the overdraw from ~4.5 to ~2.5.

Background colors

First off, you set the background color to 0 ("<backgroundcolor>0</backgroundcolor>"), but then you draw a black element across the whole screen. Just set the background color, and you save one complete screen draw.

To give some background here. For desktop style GPU's, it might be advantageous to avoid setting a background color. For a new frame, they get a buffer with undefined content. This is fine if it is overdrawn by a fanart or other backgrounds. By setting a background color, the GPU has to paint the surface before it can be rendered to. This being said, it is usually not a big problem for modern GPU's.

For mobile GPU's, setting the background color is free. Even worse, by not setting the background color, they might have to fetch the previous content of the buffer, resulting in unnecessary memory transfers.


Always active fanart fallback

The wave fanart fallback is always enabled, even when displaying fanart on top. Disabling it will end up saving another screen draw plus its associated memory cost.


Always active backdrop on the info screen

Same as explained a few posts above. Disable the drawing of the window below if the info screen is active.


Minor artifacts at 4k

The OSMC logo is not round, due to missing white space in the texture (see above). Same for the small arrows.

The gradient underlining the selected menu item at the home screen could be made sharper by doing the placement via the position an not the texture. It would also save a tiny bit of resources.
Reply
#27
(2022-06-26, 10:29)TREX6662k5 Wrote: @sarbes Along with your overdraw recommendations, are there or should there be limits to the number of draw calls / events in a frame?
I've noticed the number varies wildly with some frames hitting over 1700 calls with a fair chunk rendering elements like progress bars, horizontal lines and scrollbars. As someone who uses Kodi on a shield, those high draw count scenes are very noticeable affecting input responsiveness.
I have not seen a skin with over 100 draw calls. Most even stay below 50. In OpenGL land, those start with glDraw*. Other functions would be state changes and geometry/texture uploads.

Draw calls can be reduced by using texture atlases and merging geometry. State changes can be reduced by reordering elements. With our current system, this would be only partially effective. To get the best results, skins would have to define layers where the GUI engine is free to shuffle elements around.

On OpenGL, geometry uploads happen every frame for each element. This can be avoided by leaving them on the GPU. But I have already too much on my plate for Nexus.

In the end, those optimizations are mainly affecting driver workload. What you are describing sounds more of a problem of the underlying GUI engine efficiency in combination with a complex skin.

Anyway, this exceeds the scope of this thread. I'm cooking up some blog posts about this for some more explanation.
Reply
#28
Thank you for taking the time for this! Blush

I've now tried to incorporate all of your feedback by using visible conditions and fade animations (to 0) in order to hide background art as soon as overlaying art is visible as well as window content behind visible dialogs - something I never thought to be of any importance. But there's always something to learn!

Might you be able to take a quick look at the changes to see whether my changes are doing what you've suggested, @sarbes? Big Grin
 
(2022-06-26, 11:11)sarbes Wrote: Minor artifacts at 4k

The OSMC logo is not round, due to missing white space in the texture (see above). Same for the small arrows.

The gradient underlining the selected menu item at the home screen could be made sharper by doing the placement via the position an not the texture. It would also save a tiny bit of resources.

This wasn't an issue at all for the icons - I've simply added one pixel around the icons and saved them. By arrows you meant the ones pointing to the left in the home screen or the ones below and above the home screen list items?

The gradient is a bit of a problem for me to change really as it's not only used in lists where I can adjust the positioning easily, but it's also used for button controls where it's simply a focus texture. But as button controls don't offer any user coordinate options for these textures, I've chosen to adjust the positioning by texture - there are different height versions of this texture for button controls with varying heights. To keep things simple, I've done the same for lists as well to not introduce different ways of handling this. Having said this, maybe you've got an idea for me how this could be done more elegantly? Angel
OSMC Skinner      |    The OSMC Skin for Kodi v20 Nexus (native 16:9, 21:9 and 4:3 skin, special cinemascope/CIH version available)      |     GitHub: https://github.com/Ch1llb0/skin.osmc
Reply
#29
(2022-06-07, 23:37)sarbes Wrote: Here is a hastily written tutorial for Renderdoc: https://kodi.wiki/view/Debugging_via_Renderdoc.

I'll take a look at the other skins when I have the time.

Do you have any tips for using renderdoc on integrated graphics?

I'm often using my laptop which only has intel uhd620.

I can get the frame to capture properly in renderdoc but every output texture when walking the frames in event log is black.

Not a big deal as I can connect up my egpu in my study, but it's nicer being able to work outside on the balcony!
Arctic Fuse - Alpha now available. Support me on Ko-fi.
Reply
#30
Hi @sarbes - I have the same issue as @jurialmunkey above with integrated graphics causing black screens for each frame on my laptop. And my desktop doesn't have a screen so I can only currently access it via remote desktop which seems to cause a whole other set of issues. So I would really appreciate if you can have a look at Copacetic whenever you have a moment.

I've updated it for Nexus using fadediffuses and infill='false' wherever I can. But any other tips you have would be most appreciated. The most up to date code can be found here: https://github.com/realcopacetic/skin.copacetic

Thanks
Reply

Logout Mark Read Team Forum Stats Members Help
Performance considerations when skinning0